blob: f6f57bb5f7574b932f362df7e1614fb65dfef241 [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07004OCT 13 2014
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005Copyright 2014 Open Networking Foundation (ONF)
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07006
7Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
8the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
9or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
10
11 TestON is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 2 of the License, or
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000014 (at your option) any later version.
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -070015
16 TestON is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with TestON. If not, see <http://www.gnu.org/licenses/>.
23"""
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000024
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -070025"""
andrewonlab95ce8322014-10-13 14:12:04 -040026This driver enters the onos> prompt to issue commands.
27
kelvin8ec71442015-01-15 16:57:00 -080028Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -040029functions and document properly.
30
31If you are a contributor to the driver, please
32list your email here for future contact:
33
34jhall@onlab.us
35andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040036shreya@onlab.us
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +000037jeremyr@opennetworking.org
kelvin8ec71442015-01-15 16:57:00 -080038"""
andrewonlab95ce8322014-10-13 14:12:04 -040039import pexpect
40import re
Jon Hall30b82fa2015-03-04 17:15:43 -080041import json
42import types
Jon Hallbd16b922015-03-26 17:53:15 -070043import time
kelvin-onlaba4074292015-07-09 15:19:49 -070044import os
andrewonlab95ce8322014-10-13 14:12:04 -040045from drivers.common.clidriver import CLI
You Wangdb8cd0a2016-05-26 15:19:45 -070046from core.graph import Graph
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -070047from cStringIO import StringIO
48from itertools import izip
andrewonlab95ce8322014-10-13 14:12:04 -040049
kelvin8ec71442015-01-15 16:57:00 -080050class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040051
kelvin8ec71442015-01-15 16:57:00 -080052 def __init__( self ):
53 """
54 Initialize client
55 """
Jon Hallefbd9792015-03-05 16:11:36 -080056 self.name = None
57 self.home = None
58 self.handle = None
Devin Limdc78e202017-06-09 18:30:07 -070059 self.karafUser = None
60 self.karafPass = None
You Wangdb8cd0a2016-05-26 15:19:45 -070061 self.graph = Graph()
Devin Limdc78e202017-06-09 18:30:07 -070062 super( OnosCliDriver, self ).__init__()
kelvin8ec71442015-01-15 16:57:00 -080063
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000064 def checkOptions(self, var, defaultVar):
Devin Limdc78e202017-06-09 18:30:07 -070065 if var is None or var == "":
66 return defaultVar
67 return var
kelvin8ec71442015-01-15 16:57:00 -080068 def connect( self, **connectargs ):
69 """
andrewonlab95ce8322014-10-13 14:12:04 -040070 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080071 """
andrewonlab95ce8322014-10-13 14:12:04 -040072 try:
73 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080074 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070075 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040076 for key in self.options:
77 if key == "home":
Devin Limdc78e202017-06-09 18:30:07 -070078 self.home = self.options[ key ]
79 elif key == "karaf_username":
80 self.karafUser = self.options[ key ]
81 elif key == "karaf_password":
82 self.karafPass = self.options[ key ]
83
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000084 self.home = self.checkOptions(self.home, "~/onos")
85 self.karafUser = self.checkOptions(self.karafUser, self.user_name)
86 self.karafPass = self.checkOptions(self.karafPass, self.pwd )
andrewonlab95ce8322014-10-13 14:12:04 -040087
kelvin-onlaba4074292015-07-09 15:19:49 -070088 for key in self.options:
89 if key == 'onosIp':
90 self.onosIp = self.options[ 'onosIp' ]
91 break
92
kelvin8ec71442015-01-15 16:57:00 -080093 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070094
95 try:
Jon Hallc6793552016-01-19 14:18:37 -080096 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070097 self.ip_address = os.getenv( str( self.ip_address ) )
98 else:
99 main.log.info( self.name +
100 ": Trying to connect to " +
101 self.ip_address )
102
103 except KeyError:
104 main.log.info( "Invalid host name," +
105 " connecting to local host instead" )
106 self.ip_address = 'localhost'
107 except Exception as inst:
108 main.log.error( "Uncaught exception: " + str( inst ) )
109
kelvin8ec71442015-01-15 16:57:00 -0800110 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -0800111 user_name=self.user_name,
112 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -0800113 port=self.port,
114 pwd=self.pwd,
115 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -0400116
kelvin8ec71442015-01-15 16:57:00 -0800117 self.handle.sendline( "cd " + self.home )
Devin Limdc78e202017-06-09 18:30:07 -0700118 self.handle.expect( self.prompt )
andrewonlab95ce8322014-10-13 14:12:04 -0400119 if self.handle:
120 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800121 else:
122 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -0400123 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800124 except TypeError:
125 main.log.exception( self.name + ": Object not as expected" )
126 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400127 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800128 main.log.error( self.name + ": EOF exception found" )
129 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700130 main.cleanAndExit()
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!" )
Devin Lim44075962017-08-11 10:56:37 -0700133 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400134
kelvin8ec71442015-01-15 16:57:00 -0800135 def disconnect( self ):
136 """
andrewonlab95ce8322014-10-13 14:12:04 -0400137 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800138 """
Jon Halld61331b2015-02-17 16:35:47 -0800139 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400140 try:
Jon Hall61282e32015-03-19 11:34:11 -0700141 if self.handle:
142 i = self.logout()
143 if i == main.TRUE:
144 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700145 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700146 self.handle.sendline( "exit" )
147 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800148 except TypeError:
149 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800150 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400151 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800152 main.log.error( self.name + ": EOF exception found" )
153 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700154 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700155 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700156 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800157 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800158 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400159 response = main.FALSE
160 return response
161
kelvin8ec71442015-01-15 16:57:00 -0800162 def logout( self ):
163 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500164 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700165 Returns main.TRUE if exited CLI and
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000166 main.FALSE on timeout (not guranteed you are disconnected)
Jon Hall61282e32015-03-19 11:34:11 -0700167 None on TypeError
168 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800169 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500170 try:
Jon Hall61282e32015-03-19 11:34:11 -0700171 if self.handle:
172 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700173 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ],
Jon Hall61282e32015-03-19 11:34:11 -0700174 timeout=10 )
175 if i == 0: # In ONOS CLI
176 self.handle.sendline( "logout" )
Devin Limdc78e202017-06-09 18:30:07 -0700177 j = self.handle.expect( [ self.prompt,
Jon Hallbfe00002016-04-05 10:23:54 -0700178 "Command not found:",
179 pexpect.TIMEOUT ] )
180 if j == 0: # Successfully logged out
181 return main.TRUE
182 elif j == 1 or j == 2:
183 # ONOS didn't fully load, and logout command isn't working
184 # or the command timed out
185 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700186 try:
Devin Limdc78e202017-06-09 18:30:07 -0700187 self.handle.expect( self.prompt )
Jon Hall64ab3bd2016-05-13 11:29:44 -0700188 except pexpect.TIMEOUT:
189 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700190 return main.TRUE
Jon Halle0f0b342017-04-18 11:43:47 -0700191 else: # some other output
Jon Hallbfe00002016-04-05 10:23:54 -0700192 main.log.warn( "Unknown repsonse to logout command: '{}'",
193 repr( self.handle.before ) )
194 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700195 elif i == 1: # not in CLI
196 return main.TRUE
197 elif i == 3: # Timeout
198 return main.FALSE
199 else:
andrewonlab9627f432014-11-14 12:45:10 -0500200 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800201 except TypeError:
202 main.log.exception( self.name + ": Object not as expected" )
203 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500204 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800205 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700206 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700207 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700208 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700209 main.log.error( self.name +
210 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800211 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800212 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700213 main.cleanAndExit()
andrewonlab38d2b4a2014-11-13 16:28:47 -0500214
kelvin-onlabd3b64892015-01-20 13:26:24 -0800215 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800216 """
andrewonlab95ce8322014-10-13 14:12:04 -0400217 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800218
andrewonlab95ce8322014-10-13 14:12:04 -0400219 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800220 """
andrewonlab95ce8322014-10-13 14:12:04 -0400221 try:
222 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800223 main.log.error( "Must define cellname" )
Devin Lim44075962017-08-11 10:56:37 -0700224 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400225 else:
kelvin8ec71442015-01-15 16:57:00 -0800226 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800227 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800228 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400229 # and that this driver will have to change accordingly
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000230 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800231 handleBefore = self.handle.before
232 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800233 # Get the rest of the handle
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000234 self.handle.sendline("")
235 self.handle.expect(self.prompt)
andrew@onlab.usc400b112015-01-21 15:33:19 -0800236 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400237
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 main.log.info( "Cell call returned: " + handleBefore +
239 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400240
241 return main.TRUE
242
Jon Halld4d4b372015-01-28 16:02:41 -0800243 except TypeError:
244 main.log.exception( self.name + ": Object not as expected" )
245 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400246 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800247 main.log.error( self.name + ": eof exception found" )
248 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700249 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800250 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800251 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700252 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -0800253
pingping-lin57a56ce2015-05-20 16:43:48 -0700254 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800255 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800256 """
Jon Hallefbd9792015-03-05 16:11:36 -0800257 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800258 by user would be used to set the current karaf shell idle timeout.
259 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800260 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800261 Below is an example to start a session with 60 seconds idle timeout
262 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800263
Hari Krishna25d42f72015-01-05 15:08:28 -0800264 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800265 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800266
kelvin-onlabd3b64892015-01-20 13:26:24 -0800267 Note: karafTimeout is left as str so that this could be read
268 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800269 """
You Wangf69ab392016-01-26 16:34:38 -0800270 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400271 try:
Jon Hall67253832016-12-05 09:47:13 -0800272 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800273 self.handle.sendline( "" )
274 x = self.handle.expect( [
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000275 self.prompt, "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500276 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800277 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500278 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400279
Jon Hall67253832016-12-05 09:47:13 -0800280 # Not in CLI so login
Chiyu Chengef109502016-11-21 15:51:38 -0800281 if waitForStart:
282 # Wait for onos start ( -w ) and enter onos cli
283 startCliCommand = "onos -w "
284 else:
285 startCliCommand = "onos "
286 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800287 i = self.handle.expect( [
288 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700289 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400290
291 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800292 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800293 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800294 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800295 "config:property-set -p org.apache.karaf.shell\
296 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800297 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700298 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800299 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800300 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400301 return main.TRUE
302 else:
kelvin8ec71442015-01-15 16:57:00 -0800303 # If failed, send ctrl+c to process and try again
304 main.log.info( "Starting CLI failed. Retrying..." )
305 self.handle.send( "\x03" )
Chiyu Chengef109502016-11-21 15:51:38 -0800306 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800307 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
308 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400309 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800310 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800311 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800312 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800313 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800314 "config:property-set -p org.apache.karaf.shell\
315 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800316 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700317 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800318 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800319 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400320 return main.TRUE
321 else:
kelvin8ec71442015-01-15 16:57:00 -0800322 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800323 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400324 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400325
Jon Halld4d4b372015-01-28 16:02:41 -0800326 except TypeError:
327 main.log.exception( self.name + ": Object not as expected" )
328 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400329 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800330 main.log.error( self.name + ": EOF exception found" )
331 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700332 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800333 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800334 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700335 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400336
suibin zhang116647a2016-05-06 16:30:09 -0700337 def startCellCli( self, karafTimeout="",
338 commandlineTimeout=10, onosStartTimeout=60 ):
339 """
340 Start CLI on onos ecll handle.
341
342 karafTimeout is an optional argument. karafTimeout value passed
343 by user would be used to set the current karaf shell idle timeout.
344 Note that when ever this property is modified the shell will exit and
345 the subsequent login would reflect new idle timeout.
346 Below is an example to start a session with 60 seconds idle timeout
347 ( input value is in milliseconds ):
348
349 tValue = "60000"
350
351 Note: karafTimeout is left as str so that this could be read
352 and passed to startOnosCli from PARAMS file as str.
353 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000354
suibin zhang116647a2016-05-06 16:30:09 -0700355 try:
356 self.handle.sendline( "" )
357 x = self.handle.expect( [
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000358 self.prompt, "onos>" ], commandlineTimeout)
suibin zhang116647a2016-05-06 16:30:09 -0700359
360 if x == 1:
361 main.log.info( "ONOS cli is already running" )
362 return main.TRUE
363
364 # Wait for onos start ( -w ) and enter onos cli
365 self.handle.sendline( "/opt/onos/bin/onos" )
366 i = self.handle.expect( [
367 "onos>",
368 pexpect.TIMEOUT ], onosStartTimeout )
369
370 if i == 0:
371 main.log.info( self.name + " CLI Started successfully" )
372 if karafTimeout:
373 self.handle.sendline(
374 "config:property-set -p org.apache.karaf.shell\
375 sshIdleTimeout " +
376 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700377 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700378 self.handle.sendline( "/opt/onos/bin/onos" )
379 self.handle.expect( "onos>" )
380 return main.TRUE
381 else:
382 # If failed, send ctrl+c to process and try again
383 main.log.info( "Starting CLI failed. Retrying..." )
384 self.handle.send( "\x03" )
385 self.handle.sendline( "/opt/onos/bin/onos" )
386 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
387 timeout=30 )
388 if i == 0:
389 main.log.info( self.name + " CLI Started " +
390 "successfully after retry attempt" )
391 if karafTimeout:
392 self.handle.sendline(
393 "config:property-set -p org.apache.karaf.shell\
394 sshIdleTimeout " +
395 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700396 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700397 self.handle.sendline( "/opt/onos/bin/onos" )
398 self.handle.expect( "onos>" )
399 return main.TRUE
400 else:
401 main.log.error( "Connection to CLI " +
402 self.name + " timeout" )
403 return main.FALSE
404
405 except TypeError:
406 main.log.exception( self.name + ": Object not as expected" )
407 return None
408 except pexpect.EOF:
409 main.log.error( self.name + ": EOF exception found" )
410 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700411 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700412 except Exception:
413 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700414 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700415
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800416 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800417 """
418 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800419 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800420 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700421 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800422 Available level: DEBUG, TRACE, INFO, WARN, ERROR
423 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800424 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800425 """
426 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800427 lvlStr = ""
428 if level:
429 lvlStr = "--level=" + level
430
kelvin-onlab338f5512015-02-06 10:53:16 -0800431 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700432 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800433 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800434
kelvin-onlab9f541032015-02-04 16:19:53 -0800435 response = self.handle.before
436 if re.search( "Error", response ):
437 return main.FALSE
438 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700439 except pexpect.TIMEOUT:
440 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700441 if noExit:
442 main.cleanup()
443 return None
444 else:
Devin Lim44075962017-08-11 10:56:37 -0700445 main.cleanAndExit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800446 except pexpect.EOF:
447 main.log.error( self.name + ": EOF exception found" )
448 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700449 if noExit:
450 main.cleanup()
451 return None
452 else:
Devin Lim44075962017-08-11 10:56:37 -0700453 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800454 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800455 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700456 if noExit:
457 main.cleanup()
458 return None
459 else:
Devin Lim44075962017-08-11 10:56:37 -0700460 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400461
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700462 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, dollarSign=False ):
kelvin8ec71442015-01-15 16:57:00 -0800463 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800464 Send a completely user specified string to
465 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400466 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800467
YPZhang14a4aa92016-07-15 13:37:15 -0700468 if noExit is True, TestON will not exit, and return None
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700469 if dollarSign is True, TestON will not expect for '$' as a new CLI or onos> prompt
470 since '$' can be in the output.
YPZhangebf9eb52016-05-12 15:20:24 -0700471
andrewonlaba18f6bf2014-10-13 19:31:54 -0400472 Warning: There are no sanity checking to commands
473 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800474
kelvin8ec71442015-01-15 16:57:00 -0800475 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400476 try:
Jon Halla495f562016-05-16 18:03:26 -0700477 # Try to reconnect if disconnected from cli
478 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700479 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ] )
Jon Halla495f562016-05-16 18:03:26 -0700480 if i == 1:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000481 main.log.error( self.name + ": onos cli session closed. ")
Jon Halla495f562016-05-16 18:03:26 -0700482 if self.onosIp:
483 main.log.warn( "Trying to reconnect " + self.onosIp )
484 reconnectResult = self.startOnosCli( self.onosIp )
485 if reconnectResult:
486 main.log.info( self.name + ": onos cli session reconnected." )
487 else:
488 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700489 if noExit:
490 return None
491 else:
Devin Lim44075962017-08-11 10:56:37 -0700492 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700493 else:
Devin Lim44075962017-08-11 10:56:37 -0700494 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700495 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700496 main.log.warn( "Timeout when testing cli responsiveness" )
497 main.log.debug( self.handle.before )
498 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Halla495f562016-05-16 18:03:26 -0700499 self.handle.expect( "onos>" )
500
Jon Hall14a03b52016-05-11 12:07:30 -0700501 if debug:
502 # NOTE: This adds and average of .4 seconds per call
503 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700504 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800505 self.handle.sendline( cmdStr )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700506 if dollarSign:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000507 i = self.handle.expect( ["onos>"], timeout )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700508 else:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000509 i = self.handle.expect( ["onos>", self.prompt], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800510 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800511 # TODO: do something with i
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000512 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
Jon Hallc6793552016-01-19 14:18:37 -0800513 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700514 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700515 main.log.debug( self.name + ": Raw output" )
516 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700517
518 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800519 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800520 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700521 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700522 main.log.debug( self.name + ": ansiEscape output" )
523 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700524
kelvin-onlabfb521662015-02-27 09:52:40 -0800525 # Remove extra return chars that get added
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000526 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700527 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700528 main.log.debug( self.name + ": Removed extra returns " +
529 "from output" )
530 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700531
532 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800533 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700534 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700535 main.log.debug( self.name + ": parsed and stripped output" )
536 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700537
Jon Hall63604932015-02-26 17:09:50 -0800538 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700539 output = response.split( cmdStr.strip(), 1 )
540 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700541 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700542 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700543 main.log.debug( self.name + ": " + repr( r ) )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000544 output = output[1].strip()
GlennRC85870432015-11-23 11:45:51 -0800545 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800546 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800547 return output
GlennRCed771242016-01-13 17:02:47 -0800548 except pexpect.TIMEOUT:
549 main.log.error( self.name + ":ONOS timeout" )
550 if debug:
551 main.log.debug( self.handle.before )
552 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700553 except IndexError:
554 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700555 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700556 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800557 except TypeError:
558 main.log.exception( self.name + ": Object not as expected" )
559 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400560 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800561 main.log.error( self.name + ": EOF exception found" )
562 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700563 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700564 return None
565 else:
Devin Lim44075962017-08-11 10:56:37 -0700566 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800567 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800568 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700569 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700570 return None
571 else:
Devin Lim44075962017-08-11 10:56:37 -0700572 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400573
kelvin8ec71442015-01-15 16:57:00 -0800574 # IMPORTANT NOTE:
575 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800576 # the cli command changing 'a:b' with 'aB'.
577 # Ex ) onos:topology > onosTopology
578 # onos:links > onosLinks
579 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800580
kelvin-onlabd3b64892015-01-20 13:26:24 -0800581 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800582 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400583 Adds a new cluster node by ID and address information.
584 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800585 * nodeId
586 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400587 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800588 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800589 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400590 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800591 cmdStr = "add-node " + str( nodeId ) + " " +\
592 str( ONOSIp ) + " " + str( tcpPort )
593 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700594 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800595 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800596 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800597 main.log.error( "Error in adding node" )
598 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800599 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400600 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800601 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400602 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800603 except AssertionError:
604 main.log.exception( "" )
605 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800606 except TypeError:
607 main.log.exception( self.name + ": Object not as expected" )
608 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400609 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800610 main.log.error( self.name + ": EOF exception found" )
611 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700612 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800613 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800614 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700615 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400616
kelvin-onlabd3b64892015-01-20 13:26:24 -0800617 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800618 """
andrewonlab86dc3082014-10-13 18:18:38 -0400619 Removes a cluster by ID
620 Issues command: 'remove-node [<node-id>]'
621 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800622 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800623 """
andrewonlab86dc3082014-10-13 18:18:38 -0400624 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400625
kelvin-onlabd3b64892015-01-20 13:26:24 -0800626 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700627 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700628 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800629 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700630 if re.search( "Error", handle ):
631 main.log.error( "Error in removing node" )
632 main.log.error( handle )
633 return main.FALSE
634 else:
635 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800636 except AssertionError:
637 main.log.exception( "" )
638 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800639 except TypeError:
640 main.log.exception( self.name + ": Object not as expected" )
641 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400642 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800643 main.log.error( self.name + ": EOF exception found" )
644 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700645 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800646 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800647 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700648 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400649
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000650 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800651 """
andrewonlab7c211572014-10-15 16:45:20 -0400652 List the nodes currently visible
653 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700654 Optional argument:
655 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800656 """
andrewonlab7c211572014-10-15 16:45:20 -0400657 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700658 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700659 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700660 cmdStr += " -j"
661 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700662 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800663 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700664 return output
Jon Hallc6793552016-01-19 14:18:37 -0800665 except AssertionError:
666 main.log.exception( "" )
667 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800668 except TypeError:
669 main.log.exception( self.name + ": Object not as expected" )
670 return None
andrewonlab7c211572014-10-15 16:45:20 -0400671 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800672 main.log.error( self.name + ": EOF exception found" )
673 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700674 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800675 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800676 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700677 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400678
kelvin8ec71442015-01-15 16:57:00 -0800679 def topology( self ):
680 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700681 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700682 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700683 Return:
684 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800685 """
andrewonlab95ce8322014-10-13 14:12:04 -0400686 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700687 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800688 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800689 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800690 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700691 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400692 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800693 except AssertionError:
694 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800695 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800696 except TypeError:
697 main.log.exception( self.name + ": Object not as expected" )
698 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400699 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800700 main.log.error( self.name + ": EOF exception found" )
701 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700702 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800703 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800704 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700705 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800706
jenkins7ead5a82015-03-13 10:28:21 -0700707 def deviceRemove( self, deviceId ):
708 """
709 Removes particular device from storage
710
711 TODO: refactor this function
712 """
713 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700714 cmdStr = "device-remove " + str( deviceId )
715 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800716 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800717 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700718 if re.search( "Error", handle ):
719 main.log.error( "Error in removing device" )
720 main.log.error( handle )
721 return main.FALSE
722 else:
723 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800724 except AssertionError:
725 main.log.exception( "" )
726 return None
jenkins7ead5a82015-03-13 10:28:21 -0700727 except TypeError:
728 main.log.exception( self.name + ": Object not as expected" )
729 return None
730 except pexpect.EOF:
731 main.log.error( self.name + ": EOF exception found" )
732 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700733 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700734 except Exception:
735 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700736 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700737
kelvin-onlabd3b64892015-01-20 13:26:24 -0800738 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800739 """
Jon Hall7b02d952014-10-17 20:14:54 -0400740 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400741 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800742 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800743 """
andrewonlab86dc3082014-10-13 18:18:38 -0400744 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700745 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800746 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700747 cmdStr += " -j"
748 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800749 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800750 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700751 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800752 except AssertionError:
753 main.log.exception( "" )
754 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800755 except TypeError:
756 main.log.exception( self.name + ": Object not as expected" )
757 return None
andrewonlab7c211572014-10-15 16:45:20 -0400758 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800759 main.log.error( self.name + ": EOF exception found" )
760 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700761 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800762 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800763 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700764 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400765
kelvin-onlabd3b64892015-01-20 13:26:24 -0800766 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800767 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800768 This balances the devices across all controllers
769 by issuing command: 'onos> onos:balance-masters'
770 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800771 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800772 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800773 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700774 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800775 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800776 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700777 if re.search( "Error", handle ):
778 main.log.error( "Error in balancing masters" )
779 main.log.error( handle )
780 return main.FALSE
781 else:
782 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800783 except AssertionError:
784 main.log.exception( "" )
785 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800786 except TypeError:
787 main.log.exception( self.name + ": Object not as expected" )
788 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800789 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800790 main.log.error( self.name + ": EOF exception found" )
791 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700792 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800793 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800794 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700795 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800796
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000797 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700798 """
799 Returns the output of the masters command.
800 Optional argument:
801 * jsonFormat - boolean indicating if you want output in json
802 """
803 try:
804 cmdStr = "onos:masters"
805 if jsonFormat:
806 cmdStr += " -j"
807 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700808 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800809 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700810 return output
Jon Hallc6793552016-01-19 14:18:37 -0800811 except AssertionError:
812 main.log.exception( "" )
813 return None
acsmars24950022015-07-30 18:00:43 -0700814 except TypeError:
815 main.log.exception( self.name + ": Object not as expected" )
816 return None
817 except pexpect.EOF:
818 main.log.error( self.name + ": EOF exception found" )
819 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700820 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700821 except Exception:
822 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700823 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700824
Jon Hallc6793552016-01-19 14:18:37 -0800825 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700826 """
827 Uses the master command to check that the devices' leadership
828 is evenly divided
829
830 Dependencies: checkMasters() and summary()
831
Jon Hall6509dbf2016-06-21 17:01:17 -0700832 Returns main.TRUE if the devices are balanced
833 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700834 Exits on Exception
835 Returns None on TypeError
836 """
837 try:
Jon Hallc6793552016-01-19 14:18:37 -0800838 summaryOutput = self.summary()
839 totalDevices = json.loads( summaryOutput )[ "devices" ]
840 except ( TypeError, ValueError ):
841 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
842 return None
843 try:
acsmars24950022015-07-30 18:00:43 -0700844 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800845 mastersOutput = self.checkMasters()
846 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700847 first = masters[ 0 ][ "size" ]
848 for master in masters:
849 totalOwnedDevices += master[ "size" ]
850 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
851 main.log.error( "Mastership not balanced" )
852 main.log.info( "\n" + self.checkMasters( False ) )
853 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700854 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000855 str( len(masters) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700856 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800857 except ( TypeError, ValueError ):
858 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700859 return None
860 except pexpect.EOF:
861 main.log.error( self.name + ": EOF exception found" )
862 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700863 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700864 except Exception:
865 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700866 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700867
YPZhangfebf7302016-05-24 16:45:56 -0700868 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800869 """
Jon Halle8217482014-10-17 13:49:14 -0400870 Lists all core links
871 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800872 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800873 """
Jon Halle8217482014-10-17 13:49:14 -0400874 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700875 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800876 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700877 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700878 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800879 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800880 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700881 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800882 except AssertionError:
883 main.log.exception( "" )
884 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800885 except TypeError:
886 main.log.exception( self.name + ": Object not as expected" )
887 return None
Jon Halle8217482014-10-17 13:49:14 -0400888 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800889 main.log.error( self.name + ": EOF exception found" )
890 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700891 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800892 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800893 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700894 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400895
kelvin-onlabd3b64892015-01-20 13:26:24 -0800896 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800897 """
Jon Halle8217482014-10-17 13:49:14 -0400898 Lists all ports
899 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800900 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800901 """
Jon Halle8217482014-10-17 13:49:14 -0400902 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700903 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800904 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700905 cmdStr += " -j"
906 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800907 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800908 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700909 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800910 except AssertionError:
911 main.log.exception( "" )
912 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800913 except TypeError:
914 main.log.exception( self.name + ": Object not as expected" )
915 return None
Jon Halle8217482014-10-17 13:49:14 -0400916 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800917 main.log.error( self.name + ": EOF exception found" )
918 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700919 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800920 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800921 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700922 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400923
kelvin-onlabd3b64892015-01-20 13:26:24 -0800924 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800925 """
Jon Hall983a1702014-10-28 18:44:22 -0400926 Lists all devices and the controllers with roles assigned to them
927 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800928 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800929 """
andrewonlab7c211572014-10-15 16:45:20 -0400930 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700931 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800932 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700933 cmdStr += " -j"
934 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800935 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800936 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700937 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800938 except AssertionError:
939 main.log.exception( "" )
940 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800941 except TypeError:
942 main.log.exception( self.name + ": Object not as expected" )
943 return None
Jon Hall983a1702014-10-28 18:44:22 -0400944 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800945 main.log.error( self.name + ": EOF exception found" )
946 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700947 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800948 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800949 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700950 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -0400951
kelvin-onlabd3b64892015-01-20 13:26:24 -0800952 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800953 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800954 Given the a string containing the json representation of the "roles"
955 cli command and a partial or whole device id, returns a json object
956 containing the roles output for the first device whose id contains
957 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400958
959 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800960 A dict of the role assignments for the given device or
961 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800962 """
Jon Hall983a1702014-10-28 18:44:22 -0400963 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800964 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400965 return None
966 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800967 rawRoles = self.roles()
968 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800969 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800970 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800971 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800972 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400973 return device
974 return None
Jon Hallc6793552016-01-19 14:18:37 -0800975 except ( TypeError, ValueError ):
976 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800977 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400978 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800979 main.log.error( self.name + ": EOF exception found" )
980 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700981 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800982 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800983 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700984 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -0800985
kelvin-onlabd3b64892015-01-20 13:26:24 -0800986 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800987 """
Jon Hall94fd0472014-12-08 11:52:42 -0800988 Iterates through each device and checks if there is a master assigned
989 Returns: main.TRUE if each device has a master
990 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800991 """
Jon Hall94fd0472014-12-08 11:52:42 -0800992 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800993 rawRoles = self.roles()
994 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800995 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800996 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800997 # print device
998 if device[ 'master' ] == "none":
999 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001000 return main.FALSE
1001 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001002 except ( TypeError, ValueError ):
1003 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001004 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001005 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001006 main.log.error( self.name + ": EOF exception found" )
1007 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001008 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001009 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001010 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001011 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001012
kelvin-onlabd3b64892015-01-20 13:26:24 -08001013 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001014 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001015 Returns string of paths, and the cost.
1016 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001017 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001018 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001019 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1020 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001021 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001022 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001023 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001024 main.log.error( "Error in getting paths" )
1025 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001026 else:
kelvin8ec71442015-01-15 16:57:00 -08001027 path = handle.split( ";" )[ 0 ]
1028 cost = handle.split( ";" )[ 1 ]
1029 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001030 except AssertionError:
1031 main.log.exception( "" )
1032 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001033 except TypeError:
1034 main.log.exception( self.name + ": Object not as expected" )
1035 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001036 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001037 main.log.error( self.name + ": EOF exception found" )
1038 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001039 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001040 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001041 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001042 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001043
kelvin-onlabd3b64892015-01-20 13:26:24 -08001044 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001045 """
Jon Hallffb386d2014-11-21 13:43:38 -08001046 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001047 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001048 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001049 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001050 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001051 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001052 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001053 cmdStr += " -j"
1054 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001055 if handle:
1056 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001057 # TODO: Maybe make this less hardcoded
1058 # ConsistentMap Exceptions
1059 assert "org.onosproject.store.service" not in handle
1060 # Node not leader
1061 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001062 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001063 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001064 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001065 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001066 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001067 except TypeError:
1068 main.log.exception( self.name + ": Object not as expected" )
1069 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001070 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001071 main.log.error( self.name + ": EOF exception found" )
1072 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001073 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001074 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001075 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001076 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001077
kelvin-onlabd3b64892015-01-20 13:26:24 -08001078 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001079 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001080 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001081
Jon Hallefbd9792015-03-05 16:11:36 -08001082 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001083 partial mac address
1084
Jon Hall42db6dc2014-10-24 19:03:48 -04001085 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001086 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001087 try:
kelvin8ec71442015-01-15 16:57:00 -08001088 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001089 return None
1090 else:
1091 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001092 rawHosts = self.hosts()
1093 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001094 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001095 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001096 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001097 if not host:
1098 pass
1099 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001100 return host
1101 return None
Jon Hallc6793552016-01-19 14:18:37 -08001102 except ( TypeError, ValueError ):
1103 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001104 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001105 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001106 main.log.error( self.name + ": EOF exception found" )
1107 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001108 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001109 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001110 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001111 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001112
kelvin-onlabd3b64892015-01-20 13:26:24 -08001113 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001114 """
1115 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001116 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001117
andrewonlab3f0a4af2014-10-17 12:25:14 -04001118 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001120 IMPORTANT:
1121 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001122 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001123 Furthermore, it assumes that value of VLAN is '-1'
1124 Description:
kelvin8ec71442015-01-15 16:57:00 -08001125 Converts mininet hosts ( h1, h2, h3... ) into
1126 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1127 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001128 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001130
kelvin-onlabd3b64892015-01-20 13:26:24 -08001131 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001132 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001133 hostHex = hex( int( host ) ).zfill( 12 )
1134 hostHex = str( hostHex ).replace( 'x', '0' )
1135 i = iter( str( hostHex ) )
1136 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1137 hostHex = hostHex + "/-1"
1138 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001139
kelvin-onlabd3b64892015-01-20 13:26:24 -08001140 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001141
Jon Halld4d4b372015-01-28 16:02:41 -08001142 except TypeError:
1143 main.log.exception( self.name + ": Object not as expected" )
1144 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001145 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001146 main.log.error( self.name + ": EOF exception found" )
1147 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001148 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001149 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001150 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001151 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001152
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001153 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001154 """
andrewonlabe6745342014-10-17 14:29:13 -04001155 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001156 * hostIdOne: ONOS host id for host1
1157 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001158 Optional:
1159 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001160 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001161 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001162 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001163 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001164 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001165 Returns:
1166 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001167 """
andrewonlabe6745342014-10-17 14:29:13 -04001168 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001169 cmdStr = "add-host-intent "
1170 if vlanId:
1171 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001172 if setVlan:
1173 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001174 if encap:
1175 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001176 if bandwidth:
1177 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001178 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001179 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001180 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001181 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001182 if re.search( "Error", handle ):
1183 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001184 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001185 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001186 else:
1187 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001188 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001189 match = re.search('id=0x([\da-f]+),', handle)
kelvin-onlabfb521662015-02-27 09:52:40 -08001190 if match:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001191 return match.group()[3:-1]
kelvin-onlabfb521662015-02-27 09:52:40 -08001192 else:
1193 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001194 main.log.debug( "Response from ONOS was: " +
1195 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001196 return None
Jon Hallc6793552016-01-19 14:18:37 -08001197 except AssertionError:
1198 main.log.exception( "" )
1199 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001200 except TypeError:
1201 main.log.exception( self.name + ": Object not as expected" )
1202 return None
andrewonlabe6745342014-10-17 14:29:13 -04001203 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001204 main.log.error( self.name + ": EOF exception found" )
1205 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001206 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001207 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001208 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001209 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001210
kelvin-onlabd3b64892015-01-20 13:26:24 -08001211 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001212 """
andrewonlab7b31d232014-10-24 13:31:47 -04001213 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001214 * ingressDevice: device id of ingress device
1215 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001216 Optional:
1217 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001218 Description:
1219 Adds an optical intent by specifying an ingress and egress device
1220 Returns:
1221 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001222 """
andrewonlab7b31d232014-10-24 13:31:47 -04001223 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001224 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1225 " " + str( egressDevice )
1226 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001227 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001228 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001229 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001230 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001231 main.log.error( "Error in adding Optical intent" )
1232 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001233 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001234 main.log.info( "Optical intent installed between " +
1235 str( ingressDevice ) + " and " +
1236 str( egressDevice ) )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001237 match = re.search('id=0x([\da-f]+),', handle)
kelvin-onlabfb521662015-02-27 09:52:40 -08001238 if match:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001239 return match.group()[3:-1]
kelvin-onlabfb521662015-02-27 09:52:40 -08001240 else:
1241 main.log.error( "Error, intent ID not found" )
1242 return None
Jon Hallc6793552016-01-19 14:18:37 -08001243 except AssertionError:
1244 main.log.exception( "" )
1245 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001246 except TypeError:
1247 main.log.exception( self.name + ": Object not as expected" )
1248 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001249 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001250 main.log.error( self.name + ": EOF exception found" )
1251 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001252 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001253 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001254 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001255 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001256
kelvin-onlabd3b64892015-01-20 13:26:24 -08001257 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001258 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 ingressDevice,
1260 egressDevice,
1261 portIngress="",
1262 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001263 ethType="",
1264 ethSrc="",
1265 ethDst="",
1266 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001267 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001268 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001269 ipProto="",
1270 ipSrc="",
1271 ipDst="",
1272 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001273 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001274 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001275 setVlan="",
1276 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001277 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001278 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001279 * ingressDevice: device id of ingress device
1280 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001281 Optional:
1282 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001283 * ethSrc: specify ethSrc ( i.e. src mac addr )
1284 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001285 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001286 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001287 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001288 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001289 * ipSrc: specify ip source address
1290 * ipDst: specify ip destination address
1291 * tcpSrc: specify tcp source port
1292 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001293 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001294 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001295 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001296 Description:
kelvin8ec71442015-01-15 16:57:00 -08001297 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001298 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001299 Returns:
1300 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001301
Jon Halle3f39ff2015-01-13 11:50:53 -08001302 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001303 options developers provide for point-to-point
1304 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001305 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001306 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001307 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001308
Jeremy Songsterff553672016-05-12 17:06:23 -07001309 if ethType:
1310 cmd += " --ethType " + str( ethType )
1311 if ethSrc:
1312 cmd += " --ethSrc " + str( ethSrc )
1313 if ethDst:
1314 cmd += " --ethDst " + str( ethDst )
1315 if bandwidth:
1316 cmd += " --bandwidth " + str( bandwidth )
1317 if lambdaAlloc:
1318 cmd += " --lambda "
1319 if ipProto:
1320 cmd += " --ipProto " + str( ipProto )
1321 if ipSrc:
1322 cmd += " --ipSrc " + str( ipSrc )
1323 if ipDst:
1324 cmd += " --ipDst " + str( ipDst )
1325 if tcpSrc:
1326 cmd += " --tcpSrc " + str( tcpSrc )
1327 if tcpDst:
1328 cmd += " --tcpDst " + str( tcpDst )
1329 if vlanId:
1330 cmd += " -v " + str( vlanId )
1331 if setVlan:
1332 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001333 if encap:
1334 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001335 if protected:
1336 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001337
kelvin8ec71442015-01-15 16:57:00 -08001338 # Check whether the user appended the port
1339 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001340 if "/" in ingressDevice:
1341 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001342 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001343 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001344 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001345 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001346 # Would it make sense to throw an exception and exit
1347 # the test?
1348 return None
andrewonlab36af3822014-11-18 17:48:18 -05001349
kelvin8ec71442015-01-15 16:57:00 -08001350 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001351 str( ingressDevice ) + "/" +\
1352 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001353
kelvin-onlabd3b64892015-01-20 13:26:24 -08001354 if "/" in egressDevice:
1355 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001356 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001357 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001358 main.log.error( "You must specify the egress port" )
1359 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001360
kelvin8ec71442015-01-15 16:57:00 -08001361 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001362 str( egressDevice ) + "/" +\
1363 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001364
kelvin-onlab898a6c62015-01-16 14:13:53 -08001365 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001366 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001367 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001368 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001369 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001370 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001371 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001372 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001373 # TODO: print out all the options in this message?
1374 main.log.info( "Point-to-point intent installed between " +
1375 str( ingressDevice ) + " and " +
1376 str( egressDevice ) )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001377 match = re.search('id=0x([\da-f]+),', handle)
kelvin-onlabfb521662015-02-27 09:52:40 -08001378 if match:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001379 return match.group()[3:-1]
kelvin-onlabfb521662015-02-27 09:52:40 -08001380 else:
1381 main.log.error( "Error, intent ID not found" )
1382 return None
Jon Hallc6793552016-01-19 14:18:37 -08001383 except AssertionError:
1384 main.log.exception( "" )
1385 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001386 except TypeError:
1387 main.log.exception( self.name + ": Object not as expected" )
1388 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001389 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001390 main.log.error( self.name + ": EOF exception found" )
1391 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001392 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001393 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001394 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001395 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001396
kelvin-onlabd3b64892015-01-20 13:26:24 -08001397 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001398 self,
shahshreyac2f97072015-03-19 17:04:29 -07001399 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001400 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001401 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001402 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001403 ethType="",
1404 ethSrc="",
1405 ethDst="",
1406 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001407 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001408 ipProto="",
1409 ipSrc="",
1410 ipDst="",
1411 tcpSrc="",
1412 tcpDst="",
1413 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001414 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001415 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001416 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001417 partial=False,
1418 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001419 """
shahshreyad0c80432014-12-04 16:56:05 -08001420 Note:
shahshreya70622b12015-03-19 17:19:00 -07001421 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001422 is same. That is, all ingress devices include port numbers
1423 with a "/" or all ingress devices could specify device
1424 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001425 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001426 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001427 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001428 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001429 Optional:
1430 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001431 * ethSrc: specify ethSrc ( i.e. src mac addr )
1432 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001433 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001434 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001435 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001436 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001437 * ipSrc: specify ip source address
1438 * ipDst: specify ip destination address
1439 * tcpSrc: specify tcp source port
1440 * tcpDst: specify tcp destination port
1441 * setEthSrc: action to Rewrite Source MAC Address
1442 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001443 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001444 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001445 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001446 Description:
kelvin8ec71442015-01-15 16:57:00 -08001447 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001448 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001449 Returns:
1450 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001451
Jon Halle3f39ff2015-01-13 11:50:53 -08001452 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001453 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001454 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001455 """
shahshreyad0c80432014-12-04 16:56:05 -08001456 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001457 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001458
Jeremy Songsterff553672016-05-12 17:06:23 -07001459 if ethType:
1460 cmd += " --ethType " + str( ethType )
1461 if ethSrc:
1462 cmd += " --ethSrc " + str( ethSrc )
1463 if ethDst:
1464 cmd += " --ethDst " + str( ethDst )
1465 if bandwidth:
1466 cmd += " --bandwidth " + str( bandwidth )
1467 if lambdaAlloc:
1468 cmd += " --lambda "
1469 if ipProto:
1470 cmd += " --ipProto " + str( ipProto )
1471 if ipSrc:
1472 cmd += " --ipSrc " + str( ipSrc )
1473 if ipDst:
1474 cmd += " --ipDst " + str( ipDst )
1475 if tcpSrc:
1476 cmd += " --tcpSrc " + str( tcpSrc )
1477 if tcpDst:
1478 cmd += " --tcpDst " + str( tcpDst )
1479 if setEthSrc:
1480 cmd += " --setEthSrc " + str( setEthSrc )
1481 if setEthDst:
1482 cmd += " --setEthDst " + str( setEthDst )
1483 if vlanId:
1484 cmd += " -v " + str( vlanId )
1485 if setVlan:
1486 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001487 if partial:
1488 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001489 if encap:
1490 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001491
kelvin8ec71442015-01-15 16:57:00 -08001492 # Check whether the user appended the port
1493 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001494
1495 if portIngressList is None:
1496 for ingressDevice in ingressDeviceList:
1497 if "/" in ingressDevice:
1498 cmd += " " + str( ingressDevice )
1499 else:
1500 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001501 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001502 # TODO: perhaps more meaningful return
1503 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001504 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001505 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001506 for ingressDevice, portIngress in zip( ingressDeviceList,
1507 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001508 cmd += " " + \
1509 str( ingressDevice ) + "/" +\
1510 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001511 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001512 main.log.error( "Device list and port list does not " +
1513 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001514 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001515 if "/" in egressDevice:
1516 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001517 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001518 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001519 main.log.error( "You must specify " +
1520 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001521 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001522
kelvin8ec71442015-01-15 16:57:00 -08001523 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001524 str( egressDevice ) + "/" +\
1525 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001526 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001527 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001528 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001529 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001530 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001531 main.log.error( "Error in adding multipoint-to-singlepoint " +
1532 "intent" )
1533 return None
shahshreyad0c80432014-12-04 16:56:05 -08001534 else:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001535 match = re.search('id=0x([\da-f]+),', handle)
kelvin-onlabb9408212015-04-01 13:34:04 -07001536 if match:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001537 return match.group()[3:-1]
kelvin-onlabb9408212015-04-01 13:34:04 -07001538 else:
1539 main.log.error( "Error, intent ID not found" )
1540 return None
Jon Hallc6793552016-01-19 14:18:37 -08001541 except AssertionError:
1542 main.log.exception( "" )
1543 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001544 except TypeError:
1545 main.log.exception( self.name + ": Object not as expected" )
1546 return None
1547 except pexpect.EOF:
1548 main.log.error( self.name + ": EOF exception found" )
1549 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001550 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001551 except Exception:
1552 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001553 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001554
1555 def addSinglepointToMultipointIntent(
1556 self,
1557 ingressDevice,
1558 egressDeviceList,
1559 portIngress="",
1560 portEgressList=None,
1561 ethType="",
1562 ethSrc="",
1563 ethDst="",
1564 bandwidth="",
1565 lambdaAlloc=False,
1566 ipProto="",
1567 ipSrc="",
1568 ipDst="",
1569 tcpSrc="",
1570 tcpDst="",
1571 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001572 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001573 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001574 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001575 partial=False,
1576 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001577 """
1578 Note:
1579 This function assumes the format of all egress devices
1580 is same. That is, all egress devices include port numbers
1581 with a "/" or all egress devices could specify device
1582 ids and port numbers seperately.
1583 Required:
1584 * EgressDeviceList: List of device ids of egress device
1585 ( Atleast 2 eress devices required in the list )
1586 * ingressDevice: device id of ingress device
1587 Optional:
1588 * ethType: specify ethType
1589 * ethSrc: specify ethSrc ( i.e. src mac addr )
1590 * ethDst: specify ethDst ( i.e. dst mac addr )
1591 * bandwidth: specify bandwidth capacity of link
1592 * lambdaAlloc: if True, intent will allocate lambda
1593 for the specified intent
1594 * ipProto: specify ip protocol
1595 * ipSrc: specify ip source address
1596 * ipDst: specify ip destination address
1597 * tcpSrc: specify tcp source port
1598 * tcpDst: specify tcp destination port
1599 * setEthSrc: action to Rewrite Source MAC Address
1600 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001601 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001602 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001603 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001604 Description:
1605 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1606 specifying device id's and optional fields
1607 Returns:
1608 A string of the intent id or None on error
1609
1610 NOTE: This function may change depending on the
1611 options developers provide for singlepoint-to-multipoint
1612 intent via cli
1613 """
1614 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001615 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001616
Jeremy Songsterff553672016-05-12 17:06:23 -07001617 if ethType:
1618 cmd += " --ethType " + str( ethType )
1619 if ethSrc:
1620 cmd += " --ethSrc " + str( ethSrc )
1621 if ethDst:
1622 cmd += " --ethDst " + str( ethDst )
1623 if bandwidth:
1624 cmd += " --bandwidth " + str( bandwidth )
1625 if lambdaAlloc:
1626 cmd += " --lambda "
1627 if ipProto:
1628 cmd += " --ipProto " + str( ipProto )
1629 if ipSrc:
1630 cmd += " --ipSrc " + str( ipSrc )
1631 if ipDst:
1632 cmd += " --ipDst " + str( ipDst )
1633 if tcpSrc:
1634 cmd += " --tcpSrc " + str( tcpSrc )
1635 if tcpDst:
1636 cmd += " --tcpDst " + str( tcpDst )
1637 if setEthSrc:
1638 cmd += " --setEthSrc " + str( setEthSrc )
1639 if setEthDst:
1640 cmd += " --setEthDst " + str( setEthDst )
1641 if vlanId:
1642 cmd += " -v " + str( vlanId )
1643 if setVlan:
1644 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001645 if partial:
1646 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001647 if encap:
1648 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001649
1650 # Check whether the user appended the port
1651 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001652
kelvin-onlabb9408212015-04-01 13:34:04 -07001653 if "/" in ingressDevice:
1654 cmd += " " + str( ingressDevice )
1655 else:
1656 if not portIngress:
1657 main.log.error( "You must specify " +
1658 "the Ingress port" )
1659 return main.FALSE
1660
1661 cmd += " " +\
1662 str( ingressDevice ) + "/" +\
1663 str( portIngress )
1664
1665 if portEgressList is None:
1666 for egressDevice in egressDeviceList:
1667 if "/" in egressDevice:
1668 cmd += " " + str( egressDevice )
1669 else:
1670 main.log.error( "You must specify " +
1671 "the egress port" )
1672 # TODO: perhaps more meaningful return
1673 return main.FALSE
1674 else:
1675 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001676 for egressDevice, portEgress in zip( egressDeviceList,
1677 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001678 cmd += " " + \
1679 str( egressDevice ) + "/" +\
1680 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001681 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001682 main.log.error( "Device list and port list does not " +
1683 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001684 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001685 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001686 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001687 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001688 # If error, return error message
1689 if re.search( "Error", handle ):
1690 main.log.error( "Error in adding singlepoint-to-multipoint " +
1691 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001692 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001693 else:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001694 match = re.search('id=0x([\da-f]+),', handle)
kelvin-onlabb9408212015-04-01 13:34:04 -07001695 if match:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001696 return match.group()[3:-1]
kelvin-onlabb9408212015-04-01 13:34:04 -07001697 else:
1698 main.log.error( "Error, intent ID not found" )
1699 return None
Jon Hallc6793552016-01-19 14:18:37 -08001700 except AssertionError:
1701 main.log.exception( "" )
1702 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001703 except TypeError:
1704 main.log.exception( self.name + ": Object not as expected" )
1705 return None
shahshreyad0c80432014-12-04 16:56:05 -08001706 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001707 main.log.error( self.name + ": EOF exception found" )
1708 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001709 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001710 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001711 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001712 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001713
Hari Krishna9e232602015-04-13 17:29:08 -07001714 def addMplsIntent(
1715 self,
1716 ingressDevice,
1717 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001718 ingressPort="",
1719 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001720 ethType="",
1721 ethSrc="",
1722 ethDst="",
1723 bandwidth="",
1724 lambdaAlloc=False,
1725 ipProto="",
1726 ipSrc="",
1727 ipDst="",
1728 tcpSrc="",
1729 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001730 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001731 egressLabel="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001732 priority=""):
Hari Krishna9e232602015-04-13 17:29:08 -07001733 """
1734 Required:
1735 * ingressDevice: device id of ingress device
1736 * egressDevice: device id of egress device
1737 Optional:
1738 * ethType: specify ethType
1739 * ethSrc: specify ethSrc ( i.e. src mac addr )
1740 * ethDst: specify ethDst ( i.e. dst mac addr )
1741 * bandwidth: specify bandwidth capacity of link
1742 * lambdaAlloc: if True, intent will allocate lambda
1743 for the specified intent
1744 * ipProto: specify ip protocol
1745 * ipSrc: specify ip source address
1746 * ipDst: specify ip destination address
1747 * tcpSrc: specify tcp source port
1748 * tcpDst: specify tcp destination port
1749 * ingressLabel: Ingress MPLS label
1750 * egressLabel: Egress MPLS label
1751 Description:
1752 Adds MPLS intent by
1753 specifying device id's and optional fields
1754 Returns:
1755 A string of the intent id or None on error
1756
1757 NOTE: This function may change depending on the
1758 options developers provide for MPLS
1759 intent via cli
1760 """
1761 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001762 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001763
Jeremy Songsterff553672016-05-12 17:06:23 -07001764 if ethType:
1765 cmd += " --ethType " + str( ethType )
1766 if ethSrc:
1767 cmd += " --ethSrc " + str( ethSrc )
1768 if ethDst:
1769 cmd += " --ethDst " + str( ethDst )
1770 if bandwidth:
1771 cmd += " --bandwidth " + str( bandwidth )
1772 if lambdaAlloc:
1773 cmd += " --lambda "
1774 if ipProto:
1775 cmd += " --ipProto " + str( ipProto )
1776 if ipSrc:
1777 cmd += " --ipSrc " + str( ipSrc )
1778 if ipDst:
1779 cmd += " --ipDst " + str( ipDst )
1780 if tcpSrc:
1781 cmd += " --tcpSrc " + str( tcpSrc )
1782 if tcpDst:
1783 cmd += " --tcpDst " + str( tcpDst )
1784 if ingressLabel:
1785 cmd += " --ingressLabel " + str( ingressLabel )
1786 if egressLabel:
1787 cmd += " --egressLabel " + str( egressLabel )
1788 if priority:
1789 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001790
1791 # Check whether the user appended the port
1792 # or provided it as an input
1793 if "/" in ingressDevice:
1794 cmd += " " + str( ingressDevice )
1795 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001796 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001797 main.log.error( "You must specify the ingress port" )
1798 return None
1799
1800 cmd += " " + \
1801 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001802 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001803
1804 if "/" in egressDevice:
1805 cmd += " " + str( egressDevice )
1806 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001807 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001808 main.log.error( "You must specify the egress port" )
1809 return None
1810
1811 cmd += " " +\
1812 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001813 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001814
1815 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001816 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001817 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001818 # If error, return error message
1819 if re.search( "Error", handle ):
1820 main.log.error( "Error in adding mpls intent" )
1821 return None
1822 else:
1823 # TODO: print out all the options in this message?
1824 main.log.info( "MPLS intent installed between " +
1825 str( ingressDevice ) + " and " +
1826 str( egressDevice ) )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001827 match = re.search('id=0x([\da-f]+),', handle)
Hari Krishna9e232602015-04-13 17:29:08 -07001828 if match:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001829 return match.group()[3:-1]
Hari Krishna9e232602015-04-13 17:29:08 -07001830 else:
1831 main.log.error( "Error, intent ID not found" )
1832 return None
Jon Hallc6793552016-01-19 14:18:37 -08001833 except AssertionError:
1834 main.log.exception( "" )
1835 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001836 except TypeError:
1837 main.log.exception( self.name + ": Object not as expected" )
1838 return None
1839 except pexpect.EOF:
1840 main.log.error( self.name + ": EOF exception found" )
1841 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001842 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001843 except Exception:
1844 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001845 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001846
Jon Hallefbd9792015-03-05 16:11:36 -08001847 def removeIntent( self, intentId, app='org.onosproject.cli',
1848 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001849 """
shahshreya1c818fc2015-02-26 13:44:08 -08001850 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001851 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001852 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001853 -p or --purge: Purge the intent from the store after removal
1854
Jon Halle3f39ff2015-01-13 11:50:53 -08001855 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001856 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001857 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001858 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001859 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001860 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001861 if purge:
1862 cmdStr += " -p"
1863 if sync:
1864 cmdStr += " -s"
1865
1866 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001867 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001868 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001869 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001870 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001871 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001872 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001873 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001874 # TODO: Should this be main.TRUE
1875 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001876 except AssertionError:
1877 main.log.exception( "" )
1878 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001879 except TypeError:
1880 main.log.exception( self.name + ": Object not as expected" )
1881 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001882 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001883 main.log.error( self.name + ": EOF exception found" )
1884 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001885 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001886 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001887 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001888 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04001889
YPZhangfebf7302016-05-24 16:45:56 -07001890 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001891 """
1892 Description:
1893 Remove all the intents
1894 Optional args:-
1895 -s or --sync: Waits for the removal before returning
1896 -p or --purge: Purge the intent from the store after removal
1897 Returns:
1898 Returns main.TRUE if all intents are removed, otherwise returns
1899 main.FALSE; Returns None for exception
1900 """
1901 try:
1902 cmdStr = "remove-intent"
1903 if purge:
1904 cmdStr += " -p"
1905 if sync:
1906 cmdStr += " -s"
1907
1908 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001909 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001910 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08001911 assert "Command not found:" not in handle, handle
1912 if re.search( "Error", handle ):
1913 main.log.error( "Error in removing intent" )
1914 return main.FALSE
1915 else:
1916 return main.TRUE
1917 except AssertionError:
1918 main.log.exception( "" )
1919 return None
1920 except TypeError:
1921 main.log.exception( self.name + ": Object not as expected" )
1922 return None
1923 except pexpect.EOF:
1924 main.log.error( self.name + ": EOF exception found" )
1925 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001926 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08001927 except Exception:
1928 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001929 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08001930
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001931 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001932 """
1933 Purges all WITHDRAWN Intents
1934 """
1935 try:
1936 cmdStr = "purge-intents"
1937 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001938 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001939 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001940 if re.search( "Error", handle ):
1941 main.log.error( "Error in purging intents" )
1942 return main.FALSE
1943 else:
1944 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001945 except AssertionError:
1946 main.log.exception( "" )
1947 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001948 except TypeError:
1949 main.log.exception( self.name + ": Object not as expected" )
1950 return None
1951 except pexpect.EOF:
1952 main.log.error( self.name + ": EOF exception found" )
1953 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001954 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07001955 except Exception:
1956 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001957 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07001958
Devin Lime6fe3c42017-10-18 16:28:40 -07001959 def wipeout( self ):
1960 """
1961 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
1962 """
1963 try:
1964 cmdStr = "wipe-out please"
1965 handle = self.sendline( cmdStr, timeout=60 )
1966 assert handle is not None, "Error in sendline"
1967 assert "Command not found:" not in handle, handle
1968 return main.TRUE
1969 except AssertionError:
1970 main.log.exception( "" )
1971 return None
1972 except TypeError:
1973 main.log.exception( self.name + ": Object not as expected" )
1974 return None
1975 except pexpect.EOF:
1976 main.log.error( self.name + ": EOF exception found" )
1977 main.log.error( self.name + ": " + self.handle.before )
1978 main.cleanAndExit()
1979 except Exception:
1980 main.log.exception( self.name + ": Uncaught exception!" )
1981 main.cleanAndExit()
1982
kelvin-onlabd3b64892015-01-20 13:26:24 -08001983 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001984 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001985 NOTE: This method should be used after installing application:
1986 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001987 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001988 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001989 Description:
1990 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001991 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001992 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001993 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001994 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001995 cmdStr += " -j"
1996 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001997 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001998 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001999 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002000 except AssertionError:
2001 main.log.exception( "" )
2002 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002003 except TypeError:
2004 main.log.exception( self.name + ": Object not as expected" )
2005 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002006 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002007 main.log.error( self.name + ": EOF exception found" )
2008 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002009 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002010 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002011 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002012 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002013
pingping-lin54b03372015-08-13 14:43:10 -07002014 def ipv4RouteNumber( self ):
2015 """
2016 NOTE: This method should be used after installing application:
2017 onos-app-sdnip
2018 Description:
2019 Obtain the total IPv4 routes number in the system
2020 """
2021 try:
Pratik Parab57963572017-05-09 11:37:54 -07002022 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002023 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002024 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002025 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002026 jsonResult = json.loads( handle )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002027 return len(jsonResult['routes4'])
Jon Hallc6793552016-01-19 14:18:37 -08002028 except AssertionError:
2029 main.log.exception( "" )
2030 return None
2031 except ( TypeError, ValueError ):
2032 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002033 return None
2034 except pexpect.EOF:
2035 main.log.error( self.name + ": EOF exception found" )
2036 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002037 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002038 except Exception:
2039 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002040 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002041
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002042 #=============Function to check Bandwidth allocation========
2043 def allocations( self, jsonFormat = True, dollarSign = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002044 """
2045 Description:
2046 Obtain Bandwidth Allocation Information from ONOS cli.
2047 """
2048 try:
2049 cmdStr = "allocations"
2050 if jsonFormat:
2051 cmdStr += " -j"
2052 handle = self.sendline( cmdStr, timeout=300, dollarSign=True )
2053 assert handle is not None, "Error in sendline"
2054 assert "Command not found:" not in handle, handle
2055 return handle
2056 except AssertionError:
2057 main.log.exception( "" )
2058 return None
2059 except ( TypeError, ValueError ):
2060 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2061 return None
2062 except pexpect.EOF:
2063 main.log.error( self.name + ": EOF exception found" )
2064 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002065 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002066 except Exception:
2067 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002068 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002069
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002070 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002071 """
andrewonlabe6745342014-10-17 14:29:13 -04002072 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002073 Obtain intents from the ONOS cli.
2074 Optional:
2075 * jsonFormat: Enable output formatting in json, default to True
2076 * summary: Whether only output the intent summary, defaults to False
2077 * type: Only output a certain type of intent. This options is valid
2078 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002079 """
andrewonlabe6745342014-10-17 14:29:13 -04002080 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002081 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002082 if summary:
2083 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002084 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002085 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002086 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002087 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002088 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002089 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002090 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002091 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002092 else:
Jon Hallff566d52016-01-15 14:45:36 -08002093 intentType = ""
2094 # IF we want the summary of a specific intent type
2095 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002096 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002097 if intentType in jsonResult.keys():
2098 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002099 else:
Jon Hallff566d52016-01-15 14:45:36 -08002100 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002101 return handle
2102 else:
2103 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002104 except AssertionError:
2105 main.log.exception( "" )
2106 return None
2107 except ( TypeError, ValueError ):
2108 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002109 return None
2110 except pexpect.EOF:
2111 main.log.error( self.name + ": EOF exception found" )
2112 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002113 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002114 except Exception:
2115 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002116 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002117
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002118 def getIntentState(self, intentsId, intentsJson=None):
kelvin-onlab54400a92015-02-26 18:05:51 -08002119 """
You Wangfdcbfc42016-05-16 12:16:53 -07002120 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002121 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002122 list of intent IDs.
2123 Parameters:
2124 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002125 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002126 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002127 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002128 accepted.
2129 Returns a list of dictionaries if a list of intent IDs is accepted,
2130 and each dictionary maps 'id' to the Intent ID and 'state' to
2131 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002132 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002133
kelvin-onlab54400a92015-02-26 18:05:51 -08002134 try:
2135 state = "State is Undefined"
2136 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002137 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002138 else:
Jon Hallc6793552016-01-19 14:18:37 -08002139 rawJson = intentsJson
2140 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002141 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002142 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002143 if intentsId == intent[ 'id' ]:
2144 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002145 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002146 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002147 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002148 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002149 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002150 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002151 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002152 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002153 for intent in parsedIntentsJson:
2154 if intentsId[ i ] == intent[ 'id' ]:
2155 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002156 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002157 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002158 break
Jon Hallefbd9792015-03-05 16:11:36 -08002159 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002160 main.log.warn( "Could not find all intents in ONOS output" )
2161 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002162 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002163 else:
Jon Hall53158082017-05-18 11:17:00 -07002164 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002165 return None
Jon Hallc6793552016-01-19 14:18:37 -08002166 except ( TypeError, ValueError ):
2167 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002168 return None
2169 except pexpect.EOF:
2170 main.log.error( self.name + ": EOF exception found" )
2171 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002172 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002173 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002174 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002175 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002176
Jon Hallf539eb92017-05-22 17:18:42 -07002177 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002178 """
2179 Description:
2180 Check intents state
2181 Required:
2182 intentsId - List of intents ID to be checked
2183 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002184 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002185 state in the list.
2186 *NOTE: You can pass in a list of expected state,
2187 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002188 Return:
Jon Hall53158082017-05-18 11:17:00 -07002189 Returns main.TRUE only if all intent are the same as expected states,
2190 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002191 """
2192 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002193 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002194 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002195
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002196 #intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002197 intentsDict = []
2198 for intent in json.loads( self.intents() ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002199 if isinstance ( intentsId, types.StringType) \
2200 and intent.get('id') == intentsId:
2201 intentsDict.append(intent)
2202 elif isinstance ( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002203 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002204 intentsDict.append(intent)
Devin Lim752dd7b2017-06-27 14:40:03 -07002205
2206 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002207 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002208 "getting intents state" )
2209 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002210
2211 if isinstance( expectedState, types.StringType ):
2212 for intents in intentsDict:
2213 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002214 main.log.debug( self.name + " : Intent ID - " +
2215 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002216 " actual state = " +
2217 intents.get( 'state' )
2218 + " does not equal expected state = "
2219 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002220 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002221 elif isinstance( expectedState, types.ListType ):
2222 for intents in intentsDict:
2223 if not any( state == intents.get( 'state' ) for state in
2224 expectedState ):
2225 main.log.debug( self.name + " : Intent ID - " +
2226 intents.get( 'id' ) +
2227 " actual state = " +
2228 intents.get( 'state' ) +
2229 " does not equal expected states = "
2230 + str( expectedState ) )
2231 returnValue = main.FALSE
2232
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002233 if returnValue == main.TRUE:
2234 main.log.info( self.name + ": All " +
2235 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002236 " intents are in " + str( expectedState ) +
2237 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002238 return returnValue
2239 except TypeError:
2240 main.log.exception( self.name + ": Object not as expected" )
2241 return None
2242 except pexpect.EOF:
2243 main.log.error( self.name + ": EOF exception found" )
2244 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002245 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002246 except Exception:
2247 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002248 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002249
Jon Hallf539eb92017-05-22 17:18:42 -07002250 def compareBandwidthAllocations( self, expectedAllocations ):
2251 """
2252 Description:
2253 Compare the allocated bandwidth with the given allocations
2254 Required:
2255 expectedAllocations - The expected ONOS output of the allocations command
2256 Return:
2257 Returns main.TRUE only if all intent are the same as expected states,
2258 otherwise returns main.FALSE.
2259 """
2260 # FIXME: Convert these string comparisons to object comparisons
2261 try:
2262 returnValue = main.TRUE
2263 bandwidthFailed = False
2264 rawAlloc = self.allocations()
2265 expectedFormat = StringIO( expectedAllocations )
2266 ONOSOutput = StringIO( rawAlloc )
2267 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2268 str( expectedFormat ) ) )
2269
2270 for actual, expected in izip( ONOSOutput, expectedFormat ):
2271 actual = actual.rstrip()
2272 expected = expected.rstrip()
2273 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2274 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002275 marker1 = actual.find('allocated')
2276 m1 = actual[:marker1]
2277 marker2 = expected.find('allocated')
2278 m2 = expected[:marker2]
Jon Hallf539eb92017-05-22 17:18:42 -07002279 if m1 != m2:
2280 bandwidthFailed = True
2281 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2282 bandwidthFailed = True
2283 expectedFormat.close()
2284 ONOSOutput.close()
2285
2286 if bandwidthFailed:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002287 main.log.error("Bandwidth not allocated correctly using Intents!!")
Jon Hallf539eb92017-05-22 17:18:42 -07002288 returnValue = main.FALSE
2289 return returnValue
2290 except TypeError:
2291 main.log.exception( self.name + ": Object not as expected" )
2292 return None
2293 except pexpect.EOF:
2294 main.log.error( self.name + ": EOF exception found" )
2295 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002296 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002297 except Exception:
2298 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002299 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002300
You Wang66518af2016-05-16 15:32:59 -07002301 def compareIntent( self, intentDict ):
2302 """
2303 Description:
2304 Compare the intent ids and states provided in the argument with all intents in ONOS
2305 Return:
2306 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2307 Arguments:
2308 intentDict: a dictionary which maps intent ids to intent states
2309 """
2310 try:
2311 intentsRaw = self.intents()
2312 intentsJson = json.loads( intentsRaw )
2313 intentDictONOS = {}
2314 for intent in intentsJson:
2315 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002316 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002317 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002318 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002319 str( len( intentDict ) ) + " expected and " +
2320 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002321 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002322 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002323 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002324 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2325 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002326 else:
2327 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2328 main.log.debug( self.name + ": intent ID - " + intentID +
2329 " expected state is " + intentDict[ intentID ] +
2330 " but actual state is " + intentDictONOS[ intentID ] )
2331 returnValue = main.FALSE
2332 intentDictONOS.pop( intentID )
2333 if len( intentDictONOS ) > 0:
2334 returnValue = main.FALSE
2335 for intentID in intentDictONOS.keys():
2336 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002337 if returnValue == main.TRUE:
2338 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2339 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002340 except KeyError:
2341 main.log.exception( self.name + ": KeyError exception found" )
2342 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002343 except ( TypeError, ValueError ):
2344 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002345 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002346 except pexpect.EOF:
2347 main.log.error( self.name + ": EOF exception found" )
2348 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002349 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002350 except Exception:
2351 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002352 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002353
YPZhang14a4aa92016-07-15 13:37:15 -07002354 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002355 """
2356 Description:
2357 Check the number of installed intents.
2358 Optional:
2359 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002360 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002361 Return:
2362 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2363 , otherwise, returns main.FALSE.
2364 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002365
GlennRCed771242016-01-13 17:02:47 -08002366 try:
2367 cmd = "intents -s -j"
2368
2369 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002370 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002371 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002372 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002373 response = json.loads( response )
2374
2375 # get total and installed number, see if they are match
2376 allState = response.get( 'all' )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002377 if allState.get('total') == allState.get('installed'):
2378 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002379 return main.TRUE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002380 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002381 return main.FALSE
2382
Jon Hallc6793552016-01-19 14:18:37 -08002383 except ( TypeError, ValueError ):
2384 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002385 return None
2386 except pexpect.EOF:
2387 main.log.error( self.name + ": EOF exception found" )
2388 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002389 if noExit:
2390 return main.FALSE
2391 else:
Devin Lim44075962017-08-11 10:56:37 -07002392 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002393 except pexpect.TIMEOUT:
2394 main.log.error( self.name + ": ONOS timeout" )
2395 return None
GlennRCed771242016-01-13 17:02:47 -08002396 except Exception:
2397 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002398 if noExit:
2399 return main.FALSE
2400 else:
Devin Lim44075962017-08-11 10:56:37 -07002401 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002402
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002403 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002404 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002405 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002406 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002407 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002408 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002409 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002410 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002411 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002412 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002413 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002414 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002415 if noCore:
2416 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002417 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002418 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002419 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002420 assert "Command not found:" not in handle, handle
2421 if re.search( "Error:", handle ):
2422 main.log.error( self.name + ": flows() response: " +
2423 str( handle ) )
2424 return handle
2425 except AssertionError:
2426 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002427 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002428 except TypeError:
2429 main.log.exception( self.name + ": Object not as expected" )
2430 return None
Jon Hallc6793552016-01-19 14:18:37 -08002431 except pexpect.TIMEOUT:
2432 main.log.error( self.name + ": ONOS timeout" )
2433 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002434 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002435 main.log.error( self.name + ": EOF exception found" )
2436 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002437 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002438 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002439 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002440 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002441
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002442 def checkFlowCount(self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002443 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002444 count = int( count ) if count else 0
2445 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002446
Jon Halle0f0b342017-04-18 11:43:47 -07002447 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002448 """
2449 Description:
GlennRCed771242016-01-13 17:02:47 -08002450 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002451 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2452 if the count of those states is 0, which means all current flows
2453 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002454 Optional:
GlennRCed771242016-01-13 17:02:47 -08002455 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002456 Return:
2457 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002458 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002459 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002460 """
2461 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002462 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
GlennRCed771242016-01-13 17:02:47 -08002463 checkedStates = []
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002464 statesCount = [0, 0, 0, 0]
GlennRCed771242016-01-13 17:02:47 -08002465 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002466 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002467 if rawFlows:
2468 # if we didn't get flows or flows function return None, we should return
2469 # main.Flase
2470 checkedStates.append( json.loads( rawFlows ) )
2471 else:
2472 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002473 for i in range( len( states ) ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002474 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002475 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002476 statesCount[i] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002477 except TypeError:
2478 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002479 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002480
GlennRCed771242016-01-13 17:02:47 -08002481 # We want to count PENDING_ADD if isPENDING is true
2482 if isPENDING:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002483 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
GlennRCed771242016-01-13 17:02:47 -08002484 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002485 else:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002486 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
GlennRCed771242016-01-13 17:02:47 -08002487 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002488 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002489 except ( TypeError, ValueError ):
2490 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002491 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002492
YPZhang240842b2016-05-17 12:00:50 -07002493 except AssertionError:
2494 main.log.exception( "" )
2495 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002496 except pexpect.TIMEOUT:
2497 main.log.error( self.name + ": ONOS timeout" )
2498 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002499 except pexpect.EOF:
2500 main.log.error( self.name + ": EOF exception found" )
2501 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002502 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002503 except Exception:
2504 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002505 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002506
GlennRCed771242016-01-13 17:02:47 -08002507 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002508 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002509 """
andrewonlab87852b02014-11-19 18:44:19 -05002510 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002511 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002512 a specific point-to-point intent definition
2513 Required:
GlennRCed771242016-01-13 17:02:47 -08002514 * ingress: specify source dpid
2515 * egress: specify destination dpid
2516 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002517 Optional:
GlennRCed771242016-01-13 17:02:47 -08002518 * offset: the keyOffset is where the next batch of intents
2519 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002520 * noExit: If set to True, TestON will not exit if any error when issus command
2521 * getResponse: If set to True, function will return ONOS response.
2522
GlennRCed771242016-01-13 17:02:47 -08002523 Returns: If failed to push test intents, it will returen None,
2524 if successful, return true.
2525 Timeout expection will return None,
2526 TypeError will return false
2527 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002528 """
andrewonlab87852b02014-11-19 18:44:19 -05002529 try:
GlennRCed771242016-01-13 17:02:47 -08002530 if background:
2531 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002532 else:
GlennRCed771242016-01-13 17:02:47 -08002533 back = ""
2534 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002535 ingress,
2536 egress,
2537 batchSize,
2538 offset,
2539 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002540 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002541 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002542 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002543 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002544 if getResponse:
2545 return response
2546
GlennRCed771242016-01-13 17:02:47 -08002547 # TODO: We should handle if there is failure in installation
2548 return main.TRUE
2549
Jon Hallc6793552016-01-19 14:18:37 -08002550 except AssertionError:
2551 main.log.exception( "" )
2552 return None
GlennRCed771242016-01-13 17:02:47 -08002553 except pexpect.TIMEOUT:
2554 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002555 return None
andrewonlab87852b02014-11-19 18:44:19 -05002556 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002557 main.log.error( self.name + ": EOF exception found" )
2558 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002559 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002560 except TypeError:
2561 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002562 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002563 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002564 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002565 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002566
YPZhangebf9eb52016-05-12 15:20:24 -07002567 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002568 """
2569 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002570 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002571 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002572 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002573 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002574 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002575
YPZhangb5d3f832016-01-23 22:54:26 -08002576 try:
YPZhange3109a72016-02-02 11:25:37 -08002577 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002578 cmd = "flows -c added"
2579 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2580 if rawFlows:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002581 rawFlows = rawFlows.split("\n")
YPZhange3109a72016-02-02 11:25:37 -08002582 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002583 for l in rawFlows:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002584 totalFlows += int(l.split("Count=")[1])
YPZhang14a4aa92016-07-15 13:37:15 -07002585 else:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002586 main.log.error("Response not as expected!")
YPZhang14a4aa92016-07-15 13:37:15 -07002587 return None
2588 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002589
You Wangd3cb2ce2016-05-16 14:01:24 -07002590 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002591 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002592 return None
2593 except pexpect.EOF:
2594 main.log.error( self.name + ": EOF exception found" )
2595 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002596 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002597 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002598 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002599 except pexpect.TIMEOUT:
2600 main.log.error( self.name + ": ONOS timeout" )
2601 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002602 except Exception:
2603 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002604 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002605 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002606 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002607
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002608 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002609 """
2610 Description:
2611 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002612 Optional:
2613 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002614 Return:
2615 The number of intents
2616 """
2617 try:
2618 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002619 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002620 if response is None:
2621 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002622 response = json.loads( response )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002623 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002624 except ( TypeError, ValueError ):
2625 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002626 return None
2627 except pexpect.EOF:
2628 main.log.error( self.name + ": EOF exception found" )
2629 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002630 if noExit:
2631 return -1
2632 else:
Devin Lim44075962017-08-11 10:56:37 -07002633 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002634 except Exception:
2635 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002636 if noExit:
2637 return -1
2638 else:
Devin Lim44075962017-08-11 10:56:37 -07002639 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002640
kelvin-onlabd3b64892015-01-20 13:26:24 -08002641 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002642 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002643 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002644 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002645 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002646 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002647 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002648 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002649 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002650 cmdStr += " -j"
2651 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002652 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002653 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002654 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002655 except AssertionError:
2656 main.log.exception( "" )
2657 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002658 except TypeError:
2659 main.log.exception( self.name + ": Object not as expected" )
2660 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002661 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002662 main.log.error( self.name + ": EOF exception found" )
2663 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002664 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002665 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002666 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002667 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002668
kelvin-onlabd3b64892015-01-20 13:26:24 -08002669 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002670 """
2671 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002672 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002673 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002674 """
andrewonlab867212a2014-10-22 20:13:38 -04002675 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002676 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002677 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002678 cmdStr += " -j"
2679 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002680 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002681 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002682 if handle:
2683 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002684 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002685 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002686 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002687 else:
2688 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002689 except AssertionError:
2690 main.log.exception( "" )
2691 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002692 except TypeError:
2693 main.log.exception( self.name + ": Object not as expected" )
2694 return None
andrewonlab867212a2014-10-22 20:13:38 -04002695 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002696 main.log.error( self.name + ": EOF exception found" )
2697 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002698 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002699 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002700 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002701 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002702
kelvin8ec71442015-01-15 16:57:00 -08002703 # Wrapper functions ****************
2704 # Wrapper functions use existing driver
2705 # functions and extends their use case.
2706 # For example, we may use the output of
2707 # a normal driver function, and parse it
2708 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002709
kelvin-onlabd3b64892015-01-20 13:26:24 -08002710 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002711 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002712 Description:
2713 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002714 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002715 try:
kelvin8ec71442015-01-15 16:57:00 -08002716 # Obtain output of intents function
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002717 intentsStr = self.intents(jsonFormat=True)
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002718 if intentsStr is None:
2719 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002720 # Convert to a dictionary
2721 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002722 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002723 for intent in intents:
2724 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002725 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002726 except TypeError:
2727 main.log.exception( self.name + ": Object not as expected" )
2728 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002729 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002730 main.log.error( self.name + ": EOF exception found" )
2731 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002732 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002733 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002734 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002735 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002736
You Wang3c276252016-09-21 15:21:36 -07002737 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002738 """
2739 Determine the number of flow rules for the given device id that are
2740 in the added state
You Wang3c276252016-09-21 15:21:36 -07002741 Params:
2742 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002743 """
2744 try:
You Wang3c276252016-09-21 15:21:36 -07002745 if core:
2746 cmdStr = "flows any " + str( deviceId ) + " | " +\
2747 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2748 else:
2749 cmdStr = "flows any " + str( deviceId ) + " | " +\
2750 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002751 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002752 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002753 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002754 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002755 except AssertionError:
2756 main.log.exception( "" )
2757 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002758 except pexpect.EOF:
2759 main.log.error( self.name + ": EOF exception found" )
2760 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002761 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002762 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002763 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002764 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002765
kelvin-onlabd3b64892015-01-20 13:26:24 -08002766 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002767 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002768 Use 'devices' function to obtain list of all devices
2769 and parse the result to obtain a list of all device
2770 id's. Returns this list. Returns empty list if no
2771 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002772 List is ordered sequentially
2773
andrewonlab3e15ead2014-10-15 14:21:34 -04002774 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002775 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002776 the ids. By obtaining the list of device ids on the fly,
2777 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002778 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002779 try:
kelvin8ec71442015-01-15 16:57:00 -08002780 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002781 devicesStr = self.devices( jsonFormat=False )
2782 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002783
kelvin-onlabd3b64892015-01-20 13:26:24 -08002784 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002785 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002786 return idList
kelvin8ec71442015-01-15 16:57:00 -08002787
2788 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002789 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002790 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002791 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002792 # Split list further into arguments before and after string
2793 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002794 # append to idList
2795 for arg in tempList:
2796 idList.append( arg.split( "id=" )[ 1 ] )
2797 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002798
Jon Halld4d4b372015-01-28 16:02:41 -08002799 except TypeError:
2800 main.log.exception( self.name + ": Object not as expected" )
2801 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002802 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002803 main.log.error( self.name + ": EOF exception found" )
2804 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002805 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002806 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002807 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002808 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002809
kelvin-onlabd3b64892015-01-20 13:26:24 -08002810 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002811 """
andrewonlab7c211572014-10-15 16:45:20 -04002812 Uses 'nodes' function to obtain list of all nodes
2813 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002814 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002815 Returns:
2816 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002817 """
andrewonlab7c211572014-10-15 16:45:20 -04002818 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002819 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002820 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002821 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002822 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002823 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002824 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002825 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002826 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002827 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002828 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002829 except ( TypeError, ValueError ):
2830 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002831 return None
andrewonlab7c211572014-10-15 16:45:20 -04002832 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002833 main.log.error( self.name + ": EOF exception found" )
2834 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002835 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002836 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002837 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002838 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002839
kelvin-onlabd3b64892015-01-20 13:26:24 -08002840 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002841 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002842 Return the first device from the devices api whose 'id' contains 'dpid'
2843 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002844 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002845 try:
kelvin8ec71442015-01-15 16:57:00 -08002846 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002847 return None
2848 else:
kelvin8ec71442015-01-15 16:57:00 -08002849 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002850 rawDevices = self.devices()
2851 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002852 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002853 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002854 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2855 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002856 return device
2857 return None
Jon Hallc6793552016-01-19 14:18:37 -08002858 except ( TypeError, ValueError ):
2859 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002860 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002861 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002862 main.log.error( self.name + ": EOF exception found" )
2863 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002864 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002865 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002866 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002867 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04002868
You Wang24139872016-05-03 11:48:47 -07002869 def getTopology( self, topologyOutput ):
2870 """
2871 Definition:
2872 Loads a json topology output
2873 Return:
2874 topology = current ONOS topology
2875 """
2876 import json
2877 try:
2878 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002879 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002880 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002881 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002882 except ( TypeError, ValueError ):
2883 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2884 return None
You Wang24139872016-05-03 11:48:47 -07002885 except pexpect.EOF:
2886 main.log.error( self.name + ": EOF exception found" )
2887 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002888 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07002889 except Exception:
2890 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002891 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07002892
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002893 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002894 """
Jon Hallefbd9792015-03-05 16:11:36 -08002895 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002896 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002897 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002898
Flavio Castro82ee2f62016-06-07 15:04:12 -07002899 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002900 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002901 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002902 logLevel = level to log to.
2903 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002904
Jon Hallefbd9792015-03-05 16:11:36 -08002905 Returns: main.TRUE if the number of switches and links are correct,
2906 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002907 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002908 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002909 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002910 try:
You Wang13310252016-07-31 10:56:14 -07002911 summary = self.summary()
2912 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002913 except ( TypeError, ValueError ):
2914 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2915 return main.ERROR
2916 try:
2917 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07002918 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002919 return main.ERROR
2920 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002921 # Is the number of switches is what we expected
2922 devices = topology.get( 'devices', False )
2923 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002924 nodes = summary.get( 'nodes', False )
2925 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002926 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002927 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002928 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002929 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002930 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2931 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002932 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002933 output = output + "The number of links and switches match "\
2934 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002935 result = main.TRUE
2936 else:
You Wang24139872016-05-03 11:48:47 -07002937 output = output + \
2938 "The number of links and switches does not match " + \
2939 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002940 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002941 output = output + "\n ONOS sees %i devices" % int( devices )
2942 output = output + " (%i expected) " % int( numoswitch )
2943 output = output + "and %i links " % int( links )
2944 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002945 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002946 output = output + "and %i controllers " % int( nodes )
2947 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002948 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002949 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002950 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002951 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002952 else:
You Wang24139872016-05-03 11:48:47 -07002953 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002954 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002955 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002956 main.log.error( self.name + ": EOF exception found" )
2957 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002958 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002959 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002960 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002961 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002962
kelvin-onlabd3b64892015-01-20 13:26:24 -08002963 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002964 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002965 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002966 deviceId must be the id of a device as seen in the onos devices command
2967 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002968 role must be either master, standby, or none
2969
Jon Halle3f39ff2015-01-13 11:50:53 -08002970 Returns:
2971 main.TRUE or main.FALSE based on argument verification and
2972 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002973 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002974 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002975 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002976 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002977 cmdStr = "device-role " +\
2978 str( deviceId ) + " " +\
2979 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002980 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002981 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002982 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002983 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002984 if re.search( "Error", handle ):
2985 # end color output to escape any colours
2986 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002987 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002988 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002989 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002990 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002991 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002992 main.log.error( "Invalid 'role' given to device_role(). " +
2993 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002994 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002995 except AssertionError:
2996 main.log.exception( "" )
2997 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002998 except TypeError:
2999 main.log.exception( self.name + ": Object not as expected" )
3000 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003001 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003002 main.log.error( self.name + ": EOF exception found" )
3003 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003004 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003005 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003006 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003007 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003008
kelvin-onlabd3b64892015-01-20 13:26:24 -08003009 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003010 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003011 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003012 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003013 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003014 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003015 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003016 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003017 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003018 cmdStr += " -j"
3019 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003020 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003021 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003022 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003023 except AssertionError:
3024 main.log.exception( "" )
3025 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003026 except TypeError:
3027 main.log.exception( self.name + ": Object not as expected" )
3028 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003029 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003030 main.log.error( self.name + ": EOF exception found" )
3031 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003032 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003033 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003034 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003035 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003036
kelvin-onlabd3b64892015-01-20 13:26:24 -08003037 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003038 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003039 CLI command to get the current leader for the Election test application
3040 NOTE: Requires installation of the onos-app-election feature
3041 Returns: Node IP of the leader if one exists
3042 None if none exists
3043 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003044 """
Jon Hall94fd0472014-12-08 11:52:42 -08003045 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003046 cmdStr = "election-test-leader"
3047 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003048 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003049 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003050 # Leader
3051 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003052 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003053 nodeSearch = re.search( leaderPattern, response )
3054 if nodeSearch:
3055 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003056 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003057 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003058 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003059 # no leader
3060 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003061 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003062 nullSearch = re.search( nullPattern, response )
3063 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003064 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003065 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003066 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003067 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003068 main.log.error( "Error in electionTestLeader on " + self.name +
3069 ": " + "unexpected response" )
3070 main.log.error( repr( response ) )
3071 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003072 except AssertionError:
3073 main.log.exception( "" )
3074 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003075 except TypeError:
3076 main.log.exception( self.name + ": Object not as expected" )
3077 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003078 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003079 main.log.error( self.name + ": EOF exception found" )
3080 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003081 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003082 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003083 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003084 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003085
kelvin-onlabd3b64892015-01-20 13:26:24 -08003086 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003087 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003088 CLI command to run for leadership of the Election test application.
3089 NOTE: Requires installation of the onos-app-election feature
3090 Returns: Main.TRUE on success
3091 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003092 """
Jon Hall94fd0472014-12-08 11:52:42 -08003093 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003094 cmdStr = "election-test-run"
3095 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003096 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003097 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003098 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003099 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003100 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003101 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003102 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003103 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003104 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003105 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003106 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003107 main.log.error( "Error in electionTestRun on " + self.name +
3108 ": " + "unexpected response" )
3109 main.log.error( repr( response ) )
3110 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003111 except AssertionError:
3112 main.log.exception( "" )
3113 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003114 except TypeError:
3115 main.log.exception( self.name + ": Object not as expected" )
3116 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003117 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003118 main.log.error( self.name + ": EOF exception found" )
3119 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003120 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003121 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003122 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003123 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003124
kelvin-onlabd3b64892015-01-20 13:26:24 -08003125 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003126 """
Jon Hall94fd0472014-12-08 11:52:42 -08003127 * CLI command to withdraw the local node from leadership election for
3128 * the Election test application.
3129 #NOTE: Requires installation of the onos-app-election feature
3130 Returns: Main.TRUE on success
3131 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003132 """
Jon Hall94fd0472014-12-08 11:52:42 -08003133 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003134 cmdStr = "election-test-withdraw"
3135 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003136 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003137 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003138 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003139 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003140 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003141 if re.search( successPattern, response ):
3142 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003143 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003144 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003145 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003146 main.log.error( "Error in electionTestWithdraw on " +
3147 self.name + ": " + "unexpected response" )
3148 main.log.error( repr( response ) )
3149 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003150 except AssertionError:
3151 main.log.exception( "" )
3152 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003153 except TypeError:
3154 main.log.exception( self.name + ": Object not as expected" )
3155 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003156 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003157 main.log.error( self.name + ": EOF exception found" )
3158 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003159 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003160 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003161 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003162 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003163
kelvin8ec71442015-01-15 16:57:00 -08003164 def getDevicePortsEnabledCount( self, dpid ):
3165 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003166 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003167 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003168 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003169 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003170 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3171 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003172 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003173 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003174 if re.search( "No such device", output ):
3175 main.log.error( "Error in getting ports" )
3176 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003177 return output
Jon Hallc6793552016-01-19 14:18:37 -08003178 except AssertionError:
3179 main.log.exception( "" )
3180 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003181 except TypeError:
3182 main.log.exception( self.name + ": Object not as expected" )
3183 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003184 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003185 main.log.error( self.name + ": EOF exception found" )
3186 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003187 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003188 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003189 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003190 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003191
kelvin8ec71442015-01-15 16:57:00 -08003192 def getDeviceLinksActiveCount( self, dpid ):
3193 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003194 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003195 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003196 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003197 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003198 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3199 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003200 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003201 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003202 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003203 main.log.error( "Error in getting ports " )
3204 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003205 return output
Jon Hallc6793552016-01-19 14:18:37 -08003206 except AssertionError:
3207 main.log.exception( "" )
3208 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003209 except TypeError:
3210 main.log.exception( self.name + ": Object not as expected" )
3211 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003212 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003213 main.log.error( self.name + ": EOF exception found" )
3214 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003215 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003216 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003217 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003218 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003219
kelvin8ec71442015-01-15 16:57:00 -08003220 def getAllIntentIds( self ):
3221 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003222 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003223 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003224 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003225 cmdStr = "onos:intents | grep id="
3226 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003227 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003228 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003229 if re.search( "Error", output ):
3230 main.log.error( "Error in getting ports" )
3231 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003232 return output
Jon Hallc6793552016-01-19 14:18:37 -08003233 except AssertionError:
3234 main.log.exception( "" )
3235 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003236 except TypeError:
3237 main.log.exception( self.name + ": Object not as expected" )
3238 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003239 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003240 main.log.error( self.name + ": EOF exception found" )
3241 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003242 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003243 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003244 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003245 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003246
Jon Hall73509952015-02-24 16:42:56 -08003247 def intentSummary( self ):
3248 """
Jon Hallefbd9792015-03-05 16:11:36 -08003249 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003250 """
3251 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003252 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003253 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003254 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003255 states.append( intent.get( 'state', None ) )
3256 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003257 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003258 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003259 except ( TypeError, ValueError ):
3260 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003261 return None
3262 except pexpect.EOF:
3263 main.log.error( self.name + ": EOF exception found" )
3264 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003265 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003266 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003267 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003268 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003269
Jon Hall61282e32015-03-19 11:34:11 -07003270 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003271 """
3272 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003273 Optional argument:
3274 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003275 """
Jon Hall63604932015-02-26 17:09:50 -08003276 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003277 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003278 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003279 cmdStr += " -j"
3280 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003281 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003282 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003283 return output
Jon Hallc6793552016-01-19 14:18:37 -08003284 except AssertionError:
3285 main.log.exception( "" )
3286 return None
Jon Hall63604932015-02-26 17:09:50 -08003287 except TypeError:
3288 main.log.exception( self.name + ": Object not as expected" )
3289 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003290 except pexpect.EOF:
3291 main.log.error( self.name + ": EOF exception found" )
3292 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003293 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003294 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003295 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003296 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003297
acsmarsa4a4d1e2015-07-10 16:01:24 -07003298 def leaderCandidates( self, jsonFormat=True ):
3299 """
3300 Returns the output of the leaders -c command.
3301 Optional argument:
3302 * jsonFormat - boolean indicating if you want output in json
3303 """
3304 try:
3305 cmdStr = "onos:leaders -c"
3306 if jsonFormat:
3307 cmdStr += " -j"
3308 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003309 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003310 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003311 return output
Jon Hallc6793552016-01-19 14:18:37 -08003312 except AssertionError:
3313 main.log.exception( "" )
3314 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003315 except TypeError:
3316 main.log.exception( self.name + ": Object not as expected" )
3317 return None
3318 except pexpect.EOF:
3319 main.log.error( self.name + ": EOF exception found" )
3320 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003321 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003322 except Exception:
3323 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003324 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003325
Jon Hallc6793552016-01-19 14:18:37 -08003326 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003327 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003328 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003329 topic parameter and an empty list if the topic doesn't exist
3330 If no leader is elected leader in the returned list will be "none"
3331 Returns None if there is a type error processing the json object
3332 """
3333 try:
Jon Hall6e709752016-02-01 13:38:46 -08003334 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003335 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003336 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003337 assert "Command not found:" not in rawOutput, rawOutput
3338 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003339 results = []
3340 for dict in output:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003341 if dict["topic"] == topic:
3342 leader = dict["leader"]
3343 candidates = re.split( ", ", dict["candidates"][1:-1] )
Jon Hallc6793552016-01-19 14:18:37 -08003344 results.append( leader )
3345 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003346 return results
Jon Hallc6793552016-01-19 14:18:37 -08003347 except AssertionError:
3348 main.log.exception( "" )
3349 return None
3350 except ( TypeError, ValueError ):
3351 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003352 return None
3353 except pexpect.EOF:
3354 main.log.error( self.name + ": EOF exception found" )
3355 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003356 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003357 except Exception:
3358 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003359 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003360
Jon Hall61282e32015-03-19 11:34:11 -07003361 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003362 """
3363 Returns the output of the intent Pending map.
3364 """
Jon Hall63604932015-02-26 17:09:50 -08003365 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003366 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003367 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003368 cmdStr += " -j"
3369 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003370 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003371 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003372 return output
Jon Hallc6793552016-01-19 14:18:37 -08003373 except AssertionError:
3374 main.log.exception( "" )
3375 return None
Jon Hall63604932015-02-26 17:09:50 -08003376 except TypeError:
3377 main.log.exception( self.name + ": Object not as expected" )
3378 return None
3379 except pexpect.EOF:
3380 main.log.error( self.name + ": EOF exception found" )
3381 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003382 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003383 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003384 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003385 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003386
Jon Hall2c8959e2016-12-16 12:17:34 -08003387 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003388 """
3389 Returns the output of the raft partitions command for ONOS.
3390 """
Jon Hall61282e32015-03-19 11:34:11 -07003391 # Sample JSON
3392 # {
3393 # "leader": "tcp://10.128.30.11:7238",
3394 # "members": [
3395 # "tcp://10.128.30.11:7238",
3396 # "tcp://10.128.30.17:7238",
3397 # "tcp://10.128.30.13:7238",
3398 # ],
3399 # "name": "p1",
3400 # "term": 3
3401 # },
Jon Hall63604932015-02-26 17:09:50 -08003402 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003403 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003404 if candidates:
3405 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003406 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003407 cmdStr += " -j"
3408 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003409 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003410 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003411 return output
Jon Hallc6793552016-01-19 14:18:37 -08003412 except AssertionError:
3413 main.log.exception( "" )
3414 return None
Jon Hall63604932015-02-26 17:09:50 -08003415 except TypeError:
3416 main.log.exception( self.name + ": Object not as expected" )
3417 return None
3418 except pexpect.EOF:
3419 main.log.error( self.name + ": EOF exception found" )
3420 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003421 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003422 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003423 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003424 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003425
Jon Halle9f909e2016-09-23 10:43:12 -07003426 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003427 """
3428 Returns the output of the apps command for ONOS. This command lists
3429 information about installed ONOS applications
3430 """
3431 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003432 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003433 # "description":"ONOS OpenFlow protocol southbound providers",
3434 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003435 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003436 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003437 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003438 if summary:
3439 cmdStr += " -s"
3440 if active:
3441 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003442 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003443 cmdStr += " -j"
3444 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003445 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003446 assert "Command not found:" not in output, output
3447 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003448 return output
Jon Hallbe379602015-03-24 13:39:32 -07003449 # FIXME: look at specific exceptions/Errors
3450 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003451 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003452 return None
3453 except TypeError:
3454 main.log.exception( self.name + ": Object not as expected" )
3455 return None
3456 except pexpect.EOF:
3457 main.log.error( self.name + ": EOF exception found" )
3458 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003459 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003460 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003461 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003462 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003463
Jon Hall146f1522015-03-24 15:33:24 -07003464 def appStatus( self, appName ):
3465 """
3466 Uses the onos:apps cli command to return the status of an application.
3467 Returns:
3468 "ACTIVE" - If app is installed and activated
3469 "INSTALLED" - If app is installed and deactivated
3470 "UNINSTALLED" - If app is not installed
3471 None - on error
3472 """
Jon Hall146f1522015-03-24 15:33:24 -07003473 try:
3474 if not isinstance( appName, types.StringType ):
3475 main.log.error( self.name + ".appStatus(): appName must be" +
3476 " a string" )
3477 return None
3478 output = self.apps( jsonFormat=True )
3479 appsJson = json.loads( output )
3480 state = None
3481 for app in appsJson:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003482 if appName == app.get('name'):
3483 state = app.get('state')
Jon Hall146f1522015-03-24 15:33:24 -07003484 break
3485 if state == "ACTIVE" or state == "INSTALLED":
3486 return state
3487 elif state is None:
Jon Hall8bafdc02017-09-05 11:36:26 -07003488 main.log.warn( "{} app not found", appName )
Jon Hall146f1522015-03-24 15:33:24 -07003489 return "UNINSTALLED"
3490 elif state:
3491 main.log.error( "Unexpected state from 'onos:apps': " +
3492 str( state ) )
3493 return state
Jon Hallc6793552016-01-19 14:18:37 -08003494 except ( TypeError, ValueError ):
3495 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003496 return None
3497 except pexpect.EOF:
3498 main.log.error( self.name + ": EOF exception found" )
3499 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003500 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003501 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003502 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003503 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003504
Jon Hallbe379602015-03-24 13:39:32 -07003505 def app( self, appName, option ):
3506 """
3507 Interacts with the app command for ONOS. This command manages
3508 application inventory.
3509 """
Jon Hallbe379602015-03-24 13:39:32 -07003510 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003511 # Validate argument types
3512 valid = True
3513 if not isinstance( appName, types.StringType ):
3514 main.log.error( self.name + ".app(): appName must be a " +
3515 "string" )
3516 valid = False
3517 if not isinstance( option, types.StringType ):
3518 main.log.error( self.name + ".app(): option must be a string" )
3519 valid = False
3520 if not valid:
3521 return main.FALSE
3522 # Validate Option
3523 option = option.lower()
3524 # NOTE: Install may become a valid option
3525 if option == "activate":
3526 pass
3527 elif option == "deactivate":
3528 pass
3529 elif option == "uninstall":
3530 pass
3531 else:
3532 # Invalid option
3533 main.log.error( "The ONOS app command argument only takes " +
3534 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003535 "; was given '" + option + "'")
Jon Hallbd16b922015-03-26 17:53:15 -07003536 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003537 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003538 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003539 assert output is not None, "Error in sendline"
3540 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003541 if "Error executing command" in output:
3542 main.log.error( "Error in processing onos:app command: " +
3543 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003544 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003545 elif "No such application" in output:
3546 main.log.error( "The application '" + appName +
3547 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003548 return main.FALSE
3549 elif "Command not found:" in output:
3550 main.log.error( "Error in processing onos:app command: " +
3551 str( output ) )
3552 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003553 elif "Unsupported command:" in output:
3554 main.log.error( "Incorrect command given to 'app': " +
3555 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003556 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003557 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003558 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003559 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003560 except AssertionError:
3561 main.log.exception( self.name + ": AssertionError exception found" )
3562 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003563 except TypeError:
3564 main.log.exception( self.name + ": Object not as expected" )
3565 return main.ERROR
3566 except pexpect.EOF:
3567 main.log.error( self.name + ": EOF exception found" )
3568 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003569 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003570 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003571 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003572 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003573
Jon Hallbd16b922015-03-26 17:53:15 -07003574 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003575 """
3576 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003577 appName is the hierarchical app name, not the feature name
3578 If check is True, method will check the status of the app after the
3579 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003580 Returns main.TRUE if the command was successfully sent
3581 main.FALSE if the cli responded with an error or given
3582 incorrect input
3583 """
3584 try:
3585 if not isinstance( appName, types.StringType ):
3586 main.log.error( self.name + ".activateApp(): appName must be" +
3587 " a string" )
3588 return main.FALSE
3589 status = self.appStatus( appName )
3590 if status == "INSTALLED":
3591 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003592 if check and response == main.TRUE:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003593 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003594 status = self.appStatus( appName )
3595 if status == "ACTIVE":
3596 return main.TRUE
3597 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003598 main.log.debug( "The state of application " +
3599 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003600 time.sleep( 1 )
3601 return main.FALSE
3602 else: # not 'check' or command didn't succeed
3603 return response
Jon Hall146f1522015-03-24 15:33:24 -07003604 elif status == "ACTIVE":
3605 return main.TRUE
3606 elif status == "UNINSTALLED":
3607 main.log.error( self.name + ": Tried to activate the " +
3608 "application '" + appName + "' which is not " +
3609 "installed." )
3610 else:
3611 main.log.error( "Unexpected return value from appStatus: " +
3612 str( status ) )
3613 return main.ERROR
3614 except TypeError:
3615 main.log.exception( self.name + ": Object not as expected" )
3616 return main.ERROR
3617 except pexpect.EOF:
3618 main.log.error( self.name + ": EOF exception found" )
3619 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003620 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003621 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003622 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003623 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003624
Jon Hallbd16b922015-03-26 17:53:15 -07003625 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003626 """
3627 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003628 appName is the hierarchical app name, not the feature name
3629 If check is True, method will check the status of the app after the
3630 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003631 Returns main.TRUE if the command was successfully sent
3632 main.FALSE if the cli responded with an error or given
3633 incorrect input
3634 """
3635 try:
3636 if not isinstance( appName, types.StringType ):
3637 main.log.error( self.name + ".deactivateApp(): appName must " +
3638 "be a string" )
3639 return main.FALSE
3640 status = self.appStatus( appName )
3641 if status == "INSTALLED":
3642 return main.TRUE
3643 elif status == "ACTIVE":
3644 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003645 if check and response == main.TRUE:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003646 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003647 status = self.appStatus( appName )
3648 if status == "INSTALLED":
3649 return main.TRUE
3650 else:
3651 time.sleep( 1 )
3652 return main.FALSE
3653 else: # not check or command didn't succeed
3654 return response
Jon Hall146f1522015-03-24 15:33:24 -07003655 elif status == "UNINSTALLED":
3656 main.log.warn( self.name + ": Tried to deactivate the " +
3657 "application '" + appName + "' which is not " +
3658 "installed." )
3659 return main.TRUE
3660 else:
3661 main.log.error( "Unexpected return value from appStatus: " +
3662 str( status ) )
3663 return main.ERROR
3664 except TypeError:
3665 main.log.exception( self.name + ": Object not as expected" )
3666 return main.ERROR
3667 except pexpect.EOF:
3668 main.log.error( self.name + ": EOF exception found" )
3669 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003670 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003671 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003672 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003673 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003674
Jon Hallbd16b922015-03-26 17:53:15 -07003675 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003676 """
3677 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003678 appName is the hierarchical app name, not the feature name
3679 If check is True, method will check the status of the app after the
3680 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003681 Returns main.TRUE if the command was successfully sent
3682 main.FALSE if the cli responded with an error or given
3683 incorrect input
3684 """
3685 # TODO: check with Thomas about the state machine for apps
3686 try:
3687 if not isinstance( appName, types.StringType ):
3688 main.log.error( self.name + ".uninstallApp(): appName must " +
3689 "be a string" )
3690 return main.FALSE
3691 status = self.appStatus( appName )
3692 if status == "INSTALLED":
3693 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003694 if check and response == main.TRUE:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003695 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003696 status = self.appStatus( appName )
3697 if status == "UNINSTALLED":
3698 return main.TRUE
3699 else:
3700 time.sleep( 1 )
3701 return main.FALSE
3702 else: # not check or command didn't succeed
3703 return response
Jon Hall146f1522015-03-24 15:33:24 -07003704 elif status == "ACTIVE":
3705 main.log.warn( self.name + ": Tried to uninstall the " +
3706 "application '" + appName + "' which is " +
3707 "currently active." )
3708 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003709 if check and response == main.TRUE:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003710 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003711 status = self.appStatus( appName )
3712 if status == "UNINSTALLED":
3713 return main.TRUE
3714 else:
3715 time.sleep( 1 )
3716 return main.FALSE
3717 else: # not check or command didn't succeed
3718 return response
Jon Hall146f1522015-03-24 15:33:24 -07003719 elif status == "UNINSTALLED":
3720 return main.TRUE
3721 else:
3722 main.log.error( "Unexpected return value from appStatus: " +
3723 str( status ) )
3724 return main.ERROR
3725 except TypeError:
3726 main.log.exception( self.name + ": Object not as expected" )
3727 return main.ERROR
3728 except pexpect.EOF:
3729 main.log.error( self.name + ": EOF exception found" )
3730 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003731 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003732 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003733 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003734 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003735
3736 def appIDs( self, jsonFormat=True ):
3737 """
3738 Show the mappings between app id and app names given by the 'app-ids'
3739 cli command
3740 """
3741 try:
3742 cmdStr = "app-ids"
3743 if jsonFormat:
3744 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003745 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003746 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003747 assert "Command not found:" not in output, output
3748 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003749 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003750 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003751 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003752 return None
3753 except TypeError:
3754 main.log.exception( self.name + ": Object not as expected" )
3755 return None
3756 except pexpect.EOF:
3757 main.log.error( self.name + ": EOF exception found" )
3758 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003759 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003760 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003761 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003762 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003763
3764 def appToIDCheck( self ):
3765 """
3766 This method will check that each application's ID listed in 'apps' is
3767 the same as the ID listed in 'app-ids'. The check will also check that
3768 there are no duplicate IDs issued. Note that an app ID should be
3769 a globaly unique numerical identifier for app/app-like features. Once
3770 an ID is registered, the ID is never freed up so that if an app is
3771 reinstalled it will have the same ID.
3772
3773 Returns: main.TRUE if the check passes and
3774 main.FALSE if the check fails or
3775 main.ERROR if there is some error in processing the test
3776 """
3777 try:
Jon Hall390696c2015-05-05 17:13:41 -07003778 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003779 rawJson = self.appIDs( jsonFormat=True )
3780 if rawJson:
3781 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003782 else:
Jon Hallc6793552016-01-19 14:18:37 -08003783 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003784 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003785 rawJson = self.apps( jsonFormat=True )
3786 if rawJson:
3787 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003788 else:
Jon Hallc6793552016-01-19 14:18:37 -08003789 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003790 bail = True
3791 if bail:
3792 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003793 result = main.TRUE
3794 for app in apps:
3795 appID = app.get( 'id' )
3796 if appID is None:
3797 main.log.error( "Error parsing app: " + str( app ) )
3798 result = main.FALSE
3799 appName = app.get( 'name' )
3800 if appName is None:
3801 main.log.error( "Error parsing app: " + str( app ) )
3802 result = main.FALSE
3803 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003804 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003805 # main.log.debug( "Comparing " + str( app ) + " to " +
3806 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003807 if not current: # if ids doesn't have this id
3808 result = main.FALSE
3809 main.log.error( "'app-ids' does not have the ID for " +
3810 str( appName ) + " that apps does." )
3811 elif len( current ) > 1:
3812 # there is more than one app with this ID
3813 result = main.FALSE
3814 # We will log this later in the method
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003815 elif not current[0][ 'name' ] == appName:
3816 currentName = current[0][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07003817 result = main.FALSE
3818 main.log.error( "'app-ids' has " + str( currentName ) +
3819 " registered under id:" + str( appID ) +
3820 " but 'apps' has " + str( appName ) )
3821 else:
3822 pass # id and name match!
3823 # now make sure that app-ids has no duplicates
3824 idsList = []
3825 namesList = []
3826 for item in ids:
3827 idsList.append( item[ 'id' ] )
3828 namesList.append( item[ 'name' ] )
3829 if len( idsList ) != len( set( idsList ) ) or\
3830 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003831 main.log.error( "'app-ids' has some duplicate entries: \n"
3832 + json.dumps( ids,
3833 sort_keys=True,
3834 indent=4,
3835 separators=( ',', ': ' ) ) )
3836 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003837 return result
Jon Hallc6793552016-01-19 14:18:37 -08003838 except ( TypeError, ValueError ):
3839 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003840 return main.ERROR
3841 except pexpect.EOF:
3842 main.log.error( self.name + ": EOF exception found" )
3843 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003844 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003845 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003846 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003847 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003848
Jon Hallfb760a02015-04-13 15:35:03 -07003849 def getCfg( self, component=None, propName=None, short=False,
3850 jsonFormat=True ):
3851 """
3852 Get configuration settings from onos cli
3853 Optional arguments:
3854 component - Optionally only list configurations for a specific
3855 component. If None, all components with configurations
3856 are displayed. Case Sensitive string.
3857 propName - If component is specified, propName option will show
3858 only this specific configuration from that component.
3859 Case Sensitive string.
3860 jsonFormat - Returns output as json. Note that this will override
3861 the short option
3862 short - Short, less verbose, version of configurations.
3863 This is overridden by the json option
3864 returns:
3865 Output from cli as a string or None on error
3866 """
3867 try:
3868 baseStr = "cfg"
3869 cmdStr = " get"
3870 componentStr = ""
3871 if component:
3872 componentStr += " " + component
3873 if propName:
3874 componentStr += " " + propName
3875 if jsonFormat:
3876 baseStr += " -j"
3877 elif short:
3878 baseStr += " -s"
3879 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003880 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003881 assert "Command not found:" not in output, output
3882 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003883 return output
3884 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003885 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003886 return None
3887 except TypeError:
3888 main.log.exception( self.name + ": Object not as expected" )
3889 return None
3890 except pexpect.EOF:
3891 main.log.error( self.name + ": EOF exception found" )
3892 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003893 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003894 except Exception:
3895 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003896 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003897
3898 def setCfg( self, component, propName, value=None, check=True ):
3899 """
3900 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003901 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003902 component - The case sensitive name of the component whose
3903 property is to be set
3904 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003905 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003906 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003907 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07003908 check - Boolean, Check whether the option was successfully set this
3909 only applies when a value is given.
3910 returns:
3911 main.TRUE on success or main.FALSE on failure. If check is False,
3912 will return main.TRUE unless there is an error
3913 """
3914 try:
3915 baseStr = "cfg"
3916 cmdStr = " set " + str( component ) + " " + str( propName )
3917 if value is not None:
3918 cmdStr += " " + str( value )
3919 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003920 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003921 assert "Command not found:" not in output, output
3922 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003923 if value and check:
3924 results = self.getCfg( component=str( component ),
3925 propName=str( propName ),
3926 jsonFormat=True )
3927 # Check if current value is what we just set
3928 try:
3929 jsonOutput = json.loads( results )
3930 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003931 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003932 main.log.exception( "Error parsing cfg output" )
3933 main.log.error( "output:" + repr( results ) )
3934 return main.FALSE
3935 if current == str( value ):
3936 return main.TRUE
3937 return main.FALSE
3938 return main.TRUE
3939 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003940 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003941 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003942 except ( TypeError, ValueError ):
3943 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003944 return main.FALSE
3945 except pexpect.EOF:
3946 main.log.error( self.name + ": EOF exception found" )
3947 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003948 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003949 except Exception:
3950 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003951 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003952
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003953 def distPrimitivesSend( self, cmd ):
3954 """
3955 Function to handle sending cli commands for the distributed primitives test app
3956
3957 This command will catch some exceptions and retry the command on some
3958 specific store exceptions.
3959
3960 Required arguments:
3961 cmd - The command to send to the cli
3962 returns:
3963 string containing the cli output
3964 None on Error
3965 """
3966 try:
3967 output = self.sendline( cmd )
3968 try:
3969 assert output is not None, "Error in sendline"
3970 # TODO: Maybe make this less hardcoded
3971 # ConsistentMap Exceptions
3972 assert "org.onosproject.store.service" not in output
3973 # Node not leader
3974 assert "java.lang.IllegalStateException" not in output
3975 except AssertionError:
3976 main.log.error( "Error in processing '" + cmd + "' " +
3977 "command: " + str( output ) )
3978 retryTime = 30 # Conservative time, given by Madan
3979 main.log.info( "Waiting " + str( retryTime ) +
3980 "seconds before retrying." )
3981 time.sleep( retryTime ) # Due to change in mastership
3982 output = self.sendline( cmd )
3983 assert output is not None, "Error in sendline"
3984 assert "Command not found:" not in output, output
3985 assert "Error executing command" not in output, output
3986 main.log.info( self.name + ": " + output )
3987 return output
3988 except AssertionError:
3989 main.log.exception( "Error in processing '" + cmd + "' command." )
3990 return None
3991 except TypeError:
3992 main.log.exception( self.name + ": Object not as expected" )
3993 return None
3994 except pexpect.EOF:
3995 main.log.error( self.name + ": EOF exception found" )
3996 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003997 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003998 except Exception:
3999 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004000 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004001
Jon Hall390696c2015-05-05 17:13:41 -07004002 def setTestAdd( self, setName, values ):
4003 """
4004 CLI command to add elements to a distributed set.
4005 Arguments:
4006 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004007 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004008 Example usages:
4009 setTestAdd( "set1", "a b c" )
4010 setTestAdd( "set2", "1" )
4011 returns:
4012 main.TRUE on success OR
4013 main.FALSE if elements were already in the set OR
4014 main.ERROR on error
4015 """
4016 try:
4017 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004018 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004019 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4020 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004021 if re.search( positiveMatch, output):
Jon Hall390696c2015-05-05 17:13:41 -07004022 return main.TRUE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004023 elif re.search( negativeMatch, output):
Jon Hall390696c2015-05-05 17:13:41 -07004024 return main.FALSE
4025 else:
4026 main.log.error( self.name + ": setTestAdd did not" +
4027 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004028 main.log.debug( self.name + " actual: " + repr( output ) )
4029 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004030 except TypeError:
4031 main.log.exception( self.name + ": Object not as expected" )
4032 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004033 except Exception:
4034 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004035 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004036
4037 def setTestRemove( self, setName, values, clear=False, retain=False ):
4038 """
4039 CLI command to remove elements from a distributed set.
4040 Required arguments:
4041 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004042 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004043 Optional arguments:
4044 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004045 retain - Retain only the given values. (intersection of the
4046 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004047 returns:
4048 main.TRUE on success OR
4049 main.FALSE if the set was not changed OR
4050 main.ERROR on error
4051 """
4052 try:
4053 cmdStr = "set-test-remove "
4054 if clear:
4055 cmdStr += "-c " + str( setName )
4056 elif retain:
4057 cmdStr += "-r " + str( setName ) + " " + str( values )
4058 else:
4059 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004060 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004061 if clear:
4062 pattern = "Set " + str( setName ) + " cleared"
4063 if re.search( pattern, output ):
4064 return main.TRUE
4065 elif retain:
4066 positivePattern = str( setName ) + " was pruned to contain " +\
4067 "only elements of set \[(.*)\]"
4068 negativePattern = str( setName ) + " was not changed by " +\
4069 "retaining only elements of the set " +\
4070 "\[(.*)\]"
4071 if re.search( positivePattern, output ):
4072 return main.TRUE
4073 elif re.search( negativePattern, output ):
4074 return main.FALSE
4075 else:
4076 positivePattern = "\[(.*)\] was removed from the set " +\
4077 str( setName )
4078 if ( len( values.split() ) == 1 ):
4079 negativePattern = "\[(.*)\] was not in set " +\
4080 str( setName )
4081 else:
4082 negativePattern = "No element of \[(.*)\] was in set " +\
4083 str( setName )
4084 if re.search( positivePattern, output ):
4085 return main.TRUE
4086 elif re.search( negativePattern, output ):
4087 return main.FALSE
4088 main.log.error( self.name + ": setTestRemove did not" +
4089 " match expected output" )
4090 main.log.debug( self.name + " expected: " + pattern )
4091 main.log.debug( self.name + " actual: " + repr( output ) )
4092 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004093 except TypeError:
4094 main.log.exception( self.name + ": Object not as expected" )
4095 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004096 except Exception:
4097 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004098 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004099
4100 def setTestGet( self, setName, values="" ):
4101 """
4102 CLI command to get the elements in a distributed set.
4103 Required arguments:
4104 setName - The name of the set to remove from.
4105 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004106 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004107 returns:
4108 main.ERROR on error OR
4109 A list of elements in the set if no optional arguments are
4110 supplied OR
4111 A tuple containing the list then:
4112 main.FALSE if the given values are not in the set OR
4113 main.TRUE if the given values are in the set OR
4114 """
4115 try:
4116 values = str( values ).strip()
4117 setName = str( setName ).strip()
4118 length = len( values.split() )
4119 containsCheck = None
4120 # Patterns to match
4121 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004122 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004123 containsTrue = "Set " + setName + " contains the value " + values
4124 containsFalse = "Set " + setName + " did not contain the value " +\
4125 values
4126 containsAllTrue = "Set " + setName + " contains the the subset " +\
4127 setPattern
4128 containsAllFalse = "Set " + setName + " did not contain the the" +\
4129 " subset " + setPattern
4130
4131 cmdStr = "set-test-get "
4132 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004133 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004134 if length == 0:
4135 match = re.search( pattern, output )
4136 else: # if given values
4137 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004138 patternTrue = pattern + "\r\n" + containsTrue
4139 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004140 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004141 patternTrue = pattern + "\r\n" + containsAllTrue
4142 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004143 matchTrue = re.search( patternTrue, output )
4144 matchFalse = re.search( patternFalse, output )
4145 if matchTrue:
4146 containsCheck = main.TRUE
4147 match = matchTrue
4148 elif matchFalse:
4149 containsCheck = main.FALSE
4150 match = matchFalse
4151 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004152 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004153 "expected output" )
4154 main.log.debug( self.name + " expected: " + pattern )
4155 main.log.debug( self.name + " actual: " + repr( output ) )
4156 match = None
4157 if match:
4158 setMatch = match.group( 1 )
4159 if setMatch == '':
4160 setList = []
4161 else:
4162 setList = setMatch.split( ", " )
4163 if length > 0:
4164 return ( setList, containsCheck )
4165 else:
4166 return setList
4167 else: # no match
4168 main.log.error( self.name + ": setTestGet did not" +
4169 " match expected output" )
4170 main.log.debug( self.name + " expected: " + pattern )
4171 main.log.debug( self.name + " actual: " + repr( output ) )
4172 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004173 except TypeError:
4174 main.log.exception( self.name + ": Object not as expected" )
4175 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004176 except Exception:
4177 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004178 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004179
4180 def setTestSize( self, setName ):
4181 """
4182 CLI command to get the elements in a distributed set.
4183 Required arguments:
4184 setName - The name of the set to remove from.
4185 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004186 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004187 None on error
4188 """
4189 try:
4190 # TODO: Should this check against the number of elements returned
4191 # and then return true/false based on that?
4192 setName = str( setName ).strip()
4193 # Patterns to match
4194 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004195 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004196 setPattern
4197 cmdStr = "set-test-get -s "
4198 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004199 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004200 match = re.search( pattern, output )
4201 if match:
4202 setSize = int( match.group( 1 ) )
4203 setMatch = match.group( 2 )
4204 if len( setMatch.split() ) == setSize:
4205 main.log.info( "The size returned by " + self.name +
4206 " matches the number of elements in " +
4207 "the returned set" )
4208 else:
4209 main.log.error( "The size returned by " + self.name +
4210 " does not match the number of " +
4211 "elements in the returned set." )
4212 return setSize
4213 else: # no match
4214 main.log.error( self.name + ": setTestGet did not" +
4215 " match expected output" )
4216 main.log.debug( self.name + " expected: " + pattern )
4217 main.log.debug( self.name + " actual: " + repr( output ) )
4218 return None
Jon Hall390696c2015-05-05 17:13:41 -07004219 except TypeError:
4220 main.log.exception( self.name + ": Object not as expected" )
4221 return None
Jon Hall390696c2015-05-05 17:13:41 -07004222 except Exception:
4223 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004224 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004225
Jon Hall80daded2015-05-27 16:07:00 -07004226 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004227 """
4228 Command to list the various counters in the system.
4229 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004230 if jsonFormat, a string of the json object returned by the cli
4231 command
4232 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004233 None on error
4234 """
Jon Hall390696c2015-05-05 17:13:41 -07004235 try:
Jon Hall390696c2015-05-05 17:13:41 -07004236 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004237 if jsonFormat:
4238 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004239 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004240 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004241 assert "Command not found:" not in output, output
4242 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004243 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004244 return output
Jon Hall390696c2015-05-05 17:13:41 -07004245 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004246 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004247 return None
Jon Hall390696c2015-05-05 17:13:41 -07004248 except TypeError:
4249 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004250 return None
Jon Hall390696c2015-05-05 17:13:41 -07004251 except pexpect.EOF:
4252 main.log.error( self.name + ": EOF exception found" )
4253 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004254 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004255 except Exception:
4256 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004257 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004258
Jon Hall935db192016-04-19 00:22:04 -07004259 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004260 """
Jon Halle1a3b752015-07-22 13:02:46 -07004261 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004262 Required arguments:
4263 counter - The name of the counter to increment.
4264 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004265 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004266 returns:
4267 integer value of the counter or
4268 None on Error
4269 """
4270 try:
4271 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004272 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004273 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004274 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004275 if delta != 1:
4276 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004277 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004278 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004279 match = re.search( pattern, output )
4280 if match:
4281 return int( match.group( 1 ) )
4282 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004283 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004284 " match expected output." )
4285 main.log.debug( self.name + " expected: " + pattern )
4286 main.log.debug( self.name + " actual: " + repr( output ) )
4287 return None
Jon Hall390696c2015-05-05 17:13:41 -07004288 except TypeError:
4289 main.log.exception( self.name + ": Object not as expected" )
4290 return None
Jon Hall390696c2015-05-05 17:13:41 -07004291 except Exception:
4292 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004293 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004294
Jon Hall935db192016-04-19 00:22:04 -07004295 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004296 """
4297 CLI command to get a distributed counter then add a delta to it.
4298 Required arguments:
4299 counter - The name of the counter to increment.
4300 Optional arguments:
4301 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004302 returns:
4303 integer value of the counter or
4304 None on Error
4305 """
4306 try:
4307 counter = str( counter )
4308 delta = int( delta )
4309 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004310 cmdStr += counter
4311 if delta != 1:
4312 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004313 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004314 pattern = counter + " was updated to (-?\d+)"
4315 match = re.search( pattern, output )
4316 if match:
4317 return int( match.group( 1 ) )
4318 else:
4319 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4320 " match expected output." )
4321 main.log.debug( self.name + " expected: " + pattern )
4322 main.log.debug( self.name + " actual: " + repr( output ) )
4323 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004324 except TypeError:
4325 main.log.exception( self.name + ": Object not as expected" )
4326 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004327 except Exception:
4328 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004329 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004330
4331 def valueTestGet( self, valueName ):
4332 """
4333 CLI command to get the value of an atomic value.
4334 Required arguments:
4335 valueName - The name of the value to get.
4336 returns:
4337 string value of the value or
4338 None on Error
4339 """
4340 try:
4341 valueName = str( valueName )
4342 cmdStr = "value-test "
4343 operation = "get"
4344 cmdStr = "value-test {} {}".format( valueName,
4345 operation )
4346 output = self.distPrimitivesSend( cmdStr )
4347 pattern = "(\w+)"
4348 match = re.search( pattern, output )
4349 if match:
4350 return match.group( 1 )
4351 else:
4352 main.log.error( self.name + ": valueTestGet did not" +
4353 " match expected output." )
4354 main.log.debug( self.name + " expected: " + pattern )
4355 main.log.debug( self.name + " actual: " + repr( output ) )
4356 return None
4357 except TypeError:
4358 main.log.exception( self.name + ": Object not as expected" )
4359 return None
4360 except Exception:
4361 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004362 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004363
4364 def valueTestSet( self, valueName, newValue ):
4365 """
4366 CLI command to set the value of an atomic value.
4367 Required arguments:
4368 valueName - The name of the value to set.
4369 newValue - The value to assign to the given value.
4370 returns:
4371 main.TRUE on success or
4372 main.ERROR on Error
4373 """
4374 try:
4375 valueName = str( valueName )
4376 newValue = str( newValue )
4377 operation = "set"
4378 cmdStr = "value-test {} {} {}".format( valueName,
4379 operation,
4380 newValue )
4381 output = self.distPrimitivesSend( cmdStr )
4382 if output is not None:
4383 return main.TRUE
4384 else:
4385 return main.ERROR
4386 except TypeError:
4387 main.log.exception( self.name + ": Object not as expected" )
4388 return main.ERROR
4389 except Exception:
4390 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004391 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004392
4393 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4394 """
4395 CLI command to compareAndSet the value of an atomic value.
4396 Required arguments:
4397 valueName - The name of the value.
4398 oldValue - Compare the current value of the atomic value to this
4399 newValue - If the value equals oldValue, set the value to newValue
4400 returns:
4401 main.TRUE on success or
4402 main.FALSE on failure or
4403 main.ERROR on Error
4404 """
4405 try:
4406 valueName = str( valueName )
4407 oldValue = str( oldValue )
4408 newValue = str( newValue )
4409 operation = "compareAndSet"
4410 cmdStr = "value-test {} {} {} {}".format( valueName,
4411 operation,
4412 oldValue,
4413 newValue )
4414 output = self.distPrimitivesSend( cmdStr )
4415 pattern = "(\w+)"
4416 match = re.search( pattern, output )
4417 if match:
4418 result = match.group( 1 )
4419 if result == "true":
4420 return main.TRUE
4421 elif result == "false":
4422 return main.FALSE
4423 else:
4424 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4425 " match expected output." )
4426 main.log.debug( self.name + " expected: " + pattern )
4427 main.log.debug( self.name + " actual: " + repr( output ) )
4428 return main.ERROR
4429 except TypeError:
4430 main.log.exception( self.name + ": Object not as expected" )
4431 return main.ERROR
4432 except Exception:
4433 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004434 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004435
4436 def valueTestGetAndSet( self, valueName, newValue ):
4437 """
4438 CLI command to getAndSet the value of an atomic value.
4439 Required arguments:
4440 valueName - The name of the value to get.
4441 newValue - The value to assign to the given value
4442 returns:
4443 string value of the value or
4444 None on Error
4445 """
4446 try:
4447 valueName = str( valueName )
4448 cmdStr = "value-test "
4449 operation = "getAndSet"
4450 cmdStr += valueName + " " + operation
4451 cmdStr = "value-test {} {} {}".format( valueName,
4452 operation,
4453 newValue )
4454 output = self.distPrimitivesSend( cmdStr )
4455 pattern = "(\w+)"
4456 match = re.search( pattern, output )
4457 if match:
4458 return match.group( 1 )
4459 else:
4460 main.log.error( self.name + ": valueTestGetAndSet did not" +
4461 " match expected output." )
4462 main.log.debug( self.name + " expected: " + pattern )
4463 main.log.debug( self.name + " actual: " + repr( output ) )
4464 return None
4465 except TypeError:
4466 main.log.exception( self.name + ": Object not as expected" )
4467 return None
4468 except Exception:
4469 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004470 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004471
4472 def valueTestDestroy( self, valueName ):
4473 """
4474 CLI command to destroy an atomic value.
4475 Required arguments:
4476 valueName - The name of the value to destroy.
4477 returns:
4478 main.TRUE on success or
4479 main.ERROR on Error
4480 """
4481 try:
4482 valueName = str( valueName )
4483 cmdStr = "value-test "
4484 operation = "destroy"
4485 cmdStr += valueName + " " + operation
4486 output = self.distPrimitivesSend( cmdStr )
4487 if output is not None:
4488 return main.TRUE
4489 else:
4490 return main.ERROR
4491 except TypeError:
4492 main.log.exception( self.name + ": Object not as expected" )
4493 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004494 except Exception:
4495 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004496 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004497
YPZhangfebf7302016-05-24 16:45:56 -07004498 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004499 """
4500 Description: Execute summary command in onos
4501 Returns: json object ( summary -j ), returns main.FALSE if there is
4502 no output
4503
4504 """
4505 try:
4506 cmdStr = "summary"
4507 if jsonFormat:
4508 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004509 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004510 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004511 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004512 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004513 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004514 if not handle:
4515 main.log.error( self.name + ": There is no output in " +
4516 "summary command" )
4517 return main.FALSE
4518 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004519 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004520 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004521 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004522 except TypeError:
4523 main.log.exception( self.name + ": Object not as expected" )
4524 return None
4525 except pexpect.EOF:
4526 main.log.error( self.name + ": EOF exception found" )
4527 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004528 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004529 except Exception:
4530 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004531 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004532
Jon Hall935db192016-04-19 00:22:04 -07004533 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004534 """
4535 CLI command to get the value of a key in a consistent map using
4536 transactions. This a test function and can only get keys from the
4537 test map hard coded into the cli command
4538 Required arguments:
4539 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004540 returns:
4541 The string value of the key or
4542 None on Error
4543 """
4544 try:
4545 keyName = str( keyName )
4546 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004547 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004548 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004549 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4550 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004551 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004552 return None
4553 else:
4554 match = re.search( pattern, output )
4555 if match:
4556 return match.groupdict()[ 'value' ]
4557 else:
4558 main.log.error( self.name + ": transactionlMapGet did not" +
4559 " match expected output." )
4560 main.log.debug( self.name + " expected: " + pattern )
4561 main.log.debug( self.name + " actual: " + repr( output ) )
4562 return None
4563 except TypeError:
4564 main.log.exception( self.name + ": Object not as expected" )
4565 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004566 except Exception:
4567 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004568 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004569
Jon Hall935db192016-04-19 00:22:04 -07004570 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004571 """
4572 CLI command to put a value into 'numKeys' number of keys in a
4573 consistent map using transactions. This a test function and can only
4574 put into keys named 'Key#' of the test map hard coded into the cli command
4575 Required arguments:
4576 numKeys - Number of keys to add the value to
4577 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004578 returns:
4579 A dictionary whose keys are the name of the keys put into the map
4580 and the values of the keys are dictionaries whose key-values are
4581 'value': value put into map and optionaly
4582 'oldValue': Previous value in the key or
4583 None on Error
4584
4585 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004586 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4587 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004588 """
4589 try:
4590 numKeys = str( numKeys )
4591 value = str( value )
4592 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004593 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004594 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004595 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4596 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4597 results = {}
4598 for line in output.splitlines():
4599 new = re.search( newPattern, line )
4600 updated = re.search( updatedPattern, line )
4601 if new:
4602 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4603 elif updated:
4604 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004605 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004606 else:
4607 main.log.error( self.name + ": transactionlMapGet did not" +
4608 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004609 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4610 newPattern,
4611 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004612 main.log.debug( self.name + " actual: " + repr( output ) )
4613 return results
4614 except TypeError:
4615 main.log.exception( self.name + ": Object not as expected" )
4616 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004617 except Exception:
4618 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004619 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004620
acsmarsdaea66c2015-09-03 11:44:06 -07004621 def maps( self, jsonFormat=True ):
4622 """
4623 Description: Returns result of onos:maps
4624 Optional:
4625 * jsonFormat: enable json formatting of output
4626 """
4627 try:
4628 cmdStr = "maps"
4629 if jsonFormat:
4630 cmdStr += " -j"
4631 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004632 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004633 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004634 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004635 except AssertionError:
4636 main.log.exception( "" )
4637 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004638 except TypeError:
4639 main.log.exception( self.name + ": Object not as expected" )
4640 return None
4641 except pexpect.EOF:
4642 main.log.error( self.name + ": EOF exception found" )
4643 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004644 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004645 except Exception:
4646 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004647 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004648
4649 def getSwController( self, uri, jsonFormat=True ):
4650 """
4651 Descrition: Gets the controller information from the device
4652 """
4653 try:
4654 cmd = "device-controllers "
4655 if jsonFormat:
4656 cmd += "-j "
4657 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004658 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004659 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004660 return response
Jon Hallc6793552016-01-19 14:18:37 -08004661 except AssertionError:
4662 main.log.exception( "" )
4663 return None
GlennRC050596c2015-11-18 17:06:41 -08004664 except TypeError:
4665 main.log.exception( self.name + ": Object not as expected" )
4666 return None
4667 except pexpect.EOF:
4668 main.log.error( self.name + ": EOF exception found" )
4669 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004670 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004671 except Exception:
4672 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004673 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004674
4675 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4676 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004677 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08004678
4679 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004680 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08004681 ip - String or List: The ip address of the controller.
4682 This parameter can be formed in a couple of different ways.
4683 VALID:
4684 10.0.0.1 - just the ip address
4685 tcp:10.0.0.1 - the protocol and the ip address
4686 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4687 so that you can add controllers with different
4688 protocols and ports
4689 INVALID:
4690 10.0.0.1:6653 - this is not supported by ONOS
4691
4692 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4693 port - The port number.
4694 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4695
4696 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4697 """
4698 try:
4699 cmd = "device-setcontrollers"
4700
4701 if jsonFormat:
4702 cmd += " -j"
4703 cmd += " " + uri
4704 if isinstance( ip, str ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004705 ip = [ip]
GlennRC050596c2015-11-18 17:06:41 -08004706 for item in ip:
4707 if ":" in item:
4708 sitem = item.split( ":" )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004709 if len(sitem) == 3:
GlennRC050596c2015-11-18 17:06:41 -08004710 cmd += " " + item
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004711 elif "." in sitem[1]:
4712 cmd += " {}:{}".format(item, port)
GlennRC050596c2015-11-18 17:06:41 -08004713 else:
4714 main.log.error( "Malformed entry: " + item )
4715 raise TypeError
4716 else:
4717 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004718 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004719 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004720 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004721 if "Error" in response:
4722 main.log.error( response )
4723 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004724 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004725 except AssertionError:
4726 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004727 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004728 except TypeError:
4729 main.log.exception( self.name + ": Object not as expected" )
4730 return main.FALSE
4731 except pexpect.EOF:
4732 main.log.error( self.name + ": EOF exception found" )
4733 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004734 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004735 except Exception:
4736 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004737 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004738
4739 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004740 '''
GlennRC20fc6522015-12-23 23:26:57 -08004741 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004742 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08004743 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004744 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08004745 Returns:
4746 Returns main.FALSE if an exception is thrown or an error is present
4747 in the response. Otherwise, returns main.TRUE.
4748 NOTE:
4749 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004750 '''
GlennRC20fc6522015-12-23 23:26:57 -08004751 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004752 if type( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004753 deviceStr = device
4754 device = []
4755 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004756
4757 for d in device:
4758 time.sleep( 1 )
4759 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004760 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004761 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004762 if "Error" in response:
4763 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4764 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004765 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004766 except AssertionError:
4767 main.log.exception( "" )
4768 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004769 except TypeError:
4770 main.log.exception( self.name + ": Object not as expected" )
4771 return main.FALSE
4772 except pexpect.EOF:
4773 main.log.error( self.name + ": EOF exception found" )
4774 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004775 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004776 except Exception:
4777 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004778 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004779
4780 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004781 '''
GlennRC20fc6522015-12-23 23:26:57 -08004782 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004783 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08004784 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004785 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08004786 Returns:
4787 Returns main.FALSE if an exception is thrown or an error is present
4788 in the response. Otherwise, returns main.TRUE.
4789 NOTE:
4790 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004791 '''
GlennRC20fc6522015-12-23 23:26:57 -08004792 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004793 if type( host ) is str:
GlennRC20fc6522015-12-23 23:26:57 -08004794 host = list( host )
4795
4796 for h in host:
4797 time.sleep( 1 )
4798 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004799 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004800 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004801 if "Error" in response:
4802 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4803 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004804 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004805 except AssertionError:
4806 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004807 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004808 except TypeError:
4809 main.log.exception( self.name + ": Object not as expected" )
4810 return main.FALSE
4811 except pexpect.EOF:
4812 main.log.error( self.name + ": EOF exception found" )
4813 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004814 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004815 except Exception:
4816 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004817 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004818
YPZhangfebf7302016-05-24 16:45:56 -07004819 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004820 '''
GlennRCed771242016-01-13 17:02:47 -08004821 Description:
4822 Bring link down or up in the null-provider.
4823 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004824 begin - (string) One end of a device or switch.
4825 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08004826 returns:
4827 main.TRUE if no exceptions were thrown and no Errors are
4828 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004829 '''
GlennRCed771242016-01-13 17:02:47 -08004830 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004831 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004832 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004833 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004834 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004835 if "Error" in response or "Failure" in response:
4836 main.log.error( response )
4837 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004838 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004839 except AssertionError:
4840 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004841 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004842 except TypeError:
4843 main.log.exception( self.name + ": Object not as expected" )
4844 return main.FALSE
4845 except pexpect.EOF:
4846 main.log.error( self.name + ": EOF exception found" )
4847 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004848 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004849 except Exception:
4850 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004851 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004852
Jon Hall2c8959e2016-12-16 12:17:34 -08004853 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004854 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07004855 Description:
4856 Changes the state of port in an OF switch by means of the
4857 PORTSTATUS OF messages.
4858 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004859 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
4860 port - (string) target port in the device. Ex: '2'
4861 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07004862 returns:
4863 main.TRUE if no exceptions were thrown and no Errors are
4864 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004865 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07004866 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08004867 state = state.lower()
4868 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07004869 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07004870 response = self.sendline( cmd, showResponse=True )
4871 assert response is not None, "Error in sendline"
4872 assert "Command not found:" not in response, response
4873 if "Error" in response or "Failure" in response:
4874 main.log.error( response )
4875 return main.FALSE
4876 return main.TRUE
4877 except AssertionError:
4878 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004879 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07004880 except TypeError:
4881 main.log.exception( self.name + ": Object not as expected" )
4882 return main.FALSE
4883 except pexpect.EOF:
4884 main.log.error( self.name + ": EOF exception found" )
4885 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004886 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004887 except Exception:
4888 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004889 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004890
4891 def logSet( self, level="INFO", app="org.onosproject" ):
4892 """
4893 Set the logging level to lvl for a specific app
4894 returns main.TRUE on success
4895 returns main.FALSE if Error occurred
4896 if noExit is True, TestON will not exit, but clean up
4897 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4898 Level defaults to INFO
4899 """
4900 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004901 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07004902 self.handle.expect( "onos>" )
4903
4904 response = self.handle.before
4905 if re.search( "Error", response ):
4906 return main.FALSE
4907 return main.TRUE
4908 except pexpect.TIMEOUT:
4909 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07004910 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004911 except pexpect.EOF:
4912 main.log.error( self.name + ": EOF exception found" )
4913 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004914 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004915 except Exception:
4916 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004917 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004918
4919 def getGraphDict( self, timeout=60, includeHost=False ):
4920 """
4921 Return a dictionary which describes the latest network topology data as a
4922 graph.
4923 An example of the dictionary:
4924 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4925 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4926 Each vertex should at least have an 'edges' attribute which describes the
4927 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004928 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07004929 list of attributes.
4930 An example of the edges dictionary:
4931 'edges': { vertex2: { 'port': ..., 'weight': ... },
4932 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004933 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07004934 in topology data.
4935 """
4936 graphDict = {}
4937 try:
4938 links = self.links()
4939 links = json.loads( links )
4940 devices = self.devices()
4941 devices = json.loads( devices )
4942 idToDevice = {}
4943 for device in devices:
4944 idToDevice[ device[ 'id' ] ] = device
4945 if includeHost:
4946 hosts = self.hosts()
4947 # FIXME: support 'includeHost' argument
4948 for link in links:
4949 nodeA = link[ 'src' ][ 'device' ]
4950 nodeB = link[ 'dst' ][ 'device' ]
4951 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07004952 if nodeA not in graphDict.keys():
4953 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004954 'dpid': idToDevice[ nodeA ][ 'id' ][3:],
Jon Halle0f0b342017-04-18 11:43:47 -07004955 'type': idToDevice[ nodeA ][ 'type' ],
4956 'available': idToDevice[ nodeA ][ 'available' ],
4957 'role': idToDevice[ nodeA ][ 'role' ],
4958 'mfr': idToDevice[ nodeA ][ 'mfr' ],
4959 'hw': idToDevice[ nodeA ][ 'hw' ],
4960 'sw': idToDevice[ nodeA ][ 'sw' ],
4961 'serial': idToDevice[ nodeA ][ 'serial' ],
4962 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004963 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07004964 else:
4965 # Assert nodeB is not connected to any current links of nodeA
4966 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07004967 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
4968 'type': link[ 'type' ],
4969 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07004970 return graphDict
4971 except ( TypeError, ValueError ):
4972 main.log.exception( self.name + ": Object not as expected" )
4973 return None
4974 except KeyError:
4975 main.log.exception( self.name + ": KeyError exception found" )
4976 return None
4977 except AssertionError:
4978 main.log.exception( self.name + ": AssertionError exception found" )
4979 return None
4980 except pexpect.EOF:
4981 main.log.error( self.name + ": EOF exception found" )
4982 main.log.error( self.name + ": " + self.handle.before )
4983 return None
4984 except Exception:
4985 main.log.exception( self.name + ": Uncaught exception!" )
4986 return None
YPZhangcbc2a062016-07-11 10:55:44 -07004987
4988 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004989 '''
YPZhangcbc2a062016-07-11 10:55:44 -07004990 Send command to check intent-perf summary
4991 Returns: dictionary for intent-perf summary
4992 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004993 '''
YPZhangcbc2a062016-07-11 10:55:44 -07004994 cmd = "intent-perf -s"
4995 respDic = {}
4996 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08004997 assert resp is not None, "Error in sendline"
4998 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07004999 try:
5000 # Generate the dictionary to return
5001 for l in resp.split( "\n" ):
5002 # Delete any white space in line
5003 temp = re.sub( r'\s+', '', l )
5004 temp = temp.split( ":" )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005005 respDic[ temp[0] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005006
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005007 except (TypeError, ValueError):
YPZhangcbc2a062016-07-11 10:55:44 -07005008 main.log.exception( self.name + ": Object not as expected" )
5009 return None
5010 except KeyError:
5011 main.log.exception( self.name + ": KeyError exception found" )
5012 return None
5013 except AssertionError:
5014 main.log.exception( self.name + ": AssertionError exception found" )
5015 return None
5016 except pexpect.EOF:
5017 main.log.error( self.name + ": EOF exception found" )
5018 main.log.error( self.name + ": " + self.handle.before )
5019 return None
5020 except Exception:
5021 main.log.exception( self.name + ": Uncaught exception!" )
5022 return None
5023 return respDic
5024
Chiyu Chengec63bde2016-11-17 18:11:36 -08005025 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005026 """
5027 Searches the latest ONOS log file for the given search term and
5028 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005029
chengchiyu08303a02016-09-08 17:40:26 -07005030 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005031 searchTerm:
5032 The string to grep from the ONOS log.
5033 startLine:
5034 The term that decides which line is the start to search the searchTerm in
5035 the karaf log. For now, startTerm only works in 'first' mode.
5036 logNum:
5037 In some extreme cases, one karaf log is not big enough to contain all the
5038 information.Because of this, search mutiply logs is necessary to capture
5039 the right result. logNum is the number of karaf logs that we need to search
5040 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005041 mode:
5042 all: return all the strings that contain the search term
5043 last: return the last string that contains the search term
5044 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005045 num: return the number of times that the searchTerm appears in the log
5046 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005047 """
5048 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005049 assert type( searchTerm ) is str
Jon Halle0f0b342017-04-18 11:43:47 -07005050 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005051 logPath = '/opt/onos/log/karaf.log.'
5052 logPaths = '/opt/onos/log/karaf.log'
5053 for i in range( 1, logNum ):
5054 logPaths = logPath + str( i ) + " " + logPaths
5055 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005056 if startLine:
5057 # 100000000 is just a extreme large number to make sure this function can grep all the lines after startLine
5058 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005059 if mode == 'all':
5060 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005061 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005062 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005063 elif mode == 'first':
5064 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5065 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005066 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005067 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005068 return num
You Wang6d301d42017-04-21 10:49:33 -07005069 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005070 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005071 return int(totalLines)
You Wang6d301d42017-04-21 10:49:33 -07005072 else:
5073 main.log.error( self.name + " unsupported mode" )
5074 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005075 before = self.sendline( cmd )
5076 before = before.splitlines()
5077 # make sure the returned list only contains the search term
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005078 returnLines = [line for line in before if searchTerm in line]
chengchiyu08303a02016-09-08 17:40:26 -07005079 return returnLines
5080 except AssertionError:
5081 main.log.error( self.name + " searchTerm is not string type" )
5082 return None
5083 except pexpect.EOF:
5084 main.log.error( self.name + ": EOF exception found" )
5085 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005086 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005087 except pexpect.TIMEOUT:
5088 main.log.error( self.name + ": TIMEOUT exception found" )
5089 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005090 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005091 except Exception:
5092 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005093 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005094
5095 def vplsShow( self, jsonFormat=True ):
5096 """
5097 Description: Returns result of onos:vpls show, which should list the
5098 configured VPLS networks and the assigned interfaces.
5099 Optional:
5100 * jsonFormat: enable json formatting of output
5101 Returns:
5102 The output of the command or None on error.
5103 """
5104 try:
5105 cmdStr = "vpls show"
5106 if jsonFormat:
5107 raise NotImplementedError
5108 cmdStr += " -j"
5109 handle = self.sendline( cmdStr )
5110 assert handle is not None, "Error in sendline"
5111 assert "Command not found:" not in handle, handle
5112 return handle
5113 except AssertionError:
5114 main.log.exception( "" )
5115 return None
5116 except TypeError:
5117 main.log.exception( self.name + ": Object not as expected" )
5118 return None
5119 except pexpect.EOF:
5120 main.log.error( self.name + ": EOF exception found" )
5121 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005122 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005123 except NotImplementedError:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005124 main.log.exception( self.name + ": Json output not supported")
Jon Hall2c8959e2016-12-16 12:17:34 -08005125 return None
5126 except Exception:
5127 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005128 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005129
5130 def parseVplsShow( self ):
5131 """
5132 Parse the cli output of 'vpls show' into json output. This is required
5133 as there is currently no json output available.
5134 """
5135 try:
5136 output = []
5137 raw = self.vplsShow( jsonFormat=False )
5138 namePat = "VPLS name: (?P<name>\w+)"
5139 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5140 encapPat = "Encapsulation: (?P<encap>\w+)"
5141 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5142 mIter = re.finditer( pattern, raw )
5143 for match in mIter:
5144 item = {}
5145 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005146 ifaces = match.group( 'interfaces' ).split( ', ')
Jon Hall2c8959e2016-12-16 12:17:34 -08005147 if ifaces == [ "" ]:
5148 ifaces = []
5149 item[ 'interfaces' ] = ifaces
5150 encap = match.group( 'encap' )
5151 if encap != 'NONE':
5152 item[ 'encapsulation' ] = encap.lower()
5153 output.append( item )
5154 return output
5155 except Exception:
5156 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005157 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005158
5159 def vplsList( self, jsonFormat=True ):
5160 """
5161 Description: Returns result of onos:vpls list, which should list the
5162 configured VPLS networks.
5163 Optional:
5164 * jsonFormat: enable json formatting of output
5165 """
5166 try:
5167 cmdStr = "vpls list"
5168 if jsonFormat:
5169 raise NotImplementedError
5170 cmdStr += " -j"
5171 handle = self.sendline( cmdStr )
5172 assert handle is not None, "Error in sendline"
5173 assert "Command not found:" not in handle, handle
5174 return handle
5175 except AssertionError:
5176 main.log.exception( "" )
5177 return None
5178 except TypeError:
5179 main.log.exception( self.name + ": Object not as expected" )
5180 return None
5181 except pexpect.EOF:
5182 main.log.error( self.name + ": EOF exception found" )
5183 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005184 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005185 except NotImplementedError:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005186 main.log.exception( self.name + ": Json output not supported")
Jon Hall2c8959e2016-12-16 12:17:34 -08005187 return None
5188 except Exception:
5189 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005190 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005191
5192 def vplsCreate( self, network ):
5193 """
5194 CLI command to create a new VPLS network.
5195 Required arguments:
5196 network - String name of the network to create.
5197 returns:
5198 main.TRUE on success and main.FALSE on failure
5199 """
5200 try:
5201 network = str( network )
5202 cmdStr = "vpls create "
5203 cmdStr += network
5204 output = self.sendline( cmdStr )
5205 assert output is not None, "Error in sendline"
5206 assert "Command not found:" not in output, output
5207 assert "Error executing command" not in output, output
5208 assert "VPLS already exists:" not in output, output
5209 return main.TRUE
5210 except AssertionError:
5211 main.log.exception( "" )
5212 return main.FALSE
5213 except TypeError:
5214 main.log.exception( self.name + ": Object not as expected" )
5215 return main.FALSE
5216 except pexpect.EOF:
5217 main.log.error( self.name + ": EOF exception found" )
5218 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005219 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005220 except Exception:
5221 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005222 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005223
5224 def vplsDelete( self, network ):
5225 """
5226 CLI command to delete a VPLS network.
5227 Required arguments:
5228 network - Name of the network to delete.
5229 returns:
5230 main.TRUE on success and main.FALSE on failure
5231 """
5232 try:
5233 network = str( network )
5234 cmdStr = "vpls delete "
5235 cmdStr += network
5236 output = self.sendline( cmdStr )
5237 assert output is not None, "Error in sendline"
5238 assert "Command not found:" not in output, output
5239 assert "Error executing command" not in output, output
5240 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005241 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005242 return main.TRUE
5243 except AssertionError:
5244 main.log.exception( "" )
5245 return main.FALSE
5246 except TypeError:
5247 main.log.exception( self.name + ": Object not as expected" )
5248 return main.FALSE
5249 except pexpect.EOF:
5250 main.log.error( self.name + ": EOF exception found" )
5251 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005252 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005253 except Exception:
5254 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005255 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005256
5257 def vplsAddIface( self, network, iface ):
5258 """
5259 CLI command to add an interface to a VPLS network.
5260 Required arguments:
5261 network - Name of the network to add the interface to.
5262 iface - The ONOS name for an interface.
5263 returns:
5264 main.TRUE on success and main.FALSE on failure
5265 """
5266 try:
5267 network = str( network )
5268 iface = str( iface )
5269 cmdStr = "vpls add-if "
5270 cmdStr += network + " " + iface
5271 output = self.sendline( cmdStr )
5272 assert output is not None, "Error in sendline"
5273 assert "Command not found:" not in output, output
5274 assert "Error executing command" not in output, output
5275 assert "already associated to network" not in output, output
5276 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005277 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005278 return main.TRUE
5279 except AssertionError:
5280 main.log.exception( "" )
5281 return main.FALSE
5282 except TypeError:
5283 main.log.exception( self.name + ": Object not as expected" )
5284 return main.FALSE
5285 except pexpect.EOF:
5286 main.log.error( self.name + ": EOF exception found" )
5287 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005288 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005289 except Exception:
5290 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005291 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005292
5293 def vplsRemIface( self, network, iface ):
5294 """
5295 CLI command to remove an interface from a VPLS network.
5296 Required arguments:
5297 network - Name of the network to remove the interface from.
5298 iface - Name of the interface to remove.
5299 returns:
5300 main.TRUE on success and main.FALSE on failure
5301 """
5302 try:
5303 iface = str( iface )
5304 cmdStr = "vpls rem-if "
5305 cmdStr += network + " " + iface
5306 output = self.sendline( cmdStr )
5307 assert output is not None, "Error in sendline"
5308 assert "Command not found:" not in output, output
5309 assert "Error executing command" not in output, output
5310 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005311 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005312 return main.TRUE
5313 except AssertionError:
5314 main.log.exception( "" )
5315 return main.FALSE
5316 except TypeError:
5317 main.log.exception( self.name + ": Object not as expected" )
5318 return main.FALSE
5319 except pexpect.EOF:
5320 main.log.error( self.name + ": EOF exception found" )
5321 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005322 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005323 except Exception:
5324 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005325 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005326
5327 def vplsClean( self ):
5328 """
5329 Description: Clears the VPLS app configuration.
5330 Returns: main.TRUE on success and main.FALSE on failure
5331 """
5332 try:
5333 cmdStr = "vpls clean"
5334 handle = self.sendline( cmdStr )
5335 assert handle is not None, "Error in sendline"
5336 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005337 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005338 return handle
5339 except AssertionError:
5340 main.log.exception( "" )
5341 return main.FALSE
5342 except TypeError:
5343 main.log.exception( self.name + ": Object not as expected" )
5344 return main.FALSE
5345 except pexpect.EOF:
5346 main.log.error( self.name + ": EOF exception found" )
5347 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005348 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005349 except Exception:
5350 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005351 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005352
5353 def vplsSetEncap( self, network, encapType ):
5354 """
5355 CLI command to add an interface to a VPLS network.
5356 Required arguments:
5357 network - Name of the network to create.
5358 encapType - Type of encapsulation.
5359 returns:
5360 main.TRUE on success and main.FALSE on failure
5361 """
5362 try:
5363 network = str( network )
5364 encapType = str( encapType ).upper()
5365 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5366 cmdStr = "vpls set-encap "
5367 cmdStr += network + " " + encapType
5368 output = self.sendline( cmdStr )
5369 assert output is not None, "Error in sendline"
5370 assert "Command not found:" not in output, output
5371 assert "Error executing command" not in output, output
5372 assert "already associated to network" not in output, output
5373 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005374 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005375 return main.TRUE
5376 except AssertionError:
5377 main.log.exception( "" )
5378 return main.FALSE
5379 except TypeError:
5380 main.log.exception( self.name + ": Object not as expected" )
5381 return main.FALSE
5382 except pexpect.EOF:
5383 main.log.error( self.name + ": EOF exception found" )
5384 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005385 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005386 except Exception:
5387 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005388 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005389
5390 def interfaces( self, jsonFormat=True ):
5391 """
5392 Description: Returns result of interfaces command.
5393 Optional:
5394 * jsonFormat: enable json formatting of output
5395 Returns:
5396 The output of the command or None on error.
5397 """
5398 try:
5399 cmdStr = "interfaces"
5400 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005401 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005402 cmdStr += " -j"
5403 handle = self.sendline( cmdStr )
5404 assert handle is not None, "Error in sendline"
5405 assert "Command not found:" not in handle, handle
5406 return handle
5407 except AssertionError:
5408 main.log.exception( "" )
5409 return None
5410 except TypeError:
5411 main.log.exception( self.name + ": Object not as expected" )
5412 return None
5413 except pexpect.EOF:
5414 main.log.error( self.name + ": EOF exception found" )
5415 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005416 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005417 except NotImplementedError:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005418 main.log.exception( self.name + ": Json output not supported")
Jon Hall2c8959e2016-12-16 12:17:34 -08005419 return None
5420 except Exception:
5421 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005422 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005423
5424 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005425 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005426 Get the timestamp of searchTerm from karaf log.
5427
5428 Arguments:
5429 splitTerm_before and splitTerm_after:
5430
5431 The terms that split the string that contains the timeStamp of
5432 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5433 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5434 and the splitTerm_after is "x"
5435
5436 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005437 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005438 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005439 if logNum < 0:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005440 main.log.error("Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005441 return main.ERROR
5442 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005443 if len(lines) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005444 main.log.warn( "Captured timestamp string is empty" )
5445 return main.ERROR
5446 lines = lines[ 0 ]
5447 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005448 assert type(lines) is str
Chiyu Chengec63bde2016-11-17 18:11:36 -08005449 # get the target value
5450 line = lines.split( splitTerm_before )
5451 key = line[ 1 ].split( splitTerm_after )
5452 return int( key[ 0 ] )
5453 except IndexError:
5454 main.log.warn( "Index Error!" )
5455 return main.ERROR
5456 except AssertionError:
5457 main.log.warn( "Search Term Not Found " )
5458 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005459
5460 def workQueueAdd( self, queueName, value ):
5461 """
5462 CLI command to add a string to the specified Work Queue.
5463 This function uses the distributed primitives test app, which
5464 gives some cli access to distributed primitives for testing
5465 purposes only.
5466
5467 Required arguments:
5468 queueName - The name of the queue to add to
5469 value - The value to add to the queue
5470 returns:
5471 main.TRUE on success, main.FALSE on failure and
5472 main.ERROR on error.
5473 """
5474 try:
5475 queueName = str( queueName )
5476 value = str( value )
5477 prefix = "work-queue-test"
5478 operation = "add"
5479 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5480 output = self.distPrimitivesSend( cmdStr )
5481 if "Invalid operation name" in output:
5482 main.log.warn( output )
5483 return main.ERROR
5484 elif "Done" in output:
5485 return main.TRUE
5486 except TypeError:
5487 main.log.exception( self.name + ": Object not as expected" )
5488 return main.ERROR
5489 except Exception:
5490 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005491 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005492
5493 def workQueueAddMultiple( self, queueName, value1, value2 ):
5494 """
5495 CLI command to add two strings to the specified Work Queue.
5496 This function uses the distributed primitives test app, which
5497 gives some cli access to distributed primitives for testing
5498 purposes only.
5499
5500 Required arguments:
5501 queueName - The name of the queue to add to
5502 value1 - The first value to add to the queue
5503 value2 - The second value to add to the queue
5504 returns:
5505 main.TRUE on success, main.FALSE on failure and
5506 main.ERROR on error.
5507 """
5508 try:
5509 queueName = str( queueName )
5510 value1 = str( value1 )
5511 value2 = str( value2 )
5512 prefix = "work-queue-test"
5513 operation = "addMultiple"
5514 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5515 output = self.distPrimitivesSend( cmdStr )
5516 if "Invalid operation name" in output:
5517 main.log.warn( output )
5518 return main.ERROR
5519 elif "Done" in output:
5520 return main.TRUE
5521 except TypeError:
5522 main.log.exception( self.name + ": Object not as expected" )
5523 return main.ERROR
5524 except Exception:
5525 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005526 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005527
5528 def workQueueTakeAndComplete( self, queueName, number=1 ):
5529 """
5530 CLI command to take a value from the specified Work Queue and compelte it.
5531 This function uses the distributed primitives test app, which
5532 gives some cli access to distributed primitives for testing
5533 purposes only.
5534
5535 Required arguments:
5536 queueName - The name of the queue to add to
5537 number - The number of items to take and complete
5538 returns:
5539 main.TRUE on success, main.FALSE on failure and
5540 main.ERROR on error.
5541 """
5542 try:
5543 queueName = str( queueName )
5544 number = str( int( number ) )
5545 prefix = "work-queue-test"
5546 operation = "takeAndComplete"
5547 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5548 output = self.distPrimitivesSend( cmdStr )
5549 if "Invalid operation name" in output:
5550 main.log.warn( output )
5551 return main.ERROR
5552 elif "Done" in output:
5553 return main.TRUE
5554 except TypeError:
5555 main.log.exception( self.name + ": Object not as expected" )
5556 return main.ERROR
5557 except Exception:
5558 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005559 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005560
5561 def workQueueDestroy( self, queueName ):
5562 """
5563 CLI command to destroy the specified Work Queue.
5564 This function uses the distributed primitives test app, which
5565 gives some cli access to distributed primitives for testing
5566 purposes only.
5567
5568 Required arguments:
5569 queueName - The name of the queue to add to
5570 returns:
5571 main.TRUE on success, main.FALSE on failure and
5572 main.ERROR on error.
5573 """
5574 try:
5575 queueName = str( queueName )
5576 prefix = "work-queue-test"
5577 operation = "destroy"
5578 cmdStr = " ".join( [ prefix, queueName, operation ] )
5579 output = self.distPrimitivesSend( cmdStr )
5580 if "Invalid operation name" in output:
5581 main.log.warn( output )
5582 return main.ERROR
5583 return main.TRUE
5584 except TypeError:
5585 main.log.exception( self.name + ": Object not as expected" )
5586 return main.ERROR
5587 except Exception:
5588 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005589 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005590
5591 def workQueueTotalPending( self, queueName ):
5592 """
5593 CLI command to get the Total Pending items of the specified Work Queue.
5594 This function uses the distributed primitives test app, which
5595 gives some cli access to distributed primitives for testing
5596 purposes only.
5597
5598 Required arguments:
5599 queueName - The name of the queue to add to
5600 returns:
5601 The number of Pending items in the specified work queue or
5602 None on error
5603 """
5604 try:
5605 queueName = str( queueName )
5606 prefix = "work-queue-test"
5607 operation = "totalPending"
5608 cmdStr = " ".join( [ prefix, queueName, operation ] )
5609 output = self.distPrimitivesSend( cmdStr )
5610 pattern = r'\d+'
5611 if "Invalid operation name" in output:
5612 main.log.warn( output )
5613 return None
5614 else:
5615 match = re.search( pattern, output )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005616 return match.group(0)
Jon Halle0f0b342017-04-18 11:43:47 -07005617 except ( AttributeError, TypeError ):
5618 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5619 return None
5620 except Exception:
5621 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005622 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005623
5624 def workQueueTotalCompleted( self, queueName ):
5625 """
5626 CLI command to get the Total Completed items of the specified Work Queue.
5627 This function uses the distributed primitives test app, which
5628 gives some cli access to distributed primitives for testing
5629 purposes only.
5630
5631 Required arguments:
5632 queueName - The name of the queue to add to
5633 returns:
5634 The number of complete items in the specified work queue or
5635 None on error
5636 """
5637 try:
5638 queueName = str( queueName )
5639 prefix = "work-queue-test"
5640 operation = "totalCompleted"
5641 cmdStr = " ".join( [ prefix, queueName, operation ] )
5642 output = self.distPrimitivesSend( cmdStr )
5643 pattern = r'\d+'
5644 if "Invalid operation name" in output:
5645 main.log.warn( output )
5646 return None
5647 else:
5648 match = re.search( pattern, output )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005649 return match.group(0)
Jon Halle0f0b342017-04-18 11:43:47 -07005650 except ( AttributeError, TypeError ):
5651 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5652 return None
5653 except Exception:
5654 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005655 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005656
5657 def workQueueTotalInProgress( self, queueName ):
5658 """
5659 CLI command to get the Total In Progress items of 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 returns:
5667 The number of In Progress items in the specified work queue or
5668 None on error
5669 """
5670 try:
5671 queueName = str( queueName )
5672 prefix = "work-queue-test"
5673 operation = "totalInProgress"
5674 cmdStr = " ".join( [ prefix, queueName, operation ] )
5675 output = self.distPrimitivesSend( cmdStr )
5676 pattern = r'\d+'
5677 if "Invalid operation name" in output:
5678 main.log.warn( output )
5679 return None
5680 else:
5681 match = re.search( pattern, output )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005682 return match.group(0)
Jon Halle0f0b342017-04-18 11:43:47 -07005683 except ( AttributeError, TypeError ):
5684 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5685 return None
5686 except Exception:
5687 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005688 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00005689
5690 def events( self, args='-a' ):
5691 """
5692 Description: Returns events -a command output
5693 Optional:
5694 add other arguments
5695 """
5696 try:
5697 cmdStr = "events"
5698 if args:
5699 cmdStr += " " + args
5700 handle = self.sendline( cmdStr )
5701 assert handle is not None, "Error in sendline"
5702 assert "Command not found:" not in handle, handle
5703 return handle
5704 except AssertionError:
5705 main.log.exception( "" )
5706 return None
5707 except TypeError:
5708 main.log.exception( self.name + ": Object not as expected" )
5709 return None
5710 except pexpect.EOF:
5711 main.log.error( self.name + ": EOF exception found" )
5712 main.log.error( self.name + ": " + self.handle.before )
5713 main.cleanAndExit()
5714 except Exception:
5715 main.log.exception( self.name + ": Uncaught exception!" )
5716 main.cleanAndExit()
5717
5718 def getMaster( self, deviceID ):
5719 """
5720 Description: Obtains current master using "roles" command for a specific deviceID
5721 """
5722 try:
5723 return str( self.getRole( deviceID )[ 'master' ] )
5724 except AssertionError:
5725 main.log.exception( "" )
5726 return None
5727 except TypeError:
5728 main.log.exception( self.name + ": Object not as expected" )
5729 return None
5730 except pexpect.EOF:
5731 main.log.error( self.name + ": EOF exception found" )
5732 main.log.error( self.name + ": " + self.handle.before )
5733 main.cleanAndExit()
5734 except Exception:
5735 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07005736 main.cleanAndExit()
5737