blob: 8e6a90a53260abf6c6b06931f52728fd10b0144b [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 Halla16b4db2021-10-20 14:11:59 -0700498 if i == 1: # Not in ONOS CLI
499 # FIXME: This isn't really the correct place for this, but it works for now
500 # Check if port-forward session is still up first
501 if hasattr( main, "Cluster"):
502 ctrl = None
503 for c in main.Cluster.controllers:
504 if c.CLI is self:
505 ctrl = c
506 break
507 if not ctrl:
508 main.log.warn( self.name + ": Could not find this node in Cluster. Can't check port-forward status" )
509 elif ctrl.k8s:
510 ctrl.k8s.checkPortForward( ctrl.k8s.podName,
511 kubeconfig=ctrl.k8s.kubeConfig,
512 namespace=main.params[ 'kubernetes' ][ 'namespace' ] )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700513 main.log.error( self.name + ": onos cli session closed. " )
Jon Halla495f562016-05-16 18:03:26 -0700514 if self.onosIp:
515 main.log.warn( "Trying to reconnect " + self.onosIp )
516 reconnectResult = self.startOnosCli( self.onosIp )
517 if reconnectResult:
518 main.log.info( self.name + ": onos cli session reconnected." )
519 else:
520 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700521 if noExit:
522 return None
523 else:
Devin Lim44075962017-08-11 10:56:37 -0700524 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700525 else:
Devin Lim44075962017-08-11 10:56:37 -0700526 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700527 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700528 main.log.warn( "Timeout when testing cli responsiveness" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700529 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700530 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Hall6c9e2da2018-11-06 12:01:23 -0800531 self.handle.expect( self.karafPrompt )
Jon Halla495f562016-05-16 18:03:26 -0700532
Jon Hall0e240372018-05-02 11:21:57 -0700533 response += self.handle.before
Jon Hall14a03b52016-05-11 12:07:30 -0700534 if debug:
Jon Hall0e240372018-05-02 11:21:57 -0700535 main.log.debug( self.name + ": Raw output from sending ''" )
536 main.log.debug( self.name + ": " + repr( response ) )
537 except pexpect.TIMEOUT:
538 main.log.error( self.name + ": ONOS timeout" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700539 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
You Wang141b43b2018-06-26 16:50:18 -0700540 self.handle.send( "\x03" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800541 self.handle.expect( self.karafPrompt )
Jon Hall0e240372018-05-02 11:21:57 -0700542 return None
543 except pexpect.EOF:
544 main.log.error( self.name + ": EOF exception found" )
545 main.log.error( self.name + ": " + self.handle.before )
546 if noExit:
547 return None
548 else:
549 main.cleanAndExit()
550 except Exception:
551 main.log.exception( self.name + ": Uncaught exception!" )
552 if noExit:
553 return None
554 else:
555 main.cleanAndExit()
556
Jon Hall22e94ce2019-01-15 14:52:17 -0800557 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True, expectJson=False ):
Jon Hall0e240372018-05-02 11:21:57 -0700558 """
559 A wrapper around pexpect's sendline/expect. Will return all the output from a given command
560
561 Required Arguments:
562 cmdStr - String to send to the pexpect session
563
564 Optional Arguments:
565 showResponse - Defaults to False. If True will log the response.
566 debug - Defaults to False. If True, will enable debug logging.
567 timeout - Defaults to 10. Amount of time in seconds for a command to return
568 before a timeout.
569 noExit - Defaults to False. If True, will not exit TestON in the event of a
570 closed channel, but instead return None
Jon Hall6c9e2da2018-11-06 12:01:23 -0800571 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 -0700572
573 Warning: There are no sanity checking to commands sent using this method.
574
575 """
576 try:
577 # Try to reconnect if disconnected from cli
578 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
579 if debug:
580 # NOTE: This adds an average of .4 seconds per call
Jon Hall14a03b52016-05-11 12:07:30 -0700581 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700582 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800583 self.handle.sendline( cmdStr )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800584 self.handle.expect( self.karafPrompt, timeout )
Jon Hall63604932015-02-26 17:09:50 -0800585 response = self.handle.before
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000586 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
Jon Hallc6793552016-01-19 14:18:37 -0800587 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700588 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700589 main.log.debug( self.name + ": Raw output" )
590 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700591
Jon Hall3c0114c2020-08-11 15:07:42 -0700592 response = self.cleanOutput( response, debug=debug )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800593 # Remove control codes from karaf 4.2.1
Jon Hall3c0114c2020-08-11 15:07:42 -0700594 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 -0800595 response = karafEscape.sub( '', response )
596 if debug:
597 main.log.debug( self.name + ": karafEscape output" )
598 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700599 # Remove ANSI color control strings from output
Jon Hall43060f62020-06-23 13:13:33 -0700600 response = self.cleanOutput( response, debug )
Jon Hallc6358dd2015-04-10 12:44:28 -0700601
Jon Hall6c9e2da2018-11-06 12:01:23 -0800602 # Remove ANSI color control strings from output
Jon Hallcf31d0f2018-12-13 11:18:48 -0800603 # NOTE: karaf is sometimes adding a single character then two
604 # backspaces and sometimes adding 2 characters with 2 backspaces??
Jon Hall3c0114c2020-08-11 15:07:42 -0700605 backspaceEscape = re.compile( r'((.|\s)\x08)' )
606 unchanged = False
607 while not unchanged:
608 old = response
609 response = backspaceEscape.sub( '', response, count=1 )
610 if debug:
611 main.log.debug( self.name + ": backspaceEscape output" )
612 main.log.debug( self.name + ": " + repr( response ) )
613 unchanged = old == response
Jon Hall6c9e2da2018-11-06 12:01:23 -0800614
kelvin-onlabfb521662015-02-27 09:52:40 -0800615 # Remove extra return chars that get added
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000616 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700617 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700618 main.log.debug( self.name + ": Removed extra returns " +
619 "from output" )
620 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700621
622 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800623 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700624 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700625 main.log.debug( self.name + ": parsed and stripped output" )
626 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700627
Jon Hall63604932015-02-26 17:09:50 -0800628 # parse for just the output, remove the cmd from response
Jon Hallce0d70b2018-12-11 11:01:32 -0800629 cmdPattern = cmdStr.strip()
630 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
631 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800632 if relaxedRegex:
Jon Hallce0d70b2018-12-11 11:01:32 -0800633 cmdPattern = cmdPattern.split( '|' )[ -1 ].strip()
634 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
635 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800636 # This was added because karaf 4.2 is stripping some characters from the command echo
Jon Hallce0d70b2018-12-11 11:01:32 -0800637 output = response.split( cmdPattern, 1 )
Jon Hall22e94ce2019-01-15 14:52:17 -0800638 if expectJson:
639 main.log.warn( "Relaxed Regex: Searching for a json string amongst the output" )
640 jsonPattern = r'\{.*\}'
641 match = re.search( jsonPattern, output[ 0 ] )
642 if match:
643 output = [ '' , match.group( 0 ) ] # We expect a list with the second element to be the output
Jon Hall39e3ffe2018-12-05 11:40:29 -0800644 if len( output ) < 2:
645 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800646 cmdPattern = cmdPattern[ -5: ]
647 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
648 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
649 output = response.split( cmdPattern, 1 )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800650 else:
Jon Hallce0d70b2018-12-11 11:01:32 -0800651 output = response.split( cmdPattern, 1 )
652 if len( output ) < 2: # TODO: Should we do this without the relaxedRegex flag?
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800653 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800654 output = response.split( cmdPattern[ -5: ], 1 )
Jon Hall0e240372018-05-02 11:21:57 -0700655 if output:
656 if debug:
657 main.log.debug( self.name + ": split output" )
658 for r in output:
659 main.log.debug( self.name + ": " + repr( r ) )
Jon Hallce0d70b2018-12-11 11:01:32 -0800660 if len( output ) == 1:
661 main.log.error( "Could not remove sent command echo from output" )
662 return output
Jon Hall0e240372018-05-02 11:21:57 -0700663 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800664 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800665 main.log.info( "Response from ONOS: {}".format( output ) )
Jon Hall0e240372018-05-02 11:21:57 -0700666 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
GlennRC85870432015-11-23 11:45:51 -0800667 return output
GlennRCed771242016-01-13 17:02:47 -0800668 except pexpect.TIMEOUT:
Jon Hall0e240372018-05-02 11:21:57 -0700669 main.log.error( self.name + ": ONOS timeout" )
GlennRCed771242016-01-13 17:02:47 -0800670 if debug:
Jon Hall3c0114c2020-08-11 15:07:42 -0700671 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
You Wang6b5e5ba2019-01-31 15:32:40 -0800672 self.exitFromCmd( self.karafPrompt, 100 )
GlennRCed771242016-01-13 17:02:47 -0800673 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700674 except IndexError:
675 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700676 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700677 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800678 except TypeError:
679 main.log.exception( self.name + ": Object not as expected" )
680 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400681 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800682 main.log.error( self.name + ": EOF exception found" )
683 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700684 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700685 return None
686 else:
Devin Lim44075962017-08-11 10:56:37 -0700687 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800688 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800689 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700690 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700691 return None
692 else:
Devin Lim44075962017-08-11 10:56:37 -0700693 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400694
Jon Halld5a94fb2018-11-13 14:32:23 -0800695 def lineCount( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True ):
696 """
697 A wrapper around sendline(). Will return the number of lines returned or None on error
698
699 Required Arguments:
700 cmdStr - String to send to the pexpect session
701
702 Optional Arguments:
703 showResponse - Defaults to False. If True will log the response.
704 debug - Defaults to False. If True, will enable debug logging.
705 timeout - Defaults to 10. Amount of time in seconds for a command to return
706 before a timeout.
707 noExit - Defaults to False. If True, will not exit TestON in the event of a
708 closed channel, but instead return None
709 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.
710
711 Warning: There are no sanity checking to commands sent using this method.
712
713 """
714 try:
715 numLines = self.sendline( cmdStr, showResponse, debug, timeout, noExit, relaxedRegex )
You Wang0ce8e0c2019-02-22 12:22:26 -0800716 parsed = re.search( "(\d+)", numLines )
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800717 if not parsed:
718 main.log.error( "Warning, output of karaf's wc may have changed" )
719 return None
720 return parsed.group( 1 )
Jon Halld5a94fb2018-11-13 14:32:23 -0800721 except IndexError:
722 main.log.exception( self.name + ": Object not as expected" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800723 main.log.debug( "response: {}".format( repr( numLines ) ) )
Jon Halld5a94fb2018-11-13 14:32:23 -0800724 return None
725 except TypeError:
726 main.log.exception( self.name + ": Object not as expected" )
727 return None
728 except Exception:
729 main.log.exception( self.name + ": Uncaught exception!" )
730 if noExit:
731 return None
732 else:
733 main.cleanAndExit()
734
kelvin8ec71442015-01-15 16:57:00 -0800735 # IMPORTANT NOTE:
736 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800737 # the cli command changing 'a:b' with 'aB'.
738 # Ex ) onos:topology > onosTopology
739 # onos:links > onosLinks
740 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800741
kelvin-onlabd3b64892015-01-20 13:26:24 -0800742 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800743 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400744 Adds a new cluster node by ID and address information.
745 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800746 * nodeId
747 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400748 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800749 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800750 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400751 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800752 cmdStr = "add-node " + str( nodeId ) + " " +\
753 str( ONOSIp ) + " " + str( tcpPort )
754 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700755 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800756 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800757 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700758 main.log.error( self.name + ": Error in adding node" )
kelvin8ec71442015-01-15 16:57:00 -0800759 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800760 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400761 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800762 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400763 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800764 except AssertionError:
765 main.log.exception( "" )
766 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800767 except TypeError:
768 main.log.exception( self.name + ": Object not as expected" )
769 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400770 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800771 main.log.error( self.name + ": EOF exception found" )
772 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700773 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800774 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800775 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700776 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400777
kelvin-onlabd3b64892015-01-20 13:26:24 -0800778 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800779 """
andrewonlab86dc3082014-10-13 18:18:38 -0400780 Removes a cluster by ID
781 Issues command: 'remove-node [<node-id>]'
782 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800783 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800784 """
andrewonlab86dc3082014-10-13 18:18:38 -0400785 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400786
kelvin-onlabd3b64892015-01-20 13:26:24 -0800787 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700788 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700789 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800790 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700791 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700792 main.log.error( self.name + ": Error in removing node" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700793 main.log.error( handle )
794 return main.FALSE
795 else:
796 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800797 except AssertionError:
798 main.log.exception( "" )
799 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800800 except TypeError:
801 main.log.exception( self.name + ": Object not as expected" )
802 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400803 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800804 main.log.error( self.name + ": EOF exception found" )
805 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700806 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800807 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800808 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700809 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400810
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700811 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800812 """
andrewonlab7c211572014-10-15 16:45:20 -0400813 List the nodes currently visible
814 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700815 Optional argument:
816 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800817 """
andrewonlab7c211572014-10-15 16:45:20 -0400818 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700819 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700820 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700821 cmdStr += " -j"
822 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700823 assert output is not None, "Error in sendline"
Jon Halle37bd1f2020-09-10 12:16:41 -0700824 # "Command not found" or "Service org.onosproject.security.AuditService not found"
825 assert "not found" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700826 return output
Jon Hallc6793552016-01-19 14:18:37 -0800827 except AssertionError:
828 main.log.exception( "" )
829 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800830 except TypeError:
831 main.log.exception( self.name + ": Object not as expected" )
832 return None
andrewonlab7c211572014-10-15 16:45:20 -0400833 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800834 main.log.error( self.name + ": EOF exception found" )
835 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700836 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800837 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800838 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700839 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400840
kelvin8ec71442015-01-15 16:57:00 -0800841 def topology( self ):
842 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700843 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700844 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700845 Return:
846 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800847 """
andrewonlab95ce8322014-10-13 14:12:04 -0400848 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700849 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800850 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800851 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800852 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700853 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400854 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800855 except AssertionError:
856 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800857 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800858 except TypeError:
859 main.log.exception( self.name + ": Object not as expected" )
860 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400861 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800862 main.log.error( self.name + ": EOF exception found" )
863 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700864 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800865 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800866 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700867 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800868
jenkins7ead5a82015-03-13 10:28:21 -0700869 def deviceRemove( self, deviceId ):
870 """
871 Removes particular device from storage
872
873 TODO: refactor this function
874 """
875 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700876 cmdStr = "device-remove " + str( deviceId )
877 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800878 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800879 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700880 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700881 main.log.error( self.name + ": Error in removing device" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700882 main.log.error( handle )
883 return main.FALSE
884 else:
885 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800886 except AssertionError:
887 main.log.exception( "" )
888 return None
jenkins7ead5a82015-03-13 10:28:21 -0700889 except TypeError:
890 main.log.exception( self.name + ": Object not as expected" )
891 return None
892 except pexpect.EOF:
893 main.log.error( self.name + ": EOF exception found" )
894 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700895 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700896 except Exception:
897 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700898 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700899
You Wang3b9689a2018-08-30 12:24:00 -0700900 def devices( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800901 """
Jon Hall7b02d952014-10-17 20:14:54 -0400902 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400903 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800904 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800905 """
andrewonlab86dc3082014-10-13 18:18:38 -0400906 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700907 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800908 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700909 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700910 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800911 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800912 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700913 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800914 except AssertionError:
915 main.log.exception( "" )
916 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800917 except TypeError:
918 main.log.exception( self.name + ": Object not as expected" )
919 return None
andrewonlab7c211572014-10-15 16:45:20 -0400920 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800921 main.log.error( self.name + ": EOF exception found" )
922 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700923 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800924 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800925 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700926 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400927
kelvin-onlabd3b64892015-01-20 13:26:24 -0800928 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800929 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800930 This balances the devices across all controllers
931 by issuing command: 'onos> onos:balance-masters'
932 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800933 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800934 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800935 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700936 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800937 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800938 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700939 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700940 main.log.error( self.name + ": Error in balancing masters" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700941 main.log.error( handle )
942 return main.FALSE
943 else:
944 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800945 except AssertionError:
946 main.log.exception( "" )
947 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800948 except TypeError:
949 main.log.exception( self.name + ": Object not as expected" )
950 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800951 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800952 main.log.error( self.name + ": EOF exception found" )
953 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700954 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800955 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800956 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700957 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800958
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000959 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700960 """
961 Returns the output of the masters command.
962 Optional argument:
963 * jsonFormat - boolean indicating if you want output in json
964 """
965 try:
966 cmdStr = "onos:masters"
967 if jsonFormat:
968 cmdStr += " -j"
969 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700970 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800971 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700972 return output
Jon Hallc6793552016-01-19 14:18:37 -0800973 except AssertionError:
974 main.log.exception( "" )
975 return None
acsmars24950022015-07-30 18:00:43 -0700976 except TypeError:
977 main.log.exception( self.name + ": Object not as expected" )
978 return None
979 except pexpect.EOF:
980 main.log.error( self.name + ": EOF exception found" )
981 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700982 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700983 except Exception:
984 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700985 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700986
Jon Hallc6793552016-01-19 14:18:37 -0800987 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700988 """
989 Uses the master command to check that the devices' leadership
990 is evenly divided
991
992 Dependencies: checkMasters() and summary()
993
Jon Hall6509dbf2016-06-21 17:01:17 -0700994 Returns main.TRUE if the devices are balanced
995 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700996 Exits on Exception
997 Returns None on TypeError
998 """
999 try:
Jon Hallc6793552016-01-19 14:18:37 -08001000 summaryOutput = self.summary()
1001 totalDevices = json.loads( summaryOutput )[ "devices" ]
1002 except ( TypeError, ValueError ):
1003 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
1004 return None
1005 try:
acsmars24950022015-07-30 18:00:43 -07001006 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -08001007 mastersOutput = self.checkMasters()
1008 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -07001009 first = masters[ 0 ][ "size" ]
1010 for master in masters:
1011 totalOwnedDevices += master[ "size" ]
1012 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
1013 main.log.error( "Mastership not balanced" )
1014 main.log.info( "\n" + self.checkMasters( False ) )
1015 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -07001016 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001017 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -07001018 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001019 except ( TypeError, ValueError ):
1020 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -07001021 return None
1022 except pexpect.EOF:
1023 main.log.error( self.name + ": EOF exception found" )
1024 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001025 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -07001026 except Exception:
1027 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001028 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -07001029
YPZhangfebf7302016-05-24 16:45:56 -07001030 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -08001031 """
Jon Halle8217482014-10-17 13:49:14 -04001032 Lists all core links
1033 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001034 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001035 """
Jon Halle8217482014-10-17 13:49:14 -04001036 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001037 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001038 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001039 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07001040 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001041 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001042 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001043 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001044 except AssertionError:
1045 main.log.exception( "" )
1046 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001047 except TypeError:
1048 main.log.exception( self.name + ": Object not as expected" )
1049 return None
Jon Halle8217482014-10-17 13:49:14 -04001050 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001051 main.log.error( self.name + ": EOF exception found" )
1052 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001053 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001054 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001055 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001056 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001057
You Wang3b9689a2018-08-30 12:24:00 -07001058 def ports( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -08001059 """
Jon Halle8217482014-10-17 13:49:14 -04001060 Lists all ports
1061 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001062 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001063 """
Jon Halle8217482014-10-17 13:49:14 -04001064 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001065 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001066 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001067 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -07001068 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001069 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001070 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001071 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001072 except AssertionError:
1073 main.log.exception( "" )
1074 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001075 except TypeError:
1076 main.log.exception( self.name + ": Object not as expected" )
1077 return None
Jon Halle8217482014-10-17 13:49:14 -04001078 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001079 main.log.error( self.name + ": EOF exception found" )
1080 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001081 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001082 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001083 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001084 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001085
kelvin-onlabd3b64892015-01-20 13:26:24 -08001086 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001087 """
Jon Hall983a1702014-10-28 18:44:22 -04001088 Lists all devices and the controllers with roles assigned to them
1089 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001090 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001091 """
andrewonlab7c211572014-10-15 16:45:20 -04001092 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001093 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001094 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001095 cmdStr += " -j"
1096 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001097 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001098 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001099 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001100 except AssertionError:
1101 main.log.exception( "" )
1102 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001103 except TypeError:
1104 main.log.exception( self.name + ": Object not as expected" )
1105 return None
Jon Hall983a1702014-10-28 18:44:22 -04001106 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001107 main.log.error( self.name + ": EOF exception found" )
1108 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001109 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001110 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001111 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001112 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -04001113
kelvin-onlabd3b64892015-01-20 13:26:24 -08001114 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001115 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001116 Given the a string containing the json representation of the "roles"
1117 cli command and a partial or whole device id, returns a json object
1118 containing the roles output for the first device whose id contains
1119 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -04001120
1121 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -08001122 A dict of the role assignments for the given device or
1123 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001124 """
Jon Hall983a1702014-10-28 18:44:22 -04001125 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001126 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001127 return None
1128 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 rawRoles = self.roles()
1130 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001131 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001132 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001133 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001135 return device
1136 return None
Jon Hallc6793552016-01-19 14:18:37 -08001137 except ( TypeError, ValueError ):
1138 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001139 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001140 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001141 main.log.error( self.name + ": EOF exception found" )
1142 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001143 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001144 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001145 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001146 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001147
kelvin-onlabd3b64892015-01-20 13:26:24 -08001148 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001149 """
Jon Hall94fd0472014-12-08 11:52:42 -08001150 Iterates through each device and checks if there is a master assigned
1151 Returns: main.TRUE if each device has a master
1152 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001153 """
Jon Hall94fd0472014-12-08 11:52:42 -08001154 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001155 rawRoles = self.roles()
1156 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001157 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001158 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001159 # print device
1160 if device[ 'master' ] == "none":
1161 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001162 return main.FALSE
1163 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001164 except ( TypeError, ValueError ):
1165 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001166 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001167 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001168 main.log.error( self.name + ": EOF exception found" )
1169 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001170 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001171 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001172 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001173 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001174
kelvin-onlabd3b64892015-01-20 13:26:24 -08001175 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001176 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001177 Returns string of paths, and the cost.
1178 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001179 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001180 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001181 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1182 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001183 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001184 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001185 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001186 main.log.error( self.name + ": Error in getting paths" )
kelvin8ec71442015-01-15 16:57:00 -08001187 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001188 else:
kelvin8ec71442015-01-15 16:57:00 -08001189 path = handle.split( ";" )[ 0 ]
1190 cost = handle.split( ";" )[ 1 ]
1191 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001192 except AssertionError:
1193 main.log.exception( "" )
1194 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001195 except TypeError:
1196 main.log.exception( self.name + ": Object not as expected" )
1197 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001198 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001199 main.log.error( self.name + ": EOF exception found" )
1200 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001201 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001202 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001203 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001204 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001205
kelvin-onlabd3b64892015-01-20 13:26:24 -08001206 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001207 """
Jon Hallffb386d2014-11-21 13:43:38 -08001208 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001209 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001210 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001211 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001212 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001213 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001214 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001215 cmdStr += " -j"
1216 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001217 if handle:
1218 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001219 # TODO: Maybe make this less hardcoded
1220 # ConsistentMap Exceptions
1221 assert "org.onosproject.store.service" not in handle
1222 # Node not leader
1223 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001224 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001225 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07001226 main.log.exception( self.name + ": Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001227 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001228 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001229 except TypeError:
1230 main.log.exception( self.name + ": Object not as expected" )
1231 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001232 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001233 main.log.error( self.name + ": EOF exception found" )
1234 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001235 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001236 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001237 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001238 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001239
kelvin-onlabd3b64892015-01-20 13:26:24 -08001240 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001241 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001242 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001243
Jon Hallefbd9792015-03-05 16:11:36 -08001244 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001245 partial mac address
1246
Jon Hall42db6dc2014-10-24 19:03:48 -04001247 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001248 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001249 try:
kelvin8ec71442015-01-15 16:57:00 -08001250 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001251 return None
1252 else:
1253 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001254 rawHosts = self.hosts()
1255 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001256 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001257 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001258 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001259 if not host:
1260 pass
1261 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001262 return host
1263 return None
Jon Hallc6793552016-01-19 14:18:37 -08001264 except ( TypeError, ValueError ):
1265 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001266 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001267 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001268 main.log.error( self.name + ": EOF exception found" )
1269 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001270 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001271 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001272 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001273 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001274
kelvin-onlabd3b64892015-01-20 13:26:24 -08001275 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001276 """
1277 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001278 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001279
andrewonlab3f0a4af2014-10-17 12:25:14 -04001280 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001281 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001282 IMPORTANT:
1283 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001284 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001285 Furthermore, it assumes that value of VLAN is '-1'
1286 Description:
kelvin8ec71442015-01-15 16:57:00 -08001287 Converts mininet hosts ( h1, h2, h3... ) into
1288 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1289 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001290 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001291 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001292
kelvin-onlabd3b64892015-01-20 13:26:24 -08001293 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001294 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001295 hostHex = hex( int( host ) ).zfill( 12 )
1296 hostHex = str( hostHex ).replace( 'x', '0' )
1297 i = iter( str( hostHex ) )
1298 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1299 hostHex = hostHex + "/-1"
1300 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001301
kelvin-onlabd3b64892015-01-20 13:26:24 -08001302 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001303
Jon Halld4d4b372015-01-28 16:02:41 -08001304 except TypeError:
1305 main.log.exception( self.name + ": Object not as expected" )
1306 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001307 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001308 main.log.error( self.name + ": EOF exception found" )
1309 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001310 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001311 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001312 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001313 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001314
You Wangbc898b82018-05-03 16:22:34 -07001315 def verifyHostLocation( self, hostIp, location ):
1316 """
1317 Description:
1318 Verify the host given is discovered in all locations expected
1319 Required:
1320 hostIp: IP address of the host
1321 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1322 Could be a string or list
1323 Returns:
1324 main.TRUE if host is discovered on all locations provided
1325 main.FALSE otherwise
1326 """
You Wangbc898b82018-05-03 16:22:34 -07001327 locations = [ location ] if isinstance( location, str ) else location
1328 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1329 try:
1330 hosts = self.hosts()
1331 hosts = json.loads( hosts )
1332 targetHost = None
1333 for host in hosts:
1334 if hostIp in host[ "ipAddresses" ]:
1335 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001336 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001337 result = main.TRUE
1338 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1339 for loc in locations:
1340 discovered = False
1341 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001342 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1343 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001344 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001345 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001346 break
1347 if discovered:
1348 locationsDiscovered.remove( locDiscovered )
1349 else:
1350 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1351 result = main.FALSE
1352 if locationsDiscovered:
1353 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1354 result = main.FALSE
1355 return result
1356 except KeyError:
1357 main.log.exception( self.name + ": host data not as expected: " + hosts )
1358 return None
1359 except pexpect.EOF:
1360 main.log.error( self.name + ": EOF exception found" )
1361 main.log.error( self.name + ": " + self.handle.before )
1362 main.cleanAndExit()
1363 except Exception:
1364 main.log.exception( self.name + ": Uncaught exception" )
1365 return None
1366
You Wang53dba1e2018-02-02 17:45:44 -08001367 def verifyHostIp( self, hostList=[], prefix="" ):
1368 """
1369 Description:
1370 Verify that all hosts have IP address assigned to them
1371 Optional:
1372 hostList: If specified, verifications only happen to the hosts
1373 in hostList
1374 prefix: at least one of the ip address assigned to the host
1375 needs to have the specified prefix
1376 Returns:
1377 main.TRUE if all hosts have specific IP address assigned;
1378 main.FALSE otherwise
1379 """
You Wang53dba1e2018-02-02 17:45:44 -08001380 try:
1381 hosts = self.hosts()
1382 hosts = json.loads( hosts )
1383 if not hostList:
1384 hostList = [ host[ "id" ] for host in hosts ]
1385 for host in hosts:
1386 hostId = host[ "id" ]
1387 if hostId not in hostList:
1388 continue
1389 ipList = host[ "ipAddresses" ]
1390 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1391 if not ipList:
1392 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1393 else:
1394 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1395 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1396 else:
1397 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1398 hostList.remove( hostId )
1399 if hostList:
1400 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
Jon Hall43060f62020-06-23 13:13:33 -07001401 # Print info for debugging
1402 main.log.debug( self.name + ": hosts output: " + str( hosts ) )
You Wang53dba1e2018-02-02 17:45:44 -08001403 return main.FALSE
1404 else:
1405 return main.TRUE
1406 except KeyError:
1407 main.log.exception( self.name + ": host data not as expected: " + hosts )
1408 return None
1409 except pexpect.EOF:
1410 main.log.error( self.name + ": EOF exception found" )
1411 main.log.error( self.name + ": " + self.handle.before )
1412 main.cleanAndExit()
1413 except Exception:
1414 main.log.exception( self.name + ": Uncaught exception" )
1415 return None
1416
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001417 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001418 """
andrewonlabe6745342014-10-17 14:29:13 -04001419 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001420 * hostIdOne: ONOS host id for host1
1421 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001422 Optional:
1423 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001424 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001425 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001426 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001427 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001428 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001429 Returns:
1430 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001431 """
andrewonlabe6745342014-10-17 14:29:13 -04001432 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001433 cmdStr = "add-host-intent "
1434 if vlanId:
1435 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001436 if setVlan:
1437 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001438 if encap:
1439 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001440 if bandwidth:
1441 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001442 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001443 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001444 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001445 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001446 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001447 main.log.error( self.name + ": Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001448 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001449 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001450 else:
1451 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001452 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001453 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001454 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001455 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001456 else:
1457 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001458 main.log.debug( "Response from ONOS was: " +
1459 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001460 return None
Jon Hallc6793552016-01-19 14:18:37 -08001461 except AssertionError:
1462 main.log.exception( "" )
1463 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001464 except TypeError:
1465 main.log.exception( self.name + ": Object not as expected" )
1466 return None
andrewonlabe6745342014-10-17 14:29:13 -04001467 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001468 main.log.error( self.name + ": EOF exception found" )
1469 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001470 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001471 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001472 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001473 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001474
kelvin-onlabd3b64892015-01-20 13:26:24 -08001475 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001476 """
andrewonlab7b31d232014-10-24 13:31:47 -04001477 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001478 * ingressDevice: device id of ingress device
1479 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001480 Optional:
1481 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001482 Description:
1483 Adds an optical intent by specifying an ingress and egress device
1484 Returns:
1485 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001486 """
andrewonlab7b31d232014-10-24 13:31:47 -04001487 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001488 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1489 " " + str( egressDevice )
1490 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001491 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001492 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001493 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001494 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001495 main.log.error( self.name + ": Error in adding Optical intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001496 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001497 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001498 main.log.info( "Optical intent installed between " +
1499 str( ingressDevice ) + " and " +
1500 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001501 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001502 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001503 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001504 else:
1505 main.log.error( "Error, intent ID not found" )
1506 return None
Jon Hallc6793552016-01-19 14:18:37 -08001507 except AssertionError:
1508 main.log.exception( "" )
1509 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001510 except TypeError:
1511 main.log.exception( self.name + ": Object not as expected" )
1512 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001513 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001514 main.log.error( self.name + ": EOF exception found" )
1515 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001516 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001517 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001518 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001519 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001520
kelvin-onlabd3b64892015-01-20 13:26:24 -08001521 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001522 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001523 ingressDevice,
1524 egressDevice,
1525 portIngress="",
1526 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001527 ethType="",
1528 ethSrc="",
1529 ethDst="",
1530 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001531 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001532 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001533 ipProto="",
1534 ipSrc="",
1535 ipDst="",
1536 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001537 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001538 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001539 setVlan="",
1540 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001541 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001542 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001543 * ingressDevice: device id of ingress device
1544 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001545 Optional:
1546 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001547 * ethSrc: specify ethSrc ( i.e. src mac addr )
1548 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001549 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001550 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001551 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001552 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001553 * ipSrc: specify ip source address
1554 * ipDst: specify ip destination address
1555 * tcpSrc: specify tcp source port
1556 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001557 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001558 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001559 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001560 Description:
kelvin8ec71442015-01-15 16:57:00 -08001561 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001562 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001563 Returns:
1564 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001565
Jon Halle3f39ff2015-01-13 11:50:53 -08001566 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001567 options developers provide for point-to-point
1568 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001569 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001570 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001571 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001572
Jeremy Songsterff553672016-05-12 17:06:23 -07001573 if ethType:
1574 cmd += " --ethType " + str( ethType )
1575 if ethSrc:
1576 cmd += " --ethSrc " + str( ethSrc )
1577 if ethDst:
1578 cmd += " --ethDst " + str( ethDst )
1579 if bandwidth:
1580 cmd += " --bandwidth " + str( bandwidth )
1581 if lambdaAlloc:
1582 cmd += " --lambda "
1583 if ipProto:
1584 cmd += " --ipProto " + str( ipProto )
1585 if ipSrc:
1586 cmd += " --ipSrc " + str( ipSrc )
1587 if ipDst:
1588 cmd += " --ipDst " + str( ipDst )
1589 if tcpSrc:
1590 cmd += " --tcpSrc " + str( tcpSrc )
1591 if tcpDst:
1592 cmd += " --tcpDst " + str( tcpDst )
1593 if vlanId:
1594 cmd += " -v " + str( vlanId )
1595 if setVlan:
1596 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001597 if encap:
1598 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001599 if protected:
1600 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001601
kelvin8ec71442015-01-15 16:57:00 -08001602 # Check whether the user appended the port
1603 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001604 if "/" in ingressDevice:
1605 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001606 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001607 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001608 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001609 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001610 # Would it make sense to throw an exception and exit
1611 # the test?
1612 return None
andrewonlab36af3822014-11-18 17:48:18 -05001613
kelvin8ec71442015-01-15 16:57:00 -08001614 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001615 str( ingressDevice ) + "/" +\
1616 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001617
kelvin-onlabd3b64892015-01-20 13:26:24 -08001618 if "/" in egressDevice:
1619 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001620 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001621 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001622 main.log.error( "You must specify the egress port" )
1623 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001624
kelvin8ec71442015-01-15 16:57:00 -08001625 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001626 str( egressDevice ) + "/" +\
1627 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001628
kelvin-onlab898a6c62015-01-16 14:13:53 -08001629 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001630 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001631 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001632 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001633 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001634 main.log.error( self.name + ": Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001635 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001636 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001637 # TODO: print out all the options in this message?
1638 main.log.info( "Point-to-point intent installed between " +
1639 str( ingressDevice ) + " and " +
1640 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001641 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001642 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001643 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001644 else:
1645 main.log.error( "Error, intent ID not found" )
1646 return None
Jon Hallc6793552016-01-19 14:18:37 -08001647 except AssertionError:
1648 main.log.exception( "" )
1649 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001650 except TypeError:
1651 main.log.exception( self.name + ": Object not as expected" )
1652 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001653 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001654 main.log.error( self.name + ": EOF exception found" )
1655 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001656 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001657 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001658 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001659 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001660
kelvin-onlabd3b64892015-01-20 13:26:24 -08001661 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001662 self,
shahshreyac2f97072015-03-19 17:04:29 -07001663 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001664 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001665 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001666 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001667 ethType="",
1668 ethSrc="",
1669 ethDst="",
1670 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001671 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001672 ipProto="",
1673 ipSrc="",
1674 ipDst="",
1675 tcpSrc="",
1676 tcpDst="",
1677 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001678 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001679 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001680 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001681 partial=False,
1682 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001683 """
shahshreyad0c80432014-12-04 16:56:05 -08001684 Note:
shahshreya70622b12015-03-19 17:19:00 -07001685 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001686 is same. That is, all ingress devices include port numbers
1687 with a "/" or all ingress devices could specify device
1688 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001689 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001690 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001691 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001692 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001693 Optional:
1694 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001695 * ethSrc: specify ethSrc ( i.e. src mac addr )
1696 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001697 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001698 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001699 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001700 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001701 * ipSrc: specify ip source address
1702 * ipDst: specify ip destination address
1703 * tcpSrc: specify tcp source port
1704 * tcpDst: specify tcp destination port
1705 * setEthSrc: action to Rewrite Source MAC Address
1706 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001707 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001708 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001709 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001710 Description:
kelvin8ec71442015-01-15 16:57:00 -08001711 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001712 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001713 Returns:
1714 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001715
Jon Halle3f39ff2015-01-13 11:50:53 -08001716 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001717 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001718 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001719 """
shahshreyad0c80432014-12-04 16:56:05 -08001720 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001721 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001722
Jeremy Songsterff553672016-05-12 17:06:23 -07001723 if ethType:
1724 cmd += " --ethType " + str( ethType )
1725 if ethSrc:
1726 cmd += " --ethSrc " + str( ethSrc )
1727 if ethDst:
1728 cmd += " --ethDst " + str( ethDst )
1729 if bandwidth:
1730 cmd += " --bandwidth " + str( bandwidth )
1731 if lambdaAlloc:
1732 cmd += " --lambda "
1733 if ipProto:
1734 cmd += " --ipProto " + str( ipProto )
1735 if ipSrc:
1736 cmd += " --ipSrc " + str( ipSrc )
1737 if ipDst:
1738 cmd += " --ipDst " + str( ipDst )
1739 if tcpSrc:
1740 cmd += " --tcpSrc " + str( tcpSrc )
1741 if tcpDst:
1742 cmd += " --tcpDst " + str( tcpDst )
1743 if setEthSrc:
1744 cmd += " --setEthSrc " + str( setEthSrc )
1745 if setEthDst:
1746 cmd += " --setEthDst " + str( setEthDst )
1747 if vlanId:
1748 cmd += " -v " + str( vlanId )
1749 if setVlan:
1750 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001751 if partial:
1752 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001753 if encap:
1754 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001755
kelvin8ec71442015-01-15 16:57:00 -08001756 # Check whether the user appended the port
1757 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001758
1759 if portIngressList is None:
1760 for ingressDevice in ingressDeviceList:
1761 if "/" in ingressDevice:
1762 cmd += " " + str( ingressDevice )
1763 else:
1764 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001765 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001766 # TODO: perhaps more meaningful return
1767 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001768 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001769 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001770 for ingressDevice, portIngress in zip( ingressDeviceList,
1771 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001772 cmd += " " + \
1773 str( ingressDevice ) + "/" +\
1774 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001775 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001776 main.log.error( "Device list and port list does not " +
1777 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001778 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001779 if "/" in egressDevice:
1780 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001781 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001782 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001783 main.log.error( "You must specify " +
1784 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001785 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001786
kelvin8ec71442015-01-15 16:57:00 -08001787 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001788 str( egressDevice ) + "/" +\
1789 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001790 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001791 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001792 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001793 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001794 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001795 main.log.error( self.name + ": Error in adding multipoint-to-singlepoint " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001796 "intent" )
1797 return None
shahshreyad0c80432014-12-04 16:56:05 -08001798 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001799 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001800 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001801 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001802 else:
1803 main.log.error( "Error, intent ID not found" )
1804 return None
Jon Hallc6793552016-01-19 14:18:37 -08001805 except AssertionError:
1806 main.log.exception( "" )
1807 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001808 except TypeError:
1809 main.log.exception( self.name + ": Object not as expected" )
1810 return None
1811 except pexpect.EOF:
1812 main.log.error( self.name + ": EOF exception found" )
1813 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001814 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001815 except Exception:
1816 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001817 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001818
1819 def addSinglepointToMultipointIntent(
1820 self,
1821 ingressDevice,
1822 egressDeviceList,
1823 portIngress="",
1824 portEgressList=None,
1825 ethType="",
1826 ethSrc="",
1827 ethDst="",
1828 bandwidth="",
1829 lambdaAlloc=False,
1830 ipProto="",
1831 ipSrc="",
1832 ipDst="",
1833 tcpSrc="",
1834 tcpDst="",
1835 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001836 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001837 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001838 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001839 partial=False,
1840 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001841 """
1842 Note:
1843 This function assumes the format of all egress devices
1844 is same. That is, all egress devices include port numbers
1845 with a "/" or all egress devices could specify device
1846 ids and port numbers seperately.
1847 Required:
1848 * EgressDeviceList: List of device ids of egress device
1849 ( Atleast 2 eress devices required in the list )
1850 * ingressDevice: device id of ingress device
1851 Optional:
1852 * ethType: specify ethType
1853 * ethSrc: specify ethSrc ( i.e. src mac addr )
1854 * ethDst: specify ethDst ( i.e. dst mac addr )
1855 * bandwidth: specify bandwidth capacity of link
1856 * lambdaAlloc: if True, intent will allocate lambda
1857 for the specified intent
1858 * ipProto: specify ip protocol
1859 * ipSrc: specify ip source address
1860 * ipDst: specify ip destination address
1861 * tcpSrc: specify tcp source port
1862 * tcpDst: specify tcp destination port
1863 * setEthSrc: action to Rewrite Source MAC Address
1864 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001865 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001866 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001867 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001868 Description:
1869 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1870 specifying device id's and optional fields
1871 Returns:
1872 A string of the intent id or None on error
1873
1874 NOTE: This function may change depending on the
1875 options developers provide for singlepoint-to-multipoint
1876 intent via cli
1877 """
1878 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001879 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001880
Jeremy Songsterff553672016-05-12 17:06:23 -07001881 if ethType:
1882 cmd += " --ethType " + str( ethType )
1883 if ethSrc:
1884 cmd += " --ethSrc " + str( ethSrc )
1885 if ethDst:
1886 cmd += " --ethDst " + str( ethDst )
1887 if bandwidth:
1888 cmd += " --bandwidth " + str( bandwidth )
1889 if lambdaAlloc:
1890 cmd += " --lambda "
1891 if ipProto:
1892 cmd += " --ipProto " + str( ipProto )
1893 if ipSrc:
1894 cmd += " --ipSrc " + str( ipSrc )
1895 if ipDst:
1896 cmd += " --ipDst " + str( ipDst )
1897 if tcpSrc:
1898 cmd += " --tcpSrc " + str( tcpSrc )
1899 if tcpDst:
1900 cmd += " --tcpDst " + str( tcpDst )
1901 if setEthSrc:
1902 cmd += " --setEthSrc " + str( setEthSrc )
1903 if setEthDst:
1904 cmd += " --setEthDst " + str( setEthDst )
1905 if vlanId:
1906 cmd += " -v " + str( vlanId )
1907 if setVlan:
1908 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001909 if partial:
1910 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001911 if encap:
1912 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001913
1914 # Check whether the user appended the port
1915 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001916
kelvin-onlabb9408212015-04-01 13:34:04 -07001917 if "/" in ingressDevice:
1918 cmd += " " + str( ingressDevice )
1919 else:
1920 if not portIngress:
1921 main.log.error( "You must specify " +
1922 "the Ingress port" )
1923 return main.FALSE
1924
1925 cmd += " " +\
1926 str( ingressDevice ) + "/" +\
1927 str( portIngress )
1928
1929 if portEgressList is None:
1930 for egressDevice in egressDeviceList:
1931 if "/" in egressDevice:
1932 cmd += " " + str( egressDevice )
1933 else:
1934 main.log.error( "You must specify " +
1935 "the egress port" )
1936 # TODO: perhaps more meaningful return
1937 return main.FALSE
1938 else:
1939 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001940 for egressDevice, portEgress in zip( egressDeviceList,
1941 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001942 cmd += " " + \
1943 str( egressDevice ) + "/" +\
1944 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001945 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001946 main.log.error( "Device list and port list does not " +
1947 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001948 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001949 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001950 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001951 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001952 # If error, return error message
1953 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001954 main.log.error( self.name + ": Error in adding singlepoint-to-multipoint " +
kelvin-onlabb9408212015-04-01 13:34:04 -07001955 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001956 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001957 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001958 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001959 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001960 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001961 else:
1962 main.log.error( "Error, intent ID not found" )
1963 return None
Jon Hallc6793552016-01-19 14:18:37 -08001964 except AssertionError:
1965 main.log.exception( "" )
1966 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001967 except TypeError:
1968 main.log.exception( self.name + ": Object not as expected" )
1969 return None
shahshreyad0c80432014-12-04 16:56:05 -08001970 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001971 main.log.error( self.name + ": EOF exception found" )
1972 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001973 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001974 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001975 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001976 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001977
Hari Krishna9e232602015-04-13 17:29:08 -07001978 def addMplsIntent(
1979 self,
1980 ingressDevice,
1981 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001982 ingressPort="",
1983 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001984 ethType="",
1985 ethSrc="",
1986 ethDst="",
1987 bandwidth="",
1988 lambdaAlloc=False,
1989 ipProto="",
1990 ipSrc="",
1991 ipDst="",
1992 tcpSrc="",
1993 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001994 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001995 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001996 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001997 """
1998 Required:
1999 * ingressDevice: device id of ingress device
2000 * egressDevice: device id of egress device
2001 Optional:
2002 * ethType: specify ethType
2003 * ethSrc: specify ethSrc ( i.e. src mac addr )
2004 * ethDst: specify ethDst ( i.e. dst mac addr )
2005 * bandwidth: specify bandwidth capacity of link
2006 * lambdaAlloc: if True, intent will allocate lambda
2007 for the specified intent
2008 * ipProto: specify ip protocol
2009 * ipSrc: specify ip source address
2010 * ipDst: specify ip destination address
2011 * tcpSrc: specify tcp source port
2012 * tcpDst: specify tcp destination port
2013 * ingressLabel: Ingress MPLS label
2014 * egressLabel: Egress MPLS label
2015 Description:
2016 Adds MPLS intent by
2017 specifying device id's and optional fields
2018 Returns:
2019 A string of the intent id or None on error
2020
2021 NOTE: This function may change depending on the
2022 options developers provide for MPLS
2023 intent via cli
2024 """
2025 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07002026 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07002027
Jeremy Songsterff553672016-05-12 17:06:23 -07002028 if ethType:
2029 cmd += " --ethType " + str( ethType )
2030 if ethSrc:
2031 cmd += " --ethSrc " + str( ethSrc )
2032 if ethDst:
2033 cmd += " --ethDst " + str( ethDst )
2034 if bandwidth:
2035 cmd += " --bandwidth " + str( bandwidth )
2036 if lambdaAlloc:
2037 cmd += " --lambda "
2038 if ipProto:
2039 cmd += " --ipProto " + str( ipProto )
2040 if ipSrc:
2041 cmd += " --ipSrc " + str( ipSrc )
2042 if ipDst:
2043 cmd += " --ipDst " + str( ipDst )
2044 if tcpSrc:
2045 cmd += " --tcpSrc " + str( tcpSrc )
2046 if tcpDst:
2047 cmd += " --tcpDst " + str( tcpDst )
2048 if ingressLabel:
2049 cmd += " --ingressLabel " + str( ingressLabel )
2050 if egressLabel:
2051 cmd += " --egressLabel " + str( egressLabel )
2052 if priority:
2053 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07002054
2055 # Check whether the user appended the port
2056 # or provided it as an input
2057 if "/" in ingressDevice:
2058 cmd += " " + str( ingressDevice )
2059 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002060 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002061 main.log.error( "You must specify the ingress port" )
2062 return None
2063
2064 cmd += " " + \
2065 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002066 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07002067
2068 if "/" in egressDevice:
2069 cmd += " " + str( egressDevice )
2070 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002071 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002072 main.log.error( "You must specify the egress port" )
2073 return None
2074
2075 cmd += " " +\
2076 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002077 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07002078
2079 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08002080 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002081 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07002082 # If error, return error message
2083 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002084 main.log.error( self.name + ": Error in adding mpls intent" )
Hari Krishna9e232602015-04-13 17:29:08 -07002085 return None
2086 else:
2087 # TODO: print out all the options in this message?
2088 main.log.info( "MPLS intent installed between " +
2089 str( ingressDevice ) + " and " +
2090 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002091 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07002092 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002093 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07002094 else:
2095 main.log.error( "Error, intent ID not found" )
2096 return None
Jon Hallc6793552016-01-19 14:18:37 -08002097 except AssertionError:
2098 main.log.exception( "" )
2099 return None
Hari Krishna9e232602015-04-13 17:29:08 -07002100 except TypeError:
2101 main.log.exception( self.name + ": Object not as expected" )
2102 return None
2103 except pexpect.EOF:
2104 main.log.error( self.name + ": EOF exception found" )
2105 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002106 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002107 except Exception:
2108 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002109 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002110
Jon Hallefbd9792015-03-05 16:11:36 -08002111 def removeIntent( self, intentId, app='org.onosproject.cli',
2112 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002113 """
shahshreya1c818fc2015-02-26 13:44:08 -08002114 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07002115 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08002116 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07002117 -p or --purge: Purge the intent from the store after removal
2118
Jon Halle3f39ff2015-01-13 11:50:53 -08002119 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07002120 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08002121 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08002122 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002123 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002124 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08002125 if purge:
2126 cmdStr += " -p"
2127 if sync:
2128 cmdStr += " -s"
2129
2130 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002131 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002132 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002133 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08002134 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002135 main.log.error( self.name + ": Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002136 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04002137 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002138 # TODO: Should this be main.TRUE
2139 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002140 except AssertionError:
2141 main.log.exception( "" )
2142 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002143 except TypeError:
2144 main.log.exception( self.name + ": Object not as expected" )
2145 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002146 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002147 main.log.error( self.name + ": EOF exception found" )
2148 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002149 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002150 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002151 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002152 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002153
YPZhangfebf7302016-05-24 16:45:56 -07002154 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08002155 """
2156 Description:
2157 Remove all the intents
2158 Optional args:-
2159 -s or --sync: Waits for the removal before returning
2160 -p or --purge: Purge the intent from the store after removal
2161 Returns:
2162 Returns main.TRUE if all intents are removed, otherwise returns
2163 main.FALSE; Returns None for exception
2164 """
2165 try:
2166 cmdStr = "remove-intent"
2167 if purge:
2168 cmdStr += " -p"
2169 if sync:
2170 cmdStr += " -s"
2171
2172 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002173 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002174 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002175 assert "Command not found:" not in handle, handle
2176 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002177 main.log.error( self.name + ": Error in removing intent" )
Jeremy42df2e72016-02-23 16:37:46 -08002178 return main.FALSE
2179 else:
2180 return main.TRUE
2181 except AssertionError:
2182 main.log.exception( "" )
2183 return None
2184 except TypeError:
2185 main.log.exception( self.name + ": Object not as expected" )
2186 return None
2187 except pexpect.EOF:
2188 main.log.error( self.name + ": EOF exception found" )
2189 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002190 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002191 except Exception:
2192 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002193 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002194
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002195 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002196 """
2197 Purges all WITHDRAWN Intents
2198 """
2199 try:
2200 cmdStr = "purge-intents"
2201 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002202 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002203 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002204 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002205 main.log.error( self.name + ": Error in purging intents" )
Hari Krishna0ce0e152015-06-23 09:55:29 -07002206 return main.FALSE
2207 else:
2208 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002209 except AssertionError:
2210 main.log.exception( "" )
2211 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002212 except TypeError:
2213 main.log.exception( self.name + ": Object not as expected" )
2214 return None
2215 except pexpect.EOF:
2216 main.log.error( self.name + ": EOF exception found" )
2217 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002218 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002219 except Exception:
2220 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002221 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002222
Devin Lime6fe3c42017-10-18 16:28:40 -07002223 def wipeout( self ):
2224 """
2225 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2226 """
2227 try:
2228 cmdStr = "wipe-out please"
2229 handle = self.sendline( cmdStr, timeout=60 )
2230 assert handle is not None, "Error in sendline"
2231 assert "Command not found:" not in handle, handle
2232 return main.TRUE
2233 except AssertionError:
2234 main.log.exception( "" )
2235 return None
2236 except TypeError:
2237 main.log.exception( self.name + ": Object not as expected" )
2238 return None
2239 except pexpect.EOF:
2240 main.log.error( self.name + ": EOF exception found" )
2241 main.log.error( self.name + ": " + self.handle.before )
2242 main.cleanAndExit()
2243 except Exception:
2244 main.log.exception( self.name + ": Uncaught exception!" )
2245 main.cleanAndExit()
2246
kelvin-onlabd3b64892015-01-20 13:26:24 -08002247 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002248 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002249 NOTE: This method should be used after installing application:
2250 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002251 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002252 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002253 Description:
2254 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002255 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002256 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002257 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002258 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002259 cmdStr += " -j"
2260 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002261 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002262 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002263 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002264 except AssertionError:
2265 main.log.exception( "" )
2266 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002267 except TypeError:
2268 main.log.exception( self.name + ": Object not as expected" )
2269 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002270 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002271 main.log.error( self.name + ": EOF exception found" )
2272 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002273 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002274 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002275 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002276 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002277
pingping-lin54b03372015-08-13 14:43:10 -07002278 def ipv4RouteNumber( self ):
2279 """
2280 NOTE: This method should be used after installing application:
2281 onos-app-sdnip
2282 Description:
2283 Obtain the total IPv4 routes number in the system
2284 """
2285 try:
Pratik Parab57963572017-05-09 11:37:54 -07002286 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002287 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002288 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002289 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002290 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002291 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002292 except AssertionError:
2293 main.log.exception( "" )
2294 return None
2295 except ( TypeError, ValueError ):
2296 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002297 return None
2298 except pexpect.EOF:
2299 main.log.error( self.name + ": EOF exception found" )
2300 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002301 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002302 except Exception:
2303 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002304 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002305
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002306 # =============Function to check Bandwidth allocation========
Jon Hall0e240372018-05-02 11:21:57 -07002307 def allocations( self, jsonFormat = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002308 """
2309 Description:
2310 Obtain Bandwidth Allocation Information from ONOS cli.
2311 """
2312 try:
2313 cmdStr = "allocations"
2314 if jsonFormat:
2315 cmdStr += " -j"
Jon Hall0e240372018-05-02 11:21:57 -07002316 handle = self.sendline( cmdStr, timeout=300 )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002317 assert handle is not None, "Error in sendline"
2318 assert "Command not found:" not in handle, handle
2319 return handle
2320 except AssertionError:
2321 main.log.exception( "" )
2322 return None
2323 except ( TypeError, ValueError ):
2324 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2325 return None
2326 except pexpect.EOF:
2327 main.log.error( self.name + ": EOF exception found" )
2328 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002329 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002330 except Exception:
2331 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002332 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002333
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002334 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002335 """
andrewonlabe6745342014-10-17 14:29:13 -04002336 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002337 Obtain intents from the ONOS cli.
2338 Optional:
2339 * jsonFormat: Enable output formatting in json, default to True
2340 * summary: Whether only output the intent summary, defaults to False
2341 * type: Only output a certain type of intent. This options is valid
2342 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002343 """
andrewonlabe6745342014-10-17 14:29:13 -04002344 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002345 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002346 if summary:
2347 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002348 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002349 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002350 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002351 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002352 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002353 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002354 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002355 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002356 else:
Jon Hallff566d52016-01-15 14:45:36 -08002357 intentType = ""
2358 # IF we want the summary of a specific intent type
2359 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002360 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002361 if intentType in jsonResult.keys():
2362 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002363 else:
Jon Hallff566d52016-01-15 14:45:36 -08002364 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002365 return handle
2366 else:
2367 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002368 except AssertionError:
2369 main.log.exception( "" )
2370 return None
2371 except ( TypeError, ValueError ):
2372 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002373 return None
2374 except pexpect.EOF:
2375 main.log.error( self.name + ": EOF exception found" )
2376 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002377 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002378 except Exception:
2379 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002380 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002381
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002382 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002383 """
You Wangfdcbfc42016-05-16 12:16:53 -07002384 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002385 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002386 list of intent IDs.
2387 Parameters:
2388 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002389 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002390 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002391 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002392 accepted.
2393 Returns a list of dictionaries if a list of intent IDs is accepted,
2394 and each dictionary maps 'id' to the Intent ID and 'state' to
2395 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002396 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002397
kelvin-onlab54400a92015-02-26 18:05:51 -08002398 try:
2399 state = "State is Undefined"
2400 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002401 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002402 else:
Jon Hallc6793552016-01-19 14:18:37 -08002403 rawJson = intentsJson
2404 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002405 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002406 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002407 if intentsId == intent[ 'id' ]:
2408 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002409 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002410 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002411 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002412 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002413 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002414 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002415 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002416 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002417 for intent in parsedIntentsJson:
2418 if intentsId[ i ] == intent[ 'id' ]:
2419 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002420 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002421 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002422 break
Jon Hallefbd9792015-03-05 16:11:36 -08002423 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002424 main.log.warn( "Could not find all intents in ONOS output" )
2425 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002426 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002427 else:
Jon Hall53158082017-05-18 11:17:00 -07002428 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002429 return None
Jon Hallc6793552016-01-19 14:18:37 -08002430 except ( TypeError, ValueError ):
2431 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002432 return None
2433 except pexpect.EOF:
2434 main.log.error( self.name + ": EOF exception found" )
2435 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002436 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002437 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002438 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002439 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002440
Jon Hallf539eb92017-05-22 17:18:42 -07002441 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002442 """
2443 Description:
2444 Check intents state
2445 Required:
2446 intentsId - List of intents ID to be checked
2447 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002448 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002449 state in the list.
2450 *NOTE: You can pass in a list of expected state,
2451 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002452 Return:
Jon Hall53158082017-05-18 11:17:00 -07002453 Returns main.TRUE only if all intent are the same as expected states,
2454 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002455 """
2456 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002457 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002458 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002459
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002460 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002461 intentsDict = []
2462 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002463 if isinstance( intentsId, types.StringType ) \
2464 and intent.get( 'id' ) == intentsId:
2465 intentsDict.append( intent )
2466 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002467 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002468 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002469
2470 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002471 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002472 "getting intents state" )
2473 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002474
2475 if isinstance( expectedState, types.StringType ):
2476 for intents in intentsDict:
2477 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002478 main.log.debug( self.name + " : Intent ID - " +
2479 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002480 " actual state = " +
2481 intents.get( 'state' )
2482 + " does not equal expected state = "
2483 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002484 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002485 elif isinstance( expectedState, types.ListType ):
2486 for intents in intentsDict:
2487 if not any( state == intents.get( 'state' ) for state in
2488 expectedState ):
2489 main.log.debug( self.name + " : Intent ID - " +
2490 intents.get( 'id' ) +
2491 " actual state = " +
2492 intents.get( 'state' ) +
2493 " does not equal expected states = "
2494 + str( expectedState ) )
2495 returnValue = main.FALSE
2496
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002497 if returnValue == main.TRUE:
2498 main.log.info( self.name + ": All " +
2499 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002500 " intents are in " + str( expectedState ) +
2501 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002502 return returnValue
2503 except TypeError:
2504 main.log.exception( self.name + ": Object not as expected" )
2505 return None
2506 except pexpect.EOF:
2507 main.log.error( self.name + ": EOF exception found" )
2508 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002509 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002510 except Exception:
2511 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002512 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002513
Jon Hallf539eb92017-05-22 17:18:42 -07002514 def compareBandwidthAllocations( self, expectedAllocations ):
2515 """
2516 Description:
2517 Compare the allocated bandwidth with the given allocations
2518 Required:
2519 expectedAllocations - The expected ONOS output of the allocations command
2520 Return:
2521 Returns main.TRUE only if all intent are the same as expected states,
2522 otherwise returns main.FALSE.
2523 """
2524 # FIXME: Convert these string comparisons to object comparisons
2525 try:
2526 returnValue = main.TRUE
2527 bandwidthFailed = False
2528 rawAlloc = self.allocations()
2529 expectedFormat = StringIO( expectedAllocations )
2530 ONOSOutput = StringIO( rawAlloc )
2531 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2532 str( expectedFormat ) ) )
2533
2534 for actual, expected in izip( ONOSOutput, expectedFormat ):
2535 actual = actual.rstrip()
2536 expected = expected.rstrip()
2537 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2538 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002539 marker1 = actual.find( 'allocated' )
2540 m1 = actual[ :marker1 ]
2541 marker2 = expected.find( 'allocated' )
2542 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002543 if m1 != m2:
2544 bandwidthFailed = True
2545 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2546 bandwidthFailed = True
2547 expectedFormat.close()
2548 ONOSOutput.close()
2549
2550 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002551 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002552 returnValue = main.FALSE
2553 return returnValue
2554 except TypeError:
2555 main.log.exception( self.name + ": Object not as expected" )
2556 return None
2557 except pexpect.EOF:
2558 main.log.error( self.name + ": EOF exception found" )
2559 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002560 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002561 except Exception:
2562 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002563 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002564
You Wang66518af2016-05-16 15:32:59 -07002565 def compareIntent( self, intentDict ):
2566 """
2567 Description:
2568 Compare the intent ids and states provided in the argument with all intents in ONOS
2569 Return:
2570 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2571 Arguments:
2572 intentDict: a dictionary which maps intent ids to intent states
2573 """
2574 try:
2575 intentsRaw = self.intents()
2576 intentsJson = json.loads( intentsRaw )
2577 intentDictONOS = {}
2578 for intent in intentsJson:
2579 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002580 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002581 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002582 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002583 str( len( intentDict ) ) + " expected and " +
2584 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002585 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002586 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002587 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002588 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2589 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002590 else:
2591 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2592 main.log.debug( self.name + ": intent ID - " + intentID +
2593 " expected state is " + intentDict[ intentID ] +
2594 " but actual state is " + intentDictONOS[ intentID ] )
2595 returnValue = main.FALSE
2596 intentDictONOS.pop( intentID )
2597 if len( intentDictONOS ) > 0:
2598 returnValue = main.FALSE
2599 for intentID in intentDictONOS.keys():
2600 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002601 if returnValue == main.TRUE:
2602 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2603 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002604 except KeyError:
2605 main.log.exception( self.name + ": KeyError exception found" )
2606 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002607 except ( TypeError, ValueError ):
2608 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002609 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002610 except pexpect.EOF:
2611 main.log.error( self.name + ": EOF exception found" )
2612 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002613 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002614 except Exception:
2615 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002616 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002617
YPZhang14a4aa92016-07-15 13:37:15 -07002618 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002619 """
2620 Description:
2621 Check the number of installed intents.
2622 Optional:
2623 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002624 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002625 Return:
2626 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2627 , otherwise, returns main.FALSE.
2628 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002629
GlennRCed771242016-01-13 17:02:47 -08002630 try:
2631 cmd = "intents -s -j"
2632
2633 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002634 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002635 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002636 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002637 response = json.loads( response )
2638
2639 # get total and installed number, see if they are match
2640 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002641 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002642 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2643 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002644 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002645 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2646 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002647 return main.FALSE
2648
Jon Hallc6793552016-01-19 14:18:37 -08002649 except ( TypeError, ValueError ):
2650 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002651 return None
2652 except pexpect.EOF:
2653 main.log.error( self.name + ": EOF exception found" )
2654 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002655 if noExit:
2656 return main.FALSE
2657 else:
Devin Lim44075962017-08-11 10:56:37 -07002658 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002659 except pexpect.TIMEOUT:
2660 main.log.error( self.name + ": ONOS timeout" )
2661 return None
GlennRCed771242016-01-13 17:02:47 -08002662 except Exception:
2663 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002664 if noExit:
2665 return main.FALSE
2666 else:
Devin Lim44075962017-08-11 10:56:37 -07002667 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002668
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002669 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002670 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002671 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002672 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002673 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002674 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002675 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002676 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002677 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002678 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002679 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002680 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002681 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002682 cmdStr += " -n"
2683 cmdStr += " " + state
2684 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002685 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002686 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002687 assert "Command not found:" not in handle, handle
2688 if re.search( "Error:", handle ):
2689 main.log.error( self.name + ": flows() response: " +
2690 str( handle ) )
2691 return handle
2692 except AssertionError:
2693 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002694 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002695 except TypeError:
2696 main.log.exception( self.name + ": Object not as expected" )
2697 return None
Jon Hallc6793552016-01-19 14:18:37 -08002698 except pexpect.TIMEOUT:
2699 main.log.error( self.name + ": ONOS timeout" )
2700 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002701 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002702 main.log.error( self.name + ": EOF exception found" )
2703 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002704 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002705 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002706 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002707 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002708
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002709 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002710 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002711 count = int( count ) if count else 0
steven30801eccfe212019-01-24 13:00:42 +08002712 main.log.debug( "found {} flows".format( count ) )
Jon Hall39570262020-11-17 12:18:19 -08002713 return count if ( count >= min ) else False
GlennRCed771242016-01-13 17:02:47 -08002714
Jon Halle0f0b342017-04-18 11:43:47 -07002715 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002716 """
2717 Description:
GlennRCed771242016-01-13 17:02:47 -08002718 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002719 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2720 if the count of those states is 0, which means all current flows
2721 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002722 Optional:
GlennRCed771242016-01-13 17:02:47 -08002723 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002724 Return:
2725 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002726 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002727 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002728 """
2729 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002730 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002731 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002732 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002733 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002734 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002735 if rawFlows:
2736 # if we didn't get flows or flows function return None, we should return
2737 # main.Flase
2738 checkedStates.append( json.loads( rawFlows ) )
2739 else:
2740 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002741 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002742 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002743 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002744 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002745 except TypeError:
2746 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002747 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002748
GlennRCed771242016-01-13 17:02:47 -08002749 # We want to count PENDING_ADD if isPENDING is true
2750 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002751 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002752 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002753 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002754 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002755 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002756 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002757 except ( TypeError, ValueError ):
2758 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002759 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002760
YPZhang240842b2016-05-17 12:00:50 -07002761 except AssertionError:
2762 main.log.exception( "" )
2763 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002764 except pexpect.TIMEOUT:
2765 main.log.error( self.name + ": ONOS timeout" )
2766 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002767 except pexpect.EOF:
2768 main.log.error( self.name + ": EOF exception found" )
2769 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002770 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002771 except Exception:
2772 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002773 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002774
GlennRCed771242016-01-13 17:02:47 -08002775 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002776 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002777 """
andrewonlab87852b02014-11-19 18:44:19 -05002778 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002779 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002780 a specific point-to-point intent definition
2781 Required:
GlennRCed771242016-01-13 17:02:47 -08002782 * ingress: specify source dpid
2783 * egress: specify destination dpid
2784 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002785 Optional:
GlennRCed771242016-01-13 17:02:47 -08002786 * offset: the keyOffset is where the next batch of intents
2787 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002788 * noExit: If set to True, TestON will not exit if any error when issus command
2789 * getResponse: If set to True, function will return ONOS response.
2790
GlennRCed771242016-01-13 17:02:47 -08002791 Returns: If failed to push test intents, it will returen None,
2792 if successful, return true.
2793 Timeout expection will return None,
2794 TypeError will return false
2795 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002796 """
andrewonlab87852b02014-11-19 18:44:19 -05002797 try:
GlennRCed771242016-01-13 17:02:47 -08002798 if background:
2799 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002800 else:
GlennRCed771242016-01-13 17:02:47 -08002801 back = ""
2802 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002803 ingress,
2804 egress,
2805 batchSize,
2806 offset,
2807 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002808 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002809 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002810 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002811 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002812 if getResponse:
2813 return response
2814
GlennRCed771242016-01-13 17:02:47 -08002815 # TODO: We should handle if there is failure in installation
2816 return main.TRUE
2817
Jon Hallc6793552016-01-19 14:18:37 -08002818 except AssertionError:
2819 main.log.exception( "" )
2820 return None
GlennRCed771242016-01-13 17:02:47 -08002821 except pexpect.TIMEOUT:
2822 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002823 return None
andrewonlab87852b02014-11-19 18:44:19 -05002824 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002825 main.log.error( self.name + ": EOF exception found" )
2826 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002827 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002828 except TypeError:
2829 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002830 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002831 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002832 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002833 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002834
YPZhangebf9eb52016-05-12 15:20:24 -07002835 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002836 """
2837 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002838 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002839 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002840 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002841 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002842 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002843
YPZhangb5d3f832016-01-23 22:54:26 -08002844 try:
YPZhange3109a72016-02-02 11:25:37 -08002845 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002846 cmd = "flows -c added"
2847 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2848 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002849 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002850 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002851 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002852 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002853 else:
You Wang68568b12019-03-04 11:49:57 -08002854 main.log.warn( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002855 return None
2856 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002857
You Wangd3097f72018-12-12 11:56:03 -08002858 except IndexError:
2859 main.log.exception( "{}: Object not as expected!".format( self.name ) )
2860 main.log.debug( "rawFlows: {}".format( rawFlows ) )
2861 return None
You Wangd3cb2ce2016-05-16 14:01:24 -07002862 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002863 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002864 return None
2865 except pexpect.EOF:
2866 main.log.error( self.name + ": EOF exception found" )
2867 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002868 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002869 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002870 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002871 except pexpect.TIMEOUT:
2872 main.log.error( self.name + ": ONOS timeout" )
2873 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002874 except Exception:
2875 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002876 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002877 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002878 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002879
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002880 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002881 """
2882 Description:
2883 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002884 Optional:
2885 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002886 Return:
2887 The number of intents
2888 """
2889 try:
2890 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002891 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002892 if response is None:
2893 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002894 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002895 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002896 except ( TypeError, ValueError ):
2897 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002898 return None
2899 except pexpect.EOF:
2900 main.log.error( self.name + ": EOF exception found" )
2901 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002902 if noExit:
2903 return -1
2904 else:
Devin Lim44075962017-08-11 10:56:37 -07002905 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002906 except Exception:
2907 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002908 if noExit:
2909 return -1
2910 else:
Devin Lim44075962017-08-11 10:56:37 -07002911 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002912
kelvin-onlabd3b64892015-01-20 13:26:24 -08002913 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002914 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002915 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002916 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002917 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002918 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002919 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002920 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002921 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002922 cmdStr += " -j"
2923 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002924 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002925 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002926 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002927 except AssertionError:
2928 main.log.exception( "" )
2929 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002930 except TypeError:
2931 main.log.exception( self.name + ": Object not as expected" )
2932 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002933 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002934 main.log.error( self.name + ": EOF exception found" )
2935 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002936 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002937 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002938 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002939 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002940
kelvin-onlabd3b64892015-01-20 13:26:24 -08002941 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002942 """
2943 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002944 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002945 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002946 """
andrewonlab867212a2014-10-22 20:13:38 -04002947 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002948 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002949 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002950 cmdStr += " -j"
2951 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002952 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002953 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002954 if handle:
2955 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002956 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002957 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002958 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002959 else:
2960 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002961 except AssertionError:
2962 main.log.exception( "" )
2963 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002964 except TypeError:
2965 main.log.exception( self.name + ": Object not as expected" )
2966 return None
andrewonlab867212a2014-10-22 20:13:38 -04002967 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002968 main.log.error( self.name + ": EOF exception found" )
2969 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002970 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002971 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002972 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002973 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002974
kelvin8ec71442015-01-15 16:57:00 -08002975 # Wrapper functions ****************
2976 # Wrapper functions use existing driver
2977 # functions and extends their use case.
2978 # For example, we may use the output of
2979 # a normal driver function, and parse it
2980 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002981
kelvin-onlabd3b64892015-01-20 13:26:24 -08002982 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002983 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002984 Description:
2985 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002986 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002987 try:
kelvin8ec71442015-01-15 16:57:00 -08002988 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002989 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002990 if intentsStr is None:
2991 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002992 # Convert to a dictionary
2993 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002994 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002995 for intent in intents:
2996 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002997 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002998 except TypeError:
2999 main.log.exception( self.name + ": Object not as expected" )
3000 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04003001 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003002 main.log.error( self.name + ": EOF exception found" )
3003 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003004 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003005 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003006 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003007 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04003008
You Wang3c276252016-09-21 15:21:36 -07003009 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08003010 """
3011 Determine the number of flow rules for the given device id that are
3012 in the added state
You Wang3c276252016-09-21 15:21:36 -07003013 Params:
3014 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08003015 """
3016 try:
You Wang3c276252016-09-21 15:21:36 -07003017 if core:
3018 cmdStr = "flows any " + str( deviceId ) + " | " +\
3019 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
3020 else:
3021 cmdStr = "flows any " + str( deviceId ) + " | " +\
3022 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003023 handle = self.lineCount( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003024 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003025 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08003026 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003027 except AssertionError:
3028 main.log.exception( "" )
3029 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08003030 except pexpect.EOF:
3031 main.log.error( self.name + ": EOF exception found" )
3032 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003033 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003034 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08003035 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003036 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04003037
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003038 def groupAddedCount( self, deviceId, core=False ):
3039 """
3040 Determine the number of group rules for the given device id that are
3041 in the added state
3042 Params:
3043 core: if True, only return the number of core groups added
3044 """
3045 try:
3046 if core:
3047 cmdStr = "groups any " + str( deviceId ) + " | " +\
3048 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
3049 else:
3050 cmdStr = "groups any " + str( deviceId ) + " | " +\
3051 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003052 handle = self.lineCount( cmdStr )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003053 assert handle is not None, "Error in sendline"
3054 assert "Command not found:" not in handle, handle
3055 return handle
3056 except AssertionError:
3057 main.log.exception( "" )
3058 return None
3059 except pexpect.EOF:
3060 main.log.error( self.name + ": EOF exception found" )
3061 main.log.error( self.name + ": " + self.handle.before )
3062 main.cleanAndExit()
3063 except Exception:
3064 main.log.exception( self.name + ": Uncaught exception!" )
3065 main.cleanAndExit()
3066
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003067 def addStaticRoute( self, subnet, intf):
3068 """
3069 Adds a static route to onos.
3070 Params:
3071 subnet: The subnet reaching through this route
3072 intf: The interface this route is reachable through
3073 """
3074 try:
3075 cmdStr = "route-add " + subnet + " " + intf
3076 handle = self.sendline( cmdStr )
3077 assert handle is not None, "Error in sendline"
3078 assert "Command not found:" not in handle, handle
3079 return handle
3080 except AssertionError:
3081 main.log.exception( "" )
3082 return None
3083 except pexpect.EOF:
3084 main.log.error( self.name + ": EOF exception found" )
3085 main.log.error( self.name + ": " + self.handle.before )
3086 main.cleanAndExit()
3087 except Exception:
3088 main.log.exception( self.name + ": Uncaught exception!" )
3089 main.cleanAndExit()
3090
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003091 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
3092 """
3093 Description:
3094 Check whether the number of groups for the given device id that
3095 are in ADDED state is bigger than minGroupCount.
3096 Required:
3097 * deviceId: device id to check the number of added group rules
3098 Optional:
3099 * minGroupCount: the number of groups to compare
3100 * core: if True, only check the number of core groups added
3101 * comparison: if 0, compare with greater than minFlowCount
3102 * if 1, compare with equal to minFlowCount
3103 Return:
3104 Returns the number of groups if it is bigger than minGroupCount,
3105 returns main.FALSE otherwise.
3106 """
3107 count = self.groupAddedCount( deviceId, core )
3108 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003109 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003110 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
3111
You Wangc02f3be2018-05-18 12:14:23 -07003112 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003113 """
3114 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07003115 deviceId: Id of the device from which we retrieve groups
3116 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003117 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003118 try:
You Wangc02f3be2018-05-18 12:14:23 -07003119 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
3120 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003121 assert handle is not None, "Error in sendline"
3122 assert "Command not found:" not in handle, handle
3123 return handle
3124 except AssertionError:
3125 main.log.exception( "" )
3126 return None
3127 except TypeError:
3128 main.log.exception( self.name + ": Object not as expected" )
3129 return None
3130 except pexpect.EOF:
3131 main.log.error( self.name + ": EOF exception found" )
3132 main.log.error( self.name + ": " + self.handle.before )
3133 main.cleanAndExit()
3134 except Exception:
3135 main.log.exception( self.name + ": Uncaught exception!" )
3136 main.cleanAndExit()
3137
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003138 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003139 """
3140 Description:
3141 Check whether the number of flow rules for the given device id that
3142 are in ADDED state is bigger than minFlowCount.
3143 Required:
3144 * deviceId: device id to check the number of added flow rules
3145 Optional:
3146 * minFlowCount: the number of flow rules to compare
3147 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003148 * comparison: if 0, compare with greater than minFlowCount
3149 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003150 Return:
3151 Returns the number of flow rules if it is bigger than minFlowCount,
3152 returns main.FALSE otherwise.
3153 """
3154 count = self.flowAddedCount( deviceId, core )
3155 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003156 main.log.debug( "found {} flows".format( count ) )
Jon Hall39570262020-11-17 12:18:19 -08003157 return count if ((count >= expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003158
kelvin-onlabd3b64892015-01-20 13:26:24 -08003159 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003160 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003161 Use 'devices' function to obtain list of all devices
3162 and parse the result to obtain a list of all device
3163 id's. Returns this list. Returns empty list if no
3164 devices exist
kelvin8ec71442015-01-15 16:57:00 -08003165 List is ordered sequentially
3166
andrewonlab3e15ead2014-10-15 14:21:34 -04003167 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003168 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003169 the ids. By obtaining the list of device ids on the fly,
3170 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003171 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003172 try:
kelvin8ec71442015-01-15 16:57:00 -08003173 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003174 devicesStr = self.devices( jsonFormat=False )
3175 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003176
kelvin-onlabd3b64892015-01-20 13:26:24 -08003177 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003178 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003179 return idList
kelvin8ec71442015-01-15 16:57:00 -08003180
3181 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003182 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003183 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003184 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003185 # Split list further into arguments before and after string
3186 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003187 # append to idList
3188 for arg in tempList:
3189 idList.append( arg.split( "id=" )[ 1 ] )
3190 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003191
Jon Halld4d4b372015-01-28 16:02:41 -08003192 except TypeError:
3193 main.log.exception( self.name + ": Object not as expected" )
3194 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003195 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003196 main.log.error( self.name + ": EOF exception found" )
3197 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003198 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003199 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003200 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003201 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003202
kelvin-onlabd3b64892015-01-20 13:26:24 -08003203 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003204 """
andrewonlab7c211572014-10-15 16:45:20 -04003205 Uses 'nodes' function to obtain list of all nodes
3206 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003207 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003208 Returns:
3209 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003210 """
andrewonlab7c211572014-10-15 16:45:20 -04003211 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003212 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003213 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003214 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003215 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003216 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003217 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003218 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003219 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003220 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003221 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003222 except ( TypeError, ValueError ):
3223 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003224 return None
andrewonlab7c211572014-10-15 16:45:20 -04003225 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003226 main.log.error( self.name + ": EOF exception found" )
3227 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003228 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003229 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003230 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003231 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003232
kelvin-onlabd3b64892015-01-20 13:26:24 -08003233 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003234 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003235 Return the first device from the devices api whose 'id' contains 'dpid'
3236 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003237 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003238 try:
kelvin8ec71442015-01-15 16:57:00 -08003239 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003240 return None
3241 else:
kelvin8ec71442015-01-15 16:57:00 -08003242 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003243 rawDevices = self.devices()
3244 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003245 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003246 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003247 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3248 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003249 return device
3250 return None
Jon Hallc6793552016-01-19 14:18:37 -08003251 except ( TypeError, ValueError ):
3252 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003253 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003254 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003255 main.log.error( self.name + ": EOF exception found" )
3256 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003257 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003258 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003259 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003260 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003261
You Wang24139872016-05-03 11:48:47 -07003262 def getTopology( self, topologyOutput ):
3263 """
3264 Definition:
3265 Loads a json topology output
3266 Return:
3267 topology = current ONOS topology
3268 """
You Wang24139872016-05-03 11:48:47 -07003269 try:
3270 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003271 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003272 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003273 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003274 except ( TypeError, ValueError ):
3275 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3276 return None
You Wang24139872016-05-03 11:48:47 -07003277 except pexpect.EOF:
3278 main.log.error( self.name + ": EOF exception found" )
3279 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003280 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003281 except Exception:
3282 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003283 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003284
Jon Hall39570262020-11-17 12:18:19 -08003285 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, numoSCCs=1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003286 """
Jon Hallefbd9792015-03-05 16:11:36 -08003287 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003288 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003289 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003290
Flavio Castro82ee2f62016-06-07 15:04:12 -07003291 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003292 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003293 numoctrl = expected number of controllers
Jon Hall39570262020-11-17 12:18:19 -08003294 numoSCCs = Number of expected SCCs
You Wang24139872016-05-03 11:48:47 -07003295 logLevel = level to log to.
3296 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003297
Jon Hallefbd9792015-03-05 16:11:36 -08003298 Returns: main.TRUE if the number of switches and links are correct,
3299 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003300 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003301 """
Jon Hall42db6dc2014-10-24 19:03:48 -04003302 try:
You Wang13310252016-07-31 10:56:14 -07003303 summary = self.summary()
3304 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003305 except ( TypeError, ValueError ):
3306 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3307 return main.ERROR
3308 try:
3309 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003310 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003311 return main.ERROR
3312 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003313 # Is the number of switches is what we expected
3314 devices = topology.get( 'devices', False )
3315 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003316 nodes = summary.get( 'nodes', False )
Jon Hall39570262020-11-17 12:18:19 -08003317 SCCs = summary.get( 'SCC(s)', False )
3318 if devices is False or links is False or nodes is False or SCCs is False:
3319 main.log.warn( "Issues parsing topology and summary output" )
3320 main.log.debug( topology )
3321 main.log.debug( summary )
Jon Hall42db6dc2014-10-24 19:03:48 -04003322 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003323 switchCheck = ( int( devices ) == int( numoswitch ) )
Jon Hall39570262020-11-17 12:18:19 -08003324 if not switchCheck:
3325 main.log.debug( "switch Check Failed" )
Pier6a0c4de2018-03-18 16:01:30 -07003326 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Jon Hall39570262020-11-17 12:18:19 -08003327 if not linkCheck:
3328 main.log.debug( "link Check Failed" )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003329 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
Jon Hall39570262020-11-17 12:18:19 -08003330 if not nodeCheck:
3331 main.log.debug( "node Check Failed" )
3332 SCCsCheck = ( int( SCCs ) == int( numoSCCs ) ) or int( numoSCCs ) == -1
3333 if not SCCsCheck:
3334 main.log.debug( "SCCs Check Failed" )
3335 if switchCheck and linkCheck and nodeCheck and SCCsCheck:
kelvin8ec71442015-01-15 16:57:00 -08003336 # We expected the correct numbers
Jon Hall39570262020-11-17 12:18:19 -08003337 output = output + "The number of links, switches, nodes, and SCCs match "\
You Wang24139872016-05-03 11:48:47 -07003338 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003339 result = main.TRUE
3340 else:
You Wang24139872016-05-03 11:48:47 -07003341 output = output + \
Jon Hall627b1572020-12-01 12:01:15 -08003342 "The number of links, switches, nodes, and SCCs does not match " + \
You Wang24139872016-05-03 11:48:47 -07003343 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003344 result = main.FALSE
Jon Hall39570262020-11-17 12:18:19 -08003345 output = output + "\n ONOS sees %i devices " % int( devices )
3346 output = output + "(%i expected) " % int( numoswitch )
3347 if int( numolink ) >= 0:
Pier6a0c4de2018-03-18 16:01:30 -07003348 output = output + "and %i links " % int( links )
Jon Hall39570262020-11-17 12:18:19 -08003349 output = output + "(%i expected) " % int( numolink )
3350 if int( numoctrl ) >= 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003351 output = output + "and %i controllers " % int( nodes )
Jon Hall39570262020-11-17 12:18:19 -08003352 output = output + "(%i expected) " % int( numoctrl )
3353 if int( numoSCCs ) >= 0:
3354 output = output + "and %i SCCs " % int( SCCs )
3355 output = output + "(%i expected)" % int( numoSCCs )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003356 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003357 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003358 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003359 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003360 else:
You Wang24139872016-05-03 11:48:47 -07003361 main.log.info( output )
Jon Hall39570262020-11-17 12:18:19 -08003362 main.TOPOOUTPUT = output
kelvin8ec71442015-01-15 16:57:00 -08003363 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003364 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003365 main.log.error( self.name + ": EOF exception found" )
3366 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003367 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003368 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003369 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003370 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003371
kelvin-onlabd3b64892015-01-20 13:26:24 -08003372 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003373 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003374 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003375 deviceId must be the id of a device as seen in the onos devices command
3376 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003377 role must be either master, standby, or none
3378
Jon Halle3f39ff2015-01-13 11:50:53 -08003379 Returns:
3380 main.TRUE or main.FALSE based on argument verification and
3381 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003382 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003383 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003384 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003385 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003386 cmdStr = "device-role " +\
3387 str( deviceId ) + " " +\
3388 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003389 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003390 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003391 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003392 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003393 if re.search( "Error", handle ):
3394 # end color output to escape any colours
3395 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003396 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003397 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003398 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003399 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003400 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003401 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003402 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003403 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003404 except AssertionError:
3405 main.log.exception( "" )
3406 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003407 except TypeError:
3408 main.log.exception( self.name + ": Object not as expected" )
3409 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003410 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003411 main.log.error( self.name + ": EOF exception found" )
3412 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003413 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003414 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003415 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003416 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003417
kelvin-onlabd3b64892015-01-20 13:26:24 -08003418 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003419 """
Jon Hall0dd09952018-04-19 09:59:11 -07003420 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003421 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003422 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003423 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003424 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003425 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003426 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003427 cmdStr += " -j"
3428 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003429 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003430 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003431 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003432 except AssertionError:
3433 main.log.exception( "" )
3434 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003435 except TypeError:
3436 main.log.exception( self.name + ": Object not as expected" )
3437 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003438 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003439 main.log.error( self.name + ": EOF exception found" )
3440 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003441 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003442 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003443 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003444 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003445
kelvin-onlabd3b64892015-01-20 13:26:24 -08003446 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003447 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003448 CLI command to get the current leader for the Election test application
3449 NOTE: Requires installation of the onos-app-election feature
3450 Returns: Node IP of the leader if one exists
3451 None if none exists
3452 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003453 """
Jon Hall94fd0472014-12-08 11:52:42 -08003454 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003455 cmdStr = "election-test-leader"
3456 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003457 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003458 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003459 # Leader
3460 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003461 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003462 nodeSearch = re.search( leaderPattern, response )
3463 if nodeSearch:
3464 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003465 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003466 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003467 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003468 # no leader
3469 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003470 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003471 nullSearch = re.search( nullPattern, response )
3472 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003473 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003474 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003475 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003476 # error
Jon Hall0e240372018-05-02 11:21:57 -07003477 main.log.error( self.name + ": Error in electionTestLeader on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003478 ": " + "unexpected response" )
3479 main.log.error( repr( response ) )
3480 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003481 except AssertionError:
3482 main.log.exception( "" )
3483 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003484 except TypeError:
3485 main.log.exception( self.name + ": Object not as expected" )
3486 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003487 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003488 main.log.error( self.name + ": EOF exception found" )
3489 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003490 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003491 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003492 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003493 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003494
kelvin-onlabd3b64892015-01-20 13:26:24 -08003495 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003496 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003497 CLI command to run for leadership of the Election test application.
3498 NOTE: Requires installation of the onos-app-election feature
3499 Returns: Main.TRUE on success
3500 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003501 """
Jon Hall94fd0472014-12-08 11:52:42 -08003502 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003503 cmdStr = "election-test-run"
3504 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003505 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003506 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003507 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003508 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003509 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003510 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003511 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003512 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003513 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003514 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003515 # error
Jon Hall0e240372018-05-02 11:21:57 -07003516 main.log.error( self.name + ": Error in electionTestRun on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003517 ": " + "unexpected response" )
3518 main.log.error( repr( response ) )
3519 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003520 except AssertionError:
3521 main.log.exception( "" )
3522 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003523 except TypeError:
3524 main.log.exception( self.name + ": Object not as expected" )
3525 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003526 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003527 main.log.error( self.name + ": EOF exception found" )
3528 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003529 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003530 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003531 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003532 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003533
kelvin-onlabd3b64892015-01-20 13:26:24 -08003534 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003535 """
Jon Hall94fd0472014-12-08 11:52:42 -08003536 * CLI command to withdraw the local node from leadership election for
3537 * the Election test application.
3538 #NOTE: Requires installation of the onos-app-election feature
3539 Returns: Main.TRUE on success
3540 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003541 """
Jon Hall94fd0472014-12-08 11:52:42 -08003542 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003543 cmdStr = "election-test-withdraw"
3544 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003545 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003546 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003547 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003548 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003549 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003550 if re.search( successPattern, response ):
3551 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003552 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003553 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003554 # error
Jon Hall0e240372018-05-02 11:21:57 -07003555 main.log.error( self.name + ": Error in electionTestWithdraw on " +
Jon Hall97cf84a2016-06-20 13:35:58 -07003556 self.name + ": " + "unexpected response" )
3557 main.log.error( repr( response ) )
3558 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003559 except AssertionError:
3560 main.log.exception( "" )
3561 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003562 except TypeError:
3563 main.log.exception( self.name + ": Object not as expected" )
3564 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003565 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003566 main.log.error( self.name + ": EOF exception found" )
3567 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003568 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003569 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003570 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003571 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003572
kelvin8ec71442015-01-15 16:57:00 -08003573 def getDevicePortsEnabledCount( self, dpid ):
3574 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003575 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003576 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003577 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003578 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003579 cmdStr = "onos:ports -e " + dpid + " | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003580 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003581 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003582 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003583 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003584 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003585 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003586 return output
Jon Hallc6793552016-01-19 14:18:37 -08003587 except AssertionError:
3588 main.log.exception( "" )
3589 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003590 except TypeError:
3591 main.log.exception( self.name + ": Object not as expected" )
3592 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003593 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003594 main.log.error( self.name + ": EOF exception found" )
3595 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003596 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003597 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003598 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003599 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003600
kelvin8ec71442015-01-15 16:57:00 -08003601 def getDeviceLinksActiveCount( self, dpid ):
3602 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003603 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003604 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003605 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003606 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003607 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003608 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003609 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003610 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003611 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003612 main.log.error( self.name + ": Error in getting ports " )
kelvin-onlab898a6c62015-01-16 14:13:53 -08003613 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003614 return output
Jon Hallc6793552016-01-19 14:18:37 -08003615 except AssertionError:
3616 main.log.exception( "" )
3617 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003618 except TypeError:
3619 main.log.exception( self.name + ": Object not as expected" )
3620 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003621 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003622 main.log.error( self.name + ": EOF exception found" )
3623 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003624 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003625 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003626 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003627 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003628
kelvin8ec71442015-01-15 16:57:00 -08003629 def getAllIntentIds( self ):
3630 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003631 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003632 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003633 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003634 cmdStr = "onos:intents | grep id="
3635 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003636 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003637 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003638 if re.search( "Error", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003639 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003640 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003641 return output
Jon Hallc6793552016-01-19 14:18:37 -08003642 except AssertionError:
3643 main.log.exception( "" )
3644 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003645 except TypeError:
3646 main.log.exception( self.name + ": Object not as expected" )
3647 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003648 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003649 main.log.error( self.name + ": EOF exception found" )
3650 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003651 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003652 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003653 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003654 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003655
Jon Hall73509952015-02-24 16:42:56 -08003656 def intentSummary( self ):
3657 """
Jon Hallefbd9792015-03-05 16:11:36 -08003658 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003659 """
3660 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003661 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003662 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003663 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003664 states.append( intent.get( 'state', None ) )
3665 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003666 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003667 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003668 except ( TypeError, ValueError ):
3669 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003670 return None
3671 except pexpect.EOF:
3672 main.log.error( self.name + ": EOF exception found" )
3673 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003674 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003675 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003676 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003677 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003678
Jon Hall61282e32015-03-19 11:34:11 -07003679 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003680 """
3681 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003682 Optional argument:
3683 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003684 """
Jon Hall63604932015-02-26 17:09:50 -08003685 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003686 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003687 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003688 cmdStr += " -j"
3689 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003690 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003691 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003692 return output
Jon Hallc6793552016-01-19 14:18:37 -08003693 except AssertionError:
3694 main.log.exception( "" )
3695 return None
Jon Hall63604932015-02-26 17:09:50 -08003696 except TypeError:
3697 main.log.exception( self.name + ": Object not as expected" )
3698 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003699 except pexpect.EOF:
3700 main.log.error( self.name + ": EOF exception found" )
3701 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003702 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003703 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003704 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003705 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003706
acsmarsa4a4d1e2015-07-10 16:01:24 -07003707 def leaderCandidates( self, jsonFormat=True ):
3708 """
3709 Returns the output of the leaders -c command.
3710 Optional argument:
3711 * jsonFormat - boolean indicating if you want output in json
3712 """
3713 try:
3714 cmdStr = "onos:leaders -c"
3715 if jsonFormat:
3716 cmdStr += " -j"
3717 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003718 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003719 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003720 return output
Jon Hallc6793552016-01-19 14:18:37 -08003721 except AssertionError:
3722 main.log.exception( "" )
3723 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003724 except TypeError:
3725 main.log.exception( self.name + ": Object not as expected" )
3726 return None
3727 except pexpect.EOF:
3728 main.log.error( self.name + ": EOF exception found" )
3729 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003730 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003731 except Exception:
3732 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003733 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003734
Jon Hallc6793552016-01-19 14:18:37 -08003735 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003736 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003737 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003738 topic parameter and an empty list if the topic doesn't exist
3739 If no leader is elected leader in the returned list will be "none"
3740 Returns None if there is a type error processing the json object
3741 """
3742 try:
Jon Hall6e709752016-02-01 13:38:46 -08003743 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003744 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003745 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003746 assert "Command not found:" not in rawOutput, rawOutput
3747 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003748 results = []
3749 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003750 if dict[ "topic" ] == topic:
3751 leader = dict[ "leader" ]
3752 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003753 results.append( leader )
3754 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003755 return results
Jon Hallc6793552016-01-19 14:18:37 -08003756 except AssertionError:
3757 main.log.exception( "" )
3758 return None
3759 except ( TypeError, ValueError ):
3760 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003761 return None
3762 except pexpect.EOF:
3763 main.log.error( self.name + ": EOF exception found" )
3764 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003765 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003766 except Exception:
3767 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003768 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003769
Jon Hall61282e32015-03-19 11:34:11 -07003770 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003771 """
3772 Returns the output of the intent Pending map.
3773 """
Jon Hall63604932015-02-26 17:09:50 -08003774 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003775 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003776 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003777 cmdStr += " -j"
3778 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003779 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003780 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003781 return output
Jon Hallc6793552016-01-19 14:18:37 -08003782 except AssertionError:
3783 main.log.exception( "" )
3784 return None
Jon Hall63604932015-02-26 17:09:50 -08003785 except TypeError:
3786 main.log.exception( self.name + ": Object not as expected" )
3787 return None
3788 except pexpect.EOF:
3789 main.log.error( self.name + ": EOF exception found" )
3790 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003791 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003792 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003793 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003794 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003795
Jon Hall2c8959e2016-12-16 12:17:34 -08003796 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003797 """
3798 Returns the output of the raft partitions command for ONOS.
3799 """
Jon Hall61282e32015-03-19 11:34:11 -07003800 # Sample JSON
3801 # {
3802 # "leader": "tcp://10.128.30.11:7238",
3803 # "members": [
3804 # "tcp://10.128.30.11:7238",
3805 # "tcp://10.128.30.17:7238",
3806 # "tcp://10.128.30.13:7238",
3807 # ],
3808 # "name": "p1",
3809 # "term": 3
3810 # },
Jon Hall63604932015-02-26 17:09:50 -08003811 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003812 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003813 if candidates:
3814 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003815 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003816 cmdStr += " -j"
3817 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003818 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003819 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003820 return output
Jon Hallc6793552016-01-19 14:18:37 -08003821 except AssertionError:
3822 main.log.exception( "" )
3823 return None
Jon Hall63604932015-02-26 17:09:50 -08003824 except TypeError:
3825 main.log.exception( self.name + ": Object not as expected" )
3826 return None
3827 except pexpect.EOF:
3828 main.log.error( self.name + ": EOF exception found" )
3829 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003830 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003831 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003832 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003833 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003834
Jon Halle9f909e2016-09-23 10:43:12 -07003835 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003836 """
3837 Returns the output of the apps command for ONOS. This command lists
3838 information about installed ONOS applications
3839 """
3840 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003841 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003842 # "description":"ONOS OpenFlow protocol southbound providers",
3843 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003844 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003845 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003846 cmdStr = "onos:apps"
Jon Hallf03ae762019-01-22 13:25:27 -08003847 expectJson = False
Jon Halle9f909e2016-09-23 10:43:12 -07003848 if summary:
3849 cmdStr += " -s"
3850 if active:
3851 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003852 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003853 cmdStr += " -j"
Jon Hallf03ae762019-01-22 13:25:27 -08003854 expectJson = True
3855 output = self.sendline( cmdStr, expectJson=expectJson )
Jon Halla495f562016-05-16 18:03:26 -07003856 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003857 assert "Command not found:" not in output, output
3858 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003859 return output
Jon Hallbe379602015-03-24 13:39:32 -07003860 # FIXME: look at specific exceptions/Errors
3861 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07003862 main.log.exception( self.name + ": Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003863 return None
3864 except TypeError:
3865 main.log.exception( self.name + ": Object not as expected" )
3866 return None
3867 except pexpect.EOF:
3868 main.log.error( self.name + ": EOF exception found" )
3869 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003870 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003871 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003872 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003873 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003874
You Wangcdc51fe2018-08-12 17:14:56 -07003875 def appStatus( self, appName ):
Jon Hall146f1522015-03-24 15:33:24 -07003876 """
3877 Uses the onos:apps cli command to return the status of an application.
3878 Returns:
3879 "ACTIVE" - If app is installed and activated
3880 "INSTALLED" - If app is installed and deactivated
3881 "UNINSTALLED" - If app is not installed
3882 None - on error
3883 """
Jon Hall146f1522015-03-24 15:33:24 -07003884 try:
3885 if not isinstance( appName, types.StringType ):
3886 main.log.error( self.name + ".appStatus(): appName must be" +
3887 " a string" )
3888 return None
3889 output = self.apps( jsonFormat=True )
3890 appsJson = json.loads( output )
3891 state = None
3892 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003893 if appName == app.get( 'name' ):
3894 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003895 break
3896 if state == "ACTIVE" or state == "INSTALLED":
3897 return state
3898 elif state is None:
You Wang0d9f2c02018-08-10 14:56:32 -07003899 main.log.warn( "{} app not found".format( appName ) )
Jon Hall146f1522015-03-24 15:33:24 -07003900 return "UNINSTALLED"
3901 elif state:
3902 main.log.error( "Unexpected state from 'onos:apps': " +
3903 str( state ) )
3904 return state
Jon Hallc6793552016-01-19 14:18:37 -08003905 except ( TypeError, ValueError ):
3906 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003907 return None
3908 except pexpect.EOF:
3909 main.log.error( self.name + ": EOF exception found" )
3910 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003911 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003912 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003913 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003914 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003915
Jon Hallbe379602015-03-24 13:39:32 -07003916 def app( self, appName, option ):
3917 """
3918 Interacts with the app command for ONOS. This command manages
3919 application inventory.
3920 """
Jon Hallbe379602015-03-24 13:39:32 -07003921 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003922 # Validate argument types
3923 valid = True
3924 if not isinstance( appName, types.StringType ):
3925 main.log.error( self.name + ".app(): appName must be a " +
3926 "string" )
3927 valid = False
3928 if not isinstance( option, types.StringType ):
3929 main.log.error( self.name + ".app(): option must be a string" )
3930 valid = False
3931 if not valid:
3932 return main.FALSE
3933 # Validate Option
3934 option = option.lower()
3935 # NOTE: Install may become a valid option
3936 if option == "activate":
3937 pass
3938 elif option == "deactivate":
3939 pass
3940 elif option == "uninstall":
3941 pass
3942 else:
3943 # Invalid option
3944 main.log.error( "The ONOS app command argument only takes " +
3945 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003946 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003947 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003948 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003949 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003950 assert output is not None, "Error in sendline"
3951 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003952 if "Error executing command" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003953 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hallbe379602015-03-24 13:39:32 -07003954 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003955 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003956 elif "No such application" in output:
3957 main.log.error( "The application '" + appName +
3958 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003959 return main.FALSE
3960 elif "Command not found:" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003961 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hall146f1522015-03-24 15:33:24 -07003962 str( output ) )
3963 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003964 elif "Unsupported command:" in output:
3965 main.log.error( "Incorrect command given to 'app': " +
3966 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003967 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003968 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003969 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003970 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003971 except AssertionError:
3972 main.log.exception( self.name + ": AssertionError exception found" )
3973 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003974 except TypeError:
3975 main.log.exception( self.name + ": Object not as expected" )
3976 return main.ERROR
3977 except pexpect.EOF:
3978 main.log.error( self.name + ": EOF exception found" )
3979 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003980 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003981 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003982 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003983 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003984
Jon Hallbd16b922015-03-26 17:53:15 -07003985 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003986 """
3987 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003988 appName is the hierarchical app name, not the feature name
3989 If check is True, method will check the status of the app after the
3990 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003991 Returns main.TRUE if the command was successfully sent
3992 main.FALSE if the cli responded with an error or given
3993 incorrect input
3994 """
3995 try:
3996 if not isinstance( appName, types.StringType ):
3997 main.log.error( self.name + ".activateApp(): appName must be" +
3998 " a string" )
3999 return main.FALSE
4000 status = self.appStatus( appName )
4001 if status == "INSTALLED":
4002 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07004003 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004004 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004005 status = self.appStatus( appName )
4006 if status == "ACTIVE":
4007 return main.TRUE
4008 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07004009 main.log.debug( "The state of application " +
4010 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07004011 time.sleep( 1 )
4012 return main.FALSE
4013 else: # not 'check' or command didn't succeed
4014 return response
Jon Hall146f1522015-03-24 15:33:24 -07004015 elif status == "ACTIVE":
4016 return main.TRUE
4017 elif status == "UNINSTALLED":
4018 main.log.error( self.name + ": Tried to activate the " +
4019 "application '" + appName + "' which is not " +
4020 "installed." )
4021 else:
4022 main.log.error( "Unexpected return value from appStatus: " +
4023 str( status ) )
4024 return main.ERROR
4025 except TypeError:
4026 main.log.exception( self.name + ": Object not as expected" )
4027 return main.ERROR
4028 except pexpect.EOF:
4029 main.log.error( self.name + ": EOF exception found" )
4030 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004031 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004032 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004033 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004034 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07004035
Jon Hallbd16b922015-03-26 17:53:15 -07004036 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07004037 """
4038 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07004039 appName is the hierarchical app name, not the feature name
4040 If check is True, method will check the status of the app after the
4041 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07004042 Returns main.TRUE if the command was successfully sent
4043 main.FALSE if the cli responded with an error or given
4044 incorrect input
4045 """
4046 try:
4047 if not isinstance( appName, types.StringType ):
4048 main.log.error( self.name + ".deactivateApp(): appName must " +
4049 "be a string" )
4050 return main.FALSE
4051 status = self.appStatus( appName )
4052 if status == "INSTALLED":
4053 return main.TRUE
4054 elif status == "ACTIVE":
4055 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07004056 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004057 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004058 status = self.appStatus( appName )
4059 if status == "INSTALLED":
4060 return main.TRUE
4061 else:
4062 time.sleep( 1 )
4063 return main.FALSE
4064 else: # not check or command didn't succeed
4065 return response
Jon Hall146f1522015-03-24 15:33:24 -07004066 elif status == "UNINSTALLED":
4067 main.log.warn( self.name + ": Tried to deactivate the " +
4068 "application '" + appName + "' which is not " +
4069 "installed." )
4070 return main.TRUE
4071 else:
4072 main.log.error( "Unexpected return value from appStatus: " +
4073 str( status ) )
4074 return main.ERROR
4075 except TypeError:
4076 main.log.exception( self.name + ": Object not as expected" )
4077 return main.ERROR
4078 except pexpect.EOF:
4079 main.log.error( self.name + ": EOF exception found" )
4080 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004081 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004082 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004083 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004084 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07004085
Jon Hallbd16b922015-03-26 17:53:15 -07004086 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07004087 """
4088 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07004089 appName is the hierarchical app name, not the feature name
4090 If check is True, method will check the status of the app after the
4091 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07004092 Returns main.TRUE if the command was successfully sent
4093 main.FALSE if the cli responded with an error or given
4094 incorrect input
4095 """
4096 # TODO: check with Thomas about the state machine for apps
4097 try:
4098 if not isinstance( appName, types.StringType ):
4099 main.log.error( self.name + ".uninstallApp(): appName must " +
4100 "be a string" )
4101 return main.FALSE
4102 status = self.appStatus( appName )
4103 if status == "INSTALLED":
4104 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004105 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004106 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004107 status = self.appStatus( appName )
4108 if status == "UNINSTALLED":
4109 return main.TRUE
4110 else:
4111 time.sleep( 1 )
4112 return main.FALSE
4113 else: # not check or command didn't succeed
4114 return response
Jon Hall146f1522015-03-24 15:33:24 -07004115 elif status == "ACTIVE":
4116 main.log.warn( self.name + ": Tried to uninstall the " +
4117 "application '" + appName + "' which is " +
4118 "currently active." )
4119 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004120 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004121 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004122 status = self.appStatus( appName )
4123 if status == "UNINSTALLED":
4124 return main.TRUE
4125 else:
4126 time.sleep( 1 )
4127 return main.FALSE
4128 else: # not check or command didn't succeed
4129 return response
Jon Hall146f1522015-03-24 15:33:24 -07004130 elif status == "UNINSTALLED":
4131 return main.TRUE
4132 else:
4133 main.log.error( "Unexpected return value from appStatus: " +
4134 str( status ) )
4135 return main.ERROR
4136 except TypeError:
4137 main.log.exception( self.name + ": Object not as expected" )
4138 return main.ERROR
4139 except pexpect.EOF:
4140 main.log.error( self.name + ": EOF exception found" )
4141 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004142 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004143 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004144 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004145 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004146
4147 def appIDs( self, jsonFormat=True ):
4148 """
4149 Show the mappings between app id and app names given by the 'app-ids'
4150 cli command
4151 """
4152 try:
4153 cmdStr = "app-ids"
4154 if jsonFormat:
4155 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07004156 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004157 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004158 assert "Command not found:" not in output, output
4159 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07004160 return output
Jon Hallbd16b922015-03-26 17:53:15 -07004161 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004162 main.log.exception( self.name + ": Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07004163 return None
4164 except TypeError:
4165 main.log.exception( self.name + ": Object not as expected" )
4166 return None
4167 except pexpect.EOF:
4168 main.log.error( self.name + ": EOF exception found" )
4169 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004170 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004171 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004172 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004173 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004174
4175 def appToIDCheck( self ):
4176 """
4177 This method will check that each application's ID listed in 'apps' is
4178 the same as the ID listed in 'app-ids'. The check will also check that
4179 there are no duplicate IDs issued. Note that an app ID should be
4180 a globaly unique numerical identifier for app/app-like features. Once
4181 an ID is registered, the ID is never freed up so that if an app is
4182 reinstalled it will have the same ID.
4183
4184 Returns: main.TRUE if the check passes and
4185 main.FALSE if the check fails or
4186 main.ERROR if there is some error in processing the test
4187 """
4188 try:
Jon Hall0e240372018-05-02 11:21:57 -07004189 # Grab IDs
Jon Hallc6793552016-01-19 14:18:37 -08004190 rawJson = self.appIDs( jsonFormat=True )
4191 if rawJson:
4192 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004193 else:
Jon Hall0e240372018-05-02 11:21:57 -07004194 main.log.error( "app-ids returned nothing: " + repr( rawJson ) )
4195 return main.FALSE
4196
4197 # Grab Apps
Jon Hallc6793552016-01-19 14:18:37 -08004198 rawJson = self.apps( jsonFormat=True )
4199 if rawJson:
4200 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004201 else:
Jon Hallc6793552016-01-19 14:18:37 -08004202 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004203 return main.FALSE
Jon Hall0e240372018-05-02 11:21:57 -07004204
Jon Hallbd16b922015-03-26 17:53:15 -07004205 result = main.TRUE
4206 for app in apps:
4207 appID = app.get( 'id' )
4208 if appID is None:
4209 main.log.error( "Error parsing app: " + str( app ) )
4210 result = main.FALSE
4211 appName = app.get( 'name' )
4212 if appName is None:
4213 main.log.error( "Error parsing app: " + str( app ) )
4214 result = main.FALSE
4215 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004216 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004217 if not current: # if ids doesn't have this id
4218 result = main.FALSE
4219 main.log.error( "'app-ids' does not have the ID for " +
4220 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004221 main.log.debug( "apps command returned: " + str( app ) +
4222 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004223 elif len( current ) > 1:
4224 # there is more than one app with this ID
4225 result = main.FALSE
4226 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004227 elif not current[ 0 ][ 'name' ] == appName:
4228 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004229 result = main.FALSE
4230 main.log.error( "'app-ids' has " + str( currentName ) +
4231 " registered under id:" + str( appID ) +
4232 " but 'apps' has " + str( appName ) )
4233 else:
4234 pass # id and name match!
Jon Hall0e240372018-05-02 11:21:57 -07004235
Jon Hallbd16b922015-03-26 17:53:15 -07004236 # now make sure that app-ids has no duplicates
4237 idsList = []
4238 namesList = []
4239 for item in ids:
4240 idsList.append( item[ 'id' ] )
4241 namesList.append( item[ 'name' ] )
4242 if len( idsList ) != len( set( idsList ) ) or\
4243 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004244 main.log.error( "'app-ids' has some duplicate entries: \n"
4245 + json.dumps( ids,
4246 sort_keys=True,
4247 indent=4,
4248 separators=( ',', ': ' ) ) )
4249 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004250 return result
Jon Hallc6793552016-01-19 14:18:37 -08004251 except ( TypeError, ValueError ):
4252 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004253 return main.ERROR
4254 except pexpect.EOF:
4255 main.log.error( self.name + ": EOF exception found" )
4256 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004257 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004258 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004259 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004260 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004261
Jon Hallfb760a02015-04-13 15:35:03 -07004262 def getCfg( self, component=None, propName=None, short=False,
4263 jsonFormat=True ):
4264 """
4265 Get configuration settings from onos cli
4266 Optional arguments:
4267 component - Optionally only list configurations for a specific
4268 component. If None, all components with configurations
4269 are displayed. Case Sensitive string.
4270 propName - If component is specified, propName option will show
4271 only this specific configuration from that component.
4272 Case Sensitive string.
4273 jsonFormat - Returns output as json. Note that this will override
4274 the short option
4275 short - Short, less verbose, version of configurations.
4276 This is overridden by the json option
4277 returns:
4278 Output from cli as a string or None on error
4279 """
4280 try:
4281 baseStr = "cfg"
4282 cmdStr = " get"
4283 componentStr = ""
4284 if component:
4285 componentStr += " " + component
4286 if propName:
4287 componentStr += " " + propName
4288 if jsonFormat:
4289 baseStr += " -j"
Jon Hall22e94ce2019-01-15 14:52:17 -08004290 expectJson = True
Jon Hallfb760a02015-04-13 15:35:03 -07004291 elif short:
4292 baseStr += " -s"
Jon Hall22e94ce2019-01-15 14:52:17 -08004293 expectJson = False
4294 output = self.sendline( baseStr + cmdStr + componentStr, expectJson=expectJson )
Jon Halla495f562016-05-16 18:03:26 -07004295 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004296 assert "Command not found:" not in output, output
4297 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004298 return output
4299 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004300 main.log.exception( self.name + ": Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004301 return None
4302 except TypeError:
4303 main.log.exception( self.name + ": Object not as expected" )
4304 return None
4305 except pexpect.EOF:
4306 main.log.error( self.name + ": EOF exception found" )
4307 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004308 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004309 except Exception:
4310 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004311 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004312
4313 def setCfg( self, component, propName, value=None, check=True ):
4314 """
4315 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004316 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004317 component - The case sensitive name of the component whose
4318 property is to be set
4319 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004320 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004321 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004322 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004323 check - Boolean, Check whether the option was successfully set this
4324 only applies when a value is given.
4325 returns:
4326 main.TRUE on success or main.FALSE on failure. If check is False,
4327 will return main.TRUE unless there is an error
4328 """
4329 try:
4330 baseStr = "cfg"
4331 cmdStr = " set " + str( component ) + " " + str( propName )
4332 if value is not None:
4333 cmdStr += " " + str( value )
4334 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004335 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004336 assert "Command not found:" not in output, output
4337 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004338 if value and check:
4339 results = self.getCfg( component=str( component ),
4340 propName=str( propName ),
4341 jsonFormat=True )
4342 # Check if current value is what we just set
4343 try:
4344 jsonOutput = json.loads( results )
4345 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004346 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004347 main.log.exception( "Error parsing cfg output" )
4348 main.log.error( "output:" + repr( results ) )
4349 return main.FALSE
4350 if current == str( value ):
4351 return main.TRUE
4352 return main.FALSE
4353 return main.TRUE
4354 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004355 main.log.exception( self.name + ": Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004356 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004357 except ( TypeError, ValueError ):
4358 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004359 return main.FALSE
4360 except pexpect.EOF:
4361 main.log.error( self.name + ": EOF exception found" )
4362 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004363 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004364 except Exception:
4365 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004366 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004367
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004368 def distPrimitivesSend( self, cmd ):
4369 """
4370 Function to handle sending cli commands for the distributed primitives test app
4371
4372 This command will catch some exceptions and retry the command on some
4373 specific store exceptions.
4374
4375 Required arguments:
4376 cmd - The command to send to the cli
4377 returns:
4378 string containing the cli output
4379 None on Error
4380 """
4381 try:
4382 output = self.sendline( cmd )
4383 try:
4384 assert output is not None, "Error in sendline"
4385 # TODO: Maybe make this less hardcoded
4386 # ConsistentMap Exceptions
4387 assert "org.onosproject.store.service" not in output
4388 # Node not leader
4389 assert "java.lang.IllegalStateException" not in output
4390 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004391 main.log.error( self.name + ": Error in processing '" + cmd + "' " +
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004392 "command: " + str( output ) )
4393 retryTime = 30 # Conservative time, given by Madan
4394 main.log.info( "Waiting " + str( retryTime ) +
4395 "seconds before retrying." )
4396 time.sleep( retryTime ) # Due to change in mastership
4397 output = self.sendline( cmd )
4398 assert output is not None, "Error in sendline"
4399 assert "Command not found:" not in output, output
4400 assert "Error executing command" not in output, output
4401 main.log.info( self.name + ": " + output )
4402 return output
4403 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004404 main.log.exception( self.name + ": Error in processing '" + cmd + "' command." )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004405 return None
4406 except TypeError:
4407 main.log.exception( self.name + ": Object not as expected" )
4408 return None
4409 except pexpect.EOF:
4410 main.log.error( self.name + ": EOF exception found" )
4411 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004412 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004413 except Exception:
4414 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004415 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004416
Jon Hall390696c2015-05-05 17:13:41 -07004417 def setTestAdd( self, setName, values ):
4418 """
4419 CLI command to add elements to a distributed set.
4420 Arguments:
4421 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004422 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004423 Example usages:
4424 setTestAdd( "set1", "a b c" )
4425 setTestAdd( "set2", "1" )
4426 returns:
4427 main.TRUE on success OR
4428 main.FALSE if elements were already in the set OR
4429 main.ERROR on error
4430 """
4431 try:
4432 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004433 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004434 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4435 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004436 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004437 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004438 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004439 return main.FALSE
4440 else:
4441 main.log.error( self.name + ": setTestAdd did not" +
4442 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004443 main.log.debug( self.name + " actual: " + repr( output ) )
4444 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004445 except TypeError:
4446 main.log.exception( self.name + ": Object not as expected" )
4447 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004448 except Exception:
4449 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004450 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004451
4452 def setTestRemove( self, setName, values, clear=False, retain=False ):
4453 """
4454 CLI command to remove elements from a distributed set.
4455 Required arguments:
4456 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004457 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004458 Optional arguments:
4459 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004460 retain - Retain only the given values. (intersection of the
4461 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004462 returns:
4463 main.TRUE on success OR
4464 main.FALSE if the set was not changed OR
4465 main.ERROR on error
4466 """
4467 try:
4468 cmdStr = "set-test-remove "
4469 if clear:
4470 cmdStr += "-c " + str( setName )
4471 elif retain:
4472 cmdStr += "-r " + str( setName ) + " " + str( values )
4473 else:
4474 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004475 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004476 if clear:
4477 pattern = "Set " + str( setName ) + " cleared"
4478 if re.search( pattern, output ):
4479 return main.TRUE
4480 elif retain:
4481 positivePattern = str( setName ) + " was pruned to contain " +\
4482 "only elements of set \[(.*)\]"
4483 negativePattern = str( setName ) + " was not changed by " +\
4484 "retaining only elements of the set " +\
4485 "\[(.*)\]"
4486 if re.search( positivePattern, output ):
4487 return main.TRUE
4488 elif re.search( negativePattern, output ):
4489 return main.FALSE
4490 else:
4491 positivePattern = "\[(.*)\] was removed from the set " +\
4492 str( setName )
4493 if ( len( values.split() ) == 1 ):
4494 negativePattern = "\[(.*)\] was not in set " +\
4495 str( setName )
4496 else:
4497 negativePattern = "No element of \[(.*)\] was in set " +\
4498 str( setName )
4499 if re.search( positivePattern, output ):
4500 return main.TRUE
4501 elif re.search( negativePattern, output ):
4502 return main.FALSE
4503 main.log.error( self.name + ": setTestRemove did not" +
4504 " match expected output" )
4505 main.log.debug( self.name + " expected: " + pattern )
4506 main.log.debug( self.name + " actual: " + repr( output ) )
4507 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004508 except TypeError:
4509 main.log.exception( self.name + ": Object not as expected" )
4510 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004511 except Exception:
4512 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004513 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004514
4515 def setTestGet( self, setName, values="" ):
4516 """
4517 CLI command to get the elements in a distributed set.
4518 Required arguments:
4519 setName - The name of the set to remove from.
4520 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004521 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004522 returns:
4523 main.ERROR on error OR
4524 A list of elements in the set if no optional arguments are
4525 supplied OR
4526 A tuple containing the list then:
4527 main.FALSE if the given values are not in the set OR
4528 main.TRUE if the given values are in the set OR
4529 """
4530 try:
4531 values = str( values ).strip()
4532 setName = str( setName ).strip()
4533 length = len( values.split() )
4534 containsCheck = None
4535 # Patterns to match
4536 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004537 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004538 containsTrue = "Set " + setName + " contains the value " + values
4539 containsFalse = "Set " + setName + " did not contain the value " +\
4540 values
4541 containsAllTrue = "Set " + setName + " contains the the subset " +\
4542 setPattern
4543 containsAllFalse = "Set " + setName + " did not contain the the" +\
4544 " subset " + setPattern
4545
4546 cmdStr = "set-test-get "
4547 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004548 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004549 if length == 0:
4550 match = re.search( pattern, output )
4551 else: # if given values
4552 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004553 patternTrue = pattern + "\r\n" + containsTrue
4554 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004555 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004556 patternTrue = pattern + "\r\n" + containsAllTrue
4557 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004558 matchTrue = re.search( patternTrue, output )
4559 matchFalse = re.search( patternFalse, output )
4560 if matchTrue:
4561 containsCheck = main.TRUE
4562 match = matchTrue
4563 elif matchFalse:
4564 containsCheck = main.FALSE
4565 match = matchFalse
4566 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004567 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004568 "expected output" )
4569 main.log.debug( self.name + " expected: " + pattern )
4570 main.log.debug( self.name + " actual: " + repr( output ) )
4571 match = None
4572 if match:
4573 setMatch = match.group( 1 )
4574 if setMatch == '':
4575 setList = []
4576 else:
4577 setList = setMatch.split( ", " )
4578 if length > 0:
4579 return ( setList, containsCheck )
4580 else:
4581 return setList
4582 else: # no match
4583 main.log.error( self.name + ": setTestGet did not" +
4584 " match expected output" )
4585 main.log.debug( self.name + " expected: " + pattern )
4586 main.log.debug( self.name + " actual: " + repr( output ) )
4587 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004588 except TypeError:
4589 main.log.exception( self.name + ": Object not as expected" )
4590 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004591 except Exception:
4592 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004593 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004594
4595 def setTestSize( self, setName ):
4596 """
4597 CLI command to get the elements in a distributed set.
4598 Required arguments:
4599 setName - The name of the set to remove from.
4600 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004601 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004602 None on error
4603 """
4604 try:
4605 # TODO: Should this check against the number of elements returned
4606 # and then return true/false based on that?
4607 setName = str( setName ).strip()
4608 # Patterns to match
4609 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004610 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004611 setPattern
4612 cmdStr = "set-test-get -s "
4613 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004614 output = self.distPrimitivesSend( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -07004615 if output:
4616 match = re.search( pattern, output )
4617 if match:
4618 setSize = int( match.group( 1 ) )
4619 setMatch = match.group( 2 )
4620 if len( setMatch.split() ) == setSize:
4621 main.log.info( "The size returned by " + self.name +
4622 " matches the number of elements in " +
4623 "the returned set" )
4624 else:
4625 main.log.error( "The size returned by " + self.name +
4626 " does not match the number of " +
4627 "elements in the returned set." )
4628 return setSize
Jon Hall390696c2015-05-05 17:13:41 -07004629 else: # no match
4630 main.log.error( self.name + ": setTestGet did not" +
4631 " match expected output" )
4632 main.log.debug( self.name + " expected: " + pattern )
4633 main.log.debug( self.name + " actual: " + repr( output ) )
4634 return None
Jon Hall390696c2015-05-05 17:13:41 -07004635 except TypeError:
4636 main.log.exception( self.name + ": Object not as expected" )
4637 return None
Jon Hall390696c2015-05-05 17:13:41 -07004638 except Exception:
4639 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004640 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004641
Jon Hall80daded2015-05-27 16:07:00 -07004642 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004643 """
4644 Command to list the various counters in the system.
4645 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004646 if jsonFormat, a string of the json object returned by the cli
4647 command
4648 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004649 None on error
4650 """
Jon Hall390696c2015-05-05 17:13:41 -07004651 try:
Jon Hall390696c2015-05-05 17:13:41 -07004652 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004653 if jsonFormat:
4654 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004655 output = self.sendline( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08004656 main.log.debug( self.name + ": Counters unparsed: " + output )
4657 output = output.split( "\r\n" )[ -1 ]
4658 main.log.debug( self.name + ": Counters parsed: " + output )
Jon Halla495f562016-05-16 18:03:26 -07004659 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004660 assert "Command not found:" not in output, output
4661 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004662 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004663 return output
Jon Hall390696c2015-05-05 17:13:41 -07004664 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004665 main.log.exception( self.name + ": Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004666 return None
Jon Hall390696c2015-05-05 17:13:41 -07004667 except TypeError:
4668 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004669 return None
Jon Hall390696c2015-05-05 17:13:41 -07004670 except pexpect.EOF:
4671 main.log.error( self.name + ": EOF exception found" )
4672 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004673 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004674 except Exception:
4675 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004676 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004677
Jon Hall935db192016-04-19 00:22:04 -07004678 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004679 """
Jon Halle1a3b752015-07-22 13:02:46 -07004680 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004681 Required arguments:
4682 counter - The name of the counter to increment.
4683 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004684 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004685 returns:
4686 integer value of the counter or
4687 None on Error
4688 """
4689 try:
4690 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004691 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004692 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004693 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004694 if delta != 1:
4695 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004696 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004697 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004698 match = re.search( pattern, output )
4699 if match:
4700 return int( match.group( 1 ) )
4701 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004702 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004703 " match expected output." )
4704 main.log.debug( self.name + " expected: " + pattern )
4705 main.log.debug( self.name + " actual: " + repr( output ) )
4706 return None
Jon Hall390696c2015-05-05 17:13:41 -07004707 except TypeError:
4708 main.log.exception( self.name + ": Object not as expected" )
4709 return None
Jon Hall390696c2015-05-05 17:13:41 -07004710 except Exception:
4711 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004712 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004713
Jon Hall935db192016-04-19 00:22:04 -07004714 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004715 """
4716 CLI command to get a distributed counter then add a delta to it.
4717 Required arguments:
4718 counter - The name of the counter to increment.
4719 Optional arguments:
4720 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004721 returns:
4722 integer value of the counter or
4723 None on Error
4724 """
4725 try:
4726 counter = str( counter )
4727 delta = int( delta )
4728 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004729 cmdStr += counter
4730 if delta != 1:
4731 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004732 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004733 pattern = counter + " was updated to (-?\d+)"
4734 match = re.search( pattern, output )
4735 if match:
4736 return int( match.group( 1 ) )
4737 else:
4738 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4739 " match expected output." )
4740 main.log.debug( self.name + " expected: " + pattern )
4741 main.log.debug( self.name + " actual: " + repr( output ) )
4742 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004743 except TypeError:
4744 main.log.exception( self.name + ": Object not as expected" )
4745 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004746 except Exception:
4747 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004748 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004749
4750 def valueTestGet( self, valueName ):
4751 """
4752 CLI command to get the value of an atomic value.
4753 Required arguments:
4754 valueName - The name of the value to get.
4755 returns:
4756 string value of the value or
4757 None on Error
4758 """
4759 try:
4760 valueName = str( valueName )
4761 cmdStr = "value-test "
4762 operation = "get"
4763 cmdStr = "value-test {} {}".format( valueName,
4764 operation )
4765 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08004766 main.log.debug( self.name + ": value test unparsed: " + output )
4767 output = output.split( "\r\n" )[ -1 ]
4768 main.log.debug( self.name + ": value test parsed: " + output )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004769 pattern = "(\w+)"
4770 match = re.search( pattern, output )
4771 if match:
4772 return match.group( 1 )
4773 else:
4774 main.log.error( self.name + ": valueTestGet did not" +
4775 " match expected output." )
4776 main.log.debug( self.name + " expected: " + pattern )
4777 main.log.debug( self.name + " actual: " + repr( output ) )
4778 return None
4779 except TypeError:
4780 main.log.exception( self.name + ": Object not as expected" )
4781 return None
4782 except Exception:
4783 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004784 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004785
4786 def valueTestSet( self, valueName, newValue ):
4787 """
4788 CLI command to set the value of an atomic value.
4789 Required arguments:
4790 valueName - The name of the value to set.
4791 newValue - The value to assign to the given value.
4792 returns:
4793 main.TRUE on success or
4794 main.ERROR on Error
4795 """
4796 try:
4797 valueName = str( valueName )
4798 newValue = str( newValue )
4799 operation = "set"
4800 cmdStr = "value-test {} {} {}".format( valueName,
4801 operation,
4802 newValue )
4803 output = self.distPrimitivesSend( cmdStr )
4804 if output is not None:
4805 return main.TRUE
4806 else:
4807 return main.ERROR
4808 except TypeError:
4809 main.log.exception( self.name + ": Object not as expected" )
4810 return main.ERROR
4811 except Exception:
4812 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004813 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004814
4815 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4816 """
4817 CLI command to compareAndSet the value of an atomic value.
4818 Required arguments:
4819 valueName - The name of the value.
4820 oldValue - Compare the current value of the atomic value to this
4821 newValue - If the value equals oldValue, set the value to newValue
4822 returns:
4823 main.TRUE on success or
4824 main.FALSE on failure or
4825 main.ERROR on Error
4826 """
4827 try:
4828 valueName = str( valueName )
4829 oldValue = str( oldValue )
4830 newValue = str( newValue )
4831 operation = "compareAndSet"
4832 cmdStr = "value-test {} {} {} {}".format( valueName,
4833 operation,
4834 oldValue,
4835 newValue )
4836 output = self.distPrimitivesSend( cmdStr )
4837 pattern = "(\w+)"
4838 match = re.search( pattern, output )
4839 if match:
4840 result = match.group( 1 )
4841 if result == "true":
4842 return main.TRUE
4843 elif result == "false":
4844 return main.FALSE
4845 else:
4846 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4847 " match expected output." )
4848 main.log.debug( self.name + " expected: " + pattern )
4849 main.log.debug( self.name + " actual: " + repr( output ) )
4850 return main.ERROR
4851 except TypeError:
4852 main.log.exception( self.name + ": Object not as expected" )
4853 return main.ERROR
4854 except Exception:
4855 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004856 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004857
4858 def valueTestGetAndSet( self, valueName, newValue ):
4859 """
4860 CLI command to getAndSet the value of an atomic value.
4861 Required arguments:
4862 valueName - The name of the value to get.
4863 newValue - The value to assign to the given value
4864 returns:
4865 string value of the value or
4866 None on Error
4867 """
4868 try:
4869 valueName = str( valueName )
4870 cmdStr = "value-test "
4871 operation = "getAndSet"
4872 cmdStr += valueName + " " + operation
4873 cmdStr = "value-test {} {} {}".format( valueName,
4874 operation,
4875 newValue )
4876 output = self.distPrimitivesSend( cmdStr )
4877 pattern = "(\w+)"
4878 match = re.search( pattern, output )
4879 if match:
4880 return match.group( 1 )
4881 else:
4882 main.log.error( self.name + ": valueTestGetAndSet did not" +
4883 " match expected output." )
4884 main.log.debug( self.name + " expected: " + pattern )
4885 main.log.debug( self.name + " actual: " + repr( output ) )
4886 return None
4887 except TypeError:
4888 main.log.exception( self.name + ": Object not as expected" )
4889 return None
4890 except Exception:
4891 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004892 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004893
4894 def valueTestDestroy( self, valueName ):
4895 """
4896 CLI command to destroy an atomic value.
4897 Required arguments:
4898 valueName - The name of the value to destroy.
4899 returns:
4900 main.TRUE on success or
4901 main.ERROR on Error
4902 """
4903 try:
4904 valueName = str( valueName )
4905 cmdStr = "value-test "
4906 operation = "destroy"
4907 cmdStr += valueName + " " + operation
4908 output = self.distPrimitivesSend( cmdStr )
4909 if output is not None:
4910 return main.TRUE
4911 else:
4912 return main.ERROR
4913 except TypeError:
4914 main.log.exception( self.name + ": Object not as expected" )
4915 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004916 except Exception:
4917 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004918 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004919
YPZhangfebf7302016-05-24 16:45:56 -07004920 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004921 """
4922 Description: Execute summary command in onos
4923 Returns: json object ( summary -j ), returns main.FALSE if there is
4924 no output
4925
4926 """
4927 try:
4928 cmdStr = "summary"
4929 if jsonFormat:
4930 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004931 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004932 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004933 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004934 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004935 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004936 if not handle:
4937 main.log.error( self.name + ": There is no output in " +
4938 "summary command" )
4939 return main.FALSE
4940 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004941 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004942 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004943 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004944 except TypeError:
4945 main.log.exception( self.name + ": Object not as expected" )
4946 return None
4947 except pexpect.EOF:
4948 main.log.error( self.name + ": EOF exception found" )
4949 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004950 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004951 except Exception:
4952 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004953 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004954
Jon Hall06fd0df2021-01-25 15:50:06 -08004955 def getAddress( self):
4956 """
4957 Get the onos ip address from the cli. This is usefull when connecting using
4958 a container manager such as kubernetes. This function also sets self.address
4959 the value from ONOS.
4960
4961 Returns:
4962 The string value of the key or
4963 None on Error
4964 """
4965 try:
4966 output = self.summary()
4967 address = json.loads( output ).get( 'node' )
4968 self.address = address
4969 return address
You Wang327bad42021-03-24 14:19:58 -07004970 except ( TypeError, ValueError ):
Jon Hall06fd0df2021-01-25 15:50:06 -08004971 main.log.exception( self.name + ": Object not as expected" )
4972 return None
4973 except Exception:
4974 main.log.exception( self.name + ": Uncaught exception!" )
4975 main.cleanAndExit()
4976
Jon Hall935db192016-04-19 00:22:04 -07004977 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004978 """
4979 CLI command to get the value of a key in a consistent map using
4980 transactions. This a test function and can only get keys from the
4981 test map hard coded into the cli command
4982 Required arguments:
4983 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004984 returns:
4985 The string value of the key or
4986 None on Error
4987 """
4988 try:
4989 keyName = str( keyName )
4990 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004991 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004992 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004993 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4994 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004995 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004996 return None
4997 else:
4998 match = re.search( pattern, output )
4999 if match:
5000 return match.groupdict()[ 'value' ]
5001 else:
5002 main.log.error( self.name + ": transactionlMapGet did not" +
5003 " match expected output." )
5004 main.log.debug( self.name + " expected: " + pattern )
5005 main.log.debug( self.name + " actual: " + repr( output ) )
5006 return None
5007 except TypeError:
5008 main.log.exception( self.name + ": Object not as expected" )
5009 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07005010 except Exception:
5011 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005012 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07005013
Jon Hall935db192016-04-19 00:22:04 -07005014 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07005015 """
5016 CLI command to put a value into 'numKeys' number of keys in a
5017 consistent map using transactions. This a test function and can only
5018 put into keys named 'Key#' of the test map hard coded into the cli command
5019 Required arguments:
5020 numKeys - Number of keys to add the value to
5021 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07005022 returns:
5023 A dictionary whose keys are the name of the keys put into the map
5024 and the values of the keys are dictionaries whose key-values are
5025 'value': value put into map and optionaly
5026 'oldValue': Previous value in the key or
5027 None on Error
5028
5029 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005030 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
5031 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07005032 """
5033 try:
5034 numKeys = str( numKeys )
5035 value = str( value )
5036 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07005037 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07005038 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07005039 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
5040 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
5041 results = {}
5042 for line in output.splitlines():
5043 new = re.search( newPattern, line )
5044 updated = re.search( updatedPattern, line )
5045 if new:
5046 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
5047 elif updated:
5048 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08005049 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07005050 else:
5051 main.log.error( self.name + ": transactionlMapGet did not" +
5052 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08005053 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
5054 newPattern,
5055 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07005056 main.log.debug( self.name + " actual: " + repr( output ) )
5057 return results
Jon Hall0e240372018-05-02 11:21:57 -07005058 except ( TypeError, AttributeError ):
Jon Hall2a5002c2015-08-21 16:49:11 -07005059 main.log.exception( self.name + ": Object not as expected" )
5060 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07005061 except Exception:
5062 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005063 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08005064
acsmarsdaea66c2015-09-03 11:44:06 -07005065 def maps( self, jsonFormat=True ):
5066 """
5067 Description: Returns result of onos:maps
5068 Optional:
5069 * jsonFormat: enable json formatting of output
5070 """
5071 try:
5072 cmdStr = "maps"
5073 if jsonFormat:
5074 cmdStr += " -j"
5075 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07005076 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005077 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07005078 return handle
Jon Hallc6793552016-01-19 14:18:37 -08005079 except AssertionError:
5080 main.log.exception( "" )
5081 return None
acsmarsdaea66c2015-09-03 11:44:06 -07005082 except TypeError:
5083 main.log.exception( self.name + ": Object not as expected" )
5084 return None
5085 except pexpect.EOF:
5086 main.log.error( self.name + ": EOF exception found" )
5087 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005088 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07005089 except Exception:
5090 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005091 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005092
5093 def getSwController( self, uri, jsonFormat=True ):
5094 """
5095 Descrition: Gets the controller information from the device
5096 """
5097 try:
5098 cmd = "device-controllers "
5099 if jsonFormat:
5100 cmd += "-j "
5101 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07005102 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005103 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005104 return response
Jon Hallc6793552016-01-19 14:18:37 -08005105 except AssertionError:
5106 main.log.exception( "" )
5107 return None
GlennRC050596c2015-11-18 17:06:41 -08005108 except TypeError:
5109 main.log.exception( self.name + ": Object not as expected" )
5110 return None
5111 except pexpect.EOF:
5112 main.log.error( self.name + ": EOF exception found" )
5113 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005114 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005115 except Exception:
5116 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005117 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005118
5119 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
5120 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005121 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08005122
5123 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005124 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08005125 ip - String or List: The ip address of the controller.
5126 This parameter can be formed in a couple of different ways.
5127 VALID:
5128 10.0.0.1 - just the ip address
5129 tcp:10.0.0.1 - the protocol and the ip address
5130 tcp:10.0.0.1:6653 - the protocol and port can be specified,
5131 so that you can add controllers with different
5132 protocols and ports
5133 INVALID:
5134 10.0.0.1:6653 - this is not supported by ONOS
5135
5136 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
5137 port - The port number.
5138 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
5139
5140 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
5141 """
5142 try:
5143 cmd = "device-setcontrollers"
5144
5145 if jsonFormat:
5146 cmd += " -j"
5147 cmd += " " + uri
5148 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005149 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08005150 for item in ip:
5151 if ":" in item:
5152 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005153 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08005154 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005155 elif "." in sitem[ 1 ]:
5156 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08005157 else:
5158 main.log.error( "Malformed entry: " + item )
5159 raise TypeError
5160 else:
5161 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08005162 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07005163 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005164 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005165 if "Error" in response:
5166 main.log.error( response )
5167 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005168 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005169 except AssertionError:
5170 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005171 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005172 except TypeError:
5173 main.log.exception( self.name + ": Object not as expected" )
5174 return main.FALSE
5175 except pexpect.EOF:
5176 main.log.error( self.name + ": EOF exception found" )
5177 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005178 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005179 except Exception:
5180 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005181 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005182
5183 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005184 '''
GlennRC20fc6522015-12-23 23:26:57 -08005185 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005186 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08005187 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005188 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08005189 Returns:
5190 Returns main.FALSE if an exception is thrown or an error is present
5191 in the response. Otherwise, returns main.TRUE.
5192 NOTE:
5193 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005194 '''
GlennRC20fc6522015-12-23 23:26:57 -08005195 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005196 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07005197 deviceStr = device
5198 device = []
5199 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08005200
5201 for d in device:
5202 time.sleep( 1 )
5203 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07005204 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005205 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005206 if "Error" in response:
5207 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
5208 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005209 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005210 except AssertionError:
5211 main.log.exception( "" )
5212 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005213 except TypeError:
5214 main.log.exception( self.name + ": Object not as expected" )
5215 return main.FALSE
5216 except pexpect.EOF:
5217 main.log.error( self.name + ": EOF exception found" )
5218 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005219 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005220 except Exception:
5221 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005222 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005223
5224 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005225 '''
GlennRC20fc6522015-12-23 23:26:57 -08005226 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005227 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005228 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005229 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005230 Returns:
5231 Returns main.FALSE if an exception is thrown or an error is present
5232 in the response. Otherwise, returns main.TRUE.
5233 NOTE:
5234 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005235 '''
GlennRC20fc6522015-12-23 23:26:57 -08005236 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005237 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005238 host = list( host )
5239
5240 for h in host:
5241 time.sleep( 1 )
5242 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005243 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005244 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005245 if "Error" in response:
5246 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5247 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005248 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005249 except AssertionError:
5250 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005251 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005252 except TypeError:
5253 main.log.exception( self.name + ": Object not as expected" )
5254 return main.FALSE
5255 except pexpect.EOF:
5256 main.log.error( self.name + ": EOF exception found" )
5257 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005258 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005259 except Exception:
5260 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005261 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005262
YPZhangfebf7302016-05-24 16:45:56 -07005263 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005264 '''
GlennRCed771242016-01-13 17:02:47 -08005265 Description:
5266 Bring link down or up in the null-provider.
5267 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005268 begin - (string) One end of a device or switch.
5269 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005270 returns:
5271 main.TRUE if no exceptions were thrown and no Errors are
5272 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005273 '''
GlennRCed771242016-01-13 17:02:47 -08005274 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005275 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005276 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005277 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005278 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005279 if "Error" in response or "Failure" in response:
5280 main.log.error( response )
5281 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005282 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005283 except AssertionError:
5284 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005285 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005286 except TypeError:
5287 main.log.exception( self.name + ": Object not as expected" )
5288 return main.FALSE
5289 except pexpect.EOF:
5290 main.log.error( self.name + ": EOF exception found" )
5291 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005292 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005293 except Exception:
5294 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005295 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005296
Jon Hall2c8959e2016-12-16 12:17:34 -08005297 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005298 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005299 Description:
5300 Changes the state of port in an OF switch by means of the
5301 PORTSTATUS OF messages.
5302 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005303 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5304 port - (string) target port in the device. Ex: '2'
5305 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005306 returns:
5307 main.TRUE if no exceptions were thrown and no Errors are
5308 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005309 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005310 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005311 state = state.lower()
5312 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005313 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005314 response = self.sendline( cmd, showResponse=True )
5315 assert response is not None, "Error in sendline"
5316 assert "Command not found:" not in response, response
5317 if "Error" in response or "Failure" in response:
5318 main.log.error( response )
5319 return main.FALSE
5320 return main.TRUE
5321 except AssertionError:
5322 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005323 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005324 except TypeError:
5325 main.log.exception( self.name + ": Object not as expected" )
5326 return main.FALSE
5327 except pexpect.EOF:
5328 main.log.error( self.name + ": EOF exception found" )
5329 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005330 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005331 except Exception:
5332 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005333 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005334
5335 def logSet( self, level="INFO", app="org.onosproject" ):
5336 """
5337 Set the logging level to lvl for a specific app
5338 returns main.TRUE on success
5339 returns main.FALSE if Error occurred
5340 if noExit is True, TestON will not exit, but clean up
5341 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5342 Level defaults to INFO
5343 """
5344 try:
You Wang22e807e2021-03-29 10:53:38 -07005345 handle = self.sendline( "log:set %s %s" % ( level, app ) )
5346 assert handle is not None, "Error in sendline"
5347 assert "Command not found:" not in handle, handle
5348 if re.search( "Error", handle ):
5349 main.log.error( self.name + ": Error in setting log level" )
5350 main.log.error( handle )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005351 return main.FALSE
You Wang22e807e2021-03-29 10:53:38 -07005352 else:
5353 return main.TRUE
5354 except AssertionError:
5355 main.log.exception( "" )
5356 return None
5357 except TypeError:
5358 main.log.exception( self.name + ": Object not as expected" )
5359 return None
Flavio Castro82ee2f62016-06-07 15:04:12 -07005360 except pexpect.EOF:
5361 main.log.error( self.name + ": EOF exception found" )
5362 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005363 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005364 except Exception:
5365 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005366 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005367
Jon Hall06fd0df2021-01-25 15:50:06 -08005368 def logList( self, saveValues=True ):
5369 """
5370 Gets the current log levels and optionally saves them
5371 returns a dict of the log levels or
5372 returns main.FALSE if Error occurred
5373 """
5374 try:
5375 self.handle.sendline( "log:list" )
5376 self.handle.expect( self.karafPrompt )
5377
5378 response = self.handle.before
5379 logLevels = {}
5380 for line in response.splitlines():
5381 parsed = line.split('│')
5382 logger = parsed[0].strip()
5383 if len( parsed ) != 2 or 'Level' in parsed[1] or logger[0] == '─':
5384 continue
5385 level = parsed[1].strip()
5386 logLevels[ logger ] = level
5387 if saveValues:
5388 self.logLevels = logLevels
5389 return logLevels
5390 except pexpect.TIMEOUT:
5391 main.log.exception( self.name + ": TIMEOUT exception found" )
5392 main.cleanAndExit()
5393 except pexpect.EOF:
5394 main.log.error( self.name + ": EOF exception found" )
5395 main.log.error( self.name + ": " + self.handle.before )
5396 main.cleanAndExit()
5397 except Exception:
5398 main.log.exception( self.name + ": Uncaught exception!" )
5399 main.cleanAndExit()
5400
You Wangdb8cd0a2016-05-26 15:19:45 -07005401 def getGraphDict( self, timeout=60, includeHost=False ):
5402 """
5403 Return a dictionary which describes the latest network topology data as a
5404 graph.
5405 An example of the dictionary:
5406 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5407 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5408 Each vertex should at least have an 'edges' attribute which describes the
5409 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005410 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005411 list of attributes.
5412 An example of the edges dictionary:
5413 'edges': { vertex2: { 'port': ..., 'weight': ... },
5414 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005415 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005416 in topology data.
5417 """
5418 graphDict = {}
5419 try:
5420 links = self.links()
5421 links = json.loads( links )
5422 devices = self.devices()
5423 devices = json.loads( devices )
5424 idToDevice = {}
5425 for device in devices:
5426 idToDevice[ device[ 'id' ] ] = device
5427 if includeHost:
5428 hosts = self.hosts()
5429 # FIXME: support 'includeHost' argument
5430 for link in links:
5431 nodeA = link[ 'src' ][ 'device' ]
5432 nodeB = link[ 'dst' ][ 'device' ]
5433 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005434 if nodeA not in graphDict.keys():
5435 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005436 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005437 'type': idToDevice[ nodeA ][ 'type' ],
5438 'available': idToDevice[ nodeA ][ 'available' ],
5439 'role': idToDevice[ nodeA ][ 'role' ],
5440 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5441 'hw': idToDevice[ nodeA ][ 'hw' ],
5442 'sw': idToDevice[ nodeA ][ 'sw' ],
5443 'serial': idToDevice[ nodeA ][ 'serial' ],
5444 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005445 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005446 else:
5447 # Assert nodeB is not connected to any current links of nodeA
You Wang7d14d642019-01-23 15:10:08 -08005448 # assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
5449 pass
Jon Halle0f0b342017-04-18 11:43:47 -07005450 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5451 'type': link[ 'type' ],
5452 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005453 return graphDict
5454 except ( TypeError, ValueError ):
5455 main.log.exception( self.name + ": Object not as expected" )
5456 return None
5457 except KeyError:
5458 main.log.exception( self.name + ": KeyError exception found" )
5459 return None
5460 except AssertionError:
5461 main.log.exception( self.name + ": AssertionError exception found" )
5462 return None
5463 except pexpect.EOF:
5464 main.log.error( self.name + ": EOF exception found" )
5465 main.log.error( self.name + ": " + self.handle.before )
5466 return None
5467 except Exception:
5468 main.log.exception( self.name + ": Uncaught exception!" )
5469 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005470
5471 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005472 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005473 Send command to check intent-perf summary
5474 Returns: dictionary for intent-perf summary
5475 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005476 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005477 cmd = "intent-perf -s"
5478 respDic = {}
5479 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005480 assert resp is not None, "Error in sendline"
5481 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005482 try:
5483 # Generate the dictionary to return
5484 for l in resp.split( "\n" ):
5485 # Delete any white space in line
5486 temp = re.sub( r'\s+', '', l )
5487 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005488 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005489
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005490 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005491 main.log.exception( self.name + ": Object not as expected" )
5492 return None
5493 except KeyError:
5494 main.log.exception( self.name + ": KeyError exception found" )
5495 return None
5496 except AssertionError:
5497 main.log.exception( self.name + ": AssertionError exception found" )
5498 return None
5499 except pexpect.EOF:
5500 main.log.error( self.name + ": EOF exception found" )
5501 main.log.error( self.name + ": " + self.handle.before )
5502 return None
5503 except Exception:
5504 main.log.exception( self.name + ": Uncaught exception!" )
5505 return None
5506 return respDic
5507
Chiyu Chengec63bde2016-11-17 18:11:36 -08005508 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005509 """
5510 Searches the latest ONOS log file for the given search term and
5511 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005512
chengchiyu08303a02016-09-08 17:40:26 -07005513 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005514 searchTerm:
5515 The string to grep from the ONOS log.
5516 startLine:
5517 The term that decides which line is the start to search the searchTerm in
5518 the karaf log. For now, startTerm only works in 'first' mode.
5519 logNum:
5520 In some extreme cases, one karaf log is not big enough to contain all the
5521 information.Because of this, search mutiply logs is necessary to capture
5522 the right result. logNum is the number of karaf logs that we need to search
5523 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005524 mode:
5525 all: return all the strings that contain the search term
5526 last: return the last string that contains the search term
5527 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005528 num: return the number of times that the searchTerm appears in the log
5529 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005530 """
5531 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005532 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005533 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005534 logPath = '/opt/onos/log/karaf.log.'
5535 logPaths = '/opt/onos/log/karaf.log'
5536 for i in range( 1, logNum ):
5537 logPaths = logPath + str( i ) + " " + logPaths
5538 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005539 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005540 # 100000000 is just a extreme large number to make sure this function can
5541 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005542 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005543 if mode == 'all':
5544 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005545 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005546 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005547 elif mode == 'first':
5548 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5549 elif mode == 'num':
You Wangd91a70f2019-01-03 15:28:10 -08005550 cmd = cmd + " | grep \'" + searchTerm + "\' | wc -l"
5551 num = self.lineCount( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005552 return num
You Wang6d301d42017-04-21 10:49:33 -07005553 elif mode == 'total':
Jon Halld5a94fb2018-11-13 14:32:23 -08005554 totalLines = self.lineCount( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005555 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005556 else:
5557 main.log.error( self.name + " unsupported mode" )
5558 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005559 before = self.sendline( cmd )
5560 before = before.splitlines()
5561 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005562 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005563 return returnLines
5564 except AssertionError:
5565 main.log.error( self.name + " searchTerm is not string type" )
5566 return None
5567 except pexpect.EOF:
5568 main.log.error( self.name + ": EOF exception found" )
5569 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005570 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005571 except pexpect.TIMEOUT:
5572 main.log.error( self.name + ": TIMEOUT exception found" )
5573 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005574 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005575 except Exception:
5576 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005577 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005578
5579 def vplsShow( self, jsonFormat=True ):
5580 """
5581 Description: Returns result of onos:vpls show, which should list the
5582 configured VPLS networks and the assigned interfaces.
5583 Optional:
5584 * jsonFormat: enable json formatting of output
5585 Returns:
5586 The output of the command or None on error.
5587 """
5588 try:
5589 cmdStr = "vpls show"
5590 if jsonFormat:
5591 raise NotImplementedError
5592 cmdStr += " -j"
5593 handle = self.sendline( cmdStr )
5594 assert handle is not None, "Error in sendline"
5595 assert "Command not found:" not in handle, handle
5596 return handle
5597 except AssertionError:
5598 main.log.exception( "" )
5599 return None
5600 except TypeError:
5601 main.log.exception( self.name + ": Object not as expected" )
5602 return None
5603 except pexpect.EOF:
5604 main.log.error( self.name + ": EOF exception found" )
5605 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005606 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005607 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005608 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005609 return None
5610 except Exception:
5611 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005612 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005613
5614 def parseVplsShow( self ):
5615 """
5616 Parse the cli output of 'vpls show' into json output. This is required
5617 as there is currently no json output available.
5618 """
5619 try:
5620 output = []
5621 raw = self.vplsShow( jsonFormat=False )
5622 namePat = "VPLS name: (?P<name>\w+)"
5623 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5624 encapPat = "Encapsulation: (?P<encap>\w+)"
5625 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5626 mIter = re.finditer( pattern, raw )
5627 for match in mIter:
5628 item = {}
5629 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005630 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005631 if ifaces == [ "" ]:
5632 ifaces = []
5633 item[ 'interfaces' ] = ifaces
5634 encap = match.group( 'encap' )
5635 if encap != 'NONE':
5636 item[ 'encapsulation' ] = encap.lower()
5637 output.append( item )
5638 return output
5639 except Exception:
5640 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005641 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005642
5643 def vplsList( self, jsonFormat=True ):
5644 """
5645 Description: Returns result of onos:vpls list, which should list the
5646 configured VPLS networks.
5647 Optional:
5648 * jsonFormat: enable json formatting of output
5649 """
5650 try:
5651 cmdStr = "vpls list"
5652 if jsonFormat:
5653 raise NotImplementedError
5654 cmdStr += " -j"
5655 handle = self.sendline( cmdStr )
5656 assert handle is not None, "Error in sendline"
5657 assert "Command not found:" not in handle, handle
5658 return handle
5659 except AssertionError:
5660 main.log.exception( "" )
5661 return None
5662 except TypeError:
5663 main.log.exception( self.name + ": Object not as expected" )
5664 return None
5665 except pexpect.EOF:
5666 main.log.error( self.name + ": EOF exception found" )
5667 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005668 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005669 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005670 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005671 return None
5672 except Exception:
5673 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005674 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005675
5676 def vplsCreate( self, network ):
5677 """
5678 CLI command to create a new VPLS network.
5679 Required arguments:
5680 network - String name of the network to create.
5681 returns:
5682 main.TRUE on success and main.FALSE on failure
5683 """
5684 try:
5685 network = str( network )
5686 cmdStr = "vpls create "
5687 cmdStr += network
5688 output = self.sendline( cmdStr )
5689 assert output is not None, "Error in sendline"
5690 assert "Command not found:" not in output, output
5691 assert "Error executing command" not in output, output
5692 assert "VPLS already exists:" not in output, output
5693 return main.TRUE
5694 except AssertionError:
5695 main.log.exception( "" )
5696 return main.FALSE
5697 except TypeError:
5698 main.log.exception( self.name + ": Object not as expected" )
5699 return main.FALSE
5700 except pexpect.EOF:
5701 main.log.error( self.name + ": EOF exception found" )
5702 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005703 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005704 except Exception:
5705 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005706 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005707
5708 def vplsDelete( self, network ):
5709 """
5710 CLI command to delete a VPLS network.
5711 Required arguments:
5712 network - Name of the network to delete.
5713 returns:
5714 main.TRUE on success and main.FALSE on failure
5715 """
5716 try:
5717 network = str( network )
5718 cmdStr = "vpls delete "
5719 cmdStr += network
5720 output = self.sendline( cmdStr )
5721 assert output is not None, "Error in sendline"
5722 assert "Command not found:" not in output, output
5723 assert "Error executing command" not in output, output
5724 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005725 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005726 return main.TRUE
5727 except AssertionError:
5728 main.log.exception( "" )
5729 return main.FALSE
5730 except TypeError:
5731 main.log.exception( self.name + ": Object not as expected" )
5732 return main.FALSE
5733 except pexpect.EOF:
5734 main.log.error( self.name + ": EOF exception found" )
5735 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005736 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005737 except Exception:
5738 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005739 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005740
5741 def vplsAddIface( self, network, iface ):
5742 """
5743 CLI command to add an interface to a VPLS network.
5744 Required arguments:
5745 network - Name of the network to add the interface to.
5746 iface - The ONOS name for an interface.
5747 returns:
5748 main.TRUE on success and main.FALSE on failure
5749 """
5750 try:
5751 network = str( network )
5752 iface = str( iface )
5753 cmdStr = "vpls add-if "
5754 cmdStr += network + " " + iface
5755 output = self.sendline( cmdStr )
5756 assert output is not None, "Error in sendline"
5757 assert "Command not found:" not in output, output
5758 assert "Error executing command" not in output, output
5759 assert "already associated to network" not in output, output
5760 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005761 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005762 return main.TRUE
5763 except AssertionError:
5764 main.log.exception( "" )
5765 return main.FALSE
5766 except TypeError:
5767 main.log.exception( self.name + ": Object not as expected" )
5768 return main.FALSE
5769 except pexpect.EOF:
5770 main.log.error( self.name + ": EOF exception found" )
5771 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005772 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005773 except Exception:
5774 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005775 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005776
5777 def vplsRemIface( self, network, iface ):
5778 """
5779 CLI command to remove an interface from a VPLS network.
5780 Required arguments:
5781 network - Name of the network to remove the interface from.
5782 iface - Name of the interface to remove.
5783 returns:
5784 main.TRUE on success and main.FALSE on failure
5785 """
5786 try:
5787 iface = str( iface )
5788 cmdStr = "vpls rem-if "
5789 cmdStr += network + " " + iface
5790 output = self.sendline( cmdStr )
5791 assert output is not None, "Error in sendline"
5792 assert "Command not found:" not in output, output
5793 assert "Error executing command" not in output, output
5794 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005795 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005796 return main.TRUE
5797 except AssertionError:
5798 main.log.exception( "" )
5799 return main.FALSE
5800 except TypeError:
5801 main.log.exception( self.name + ": Object not as expected" )
5802 return main.FALSE
5803 except pexpect.EOF:
5804 main.log.error( self.name + ": EOF exception found" )
5805 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005806 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005807 except Exception:
5808 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005809 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005810
5811 def vplsClean( self ):
5812 """
5813 Description: Clears the VPLS app configuration.
5814 Returns: main.TRUE on success and main.FALSE on failure
5815 """
5816 try:
5817 cmdStr = "vpls clean"
5818 handle = self.sendline( cmdStr )
5819 assert handle is not None, "Error in sendline"
5820 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005821 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005822 return handle
5823 except AssertionError:
5824 main.log.exception( "" )
5825 return main.FALSE
5826 except TypeError:
5827 main.log.exception( self.name + ": Object not as expected" )
5828 return main.FALSE
5829 except pexpect.EOF:
5830 main.log.error( self.name + ": EOF exception found" )
5831 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005832 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005833 except Exception:
5834 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005835 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005836
5837 def vplsSetEncap( self, network, encapType ):
5838 """
5839 CLI command to add an interface to a VPLS network.
5840 Required arguments:
5841 network - Name of the network to create.
5842 encapType - Type of encapsulation.
5843 returns:
5844 main.TRUE on success and main.FALSE on failure
5845 """
5846 try:
5847 network = str( network )
5848 encapType = str( encapType ).upper()
5849 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5850 cmdStr = "vpls set-encap "
5851 cmdStr += network + " " + encapType
5852 output = self.sendline( cmdStr )
5853 assert output is not None, "Error in sendline"
5854 assert "Command not found:" not in output, output
5855 assert "Error executing command" not in output, output
5856 assert "already associated to network" not in output, output
5857 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005858 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005859 return main.TRUE
5860 except AssertionError:
5861 main.log.exception( "" )
5862 return main.FALSE
5863 except TypeError:
5864 main.log.exception( self.name + ": Object not as expected" )
5865 return main.FALSE
5866 except pexpect.EOF:
5867 main.log.error( self.name + ": EOF exception found" )
5868 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005869 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005870 except Exception:
5871 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005872 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005873
5874 def interfaces( self, jsonFormat=True ):
5875 """
5876 Description: Returns result of interfaces command.
5877 Optional:
5878 * jsonFormat: enable json formatting of output
5879 Returns:
5880 The output of the command or None on error.
5881 """
5882 try:
5883 cmdStr = "interfaces"
5884 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005885 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005886 cmdStr += " -j"
5887 handle = self.sendline( cmdStr )
5888 assert handle is not None, "Error in sendline"
5889 assert "Command not found:" not in handle, handle
5890 return handle
5891 except AssertionError:
5892 main.log.exception( "" )
5893 return None
5894 except TypeError:
5895 main.log.exception( self.name + ": Object not as expected" )
5896 return None
5897 except pexpect.EOF:
5898 main.log.error( self.name + ": EOF exception found" )
5899 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005900 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005901 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005902 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005903 return None
5904 except Exception:
5905 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005906 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005907
5908 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005909 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005910 Get the timestamp of searchTerm from karaf log.
5911
5912 Arguments:
5913 splitTerm_before and splitTerm_after:
5914
5915 The terms that split the string that contains the timeStamp of
5916 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5917 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5918 and the splitTerm_after is "x"
5919
5920 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005921 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005922 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005923 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005924 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005925 return main.ERROR
5926 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005927 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005928 main.log.warn( "Captured timestamp string is empty" )
5929 return main.ERROR
5930 lines = lines[ 0 ]
5931 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005932 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005933 # get the target value
5934 line = lines.split( splitTerm_before )
5935 key = line[ 1 ].split( splitTerm_after )
5936 return int( key[ 0 ] )
5937 except IndexError:
5938 main.log.warn( "Index Error!" )
5939 return main.ERROR
5940 except AssertionError:
5941 main.log.warn( "Search Term Not Found " )
5942 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005943
5944 def workQueueAdd( self, queueName, value ):
5945 """
5946 CLI command to add a string to the specified Work Queue.
5947 This function uses the distributed primitives test app, which
5948 gives some cli access to distributed primitives for testing
5949 purposes only.
5950
5951 Required arguments:
5952 queueName - The name of the queue to add to
5953 value - The value to add to the queue
5954 returns:
5955 main.TRUE on success, main.FALSE on failure and
5956 main.ERROR on error.
5957 """
5958 try:
5959 queueName = str( queueName )
5960 value = str( value )
5961 prefix = "work-queue-test"
5962 operation = "add"
5963 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5964 output = self.distPrimitivesSend( cmdStr )
5965 if "Invalid operation name" in output:
5966 main.log.warn( output )
5967 return main.ERROR
5968 elif "Done" in output:
5969 return main.TRUE
5970 except TypeError:
5971 main.log.exception( self.name + ": Object not as expected" )
5972 return main.ERROR
5973 except Exception:
5974 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005975 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005976
5977 def workQueueAddMultiple( self, queueName, value1, value2 ):
5978 """
5979 CLI command to add two strings to the specified Work Queue.
5980 This function uses the distributed primitives test app, which
5981 gives some cli access to distributed primitives for testing
5982 purposes only.
5983
5984 Required arguments:
5985 queueName - The name of the queue to add to
5986 value1 - The first value to add to the queue
5987 value2 - The second value to add to the queue
5988 returns:
5989 main.TRUE on success, main.FALSE on failure and
5990 main.ERROR on error.
5991 """
5992 try:
5993 queueName = str( queueName )
5994 value1 = str( value1 )
5995 value2 = str( value2 )
5996 prefix = "work-queue-test"
5997 operation = "addMultiple"
5998 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5999 output = self.distPrimitivesSend( cmdStr )
6000 if "Invalid operation name" in output:
6001 main.log.warn( output )
6002 return main.ERROR
6003 elif "Done" in output:
6004 return main.TRUE
6005 except TypeError:
6006 main.log.exception( self.name + ": Object not as expected" )
6007 return main.ERROR
6008 except Exception:
6009 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006010 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006011
6012 def workQueueTakeAndComplete( self, queueName, number=1 ):
6013 """
6014 CLI command to take a value from the specified Work Queue and compelte it.
6015 This function uses the distributed primitives test app, which
6016 gives some cli access to distributed primitives for testing
6017 purposes only.
6018
6019 Required arguments:
6020 queueName - The name of the queue to add to
6021 number - The number of items to take and complete
6022 returns:
6023 main.TRUE on success, main.FALSE on failure and
6024 main.ERROR on error.
6025 """
6026 try:
6027 queueName = str( queueName )
6028 number = str( int( number ) )
6029 prefix = "work-queue-test"
6030 operation = "takeAndComplete"
6031 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
6032 output = self.distPrimitivesSend( cmdStr )
6033 if "Invalid operation name" in output:
6034 main.log.warn( output )
6035 return main.ERROR
6036 elif "Done" in output:
6037 return main.TRUE
6038 except TypeError:
6039 main.log.exception( self.name + ": Object not as expected" )
6040 return main.ERROR
6041 except Exception:
6042 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006043 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006044
6045 def workQueueDestroy( self, queueName ):
6046 """
6047 CLI command to destroy the specified Work Queue.
6048 This function uses the distributed primitives test app, which
6049 gives some cli access to distributed primitives for testing
6050 purposes only.
6051
6052 Required arguments:
6053 queueName - The name of the queue to add to
6054 returns:
6055 main.TRUE on success, main.FALSE on failure and
6056 main.ERROR on error.
6057 """
6058 try:
6059 queueName = str( queueName )
6060 prefix = "work-queue-test"
6061 operation = "destroy"
6062 cmdStr = " ".join( [ prefix, queueName, operation ] )
6063 output = self.distPrimitivesSend( cmdStr )
6064 if "Invalid operation name" in output:
6065 main.log.warn( output )
6066 return main.ERROR
6067 return main.TRUE
6068 except TypeError:
6069 main.log.exception( self.name + ": Object not as expected" )
6070 return main.ERROR
6071 except Exception:
6072 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006073 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006074
6075 def workQueueTotalPending( self, queueName ):
6076 """
6077 CLI command to get the Total Pending items of the specified Work Queue.
6078 This function uses the distributed primitives test app, which
6079 gives some cli access to distributed primitives for testing
6080 purposes only.
6081
6082 Required arguments:
6083 queueName - The name of the queue to add to
6084 returns:
6085 The number of Pending items in the specified work queue or
6086 None on error
6087 """
6088 try:
6089 queueName = str( queueName )
6090 prefix = "work-queue-test"
6091 operation = "totalPending"
6092 cmdStr = " ".join( [ prefix, queueName, operation ] )
6093 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08006094 main.log.debug( self.name + ": work queue unparsed: " + output )
6095 output = output.split( "\r\n" )[ -1 ]
6096 main.log.debug( self.name + ": work queue parsed: " + output )
Jon Halle0f0b342017-04-18 11:43:47 -07006097 pattern = r'\d+'
6098 if "Invalid operation name" in output:
6099 main.log.warn( output )
6100 return None
6101 else:
6102 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006103 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006104 except ( AttributeError, TypeError ):
6105 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6106 return None
6107 except Exception:
6108 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006109 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006110
6111 def workQueueTotalCompleted( self, queueName ):
6112 """
6113 CLI command to get the Total Completed items of the specified Work Queue.
6114 This function uses the distributed primitives test app, which
6115 gives some cli access to distributed primitives for testing
6116 purposes only.
6117
6118 Required arguments:
6119 queueName - The name of the queue to add to
6120 returns:
6121 The number of complete items in the specified work queue or
6122 None on error
6123 """
6124 try:
6125 queueName = str( queueName )
6126 prefix = "work-queue-test"
6127 operation = "totalCompleted"
6128 cmdStr = " ".join( [ prefix, queueName, operation ] )
6129 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08006130 main.log.debug( self.name + ": work queue unparsed: " + output )
6131 output = output.split( "\r\n" )[ -1 ]
6132 main.log.debug( self.name + ": work queue parsed: " + output )
Jon Halle0f0b342017-04-18 11:43:47 -07006133 pattern = r'\d+'
6134 if "Invalid operation name" in output:
6135 main.log.warn( output )
6136 return None
6137 else:
6138 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006139 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006140 except ( AttributeError, TypeError ):
6141 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6142 return None
6143 except Exception:
6144 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006145 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006146
6147 def workQueueTotalInProgress( self, queueName ):
6148 """
6149 CLI command to get the Total In Progress items of the specified Work Queue.
6150 This function uses the distributed primitives test app, which
6151 gives some cli access to distributed primitives for testing
6152 purposes only.
6153
6154 Required arguments:
6155 queueName - The name of the queue to add to
6156 returns:
6157 The number of In Progress items in the specified work queue or
6158 None on error
6159 """
6160 try:
6161 queueName = str( queueName )
6162 prefix = "work-queue-test"
6163 operation = "totalInProgress"
6164 cmdStr = " ".join( [ prefix, queueName, operation ] )
6165 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08006166 main.log.debug( self.name + ": work queue unparsed: " + output )
6167 output = output.split( "\r\n" )[ -1 ]
6168 main.log.debug( self.name + ": work queue parsed: " + output )
Jon Halle0f0b342017-04-18 11:43:47 -07006169 pattern = r'\d+'
6170 if "Invalid operation name" in output:
6171 main.log.warn( output )
6172 return None
6173 else:
6174 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006175 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006176 except ( AttributeError, TypeError ):
6177 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6178 return None
6179 except Exception:
6180 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006181 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00006182
6183 def events( self, args='-a' ):
6184 """
6185 Description: Returns events -a command output
6186 Optional:
6187 add other arguments
6188 """
6189 try:
6190 cmdStr = "events"
6191 if args:
6192 cmdStr += " " + args
6193 handle = self.sendline( cmdStr )
6194 assert handle is not None, "Error in sendline"
6195 assert "Command not found:" not in handle, handle
6196 return handle
6197 except AssertionError:
6198 main.log.exception( "" )
6199 return None
6200 except TypeError:
6201 main.log.exception( self.name + ": Object not as expected" )
6202 return None
6203 except pexpect.EOF:
6204 main.log.error( self.name + ": EOF exception found" )
6205 main.log.error( self.name + ": " + self.handle.before )
6206 main.cleanAndExit()
6207 except Exception:
6208 main.log.exception( self.name + ": Uncaught exception!" )
6209 main.cleanAndExit()
6210
6211 def getMaster( self, deviceID ):
6212 """
6213 Description: Obtains current master using "roles" command for a specific deviceID
6214 """
6215 try:
6216 return str( self.getRole( deviceID )[ 'master' ] )
6217 except AssertionError:
6218 main.log.exception( "" )
6219 return None
6220 except TypeError:
6221 main.log.exception( self.name + ": Object not as expected" )
6222 return None
6223 except pexpect.EOF:
6224 main.log.error( self.name + ": EOF exception found" )
6225 main.log.error( self.name + ": " + self.handle.before )
6226 main.cleanAndExit()
6227 except Exception:
6228 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07006229 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08006230
6231 def issu( self ):
6232 """
6233 Short summary of In-Service Software Upgrade status
6234
6235 Returns the output of the cli command or None on Error
6236 """
6237 try:
6238 cmdStr = "issu"
6239 handle = self.sendline( cmdStr )
6240 assert handle is not None, "Error in sendline"
6241 assert "Command not found:" not in handle, handle
6242 assert "Unsupported command:" not in handle, handle
6243 return handle
6244 except AssertionError:
6245 main.log.exception( "" )
6246 return None
6247 except TypeError:
6248 main.log.exception( self.name + ": Object not as expected" )
6249 return None
6250 except pexpect.EOF:
6251 main.log.error( self.name + ": EOF exception found" )
6252 main.log.error( self.name + ": " + self.handle.before )
6253 main.cleanAndExit()
6254 except Exception:
6255 main.log.exception( self.name + ": Uncaught exception!" )
6256 main.cleanAndExit()
6257
6258 def issuInit( self ):
6259 """
6260 Initiates an In-Service Software Upgrade
6261
6262 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6263 """
6264 try:
6265 cmdStr = "issu init"
6266 handle = self.sendline( cmdStr )
6267 assert handle is not None, "Error in sendline"
6268 assert "Command not found:" not in handle, handle
6269 assert "Unsupported command:" not in handle, handle
6270 if "Initialized" in handle:
6271 return main.TRUE
6272 else:
6273 return main.FALSE
6274 except AssertionError:
6275 main.log.exception( "" )
6276 return main.ERROR
6277 except TypeError:
6278 main.log.exception( self.name + ": Object not as expected" )
6279 return main.ERROR
6280 except pexpect.EOF:
6281 main.log.error( self.name + ": EOF exception found" )
6282 main.log.error( self.name + ": " + self.handle.before )
6283 main.cleanAndExit()
6284 except Exception:
6285 main.log.exception( self.name + ": Uncaught exception!" )
6286 main.cleanAndExit()
6287
6288 def issuUpgrade( self ):
6289 """
6290 Transitions stores to upgraded nodes
6291
6292 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6293 """
6294 try:
6295 cmdStr = "issu upgrade"
6296 handle = self.sendline( cmdStr )
6297 assert handle is not None, "Error in sendline"
6298 assert "Command not found:" not in handle, handle
6299 assert "Unsupported command:" not in handle, handle
6300 if "Upgraded" in handle:
6301 return main.TRUE
6302 else:
6303 return main.FALSE
6304 except AssertionError:
6305 main.log.exception( "" )
6306 return main.ERROR
6307 except TypeError:
6308 main.log.exception( self.name + ": Object not as expected" )
6309 return main.ERROR
6310 except pexpect.EOF:
6311 main.log.error( self.name + ": EOF exception found" )
6312 main.log.error( self.name + ": " + self.handle.before )
6313 main.cleanAndExit()
6314 except Exception:
6315 main.log.exception( self.name + ": Uncaught exception!" )
6316 main.cleanAndExit()
6317
6318 def issuCommit( self ):
6319 """
6320 Finalizes an In-Service Software Upgrade
6321
6322 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6323 """
6324 try:
6325 cmdStr = "issu commit"
6326 handle = self.sendline( cmdStr )
6327 assert handle is not None, "Error in sendline"
6328 assert "Command not found:" not in handle, handle
6329 assert "Unsupported command:" not in handle, handle
6330 # TODO: Check the version returned by this command
6331 if "Committed version" in handle:
6332 return main.TRUE
6333 else:
6334 return main.FALSE
6335 except AssertionError:
6336 main.log.exception( "" )
6337 return main.ERROR
6338 except TypeError:
6339 main.log.exception( self.name + ": Object not as expected" )
6340 return main.ERROR
6341 except pexpect.EOF:
6342 main.log.error( self.name + ": EOF exception found" )
6343 main.log.error( self.name + ": " + self.handle.before )
6344 main.cleanAndExit()
6345 except Exception:
6346 main.log.exception( self.name + ": Uncaught exception!" )
6347 main.cleanAndExit()
6348
6349 def issuRollback( self ):
6350 """
6351 Rolls back an In-Service Software Upgrade
6352
6353 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6354 """
6355 try:
6356 cmdStr = "issu rollback"
6357 handle = self.sendline( cmdStr )
6358 assert handle is not None, "Error in sendline"
6359 assert "Command not found:" not in handle, handle
6360 assert "Unsupported command:" not in handle, handle
6361 # TODO: Check the version returned by this command
6362 if "Rolled back to version" in handle:
6363 return main.TRUE
6364 else:
6365 return main.FALSE
6366 except AssertionError:
6367 main.log.exception( "" )
6368 return main.ERROR
6369 except TypeError:
6370 main.log.exception( self.name + ": Object not as expected" )
6371 return main.ERROR
6372 except pexpect.EOF:
6373 main.log.error( self.name + ": EOF exception found" )
6374 main.log.error( self.name + ": " + self.handle.before )
6375 main.cleanAndExit()
6376 except Exception:
6377 main.log.exception( self.name + ": Uncaught exception!" )
6378 main.cleanAndExit()
6379
6380 def issuReset( self ):
6381 """
6382 Resets the In-Service Software Upgrade status after a rollback
6383
6384 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6385 """
6386 try:
6387 cmdStr = "issu reset"
6388 handle = self.sendline( cmdStr )
6389 assert handle is not None, "Error in sendline"
6390 assert "Command not found:" not in handle, handle
6391 assert "Unsupported command:" not in handle, handle
6392 # TODO: Check the version returned by this command
6393 if "Reset version" in handle:
6394 return main.TRUE
6395 else:
6396 return main.FALSE
6397 except AssertionError:
6398 main.log.exception( "" )
6399 return main.ERROR
6400 except TypeError:
6401 main.log.exception( self.name + ": Object not as expected" )
6402 return main.ERROR
6403 except pexpect.EOF:
6404 main.log.error( self.name + ": EOF exception found" )
6405 main.log.error( self.name + ": " + self.handle.before )
6406 main.cleanAndExit()
6407 except Exception:
6408 main.log.exception( self.name + ": Uncaught exception!" )
6409 main.cleanAndExit()
6410
6411 def issuStatus( self ):
6412 """
6413 Status of an In-Service Software Upgrade
6414
6415 Returns the output of the cli command or None on Error
6416 """
6417 try:
6418 cmdStr = "issu status"
6419 handle = self.sendline( cmdStr )
6420 assert handle is not None, "Error in sendline"
6421 assert "Command not found:" not in handle, handle
6422 assert "Unsupported command:" not in handle, handle
6423 return handle
6424 except AssertionError:
6425 main.log.exception( "" )
6426 return None
6427 except TypeError:
6428 main.log.exception( self.name + ": Object not as expected" )
6429 return None
6430 except pexpect.EOF:
6431 main.log.error( self.name + ": EOF exception found" )
6432 main.log.error( self.name + ": " + self.handle.before )
6433 main.cleanAndExit()
6434 except Exception:
6435 main.log.exception( self.name + ": Uncaught exception!" )
6436 main.cleanAndExit()
6437
6438 def issuVersion( self ):
6439 """
6440 Get the version of an In-Service Software Upgrade
6441
6442 Returns the output of the cli command or None on Error
6443 """
6444 try:
6445 cmdStr = "issu version"
6446 handle = self.sendline( cmdStr )
6447 assert handle is not None, "Error in sendline"
6448 assert "Command not found:" not in handle, handle
6449 assert "Unsupported command:" not in handle, handle
6450 return handle
6451 except AssertionError:
6452 main.log.exception( "" )
6453 return None
6454 except TypeError:
6455 main.log.exception( self.name + ": Object not as expected" )
6456 return None
6457 except pexpect.EOF:
6458 main.log.error( self.name + ": EOF exception found" )
6459 main.log.error( self.name + ": " + self.handle.before )
6460 main.cleanAndExit()
6461 except Exception:
6462 main.log.exception( self.name + ": Uncaught exception!" )
6463 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006464
6465 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6466 """
6467 Create a multicast route by calling 'mcast-join' command
6468 sIP: source IP of the multicast route
6469 groupIP: group IP of the multicast route
6470 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6471 dPorts: a list of destination ports of the multicast route
6472 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6473 """
6474 try:
6475 cmdStr = "mcast-join"
6476 cmdStr += " " + str( sIP )
6477 cmdStr += " " + str( groupIP )
6478 cmdStr += " " + str( sPort )
6479 assert isinstance( dPorts, list )
6480 for dPort in dPorts:
6481 cmdStr += " " + str( dPort )
6482 handle = self.sendline( cmdStr )
6483 assert handle is not None, "Error in sendline"
6484 assert "Command not found:" not in handle, handle
6485 assert "Unsupported command:" not in handle, handle
6486 assert "Error executing command" not in handle, handle
6487 if "Added the mcast route" in handle:
6488 return main.TRUE
6489 else:
6490 return main.FALSE
6491 except AssertionError:
6492 main.log.exception( "" )
6493 return None
6494 except TypeError:
6495 main.log.exception( self.name + ": Object not as expected" )
6496 return None
6497 except pexpect.EOF:
6498 main.log.error( self.name + ": EOF exception found" )
6499 main.log.error( self.name + ": " + self.handle.before )
6500 main.cleanAndExit()
6501 except Exception:
6502 main.log.exception( self.name + ": Uncaught exception!" )
6503 main.cleanAndExit()
6504
6505 def mcastDelete( self, sIP, groupIP, dPorts ):
6506 """
6507 Delete a multicast route by calling 'mcast-delete' command
6508 sIP: source IP of the multicast route
6509 groupIP: group IP of the multicast route
6510 dPorts: a list of destination ports of the multicast route
6511 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6512 """
6513 try:
6514 cmdStr = "mcast-delete"
6515 cmdStr += " " + str( sIP )
6516 cmdStr += " " + str( groupIP )
6517 assert isinstance( dPorts, list )
6518 for dPort in dPorts:
6519 cmdStr += " " + str( dPort )
6520 handle = self.sendline( cmdStr )
6521 assert handle is not None, "Error in sendline"
6522 assert "Command not found:" not in handle, handle
6523 assert "Unsupported command:" not in handle, handle
6524 assert "Error executing command" not in handle, handle
6525 if "Updated the mcast route" in handle:
6526 return main.TRUE
6527 else:
6528 return main.FALSE
6529 except AssertionError:
6530 main.log.exception( "" )
6531 return None
6532 except TypeError:
6533 main.log.exception( self.name + ": Object not as expected" )
6534 return None
6535 except pexpect.EOF:
6536 main.log.error( self.name + ": EOF exception found" )
6537 main.log.error( self.name + ": " + self.handle.before )
6538 main.cleanAndExit()
6539 except Exception:
6540 main.log.exception( self.name + ": Uncaught exception!" )
6541 main.cleanAndExit()
6542
6543 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6544 """
6545 Create a multicast route by calling 'mcast-host-join' command
6546 sAddr: we can provide * for ASM or a specific address for SSM
6547 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006548 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006549 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6550 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6551 """
6552 try:
6553 cmdStr = "mcast-host-join"
6554 cmdStr += " -sAddr " + str( sAddr )
6555 cmdStr += " -gAddr " + str( gAddr )
6556 assert isinstance( srcs, list )
6557 for src in srcs:
6558 cmdStr += " -srcs " + str( src )
6559 assert isinstance( sinks, list )
6560 for sink in sinks:
6561 cmdStr += " -sinks " + str( sink )
6562 handle = self.sendline( cmdStr )
6563 assert handle is not None, "Error in sendline"
6564 assert "Command not found:" not in handle, handle
6565 assert "Unsupported command:" not in handle, handle
6566 assert "Error executing command" not in handle, handle
6567 if "Added the mcast route" in handle:
6568 return main.TRUE
6569 else:
6570 return main.FALSE
6571 except AssertionError:
6572 main.log.exception( "" )
6573 return None
6574 except TypeError:
6575 main.log.exception( self.name + ": Object not as expected" )
6576 return None
6577 except pexpect.EOF:
6578 main.log.error( self.name + ": EOF exception found" )
6579 main.log.error( self.name + ": " + self.handle.before )
6580 main.cleanAndExit()
6581 except Exception:
6582 main.log.exception( self.name + ": Uncaught exception!" )
6583 main.cleanAndExit()
6584
6585 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6586 """
6587 Delete multicast sink(s) by calling 'mcast-host-delete' command
6588 sAddr: we can provide * for ASM or a specific address for SSM
6589 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006590 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006591 will delete the route if not specified
6592 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6593 """
6594 try:
6595 cmdStr = "mcast-host-delete"
6596 cmdStr += " -sAddr " + str( sAddr )
6597 cmdStr += " -gAddr " + str( gAddr )
6598 if host:
6599 cmdStr += " -h " + str( host )
6600 handle = self.sendline( cmdStr )
6601 assert handle is not None, "Error in sendline"
6602 assert "Command not found:" not in handle, handle
6603 assert "Unsupported command:" not in handle, handle
6604 assert "Error executing command" not in handle, handle
6605 if "Updated the mcast route" in handle:
6606 return main.TRUE
6607 elif "Deleted the mcast route" in handle:
6608 return main.TRUE
6609 else:
6610 return main.FALSE
6611 except AssertionError:
6612 main.log.exception( "" )
6613 return None
6614 except TypeError:
6615 main.log.exception( self.name + ": Object not as expected" )
6616 return None
6617 except pexpect.EOF:
6618 main.log.error( self.name + ": EOF exception found" )
6619 main.log.error( self.name + ": " + self.handle.before )
6620 main.cleanAndExit()
6621 except Exception:
6622 main.log.exception( self.name + ": Uncaught exception!" )
6623 main.cleanAndExit()
6624
You Wang547893e2018-05-08 13:34:59 -07006625 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6626 """
6627 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6628 sAddr: we can provide * for ASM or a specific address for SSM
6629 gAddr: specifies multicast group address
6630 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6631 will delete the route if not specified
6632 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6633 """
6634 try:
6635 cmdStr = "mcast-sink-delete"
6636 cmdStr += " -sAddr " + str( sAddr )
6637 cmdStr += " -gAddr " + str( gAddr )
6638 if sink:
6639 cmdStr += " -s " + str( sink )
6640 handle = self.sendline( cmdStr )
6641 assert handle is not None, "Error in sendline"
6642 assert "Command not found:" not in handle, handle
6643 assert "Unsupported command:" not in handle, handle
6644 assert "Error executing command" not in handle, handle
6645 if "Updated the mcast route" in handle:
6646 return main.TRUE
6647 elif "Deleted the mcast route" in handle:
6648 return main.TRUE
6649 else:
6650 return main.FALSE
6651 except AssertionError:
6652 main.log.exception( "" )
6653 return None
6654 except TypeError:
6655 main.log.exception( self.name + ": Object not as expected" )
6656 return None
6657 except pexpect.EOF:
6658 main.log.error( self.name + ": EOF exception found" )
6659 main.log.error( self.name + ": " + self.handle.before )
6660 main.cleanAndExit()
6661 except Exception:
6662 main.log.exception( self.name + ": Uncaught exception!" )
6663 main.cleanAndExit()
6664
You Wange24d6272018-03-27 21:18:50 -07006665 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6666 """
6667 Delete multicast src(s) by calling 'mcast-source-delete' command
6668 sAddr: we can provide * for ASM or a specific address for SSM
6669 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006670 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 -07006671 will delete the route if not specified
6672 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6673 """
6674 try:
6675 cmdStr = "mcast-source-delete"
6676 cmdStr += " -sAddr " + str( sAddr )
6677 cmdStr += " -gAddr " + str( gAddr )
6678 if srcs:
6679 assert isinstance( srcs, list )
6680 for src in srcs:
6681 cmdStr += " -src " + str( src )
6682 handle = self.sendline( cmdStr )
6683 assert handle is not None, "Error in sendline"
6684 assert "Command not found:" not in handle, handle
6685 assert "Unsupported command:" not in handle, handle
6686 assert "Error executing command" not in handle, handle
6687 if "Updated the mcast route" in handle:
6688 return main.TRUE
6689 elif "Deleted the mcast route" in handle:
6690 return main.TRUE
6691 else:
6692 return main.FALSE
6693 except AssertionError:
6694 main.log.exception( "" )
6695 return None
6696 except TypeError:
6697 main.log.exception( self.name + ": Object not as expected" )
6698 return None
6699 except pexpect.EOF:
6700 main.log.error( self.name + ": EOF exception found" )
6701 main.log.error( self.name + ": " + self.handle.before )
6702 main.cleanAndExit()
6703 except Exception:
6704 main.log.exception( self.name + ": Uncaught exception!" )
6705 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006706
6707 def netcfg( self, jsonFormat=True, args="" ):
6708 """
6709 Run netcfg cli command with given args
6710 """
6711 try:
6712 cmdStr = "netcfg"
6713 if jsonFormat:
6714 cmdStr = cmdStr + " -j"
6715 if args:
6716 cmdStr = cmdStr + " " + str( args )
6717 handle = self.sendline( cmdStr )
6718 assert handle is not None, "Error in sendline"
6719 assert "Command not found:" not in handle, handle
6720 assert "Unsupported command:" not in handle, handle
6721 assert "Error executing command" not in handle, handle
6722 return handle
6723 except AssertionError:
6724 main.log.exception( "" )
6725 return None
6726 except TypeError:
6727 main.log.exception( self.name + ": Object not as expected" )
6728 return None
6729 except pexpect.EOF:
6730 main.log.error( self.name + ": EOF exception found" )
6731 main.log.error( self.name + ": " + self.handle.before )
6732 main.cleanAndExit()
6733 except Exception:
6734 main.log.exception( self.name + ": Uncaught exception!" )
6735 main.cleanAndExit()
6736
You Wang0fa76e72018-05-18 11:33:25 -07006737 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True, simple=False ):
You Wang5da39c82018-04-26 22:55:08 -07006738 """
You Wang54b1d672018-06-11 16:44:13 -07006739 Compose and return a list of t3-troubleshoot cli commands for given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006740 Options:
6741 sAddr: IP address of the source host
6742 dAddr: IP address of the destination host
You Wang0fa76e72018-05-18 11:33:25 -07006743 ipv6: True if hosts are IPv6
6744 verbose: return verbose t3 output if True
6745 simple: compose command for t3-troubleshoot-simple if True
You Wang5da39c82018-04-26 22:55:08 -07006746 """
6747 try:
6748 # Collect information of both hosts from onos
6749 hosts = self.hosts()
6750 hosts = json.loads( hosts )
6751 sHost = None
6752 dHost = None
6753 for host in hosts:
6754 if sAddr in host[ "ipAddresses" ]:
6755 sHost = host
6756 elif dAddr in host[ "ipAddresses" ]:
6757 dHost = host
6758 if sHost and dHost:
6759 break
6760 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang54b1d672018-06-11 16:44:13 -07006761 cmdList = []
You Wang5d9527b2018-05-29 17:08:54 -07006762 if simple:
6763 assert dHost, "Not able to find host with IP {}".format( dAddr )
You Wang54b1d672018-06-11 16:44:13 -07006764 cmdStr = "t3-troubleshoot-simple"
6765 if verbose:
6766 cmdStr += " -vv"
6767 if ipv6:
6768 cmdStr += " -et ipv6"
You Wang0fa76e72018-05-18 11:33:25 -07006769 cmdStr += " {}/{} {}/{}".format( sHost[ "mac" ], sHost[ "vlan" ], dHost[ "mac" ], dHost[ "vlan" ] )
You Wang54b1d672018-06-11 16:44:13 -07006770 cmdList.append( cmdStr )
You Wang0fa76e72018-05-18 11:33:25 -07006771 else:
You Wang54b1d672018-06-11 16:44:13 -07006772 for location in sHost[ "locations" ]:
6773 cmdStr = "t3-troubleshoot"
6774 if verbose:
6775 cmdStr += " -vv"
6776 if ipv6:
6777 cmdStr += " -et ipv6"
6778 cmdStr += " -s " + str( sAddr )
6779 cmdStr += " -sp " + str( location[ "elementId" ] ) + "/" + str( location[ "port" ] )
6780 cmdStr += " -sm " + str( sHost[ "mac" ] )
6781 if sHost[ "vlan" ] != "None":
6782 cmdStr += " -vid " + sHost[ "vlan" ]
6783 cmdStr += " -d " + str( dAddr )
6784 netcfg = self.netcfg( args="devices {}".format( location[ "elementId" ] ) )
6785 netcfg = json.loads( netcfg )
6786 assert netcfg, "Failed to get netcfg"
6787 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6788 cmdList.append( cmdStr )
6789 return cmdList
You Wang5da39c82018-04-26 22:55:08 -07006790 except AssertionError:
6791 main.log.exception( "" )
6792 return None
6793 except ( KeyError, TypeError ):
6794 main.log.exception( self.name + ": Object not as expected" )
6795 return None
6796 except Exception:
6797 main.log.exception( self.name + ": Uncaught exception!" )
6798 main.cleanAndExit()
6799
6800 def t3( self, sAddr, dAddr, ipv6=False ):
6801 """
You Wang54b1d672018-06-11 16:44:13 -07006802 Run t3-troubleshoot cli commands for all posible routes given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006803 Options:
6804 sAddr: IP address of the source host
6805 dAddr: IP address of the destination host
6806 """
6807 try:
You Wang54b1d672018-06-11 16:44:13 -07006808 cmdList = self.composeT3Command( sAddr, dAddr, ipv6 )
6809 assert cmdList is not None, "composeT3Command returned None"
6810 t3Output = ""
6811 for cmdStr in cmdList:
6812 handle = self.sendline( cmdStr )
6813 assert handle is not None, "Error in sendline"
6814 assert "Command not found:" not in handle, handle
6815 assert "Unsupported command:" not in handle, handle
6816 assert "Error executing command" not in handle, handle
6817 assert "Tracing packet" in handle
6818 t3Output += handle
6819 return t3Output
You Wang5da39c82018-04-26 22:55:08 -07006820 except AssertionError:
6821 main.log.exception( "" )
6822 return None
6823 except pexpect.EOF:
6824 main.log.error( self.name + ": EOF exception found" )
6825 main.log.error( self.name + ": " + self.handle.before )
6826 main.cleanAndExit()
6827 except Exception:
6828 main.log.exception( self.name + ": Uncaught exception!" )
6829 main.cleanAndExit()
Jon Hall3c0114c2020-08-11 15:07:42 -07006830
6831 def prepareForCLI( self, debug=True, maxRetries=120 ):
6832 """
6833 Prepare docker container to connect to onos cli
6834 """
6835 try:
6836 # Wait for log files to be created
6837 ready = 0
6838 retries = 0
6839 while not ready and retries < maxRetries:
6840 retries += 1
6841 self.handle.sendline( "ls -al /root/onos/apache-karaf-*/data/log" )
6842 ready = self.handle.expect( [ "No such file or directory", self.dockerPrompt ] )
6843 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
6844 if not ready:
6845 self.handle.expect( self.dockerPrompt )
6846 time.sleep( 1 )
Jon Hall3c0114c2020-08-11 15:07:42 -07006847
6848 cmdList = []
6849 cmdList.append( "apt-get update" )
6850 cmdList.append( "apt-get install -y openssh-server" )
6851 # Some built in scripts are hardcoded
6852 cmdList.append( "ln -s /root/onos /opt/onos" )
6853 cmdList.append( "ln -s /root/onos/apache-karaf-*/data/log /opt/onos/log" )
6854 cmdList.append( "ls -al /opt/onos" )
6855 output = ""
6856 for cmdStr in cmdList:
6857 self.handle.sendline( cmdStr )
Jon Hall627b1572020-12-01 12:01:15 -08006858 self.handle.expect( self.dockerPrompt, timeout=420 )
Jon Hall3c0114c2020-08-11 15:07:42 -07006859 self.handle.sendline( "" )
6860 self.handle.expect( self.dockerPrompt )
6861 handle = self.handle.before
6862 assert "command not found" not in handle, handle
6863 assert "No such file or directory" not in handle, handle
6864 output += handle
6865 if debug:
6866 main.log.debug( "%s: %s" % ( self.name, output ) )
6867 return output
6868 except AssertionError:
6869 main.log.exception( "" )
6870 return None
6871 except pexpect.EOF:
6872 main.log.error( self.name + ": EOF exception found" )
6873 main.log.error( self.name + ": " + self.handle.before )
6874 main.cleanAndExit()
6875 except Exception:
6876 main.log.exception( self.name + ": Uncaught exception!" )
6877 main.cleanAndExit()
6878
6879 def onosSecureSSH( self, userName="onos", userPWD="rocks" ):
6880 """
6881 Enables secure access to ONOS console
6882 by removing default users & keys.
6883
6884 bin/onos-user-password onos rocks
6885
6886 Returns: main.TRUE on success and main.FALSE on failure
6887 """
6888
6889 try:
6890 self.handle.sendline( "" )
6891 self.handle.expect( self.dockerPrompt )
6892
6893 self.handle.sendline( "[ ! -f ~/.ssh/id_rsa.pub ] && ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' -q" )
6894 self.handle.expect( self.dockerPrompt )
6895 main.log.debug( "%s: %s%s" % ( self.name, self.handle.before, self.handle.after ) )
6896
6897 self.handle.sendline( "bin/onos-user-key $(id -un) $(cut -d\\\\ -f2 ~/.ssh/id_rsa.pub)" )
6898 self.handle.expect( pexpect.TIMEOUT, timeout=10 )
6899 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
6900
6901 self.handle.sendline( "bin/onos-user-password %s %s" % ( userName, userPWD ) )
6902 i = self.handle.expect( [ "usage",
6903 self.dockerPrompt,
6904 pexpect.TIMEOUT ] )
6905 if i == 0:
6906 # malformed command
6907 main.log.warn( self.name + ": Could not parse onos-user-password command" )
6908 self.handle.expect( self.dockerPrompt )
6909 return main.FALSE
6910 elif i == 1:
6911 # Process started
6912 main.log.info( self.name + ": SSH password added for user " + userName )
6913 return main.TRUE
6914 elif i == 2:
6915 # timeout
6916 main.log.error( self.name + ": Failed to secure onos ssh " )
6917 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
6918 except pexpect.EOF:
6919 main.log.error( self.name + ": EOF exception found" )
6920 main.log.error( self.name + ": " + self.handle.before )
6921 main.cleanAndExit()
6922 except Exception:
6923 main.log.exception( self.name + ": Uncaught exception!" )
6924 main.cleanAndExit()
Jon Hall62ab6752021-08-22 16:47:43 -07006925
6926 def routeAdd( self, prefix, nextHop, jsonFormat=True ):
6927 """
6928 Add a route with the given prefix and nextHop
6929 """
6930 try:
6931 cmdStr = "route-add %s %s %s" % ( "-j" if jsonFormat else "", prefix, nextHop )
6932 handle = self.sendline( cmdStr )
6933 assert handle is not None, "Error in sendline"
6934 assert "Command not found:" not in handle, handle
6935 assert "Unsupported command:" not in handle, handle
6936 assert "Error executing command" not in handle, handle
6937 return handle
6938 except AssertionError:
6939 main.log.exception( "" )
6940 return None
6941 except TypeError:
6942 main.log.exception( self.name + ": Object not as expected" )
6943 return None
6944 except pexpect.EOF:
6945 main.log.error( self.name + ": EOF exception found" )
6946 main.log.error( self.name + ": " + self.handle.before )
6947 main.cleanAndExit()
6948 except Exception:
6949 main.log.exception( self.name + ": Uncaught exception!" )
6950 main.cleanAndExit()
6951
6952 def routeRemove( self, prefix, nextHop, source=None, jsonFormat=True ):
6953 """
6954 Remove a route with the given prefix and nextHop
6955 """
6956 try:
6957 if source:
6958 raise NotImplemented
6959 cmdStr = "route-remove %s %s %s" % ( "-j" if jsonFormat else "", prefix, nextHop )
6960 handle = self.sendline( cmdStr )
6961 assert handle is not None, "Error in sendline"
6962 assert "Command not found:" not in handle, handle
6963 assert "Unsupported command:" not in handle, handle
6964 assert "Error executing command" not in handle, handle
6965 return handle
6966 except AssertionError:
6967 main.log.exception( "" )
6968 return None
6969 except TypeError:
6970 main.log.exception( self.name + ": Object not as expected" )
6971 return None
6972 except pexpect.EOF:
6973 main.log.error( self.name + ": EOF exception found" )
6974 main.log.error( self.name + ": " + self.handle.before )
6975 main.cleanAndExit()
6976 except Exception:
6977 main.log.exception( self.name + ": Uncaught exception!" )
6978 main.cleanAndExit()
6979
6980 def routes( self, jsonFormat=True, args="" ):
6981 """
6982 Get routes from ONOS
6983 """
6984 try:
6985 cmdStr = "routes"
6986 if jsonFormat:
6987 cmdStr = cmdStr + " -j"
6988 handle = self.sendline( cmdStr )
6989 assert handle is not None, "Error in sendline"
6990 assert "Command not found:" not in handle, handle
6991 assert "Unsupported command:" not in handle, handle
6992 assert "Error executing command" not in handle, handle
6993 return handle
6994 except AssertionError:
6995 main.log.exception( "" )
6996 return None
6997 except TypeError:
6998 main.log.exception( self.name + ": Object not as expected" )
6999 return None
7000 except pexpect.EOF:
7001 main.log.error( self.name + ": EOF exception found" )
7002 main.log.error( self.name + ": " + self.handle.before )
7003 main.cleanAndExit()
7004 except Exception:
7005 main.log.exception( self.name + ": Uncaught exception!" )
7006 main.cleanAndExit()