blob: bafa284ab48f1596b670b1d18ed5d545f8c00734 [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
Jon Hall06fd0df2021-01-25 15:50:06 -08002# -*- coding: utf-8 -*-
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
Jon Hall06fd0df2021-01-25 15:50:06 -080061 self.karafPort = None
Jon Hall9b0de1f2020-08-24 15:38:04 -070062 self.karafTimeout = None
Jon Hall06fd0df2021-01-25 15:50:06 -080063 self.address = None
Siddesh52750622021-03-05 19:52:03 +000064 self.karafPromptUser = None
Jon Hall3c0114c2020-08-11 15:07:42 -070065 self.dockerPrompt = None
You Wangdb8cd0a2016-05-26 15:19:45 -070066 self.graph = Graph()
Devin Limdc78e202017-06-09 18:30:07 -070067 super( OnosCliDriver, self ).__init__()
kelvin8ec71442015-01-15 16:57:00 -080068
69 def connect( self, **connectargs ):
70 """
andrewonlab95ce8322014-10-13 14:12:04 -040071 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080072 """
andrewonlab95ce8322014-10-13 14:12:04 -040073 try:
74 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080075 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070076 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040077 for key in self.options:
78 if key == "home":
Devin Limdc78e202017-06-09 18:30:07 -070079 self.home = self.options[ key ]
80 elif key == "karaf_username":
81 self.karafUser = self.options[ key ]
82 elif key == "karaf_password":
83 self.karafPass = self.options[ key ]
Jon Hall3c0114c2020-08-11 15:07:42 -070084 elif key == "docker_prompt":
85 self.dockerPrompt = self.options[ key ]
Jon Hall9b0de1f2020-08-24 15:38:04 -070086 elif key == "karaf_timeout":
87 self.karafTimeout = self.options[ key ]
Jon Hall06fd0df2021-01-25 15:50:06 -080088 elif key == "karaf_port":
89 self.karafPort = self.options[ key ]
Siddesh52750622021-03-05 19:52:03 +000090 elif key == "karafPromptUser":
91 self.karafPromptUser = self.options[ key ]
Jeremy Ronquillo82705492017-10-18 14:19:55 -070092 self.home = self.checkOptions( self.home, "~/onos" )
93 self.karafUser = self.checkOptions( self.karafUser, self.user_name )
94 self.karafPass = self.checkOptions( self.karafPass, self.pwd )
Jon Hall06fd0df2021-01-25 15:50:06 -080095 self.karafPort = self.checkOptions( self.karafPort, 8101 )
Jon Hall3c0114c2020-08-11 15:07:42 -070096 self.dockerPrompt = self.checkOptions( self.dockerPrompt, "~/onos#" )
Jon Hall9b0de1f2020-08-24 15:38:04 -070097 self.karafTimeout = self.checkOptions( self.karafTimeout, 7200000 )
andrewonlab95ce8322014-10-13 14:12:04 -040098
Siddesh52750622021-03-05 19:52:03 +000099 self.karafPrompt = self.karafPromptUser + "@root >"
kelvin-onlaba4074292015-07-09 15:19:49 -0700100 for key in self.options:
101 if key == 'onosIp':
102 self.onosIp = self.options[ 'onosIp' ]
103 break
104
kelvin8ec71442015-01-15 16:57:00 -0800105 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -0700106
107 try:
Jon Hallc6793552016-01-19 14:18:37 -0800108 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -0700109 self.ip_address = os.getenv( str( self.ip_address ) )
110 else:
111 main.log.info( self.name +
112 ": Trying to connect to " +
113 self.ip_address )
114
115 except KeyError:
116 main.log.info( "Invalid host name," +
117 " connecting to local host instead" )
118 self.ip_address = 'localhost'
119 except Exception as inst:
120 main.log.error( "Uncaught exception: " + str( inst ) )
121
kelvin8ec71442015-01-15 16:57:00 -0800122 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -0800123 user_name=self.user_name,
124 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -0800125 port=self.port,
126 pwd=self.pwd,
127 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -0400128
kelvin8ec71442015-01-15 16:57:00 -0800129 self.handle.sendline( "cd " + self.home )
Devin Limdc78e202017-06-09 18:30:07 -0700130 self.handle.expect( self.prompt )
andrewonlab95ce8322014-10-13 14:12:04 -0400131 if self.handle:
Jon Hall06fd0df2021-01-25 15:50:06 -0800132 self.address = self.ip_address
andrewonlab95ce8322014-10-13 14:12:04 -0400133 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800134 else:
135 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -0400136 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800137 except TypeError:
138 main.log.exception( self.name + ": Object not as expected" )
139 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400140 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800141 main.log.error( self.name + ": EOF exception found" )
142 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700143 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800144 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800145 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700146 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400147
kelvin8ec71442015-01-15 16:57:00 -0800148 def disconnect( self ):
149 """
andrewonlab95ce8322014-10-13 14:12:04 -0400150 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800151 """
Jon Halld61331b2015-02-17 16:35:47 -0800152 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400153 try:
Jon Hall61282e32015-03-19 11:34:11 -0700154 if self.handle:
155 i = self.logout()
156 if i == main.TRUE:
157 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700158 for l in range( 3 ):
159 p = self.handle.expect( [ self.prompt, self.dockerPrompt ] )
160 if p == 1:
161 self.inDocker = False
162 self.handle.sendline( "exit" )
163 j = self.handle.expect( [ "closed", pexpect.TIMEOUT ], timeout=3 )
164 if j == 0:
165 return response
166 response = main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800167 except TypeError:
168 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800169 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400170 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800171 main.log.error( self.name + ": EOF exception found" )
172 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700173 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700174 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700175 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800176 except Exception:
Jon Hall3c0114c2020-08-11 15:07:42 -0700177 main.log.exception( self.name + ": disconnection failed from the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400178 response = main.FALSE
179 return response
180
kelvin8ec71442015-01-15 16:57:00 -0800181 def logout( self ):
182 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500183 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700184 Returns main.TRUE if exited CLI and
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000185 main.FALSE on timeout (not guranteed you are disconnected)
Jon Hall61282e32015-03-19 11:34:11 -0700186 None on TypeError
187 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800188 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500189 try:
Jon Hall61282e32015-03-19 11:34:11 -0700190 if self.handle:
191 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700192 i = self.handle.expect( [ self.karafPrompt,
193 self.Prompt(),
194 pexpect.TIMEOUT ],
195
Jon Hall61282e32015-03-19 11:34:11 -0700196 timeout=10 )
197 if i == 0: # In ONOS CLI
198 self.handle.sendline( "logout" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700199 j = self.handle.expect( [ self.Prompt(),
Jon Hallbfe00002016-04-05 10:23:54 -0700200 "Command not found:",
201 pexpect.TIMEOUT ] )
202 if j == 0: # Successfully logged out
203 return main.TRUE
204 elif j == 1 or j == 2:
205 # ONOS didn't fully load, and logout command isn't working
206 # or the command timed out
207 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700208 try:
Jon Hall3c0114c2020-08-11 15:07:42 -0700209 self.handle.expect( self.Prompt() )
Jon Hall64ab3bd2016-05-13 11:29:44 -0700210 except pexpect.TIMEOUT:
211 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700212 return main.TRUE
Jon Halle0f0b342017-04-18 11:43:47 -0700213 else: # some other output
Jon Hallbfe00002016-04-05 10:23:54 -0700214 main.log.warn( "Unknown repsonse to logout command: '{}'",
215 repr( self.handle.before ) )
216 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700217 elif i == 1: # not in CLI
218 return main.TRUE
steven30801e42f1fb2019-01-17 11:31:45 +0800219 elif i == 2: # Timeout
Jon Hall61282e32015-03-19 11:34:11 -0700220 return main.FALSE
221 else:
andrewonlab9627f432014-11-14 12:45:10 -0500222 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800223 except TypeError:
224 main.log.exception( self.name + ": Object not as expected" )
225 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500226 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800227 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700228 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700229 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700230 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700231 main.log.error( self.name +
232 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800233 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800234 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700235 main.cleanAndExit()
andrewonlab38d2b4a2014-11-13 16:28:47 -0500236
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800238 """
andrewonlab95ce8322014-10-13 14:12:04 -0400239 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800240
andrewonlab95ce8322014-10-13 14:12:04 -0400241 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800242 """
andrewonlab95ce8322014-10-13 14:12:04 -0400243 try:
244 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800245 main.log.error( "Must define cellname" )
Devin Lim44075962017-08-11 10:56:37 -0700246 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400247 else:
kelvin8ec71442015-01-15 16:57:00 -0800248 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800249 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800250 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400251 # and that this driver will have to change accordingly
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700252 self.handle.expect( str( cellname ) )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800253 handleBefore = self.handle.before
254 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800255 # Get the rest of the handle
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700256 self.handle.sendline( "" )
257 self.handle.expect( self.prompt )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800258 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400259
kelvin-onlabd3b64892015-01-20 13:26:24 -0800260 main.log.info( "Cell call returned: " + handleBefore +
261 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400262
263 return main.TRUE
264
Jon Halld4d4b372015-01-28 16:02:41 -0800265 except TypeError:
266 main.log.exception( self.name + ": Object not as expected" )
267 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400268 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800269 main.log.error( self.name + ": eof exception found" )
270 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700271 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800272 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800273 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700274 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -0800275
pingping-lin57a56ce2015-05-20 16:43:48 -0700276 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800277 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800278 """
Jon Hallefbd9792015-03-05 16:11:36 -0800279 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800280 by user would be used to set the current karaf shell idle timeout.
281 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800282 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800283 Below is an example to start a session with 60 seconds idle timeout
284 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800285
Hari Krishna25d42f72015-01-05 15:08:28 -0800286 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800287 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800288
kelvin-onlabd3b64892015-01-20 13:26:24 -0800289 Note: karafTimeout is left as str so that this could be read
290 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800291 """
You Wangf69ab392016-01-26 16:34:38 -0800292 self.onosIp = ONOSIp
Jon Hall06fd0df2021-01-25 15:50:06 -0800293 self.address = self.onosIp
andrewonlab95ce8322014-10-13 14:12:04 -0400294 try:
Jon Hall67253832016-12-05 09:47:13 -0800295 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800296 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700297 x = self.handle.expect( [ self.Prompt(), self.karafPrompt ], commandlineTimeout )
andrewonlab48829f62014-11-17 13:49:01 -0500298 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800299 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500300 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400301
Jon Hall67253832016-12-05 09:47:13 -0800302 # Not in CLI so login
Jon Hall3c0114c2020-08-11 15:07:42 -0700303 if self.inDocker:
304 # The Docker does not have all the wrapper scripts
Jon Hall06fd0df2021-01-25 15:50:06 -0800305 startCliCommand = "ssh -p %s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null %s@localhost" % ( self.karafPort, self.karafUser )
Jon Hall3c0114c2020-08-11 15:07:42 -0700306 elif waitForStart:
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800307 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
Jon Hall3c0114c2020-08-11 15:07:42 -0700308 startCliCommand = "onos-wait-for-start " + str( ONOSIp )
Chiyu Chengef109502016-11-21 15:51:38 -0800309 else:
Jon Hall3c0114c2020-08-11 15:07:42 -0700310 startCliCommand = "onos " + str( ONOSIp )
311 self.handle.sendline( startCliCommand )
312 tries = 0
Jon Hallf69e3162020-09-01 09:08:44 -0700313 timeoutSet = False
Jon Hall3c0114c2020-08-11 15:07:42 -0700314 while tries < 5:
315 i = self.handle.expect( [
316 self.karafPrompt,
317 "Password:",
318 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400319
andrewonlab3a7c3c72014-10-24 17:21:03 -0400320 if i == 0:
Jon Hallf69e3162020-09-01 09:08:44 -0700321 if not karafTimeout or timeoutSet:
Jon Hall9b0de1f2020-08-24 15:38:04 -0700322 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
323 return main.TRUE
Hari Krishnae36ef212015-01-04 14:09:13 -0800324 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800325 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800326 "config:property-set -p org.apache.karaf.shell\
Jon Hall3c0114c2020-08-11 15:07:42 -0700327 sshIdleTimeout " +
Jon Hall9b0de1f2020-08-24 15:38:04 -0700328 str( karafTimeout ) )
329 self.handle.expect( "closed by remote host" )
Jon Hallf69e3162020-09-01 09:08:44 -0700330 self.handle.expect( self.Prompt() )
Jon Hall9b0de1f2020-08-24 15:38:04 -0700331 self.handle.sendline( startCliCommand )
Jon Hallf69e3162020-09-01 09:08:44 -0700332 timeoutSet = True
Jon Hall3c0114c2020-08-11 15:07:42 -0700333 elif i == 1:
334 main.log.info( str( ONOSIp ) + " CLI asking for password" )
335 main.log.debug( "Sending %s" % self.karafPass )
336 self.handle.sendline( self.karafPass )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400337 else:
Jon Hall3c0114c2020-08-11 15:07:42 -0700338 # If failed, send ctrl+c to process and try again
339 main.log.info( "Starting CLI failed. Retrying..." )
Jon Hallf69e3162020-09-01 09:08:44 -0700340 time.sleep( 5 )
Jon Hall3c0114c2020-08-11 15:07:42 -0700341 self.handle.send( "\x03" )
342 self.handle.sendline( startCliCommand )
343 tries += 1
344 main.log.error( "Connection to CLI " + str( ONOSIp ) + " timeout" )
345 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800346 except TypeError:
347 main.log.exception( self.name + ": Object not as expected" )
348 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400349 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800350 main.log.error( self.name + ": EOF exception found" )
351 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700352 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800353 except Exception:
Jon Hall06fd0df2021-01-25 15:50:06 -0800354 main.log.debug( self.handle.before + str( self.handle.after ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800355 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700356 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400357
suibin zhang116647a2016-05-06 16:30:09 -0700358 def startCellCli( self, karafTimeout="",
359 commandlineTimeout=10, onosStartTimeout=60 ):
360 """
Jon Hall3c0114c2020-08-11 15:07:42 -0700361 Start CLI on onos cell handle.
suibin zhang116647a2016-05-06 16:30:09 -0700362
363 karafTimeout is an optional argument. karafTimeout value passed
364 by user would be used to set the current karaf shell idle timeout.
365 Note that when ever this property is modified the shell will exit and
366 the subsequent login would reflect new idle timeout.
367 Below is an example to start a session with 60 seconds idle timeout
368 ( input value is in milliseconds ):
369
370 tValue = "60000"
371
372 Note: karafTimeout is left as str so that this could be read
373 and passed to startOnosCli from PARAMS file as str.
374 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000375
suibin zhang116647a2016-05-06 16:30:09 -0700376 try:
377 self.handle.sendline( "" )
378 x = self.handle.expect( [
Jon Hall3c0114c2020-08-11 15:07:42 -0700379 self.Prompt(), self.karafPrompt ], commandlineTimeout )
suibin zhang116647a2016-05-06 16:30:09 -0700380
381 if x == 1:
382 main.log.info( "ONOS cli is already running" )
383 return main.TRUE
384
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800385 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
suibin zhang116647a2016-05-06 16:30:09 -0700386 self.handle.sendline( "/opt/onos/bin/onos" )
387 i = self.handle.expect( [
Jon Hall6c9e2da2018-11-06 12:01:23 -0800388 self.karafPrompt,
suibin zhang116647a2016-05-06 16:30:09 -0700389 pexpect.TIMEOUT ], onosStartTimeout )
390
391 if i == 0:
392 main.log.info( self.name + " CLI Started successfully" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800393 if karafTimeout: # FIXME: This doesn't look right
suibin zhang116647a2016-05-06 16:30:09 -0700394 self.handle.sendline(
395 "config:property-set -p org.apache.karaf.shell\
396 sshIdleTimeout " +
397 karafTimeout )
Jon Hall3c0114c2020-08-11 15:07:42 -0700398 self.handle.expect( self.Prompt() )
suibin zhang116647a2016-05-06 16:30:09 -0700399 self.handle.sendline( "/opt/onos/bin/onos" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800400 self.handle.expect( self.karafPrompt )
suibin zhang116647a2016-05-06 16:30:09 -0700401 return main.TRUE
402 else:
403 # If failed, send ctrl+c to process and try again
404 main.log.info( "Starting CLI failed. Retrying..." )
405 self.handle.send( "\x03" )
406 self.handle.sendline( "/opt/onos/bin/onos" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800407 i = self.handle.expect( [ self.karafPrompt, pexpect.TIMEOUT ],
suibin zhang116647a2016-05-06 16:30:09 -0700408 timeout=30 )
409 if i == 0:
410 main.log.info( self.name + " CLI Started " +
411 "successfully after retry attempt" )
412 if karafTimeout:
413 self.handle.sendline(
414 "config:property-set -p org.apache.karaf.shell\
415 sshIdleTimeout " +
416 karafTimeout )
Jon Hall3c0114c2020-08-11 15:07:42 -0700417 self.handle.expect( self.Prompt() )
suibin zhang116647a2016-05-06 16:30:09 -0700418 self.handle.sendline( "/opt/onos/bin/onos" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800419 self.handle.expect( self.karafPrompt )
suibin zhang116647a2016-05-06 16:30:09 -0700420 return main.TRUE
421 else:
422 main.log.error( "Connection to CLI " +
423 self.name + " timeout" )
424 return main.FALSE
425
426 except TypeError:
427 main.log.exception( self.name + ": Object not as expected" )
428 return None
429 except pexpect.EOF:
430 main.log.error( self.name + ": EOF exception found" )
431 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700432 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700433 except Exception:
434 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700435 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700436
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800437 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800438 """
You Wang22e807e2021-03-29 10:53:38 -0700439 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800440 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800441 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700442 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800443 Available level: DEBUG, TRACE, INFO, WARN, ERROR
444 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800445 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800446 """
447 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800448 lvlStr = ""
449 if level:
450 lvlStr = "--level=" + level
You Wang22e807e2021-03-29 10:53:38 -0700451 handle = self.sendline( "log:log " + lvlStr + " " + cmdStr, noExit=noExit )
452 assert handle is not None, "Error in sendline"
453 assert "Command not found:" not in handle, handle
454 if re.search( "Error", handle ):
455 main.log.error( self.name + ": Error in logging message" )
456 main.log.error( handle )
kelvin-onlab9f541032015-02-04 16:19:53 -0800457 return main.FALSE
YPZhangebf9eb52016-05-12 15:20:24 -0700458 else:
You Wang22e807e2021-03-29 10:53:38 -0700459 return main.TRUE
460 except AssertionError:
461 main.log.exception( "" )
462 return None
463 except TypeError:
464 main.log.exception( self.name + ": Object not as expected" )
465 return None
kelvin-onlab9f541032015-02-04 16:19:53 -0800466 except pexpect.EOF:
467 main.log.error( self.name + ": EOF exception found" )
468 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700469 if noExit:
470 main.cleanup()
471 return None
472 else:
Devin Lim44075962017-08-11 10:56:37 -0700473 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800474 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800475 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700476 if noExit:
477 main.cleanup()
478 return None
479 else:
Devin Lim44075962017-08-11 10:56:37 -0700480 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400481
Jon Hall0e240372018-05-02 11:21:57 -0700482 def clearBuffer( self, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800483 """
Jon Hall0e240372018-05-02 11:21:57 -0700484 Test cli connection and clear any left over output in the buffer
485 Optional Arguments:
486 debug - Defaults to False. If True, will enable debug logging.
487 timeout - Defaults to 10. Amount of time in seconds for a command to return
488 before a timeout.
489 noExit - Defaults to False. If True, will not exit TestON in the event of a
kelvin8ec71442015-01-15 16:57:00 -0800490 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400491 try:
Jon Halla495f562016-05-16 18:03:26 -0700492 # Try to reconnect if disconnected from cli
493 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700494 i = self.handle.expect( [ self.karafPrompt,
495 self.Prompt(),
496 pexpect.TIMEOUT ] )
Jon Hall0e240372018-05-02 11:21:57 -0700497 response = self.handle.before
Jon Halla495f562016-05-16 18:03:26 -0700498 if i == 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700499 main.log.error( self.name + ": onos cli session closed. " )
Jon Halla495f562016-05-16 18:03:26 -0700500 if self.onosIp:
501 main.log.warn( "Trying to reconnect " + self.onosIp )
502 reconnectResult = self.startOnosCli( self.onosIp )
503 if reconnectResult:
504 main.log.info( self.name + ": onos cli session reconnected." )
505 else:
506 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700507 if noExit:
508 return None
509 else:
Devin Lim44075962017-08-11 10:56:37 -0700510 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700511 else:
Devin Lim44075962017-08-11 10:56:37 -0700512 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700513 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700514 main.log.warn( "Timeout when testing cli responsiveness" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700515 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700516 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Hall6c9e2da2018-11-06 12:01:23 -0800517 self.handle.expect( self.karafPrompt )
Jon Halla495f562016-05-16 18:03:26 -0700518
Jon Hall0e240372018-05-02 11:21:57 -0700519 response += self.handle.before
Jon Hall14a03b52016-05-11 12:07:30 -0700520 if debug:
Jon Hall0e240372018-05-02 11:21:57 -0700521 main.log.debug( self.name + ": Raw output from sending ''" )
522 main.log.debug( self.name + ": " + repr( response ) )
523 except pexpect.TIMEOUT:
524 main.log.error( self.name + ": ONOS timeout" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700525 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
You Wang141b43b2018-06-26 16:50:18 -0700526 self.handle.send( "\x03" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800527 self.handle.expect( self.karafPrompt )
Jon Hall0e240372018-05-02 11:21:57 -0700528 return None
529 except pexpect.EOF:
530 main.log.error( self.name + ": EOF exception found" )
531 main.log.error( self.name + ": " + self.handle.before )
532 if noExit:
533 return None
534 else:
535 main.cleanAndExit()
536 except Exception:
537 main.log.exception( self.name + ": Uncaught exception!" )
538 if noExit:
539 return None
540 else:
541 main.cleanAndExit()
542
Jon Hall22e94ce2019-01-15 14:52:17 -0800543 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True, expectJson=False ):
Jon Hall0e240372018-05-02 11:21:57 -0700544 """
545 A wrapper around pexpect's sendline/expect. Will return all the output from a given command
546
547 Required Arguments:
548 cmdStr - String to send to the pexpect session
549
550 Optional Arguments:
551 showResponse - Defaults to False. If True will log the response.
552 debug - Defaults to False. If True, will enable debug logging.
553 timeout - Defaults to 10. Amount of time in seconds for a command to return
554 before a timeout.
555 noExit - Defaults to False. If True, will not exit TestON in the event of a
556 closed channel, but instead return None
Jon Hall6c9e2da2018-11-06 12:01:23 -0800557 relaxedRegex - Defaults to True. If there is a pipe in the command send, will only try to match the last part of the piped command.
Jon Hall0e240372018-05-02 11:21:57 -0700558
559 Warning: There are no sanity checking to commands sent using this method.
560
561 """
562 try:
563 # Try to reconnect if disconnected from cli
564 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
565 if debug:
566 # NOTE: This adds an average of .4 seconds per call
Jon Hall14a03b52016-05-11 12:07:30 -0700567 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700568 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800569 self.handle.sendline( cmdStr )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800570 self.handle.expect( self.karafPrompt, timeout )
Jon Hall63604932015-02-26 17:09:50 -0800571 response = self.handle.before
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000572 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
Jon Hallc6793552016-01-19 14:18:37 -0800573 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700574 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700575 main.log.debug( self.name + ": Raw output" )
576 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700577
Jon Hall3c0114c2020-08-11 15:07:42 -0700578 response = self.cleanOutput( response, debug=debug )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800579 # Remove control codes from karaf 4.2.1
Jon Hall3c0114c2020-08-11 15:07:42 -0700580 karafEscape = re.compile( r"('(0|1)~\'|\r\r\r\n\x1b\[A\x1b\[79C(x|\s)?|\x1b(>|=~?)|\x1b\[90m~)" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800581 response = karafEscape.sub( '', response )
582 if debug:
583 main.log.debug( self.name + ": karafEscape output" )
584 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700585 # Remove ANSI color control strings from output
Jon Hall43060f62020-06-23 13:13:33 -0700586 response = self.cleanOutput( response, debug )
Jon Hallc6358dd2015-04-10 12:44:28 -0700587
Jon Hall6c9e2da2018-11-06 12:01:23 -0800588 # Remove ANSI color control strings from output
Jon Hallcf31d0f2018-12-13 11:18:48 -0800589 # NOTE: karaf is sometimes adding a single character then two
590 # backspaces and sometimes adding 2 characters with 2 backspaces??
Jon Hall3c0114c2020-08-11 15:07:42 -0700591 backspaceEscape = re.compile( r'((.|\s)\x08)' )
592 unchanged = False
593 while not unchanged:
594 old = response
595 response = backspaceEscape.sub( '', response, count=1 )
596 if debug:
597 main.log.debug( self.name + ": backspaceEscape output" )
598 main.log.debug( self.name + ": " + repr( response ) )
599 unchanged = old == response
Jon Hall6c9e2da2018-11-06 12:01:23 -0800600
kelvin-onlabfb521662015-02-27 09:52:40 -0800601 # Remove extra return chars that get added
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000602 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700603 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700604 main.log.debug( self.name + ": Removed extra returns " +
605 "from output" )
606 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700607
608 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800609 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700610 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700611 main.log.debug( self.name + ": parsed and stripped output" )
612 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700613
Jon Hall63604932015-02-26 17:09:50 -0800614 # parse for just the output, remove the cmd from response
Jon Hallce0d70b2018-12-11 11:01:32 -0800615 cmdPattern = cmdStr.strip()
616 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
617 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800618 if relaxedRegex:
Jon Hallce0d70b2018-12-11 11:01:32 -0800619 cmdPattern = cmdPattern.split( '|' )[ -1 ].strip()
620 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
621 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800622 # This was added because karaf 4.2 is stripping some characters from the command echo
Jon Hallce0d70b2018-12-11 11:01:32 -0800623 output = response.split( cmdPattern, 1 )
Jon Hall22e94ce2019-01-15 14:52:17 -0800624 if expectJson:
625 main.log.warn( "Relaxed Regex: Searching for a json string amongst the output" )
626 jsonPattern = r'\{.*\}'
627 match = re.search( jsonPattern, output[ 0 ] )
628 if match:
629 output = [ '' , match.group( 0 ) ] # We expect a list with the second element to be the output
Jon Hall39e3ffe2018-12-05 11:40:29 -0800630 if len( output ) < 2:
631 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800632 cmdPattern = cmdPattern[ -5: ]
633 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
634 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
635 output = response.split( cmdPattern, 1 )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800636 else:
Jon Hallce0d70b2018-12-11 11:01:32 -0800637 output = response.split( cmdPattern, 1 )
638 if len( output ) < 2: # TODO: Should we do this without the relaxedRegex flag?
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800639 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800640 output = response.split( cmdPattern[ -5: ], 1 )
Jon Hall0e240372018-05-02 11:21:57 -0700641 if output:
642 if debug:
643 main.log.debug( self.name + ": split output" )
644 for r in output:
645 main.log.debug( self.name + ": " + repr( r ) )
Jon Hallce0d70b2018-12-11 11:01:32 -0800646 if len( output ) == 1:
647 main.log.error( "Could not remove sent command echo from output" )
648 return output
Jon Hall0e240372018-05-02 11:21:57 -0700649 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800650 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800651 main.log.info( "Response from ONOS: {}".format( output ) )
Jon Hall0e240372018-05-02 11:21:57 -0700652 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
GlennRC85870432015-11-23 11:45:51 -0800653 return output
GlennRCed771242016-01-13 17:02:47 -0800654 except pexpect.TIMEOUT:
Jon Hall0e240372018-05-02 11:21:57 -0700655 main.log.error( self.name + ": ONOS timeout" )
GlennRCed771242016-01-13 17:02:47 -0800656 if debug:
Jon Hall3c0114c2020-08-11 15:07:42 -0700657 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
You Wang6b5e5ba2019-01-31 15:32:40 -0800658 self.exitFromCmd( self.karafPrompt, 100 )
GlennRCed771242016-01-13 17:02:47 -0800659 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700660 except IndexError:
661 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700662 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700663 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800664 except TypeError:
665 main.log.exception( self.name + ": Object not as expected" )
666 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400667 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800668 main.log.error( self.name + ": EOF exception found" )
669 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700670 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700671 return None
672 else:
Devin Lim44075962017-08-11 10:56:37 -0700673 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800674 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800675 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700676 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700677 return None
678 else:
Devin Lim44075962017-08-11 10:56:37 -0700679 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400680
Jon Halld5a94fb2018-11-13 14:32:23 -0800681 def lineCount( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True ):
682 """
683 A wrapper around sendline(). Will return the number of lines returned or None on error
684
685 Required Arguments:
686 cmdStr - String to send to the pexpect session
687
688 Optional Arguments:
689 showResponse - Defaults to False. If True will log the response.
690 debug - Defaults to False. If True, will enable debug logging.
691 timeout - Defaults to 10. Amount of time in seconds for a command to return
692 before a timeout.
693 noExit - Defaults to False. If True, will not exit TestON in the event of a
694 closed channel, but instead return None
695 relaxedRegex - Defaults to True. If there is a pipe in the command send, will only try to match the last part of the piped command.
696
697 Warning: There are no sanity checking to commands sent using this method.
698
699 """
700 try:
701 numLines = self.sendline( cmdStr, showResponse, debug, timeout, noExit, relaxedRegex )
You Wang0ce8e0c2019-02-22 12:22:26 -0800702 parsed = re.search( "(\d+)", numLines )
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800703 if not parsed:
704 main.log.error( "Warning, output of karaf's wc may have changed" )
705 return None
706 return parsed.group( 1 )
Jon Halld5a94fb2018-11-13 14:32:23 -0800707 except IndexError:
708 main.log.exception( self.name + ": Object not as expected" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800709 main.log.debug( "response: {}".format( repr( numLines ) ) )
Jon Halld5a94fb2018-11-13 14:32:23 -0800710 return None
711 except TypeError:
712 main.log.exception( self.name + ": Object not as expected" )
713 return None
714 except Exception:
715 main.log.exception( self.name + ": Uncaught exception!" )
716 if noExit:
717 return None
718 else:
719 main.cleanAndExit()
720
kelvin8ec71442015-01-15 16:57:00 -0800721 # IMPORTANT NOTE:
722 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800723 # the cli command changing 'a:b' with 'aB'.
724 # Ex ) onos:topology > onosTopology
725 # onos:links > onosLinks
726 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800727
kelvin-onlabd3b64892015-01-20 13:26:24 -0800728 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800729 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400730 Adds a new cluster node by ID and address information.
731 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800732 * nodeId
733 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400734 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800735 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800736 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400737 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800738 cmdStr = "add-node " + str( nodeId ) + " " +\
739 str( ONOSIp ) + " " + str( tcpPort )
740 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700741 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800742 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800743 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700744 main.log.error( self.name + ": Error in adding node" )
kelvin8ec71442015-01-15 16:57:00 -0800745 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800746 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400747 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800748 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400749 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800750 except AssertionError:
751 main.log.exception( "" )
752 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800753 except TypeError:
754 main.log.exception( self.name + ": Object not as expected" )
755 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400756 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800757 main.log.error( self.name + ": EOF exception found" )
758 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700759 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800760 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800761 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700762 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400763
kelvin-onlabd3b64892015-01-20 13:26:24 -0800764 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800765 """
andrewonlab86dc3082014-10-13 18:18:38 -0400766 Removes a cluster by ID
767 Issues command: 'remove-node [<node-id>]'
768 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800769 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800770 """
andrewonlab86dc3082014-10-13 18:18:38 -0400771 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400772
kelvin-onlabd3b64892015-01-20 13:26:24 -0800773 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700774 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700775 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 ):
Jon Hall0e240372018-05-02 11:21:57 -0700778 main.log.error( self.name + ": Error in removing node" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700779 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
andrewonlab86dc3082014-10-13 18:18:38 -0400789 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()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400796
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700797 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800798 """
andrewonlab7c211572014-10-15 16:45:20 -0400799 List the nodes currently visible
800 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700801 Optional argument:
802 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800803 """
andrewonlab7c211572014-10-15 16:45:20 -0400804 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700805 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700806 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700807 cmdStr += " -j"
808 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700809 assert output is not None, "Error in sendline"
Jon Halle37bd1f2020-09-10 12:16:41 -0700810 # "Command not found" or "Service org.onosproject.security.AuditService not found"
811 assert "not found" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700812 return output
Jon Hallc6793552016-01-19 14:18:37 -0800813 except AssertionError:
814 main.log.exception( "" )
815 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800816 except TypeError:
817 main.log.exception( self.name + ": Object not as expected" )
818 return None
andrewonlab7c211572014-10-15 16:45:20 -0400819 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800820 main.log.error( self.name + ": EOF exception found" )
821 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700822 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800823 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800824 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700825 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400826
kelvin8ec71442015-01-15 16:57:00 -0800827 def topology( self ):
828 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700829 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700830 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700831 Return:
832 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800833 """
andrewonlab95ce8322014-10-13 14:12:04 -0400834 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700835 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800836 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800837 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800838 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700839 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400840 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800841 except AssertionError:
842 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800843 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800844 except TypeError:
845 main.log.exception( self.name + ": Object not as expected" )
846 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400847 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800848 main.log.error( self.name + ": EOF exception found" )
849 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700850 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800851 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800852 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700853 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800854
jenkins7ead5a82015-03-13 10:28:21 -0700855 def deviceRemove( self, deviceId ):
856 """
857 Removes particular device from storage
858
859 TODO: refactor this function
860 """
861 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700862 cmdStr = "device-remove " + str( deviceId )
863 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800864 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800865 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700866 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700867 main.log.error( self.name + ": Error in removing device" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700868 main.log.error( handle )
869 return main.FALSE
870 else:
871 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800872 except AssertionError:
873 main.log.exception( "" )
874 return None
jenkins7ead5a82015-03-13 10:28:21 -0700875 except TypeError:
876 main.log.exception( self.name + ": Object not as expected" )
877 return None
878 except pexpect.EOF:
879 main.log.error( self.name + ": EOF exception found" )
880 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700881 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700882 except Exception:
883 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700884 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700885
You Wang3b9689a2018-08-30 12:24:00 -0700886 def devices( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800887 """
Jon Hall7b02d952014-10-17 20:14:54 -0400888 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400889 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800890 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800891 """
andrewonlab86dc3082014-10-13 18:18:38 -0400892 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700893 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800894 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700895 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700896 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800897 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800898 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700899 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800900 except AssertionError:
901 main.log.exception( "" )
902 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800903 except TypeError:
904 main.log.exception( self.name + ": Object not as expected" )
905 return None
andrewonlab7c211572014-10-15 16:45:20 -0400906 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800907 main.log.error( self.name + ": EOF exception found" )
908 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700909 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800910 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800911 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700912 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400913
kelvin-onlabd3b64892015-01-20 13:26:24 -0800914 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800915 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800916 This balances the devices across all controllers
917 by issuing command: 'onos> onos:balance-masters'
918 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800919 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800920 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800921 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700922 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800923 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800924 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700925 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700926 main.log.error( self.name + ": Error in balancing masters" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700927 main.log.error( handle )
928 return main.FALSE
929 else:
930 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800931 except AssertionError:
932 main.log.exception( "" )
933 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800934 except TypeError:
935 main.log.exception( self.name + ": Object not as expected" )
936 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800937 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800938 main.log.error( self.name + ": EOF exception found" )
939 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700940 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800941 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800942 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700943 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800944
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000945 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700946 """
947 Returns the output of the masters command.
948 Optional argument:
949 * jsonFormat - boolean indicating if you want output in json
950 """
951 try:
952 cmdStr = "onos:masters"
953 if jsonFormat:
954 cmdStr += " -j"
955 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700956 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800957 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700958 return output
Jon Hallc6793552016-01-19 14:18:37 -0800959 except AssertionError:
960 main.log.exception( "" )
961 return None
acsmars24950022015-07-30 18:00:43 -0700962 except TypeError:
963 main.log.exception( self.name + ": Object not as expected" )
964 return None
965 except pexpect.EOF:
966 main.log.error( self.name + ": EOF exception found" )
967 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700968 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700969 except Exception:
970 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700971 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700972
Jon Hallc6793552016-01-19 14:18:37 -0800973 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700974 """
975 Uses the master command to check that the devices' leadership
976 is evenly divided
977
978 Dependencies: checkMasters() and summary()
979
Jon Hall6509dbf2016-06-21 17:01:17 -0700980 Returns main.TRUE if the devices are balanced
981 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700982 Exits on Exception
983 Returns None on TypeError
984 """
985 try:
Jon Hallc6793552016-01-19 14:18:37 -0800986 summaryOutput = self.summary()
987 totalDevices = json.loads( summaryOutput )[ "devices" ]
988 except ( TypeError, ValueError ):
989 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
990 return None
991 try:
acsmars24950022015-07-30 18:00:43 -0700992 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800993 mastersOutput = self.checkMasters()
994 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700995 first = masters[ 0 ][ "size" ]
996 for master in masters:
997 totalOwnedDevices += master[ "size" ]
998 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
999 main.log.error( "Mastership not balanced" )
1000 main.log.info( "\n" + self.checkMasters( False ) )
1001 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -07001002 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001003 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -07001004 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001005 except ( TypeError, ValueError ):
1006 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -07001007 return None
1008 except pexpect.EOF:
1009 main.log.error( self.name + ": EOF exception found" )
1010 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001011 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -07001012 except Exception:
1013 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001014 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -07001015
YPZhangfebf7302016-05-24 16:45:56 -07001016 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -08001017 """
Jon Halle8217482014-10-17 13:49:14 -04001018 Lists all core links
1019 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001020 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001021 """
Jon Halle8217482014-10-17 13:49:14 -04001022 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001023 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001024 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001025 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07001026 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001027 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001028 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001029 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001030 except AssertionError:
1031 main.log.exception( "" )
1032 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001033 except TypeError:
1034 main.log.exception( self.name + ": Object not as expected" )
1035 return None
Jon Halle8217482014-10-17 13:49:14 -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 Halle8217482014-10-17 13:49:14 -04001043
You Wang3b9689a2018-08-30 12:24:00 -07001044 def ports( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -08001045 """
Jon Halle8217482014-10-17 13:49:14 -04001046 Lists all ports
1047 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 Halle8217482014-10-17 13:49:14 -04001050 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001051 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001052 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001053 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -07001054 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001055 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001056 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001057 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001058 except AssertionError:
1059 main.log.exception( "" )
1060 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001061 except TypeError:
1062 main.log.exception( self.name + ": Object not as expected" )
1063 return None
Jon Halle8217482014-10-17 13:49:14 -04001064 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001065 main.log.error( self.name + ": EOF exception found" )
1066 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001067 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001068 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001069 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001070 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001071
kelvin-onlabd3b64892015-01-20 13:26:24 -08001072 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001073 """
Jon Hall983a1702014-10-28 18:44:22 -04001074 Lists all devices and the controllers with roles assigned to them
1075 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001076 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001077 """
andrewonlab7c211572014-10-15 16:45:20 -04001078 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001079 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001080 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001081 cmdStr += " -j"
1082 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001083 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001084 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001085 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001086 except AssertionError:
1087 main.log.exception( "" )
1088 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001089 except TypeError:
1090 main.log.exception( self.name + ": Object not as expected" )
1091 return None
Jon Hall983a1702014-10-28 18:44:22 -04001092 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001093 main.log.error( self.name + ": EOF exception found" )
1094 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001095 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001096 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001097 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001098 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -04001099
kelvin-onlabd3b64892015-01-20 13:26:24 -08001100 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001101 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001102 Given the a string containing the json representation of the "roles"
1103 cli command and a partial or whole device id, returns a json object
1104 containing the roles output for the first device whose id contains
1105 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -04001106
1107 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -08001108 A dict of the role assignments for the given device or
1109 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001110 """
Jon Hall983a1702014-10-28 18:44:22 -04001111 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001112 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001113 return None
1114 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001115 rawRoles = self.roles()
1116 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001117 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001118 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001119 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001120 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001121 return device
1122 return None
Jon Hallc6793552016-01-19 14:18:37 -08001123 except ( TypeError, ValueError ):
1124 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001125 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001126 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001127 main.log.error( self.name + ": EOF exception found" )
1128 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001129 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001130 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001131 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001132 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001133
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001135 """
Jon Hall94fd0472014-12-08 11:52:42 -08001136 Iterates through each device and checks if there is a master assigned
1137 Returns: main.TRUE if each device has a master
1138 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001139 """
Jon Hall94fd0472014-12-08 11:52:42 -08001140 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001141 rawRoles = self.roles()
1142 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001143 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001144 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001145 # print device
1146 if device[ 'master' ] == "none":
1147 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001148 return main.FALSE
1149 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001150 except ( TypeError, ValueError ):
1151 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001152 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001153 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001154 main.log.error( self.name + ": EOF exception found" )
1155 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001156 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001157 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001158 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001159 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001160
kelvin-onlabd3b64892015-01-20 13:26:24 -08001161 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001162 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001163 Returns string of paths, and the cost.
1164 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001165 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001166 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001167 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1168 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001169 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001170 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001171 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001172 main.log.error( self.name + ": Error in getting paths" )
kelvin8ec71442015-01-15 16:57:00 -08001173 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001174 else:
kelvin8ec71442015-01-15 16:57:00 -08001175 path = handle.split( ";" )[ 0 ]
1176 cost = handle.split( ";" )[ 1 ]
1177 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001178 except AssertionError:
1179 main.log.exception( "" )
1180 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001181 except TypeError:
1182 main.log.exception( self.name + ": Object not as expected" )
1183 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001184 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001185 main.log.error( self.name + ": EOF exception found" )
1186 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001187 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001188 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001189 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001190 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001191
kelvin-onlabd3b64892015-01-20 13:26:24 -08001192 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001193 """
Jon Hallffb386d2014-11-21 13:43:38 -08001194 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001195 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001196 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001197 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001198 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001199 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001200 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001201 cmdStr += " -j"
1202 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001203 if handle:
1204 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001205 # TODO: Maybe make this less hardcoded
1206 # ConsistentMap Exceptions
1207 assert "org.onosproject.store.service" not in handle
1208 # Node not leader
1209 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001210 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001211 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07001212 main.log.exception( self.name + ": Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001213 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001214 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001215 except TypeError:
1216 main.log.exception( self.name + ": Object not as expected" )
1217 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001218 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001219 main.log.error( self.name + ": EOF exception found" )
1220 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001221 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001222 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001223 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001224 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001225
kelvin-onlabd3b64892015-01-20 13:26:24 -08001226 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001227 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001228 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001229
Jon Hallefbd9792015-03-05 16:11:36 -08001230 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001231 partial mac address
1232
Jon Hall42db6dc2014-10-24 19:03:48 -04001233 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001234 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001235 try:
kelvin8ec71442015-01-15 16:57:00 -08001236 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001237 return None
1238 else:
1239 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001240 rawHosts = self.hosts()
1241 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001242 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001243 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001244 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001245 if not host:
1246 pass
1247 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001248 return host
1249 return None
Jon Hallc6793552016-01-19 14:18:37 -08001250 except ( TypeError, ValueError ):
1251 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001252 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001253 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001254 main.log.error( self.name + ": EOF exception found" )
1255 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001256 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001257 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001258 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001259 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001260
kelvin-onlabd3b64892015-01-20 13:26:24 -08001261 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001262 """
1263 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001264 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001265
andrewonlab3f0a4af2014-10-17 12:25:14 -04001266 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001267 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001268 IMPORTANT:
1269 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001270 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001271 Furthermore, it assumes that value of VLAN is '-1'
1272 Description:
kelvin8ec71442015-01-15 16:57:00 -08001273 Converts mininet hosts ( h1, h2, h3... ) into
1274 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1275 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001276 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001277 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001278
kelvin-onlabd3b64892015-01-20 13:26:24 -08001279 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001280 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001281 hostHex = hex( int( host ) ).zfill( 12 )
1282 hostHex = str( hostHex ).replace( 'x', '0' )
1283 i = iter( str( hostHex ) )
1284 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1285 hostHex = hostHex + "/-1"
1286 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001287
kelvin-onlabd3b64892015-01-20 13:26:24 -08001288 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001289
Jon Halld4d4b372015-01-28 16:02:41 -08001290 except TypeError:
1291 main.log.exception( self.name + ": Object not as expected" )
1292 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001293 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001294 main.log.error( self.name + ": EOF exception found" )
1295 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001296 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001297 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001298 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001299 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001300
You Wangbc898b82018-05-03 16:22:34 -07001301 def verifyHostLocation( self, hostIp, location ):
1302 """
1303 Description:
1304 Verify the host given is discovered in all locations expected
1305 Required:
1306 hostIp: IP address of the host
1307 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1308 Could be a string or list
1309 Returns:
1310 main.TRUE if host is discovered on all locations provided
1311 main.FALSE otherwise
1312 """
You Wangbc898b82018-05-03 16:22:34 -07001313 locations = [ location ] if isinstance( location, str ) else location
1314 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1315 try:
1316 hosts = self.hosts()
1317 hosts = json.loads( hosts )
1318 targetHost = None
1319 for host in hosts:
1320 if hostIp in host[ "ipAddresses" ]:
1321 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001322 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001323 result = main.TRUE
1324 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1325 for loc in locations:
1326 discovered = False
1327 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001328 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1329 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001330 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001331 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001332 break
1333 if discovered:
1334 locationsDiscovered.remove( locDiscovered )
1335 else:
1336 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1337 result = main.FALSE
1338 if locationsDiscovered:
1339 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1340 result = main.FALSE
1341 return result
1342 except KeyError:
1343 main.log.exception( self.name + ": host data not as expected: " + hosts )
1344 return None
1345 except pexpect.EOF:
1346 main.log.error( self.name + ": EOF exception found" )
1347 main.log.error( self.name + ": " + self.handle.before )
1348 main.cleanAndExit()
1349 except Exception:
1350 main.log.exception( self.name + ": Uncaught exception" )
1351 return None
1352
You Wang53dba1e2018-02-02 17:45:44 -08001353 def verifyHostIp( self, hostList=[], prefix="" ):
1354 """
1355 Description:
1356 Verify that all hosts have IP address assigned to them
1357 Optional:
1358 hostList: If specified, verifications only happen to the hosts
1359 in hostList
1360 prefix: at least one of the ip address assigned to the host
1361 needs to have the specified prefix
1362 Returns:
1363 main.TRUE if all hosts have specific IP address assigned;
1364 main.FALSE otherwise
1365 """
You Wang53dba1e2018-02-02 17:45:44 -08001366 try:
1367 hosts = self.hosts()
1368 hosts = json.loads( hosts )
1369 if not hostList:
1370 hostList = [ host[ "id" ] for host in hosts ]
1371 for host in hosts:
1372 hostId = host[ "id" ]
1373 if hostId not in hostList:
1374 continue
1375 ipList = host[ "ipAddresses" ]
1376 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1377 if not ipList:
1378 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1379 else:
1380 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1381 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1382 else:
1383 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1384 hostList.remove( hostId )
1385 if hostList:
1386 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
Jon Hall43060f62020-06-23 13:13:33 -07001387 # Print info for debugging
1388 main.log.debug( self.name + ": hosts output: " + str( hosts ) )
You Wang53dba1e2018-02-02 17:45:44 -08001389 return main.FALSE
1390 else:
1391 return main.TRUE
1392 except KeyError:
1393 main.log.exception( self.name + ": host data not as expected: " + hosts )
1394 return None
1395 except pexpect.EOF:
1396 main.log.error( self.name + ": EOF exception found" )
1397 main.log.error( self.name + ": " + self.handle.before )
1398 main.cleanAndExit()
1399 except Exception:
1400 main.log.exception( self.name + ": Uncaught exception" )
1401 return None
1402
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001403 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001404 """
andrewonlabe6745342014-10-17 14:29:13 -04001405 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001406 * hostIdOne: ONOS host id for host1
1407 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001408 Optional:
1409 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001410 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001411 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001412 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001413 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001414 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001415 Returns:
1416 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001417 """
andrewonlabe6745342014-10-17 14:29:13 -04001418 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001419 cmdStr = "add-host-intent "
1420 if vlanId:
1421 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001422 if setVlan:
1423 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001424 if encap:
1425 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001426 if bandwidth:
1427 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001428 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001429 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001430 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001431 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001432 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001433 main.log.error( self.name + ": Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001434 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001435 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001436 else:
1437 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001438 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001439 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001440 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001441 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001442 else:
1443 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001444 main.log.debug( "Response from ONOS was: " +
1445 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001446 return None
Jon Hallc6793552016-01-19 14:18:37 -08001447 except AssertionError:
1448 main.log.exception( "" )
1449 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001450 except TypeError:
1451 main.log.exception( self.name + ": Object not as expected" )
1452 return None
andrewonlabe6745342014-10-17 14:29:13 -04001453 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001454 main.log.error( self.name + ": EOF exception found" )
1455 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001456 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001457 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001458 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001459 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001460
kelvin-onlabd3b64892015-01-20 13:26:24 -08001461 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001462 """
andrewonlab7b31d232014-10-24 13:31:47 -04001463 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001464 * ingressDevice: device id of ingress device
1465 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001466 Optional:
1467 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001468 Description:
1469 Adds an optical intent by specifying an ingress and egress device
1470 Returns:
1471 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001472 """
andrewonlab7b31d232014-10-24 13:31:47 -04001473 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001474 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1475 " " + str( egressDevice )
1476 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001477 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001478 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001479 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001480 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001481 main.log.error( self.name + ": Error in adding Optical intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001482 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001483 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001484 main.log.info( "Optical intent installed between " +
1485 str( ingressDevice ) + " and " +
1486 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001487 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001488 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001489 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001490 else:
1491 main.log.error( "Error, intent ID not found" )
1492 return None
Jon Hallc6793552016-01-19 14:18:37 -08001493 except AssertionError:
1494 main.log.exception( "" )
1495 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001496 except TypeError:
1497 main.log.exception( self.name + ": Object not as expected" )
1498 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001499 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001500 main.log.error( self.name + ": EOF exception found" )
1501 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001502 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001503 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001504 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001505 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001506
kelvin-onlabd3b64892015-01-20 13:26:24 -08001507 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001508 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001509 ingressDevice,
1510 egressDevice,
1511 portIngress="",
1512 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001513 ethType="",
1514 ethSrc="",
1515 ethDst="",
1516 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001517 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001518 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001519 ipProto="",
1520 ipSrc="",
1521 ipDst="",
1522 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001523 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001524 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001525 setVlan="",
1526 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001527 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001528 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001529 * ingressDevice: device id of ingress device
1530 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001531 Optional:
1532 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001533 * ethSrc: specify ethSrc ( i.e. src mac addr )
1534 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001535 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001536 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001537 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001538 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001539 * ipSrc: specify ip source address
1540 * ipDst: specify ip destination address
1541 * tcpSrc: specify tcp source port
1542 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001543 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001544 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001545 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001546 Description:
kelvin8ec71442015-01-15 16:57:00 -08001547 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001548 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001549 Returns:
1550 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001551
Jon Halle3f39ff2015-01-13 11:50:53 -08001552 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001553 options developers provide for point-to-point
1554 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001555 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001556 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001557 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001558
Jeremy Songsterff553672016-05-12 17:06:23 -07001559 if ethType:
1560 cmd += " --ethType " + str( ethType )
1561 if ethSrc:
1562 cmd += " --ethSrc " + str( ethSrc )
1563 if ethDst:
1564 cmd += " --ethDst " + str( ethDst )
1565 if bandwidth:
1566 cmd += " --bandwidth " + str( bandwidth )
1567 if lambdaAlloc:
1568 cmd += " --lambda "
1569 if ipProto:
1570 cmd += " --ipProto " + str( ipProto )
1571 if ipSrc:
1572 cmd += " --ipSrc " + str( ipSrc )
1573 if ipDst:
1574 cmd += " --ipDst " + str( ipDst )
1575 if tcpSrc:
1576 cmd += " --tcpSrc " + str( tcpSrc )
1577 if tcpDst:
1578 cmd += " --tcpDst " + str( tcpDst )
1579 if vlanId:
1580 cmd += " -v " + str( vlanId )
1581 if setVlan:
1582 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001583 if encap:
1584 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001585 if protected:
1586 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001587
kelvin8ec71442015-01-15 16:57:00 -08001588 # Check whether the user appended the port
1589 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001590 if "/" in ingressDevice:
1591 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001592 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001593 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001594 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001595 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001596 # Would it make sense to throw an exception and exit
1597 # the test?
1598 return None
andrewonlab36af3822014-11-18 17:48:18 -05001599
kelvin8ec71442015-01-15 16:57:00 -08001600 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001601 str( ingressDevice ) + "/" +\
1602 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001603
kelvin-onlabd3b64892015-01-20 13:26:24 -08001604 if "/" in egressDevice:
1605 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001606 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001607 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001608 main.log.error( "You must specify the egress port" )
1609 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001610
kelvin8ec71442015-01-15 16:57:00 -08001611 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001612 str( egressDevice ) + "/" +\
1613 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001614
kelvin-onlab898a6c62015-01-16 14:13:53 -08001615 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001616 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001617 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001618 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001619 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001620 main.log.error( self.name + ": Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001621 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001622 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001623 # TODO: print out all the options in this message?
1624 main.log.info( "Point-to-point intent installed between " +
1625 str( ingressDevice ) + " and " +
1626 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001627 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001628 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001629 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001630 else:
1631 main.log.error( "Error, intent ID not found" )
1632 return None
Jon Hallc6793552016-01-19 14:18:37 -08001633 except AssertionError:
1634 main.log.exception( "" )
1635 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001636 except TypeError:
1637 main.log.exception( self.name + ": Object not as expected" )
1638 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001639 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001640 main.log.error( self.name + ": EOF exception found" )
1641 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001642 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001643 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001644 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001645 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001646
kelvin-onlabd3b64892015-01-20 13:26:24 -08001647 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001648 self,
shahshreyac2f97072015-03-19 17:04:29 -07001649 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001650 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001651 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001652 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001653 ethType="",
1654 ethSrc="",
1655 ethDst="",
1656 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001657 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001658 ipProto="",
1659 ipSrc="",
1660 ipDst="",
1661 tcpSrc="",
1662 tcpDst="",
1663 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001664 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001665 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001666 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001667 partial=False,
1668 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001669 """
shahshreyad0c80432014-12-04 16:56:05 -08001670 Note:
shahshreya70622b12015-03-19 17:19:00 -07001671 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001672 is same. That is, all ingress devices include port numbers
1673 with a "/" or all ingress devices could specify device
1674 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001675 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001676 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001677 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001678 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001679 Optional:
1680 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001681 * ethSrc: specify ethSrc ( i.e. src mac addr )
1682 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001683 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001684 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001685 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001686 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001687 * ipSrc: specify ip source address
1688 * ipDst: specify ip destination address
1689 * tcpSrc: specify tcp source port
1690 * tcpDst: specify tcp destination port
1691 * setEthSrc: action to Rewrite Source MAC Address
1692 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001693 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001694 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001695 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001696 Description:
kelvin8ec71442015-01-15 16:57:00 -08001697 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001698 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001699 Returns:
1700 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001701
Jon Halle3f39ff2015-01-13 11:50:53 -08001702 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001703 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001704 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001705 """
shahshreyad0c80432014-12-04 16:56:05 -08001706 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001707 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001708
Jeremy Songsterff553672016-05-12 17:06:23 -07001709 if ethType:
1710 cmd += " --ethType " + str( ethType )
1711 if ethSrc:
1712 cmd += " --ethSrc " + str( ethSrc )
1713 if ethDst:
1714 cmd += " --ethDst " + str( ethDst )
1715 if bandwidth:
1716 cmd += " --bandwidth " + str( bandwidth )
1717 if lambdaAlloc:
1718 cmd += " --lambda "
1719 if ipProto:
1720 cmd += " --ipProto " + str( ipProto )
1721 if ipSrc:
1722 cmd += " --ipSrc " + str( ipSrc )
1723 if ipDst:
1724 cmd += " --ipDst " + str( ipDst )
1725 if tcpSrc:
1726 cmd += " --tcpSrc " + str( tcpSrc )
1727 if tcpDst:
1728 cmd += " --tcpDst " + str( tcpDst )
1729 if setEthSrc:
1730 cmd += " --setEthSrc " + str( setEthSrc )
1731 if setEthDst:
1732 cmd += " --setEthDst " + str( setEthDst )
1733 if vlanId:
1734 cmd += " -v " + str( vlanId )
1735 if setVlan:
1736 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001737 if partial:
1738 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001739 if encap:
1740 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001741
kelvin8ec71442015-01-15 16:57:00 -08001742 # Check whether the user appended the port
1743 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001744
1745 if portIngressList is None:
1746 for ingressDevice in ingressDeviceList:
1747 if "/" in ingressDevice:
1748 cmd += " " + str( ingressDevice )
1749 else:
1750 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001751 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001752 # TODO: perhaps more meaningful return
1753 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001754 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001755 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001756 for ingressDevice, portIngress in zip( ingressDeviceList,
1757 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001758 cmd += " " + \
1759 str( ingressDevice ) + "/" +\
1760 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001761 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001762 main.log.error( "Device list and port list does not " +
1763 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001764 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001765 if "/" in egressDevice:
1766 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001767 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001768 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001769 main.log.error( "You must specify " +
1770 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001771 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001772
kelvin8ec71442015-01-15 16:57:00 -08001773 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001774 str( egressDevice ) + "/" +\
1775 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001776 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001777 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001778 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001779 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001780 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001781 main.log.error( self.name + ": Error in adding multipoint-to-singlepoint " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001782 "intent" )
1783 return None
shahshreyad0c80432014-12-04 16:56:05 -08001784 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001785 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001786 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001787 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001788 else:
1789 main.log.error( "Error, intent ID not found" )
1790 return None
Jon Hallc6793552016-01-19 14:18:37 -08001791 except AssertionError:
1792 main.log.exception( "" )
1793 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001794 except TypeError:
1795 main.log.exception( self.name + ": Object not as expected" )
1796 return None
1797 except pexpect.EOF:
1798 main.log.error( self.name + ": EOF exception found" )
1799 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001800 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001801 except Exception:
1802 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001803 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001804
1805 def addSinglepointToMultipointIntent(
1806 self,
1807 ingressDevice,
1808 egressDeviceList,
1809 portIngress="",
1810 portEgressList=None,
1811 ethType="",
1812 ethSrc="",
1813 ethDst="",
1814 bandwidth="",
1815 lambdaAlloc=False,
1816 ipProto="",
1817 ipSrc="",
1818 ipDst="",
1819 tcpSrc="",
1820 tcpDst="",
1821 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001822 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001823 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001824 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001825 partial=False,
1826 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001827 """
1828 Note:
1829 This function assumes the format of all egress devices
1830 is same. That is, all egress devices include port numbers
1831 with a "/" or all egress devices could specify device
1832 ids and port numbers seperately.
1833 Required:
1834 * EgressDeviceList: List of device ids of egress device
1835 ( Atleast 2 eress devices required in the list )
1836 * ingressDevice: device id of ingress device
1837 Optional:
1838 * ethType: specify ethType
1839 * ethSrc: specify ethSrc ( i.e. src mac addr )
1840 * ethDst: specify ethDst ( i.e. dst mac addr )
1841 * bandwidth: specify bandwidth capacity of link
1842 * lambdaAlloc: if True, intent will allocate lambda
1843 for the specified intent
1844 * ipProto: specify ip protocol
1845 * ipSrc: specify ip source address
1846 * ipDst: specify ip destination address
1847 * tcpSrc: specify tcp source port
1848 * tcpDst: specify tcp destination port
1849 * setEthSrc: action to Rewrite Source MAC Address
1850 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001851 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001852 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001853 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001854 Description:
1855 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1856 specifying device id's and optional fields
1857 Returns:
1858 A string of the intent id or None on error
1859
1860 NOTE: This function may change depending on the
1861 options developers provide for singlepoint-to-multipoint
1862 intent via cli
1863 """
1864 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001865 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001866
Jeremy Songsterff553672016-05-12 17:06:23 -07001867 if ethType:
1868 cmd += " --ethType " + str( ethType )
1869 if ethSrc:
1870 cmd += " --ethSrc " + str( ethSrc )
1871 if ethDst:
1872 cmd += " --ethDst " + str( ethDst )
1873 if bandwidth:
1874 cmd += " --bandwidth " + str( bandwidth )
1875 if lambdaAlloc:
1876 cmd += " --lambda "
1877 if ipProto:
1878 cmd += " --ipProto " + str( ipProto )
1879 if ipSrc:
1880 cmd += " --ipSrc " + str( ipSrc )
1881 if ipDst:
1882 cmd += " --ipDst " + str( ipDst )
1883 if tcpSrc:
1884 cmd += " --tcpSrc " + str( tcpSrc )
1885 if tcpDst:
1886 cmd += " --tcpDst " + str( tcpDst )
1887 if setEthSrc:
1888 cmd += " --setEthSrc " + str( setEthSrc )
1889 if setEthDst:
1890 cmd += " --setEthDst " + str( setEthDst )
1891 if vlanId:
1892 cmd += " -v " + str( vlanId )
1893 if setVlan:
1894 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001895 if partial:
1896 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001897 if encap:
1898 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001899
1900 # Check whether the user appended the port
1901 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001902
kelvin-onlabb9408212015-04-01 13:34:04 -07001903 if "/" in ingressDevice:
1904 cmd += " " + str( ingressDevice )
1905 else:
1906 if not portIngress:
1907 main.log.error( "You must specify " +
1908 "the Ingress port" )
1909 return main.FALSE
1910
1911 cmd += " " +\
1912 str( ingressDevice ) + "/" +\
1913 str( portIngress )
1914
1915 if portEgressList is None:
1916 for egressDevice in egressDeviceList:
1917 if "/" in egressDevice:
1918 cmd += " " + str( egressDevice )
1919 else:
1920 main.log.error( "You must specify " +
1921 "the egress port" )
1922 # TODO: perhaps more meaningful return
1923 return main.FALSE
1924 else:
1925 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001926 for egressDevice, portEgress in zip( egressDeviceList,
1927 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001928 cmd += " " + \
1929 str( egressDevice ) + "/" +\
1930 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001931 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001932 main.log.error( "Device list and port list does not " +
1933 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001934 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001935 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001936 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001937 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001938 # If error, return error message
1939 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001940 main.log.error( self.name + ": Error in adding singlepoint-to-multipoint " +
kelvin-onlabb9408212015-04-01 13:34:04 -07001941 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001942 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001943 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001944 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001945 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001946 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001947 else:
1948 main.log.error( "Error, intent ID not found" )
1949 return None
Jon Hallc6793552016-01-19 14:18:37 -08001950 except AssertionError:
1951 main.log.exception( "" )
1952 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001953 except TypeError:
1954 main.log.exception( self.name + ": Object not as expected" )
1955 return None
shahshreyad0c80432014-12-04 16:56:05 -08001956 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001957 main.log.error( self.name + ": EOF exception found" )
1958 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001959 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001960 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001961 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001962 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001963
Hari Krishna9e232602015-04-13 17:29:08 -07001964 def addMplsIntent(
1965 self,
1966 ingressDevice,
1967 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001968 ingressPort="",
1969 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001970 ethType="",
1971 ethSrc="",
1972 ethDst="",
1973 bandwidth="",
1974 lambdaAlloc=False,
1975 ipProto="",
1976 ipSrc="",
1977 ipDst="",
1978 tcpSrc="",
1979 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001980 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001981 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001982 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001983 """
1984 Required:
1985 * ingressDevice: device id of ingress device
1986 * egressDevice: device id of egress device
1987 Optional:
1988 * ethType: specify ethType
1989 * ethSrc: specify ethSrc ( i.e. src mac addr )
1990 * ethDst: specify ethDst ( i.e. dst mac addr )
1991 * bandwidth: specify bandwidth capacity of link
1992 * lambdaAlloc: if True, intent will allocate lambda
1993 for the specified intent
1994 * ipProto: specify ip protocol
1995 * ipSrc: specify ip source address
1996 * ipDst: specify ip destination address
1997 * tcpSrc: specify tcp source port
1998 * tcpDst: specify tcp destination port
1999 * ingressLabel: Ingress MPLS label
2000 * egressLabel: Egress MPLS label
2001 Description:
2002 Adds MPLS intent by
2003 specifying device id's and optional fields
2004 Returns:
2005 A string of the intent id or None on error
2006
2007 NOTE: This function may change depending on the
2008 options developers provide for MPLS
2009 intent via cli
2010 """
2011 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07002012 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07002013
Jeremy Songsterff553672016-05-12 17:06:23 -07002014 if ethType:
2015 cmd += " --ethType " + str( ethType )
2016 if ethSrc:
2017 cmd += " --ethSrc " + str( ethSrc )
2018 if ethDst:
2019 cmd += " --ethDst " + str( ethDst )
2020 if bandwidth:
2021 cmd += " --bandwidth " + str( bandwidth )
2022 if lambdaAlloc:
2023 cmd += " --lambda "
2024 if ipProto:
2025 cmd += " --ipProto " + str( ipProto )
2026 if ipSrc:
2027 cmd += " --ipSrc " + str( ipSrc )
2028 if ipDst:
2029 cmd += " --ipDst " + str( ipDst )
2030 if tcpSrc:
2031 cmd += " --tcpSrc " + str( tcpSrc )
2032 if tcpDst:
2033 cmd += " --tcpDst " + str( tcpDst )
2034 if ingressLabel:
2035 cmd += " --ingressLabel " + str( ingressLabel )
2036 if egressLabel:
2037 cmd += " --egressLabel " + str( egressLabel )
2038 if priority:
2039 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07002040
2041 # Check whether the user appended the port
2042 # or provided it as an input
2043 if "/" in ingressDevice:
2044 cmd += " " + str( ingressDevice )
2045 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002046 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002047 main.log.error( "You must specify the ingress port" )
2048 return None
2049
2050 cmd += " " + \
2051 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002052 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07002053
2054 if "/" in egressDevice:
2055 cmd += " " + str( egressDevice )
2056 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002057 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002058 main.log.error( "You must specify the egress port" )
2059 return None
2060
2061 cmd += " " +\
2062 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002063 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07002064
2065 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08002066 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002067 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07002068 # If error, return error message
2069 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002070 main.log.error( self.name + ": Error in adding mpls intent" )
Hari Krishna9e232602015-04-13 17:29:08 -07002071 return None
2072 else:
2073 # TODO: print out all the options in this message?
2074 main.log.info( "MPLS intent installed between " +
2075 str( ingressDevice ) + " and " +
2076 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002077 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07002078 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002079 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07002080 else:
2081 main.log.error( "Error, intent ID not found" )
2082 return None
Jon Hallc6793552016-01-19 14:18:37 -08002083 except AssertionError:
2084 main.log.exception( "" )
2085 return None
Hari Krishna9e232602015-04-13 17:29:08 -07002086 except TypeError:
2087 main.log.exception( self.name + ": Object not as expected" )
2088 return None
2089 except pexpect.EOF:
2090 main.log.error( self.name + ": EOF exception found" )
2091 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002092 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002093 except Exception:
2094 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002095 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002096
Jon Hallefbd9792015-03-05 16:11:36 -08002097 def removeIntent( self, intentId, app='org.onosproject.cli',
2098 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002099 """
shahshreya1c818fc2015-02-26 13:44:08 -08002100 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07002101 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08002102 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07002103 -p or --purge: Purge the intent from the store after removal
2104
Jon Halle3f39ff2015-01-13 11:50:53 -08002105 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07002106 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08002107 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08002108 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002109 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002110 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08002111 if purge:
2112 cmdStr += " -p"
2113 if sync:
2114 cmdStr += " -s"
2115
2116 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002117 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002118 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002119 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08002120 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002121 main.log.error( self.name + ": Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002122 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04002123 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002124 # TODO: Should this be main.TRUE
2125 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002126 except AssertionError:
2127 main.log.exception( "" )
2128 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002129 except TypeError:
2130 main.log.exception( self.name + ": Object not as expected" )
2131 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002132 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002133 main.log.error( self.name + ": EOF exception found" )
2134 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002135 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002136 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002137 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002138 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002139
YPZhangfebf7302016-05-24 16:45:56 -07002140 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08002141 """
2142 Description:
2143 Remove all the intents
2144 Optional args:-
2145 -s or --sync: Waits for the removal before returning
2146 -p or --purge: Purge the intent from the store after removal
2147 Returns:
2148 Returns main.TRUE if all intents are removed, otherwise returns
2149 main.FALSE; Returns None for exception
2150 """
2151 try:
2152 cmdStr = "remove-intent"
2153 if purge:
2154 cmdStr += " -p"
2155 if sync:
2156 cmdStr += " -s"
2157
2158 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002159 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002160 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002161 assert "Command not found:" not in handle, handle
2162 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002163 main.log.error( self.name + ": Error in removing intent" )
Jeremy42df2e72016-02-23 16:37:46 -08002164 return main.FALSE
2165 else:
2166 return main.TRUE
2167 except AssertionError:
2168 main.log.exception( "" )
2169 return None
2170 except TypeError:
2171 main.log.exception( self.name + ": Object not as expected" )
2172 return None
2173 except pexpect.EOF:
2174 main.log.error( self.name + ": EOF exception found" )
2175 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002176 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002177 except Exception:
2178 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002179 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002180
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002181 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002182 """
2183 Purges all WITHDRAWN Intents
2184 """
2185 try:
2186 cmdStr = "purge-intents"
2187 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002188 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002189 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002190 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002191 main.log.error( self.name + ": Error in purging intents" )
Hari Krishna0ce0e152015-06-23 09:55:29 -07002192 return main.FALSE
2193 else:
2194 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002195 except AssertionError:
2196 main.log.exception( "" )
2197 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002198 except TypeError:
2199 main.log.exception( self.name + ": Object not as expected" )
2200 return None
2201 except pexpect.EOF:
2202 main.log.error( self.name + ": EOF exception found" )
2203 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002204 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002205 except Exception:
2206 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002207 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002208
Devin Lime6fe3c42017-10-18 16:28:40 -07002209 def wipeout( self ):
2210 """
2211 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2212 """
2213 try:
2214 cmdStr = "wipe-out please"
2215 handle = self.sendline( cmdStr, timeout=60 )
2216 assert handle is not None, "Error in sendline"
2217 assert "Command not found:" not in handle, handle
2218 return main.TRUE
2219 except AssertionError:
2220 main.log.exception( "" )
2221 return None
2222 except TypeError:
2223 main.log.exception( self.name + ": Object not as expected" )
2224 return None
2225 except pexpect.EOF:
2226 main.log.error( self.name + ": EOF exception found" )
2227 main.log.error( self.name + ": " + self.handle.before )
2228 main.cleanAndExit()
2229 except Exception:
2230 main.log.exception( self.name + ": Uncaught exception!" )
2231 main.cleanAndExit()
2232
kelvin-onlabd3b64892015-01-20 13:26:24 -08002233 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002234 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002235 NOTE: This method should be used after installing application:
2236 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002237 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002238 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002239 Description:
2240 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002241 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002242 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002243 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002244 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002245 cmdStr += " -j"
2246 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002247 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002248 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002249 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002250 except AssertionError:
2251 main.log.exception( "" )
2252 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002253 except TypeError:
2254 main.log.exception( self.name + ": Object not as expected" )
2255 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002256 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002257 main.log.error( self.name + ": EOF exception found" )
2258 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002259 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002260 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002261 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002262 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002263
pingping-lin54b03372015-08-13 14:43:10 -07002264 def ipv4RouteNumber( self ):
2265 """
2266 NOTE: This method should be used after installing application:
2267 onos-app-sdnip
2268 Description:
2269 Obtain the total IPv4 routes number in the system
2270 """
2271 try:
Pratik Parab57963572017-05-09 11:37:54 -07002272 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002273 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002274 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002275 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002276 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002277 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002278 except AssertionError:
2279 main.log.exception( "" )
2280 return None
2281 except ( TypeError, ValueError ):
2282 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002283 return None
2284 except pexpect.EOF:
2285 main.log.error( self.name + ": EOF exception found" )
2286 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002287 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002288 except Exception:
2289 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002290 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002291
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002292 # =============Function to check Bandwidth allocation========
Jon Hall0e240372018-05-02 11:21:57 -07002293 def allocations( self, jsonFormat = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002294 """
2295 Description:
2296 Obtain Bandwidth Allocation Information from ONOS cli.
2297 """
2298 try:
2299 cmdStr = "allocations"
2300 if jsonFormat:
2301 cmdStr += " -j"
Jon Hall0e240372018-05-02 11:21:57 -07002302 handle = self.sendline( cmdStr, timeout=300 )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002303 assert handle is not None, "Error in sendline"
2304 assert "Command not found:" not in handle, handle
2305 return handle
2306 except AssertionError:
2307 main.log.exception( "" )
2308 return None
2309 except ( TypeError, ValueError ):
2310 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2311 return None
2312 except pexpect.EOF:
2313 main.log.error( self.name + ": EOF exception found" )
2314 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002315 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002316 except Exception:
2317 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002318 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002319
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002320 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002321 """
andrewonlabe6745342014-10-17 14:29:13 -04002322 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002323 Obtain intents from the ONOS cli.
2324 Optional:
2325 * jsonFormat: Enable output formatting in json, default to True
2326 * summary: Whether only output the intent summary, defaults to False
2327 * type: Only output a certain type of intent. This options is valid
2328 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002329 """
andrewonlabe6745342014-10-17 14:29:13 -04002330 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002331 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002332 if summary:
2333 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002334 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002335 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002336 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002337 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002338 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002339 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002340 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002341 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002342 else:
Jon Hallff566d52016-01-15 14:45:36 -08002343 intentType = ""
2344 # IF we want the summary of a specific intent type
2345 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002346 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002347 if intentType in jsonResult.keys():
2348 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002349 else:
Jon Hallff566d52016-01-15 14:45:36 -08002350 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002351 return handle
2352 else:
2353 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002354 except AssertionError:
2355 main.log.exception( "" )
2356 return None
2357 except ( TypeError, ValueError ):
2358 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002359 return None
2360 except pexpect.EOF:
2361 main.log.error( self.name + ": EOF exception found" )
2362 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002363 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002364 except Exception:
2365 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002366 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002367
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002368 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002369 """
You Wangfdcbfc42016-05-16 12:16:53 -07002370 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002371 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002372 list of intent IDs.
2373 Parameters:
2374 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002375 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002376 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002377 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002378 accepted.
2379 Returns a list of dictionaries if a list of intent IDs is accepted,
2380 and each dictionary maps 'id' to the Intent ID and 'state' to
2381 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002382 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002383
kelvin-onlab54400a92015-02-26 18:05:51 -08002384 try:
2385 state = "State is Undefined"
2386 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002387 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002388 else:
Jon Hallc6793552016-01-19 14:18:37 -08002389 rawJson = intentsJson
2390 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002391 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002392 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002393 if intentsId == intent[ 'id' ]:
2394 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002395 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002396 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002397 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002398 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002399 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002400 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002401 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002402 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002403 for intent in parsedIntentsJson:
2404 if intentsId[ i ] == intent[ 'id' ]:
2405 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002406 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002407 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002408 break
Jon Hallefbd9792015-03-05 16:11:36 -08002409 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002410 main.log.warn( "Could not find all intents in ONOS output" )
2411 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002412 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002413 else:
Jon Hall53158082017-05-18 11:17:00 -07002414 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002415 return None
Jon Hallc6793552016-01-19 14:18:37 -08002416 except ( TypeError, ValueError ):
2417 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002418 return None
2419 except pexpect.EOF:
2420 main.log.error( self.name + ": EOF exception found" )
2421 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002422 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002423 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002424 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002425 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002426
Jon Hallf539eb92017-05-22 17:18:42 -07002427 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002428 """
2429 Description:
2430 Check intents state
2431 Required:
2432 intentsId - List of intents ID to be checked
2433 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002434 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002435 state in the list.
2436 *NOTE: You can pass in a list of expected state,
2437 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002438 Return:
Jon Hall53158082017-05-18 11:17:00 -07002439 Returns main.TRUE only if all intent are the same as expected states,
2440 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002441 """
2442 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002443 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002444 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002445
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002446 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002447 intentsDict = []
2448 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002449 if isinstance( intentsId, types.StringType ) \
2450 and intent.get( 'id' ) == intentsId:
2451 intentsDict.append( intent )
2452 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002453 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002454 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002455
2456 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002457 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002458 "getting intents state" )
2459 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002460
2461 if isinstance( expectedState, types.StringType ):
2462 for intents in intentsDict:
2463 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002464 main.log.debug( self.name + " : Intent ID - " +
2465 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002466 " actual state = " +
2467 intents.get( 'state' )
2468 + " does not equal expected state = "
2469 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002470 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002471 elif isinstance( expectedState, types.ListType ):
2472 for intents in intentsDict:
2473 if not any( state == intents.get( 'state' ) for state in
2474 expectedState ):
2475 main.log.debug( self.name + " : Intent ID - " +
2476 intents.get( 'id' ) +
2477 " actual state = " +
2478 intents.get( 'state' ) +
2479 " does not equal expected states = "
2480 + str( expectedState ) )
2481 returnValue = main.FALSE
2482
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002483 if returnValue == main.TRUE:
2484 main.log.info( self.name + ": All " +
2485 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002486 " intents are in " + str( expectedState ) +
2487 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002488 return returnValue
2489 except TypeError:
2490 main.log.exception( self.name + ": Object not as expected" )
2491 return None
2492 except pexpect.EOF:
2493 main.log.error( self.name + ": EOF exception found" )
2494 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002495 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002496 except Exception:
2497 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002498 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002499
Jon Hallf539eb92017-05-22 17:18:42 -07002500 def compareBandwidthAllocations( self, expectedAllocations ):
2501 """
2502 Description:
2503 Compare the allocated bandwidth with the given allocations
2504 Required:
2505 expectedAllocations - The expected ONOS output of the allocations command
2506 Return:
2507 Returns main.TRUE only if all intent are the same as expected states,
2508 otherwise returns main.FALSE.
2509 """
2510 # FIXME: Convert these string comparisons to object comparisons
2511 try:
2512 returnValue = main.TRUE
2513 bandwidthFailed = False
2514 rawAlloc = self.allocations()
2515 expectedFormat = StringIO( expectedAllocations )
2516 ONOSOutput = StringIO( rawAlloc )
2517 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2518 str( expectedFormat ) ) )
2519
2520 for actual, expected in izip( ONOSOutput, expectedFormat ):
2521 actual = actual.rstrip()
2522 expected = expected.rstrip()
2523 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2524 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002525 marker1 = actual.find( 'allocated' )
2526 m1 = actual[ :marker1 ]
2527 marker2 = expected.find( 'allocated' )
2528 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002529 if m1 != m2:
2530 bandwidthFailed = True
2531 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2532 bandwidthFailed = True
2533 expectedFormat.close()
2534 ONOSOutput.close()
2535
2536 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002537 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002538 returnValue = main.FALSE
2539 return returnValue
2540 except TypeError:
2541 main.log.exception( self.name + ": Object not as expected" )
2542 return None
2543 except pexpect.EOF:
2544 main.log.error( self.name + ": EOF exception found" )
2545 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002546 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002547 except Exception:
2548 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002549 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002550
You Wang66518af2016-05-16 15:32:59 -07002551 def compareIntent( self, intentDict ):
2552 """
2553 Description:
2554 Compare the intent ids and states provided in the argument with all intents in ONOS
2555 Return:
2556 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2557 Arguments:
2558 intentDict: a dictionary which maps intent ids to intent states
2559 """
2560 try:
2561 intentsRaw = self.intents()
2562 intentsJson = json.loads( intentsRaw )
2563 intentDictONOS = {}
2564 for intent in intentsJson:
2565 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002566 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002567 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002568 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002569 str( len( intentDict ) ) + " expected and " +
2570 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002571 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002572 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002573 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002574 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2575 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002576 else:
2577 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2578 main.log.debug( self.name + ": intent ID - " + intentID +
2579 " expected state is " + intentDict[ intentID ] +
2580 " but actual state is " + intentDictONOS[ intentID ] )
2581 returnValue = main.FALSE
2582 intentDictONOS.pop( intentID )
2583 if len( intentDictONOS ) > 0:
2584 returnValue = main.FALSE
2585 for intentID in intentDictONOS.keys():
2586 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002587 if returnValue == main.TRUE:
2588 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2589 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002590 except KeyError:
2591 main.log.exception( self.name + ": KeyError exception found" )
2592 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002593 except ( TypeError, ValueError ):
2594 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002595 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002596 except pexpect.EOF:
2597 main.log.error( self.name + ": EOF exception found" )
2598 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002599 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002600 except Exception:
2601 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002602 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002603
YPZhang14a4aa92016-07-15 13:37:15 -07002604 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002605 """
2606 Description:
2607 Check the number of installed intents.
2608 Optional:
2609 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002610 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002611 Return:
2612 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2613 , otherwise, returns main.FALSE.
2614 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002615
GlennRCed771242016-01-13 17:02:47 -08002616 try:
2617 cmd = "intents -s -j"
2618
2619 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002620 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002621 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002622 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002623 response = json.loads( response )
2624
2625 # get total and installed number, see if they are match
2626 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002627 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002628 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2629 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002630 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002631 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2632 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002633 return main.FALSE
2634
Jon Hallc6793552016-01-19 14:18:37 -08002635 except ( TypeError, ValueError ):
2636 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002637 return None
2638 except pexpect.EOF:
2639 main.log.error( self.name + ": EOF exception found" )
2640 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002641 if noExit:
2642 return main.FALSE
2643 else:
Devin Lim44075962017-08-11 10:56:37 -07002644 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002645 except pexpect.TIMEOUT:
2646 main.log.error( self.name + ": ONOS timeout" )
2647 return None
GlennRCed771242016-01-13 17:02:47 -08002648 except Exception:
2649 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002650 if noExit:
2651 return main.FALSE
2652 else:
Devin Lim44075962017-08-11 10:56:37 -07002653 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002654
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002655 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002656 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002657 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002658 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002659 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002660 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002661 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002662 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002663 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002664 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002665 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002666 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002667 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002668 cmdStr += " -n"
2669 cmdStr += " " + state
2670 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002671 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002672 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002673 assert "Command not found:" not in handle, handle
2674 if re.search( "Error:", handle ):
2675 main.log.error( self.name + ": flows() response: " +
2676 str( handle ) )
2677 return handle
2678 except AssertionError:
2679 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002680 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002681 except TypeError:
2682 main.log.exception( self.name + ": Object not as expected" )
2683 return None
Jon Hallc6793552016-01-19 14:18:37 -08002684 except pexpect.TIMEOUT:
2685 main.log.error( self.name + ": ONOS timeout" )
2686 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002687 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002688 main.log.error( self.name + ": EOF exception found" )
2689 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002690 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002691 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002692 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002693 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002694
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002695 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002696 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002697 count = int( count ) if count else 0
steven30801eccfe212019-01-24 13:00:42 +08002698 main.log.debug( "found {} flows".format( count ) )
Jon Hall39570262020-11-17 12:18:19 -08002699 return count if ( count >= min ) else False
GlennRCed771242016-01-13 17:02:47 -08002700
Jon Halle0f0b342017-04-18 11:43:47 -07002701 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002702 """
2703 Description:
GlennRCed771242016-01-13 17:02:47 -08002704 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002705 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2706 if the count of those states is 0, which means all current flows
2707 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002708 Optional:
GlennRCed771242016-01-13 17:02:47 -08002709 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002710 Return:
2711 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002712 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002713 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002714 """
2715 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002716 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002717 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002718 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002719 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002720 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002721 if rawFlows:
2722 # if we didn't get flows or flows function return None, we should return
2723 # main.Flase
2724 checkedStates.append( json.loads( rawFlows ) )
2725 else:
2726 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002727 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002728 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002729 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002730 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002731 except TypeError:
2732 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002733 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002734
GlennRCed771242016-01-13 17:02:47 -08002735 # We want to count PENDING_ADD if isPENDING is true
2736 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002737 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002738 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002739 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002740 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002741 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002742 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002743 except ( TypeError, ValueError ):
2744 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002745 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002746
YPZhang240842b2016-05-17 12:00:50 -07002747 except AssertionError:
2748 main.log.exception( "" )
2749 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002750 except pexpect.TIMEOUT:
2751 main.log.error( self.name + ": ONOS timeout" )
2752 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002753 except pexpect.EOF:
2754 main.log.error( self.name + ": EOF exception found" )
2755 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002756 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002757 except Exception:
2758 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002759 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002760
GlennRCed771242016-01-13 17:02:47 -08002761 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002762 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002763 """
andrewonlab87852b02014-11-19 18:44:19 -05002764 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002765 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002766 a specific point-to-point intent definition
2767 Required:
GlennRCed771242016-01-13 17:02:47 -08002768 * ingress: specify source dpid
2769 * egress: specify destination dpid
2770 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002771 Optional:
GlennRCed771242016-01-13 17:02:47 -08002772 * offset: the keyOffset is where the next batch of intents
2773 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002774 * noExit: If set to True, TestON will not exit if any error when issus command
2775 * getResponse: If set to True, function will return ONOS response.
2776
GlennRCed771242016-01-13 17:02:47 -08002777 Returns: If failed to push test intents, it will returen None,
2778 if successful, return true.
2779 Timeout expection will return None,
2780 TypeError will return false
2781 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002782 """
andrewonlab87852b02014-11-19 18:44:19 -05002783 try:
GlennRCed771242016-01-13 17:02:47 -08002784 if background:
2785 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002786 else:
GlennRCed771242016-01-13 17:02:47 -08002787 back = ""
2788 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002789 ingress,
2790 egress,
2791 batchSize,
2792 offset,
2793 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002794 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002795 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002796 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002797 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002798 if getResponse:
2799 return response
2800
GlennRCed771242016-01-13 17:02:47 -08002801 # TODO: We should handle if there is failure in installation
2802 return main.TRUE
2803
Jon Hallc6793552016-01-19 14:18:37 -08002804 except AssertionError:
2805 main.log.exception( "" )
2806 return None
GlennRCed771242016-01-13 17:02:47 -08002807 except pexpect.TIMEOUT:
2808 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002809 return None
andrewonlab87852b02014-11-19 18:44:19 -05002810 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002811 main.log.error( self.name + ": EOF exception found" )
2812 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002813 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002814 except TypeError:
2815 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002816 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002817 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002818 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002819 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002820
YPZhangebf9eb52016-05-12 15:20:24 -07002821 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002822 """
2823 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002824 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002825 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002826 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002827 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002828 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002829
YPZhangb5d3f832016-01-23 22:54:26 -08002830 try:
YPZhange3109a72016-02-02 11:25:37 -08002831 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002832 cmd = "flows -c added"
2833 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2834 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002835 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002836 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002837 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002838 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002839 else:
You Wang68568b12019-03-04 11:49:57 -08002840 main.log.warn( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002841 return None
2842 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002843
You Wangd3097f72018-12-12 11:56:03 -08002844 except IndexError:
2845 main.log.exception( "{}: Object not as expected!".format( self.name ) )
2846 main.log.debug( "rawFlows: {}".format( rawFlows ) )
2847 return None
You Wangd3cb2ce2016-05-16 14:01:24 -07002848 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002849 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002850 return None
2851 except pexpect.EOF:
2852 main.log.error( self.name + ": EOF exception found" )
2853 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002854 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002855 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002856 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002857 except pexpect.TIMEOUT:
2858 main.log.error( self.name + ": ONOS timeout" )
2859 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002860 except Exception:
2861 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002862 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002863 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002864 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002865
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002866 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002867 """
2868 Description:
2869 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002870 Optional:
2871 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002872 Return:
2873 The number of intents
2874 """
2875 try:
2876 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002877 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002878 if response is None:
2879 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002880 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002881 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002882 except ( TypeError, ValueError ):
2883 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002884 return None
2885 except pexpect.EOF:
2886 main.log.error( self.name + ": EOF exception found" )
2887 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002888 if noExit:
2889 return -1
2890 else:
Devin Lim44075962017-08-11 10:56:37 -07002891 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002892 except Exception:
2893 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002894 if noExit:
2895 return -1
2896 else:
Devin Lim44075962017-08-11 10:56:37 -07002897 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002898
kelvin-onlabd3b64892015-01-20 13:26:24 -08002899 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002900 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002901 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002902 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002903 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002904 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002905 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002906 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002907 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002908 cmdStr += " -j"
2909 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002910 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002911 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002912 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002913 except AssertionError:
2914 main.log.exception( "" )
2915 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002916 except TypeError:
2917 main.log.exception( self.name + ": Object not as expected" )
2918 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002919 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002920 main.log.error( self.name + ": EOF exception found" )
2921 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002922 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002923 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002924 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002925 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002926
kelvin-onlabd3b64892015-01-20 13:26:24 -08002927 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002928 """
2929 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002930 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002931 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002932 """
andrewonlab867212a2014-10-22 20:13:38 -04002933 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002934 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002935 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002936 cmdStr += " -j"
2937 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002938 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002939 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002940 if handle:
2941 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002942 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002943 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002944 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002945 else:
2946 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002947 except AssertionError:
2948 main.log.exception( "" )
2949 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002950 except TypeError:
2951 main.log.exception( self.name + ": Object not as expected" )
2952 return None
andrewonlab867212a2014-10-22 20:13:38 -04002953 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002954 main.log.error( self.name + ": EOF exception found" )
2955 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002956 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002957 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002958 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002959 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002960
kelvin8ec71442015-01-15 16:57:00 -08002961 # Wrapper functions ****************
2962 # Wrapper functions use existing driver
2963 # functions and extends their use case.
2964 # For example, we may use the output of
2965 # a normal driver function, and parse it
2966 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002967
kelvin-onlabd3b64892015-01-20 13:26:24 -08002968 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002969 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002970 Description:
2971 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002972 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002973 try:
kelvin8ec71442015-01-15 16:57:00 -08002974 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002975 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002976 if intentsStr is None:
2977 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002978 # Convert to a dictionary
2979 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002980 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002981 for intent in intents:
2982 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002983 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002984 except TypeError:
2985 main.log.exception( self.name + ": Object not as expected" )
2986 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002987 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002988 main.log.error( self.name + ": EOF exception found" )
2989 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002990 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002991 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002992 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002993 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002994
You Wang3c276252016-09-21 15:21:36 -07002995 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002996 """
2997 Determine the number of flow rules for the given device id that are
2998 in the added state
You Wang3c276252016-09-21 15:21:36 -07002999 Params:
3000 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08003001 """
3002 try:
You Wang3c276252016-09-21 15:21:36 -07003003 if core:
3004 cmdStr = "flows any " + str( deviceId ) + " | " +\
3005 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
3006 else:
3007 cmdStr = "flows any " + str( deviceId ) + " | " +\
3008 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003009 handle = self.lineCount( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003010 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003011 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08003012 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003013 except AssertionError:
3014 main.log.exception( "" )
3015 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08003016 except pexpect.EOF:
3017 main.log.error( self.name + ": EOF exception found" )
3018 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003019 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003020 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08003021 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003022 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04003023
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003024 def groupAddedCount( self, deviceId, core=False ):
3025 """
3026 Determine the number of group rules for the given device id that are
3027 in the added state
3028 Params:
3029 core: if True, only return the number of core groups added
3030 """
3031 try:
3032 if core:
3033 cmdStr = "groups any " + str( deviceId ) + " | " +\
3034 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
3035 else:
3036 cmdStr = "groups any " + str( deviceId ) + " | " +\
3037 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003038 handle = self.lineCount( cmdStr )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003039 assert handle is not None, "Error in sendline"
3040 assert "Command not found:" not in handle, handle
3041 return handle
3042 except AssertionError:
3043 main.log.exception( "" )
3044 return None
3045 except pexpect.EOF:
3046 main.log.error( self.name + ": EOF exception found" )
3047 main.log.error( self.name + ": " + self.handle.before )
3048 main.cleanAndExit()
3049 except Exception:
3050 main.log.exception( self.name + ": Uncaught exception!" )
3051 main.cleanAndExit()
3052
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003053 def addStaticRoute( self, subnet, intf):
3054 """
3055 Adds a static route to onos.
3056 Params:
3057 subnet: The subnet reaching through this route
3058 intf: The interface this route is reachable through
3059 """
3060 try:
3061 cmdStr = "route-add " + subnet + " " + intf
3062 handle = self.sendline( cmdStr )
3063 assert handle is not None, "Error in sendline"
3064 assert "Command not found:" not in handle, handle
3065 return handle
3066 except AssertionError:
3067 main.log.exception( "" )
3068 return None
3069 except pexpect.EOF:
3070 main.log.error( self.name + ": EOF exception found" )
3071 main.log.error( self.name + ": " + self.handle.before )
3072 main.cleanAndExit()
3073 except Exception:
3074 main.log.exception( self.name + ": Uncaught exception!" )
3075 main.cleanAndExit()
3076
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003077 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
3078 """
3079 Description:
3080 Check whether the number of groups for the given device id that
3081 are in ADDED state is bigger than minGroupCount.
3082 Required:
3083 * deviceId: device id to check the number of added group rules
3084 Optional:
3085 * minGroupCount: the number of groups to compare
3086 * core: if True, only check the number of core groups added
3087 * comparison: if 0, compare with greater than minFlowCount
3088 * if 1, compare with equal to minFlowCount
3089 Return:
3090 Returns the number of groups if it is bigger than minGroupCount,
3091 returns main.FALSE otherwise.
3092 """
3093 count = self.groupAddedCount( deviceId, core )
3094 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003095 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003096 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
3097
You Wangc02f3be2018-05-18 12:14:23 -07003098 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003099 """
3100 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07003101 deviceId: Id of the device from which we retrieve groups
3102 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003103 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003104 try:
You Wangc02f3be2018-05-18 12:14:23 -07003105 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
3106 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003107 assert handle is not None, "Error in sendline"
3108 assert "Command not found:" not in handle, handle
3109 return handle
3110 except AssertionError:
3111 main.log.exception( "" )
3112 return None
3113 except TypeError:
3114 main.log.exception( self.name + ": Object not as expected" )
3115 return None
3116 except pexpect.EOF:
3117 main.log.error( self.name + ": EOF exception found" )
3118 main.log.error( self.name + ": " + self.handle.before )
3119 main.cleanAndExit()
3120 except Exception:
3121 main.log.exception( self.name + ": Uncaught exception!" )
3122 main.cleanAndExit()
3123
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003124 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003125 """
3126 Description:
3127 Check whether the number of flow rules for the given device id that
3128 are in ADDED state is bigger than minFlowCount.
3129 Required:
3130 * deviceId: device id to check the number of added flow rules
3131 Optional:
3132 * minFlowCount: the number of flow rules to compare
3133 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003134 * comparison: if 0, compare with greater than minFlowCount
3135 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003136 Return:
3137 Returns the number of flow rules if it is bigger than minFlowCount,
3138 returns main.FALSE otherwise.
3139 """
3140 count = self.flowAddedCount( deviceId, core )
3141 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003142 main.log.debug( "found {} flows".format( count ) )
Jon Hall39570262020-11-17 12:18:19 -08003143 return count if ((count >= expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003144
kelvin-onlabd3b64892015-01-20 13:26:24 -08003145 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003146 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003147 Use 'devices' function to obtain list of all devices
3148 and parse the result to obtain a list of all device
3149 id's. Returns this list. Returns empty list if no
3150 devices exist
kelvin8ec71442015-01-15 16:57:00 -08003151 List is ordered sequentially
3152
andrewonlab3e15ead2014-10-15 14:21:34 -04003153 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003154 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003155 the ids. By obtaining the list of device ids on the fly,
3156 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003157 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003158 try:
kelvin8ec71442015-01-15 16:57:00 -08003159 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003160 devicesStr = self.devices( jsonFormat=False )
3161 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003162
kelvin-onlabd3b64892015-01-20 13:26:24 -08003163 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003164 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003165 return idList
kelvin8ec71442015-01-15 16:57:00 -08003166
3167 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003168 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003169 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003170 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003171 # Split list further into arguments before and after string
3172 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003173 # append to idList
3174 for arg in tempList:
3175 idList.append( arg.split( "id=" )[ 1 ] )
3176 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003177
Jon Halld4d4b372015-01-28 16:02:41 -08003178 except TypeError:
3179 main.log.exception( self.name + ": Object not as expected" )
3180 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003181 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003182 main.log.error( self.name + ": EOF exception found" )
3183 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003184 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003185 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003186 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003187 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003188
kelvin-onlabd3b64892015-01-20 13:26:24 -08003189 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003190 """
andrewonlab7c211572014-10-15 16:45:20 -04003191 Uses 'nodes' function to obtain list of all nodes
3192 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003193 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003194 Returns:
3195 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003196 """
andrewonlab7c211572014-10-15 16:45:20 -04003197 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003198 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003199 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003200 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003201 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003202 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003203 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003204 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003205 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003206 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003207 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003208 except ( TypeError, ValueError ):
3209 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003210 return None
andrewonlab7c211572014-10-15 16:45:20 -04003211 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003212 main.log.error( self.name + ": EOF exception found" )
3213 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003214 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003215 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003216 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003217 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003218
kelvin-onlabd3b64892015-01-20 13:26:24 -08003219 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003220 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003221 Return the first device from the devices api whose 'id' contains 'dpid'
3222 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003223 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003224 try:
kelvin8ec71442015-01-15 16:57:00 -08003225 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003226 return None
3227 else:
kelvin8ec71442015-01-15 16:57:00 -08003228 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003229 rawDevices = self.devices()
3230 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003231 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003232 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003233 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3234 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003235 return device
3236 return None
Jon Hallc6793552016-01-19 14:18:37 -08003237 except ( TypeError, ValueError ):
3238 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003239 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003240 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003241 main.log.error( self.name + ": EOF exception found" )
3242 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003243 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003244 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003245 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003246 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003247
You Wang24139872016-05-03 11:48:47 -07003248 def getTopology( self, topologyOutput ):
3249 """
3250 Definition:
3251 Loads a json topology output
3252 Return:
3253 topology = current ONOS topology
3254 """
You Wang24139872016-05-03 11:48:47 -07003255 try:
3256 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003257 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003258 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003259 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003260 except ( TypeError, ValueError ):
3261 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3262 return None
You Wang24139872016-05-03 11:48:47 -07003263 except pexpect.EOF:
3264 main.log.error( self.name + ": EOF exception found" )
3265 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003266 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003267 except Exception:
3268 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003269 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003270
Jon Hall39570262020-11-17 12:18:19 -08003271 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, numoSCCs=1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003272 """
Jon Hallefbd9792015-03-05 16:11:36 -08003273 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003274 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003275 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003276
Flavio Castro82ee2f62016-06-07 15:04:12 -07003277 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003278 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003279 numoctrl = expected number of controllers
Jon Hall39570262020-11-17 12:18:19 -08003280 numoSCCs = Number of expected SCCs
You Wang24139872016-05-03 11:48:47 -07003281 logLevel = level to log to.
3282 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003283
Jon Hallefbd9792015-03-05 16:11:36 -08003284 Returns: main.TRUE if the number of switches and links are correct,
3285 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003286 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003287 """
Jon Hall42db6dc2014-10-24 19:03:48 -04003288 try:
You Wang13310252016-07-31 10:56:14 -07003289 summary = self.summary()
3290 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003291 except ( TypeError, ValueError ):
3292 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3293 return main.ERROR
3294 try:
3295 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003296 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003297 return main.ERROR
3298 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003299 # Is the number of switches is what we expected
3300 devices = topology.get( 'devices', False )
3301 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003302 nodes = summary.get( 'nodes', False )
Jon Hall39570262020-11-17 12:18:19 -08003303 SCCs = summary.get( 'SCC(s)', False )
3304 if devices is False or links is False or nodes is False or SCCs is False:
3305 main.log.warn( "Issues parsing topology and summary output" )
3306 main.log.debug( topology )
3307 main.log.debug( summary )
Jon Hall42db6dc2014-10-24 19:03:48 -04003308 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003309 switchCheck = ( int( devices ) == int( numoswitch ) )
Jon Hall39570262020-11-17 12:18:19 -08003310 if not switchCheck:
3311 main.log.debug( "switch Check Failed" )
Pier6a0c4de2018-03-18 16:01:30 -07003312 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Jon Hall39570262020-11-17 12:18:19 -08003313 if not linkCheck:
3314 main.log.debug( "link Check Failed" )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003315 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
Jon Hall39570262020-11-17 12:18:19 -08003316 if not nodeCheck:
3317 main.log.debug( "node Check Failed" )
3318 SCCsCheck = ( int( SCCs ) == int( numoSCCs ) ) or int( numoSCCs ) == -1
3319 if not SCCsCheck:
3320 main.log.debug( "SCCs Check Failed" )
3321 if switchCheck and linkCheck and nodeCheck and SCCsCheck:
kelvin8ec71442015-01-15 16:57:00 -08003322 # We expected the correct numbers
Jon Hall39570262020-11-17 12:18:19 -08003323 output = output + "The number of links, switches, nodes, and SCCs match "\
You Wang24139872016-05-03 11:48:47 -07003324 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003325 result = main.TRUE
3326 else:
You Wang24139872016-05-03 11:48:47 -07003327 output = output + \
Jon Hall627b1572020-12-01 12:01:15 -08003328 "The number of links, switches, nodes, and SCCs does not match " + \
You Wang24139872016-05-03 11:48:47 -07003329 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003330 result = main.FALSE
Jon Hall39570262020-11-17 12:18:19 -08003331 output = output + "\n ONOS sees %i devices " % int( devices )
3332 output = output + "(%i expected) " % int( numoswitch )
3333 if int( numolink ) >= 0:
Pier6a0c4de2018-03-18 16:01:30 -07003334 output = output + "and %i links " % int( links )
Jon Hall39570262020-11-17 12:18:19 -08003335 output = output + "(%i expected) " % int( numolink )
3336 if int( numoctrl ) >= 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003337 output = output + "and %i controllers " % int( nodes )
Jon Hall39570262020-11-17 12:18:19 -08003338 output = output + "(%i expected) " % int( numoctrl )
3339 if int( numoSCCs ) >= 0:
3340 output = output + "and %i SCCs " % int( SCCs )
3341 output = output + "(%i expected)" % int( numoSCCs )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003342 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003343 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003344 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003345 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003346 else:
You Wang24139872016-05-03 11:48:47 -07003347 main.log.info( output )
Jon Hall39570262020-11-17 12:18:19 -08003348 main.TOPOOUTPUT = output
kelvin8ec71442015-01-15 16:57:00 -08003349 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003350 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003351 main.log.error( self.name + ": EOF exception found" )
3352 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003353 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003354 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003355 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003356 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003357
kelvin-onlabd3b64892015-01-20 13:26:24 -08003358 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003359 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003360 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003361 deviceId must be the id of a device as seen in the onos devices command
3362 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003363 role must be either master, standby, or none
3364
Jon Halle3f39ff2015-01-13 11:50:53 -08003365 Returns:
3366 main.TRUE or main.FALSE based on argument verification and
3367 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003368 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003369 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003370 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003371 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003372 cmdStr = "device-role " +\
3373 str( deviceId ) + " " +\
3374 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003375 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003376 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003377 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003378 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003379 if re.search( "Error", handle ):
3380 # end color output to escape any colours
3381 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003382 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003383 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003384 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003385 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003386 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003387 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003388 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003389 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003390 except AssertionError:
3391 main.log.exception( "" )
3392 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003393 except TypeError:
3394 main.log.exception( self.name + ": Object not as expected" )
3395 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003396 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003397 main.log.error( self.name + ": EOF exception found" )
3398 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003399 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003400 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003401 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003402 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003403
kelvin-onlabd3b64892015-01-20 13:26:24 -08003404 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003405 """
Jon Hall0dd09952018-04-19 09:59:11 -07003406 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003407 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003408 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003409 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003410 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003411 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003412 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003413 cmdStr += " -j"
3414 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003415 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003416 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003417 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003418 except AssertionError:
3419 main.log.exception( "" )
3420 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003421 except TypeError:
3422 main.log.exception( self.name + ": Object not as expected" )
3423 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003424 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003425 main.log.error( self.name + ": EOF exception found" )
3426 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003427 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003428 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003429 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003430 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003431
kelvin-onlabd3b64892015-01-20 13:26:24 -08003432 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003433 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003434 CLI command to get the current leader for the Election test application
3435 NOTE: Requires installation of the onos-app-election feature
3436 Returns: Node IP of the leader if one exists
3437 None if none exists
3438 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003439 """
Jon Hall94fd0472014-12-08 11:52:42 -08003440 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003441 cmdStr = "election-test-leader"
3442 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003443 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003444 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003445 # Leader
3446 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003447 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003448 nodeSearch = re.search( leaderPattern, response )
3449 if nodeSearch:
3450 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003451 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003452 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003453 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003454 # no leader
3455 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003456 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003457 nullSearch = re.search( nullPattern, response )
3458 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003459 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003460 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003461 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003462 # error
Jon Hall0e240372018-05-02 11:21:57 -07003463 main.log.error( self.name + ": Error in electionTestLeader on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003464 ": " + "unexpected response" )
3465 main.log.error( repr( response ) )
3466 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003467 except AssertionError:
3468 main.log.exception( "" )
3469 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003470 except TypeError:
3471 main.log.exception( self.name + ": Object not as expected" )
3472 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003473 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003474 main.log.error( self.name + ": EOF exception found" )
3475 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003476 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003477 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003478 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003479 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003480
kelvin-onlabd3b64892015-01-20 13:26:24 -08003481 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003482 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003483 CLI command to run for leadership of the Election test application.
3484 NOTE: Requires installation of the onos-app-election feature
3485 Returns: Main.TRUE on success
3486 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003487 """
Jon Hall94fd0472014-12-08 11:52:42 -08003488 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003489 cmdStr = "election-test-run"
3490 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003491 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003492 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003493 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003494 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003495 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003496 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003497 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003498 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003499 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003500 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003501 # error
Jon Hall0e240372018-05-02 11:21:57 -07003502 main.log.error( self.name + ": Error in electionTestRun on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003503 ": " + "unexpected response" )
3504 main.log.error( repr( response ) )
3505 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003506 except AssertionError:
3507 main.log.exception( "" )
3508 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003509 except TypeError:
3510 main.log.exception( self.name + ": Object not as expected" )
3511 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003512 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003513 main.log.error( self.name + ": EOF exception found" )
3514 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003515 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003516 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003517 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003518 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003519
kelvin-onlabd3b64892015-01-20 13:26:24 -08003520 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003521 """
Jon Hall94fd0472014-12-08 11:52:42 -08003522 * CLI command to withdraw the local node from leadership election for
3523 * the Election test application.
3524 #NOTE: Requires installation of the onos-app-election feature
3525 Returns: Main.TRUE on success
3526 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003527 """
Jon Hall94fd0472014-12-08 11:52:42 -08003528 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003529 cmdStr = "election-test-withdraw"
3530 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003531 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003532 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003533 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003534 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003535 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003536 if re.search( successPattern, response ):
3537 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003538 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003539 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003540 # error
Jon Hall0e240372018-05-02 11:21:57 -07003541 main.log.error( self.name + ": Error in electionTestWithdraw on " +
Jon Hall97cf84a2016-06-20 13:35:58 -07003542 self.name + ": " + "unexpected response" )
3543 main.log.error( repr( response ) )
3544 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003545 except AssertionError:
3546 main.log.exception( "" )
3547 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003548 except TypeError:
3549 main.log.exception( self.name + ": Object not as expected" )
3550 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003551 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003552 main.log.error( self.name + ": EOF exception found" )
3553 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003554 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003555 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003556 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003557 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003558
kelvin8ec71442015-01-15 16:57:00 -08003559 def getDevicePortsEnabledCount( self, dpid ):
3560 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003561 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003562 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003563 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003564 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003565 cmdStr = "onos:ports -e " + dpid + " | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003566 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003567 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003568 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003569 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003570 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003571 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003572 return output
Jon Hallc6793552016-01-19 14:18:37 -08003573 except AssertionError:
3574 main.log.exception( "" )
3575 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003576 except TypeError:
3577 main.log.exception( self.name + ": Object not as expected" )
3578 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003579 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003580 main.log.error( self.name + ": EOF exception found" )
3581 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003582 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003583 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003584 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003585 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003586
kelvin8ec71442015-01-15 16:57:00 -08003587 def getDeviceLinksActiveCount( self, dpid ):
3588 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003589 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003590 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003591 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003592 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003593 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003594 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003595 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003596 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003597 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003598 main.log.error( self.name + ": Error in getting ports " )
kelvin-onlab898a6c62015-01-16 14:13:53 -08003599 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003600 return output
Jon Hallc6793552016-01-19 14:18:37 -08003601 except AssertionError:
3602 main.log.exception( "" )
3603 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003604 except TypeError:
3605 main.log.exception( self.name + ": Object not as expected" )
3606 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003607 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003608 main.log.error( self.name + ": EOF exception found" )
3609 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003610 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003611 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003612 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003613 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003614
kelvin8ec71442015-01-15 16:57:00 -08003615 def getAllIntentIds( self ):
3616 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003617 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003618 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003619 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003620 cmdStr = "onos:intents | grep id="
3621 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003622 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003623 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003624 if re.search( "Error", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003625 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003626 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003627 return output
Jon Hallc6793552016-01-19 14:18:37 -08003628 except AssertionError:
3629 main.log.exception( "" )
3630 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003631 except TypeError:
3632 main.log.exception( self.name + ": Object not as expected" )
3633 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003634 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003635 main.log.error( self.name + ": EOF exception found" )
3636 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003637 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003638 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003639 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003640 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003641
Jon Hall73509952015-02-24 16:42:56 -08003642 def intentSummary( self ):
3643 """
Jon Hallefbd9792015-03-05 16:11:36 -08003644 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003645 """
3646 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003647 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003648 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003649 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003650 states.append( intent.get( 'state', None ) )
3651 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003652 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003653 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003654 except ( TypeError, ValueError ):
3655 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003656 return None
3657 except pexpect.EOF:
3658 main.log.error( self.name + ": EOF exception found" )
3659 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003660 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003661 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003662 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003663 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003664
Jon Hall61282e32015-03-19 11:34:11 -07003665 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003666 """
3667 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003668 Optional argument:
3669 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003670 """
Jon Hall63604932015-02-26 17:09:50 -08003671 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003672 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003673 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003674 cmdStr += " -j"
3675 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003676 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003677 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003678 return output
Jon Hallc6793552016-01-19 14:18:37 -08003679 except AssertionError:
3680 main.log.exception( "" )
3681 return None
Jon Hall63604932015-02-26 17:09:50 -08003682 except TypeError:
3683 main.log.exception( self.name + ": Object not as expected" )
3684 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003685 except pexpect.EOF:
3686 main.log.error( self.name + ": EOF exception found" )
3687 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003688 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003689 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003690 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003691 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003692
acsmarsa4a4d1e2015-07-10 16:01:24 -07003693 def leaderCandidates( self, jsonFormat=True ):
3694 """
3695 Returns the output of the leaders -c command.
3696 Optional argument:
3697 * jsonFormat - boolean indicating if you want output in json
3698 """
3699 try:
3700 cmdStr = "onos:leaders -c"
3701 if jsonFormat:
3702 cmdStr += " -j"
3703 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003704 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003705 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003706 return output
Jon Hallc6793552016-01-19 14:18:37 -08003707 except AssertionError:
3708 main.log.exception( "" )
3709 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003710 except TypeError:
3711 main.log.exception( self.name + ": Object not as expected" )
3712 return None
3713 except pexpect.EOF:
3714 main.log.error( self.name + ": EOF exception found" )
3715 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003716 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003717 except Exception:
3718 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003719 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003720
Jon Hallc6793552016-01-19 14:18:37 -08003721 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003722 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003723 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003724 topic parameter and an empty list if the topic doesn't exist
3725 If no leader is elected leader in the returned list will be "none"
3726 Returns None if there is a type error processing the json object
3727 """
3728 try:
Jon Hall6e709752016-02-01 13:38:46 -08003729 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003730 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003731 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003732 assert "Command not found:" not in rawOutput, rawOutput
3733 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003734 results = []
3735 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003736 if dict[ "topic" ] == topic:
3737 leader = dict[ "leader" ]
3738 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003739 results.append( leader )
3740 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003741 return results
Jon Hallc6793552016-01-19 14:18:37 -08003742 except AssertionError:
3743 main.log.exception( "" )
3744 return None
3745 except ( TypeError, ValueError ):
3746 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003747 return None
3748 except pexpect.EOF:
3749 main.log.error( self.name + ": EOF exception found" )
3750 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003751 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003752 except Exception:
3753 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003754 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003755
Jon Hall61282e32015-03-19 11:34:11 -07003756 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003757 """
3758 Returns the output of the intent Pending map.
3759 """
Jon Hall63604932015-02-26 17:09:50 -08003760 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003761 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003762 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003763 cmdStr += " -j"
3764 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003765 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003766 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003767 return output
Jon Hallc6793552016-01-19 14:18:37 -08003768 except AssertionError:
3769 main.log.exception( "" )
3770 return None
Jon Hall63604932015-02-26 17:09:50 -08003771 except TypeError:
3772 main.log.exception( self.name + ": Object not as expected" )
3773 return None
3774 except pexpect.EOF:
3775 main.log.error( self.name + ": EOF exception found" )
3776 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003777 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003778 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003779 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003780 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003781
Jon Hall2c8959e2016-12-16 12:17:34 -08003782 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003783 """
3784 Returns the output of the raft partitions command for ONOS.
3785 """
Jon Hall61282e32015-03-19 11:34:11 -07003786 # Sample JSON
3787 # {
3788 # "leader": "tcp://10.128.30.11:7238",
3789 # "members": [
3790 # "tcp://10.128.30.11:7238",
3791 # "tcp://10.128.30.17:7238",
3792 # "tcp://10.128.30.13:7238",
3793 # ],
3794 # "name": "p1",
3795 # "term": 3
3796 # },
Jon Hall63604932015-02-26 17:09:50 -08003797 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003798 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003799 if candidates:
3800 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003801 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003802 cmdStr += " -j"
3803 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003804 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003805 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003806 return output
Jon Hallc6793552016-01-19 14:18:37 -08003807 except AssertionError:
3808 main.log.exception( "" )
3809 return None
Jon Hall63604932015-02-26 17:09:50 -08003810 except TypeError:
3811 main.log.exception( self.name + ": Object not as expected" )
3812 return None
3813 except pexpect.EOF:
3814 main.log.error( self.name + ": EOF exception found" )
3815 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003816 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003817 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003818 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003819 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003820
Jon Halle9f909e2016-09-23 10:43:12 -07003821 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003822 """
3823 Returns the output of the apps command for ONOS. This command lists
3824 information about installed ONOS applications
3825 """
3826 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003827 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003828 # "description":"ONOS OpenFlow protocol southbound providers",
3829 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003830 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003831 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003832 cmdStr = "onos:apps"
Jon Hallf03ae762019-01-22 13:25:27 -08003833 expectJson = False
Jon Halle9f909e2016-09-23 10:43:12 -07003834 if summary:
3835 cmdStr += " -s"
3836 if active:
3837 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003838 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003839 cmdStr += " -j"
Jon Hallf03ae762019-01-22 13:25:27 -08003840 expectJson = True
3841 output = self.sendline( cmdStr, expectJson=expectJson )
Jon Halla495f562016-05-16 18:03:26 -07003842 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003843 assert "Command not found:" not in output, output
3844 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003845 return output
Jon Hallbe379602015-03-24 13:39:32 -07003846 # FIXME: look at specific exceptions/Errors
3847 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07003848 main.log.exception( self.name + ": Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003849 return None
3850 except TypeError:
3851 main.log.exception( self.name + ": Object not as expected" )
3852 return None
3853 except pexpect.EOF:
3854 main.log.error( self.name + ": EOF exception found" )
3855 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003856 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003857 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003858 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003859 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003860
You Wangcdc51fe2018-08-12 17:14:56 -07003861 def appStatus( self, appName ):
Jon Hall146f1522015-03-24 15:33:24 -07003862 """
3863 Uses the onos:apps cli command to return the status of an application.
3864 Returns:
3865 "ACTIVE" - If app is installed and activated
3866 "INSTALLED" - If app is installed and deactivated
3867 "UNINSTALLED" - If app is not installed
3868 None - on error
3869 """
Jon Hall146f1522015-03-24 15:33:24 -07003870 try:
3871 if not isinstance( appName, types.StringType ):
3872 main.log.error( self.name + ".appStatus(): appName must be" +
3873 " a string" )
3874 return None
3875 output = self.apps( jsonFormat=True )
3876 appsJson = json.loads( output )
3877 state = None
3878 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003879 if appName == app.get( 'name' ):
3880 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003881 break
3882 if state == "ACTIVE" or state == "INSTALLED":
3883 return state
3884 elif state is None:
You Wang0d9f2c02018-08-10 14:56:32 -07003885 main.log.warn( "{} app not found".format( appName ) )
Jon Hall146f1522015-03-24 15:33:24 -07003886 return "UNINSTALLED"
3887 elif state:
3888 main.log.error( "Unexpected state from 'onos:apps': " +
3889 str( state ) )
3890 return state
Jon Hallc6793552016-01-19 14:18:37 -08003891 except ( TypeError, ValueError ):
3892 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003893 return None
3894 except pexpect.EOF:
3895 main.log.error( self.name + ": EOF exception found" )
3896 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003897 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003898 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003899 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003900 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003901
Jon Hallbe379602015-03-24 13:39:32 -07003902 def app( self, appName, option ):
3903 """
3904 Interacts with the app command for ONOS. This command manages
3905 application inventory.
3906 """
Jon Hallbe379602015-03-24 13:39:32 -07003907 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003908 # Validate argument types
3909 valid = True
3910 if not isinstance( appName, types.StringType ):
3911 main.log.error( self.name + ".app(): appName must be a " +
3912 "string" )
3913 valid = False
3914 if not isinstance( option, types.StringType ):
3915 main.log.error( self.name + ".app(): option must be a string" )
3916 valid = False
3917 if not valid:
3918 return main.FALSE
3919 # Validate Option
3920 option = option.lower()
3921 # NOTE: Install may become a valid option
3922 if option == "activate":
3923 pass
3924 elif option == "deactivate":
3925 pass
3926 elif option == "uninstall":
3927 pass
3928 else:
3929 # Invalid option
3930 main.log.error( "The ONOS app command argument only takes " +
3931 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003932 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003933 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003934 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003935 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003936 assert output is not None, "Error in sendline"
3937 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003938 if "Error executing command" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003939 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hallbe379602015-03-24 13:39:32 -07003940 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003941 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003942 elif "No such application" in output:
3943 main.log.error( "The application '" + appName +
3944 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003945 return main.FALSE
3946 elif "Command not found:" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003947 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hall146f1522015-03-24 15:33:24 -07003948 str( output ) )
3949 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003950 elif "Unsupported command:" in output:
3951 main.log.error( "Incorrect command given to 'app': " +
3952 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003953 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003954 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003955 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003956 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003957 except AssertionError:
3958 main.log.exception( self.name + ": AssertionError exception found" )
3959 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003960 except TypeError:
3961 main.log.exception( self.name + ": Object not as expected" )
3962 return main.ERROR
3963 except pexpect.EOF:
3964 main.log.error( self.name + ": EOF exception found" )
3965 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003966 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003967 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003968 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003969 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003970
Jon Hallbd16b922015-03-26 17:53:15 -07003971 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003972 """
3973 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003974 appName is the hierarchical app name, not the feature name
3975 If check is True, method will check the status of the app after the
3976 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003977 Returns main.TRUE if the command was successfully sent
3978 main.FALSE if the cli responded with an error or given
3979 incorrect input
3980 """
3981 try:
3982 if not isinstance( appName, types.StringType ):
3983 main.log.error( self.name + ".activateApp(): appName must be" +
3984 " a string" )
3985 return main.FALSE
3986 status = self.appStatus( appName )
3987 if status == "INSTALLED":
3988 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003989 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003990 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003991 status = self.appStatus( appName )
3992 if status == "ACTIVE":
3993 return main.TRUE
3994 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003995 main.log.debug( "The state of application " +
3996 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003997 time.sleep( 1 )
3998 return main.FALSE
3999 else: # not 'check' or command didn't succeed
4000 return response
Jon Hall146f1522015-03-24 15:33:24 -07004001 elif status == "ACTIVE":
4002 return main.TRUE
4003 elif status == "UNINSTALLED":
4004 main.log.error( self.name + ": Tried to activate the " +
4005 "application '" + appName + "' which is not " +
4006 "installed." )
4007 else:
4008 main.log.error( "Unexpected return value from appStatus: " +
4009 str( status ) )
4010 return main.ERROR
4011 except TypeError:
4012 main.log.exception( self.name + ": Object not as expected" )
4013 return main.ERROR
4014 except pexpect.EOF:
4015 main.log.error( self.name + ": EOF exception found" )
4016 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004017 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004018 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004019 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004020 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07004021
Jon Hallbd16b922015-03-26 17:53:15 -07004022 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07004023 """
4024 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07004025 appName is the hierarchical app name, not the feature name
4026 If check is True, method will check the status of the app after the
4027 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07004028 Returns main.TRUE if the command was successfully sent
4029 main.FALSE if the cli responded with an error or given
4030 incorrect input
4031 """
4032 try:
4033 if not isinstance( appName, types.StringType ):
4034 main.log.error( self.name + ".deactivateApp(): appName must " +
4035 "be a string" )
4036 return main.FALSE
4037 status = self.appStatus( appName )
4038 if status == "INSTALLED":
4039 return main.TRUE
4040 elif status == "ACTIVE":
4041 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07004042 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004043 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004044 status = self.appStatus( appName )
4045 if status == "INSTALLED":
4046 return main.TRUE
4047 else:
4048 time.sleep( 1 )
4049 return main.FALSE
4050 else: # not check or command didn't succeed
4051 return response
Jon Hall146f1522015-03-24 15:33:24 -07004052 elif status == "UNINSTALLED":
4053 main.log.warn( self.name + ": Tried to deactivate the " +
4054 "application '" + appName + "' which is not " +
4055 "installed." )
4056 return main.TRUE
4057 else:
4058 main.log.error( "Unexpected return value from appStatus: " +
4059 str( status ) )
4060 return main.ERROR
4061 except TypeError:
4062 main.log.exception( self.name + ": Object not as expected" )
4063 return main.ERROR
4064 except pexpect.EOF:
4065 main.log.error( self.name + ": EOF exception found" )
4066 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004067 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004068 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004069 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004070 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07004071
Jon Hallbd16b922015-03-26 17:53:15 -07004072 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07004073 """
4074 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07004075 appName is the hierarchical app name, not the feature name
4076 If check is True, method will check the status of the app after the
4077 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07004078 Returns main.TRUE if the command was successfully sent
4079 main.FALSE if the cli responded with an error or given
4080 incorrect input
4081 """
4082 # TODO: check with Thomas about the state machine for apps
4083 try:
4084 if not isinstance( appName, types.StringType ):
4085 main.log.error( self.name + ".uninstallApp(): appName must " +
4086 "be a string" )
4087 return main.FALSE
4088 status = self.appStatus( appName )
4089 if status == "INSTALLED":
4090 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004091 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004092 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004093 status = self.appStatus( appName )
4094 if status == "UNINSTALLED":
4095 return main.TRUE
4096 else:
4097 time.sleep( 1 )
4098 return main.FALSE
4099 else: # not check or command didn't succeed
4100 return response
Jon Hall146f1522015-03-24 15:33:24 -07004101 elif status == "ACTIVE":
4102 main.log.warn( self.name + ": Tried to uninstall the " +
4103 "application '" + appName + "' which is " +
4104 "currently active." )
4105 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004106 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004107 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004108 status = self.appStatus( appName )
4109 if status == "UNINSTALLED":
4110 return main.TRUE
4111 else:
4112 time.sleep( 1 )
4113 return main.FALSE
4114 else: # not check or command didn't succeed
4115 return response
Jon Hall146f1522015-03-24 15:33:24 -07004116 elif status == "UNINSTALLED":
4117 return main.TRUE
4118 else:
4119 main.log.error( "Unexpected return value from appStatus: " +
4120 str( status ) )
4121 return main.ERROR
4122 except TypeError:
4123 main.log.exception( self.name + ": Object not as expected" )
4124 return main.ERROR
4125 except pexpect.EOF:
4126 main.log.error( self.name + ": EOF exception found" )
4127 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004128 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004129 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004130 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004131 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004132
4133 def appIDs( self, jsonFormat=True ):
4134 """
4135 Show the mappings between app id and app names given by the 'app-ids'
4136 cli command
4137 """
4138 try:
4139 cmdStr = "app-ids"
4140 if jsonFormat:
4141 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07004142 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004143 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004144 assert "Command not found:" not in output, output
4145 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07004146 return output
Jon Hallbd16b922015-03-26 17:53:15 -07004147 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004148 main.log.exception( self.name + ": Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07004149 return None
4150 except TypeError:
4151 main.log.exception( self.name + ": Object not as expected" )
4152 return None
4153 except pexpect.EOF:
4154 main.log.error( self.name + ": EOF exception found" )
4155 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004156 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004157 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004158 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004159 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004160
4161 def appToIDCheck( self ):
4162 """
4163 This method will check that each application's ID listed in 'apps' is
4164 the same as the ID listed in 'app-ids'. The check will also check that
4165 there are no duplicate IDs issued. Note that an app ID should be
4166 a globaly unique numerical identifier for app/app-like features. Once
4167 an ID is registered, the ID is never freed up so that if an app is
4168 reinstalled it will have the same ID.
4169
4170 Returns: main.TRUE if the check passes and
4171 main.FALSE if the check fails or
4172 main.ERROR if there is some error in processing the test
4173 """
4174 try:
Jon Hall0e240372018-05-02 11:21:57 -07004175 # Grab IDs
Jon Hallc6793552016-01-19 14:18:37 -08004176 rawJson = self.appIDs( jsonFormat=True )
4177 if rawJson:
4178 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004179 else:
Jon Hall0e240372018-05-02 11:21:57 -07004180 main.log.error( "app-ids returned nothing: " + repr( rawJson ) )
4181 return main.FALSE
4182
4183 # Grab Apps
Jon Hallc6793552016-01-19 14:18:37 -08004184 rawJson = self.apps( jsonFormat=True )
4185 if rawJson:
4186 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004187 else:
Jon Hallc6793552016-01-19 14:18:37 -08004188 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004189 return main.FALSE
Jon Hall0e240372018-05-02 11:21:57 -07004190
Jon Hallbd16b922015-03-26 17:53:15 -07004191 result = main.TRUE
4192 for app in apps:
4193 appID = app.get( 'id' )
4194 if appID is None:
4195 main.log.error( "Error parsing app: " + str( app ) )
4196 result = main.FALSE
4197 appName = app.get( 'name' )
4198 if appName is None:
4199 main.log.error( "Error parsing app: " + str( app ) )
4200 result = main.FALSE
4201 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004202 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004203 if not current: # if ids doesn't have this id
4204 result = main.FALSE
4205 main.log.error( "'app-ids' does not have the ID for " +
4206 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004207 main.log.debug( "apps command returned: " + str( app ) +
4208 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004209 elif len( current ) > 1:
4210 # there is more than one app with this ID
4211 result = main.FALSE
4212 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004213 elif not current[ 0 ][ 'name' ] == appName:
4214 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004215 result = main.FALSE
4216 main.log.error( "'app-ids' has " + str( currentName ) +
4217 " registered under id:" + str( appID ) +
4218 " but 'apps' has " + str( appName ) )
4219 else:
4220 pass # id and name match!
Jon Hall0e240372018-05-02 11:21:57 -07004221
Jon Hallbd16b922015-03-26 17:53:15 -07004222 # now make sure that app-ids has no duplicates
4223 idsList = []
4224 namesList = []
4225 for item in ids:
4226 idsList.append( item[ 'id' ] )
4227 namesList.append( item[ 'name' ] )
4228 if len( idsList ) != len( set( idsList ) ) or\
4229 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004230 main.log.error( "'app-ids' has some duplicate entries: \n"
4231 + json.dumps( ids,
4232 sort_keys=True,
4233 indent=4,
4234 separators=( ',', ': ' ) ) )
4235 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004236 return result
Jon Hallc6793552016-01-19 14:18:37 -08004237 except ( TypeError, ValueError ):
4238 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004239 return main.ERROR
4240 except pexpect.EOF:
4241 main.log.error( self.name + ": EOF exception found" )
4242 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004243 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004244 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004245 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004246 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004247
Jon Hallfb760a02015-04-13 15:35:03 -07004248 def getCfg( self, component=None, propName=None, short=False,
4249 jsonFormat=True ):
4250 """
4251 Get configuration settings from onos cli
4252 Optional arguments:
4253 component - Optionally only list configurations for a specific
4254 component. If None, all components with configurations
4255 are displayed. Case Sensitive string.
4256 propName - If component is specified, propName option will show
4257 only this specific configuration from that component.
4258 Case Sensitive string.
4259 jsonFormat - Returns output as json. Note that this will override
4260 the short option
4261 short - Short, less verbose, version of configurations.
4262 This is overridden by the json option
4263 returns:
4264 Output from cli as a string or None on error
4265 """
4266 try:
4267 baseStr = "cfg"
4268 cmdStr = " get"
4269 componentStr = ""
4270 if component:
4271 componentStr += " " + component
4272 if propName:
4273 componentStr += " " + propName
4274 if jsonFormat:
4275 baseStr += " -j"
Jon Hall22e94ce2019-01-15 14:52:17 -08004276 expectJson = True
Jon Hallfb760a02015-04-13 15:35:03 -07004277 elif short:
4278 baseStr += " -s"
Jon Hall22e94ce2019-01-15 14:52:17 -08004279 expectJson = False
4280 output = self.sendline( baseStr + cmdStr + componentStr, expectJson=expectJson )
Jon Halla495f562016-05-16 18:03:26 -07004281 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004282 assert "Command not found:" not in output, output
4283 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004284 return output
4285 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004286 main.log.exception( self.name + ": Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004287 return None
4288 except TypeError:
4289 main.log.exception( self.name + ": Object not as expected" )
4290 return None
4291 except pexpect.EOF:
4292 main.log.error( self.name + ": EOF exception found" )
4293 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004294 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004295 except Exception:
4296 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004297 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004298
4299 def setCfg( self, component, propName, value=None, check=True ):
4300 """
4301 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004302 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004303 component - The case sensitive name of the component whose
4304 property is to be set
4305 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004306 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004307 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004308 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004309 check - Boolean, Check whether the option was successfully set this
4310 only applies when a value is given.
4311 returns:
4312 main.TRUE on success or main.FALSE on failure. If check is False,
4313 will return main.TRUE unless there is an error
4314 """
4315 try:
4316 baseStr = "cfg"
4317 cmdStr = " set " + str( component ) + " " + str( propName )
4318 if value is not None:
4319 cmdStr += " " + str( value )
4320 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004321 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004322 assert "Command not found:" not in output, output
4323 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004324 if value and check:
4325 results = self.getCfg( component=str( component ),
4326 propName=str( propName ),
4327 jsonFormat=True )
4328 # Check if current value is what we just set
4329 try:
4330 jsonOutput = json.loads( results )
4331 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004332 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004333 main.log.exception( "Error parsing cfg output" )
4334 main.log.error( "output:" + repr( results ) )
4335 return main.FALSE
4336 if current == str( value ):
4337 return main.TRUE
4338 return main.FALSE
4339 return main.TRUE
4340 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004341 main.log.exception( self.name + ": Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004342 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004343 except ( TypeError, ValueError ):
4344 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004345 return main.FALSE
4346 except pexpect.EOF:
4347 main.log.error( self.name + ": EOF exception found" )
4348 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004349 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004350 except Exception:
4351 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004352 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004353
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004354 def distPrimitivesSend( self, cmd ):
4355 """
4356 Function to handle sending cli commands for the distributed primitives test app
4357
4358 This command will catch some exceptions and retry the command on some
4359 specific store exceptions.
4360
4361 Required arguments:
4362 cmd - The command to send to the cli
4363 returns:
4364 string containing the cli output
4365 None on Error
4366 """
4367 try:
4368 output = self.sendline( cmd )
4369 try:
4370 assert output is not None, "Error in sendline"
4371 # TODO: Maybe make this less hardcoded
4372 # ConsistentMap Exceptions
4373 assert "org.onosproject.store.service" not in output
4374 # Node not leader
4375 assert "java.lang.IllegalStateException" not in output
4376 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004377 main.log.error( self.name + ": Error in processing '" + cmd + "' " +
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004378 "command: " + str( output ) )
4379 retryTime = 30 # Conservative time, given by Madan
4380 main.log.info( "Waiting " + str( retryTime ) +
4381 "seconds before retrying." )
4382 time.sleep( retryTime ) # Due to change in mastership
4383 output = self.sendline( cmd )
4384 assert output is not None, "Error in sendline"
4385 assert "Command not found:" not in output, output
4386 assert "Error executing command" not in output, output
4387 main.log.info( self.name + ": " + output )
4388 return output
4389 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004390 main.log.exception( self.name + ": Error in processing '" + cmd + "' command." )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004391 return None
4392 except TypeError:
4393 main.log.exception( self.name + ": Object not as expected" )
4394 return None
4395 except pexpect.EOF:
4396 main.log.error( self.name + ": EOF exception found" )
4397 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004398 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004399 except Exception:
4400 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004401 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004402
Jon Hall390696c2015-05-05 17:13:41 -07004403 def setTestAdd( self, setName, values ):
4404 """
4405 CLI command to add elements to a distributed set.
4406 Arguments:
4407 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004408 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004409 Example usages:
4410 setTestAdd( "set1", "a b c" )
4411 setTestAdd( "set2", "1" )
4412 returns:
4413 main.TRUE on success OR
4414 main.FALSE if elements were already in the set OR
4415 main.ERROR on error
4416 """
4417 try:
4418 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004419 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004420 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4421 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004422 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004423 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004424 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004425 return main.FALSE
4426 else:
4427 main.log.error( self.name + ": setTestAdd did not" +
4428 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004429 main.log.debug( self.name + " actual: " + repr( output ) )
4430 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004431 except TypeError:
4432 main.log.exception( self.name + ": Object not as expected" )
4433 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004434 except Exception:
4435 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004436 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004437
4438 def setTestRemove( self, setName, values, clear=False, retain=False ):
4439 """
4440 CLI command to remove elements from a distributed set.
4441 Required arguments:
4442 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004443 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004444 Optional arguments:
4445 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004446 retain - Retain only the given values. (intersection of the
4447 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004448 returns:
4449 main.TRUE on success OR
4450 main.FALSE if the set was not changed OR
4451 main.ERROR on error
4452 """
4453 try:
4454 cmdStr = "set-test-remove "
4455 if clear:
4456 cmdStr += "-c " + str( setName )
4457 elif retain:
4458 cmdStr += "-r " + str( setName ) + " " + str( values )
4459 else:
4460 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004461 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004462 if clear:
4463 pattern = "Set " + str( setName ) + " cleared"
4464 if re.search( pattern, output ):
4465 return main.TRUE
4466 elif retain:
4467 positivePattern = str( setName ) + " was pruned to contain " +\
4468 "only elements of set \[(.*)\]"
4469 negativePattern = str( setName ) + " was not changed by " +\
4470 "retaining only elements of the set " +\
4471 "\[(.*)\]"
4472 if re.search( positivePattern, output ):
4473 return main.TRUE
4474 elif re.search( negativePattern, output ):
4475 return main.FALSE
4476 else:
4477 positivePattern = "\[(.*)\] was removed from the set " +\
4478 str( setName )
4479 if ( len( values.split() ) == 1 ):
4480 negativePattern = "\[(.*)\] was not in set " +\
4481 str( setName )
4482 else:
4483 negativePattern = "No element of \[(.*)\] was in set " +\
4484 str( setName )
4485 if re.search( positivePattern, output ):
4486 return main.TRUE
4487 elif re.search( negativePattern, output ):
4488 return main.FALSE
4489 main.log.error( self.name + ": setTestRemove did not" +
4490 " match expected output" )
4491 main.log.debug( self.name + " expected: " + pattern )
4492 main.log.debug( self.name + " actual: " + repr( output ) )
4493 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004494 except TypeError:
4495 main.log.exception( self.name + ": Object not as expected" )
4496 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004497 except Exception:
4498 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004499 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004500
4501 def setTestGet( self, setName, values="" ):
4502 """
4503 CLI command to get the elements in a distributed set.
4504 Required arguments:
4505 setName - The name of the set to remove from.
4506 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004507 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004508 returns:
4509 main.ERROR on error OR
4510 A list of elements in the set if no optional arguments are
4511 supplied OR
4512 A tuple containing the list then:
4513 main.FALSE if the given values are not in the set OR
4514 main.TRUE if the given values are in the set OR
4515 """
4516 try:
4517 values = str( values ).strip()
4518 setName = str( setName ).strip()
4519 length = len( values.split() )
4520 containsCheck = None
4521 # Patterns to match
4522 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004523 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004524 containsTrue = "Set " + setName + " contains the value " + values
4525 containsFalse = "Set " + setName + " did not contain the value " +\
4526 values
4527 containsAllTrue = "Set " + setName + " contains the the subset " +\
4528 setPattern
4529 containsAllFalse = "Set " + setName + " did not contain the the" +\
4530 " subset " + setPattern
4531
4532 cmdStr = "set-test-get "
4533 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004534 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004535 if length == 0:
4536 match = re.search( pattern, output )
4537 else: # if given values
4538 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004539 patternTrue = pattern + "\r\n" + containsTrue
4540 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004541 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004542 patternTrue = pattern + "\r\n" + containsAllTrue
4543 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004544 matchTrue = re.search( patternTrue, output )
4545 matchFalse = re.search( patternFalse, output )
4546 if matchTrue:
4547 containsCheck = main.TRUE
4548 match = matchTrue
4549 elif matchFalse:
4550 containsCheck = main.FALSE
4551 match = matchFalse
4552 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004553 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004554 "expected output" )
4555 main.log.debug( self.name + " expected: " + pattern )
4556 main.log.debug( self.name + " actual: " + repr( output ) )
4557 match = None
4558 if match:
4559 setMatch = match.group( 1 )
4560 if setMatch == '':
4561 setList = []
4562 else:
4563 setList = setMatch.split( ", " )
4564 if length > 0:
4565 return ( setList, containsCheck )
4566 else:
4567 return setList
4568 else: # no match
4569 main.log.error( self.name + ": setTestGet did not" +
4570 " match expected output" )
4571 main.log.debug( self.name + " expected: " + pattern )
4572 main.log.debug( self.name + " actual: " + repr( output ) )
4573 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004574 except TypeError:
4575 main.log.exception( self.name + ": Object not as expected" )
4576 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004577 except Exception:
4578 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004579 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004580
4581 def setTestSize( self, setName ):
4582 """
4583 CLI command to get the elements in a distributed set.
4584 Required arguments:
4585 setName - The name of the set to remove from.
4586 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004587 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004588 None on error
4589 """
4590 try:
4591 # TODO: Should this check against the number of elements returned
4592 # and then return true/false based on that?
4593 setName = str( setName ).strip()
4594 # Patterns to match
4595 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004596 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004597 setPattern
4598 cmdStr = "set-test-get -s "
4599 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004600 output = self.distPrimitivesSend( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -07004601 if output:
4602 match = re.search( pattern, output )
4603 if match:
4604 setSize = int( match.group( 1 ) )
4605 setMatch = match.group( 2 )
4606 if len( setMatch.split() ) == setSize:
4607 main.log.info( "The size returned by " + self.name +
4608 " matches the number of elements in " +
4609 "the returned set" )
4610 else:
4611 main.log.error( "The size returned by " + self.name +
4612 " does not match the number of " +
4613 "elements in the returned set." )
4614 return setSize
Jon Hall390696c2015-05-05 17:13:41 -07004615 else: # no match
4616 main.log.error( self.name + ": setTestGet did not" +
4617 " match expected output" )
4618 main.log.debug( self.name + " expected: " + pattern )
4619 main.log.debug( self.name + " actual: " + repr( output ) )
4620 return None
Jon Hall390696c2015-05-05 17:13:41 -07004621 except TypeError:
4622 main.log.exception( self.name + ": Object not as expected" )
4623 return None
Jon Hall390696c2015-05-05 17:13:41 -07004624 except Exception:
4625 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004626 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004627
Jon Hall80daded2015-05-27 16:07:00 -07004628 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004629 """
4630 Command to list the various counters in the system.
4631 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004632 if jsonFormat, a string of the json object returned by the cli
4633 command
4634 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004635 None on error
4636 """
Jon Hall390696c2015-05-05 17:13:41 -07004637 try:
Jon Hall390696c2015-05-05 17:13:41 -07004638 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004639 if jsonFormat:
4640 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004641 output = self.sendline( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08004642 main.log.debug( self.name + ": Counters unparsed: " + output )
4643 output = output.split( "\r\n" )[ -1 ]
4644 main.log.debug( self.name + ": Counters parsed: " + output )
Jon Halla495f562016-05-16 18:03:26 -07004645 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004646 assert "Command not found:" not in output, output
4647 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004648 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004649 return output
Jon Hall390696c2015-05-05 17:13:41 -07004650 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004651 main.log.exception( self.name + ": Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004652 return None
Jon Hall390696c2015-05-05 17:13:41 -07004653 except TypeError:
4654 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004655 return None
Jon Hall390696c2015-05-05 17:13:41 -07004656 except pexpect.EOF:
4657 main.log.error( self.name + ": EOF exception found" )
4658 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004659 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004660 except Exception:
4661 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004662 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004663
Jon Hall935db192016-04-19 00:22:04 -07004664 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004665 """
Jon Halle1a3b752015-07-22 13:02:46 -07004666 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004667 Required arguments:
4668 counter - The name of the counter to increment.
4669 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004670 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004671 returns:
4672 integer value of the counter or
4673 None on Error
4674 """
4675 try:
4676 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004677 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004678 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004679 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004680 if delta != 1:
4681 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004682 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004683 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004684 match = re.search( pattern, output )
4685 if match:
4686 return int( match.group( 1 ) )
4687 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004688 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004689 " match expected output." )
4690 main.log.debug( self.name + " expected: " + pattern )
4691 main.log.debug( self.name + " actual: " + repr( output ) )
4692 return None
Jon Hall390696c2015-05-05 17:13:41 -07004693 except TypeError:
4694 main.log.exception( self.name + ": Object not as expected" )
4695 return None
Jon Hall390696c2015-05-05 17:13:41 -07004696 except Exception:
4697 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004698 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004699
Jon Hall935db192016-04-19 00:22:04 -07004700 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004701 """
4702 CLI command to get a distributed counter then add a delta to it.
4703 Required arguments:
4704 counter - The name of the counter to increment.
4705 Optional arguments:
4706 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004707 returns:
4708 integer value of the counter or
4709 None on Error
4710 """
4711 try:
4712 counter = str( counter )
4713 delta = int( delta )
4714 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004715 cmdStr += counter
4716 if delta != 1:
4717 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004718 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004719 pattern = counter + " was updated to (-?\d+)"
4720 match = re.search( pattern, output )
4721 if match:
4722 return int( match.group( 1 ) )
4723 else:
4724 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4725 " match expected output." )
4726 main.log.debug( self.name + " expected: " + pattern )
4727 main.log.debug( self.name + " actual: " + repr( output ) )
4728 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004729 except TypeError:
4730 main.log.exception( self.name + ": Object not as expected" )
4731 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004732 except Exception:
4733 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004734 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004735
4736 def valueTestGet( self, valueName ):
4737 """
4738 CLI command to get the value of an atomic value.
4739 Required arguments:
4740 valueName - The name of the value to get.
4741 returns:
4742 string value of the value or
4743 None on Error
4744 """
4745 try:
4746 valueName = str( valueName )
4747 cmdStr = "value-test "
4748 operation = "get"
4749 cmdStr = "value-test {} {}".format( valueName,
4750 operation )
4751 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08004752 main.log.debug( self.name + ": value test unparsed: " + output )
4753 output = output.split( "\r\n" )[ -1 ]
4754 main.log.debug( self.name + ": value test parsed: " + output )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004755 pattern = "(\w+)"
4756 match = re.search( pattern, output )
4757 if match:
4758 return match.group( 1 )
4759 else:
4760 main.log.error( self.name + ": valueTestGet did not" +
4761 " match expected output." )
4762 main.log.debug( self.name + " expected: " + pattern )
4763 main.log.debug( self.name + " actual: " + repr( output ) )
4764 return None
4765 except TypeError:
4766 main.log.exception( self.name + ": Object not as expected" )
4767 return None
4768 except Exception:
4769 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004770 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004771
4772 def valueTestSet( self, valueName, newValue ):
4773 """
4774 CLI command to set the value of an atomic value.
4775 Required arguments:
4776 valueName - The name of the value to set.
4777 newValue - The value to assign to the given value.
4778 returns:
4779 main.TRUE on success or
4780 main.ERROR on Error
4781 """
4782 try:
4783 valueName = str( valueName )
4784 newValue = str( newValue )
4785 operation = "set"
4786 cmdStr = "value-test {} {} {}".format( valueName,
4787 operation,
4788 newValue )
4789 output = self.distPrimitivesSend( cmdStr )
4790 if output is not None:
4791 return main.TRUE
4792 else:
4793 return main.ERROR
4794 except TypeError:
4795 main.log.exception( self.name + ": Object not as expected" )
4796 return main.ERROR
4797 except Exception:
4798 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004799 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004800
4801 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4802 """
4803 CLI command to compareAndSet the value of an atomic value.
4804 Required arguments:
4805 valueName - The name of the value.
4806 oldValue - Compare the current value of the atomic value to this
4807 newValue - If the value equals oldValue, set the value to newValue
4808 returns:
4809 main.TRUE on success or
4810 main.FALSE on failure or
4811 main.ERROR on Error
4812 """
4813 try:
4814 valueName = str( valueName )
4815 oldValue = str( oldValue )
4816 newValue = str( newValue )
4817 operation = "compareAndSet"
4818 cmdStr = "value-test {} {} {} {}".format( valueName,
4819 operation,
4820 oldValue,
4821 newValue )
4822 output = self.distPrimitivesSend( cmdStr )
4823 pattern = "(\w+)"
4824 match = re.search( pattern, output )
4825 if match:
4826 result = match.group( 1 )
4827 if result == "true":
4828 return main.TRUE
4829 elif result == "false":
4830 return main.FALSE
4831 else:
4832 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4833 " match expected output." )
4834 main.log.debug( self.name + " expected: " + pattern )
4835 main.log.debug( self.name + " actual: " + repr( output ) )
4836 return main.ERROR
4837 except TypeError:
4838 main.log.exception( self.name + ": Object not as expected" )
4839 return main.ERROR
4840 except Exception:
4841 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004842 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004843
4844 def valueTestGetAndSet( self, valueName, newValue ):
4845 """
4846 CLI command to getAndSet the value of an atomic value.
4847 Required arguments:
4848 valueName - The name of the value to get.
4849 newValue - The value to assign to the given value
4850 returns:
4851 string value of the value or
4852 None on Error
4853 """
4854 try:
4855 valueName = str( valueName )
4856 cmdStr = "value-test "
4857 operation = "getAndSet"
4858 cmdStr += valueName + " " + operation
4859 cmdStr = "value-test {} {} {}".format( valueName,
4860 operation,
4861 newValue )
4862 output = self.distPrimitivesSend( cmdStr )
4863 pattern = "(\w+)"
4864 match = re.search( pattern, output )
4865 if match:
4866 return match.group( 1 )
4867 else:
4868 main.log.error( self.name + ": valueTestGetAndSet did not" +
4869 " match expected output." )
4870 main.log.debug( self.name + " expected: " + pattern )
4871 main.log.debug( self.name + " actual: " + repr( output ) )
4872 return None
4873 except TypeError:
4874 main.log.exception( self.name + ": Object not as expected" )
4875 return None
4876 except Exception:
4877 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004878 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004879
4880 def valueTestDestroy( self, valueName ):
4881 """
4882 CLI command to destroy an atomic value.
4883 Required arguments:
4884 valueName - The name of the value to destroy.
4885 returns:
4886 main.TRUE on success or
4887 main.ERROR on Error
4888 """
4889 try:
4890 valueName = str( valueName )
4891 cmdStr = "value-test "
4892 operation = "destroy"
4893 cmdStr += valueName + " " + operation
4894 output = self.distPrimitivesSend( cmdStr )
4895 if output is not None:
4896 return main.TRUE
4897 else:
4898 return main.ERROR
4899 except TypeError:
4900 main.log.exception( self.name + ": Object not as expected" )
4901 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004902 except Exception:
4903 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004904 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004905
YPZhangfebf7302016-05-24 16:45:56 -07004906 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004907 """
4908 Description: Execute summary command in onos
4909 Returns: json object ( summary -j ), returns main.FALSE if there is
4910 no output
4911
4912 """
4913 try:
4914 cmdStr = "summary"
4915 if jsonFormat:
4916 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004917 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004918 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004919 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004920 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004921 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004922 if not handle:
4923 main.log.error( self.name + ": There is no output in " +
4924 "summary command" )
4925 return main.FALSE
4926 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004927 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004928 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004929 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004930 except TypeError:
4931 main.log.exception( self.name + ": Object not as expected" )
4932 return None
4933 except pexpect.EOF:
4934 main.log.error( self.name + ": EOF exception found" )
4935 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004936 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004937 except Exception:
4938 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004939 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004940
Jon Hall06fd0df2021-01-25 15:50:06 -08004941 def getAddress( self):
4942 """
4943 Get the onos ip address from the cli. This is usefull when connecting using
4944 a container manager such as kubernetes. This function also sets self.address
4945 the value from ONOS.
4946
4947 Returns:
4948 The string value of the key or
4949 None on Error
4950 """
4951 try:
4952 output = self.summary()
4953 address = json.loads( output ).get( 'node' )
4954 self.address = address
4955 return address
You Wang327bad42021-03-24 14:19:58 -07004956 except ( TypeError, ValueError ):
Jon Hall06fd0df2021-01-25 15:50:06 -08004957 main.log.exception( self.name + ": Object not as expected" )
4958 return None
4959 except Exception:
4960 main.log.exception( self.name + ": Uncaught exception!" )
4961 main.cleanAndExit()
4962
Jon Hall935db192016-04-19 00:22:04 -07004963 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004964 """
4965 CLI command to get the value of a key in a consistent map using
4966 transactions. This a test function and can only get keys from the
4967 test map hard coded into the cli command
4968 Required arguments:
4969 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004970 returns:
4971 The string value of the key or
4972 None on Error
4973 """
4974 try:
4975 keyName = str( keyName )
4976 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004977 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004978 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004979 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4980 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004981 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004982 return None
4983 else:
4984 match = re.search( pattern, output )
4985 if match:
4986 return match.groupdict()[ 'value' ]
4987 else:
4988 main.log.error( self.name + ": transactionlMapGet did not" +
4989 " match expected output." )
4990 main.log.debug( self.name + " expected: " + pattern )
4991 main.log.debug( self.name + " actual: " + repr( output ) )
4992 return None
4993 except TypeError:
4994 main.log.exception( self.name + ": Object not as expected" )
4995 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004996 except Exception:
4997 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004998 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004999
Jon Hall935db192016-04-19 00:22:04 -07005000 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07005001 """
5002 CLI command to put a value into 'numKeys' number of keys in a
5003 consistent map using transactions. This a test function and can only
5004 put into keys named 'Key#' of the test map hard coded into the cli command
5005 Required arguments:
5006 numKeys - Number of keys to add the value to
5007 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07005008 returns:
5009 A dictionary whose keys are the name of the keys put into the map
5010 and the values of the keys are dictionaries whose key-values are
5011 'value': value put into map and optionaly
5012 'oldValue': Previous value in the key or
5013 None on Error
5014
5015 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005016 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
5017 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07005018 """
5019 try:
5020 numKeys = str( numKeys )
5021 value = str( value )
5022 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07005023 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07005024 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07005025 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
5026 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
5027 results = {}
5028 for line in output.splitlines():
5029 new = re.search( newPattern, line )
5030 updated = re.search( updatedPattern, line )
5031 if new:
5032 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
5033 elif updated:
5034 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08005035 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07005036 else:
5037 main.log.error( self.name + ": transactionlMapGet did not" +
5038 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08005039 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
5040 newPattern,
5041 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07005042 main.log.debug( self.name + " actual: " + repr( output ) )
5043 return results
Jon Hall0e240372018-05-02 11:21:57 -07005044 except ( TypeError, AttributeError ):
Jon Hall2a5002c2015-08-21 16:49:11 -07005045 main.log.exception( self.name + ": Object not as expected" )
5046 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07005047 except Exception:
5048 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005049 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08005050
acsmarsdaea66c2015-09-03 11:44:06 -07005051 def maps( self, jsonFormat=True ):
5052 """
5053 Description: Returns result of onos:maps
5054 Optional:
5055 * jsonFormat: enable json formatting of output
5056 """
5057 try:
5058 cmdStr = "maps"
5059 if jsonFormat:
5060 cmdStr += " -j"
5061 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07005062 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005063 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07005064 return handle
Jon Hallc6793552016-01-19 14:18:37 -08005065 except AssertionError:
5066 main.log.exception( "" )
5067 return None
acsmarsdaea66c2015-09-03 11:44:06 -07005068 except TypeError:
5069 main.log.exception( self.name + ": Object not as expected" )
5070 return None
5071 except pexpect.EOF:
5072 main.log.error( self.name + ": EOF exception found" )
5073 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005074 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07005075 except Exception:
5076 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005077 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005078
5079 def getSwController( self, uri, jsonFormat=True ):
5080 """
5081 Descrition: Gets the controller information from the device
5082 """
5083 try:
5084 cmd = "device-controllers "
5085 if jsonFormat:
5086 cmd += "-j "
5087 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07005088 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005089 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005090 return response
Jon Hallc6793552016-01-19 14:18:37 -08005091 except AssertionError:
5092 main.log.exception( "" )
5093 return None
GlennRC050596c2015-11-18 17:06:41 -08005094 except TypeError:
5095 main.log.exception( self.name + ": Object not as expected" )
5096 return None
5097 except pexpect.EOF:
5098 main.log.error( self.name + ": EOF exception found" )
5099 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005100 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005101 except Exception:
5102 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005103 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005104
5105 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
5106 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005107 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08005108
5109 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005110 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08005111 ip - String or List: The ip address of the controller.
5112 This parameter can be formed in a couple of different ways.
5113 VALID:
5114 10.0.0.1 - just the ip address
5115 tcp:10.0.0.1 - the protocol and the ip address
5116 tcp:10.0.0.1:6653 - the protocol and port can be specified,
5117 so that you can add controllers with different
5118 protocols and ports
5119 INVALID:
5120 10.0.0.1:6653 - this is not supported by ONOS
5121
5122 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
5123 port - The port number.
5124 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
5125
5126 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
5127 """
5128 try:
5129 cmd = "device-setcontrollers"
5130
5131 if jsonFormat:
5132 cmd += " -j"
5133 cmd += " " + uri
5134 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005135 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08005136 for item in ip:
5137 if ":" in item:
5138 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005139 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08005140 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005141 elif "." in sitem[ 1 ]:
5142 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08005143 else:
5144 main.log.error( "Malformed entry: " + item )
5145 raise TypeError
5146 else:
5147 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08005148 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07005149 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005150 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005151 if "Error" in response:
5152 main.log.error( response )
5153 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005154 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005155 except AssertionError:
5156 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005157 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005158 except TypeError:
5159 main.log.exception( self.name + ": Object not as expected" )
5160 return main.FALSE
5161 except pexpect.EOF:
5162 main.log.error( self.name + ": EOF exception found" )
5163 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005164 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005165 except Exception:
5166 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005167 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005168
5169 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005170 '''
GlennRC20fc6522015-12-23 23:26:57 -08005171 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005172 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08005173 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005174 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08005175 Returns:
5176 Returns main.FALSE if an exception is thrown or an error is present
5177 in the response. Otherwise, returns main.TRUE.
5178 NOTE:
5179 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005180 '''
GlennRC20fc6522015-12-23 23:26:57 -08005181 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005182 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07005183 deviceStr = device
5184 device = []
5185 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08005186
5187 for d in device:
5188 time.sleep( 1 )
5189 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07005190 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005191 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005192 if "Error" in response:
5193 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
5194 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005195 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005196 except AssertionError:
5197 main.log.exception( "" )
5198 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005199 except TypeError:
5200 main.log.exception( self.name + ": Object not as expected" )
5201 return main.FALSE
5202 except pexpect.EOF:
5203 main.log.error( self.name + ": EOF exception found" )
5204 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005205 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005206 except Exception:
5207 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005208 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005209
5210 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005211 '''
GlennRC20fc6522015-12-23 23:26:57 -08005212 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005213 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005214 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005215 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005216 Returns:
5217 Returns main.FALSE if an exception is thrown or an error is present
5218 in the response. Otherwise, returns main.TRUE.
5219 NOTE:
5220 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005221 '''
GlennRC20fc6522015-12-23 23:26:57 -08005222 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005223 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005224 host = list( host )
5225
5226 for h in host:
5227 time.sleep( 1 )
5228 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005229 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005230 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005231 if "Error" in response:
5232 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5233 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005234 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005235 except AssertionError:
5236 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005237 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005238 except TypeError:
5239 main.log.exception( self.name + ": Object not as expected" )
5240 return main.FALSE
5241 except pexpect.EOF:
5242 main.log.error( self.name + ": EOF exception found" )
5243 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005244 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005245 except Exception:
5246 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005247 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005248
YPZhangfebf7302016-05-24 16:45:56 -07005249 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005250 '''
GlennRCed771242016-01-13 17:02:47 -08005251 Description:
5252 Bring link down or up in the null-provider.
5253 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005254 begin - (string) One end of a device or switch.
5255 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005256 returns:
5257 main.TRUE if no exceptions were thrown and no Errors are
5258 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005259 '''
GlennRCed771242016-01-13 17:02:47 -08005260 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005261 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005262 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005263 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005264 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005265 if "Error" in response or "Failure" in response:
5266 main.log.error( response )
5267 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005268 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005269 except AssertionError:
5270 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005271 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005272 except TypeError:
5273 main.log.exception( self.name + ": Object not as expected" )
5274 return main.FALSE
5275 except pexpect.EOF:
5276 main.log.error( self.name + ": EOF exception found" )
5277 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005278 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005279 except Exception:
5280 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005281 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005282
Jon Hall2c8959e2016-12-16 12:17:34 -08005283 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005284 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005285 Description:
5286 Changes the state of port in an OF switch by means of the
5287 PORTSTATUS OF messages.
5288 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005289 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5290 port - (string) target port in the device. Ex: '2'
5291 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005292 returns:
5293 main.TRUE if no exceptions were thrown and no Errors are
5294 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005295 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005296 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005297 state = state.lower()
5298 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005299 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005300 response = self.sendline( cmd, showResponse=True )
5301 assert response is not None, "Error in sendline"
5302 assert "Command not found:" not in response, response
5303 if "Error" in response or "Failure" in response:
5304 main.log.error( response )
5305 return main.FALSE
5306 return main.TRUE
5307 except AssertionError:
5308 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005309 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005310 except TypeError:
5311 main.log.exception( self.name + ": Object not as expected" )
5312 return main.FALSE
5313 except pexpect.EOF:
5314 main.log.error( self.name + ": EOF exception found" )
5315 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005316 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005317 except Exception:
5318 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005319 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005320
5321 def logSet( self, level="INFO", app="org.onosproject" ):
5322 """
5323 Set the logging level to lvl for a specific app
5324 returns main.TRUE on success
5325 returns main.FALSE if Error occurred
5326 if noExit is True, TestON will not exit, but clean up
5327 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5328 Level defaults to INFO
5329 """
5330 try:
You Wang22e807e2021-03-29 10:53:38 -07005331 handle = self.sendline( "log:set %s %s" % ( level, app ) )
5332 assert handle is not None, "Error in sendline"
5333 assert "Command not found:" not in handle, handle
5334 if re.search( "Error", handle ):
5335 main.log.error( self.name + ": Error in setting log level" )
5336 main.log.error( handle )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005337 return main.FALSE
You Wang22e807e2021-03-29 10:53:38 -07005338 else:
5339 return main.TRUE
5340 except AssertionError:
5341 main.log.exception( "" )
5342 return None
5343 except TypeError:
5344 main.log.exception( self.name + ": Object not as expected" )
5345 return None
Flavio Castro82ee2f62016-06-07 15:04:12 -07005346 except pexpect.EOF:
5347 main.log.error( self.name + ": EOF exception found" )
5348 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005349 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005350 except Exception:
5351 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005352 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005353
Jon Hall06fd0df2021-01-25 15:50:06 -08005354 def logList( self, saveValues=True ):
5355 """
5356 Gets the current log levels and optionally saves them
5357 returns a dict of the log levels or
5358 returns main.FALSE if Error occurred
5359 """
5360 try:
5361 self.handle.sendline( "log:list" )
5362 self.handle.expect( self.karafPrompt )
5363
5364 response = self.handle.before
5365 logLevels = {}
5366 for line in response.splitlines():
5367 parsed = line.split('│')
5368 logger = parsed[0].strip()
5369 if len( parsed ) != 2 or 'Level' in parsed[1] or logger[0] == '─':
5370 continue
5371 level = parsed[1].strip()
5372 logLevels[ logger ] = level
5373 if saveValues:
5374 self.logLevels = logLevels
5375 return logLevels
5376 except pexpect.TIMEOUT:
5377 main.log.exception( self.name + ": TIMEOUT exception found" )
5378 main.cleanAndExit()
5379 except pexpect.EOF:
5380 main.log.error( self.name + ": EOF exception found" )
5381 main.log.error( self.name + ": " + self.handle.before )
5382 main.cleanAndExit()
5383 except Exception:
5384 main.log.exception( self.name + ": Uncaught exception!" )
5385 main.cleanAndExit()
5386
You Wangdb8cd0a2016-05-26 15:19:45 -07005387 def getGraphDict( self, timeout=60, includeHost=False ):
5388 """
5389 Return a dictionary which describes the latest network topology data as a
5390 graph.
5391 An example of the dictionary:
5392 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5393 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5394 Each vertex should at least have an 'edges' attribute which describes the
5395 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005396 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005397 list of attributes.
5398 An example of the edges dictionary:
5399 'edges': { vertex2: { 'port': ..., 'weight': ... },
5400 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005401 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005402 in topology data.
5403 """
5404 graphDict = {}
5405 try:
5406 links = self.links()
5407 links = json.loads( links )
5408 devices = self.devices()
5409 devices = json.loads( devices )
5410 idToDevice = {}
5411 for device in devices:
5412 idToDevice[ device[ 'id' ] ] = device
5413 if includeHost:
5414 hosts = self.hosts()
5415 # FIXME: support 'includeHost' argument
5416 for link in links:
5417 nodeA = link[ 'src' ][ 'device' ]
5418 nodeB = link[ 'dst' ][ 'device' ]
5419 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005420 if nodeA not in graphDict.keys():
5421 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005422 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005423 'type': idToDevice[ nodeA ][ 'type' ],
5424 'available': idToDevice[ nodeA ][ 'available' ],
5425 'role': idToDevice[ nodeA ][ 'role' ],
5426 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5427 'hw': idToDevice[ nodeA ][ 'hw' ],
5428 'sw': idToDevice[ nodeA ][ 'sw' ],
5429 'serial': idToDevice[ nodeA ][ 'serial' ],
5430 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005431 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005432 else:
5433 # Assert nodeB is not connected to any current links of nodeA
You Wang7d14d642019-01-23 15:10:08 -08005434 # assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
5435 pass
Jon Halle0f0b342017-04-18 11:43:47 -07005436 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5437 'type': link[ 'type' ],
5438 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005439 return graphDict
5440 except ( TypeError, ValueError ):
5441 main.log.exception( self.name + ": Object not as expected" )
5442 return None
5443 except KeyError:
5444 main.log.exception( self.name + ": KeyError exception found" )
5445 return None
5446 except AssertionError:
5447 main.log.exception( self.name + ": AssertionError exception found" )
5448 return None
5449 except pexpect.EOF:
5450 main.log.error( self.name + ": EOF exception found" )
5451 main.log.error( self.name + ": " + self.handle.before )
5452 return None
5453 except Exception:
5454 main.log.exception( self.name + ": Uncaught exception!" )
5455 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005456
5457 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005458 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005459 Send command to check intent-perf summary
5460 Returns: dictionary for intent-perf summary
5461 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005462 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005463 cmd = "intent-perf -s"
5464 respDic = {}
5465 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005466 assert resp is not None, "Error in sendline"
5467 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005468 try:
5469 # Generate the dictionary to return
5470 for l in resp.split( "\n" ):
5471 # Delete any white space in line
5472 temp = re.sub( r'\s+', '', l )
5473 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005474 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005475
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005476 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005477 main.log.exception( self.name + ": Object not as expected" )
5478 return None
5479 except KeyError:
5480 main.log.exception( self.name + ": KeyError exception found" )
5481 return None
5482 except AssertionError:
5483 main.log.exception( self.name + ": AssertionError exception found" )
5484 return None
5485 except pexpect.EOF:
5486 main.log.error( self.name + ": EOF exception found" )
5487 main.log.error( self.name + ": " + self.handle.before )
5488 return None
5489 except Exception:
5490 main.log.exception( self.name + ": Uncaught exception!" )
5491 return None
5492 return respDic
5493
Chiyu Chengec63bde2016-11-17 18:11:36 -08005494 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005495 """
5496 Searches the latest ONOS log file for the given search term and
5497 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005498
chengchiyu08303a02016-09-08 17:40:26 -07005499 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005500 searchTerm:
5501 The string to grep from the ONOS log.
5502 startLine:
5503 The term that decides which line is the start to search the searchTerm in
5504 the karaf log. For now, startTerm only works in 'first' mode.
5505 logNum:
5506 In some extreme cases, one karaf log is not big enough to contain all the
5507 information.Because of this, search mutiply logs is necessary to capture
5508 the right result. logNum is the number of karaf logs that we need to search
5509 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005510 mode:
5511 all: return all the strings that contain the search term
5512 last: return the last string that contains the search term
5513 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005514 num: return the number of times that the searchTerm appears in the log
5515 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005516 """
5517 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005518 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005519 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005520 logPath = '/opt/onos/log/karaf.log.'
5521 logPaths = '/opt/onos/log/karaf.log'
5522 for i in range( 1, logNum ):
5523 logPaths = logPath + str( i ) + " " + logPaths
5524 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005525 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005526 # 100000000 is just a extreme large number to make sure this function can
5527 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005528 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005529 if mode == 'all':
5530 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005531 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005532 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005533 elif mode == 'first':
5534 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5535 elif mode == 'num':
You Wangd91a70f2019-01-03 15:28:10 -08005536 cmd = cmd + " | grep \'" + searchTerm + "\' | wc -l"
5537 num = self.lineCount( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005538 return num
You Wang6d301d42017-04-21 10:49:33 -07005539 elif mode == 'total':
Jon Halld5a94fb2018-11-13 14:32:23 -08005540 totalLines = self.lineCount( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005541 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005542 else:
5543 main.log.error( self.name + " unsupported mode" )
5544 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005545 before = self.sendline( cmd )
5546 before = before.splitlines()
5547 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005548 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005549 return returnLines
5550 except AssertionError:
5551 main.log.error( self.name + " searchTerm is not string type" )
5552 return None
5553 except pexpect.EOF:
5554 main.log.error( self.name + ": EOF exception found" )
5555 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005556 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005557 except pexpect.TIMEOUT:
5558 main.log.error( self.name + ": TIMEOUT exception found" )
5559 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005560 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005561 except Exception:
5562 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005563 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005564
5565 def vplsShow( self, jsonFormat=True ):
5566 """
5567 Description: Returns result of onos:vpls show, which should list the
5568 configured VPLS networks and the assigned interfaces.
5569 Optional:
5570 * jsonFormat: enable json formatting of output
5571 Returns:
5572 The output of the command or None on error.
5573 """
5574 try:
5575 cmdStr = "vpls show"
5576 if jsonFormat:
5577 raise NotImplementedError
5578 cmdStr += " -j"
5579 handle = self.sendline( cmdStr )
5580 assert handle is not None, "Error in sendline"
5581 assert "Command not found:" not in handle, handle
5582 return handle
5583 except AssertionError:
5584 main.log.exception( "" )
5585 return None
5586 except TypeError:
5587 main.log.exception( self.name + ": Object not as expected" )
5588 return None
5589 except pexpect.EOF:
5590 main.log.error( self.name + ": EOF exception found" )
5591 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005592 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005593 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005594 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005595 return None
5596 except Exception:
5597 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005598 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005599
5600 def parseVplsShow( self ):
5601 """
5602 Parse the cli output of 'vpls show' into json output. This is required
5603 as there is currently no json output available.
5604 """
5605 try:
5606 output = []
5607 raw = self.vplsShow( jsonFormat=False )
5608 namePat = "VPLS name: (?P<name>\w+)"
5609 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5610 encapPat = "Encapsulation: (?P<encap>\w+)"
5611 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5612 mIter = re.finditer( pattern, raw )
5613 for match in mIter:
5614 item = {}
5615 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005616 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005617 if ifaces == [ "" ]:
5618 ifaces = []
5619 item[ 'interfaces' ] = ifaces
5620 encap = match.group( 'encap' )
5621 if encap != 'NONE':
5622 item[ 'encapsulation' ] = encap.lower()
5623 output.append( item )
5624 return output
5625 except Exception:
5626 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005627 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005628
5629 def vplsList( self, jsonFormat=True ):
5630 """
5631 Description: Returns result of onos:vpls list, which should list the
5632 configured VPLS networks.
5633 Optional:
5634 * jsonFormat: enable json formatting of output
5635 """
5636 try:
5637 cmdStr = "vpls list"
5638 if jsonFormat:
5639 raise NotImplementedError
5640 cmdStr += " -j"
5641 handle = self.sendline( cmdStr )
5642 assert handle is not None, "Error in sendline"
5643 assert "Command not found:" not in handle, handle
5644 return handle
5645 except AssertionError:
5646 main.log.exception( "" )
5647 return None
5648 except TypeError:
5649 main.log.exception( self.name + ": Object not as expected" )
5650 return None
5651 except pexpect.EOF:
5652 main.log.error( self.name + ": EOF exception found" )
5653 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005654 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005655 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005656 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005657 return None
5658 except Exception:
5659 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005660 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005661
5662 def vplsCreate( self, network ):
5663 """
5664 CLI command to create a new VPLS network.
5665 Required arguments:
5666 network - String name of the network to create.
5667 returns:
5668 main.TRUE on success and main.FALSE on failure
5669 """
5670 try:
5671 network = str( network )
5672 cmdStr = "vpls create "
5673 cmdStr += network
5674 output = self.sendline( cmdStr )
5675 assert output is not None, "Error in sendline"
5676 assert "Command not found:" not in output, output
5677 assert "Error executing command" not in output, output
5678 assert "VPLS already exists:" not in output, output
5679 return main.TRUE
5680 except AssertionError:
5681 main.log.exception( "" )
5682 return main.FALSE
5683 except TypeError:
5684 main.log.exception( self.name + ": Object not as expected" )
5685 return main.FALSE
5686 except pexpect.EOF:
5687 main.log.error( self.name + ": EOF exception found" )
5688 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005689 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005690 except Exception:
5691 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005692 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005693
5694 def vplsDelete( self, network ):
5695 """
5696 CLI command to delete a VPLS network.
5697 Required arguments:
5698 network - Name of the network to delete.
5699 returns:
5700 main.TRUE on success and main.FALSE on failure
5701 """
5702 try:
5703 network = str( network )
5704 cmdStr = "vpls delete "
5705 cmdStr += network
5706 output = self.sendline( cmdStr )
5707 assert output is not None, "Error in sendline"
5708 assert "Command not found:" not in output, output
5709 assert "Error executing command" not in output, output
5710 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005711 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005712 return main.TRUE
5713 except AssertionError:
5714 main.log.exception( "" )
5715 return main.FALSE
5716 except TypeError:
5717 main.log.exception( self.name + ": Object not as expected" )
5718 return main.FALSE
5719 except pexpect.EOF:
5720 main.log.error( self.name + ": EOF exception found" )
5721 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005722 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005723 except Exception:
5724 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005725 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005726
5727 def vplsAddIface( self, network, iface ):
5728 """
5729 CLI command to add an interface to a VPLS network.
5730 Required arguments:
5731 network - Name of the network to add the interface to.
5732 iface - The ONOS name for an interface.
5733 returns:
5734 main.TRUE on success and main.FALSE on failure
5735 """
5736 try:
5737 network = str( network )
5738 iface = str( iface )
5739 cmdStr = "vpls add-if "
5740 cmdStr += network + " " + iface
5741 output = self.sendline( cmdStr )
5742 assert output is not None, "Error in sendline"
5743 assert "Command not found:" not in output, output
5744 assert "Error executing command" not in output, output
5745 assert "already associated to network" not in output, output
5746 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005747 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005748 return main.TRUE
5749 except AssertionError:
5750 main.log.exception( "" )
5751 return main.FALSE
5752 except TypeError:
5753 main.log.exception( self.name + ": Object not as expected" )
5754 return main.FALSE
5755 except pexpect.EOF:
5756 main.log.error( self.name + ": EOF exception found" )
5757 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005758 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005759 except Exception:
5760 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005761 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005762
5763 def vplsRemIface( self, network, iface ):
5764 """
5765 CLI command to remove an interface from a VPLS network.
5766 Required arguments:
5767 network - Name of the network to remove the interface from.
5768 iface - Name of the interface to remove.
5769 returns:
5770 main.TRUE on success and main.FALSE on failure
5771 """
5772 try:
5773 iface = str( iface )
5774 cmdStr = "vpls rem-if "
5775 cmdStr += network + " " + iface
5776 output = self.sendline( cmdStr )
5777 assert output is not None, "Error in sendline"
5778 assert "Command not found:" not in output, output
5779 assert "Error executing command" not in output, output
5780 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005781 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005782 return main.TRUE
5783 except AssertionError:
5784 main.log.exception( "" )
5785 return main.FALSE
5786 except TypeError:
5787 main.log.exception( self.name + ": Object not as expected" )
5788 return main.FALSE
5789 except pexpect.EOF:
5790 main.log.error( self.name + ": EOF exception found" )
5791 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005792 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005793 except Exception:
5794 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005795 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005796
5797 def vplsClean( self ):
5798 """
5799 Description: Clears the VPLS app configuration.
5800 Returns: main.TRUE on success and main.FALSE on failure
5801 """
5802 try:
5803 cmdStr = "vpls clean"
5804 handle = self.sendline( cmdStr )
5805 assert handle is not None, "Error in sendline"
5806 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005807 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005808 return handle
5809 except AssertionError:
5810 main.log.exception( "" )
5811 return main.FALSE
5812 except TypeError:
5813 main.log.exception( self.name + ": Object not as expected" )
5814 return main.FALSE
5815 except pexpect.EOF:
5816 main.log.error( self.name + ": EOF exception found" )
5817 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005818 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005819 except Exception:
5820 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005821 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005822
5823 def vplsSetEncap( self, network, encapType ):
5824 """
5825 CLI command to add an interface to a VPLS network.
5826 Required arguments:
5827 network - Name of the network to create.
5828 encapType - Type of encapsulation.
5829 returns:
5830 main.TRUE on success and main.FALSE on failure
5831 """
5832 try:
5833 network = str( network )
5834 encapType = str( encapType ).upper()
5835 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5836 cmdStr = "vpls set-encap "
5837 cmdStr += network + " " + encapType
5838 output = self.sendline( cmdStr )
5839 assert output is not None, "Error in sendline"
5840 assert "Command not found:" not in output, output
5841 assert "Error executing command" not in output, output
5842 assert "already associated to network" not in output, output
5843 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005844 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005845 return main.TRUE
5846 except AssertionError:
5847 main.log.exception( "" )
5848 return main.FALSE
5849 except TypeError:
5850 main.log.exception( self.name + ": Object not as expected" )
5851 return main.FALSE
5852 except pexpect.EOF:
5853 main.log.error( self.name + ": EOF exception found" )
5854 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005855 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005856 except Exception:
5857 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005858 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005859
5860 def interfaces( self, jsonFormat=True ):
5861 """
5862 Description: Returns result of interfaces command.
5863 Optional:
5864 * jsonFormat: enable json formatting of output
5865 Returns:
5866 The output of the command or None on error.
5867 """
5868 try:
5869 cmdStr = "interfaces"
5870 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005871 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005872 cmdStr += " -j"
5873 handle = self.sendline( cmdStr )
5874 assert handle is not None, "Error in sendline"
5875 assert "Command not found:" not in handle, handle
5876 return handle
5877 except AssertionError:
5878 main.log.exception( "" )
5879 return None
5880 except TypeError:
5881 main.log.exception( self.name + ": Object not as expected" )
5882 return None
5883 except pexpect.EOF:
5884 main.log.error( self.name + ": EOF exception found" )
5885 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005886 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005887 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005888 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005889 return None
5890 except Exception:
5891 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005892 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005893
5894 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005895 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005896 Get the timestamp of searchTerm from karaf log.
5897
5898 Arguments:
5899 splitTerm_before and splitTerm_after:
5900
5901 The terms that split the string that contains the timeStamp of
5902 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5903 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5904 and the splitTerm_after is "x"
5905
5906 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005907 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005908 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005909 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005910 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005911 return main.ERROR
5912 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005913 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005914 main.log.warn( "Captured timestamp string is empty" )
5915 return main.ERROR
5916 lines = lines[ 0 ]
5917 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005918 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005919 # get the target value
5920 line = lines.split( splitTerm_before )
5921 key = line[ 1 ].split( splitTerm_after )
5922 return int( key[ 0 ] )
5923 except IndexError:
5924 main.log.warn( "Index Error!" )
5925 return main.ERROR
5926 except AssertionError:
5927 main.log.warn( "Search Term Not Found " )
5928 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005929
5930 def workQueueAdd( self, queueName, value ):
5931 """
5932 CLI command to add a string to the specified Work Queue.
5933 This function uses the distributed primitives test app, which
5934 gives some cli access to distributed primitives for testing
5935 purposes only.
5936
5937 Required arguments:
5938 queueName - The name of the queue to add to
5939 value - The value to add to the queue
5940 returns:
5941 main.TRUE on success, main.FALSE on failure and
5942 main.ERROR on error.
5943 """
5944 try:
5945 queueName = str( queueName )
5946 value = str( value )
5947 prefix = "work-queue-test"
5948 operation = "add"
5949 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5950 output = self.distPrimitivesSend( cmdStr )
5951 if "Invalid operation name" in output:
5952 main.log.warn( output )
5953 return main.ERROR
5954 elif "Done" in output:
5955 return main.TRUE
5956 except TypeError:
5957 main.log.exception( self.name + ": Object not as expected" )
5958 return main.ERROR
5959 except Exception:
5960 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005961 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005962
5963 def workQueueAddMultiple( self, queueName, value1, value2 ):
5964 """
5965 CLI command to add two strings to the specified Work Queue.
5966 This function uses the distributed primitives test app, which
5967 gives some cli access to distributed primitives for testing
5968 purposes only.
5969
5970 Required arguments:
5971 queueName - The name of the queue to add to
5972 value1 - The first value to add to the queue
5973 value2 - The second value to add to the queue
5974 returns:
5975 main.TRUE on success, main.FALSE on failure and
5976 main.ERROR on error.
5977 """
5978 try:
5979 queueName = str( queueName )
5980 value1 = str( value1 )
5981 value2 = str( value2 )
5982 prefix = "work-queue-test"
5983 operation = "addMultiple"
5984 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5985 output = self.distPrimitivesSend( cmdStr )
5986 if "Invalid operation name" in output:
5987 main.log.warn( output )
5988 return main.ERROR
5989 elif "Done" in output:
5990 return main.TRUE
5991 except TypeError:
5992 main.log.exception( self.name + ": Object not as expected" )
5993 return main.ERROR
5994 except Exception:
5995 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005996 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005997
5998 def workQueueTakeAndComplete( self, queueName, number=1 ):
5999 """
6000 CLI command to take a value from the specified Work Queue and compelte it.
6001 This function uses the distributed primitives test app, which
6002 gives some cli access to distributed primitives for testing
6003 purposes only.
6004
6005 Required arguments:
6006 queueName - The name of the queue to add to
6007 number - The number of items to take and complete
6008 returns:
6009 main.TRUE on success, main.FALSE on failure and
6010 main.ERROR on error.
6011 """
6012 try:
6013 queueName = str( queueName )
6014 number = str( int( number ) )
6015 prefix = "work-queue-test"
6016 operation = "takeAndComplete"
6017 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
6018 output = self.distPrimitivesSend( cmdStr )
6019 if "Invalid operation name" in output:
6020 main.log.warn( output )
6021 return main.ERROR
6022 elif "Done" in output:
6023 return main.TRUE
6024 except TypeError:
6025 main.log.exception( self.name + ": Object not as expected" )
6026 return main.ERROR
6027 except Exception:
6028 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006029 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006030
6031 def workQueueDestroy( self, queueName ):
6032 """
6033 CLI command to destroy the specified Work Queue.
6034 This function uses the distributed primitives test app, which
6035 gives some cli access to distributed primitives for testing
6036 purposes only.
6037
6038 Required arguments:
6039 queueName - The name of the queue to add to
6040 returns:
6041 main.TRUE on success, main.FALSE on failure and
6042 main.ERROR on error.
6043 """
6044 try:
6045 queueName = str( queueName )
6046 prefix = "work-queue-test"
6047 operation = "destroy"
6048 cmdStr = " ".join( [ prefix, queueName, operation ] )
6049 output = self.distPrimitivesSend( cmdStr )
6050 if "Invalid operation name" in output:
6051 main.log.warn( output )
6052 return main.ERROR
6053 return main.TRUE
6054 except TypeError:
6055 main.log.exception( self.name + ": Object not as expected" )
6056 return main.ERROR
6057 except Exception:
6058 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006059 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006060
6061 def workQueueTotalPending( self, queueName ):
6062 """
6063 CLI command to get the Total Pending items of the specified Work Queue.
6064 This function uses the distributed primitives test app, which
6065 gives some cli access to distributed primitives for testing
6066 purposes only.
6067
6068 Required arguments:
6069 queueName - The name of the queue to add to
6070 returns:
6071 The number of Pending items in the specified work queue or
6072 None on error
6073 """
6074 try:
6075 queueName = str( queueName )
6076 prefix = "work-queue-test"
6077 operation = "totalPending"
6078 cmdStr = " ".join( [ prefix, queueName, operation ] )
6079 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08006080 main.log.debug( self.name + ": work queue unparsed: " + output )
6081 output = output.split( "\r\n" )[ -1 ]
6082 main.log.debug( self.name + ": work queue parsed: " + output )
Jon Halle0f0b342017-04-18 11:43:47 -07006083 pattern = r'\d+'
6084 if "Invalid operation name" in output:
6085 main.log.warn( output )
6086 return None
6087 else:
6088 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006089 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006090 except ( AttributeError, TypeError ):
6091 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6092 return None
6093 except Exception:
6094 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006095 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006096
6097 def workQueueTotalCompleted( self, queueName ):
6098 """
6099 CLI command to get the Total Completed items of the specified Work Queue.
6100 This function uses the distributed primitives test app, which
6101 gives some cli access to distributed primitives for testing
6102 purposes only.
6103
6104 Required arguments:
6105 queueName - The name of the queue to add to
6106 returns:
6107 The number of complete items in the specified work queue or
6108 None on error
6109 """
6110 try:
6111 queueName = str( queueName )
6112 prefix = "work-queue-test"
6113 operation = "totalCompleted"
6114 cmdStr = " ".join( [ prefix, queueName, operation ] )
6115 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08006116 main.log.debug( self.name + ": work queue unparsed: " + output )
6117 output = output.split( "\r\n" )[ -1 ]
6118 main.log.debug( self.name + ": work queue parsed: " + output )
Jon Halle0f0b342017-04-18 11:43:47 -07006119 pattern = r'\d+'
6120 if "Invalid operation name" in output:
6121 main.log.warn( output )
6122 return None
6123 else:
6124 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006125 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006126 except ( AttributeError, TypeError ):
6127 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6128 return None
6129 except Exception:
6130 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006131 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006132
6133 def workQueueTotalInProgress( self, queueName ):
6134 """
6135 CLI command to get the Total In Progress items of the specified Work Queue.
6136 This function uses the distributed primitives test app, which
6137 gives some cli access to distributed primitives for testing
6138 purposes only.
6139
6140 Required arguments:
6141 queueName - The name of the queue to add to
6142 returns:
6143 The number of In Progress items in the specified work queue or
6144 None on error
6145 """
6146 try:
6147 queueName = str( queueName )
6148 prefix = "work-queue-test"
6149 operation = "totalInProgress"
6150 cmdStr = " ".join( [ prefix, queueName, operation ] )
6151 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08006152 main.log.debug( self.name + ": work queue unparsed: " + output )
6153 output = output.split( "\r\n" )[ -1 ]
6154 main.log.debug( self.name + ": work queue parsed: " + output )
Jon Halle0f0b342017-04-18 11:43:47 -07006155 pattern = r'\d+'
6156 if "Invalid operation name" in output:
6157 main.log.warn( output )
6158 return None
6159 else:
6160 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006161 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006162 except ( AttributeError, TypeError ):
6163 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6164 return None
6165 except Exception:
6166 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006167 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00006168
6169 def events( self, args='-a' ):
6170 """
6171 Description: Returns events -a command output
6172 Optional:
6173 add other arguments
6174 """
6175 try:
6176 cmdStr = "events"
6177 if args:
6178 cmdStr += " " + args
6179 handle = self.sendline( cmdStr )
6180 assert handle is not None, "Error in sendline"
6181 assert "Command not found:" not in handle, handle
6182 return handle
6183 except AssertionError:
6184 main.log.exception( "" )
6185 return None
6186 except TypeError:
6187 main.log.exception( self.name + ": Object not as expected" )
6188 return None
6189 except pexpect.EOF:
6190 main.log.error( self.name + ": EOF exception found" )
6191 main.log.error( self.name + ": " + self.handle.before )
6192 main.cleanAndExit()
6193 except Exception:
6194 main.log.exception( self.name + ": Uncaught exception!" )
6195 main.cleanAndExit()
6196
6197 def getMaster( self, deviceID ):
6198 """
6199 Description: Obtains current master using "roles" command for a specific deviceID
6200 """
6201 try:
6202 return str( self.getRole( deviceID )[ 'master' ] )
6203 except AssertionError:
6204 main.log.exception( "" )
6205 return None
6206 except TypeError:
6207 main.log.exception( self.name + ": Object not as expected" )
6208 return None
6209 except pexpect.EOF:
6210 main.log.error( self.name + ": EOF exception found" )
6211 main.log.error( self.name + ": " + self.handle.before )
6212 main.cleanAndExit()
6213 except Exception:
6214 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07006215 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08006216
6217 def issu( self ):
6218 """
6219 Short summary of In-Service Software Upgrade status
6220
6221 Returns the output of the cli command or None on Error
6222 """
6223 try:
6224 cmdStr = "issu"
6225 handle = self.sendline( cmdStr )
6226 assert handle is not None, "Error in sendline"
6227 assert "Command not found:" not in handle, handle
6228 assert "Unsupported command:" not in handle, handle
6229 return handle
6230 except AssertionError:
6231 main.log.exception( "" )
6232 return None
6233 except TypeError:
6234 main.log.exception( self.name + ": Object not as expected" )
6235 return None
6236 except pexpect.EOF:
6237 main.log.error( self.name + ": EOF exception found" )
6238 main.log.error( self.name + ": " + self.handle.before )
6239 main.cleanAndExit()
6240 except Exception:
6241 main.log.exception( self.name + ": Uncaught exception!" )
6242 main.cleanAndExit()
6243
6244 def issuInit( self ):
6245 """
6246 Initiates an In-Service Software Upgrade
6247
6248 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6249 """
6250 try:
6251 cmdStr = "issu init"
6252 handle = self.sendline( cmdStr )
6253 assert handle is not None, "Error in sendline"
6254 assert "Command not found:" not in handle, handle
6255 assert "Unsupported command:" not in handle, handle
6256 if "Initialized" in handle:
6257 return main.TRUE
6258 else:
6259 return main.FALSE
6260 except AssertionError:
6261 main.log.exception( "" )
6262 return main.ERROR
6263 except TypeError:
6264 main.log.exception( self.name + ": Object not as expected" )
6265 return main.ERROR
6266 except pexpect.EOF:
6267 main.log.error( self.name + ": EOF exception found" )
6268 main.log.error( self.name + ": " + self.handle.before )
6269 main.cleanAndExit()
6270 except Exception:
6271 main.log.exception( self.name + ": Uncaught exception!" )
6272 main.cleanAndExit()
6273
6274 def issuUpgrade( self ):
6275 """
6276 Transitions stores to upgraded nodes
6277
6278 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6279 """
6280 try:
6281 cmdStr = "issu upgrade"
6282 handle = self.sendline( cmdStr )
6283 assert handle is not None, "Error in sendline"
6284 assert "Command not found:" not in handle, handle
6285 assert "Unsupported command:" not in handle, handle
6286 if "Upgraded" in handle:
6287 return main.TRUE
6288 else:
6289 return main.FALSE
6290 except AssertionError:
6291 main.log.exception( "" )
6292 return main.ERROR
6293 except TypeError:
6294 main.log.exception( self.name + ": Object not as expected" )
6295 return main.ERROR
6296 except pexpect.EOF:
6297 main.log.error( self.name + ": EOF exception found" )
6298 main.log.error( self.name + ": " + self.handle.before )
6299 main.cleanAndExit()
6300 except Exception:
6301 main.log.exception( self.name + ": Uncaught exception!" )
6302 main.cleanAndExit()
6303
6304 def issuCommit( self ):
6305 """
6306 Finalizes an In-Service Software Upgrade
6307
6308 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6309 """
6310 try:
6311 cmdStr = "issu commit"
6312 handle = self.sendline( cmdStr )
6313 assert handle is not None, "Error in sendline"
6314 assert "Command not found:" not in handle, handle
6315 assert "Unsupported command:" not in handle, handle
6316 # TODO: Check the version returned by this command
6317 if "Committed version" in handle:
6318 return main.TRUE
6319 else:
6320 return main.FALSE
6321 except AssertionError:
6322 main.log.exception( "" )
6323 return main.ERROR
6324 except TypeError:
6325 main.log.exception( self.name + ": Object not as expected" )
6326 return main.ERROR
6327 except pexpect.EOF:
6328 main.log.error( self.name + ": EOF exception found" )
6329 main.log.error( self.name + ": " + self.handle.before )
6330 main.cleanAndExit()
6331 except Exception:
6332 main.log.exception( self.name + ": Uncaught exception!" )
6333 main.cleanAndExit()
6334
6335 def issuRollback( self ):
6336 """
6337 Rolls back an In-Service Software Upgrade
6338
6339 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6340 """
6341 try:
6342 cmdStr = "issu rollback"
6343 handle = self.sendline( cmdStr )
6344 assert handle is not None, "Error in sendline"
6345 assert "Command not found:" not in handle, handle
6346 assert "Unsupported command:" not in handle, handle
6347 # TODO: Check the version returned by this command
6348 if "Rolled back to version" in handle:
6349 return main.TRUE
6350 else:
6351 return main.FALSE
6352 except AssertionError:
6353 main.log.exception( "" )
6354 return main.ERROR
6355 except TypeError:
6356 main.log.exception( self.name + ": Object not as expected" )
6357 return main.ERROR
6358 except pexpect.EOF:
6359 main.log.error( self.name + ": EOF exception found" )
6360 main.log.error( self.name + ": " + self.handle.before )
6361 main.cleanAndExit()
6362 except Exception:
6363 main.log.exception( self.name + ": Uncaught exception!" )
6364 main.cleanAndExit()
6365
6366 def issuReset( self ):
6367 """
6368 Resets the In-Service Software Upgrade status after a rollback
6369
6370 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6371 """
6372 try:
6373 cmdStr = "issu reset"
6374 handle = self.sendline( cmdStr )
6375 assert handle is not None, "Error in sendline"
6376 assert "Command not found:" not in handle, handle
6377 assert "Unsupported command:" not in handle, handle
6378 # TODO: Check the version returned by this command
6379 if "Reset version" in handle:
6380 return main.TRUE
6381 else:
6382 return main.FALSE
6383 except AssertionError:
6384 main.log.exception( "" )
6385 return main.ERROR
6386 except TypeError:
6387 main.log.exception( self.name + ": Object not as expected" )
6388 return main.ERROR
6389 except pexpect.EOF:
6390 main.log.error( self.name + ": EOF exception found" )
6391 main.log.error( self.name + ": " + self.handle.before )
6392 main.cleanAndExit()
6393 except Exception:
6394 main.log.exception( self.name + ": Uncaught exception!" )
6395 main.cleanAndExit()
6396
6397 def issuStatus( self ):
6398 """
6399 Status of an In-Service Software Upgrade
6400
6401 Returns the output of the cli command or None on Error
6402 """
6403 try:
6404 cmdStr = "issu status"
6405 handle = self.sendline( cmdStr )
6406 assert handle is not None, "Error in sendline"
6407 assert "Command not found:" not in handle, handle
6408 assert "Unsupported command:" not in handle, handle
6409 return handle
6410 except AssertionError:
6411 main.log.exception( "" )
6412 return None
6413 except TypeError:
6414 main.log.exception( self.name + ": Object not as expected" )
6415 return None
6416 except pexpect.EOF:
6417 main.log.error( self.name + ": EOF exception found" )
6418 main.log.error( self.name + ": " + self.handle.before )
6419 main.cleanAndExit()
6420 except Exception:
6421 main.log.exception( self.name + ": Uncaught exception!" )
6422 main.cleanAndExit()
6423
6424 def issuVersion( self ):
6425 """
6426 Get the version of an In-Service Software Upgrade
6427
6428 Returns the output of the cli command or None on Error
6429 """
6430 try:
6431 cmdStr = "issu version"
6432 handle = self.sendline( cmdStr )
6433 assert handle is not None, "Error in sendline"
6434 assert "Command not found:" not in handle, handle
6435 assert "Unsupported command:" not in handle, handle
6436 return handle
6437 except AssertionError:
6438 main.log.exception( "" )
6439 return None
6440 except TypeError:
6441 main.log.exception( self.name + ": Object not as expected" )
6442 return None
6443 except pexpect.EOF:
6444 main.log.error( self.name + ": EOF exception found" )
6445 main.log.error( self.name + ": " + self.handle.before )
6446 main.cleanAndExit()
6447 except Exception:
6448 main.log.exception( self.name + ": Uncaught exception!" )
6449 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006450
6451 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6452 """
6453 Create a multicast route by calling 'mcast-join' command
6454 sIP: source IP of the multicast route
6455 groupIP: group IP of the multicast route
6456 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6457 dPorts: a list of destination ports of the multicast route
6458 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6459 """
6460 try:
6461 cmdStr = "mcast-join"
6462 cmdStr += " " + str( sIP )
6463 cmdStr += " " + str( groupIP )
6464 cmdStr += " " + str( sPort )
6465 assert isinstance( dPorts, list )
6466 for dPort in dPorts:
6467 cmdStr += " " + str( dPort )
6468 handle = self.sendline( cmdStr )
6469 assert handle is not None, "Error in sendline"
6470 assert "Command not found:" not in handle, handle
6471 assert "Unsupported command:" not in handle, handle
6472 assert "Error executing command" not in handle, handle
6473 if "Added the mcast route" in handle:
6474 return main.TRUE
6475 else:
6476 return main.FALSE
6477 except AssertionError:
6478 main.log.exception( "" )
6479 return None
6480 except TypeError:
6481 main.log.exception( self.name + ": Object not as expected" )
6482 return None
6483 except pexpect.EOF:
6484 main.log.error( self.name + ": EOF exception found" )
6485 main.log.error( self.name + ": " + self.handle.before )
6486 main.cleanAndExit()
6487 except Exception:
6488 main.log.exception( self.name + ": Uncaught exception!" )
6489 main.cleanAndExit()
6490
6491 def mcastDelete( self, sIP, groupIP, dPorts ):
6492 """
6493 Delete a multicast route by calling 'mcast-delete' command
6494 sIP: source IP of the multicast route
6495 groupIP: group IP of the multicast route
6496 dPorts: a list of destination ports of the multicast route
6497 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6498 """
6499 try:
6500 cmdStr = "mcast-delete"
6501 cmdStr += " " + str( sIP )
6502 cmdStr += " " + str( groupIP )
6503 assert isinstance( dPorts, list )
6504 for dPort in dPorts:
6505 cmdStr += " " + str( dPort )
6506 handle = self.sendline( cmdStr )
6507 assert handle is not None, "Error in sendline"
6508 assert "Command not found:" not in handle, handle
6509 assert "Unsupported command:" not in handle, handle
6510 assert "Error executing command" not in handle, handle
6511 if "Updated the mcast route" in handle:
6512 return main.TRUE
6513 else:
6514 return main.FALSE
6515 except AssertionError:
6516 main.log.exception( "" )
6517 return None
6518 except TypeError:
6519 main.log.exception( self.name + ": Object not as expected" )
6520 return None
6521 except pexpect.EOF:
6522 main.log.error( self.name + ": EOF exception found" )
6523 main.log.error( self.name + ": " + self.handle.before )
6524 main.cleanAndExit()
6525 except Exception:
6526 main.log.exception( self.name + ": Uncaught exception!" )
6527 main.cleanAndExit()
6528
6529 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6530 """
6531 Create a multicast route by calling 'mcast-host-join' command
6532 sAddr: we can provide * for ASM or a specific address for SSM
6533 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006534 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006535 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6536 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6537 """
6538 try:
6539 cmdStr = "mcast-host-join"
6540 cmdStr += " -sAddr " + str( sAddr )
6541 cmdStr += " -gAddr " + str( gAddr )
6542 assert isinstance( srcs, list )
6543 for src in srcs:
6544 cmdStr += " -srcs " + str( src )
6545 assert isinstance( sinks, list )
6546 for sink in sinks:
6547 cmdStr += " -sinks " + str( sink )
6548 handle = self.sendline( cmdStr )
6549 assert handle is not None, "Error in sendline"
6550 assert "Command not found:" not in handle, handle
6551 assert "Unsupported command:" not in handle, handle
6552 assert "Error executing command" not in handle, handle
6553 if "Added the mcast route" in handle:
6554 return main.TRUE
6555 else:
6556 return main.FALSE
6557 except AssertionError:
6558 main.log.exception( "" )
6559 return None
6560 except TypeError:
6561 main.log.exception( self.name + ": Object not as expected" )
6562 return None
6563 except pexpect.EOF:
6564 main.log.error( self.name + ": EOF exception found" )
6565 main.log.error( self.name + ": " + self.handle.before )
6566 main.cleanAndExit()
6567 except Exception:
6568 main.log.exception( self.name + ": Uncaught exception!" )
6569 main.cleanAndExit()
6570
6571 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6572 """
6573 Delete multicast sink(s) by calling 'mcast-host-delete' command
6574 sAddr: we can provide * for ASM or a specific address for SSM
6575 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006576 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006577 will delete the route if not specified
6578 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6579 """
6580 try:
6581 cmdStr = "mcast-host-delete"
6582 cmdStr += " -sAddr " + str( sAddr )
6583 cmdStr += " -gAddr " + str( gAddr )
6584 if host:
6585 cmdStr += " -h " + str( host )
6586 handle = self.sendline( cmdStr )
6587 assert handle is not None, "Error in sendline"
6588 assert "Command not found:" not in handle, handle
6589 assert "Unsupported command:" not in handle, handle
6590 assert "Error executing command" not in handle, handle
6591 if "Updated the mcast route" in handle:
6592 return main.TRUE
6593 elif "Deleted the mcast route" in handle:
6594 return main.TRUE
6595 else:
6596 return main.FALSE
6597 except AssertionError:
6598 main.log.exception( "" )
6599 return None
6600 except TypeError:
6601 main.log.exception( self.name + ": Object not as expected" )
6602 return None
6603 except pexpect.EOF:
6604 main.log.error( self.name + ": EOF exception found" )
6605 main.log.error( self.name + ": " + self.handle.before )
6606 main.cleanAndExit()
6607 except Exception:
6608 main.log.exception( self.name + ": Uncaught exception!" )
6609 main.cleanAndExit()
6610
You Wang547893e2018-05-08 13:34:59 -07006611 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6612 """
6613 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6614 sAddr: we can provide * for ASM or a specific address for SSM
6615 gAddr: specifies multicast group address
6616 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6617 will delete the route if not specified
6618 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6619 """
6620 try:
6621 cmdStr = "mcast-sink-delete"
6622 cmdStr += " -sAddr " + str( sAddr )
6623 cmdStr += " -gAddr " + str( gAddr )
6624 if sink:
6625 cmdStr += " -s " + str( sink )
6626 handle = self.sendline( cmdStr )
6627 assert handle is not None, "Error in sendline"
6628 assert "Command not found:" not in handle, handle
6629 assert "Unsupported command:" not in handle, handle
6630 assert "Error executing command" not in handle, handle
6631 if "Updated the mcast route" in handle:
6632 return main.TRUE
6633 elif "Deleted the mcast route" in handle:
6634 return main.TRUE
6635 else:
6636 return main.FALSE
6637 except AssertionError:
6638 main.log.exception( "" )
6639 return None
6640 except TypeError:
6641 main.log.exception( self.name + ": Object not as expected" )
6642 return None
6643 except pexpect.EOF:
6644 main.log.error( self.name + ": EOF exception found" )
6645 main.log.error( self.name + ": " + self.handle.before )
6646 main.cleanAndExit()
6647 except Exception:
6648 main.log.exception( self.name + ": Uncaught exception!" )
6649 main.cleanAndExit()
6650
You Wange24d6272018-03-27 21:18:50 -07006651 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6652 """
6653 Delete multicast src(s) by calling 'mcast-source-delete' command
6654 sAddr: we can provide * for ASM or a specific address for SSM
6655 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006656 srcs: a list of host IDs of the sources e.g. ["00:AA:00:00:01:05/40"],
You Wange24d6272018-03-27 21:18:50 -07006657 will delete the route if not specified
6658 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6659 """
6660 try:
6661 cmdStr = "mcast-source-delete"
6662 cmdStr += " -sAddr " + str( sAddr )
6663 cmdStr += " -gAddr " + str( gAddr )
6664 if srcs:
6665 assert isinstance( srcs, list )
6666 for src in srcs:
6667 cmdStr += " -src " + str( src )
6668 handle = self.sendline( cmdStr )
6669 assert handle is not None, "Error in sendline"
6670 assert "Command not found:" not in handle, handle
6671 assert "Unsupported command:" not in handle, handle
6672 assert "Error executing command" not in handle, handle
6673 if "Updated the mcast route" in handle:
6674 return main.TRUE
6675 elif "Deleted the mcast route" in handle:
6676 return main.TRUE
6677 else:
6678 return main.FALSE
6679 except AssertionError:
6680 main.log.exception( "" )
6681 return None
6682 except TypeError:
6683 main.log.exception( self.name + ": Object not as expected" )
6684 return None
6685 except pexpect.EOF:
6686 main.log.error( self.name + ": EOF exception found" )
6687 main.log.error( self.name + ": " + self.handle.before )
6688 main.cleanAndExit()
6689 except Exception:
6690 main.log.exception( self.name + ": Uncaught exception!" )
6691 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006692
6693 def netcfg( self, jsonFormat=True, args="" ):
6694 """
6695 Run netcfg cli command with given args
6696 """
6697 try:
6698 cmdStr = "netcfg"
6699 if jsonFormat:
6700 cmdStr = cmdStr + " -j"
6701 if args:
6702 cmdStr = cmdStr + " " + str( args )
6703 handle = self.sendline( cmdStr )
6704 assert handle is not None, "Error in sendline"
6705 assert "Command not found:" not in handle, handle
6706 assert "Unsupported command:" not in handle, handle
6707 assert "Error executing command" not in handle, handle
6708 return handle
6709 except AssertionError:
6710 main.log.exception( "" )
6711 return None
6712 except TypeError:
6713 main.log.exception( self.name + ": Object not as expected" )
6714 return None
6715 except pexpect.EOF:
6716 main.log.error( self.name + ": EOF exception found" )
6717 main.log.error( self.name + ": " + self.handle.before )
6718 main.cleanAndExit()
6719 except Exception:
6720 main.log.exception( self.name + ": Uncaught exception!" )
6721 main.cleanAndExit()
6722
You Wang0fa76e72018-05-18 11:33:25 -07006723 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True, simple=False ):
You Wang5da39c82018-04-26 22:55:08 -07006724 """
You Wang54b1d672018-06-11 16:44:13 -07006725 Compose and return a list of t3-troubleshoot cli commands for given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006726 Options:
6727 sAddr: IP address of the source host
6728 dAddr: IP address of the destination host
You Wang0fa76e72018-05-18 11:33:25 -07006729 ipv6: True if hosts are IPv6
6730 verbose: return verbose t3 output if True
6731 simple: compose command for t3-troubleshoot-simple if True
You Wang5da39c82018-04-26 22:55:08 -07006732 """
6733 try:
6734 # Collect information of both hosts from onos
6735 hosts = self.hosts()
6736 hosts = json.loads( hosts )
6737 sHost = None
6738 dHost = None
6739 for host in hosts:
6740 if sAddr in host[ "ipAddresses" ]:
6741 sHost = host
6742 elif dAddr in host[ "ipAddresses" ]:
6743 dHost = host
6744 if sHost and dHost:
6745 break
6746 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang54b1d672018-06-11 16:44:13 -07006747 cmdList = []
You Wang5d9527b2018-05-29 17:08:54 -07006748 if simple:
6749 assert dHost, "Not able to find host with IP {}".format( dAddr )
You Wang54b1d672018-06-11 16:44:13 -07006750 cmdStr = "t3-troubleshoot-simple"
6751 if verbose:
6752 cmdStr += " -vv"
6753 if ipv6:
6754 cmdStr += " -et ipv6"
You Wang0fa76e72018-05-18 11:33:25 -07006755 cmdStr += " {}/{} {}/{}".format( sHost[ "mac" ], sHost[ "vlan" ], dHost[ "mac" ], dHost[ "vlan" ] )
You Wang54b1d672018-06-11 16:44:13 -07006756 cmdList.append( cmdStr )
You Wang0fa76e72018-05-18 11:33:25 -07006757 else:
You Wang54b1d672018-06-11 16:44:13 -07006758 for location in sHost[ "locations" ]:
6759 cmdStr = "t3-troubleshoot"
6760 if verbose:
6761 cmdStr += " -vv"
6762 if ipv6:
6763 cmdStr += " -et ipv6"
6764 cmdStr += " -s " + str( sAddr )
6765 cmdStr += " -sp " + str( location[ "elementId" ] ) + "/" + str( location[ "port" ] )
6766 cmdStr += " -sm " + str( sHost[ "mac" ] )
6767 if sHost[ "vlan" ] != "None":
6768 cmdStr += " -vid " + sHost[ "vlan" ]
6769 cmdStr += " -d " + str( dAddr )
6770 netcfg = self.netcfg( args="devices {}".format( location[ "elementId" ] ) )
6771 netcfg = json.loads( netcfg )
6772 assert netcfg, "Failed to get netcfg"
6773 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6774 cmdList.append( cmdStr )
6775 return cmdList
You Wang5da39c82018-04-26 22:55:08 -07006776 except AssertionError:
6777 main.log.exception( "" )
6778 return None
6779 except ( KeyError, TypeError ):
6780 main.log.exception( self.name + ": Object not as expected" )
6781 return None
6782 except Exception:
6783 main.log.exception( self.name + ": Uncaught exception!" )
6784 main.cleanAndExit()
6785
6786 def t3( self, sAddr, dAddr, ipv6=False ):
6787 """
You Wang54b1d672018-06-11 16:44:13 -07006788 Run t3-troubleshoot cli commands for all posible routes given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006789 Options:
6790 sAddr: IP address of the source host
6791 dAddr: IP address of the destination host
6792 """
6793 try:
You Wang54b1d672018-06-11 16:44:13 -07006794 cmdList = self.composeT3Command( sAddr, dAddr, ipv6 )
6795 assert cmdList is not None, "composeT3Command returned None"
6796 t3Output = ""
6797 for cmdStr in cmdList:
6798 handle = self.sendline( cmdStr )
6799 assert handle is not None, "Error in sendline"
6800 assert "Command not found:" not in handle, handle
6801 assert "Unsupported command:" not in handle, handle
6802 assert "Error executing command" not in handle, handle
6803 assert "Tracing packet" in handle
6804 t3Output += handle
6805 return t3Output
You Wang5da39c82018-04-26 22:55:08 -07006806 except AssertionError:
6807 main.log.exception( "" )
6808 return None
6809 except pexpect.EOF:
6810 main.log.error( self.name + ": EOF exception found" )
6811 main.log.error( self.name + ": " + self.handle.before )
6812 main.cleanAndExit()
6813 except Exception:
6814 main.log.exception( self.name + ": Uncaught exception!" )
6815 main.cleanAndExit()
Jon Hall3c0114c2020-08-11 15:07:42 -07006816
6817 def prepareForCLI( self, debug=True, maxRetries=120 ):
6818 """
6819 Prepare docker container to connect to onos cli
6820 """
6821 try:
6822 # Wait for log files to be created
6823 ready = 0
6824 retries = 0
6825 while not ready and retries < maxRetries:
6826 retries += 1
6827 self.handle.sendline( "ls -al /root/onos/apache-karaf-*/data/log" )
6828 ready = self.handle.expect( [ "No such file or directory", self.dockerPrompt ] )
6829 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
6830 if not ready:
6831 self.handle.expect( self.dockerPrompt )
6832 time.sleep( 1 )
Jon Hall3c0114c2020-08-11 15:07:42 -07006833
6834 cmdList = []
6835 cmdList.append( "apt-get update" )
6836 cmdList.append( "apt-get install -y openssh-server" )
6837 # Some built in scripts are hardcoded
6838 cmdList.append( "ln -s /root/onos /opt/onos" )
6839 cmdList.append( "ln -s /root/onos/apache-karaf-*/data/log /opt/onos/log" )
6840 cmdList.append( "ls -al /opt/onos" )
6841 output = ""
6842 for cmdStr in cmdList:
6843 self.handle.sendline( cmdStr )
Jon Hall627b1572020-12-01 12:01:15 -08006844 self.handle.expect( self.dockerPrompt, timeout=420 )
Jon Hall3c0114c2020-08-11 15:07:42 -07006845 self.handle.sendline( "" )
6846 self.handle.expect( self.dockerPrompt )
6847 handle = self.handle.before
6848 assert "command not found" not in handle, handle
6849 assert "No such file or directory" not in handle, handle
6850 output += handle
6851 if debug:
6852 main.log.debug( "%s: %s" % ( self.name, output ) )
6853 return output
6854 except AssertionError:
6855 main.log.exception( "" )
6856 return None
6857 except pexpect.EOF:
6858 main.log.error( self.name + ": EOF exception found" )
6859 main.log.error( self.name + ": " + self.handle.before )
6860 main.cleanAndExit()
6861 except Exception:
6862 main.log.exception( self.name + ": Uncaught exception!" )
6863 main.cleanAndExit()
6864
6865 def onosSecureSSH( self, userName="onos", userPWD="rocks" ):
6866 """
6867 Enables secure access to ONOS console
6868 by removing default users & keys.
6869
6870 bin/onos-user-password onos rocks
6871
6872 Returns: main.TRUE on success and main.FALSE on failure
6873 """
6874
6875 try:
6876 self.handle.sendline( "" )
6877 self.handle.expect( self.dockerPrompt )
6878
6879 self.handle.sendline( "[ ! -f ~/.ssh/id_rsa.pub ] && ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' -q" )
6880 self.handle.expect( self.dockerPrompt )
6881 main.log.debug( "%s: %s%s" % ( self.name, self.handle.before, self.handle.after ) )
6882
6883 self.handle.sendline( "bin/onos-user-key $(id -un) $(cut -d\\\\ -f2 ~/.ssh/id_rsa.pub)" )
6884 self.handle.expect( pexpect.TIMEOUT, timeout=10 )
6885 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
6886
6887 self.handle.sendline( "bin/onos-user-password %s %s" % ( userName, userPWD ) )
6888 i = self.handle.expect( [ "usage",
6889 self.dockerPrompt,
6890 pexpect.TIMEOUT ] )
6891 if i == 0:
6892 # malformed command
6893 main.log.warn( self.name + ": Could not parse onos-user-password command" )
6894 self.handle.expect( self.dockerPrompt )
6895 return main.FALSE
6896 elif i == 1:
6897 # Process started
6898 main.log.info( self.name + ": SSH password added for user " + userName )
6899 return main.TRUE
6900 elif i == 2:
6901 # timeout
6902 main.log.error( self.name + ": Failed to secure onos ssh " )
6903 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
6904 except pexpect.EOF:
6905 main.log.error( self.name + ": EOF exception found" )
6906 main.log.error( self.name + ": " + self.handle.before )
6907 main.cleanAndExit()
6908 except Exception:
6909 main.log.exception( self.name + ": Uncaught exception!" )
6910 main.cleanAndExit()
Jon Hall62ab6752021-08-22 16:47:43 -07006911
6912 def routeAdd( self, prefix, nextHop, jsonFormat=True ):
6913 """
6914 Add a route with the given prefix and nextHop
6915 """
6916 try:
6917 cmdStr = "route-add %s %s %s" % ( "-j" if jsonFormat else "", prefix, nextHop )
6918 handle = self.sendline( cmdStr )
6919 assert handle is not None, "Error in sendline"
6920 assert "Command not found:" not in handle, handle
6921 assert "Unsupported command:" not in handle, handle
6922 assert "Error executing command" not in handle, handle
6923 return handle
6924 except AssertionError:
6925 main.log.exception( "" )
6926 return None
6927 except TypeError:
6928 main.log.exception( self.name + ": Object not as expected" )
6929 return None
6930 except pexpect.EOF:
6931 main.log.error( self.name + ": EOF exception found" )
6932 main.log.error( self.name + ": " + self.handle.before )
6933 main.cleanAndExit()
6934 except Exception:
6935 main.log.exception( self.name + ": Uncaught exception!" )
6936 main.cleanAndExit()
6937
6938 def routeRemove( self, prefix, nextHop, source=None, jsonFormat=True ):
6939 """
6940 Remove a route with the given prefix and nextHop
6941 """
6942 try:
6943 if source:
6944 raise NotImplemented
6945 cmdStr = "route-remove %s %s %s" % ( "-j" if jsonFormat else "", prefix, nextHop )
6946 handle = self.sendline( cmdStr )
6947 assert handle is not None, "Error in sendline"
6948 assert "Command not found:" not in handle, handle
6949 assert "Unsupported command:" not in handle, handle
6950 assert "Error executing command" not in handle, handle
6951 return handle
6952 except AssertionError:
6953 main.log.exception( "" )
6954 return None
6955 except TypeError:
6956 main.log.exception( self.name + ": Object not as expected" )
6957 return None
6958 except pexpect.EOF:
6959 main.log.error( self.name + ": EOF exception found" )
6960 main.log.error( self.name + ": " + self.handle.before )
6961 main.cleanAndExit()
6962 except Exception:
6963 main.log.exception( self.name + ": Uncaught exception!" )
6964 main.cleanAndExit()
6965
6966 def routes( self, jsonFormat=True, args="" ):
6967 """
6968 Get routes from ONOS
6969 """
6970 try:
6971 cmdStr = "routes"
6972 if jsonFormat:
6973 cmdStr = cmdStr + " -j"
6974 handle = self.sendline( cmdStr )
6975 assert handle is not None, "Error in sendline"
6976 assert "Command not found:" not in handle, handle
6977 assert "Unsupported command:" not in handle, handle
6978 assert "Error executing command" not in handle, handle
6979 return handle
6980 except AssertionError:
6981 main.log.exception( "" )
6982 return None
6983 except TypeError:
6984 main.log.exception( self.name + ": Object not as expected" )
6985 return None
6986 except pexpect.EOF:
6987 main.log.error( self.name + ": EOF exception found" )
6988 main.log.error( self.name + ": " + self.handle.before )
6989 main.cleanAndExit()
6990 except Exception:
6991 main.log.exception( self.name + ": Uncaught exception!" )
6992 main.cleanAndExit()