blob: 1e31f31e9f616a6710cd1f1d0938f6e3f956d252 [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
Jon Hall9b0de1f2020-08-24 15:38:04 -070064
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 ]
Jeremy Ronquillo82705492017-10-18 14:19:55 -070090 self.home = self.checkOptions( self.home, "~/onos" )
91 self.karafUser = self.checkOptions( self.karafUser, self.user_name )
92 self.karafPass = self.checkOptions( self.karafPass, self.pwd )
Jon Hall06fd0df2021-01-25 15:50:06 -080093 self.karafPort = self.checkOptions( self.karafPort, 8101 )
Jon Hall3c0114c2020-08-11 15:07:42 -070094 self.dockerPrompt = self.checkOptions( self.dockerPrompt, "~/onos#" )
Jon Hall9b0de1f2020-08-24 15:38:04 -070095 self.karafTimeout = self.checkOptions( self.karafTimeout, 7200000 )
andrewonlab95ce8322014-10-13 14:12:04 -040096
Jon Hall06fd0df2021-01-25 15:50:06 -080097 self.karafPrompt = self.karafUser + "@root >"
98
kelvin-onlaba4074292015-07-09 15:19:49 -070099 for key in self.options:
100 if key == 'onosIp':
101 self.onosIp = self.options[ 'onosIp' ]
102 break
103
kelvin8ec71442015-01-15 16:57:00 -0800104 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -0700105
106 try:
Jon Hallc6793552016-01-19 14:18:37 -0800107 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -0700108 self.ip_address = os.getenv( str( self.ip_address ) )
109 else:
110 main.log.info( self.name +
111 ": Trying to connect to " +
112 self.ip_address )
113
114 except KeyError:
115 main.log.info( "Invalid host name," +
116 " connecting to local host instead" )
117 self.ip_address = 'localhost'
118 except Exception as inst:
119 main.log.error( "Uncaught exception: " + str( inst ) )
120
kelvin8ec71442015-01-15 16:57:00 -0800121 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -0800122 user_name=self.user_name,
123 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -0800124 port=self.port,
125 pwd=self.pwd,
126 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -0400127
kelvin8ec71442015-01-15 16:57:00 -0800128 self.handle.sendline( "cd " + self.home )
Devin Limdc78e202017-06-09 18:30:07 -0700129 self.handle.expect( self.prompt )
andrewonlab95ce8322014-10-13 14:12:04 -0400130 if self.handle:
Jon Hall06fd0df2021-01-25 15:50:06 -0800131 self.address = self.ip_address
andrewonlab95ce8322014-10-13 14:12:04 -0400132 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800133 else:
134 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -0400135 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800136 except TypeError:
137 main.log.exception( self.name + ": Object not as expected" )
138 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400139 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800140 main.log.error( self.name + ": EOF exception found" )
141 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700142 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800143 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800144 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700145 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400146
kelvin8ec71442015-01-15 16:57:00 -0800147 def disconnect( self ):
148 """
andrewonlab95ce8322014-10-13 14:12:04 -0400149 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800150 """
Jon Halld61331b2015-02-17 16:35:47 -0800151 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400152 try:
Jon Hall61282e32015-03-19 11:34:11 -0700153 if self.handle:
154 i = self.logout()
155 if i == main.TRUE:
156 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700157 for l in range( 3 ):
158 p = self.handle.expect( [ self.prompt, self.dockerPrompt ] )
159 if p == 1:
160 self.inDocker = False
161 self.handle.sendline( "exit" )
162 j = self.handle.expect( [ "closed", pexpect.TIMEOUT ], timeout=3 )
163 if j == 0:
164 return response
165 response = main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800166 except TypeError:
167 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800168 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400169 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800170 main.log.error( self.name + ": EOF exception found" )
171 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700172 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700173 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700174 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800175 except Exception:
Jon Hall3c0114c2020-08-11 15:07:42 -0700176 main.log.exception( self.name + ": disconnection failed from the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400177 response = main.FALSE
178 return response
179
kelvin8ec71442015-01-15 16:57:00 -0800180 def logout( self ):
181 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500182 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700183 Returns main.TRUE if exited CLI and
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000184 main.FALSE on timeout (not guranteed you are disconnected)
Jon Hall61282e32015-03-19 11:34:11 -0700185 None on TypeError
186 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800187 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500188 try:
Jon Hall61282e32015-03-19 11:34:11 -0700189 if self.handle:
190 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700191 i = self.handle.expect( [ self.karafPrompt,
192 self.Prompt(),
193 pexpect.TIMEOUT ],
194
Jon Hall61282e32015-03-19 11:34:11 -0700195 timeout=10 )
196 if i == 0: # In ONOS CLI
197 self.handle.sendline( "logout" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700198 j = self.handle.expect( [ self.Prompt(),
Jon Hallbfe00002016-04-05 10:23:54 -0700199 "Command not found:",
200 pexpect.TIMEOUT ] )
201 if j == 0: # Successfully logged out
202 return main.TRUE
203 elif j == 1 or j == 2:
204 # ONOS didn't fully load, and logout command isn't working
205 # or the command timed out
206 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700207 try:
Jon Hall3c0114c2020-08-11 15:07:42 -0700208 self.handle.expect( self.Prompt() )
Jon Hall64ab3bd2016-05-13 11:29:44 -0700209 except pexpect.TIMEOUT:
210 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700211 return main.TRUE
Jon Halle0f0b342017-04-18 11:43:47 -0700212 else: # some other output
Jon Hallbfe00002016-04-05 10:23:54 -0700213 main.log.warn( "Unknown repsonse to logout command: '{}'",
214 repr( self.handle.before ) )
215 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700216 elif i == 1: # not in CLI
217 return main.TRUE
steven30801e42f1fb2019-01-17 11:31:45 +0800218 elif i == 2: # Timeout
Jon Hall61282e32015-03-19 11:34:11 -0700219 return main.FALSE
220 else:
andrewonlab9627f432014-11-14 12:45:10 -0500221 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800222 except TypeError:
223 main.log.exception( self.name + ": Object not as expected" )
224 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500225 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800226 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700227 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700228 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700229 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700230 main.log.error( self.name +
231 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800232 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800233 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700234 main.cleanAndExit()
andrewonlab38d2b4a2014-11-13 16:28:47 -0500235
kelvin-onlabd3b64892015-01-20 13:26:24 -0800236 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800237 """
andrewonlab95ce8322014-10-13 14:12:04 -0400238 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800239
andrewonlab95ce8322014-10-13 14:12:04 -0400240 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800241 """
andrewonlab95ce8322014-10-13 14:12:04 -0400242 try:
243 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800244 main.log.error( "Must define cellname" )
Devin Lim44075962017-08-11 10:56:37 -0700245 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400246 else:
kelvin8ec71442015-01-15 16:57:00 -0800247 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800248 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800249 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400250 # and that this driver will have to change accordingly
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700251 self.handle.expect( str( cellname ) )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800252 handleBefore = self.handle.before
253 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800254 # Get the rest of the handle
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700255 self.handle.sendline( "" )
256 self.handle.expect( self.prompt )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800257 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400258
kelvin-onlabd3b64892015-01-20 13:26:24 -0800259 main.log.info( "Cell call returned: " + handleBefore +
260 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400261
262 return main.TRUE
263
Jon Halld4d4b372015-01-28 16:02:41 -0800264 except TypeError:
265 main.log.exception( self.name + ": Object not as expected" )
266 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400267 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800268 main.log.error( self.name + ": eof exception found" )
269 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700270 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800271 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800272 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700273 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -0800274
pingping-lin57a56ce2015-05-20 16:43:48 -0700275 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800276 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800277 """
Jon Hallefbd9792015-03-05 16:11:36 -0800278 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800279 by user would be used to set the current karaf shell idle timeout.
280 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800281 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800282 Below is an example to start a session with 60 seconds idle timeout
283 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800284
Hari Krishna25d42f72015-01-05 15:08:28 -0800285 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800286 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800287
kelvin-onlabd3b64892015-01-20 13:26:24 -0800288 Note: karafTimeout is left as str so that this could be read
289 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800290 """
You Wangf69ab392016-01-26 16:34:38 -0800291 self.onosIp = ONOSIp
Jon Hall06fd0df2021-01-25 15:50:06 -0800292 self.address = self.onosIp
andrewonlab95ce8322014-10-13 14:12:04 -0400293 try:
Jon Hall67253832016-12-05 09:47:13 -0800294 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800295 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700296 x = self.handle.expect( [ self.Prompt(), self.karafPrompt ], commandlineTimeout )
andrewonlab48829f62014-11-17 13:49:01 -0500297 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800298 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500299 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400300
Jon Hall67253832016-12-05 09:47:13 -0800301 # Not in CLI so login
Jon Hall3c0114c2020-08-11 15:07:42 -0700302 if self.inDocker:
303 # The Docker does not have all the wrapper scripts
Jon Hall06fd0df2021-01-25 15:50:06 -0800304 startCliCommand = "ssh -p %s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null %s@localhost" % ( self.karafPort, self.karafUser )
Jon Hall3c0114c2020-08-11 15:07:42 -0700305 elif waitForStart:
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800306 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
Jon Hall3c0114c2020-08-11 15:07:42 -0700307 startCliCommand = "onos-wait-for-start " + str( ONOSIp )
Chiyu Chengef109502016-11-21 15:51:38 -0800308 else:
Jon Hall3c0114c2020-08-11 15:07:42 -0700309 startCliCommand = "onos " + str( ONOSIp )
310 self.handle.sendline( startCliCommand )
311 tries = 0
Jon Hallf69e3162020-09-01 09:08:44 -0700312 timeoutSet = False
Jon Hall3c0114c2020-08-11 15:07:42 -0700313 while tries < 5:
314 i = self.handle.expect( [
315 self.karafPrompt,
316 "Password:",
317 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400318
andrewonlab3a7c3c72014-10-24 17:21:03 -0400319 if i == 0:
Jon Hallf69e3162020-09-01 09:08:44 -0700320 if not karafTimeout or timeoutSet:
Jon Hall9b0de1f2020-08-24 15:38:04 -0700321 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
322 return main.TRUE
Hari Krishnae36ef212015-01-04 14:09:13 -0800323 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800324 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800325 "config:property-set -p org.apache.karaf.shell\
Jon Hall3c0114c2020-08-11 15:07:42 -0700326 sshIdleTimeout " +
Jon Hall9b0de1f2020-08-24 15:38:04 -0700327 str( karafTimeout ) )
328 self.handle.expect( "closed by remote host" )
Jon Hallf69e3162020-09-01 09:08:44 -0700329 self.handle.expect( self.Prompt() )
Jon Hall9b0de1f2020-08-24 15:38:04 -0700330 self.handle.sendline( startCliCommand )
Jon Hallf69e3162020-09-01 09:08:44 -0700331 timeoutSet = True
Jon Hall3c0114c2020-08-11 15:07:42 -0700332 elif i == 1:
333 main.log.info( str( ONOSIp ) + " CLI asking for password" )
334 main.log.debug( "Sending %s" % self.karafPass )
335 self.handle.sendline( self.karafPass )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400336 else:
Jon Hall3c0114c2020-08-11 15:07:42 -0700337 # If failed, send ctrl+c to process and try again
338 main.log.info( "Starting CLI failed. Retrying..." )
Jon Hallf69e3162020-09-01 09:08:44 -0700339 time.sleep( 5 )
Jon Hall3c0114c2020-08-11 15:07:42 -0700340 self.handle.send( "\x03" )
341 self.handle.sendline( startCliCommand )
342 tries += 1
343 main.log.error( "Connection to CLI " + str( ONOSIp ) + " timeout" )
344 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800345 except TypeError:
346 main.log.exception( self.name + ": Object not as expected" )
347 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400348 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800349 main.log.error( self.name + ": EOF exception found" )
350 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700351 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800352 except Exception:
Jon Hall06fd0df2021-01-25 15:50:06 -0800353 main.log.debug( self.handle.before + str( self.handle.after ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800354 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700355 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400356
suibin zhang116647a2016-05-06 16:30:09 -0700357 def startCellCli( self, karafTimeout="",
358 commandlineTimeout=10, onosStartTimeout=60 ):
359 """
Jon Hall3c0114c2020-08-11 15:07:42 -0700360 Start CLI on onos cell handle.
suibin zhang116647a2016-05-06 16:30:09 -0700361
362 karafTimeout is an optional argument. karafTimeout value passed
363 by user would be used to set the current karaf shell idle timeout.
364 Note that when ever this property is modified the shell will exit and
365 the subsequent login would reflect new idle timeout.
366 Below is an example to start a session with 60 seconds idle timeout
367 ( input value is in milliseconds ):
368
369 tValue = "60000"
370
371 Note: karafTimeout is left as str so that this could be read
372 and passed to startOnosCli from PARAMS file as str.
373 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000374
suibin zhang116647a2016-05-06 16:30:09 -0700375 try:
376 self.handle.sendline( "" )
377 x = self.handle.expect( [
Jon Hall3c0114c2020-08-11 15:07:42 -0700378 self.Prompt(), self.karafPrompt ], commandlineTimeout )
suibin zhang116647a2016-05-06 16:30:09 -0700379
380 if x == 1:
381 main.log.info( "ONOS cli is already running" )
382 return main.TRUE
383
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800384 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
suibin zhang116647a2016-05-06 16:30:09 -0700385 self.handle.sendline( "/opt/onos/bin/onos" )
386 i = self.handle.expect( [
Jon Hall6c9e2da2018-11-06 12:01:23 -0800387 self.karafPrompt,
suibin zhang116647a2016-05-06 16:30:09 -0700388 pexpect.TIMEOUT ], onosStartTimeout )
389
390 if i == 0:
391 main.log.info( self.name + " CLI Started successfully" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800392 if karafTimeout: # FIXME: This doesn't look right
suibin zhang116647a2016-05-06 16:30:09 -0700393 self.handle.sendline(
394 "config:property-set -p org.apache.karaf.shell\
395 sshIdleTimeout " +
396 karafTimeout )
Jon Hall3c0114c2020-08-11 15:07:42 -0700397 self.handle.expect( self.Prompt() )
suibin zhang116647a2016-05-06 16:30:09 -0700398 self.handle.sendline( "/opt/onos/bin/onos" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800399 self.handle.expect( self.karafPrompt )
suibin zhang116647a2016-05-06 16:30:09 -0700400 return main.TRUE
401 else:
402 # If failed, send ctrl+c to process and try again
403 main.log.info( "Starting CLI failed. Retrying..." )
404 self.handle.send( "\x03" )
405 self.handle.sendline( "/opt/onos/bin/onos" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800406 i = self.handle.expect( [ self.karafPrompt, pexpect.TIMEOUT ],
suibin zhang116647a2016-05-06 16:30:09 -0700407 timeout=30 )
408 if i == 0:
409 main.log.info( self.name + " CLI Started " +
410 "successfully after retry attempt" )
411 if karafTimeout:
412 self.handle.sendline(
413 "config:property-set -p org.apache.karaf.shell\
414 sshIdleTimeout " +
415 karafTimeout )
Jon Hall3c0114c2020-08-11 15:07:42 -0700416 self.handle.expect( self.Prompt() )
suibin zhang116647a2016-05-06 16:30:09 -0700417 self.handle.sendline( "/opt/onos/bin/onos" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800418 self.handle.expect( self.karafPrompt )
suibin zhang116647a2016-05-06 16:30:09 -0700419 return main.TRUE
420 else:
421 main.log.error( "Connection to CLI " +
422 self.name + " timeout" )
423 return main.FALSE
424
425 except TypeError:
426 main.log.exception( self.name + ": Object not as expected" )
427 return None
428 except pexpect.EOF:
429 main.log.error( self.name + ": EOF exception found" )
430 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700431 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700432 except Exception:
433 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700434 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700435
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800436 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800437 """
438 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800439 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800440 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700441 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800442 Available level: DEBUG, TRACE, INFO, WARN, ERROR
443 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800444 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800445 """
446 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800447 lvlStr = ""
448 if level:
449 lvlStr = "--level=" + level
450
kelvin-onlab338f5512015-02-06 10:53:16 -0800451 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700452 self.handle.expect( "log:log" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800453 self.handle.expect( self.karafPrompt )
kelvin-onlabfb521662015-02-27 09:52:40 -0800454
kelvin-onlab9f541032015-02-04 16:19:53 -0800455 response = self.handle.before
456 if re.search( "Error", response ):
Jon Halldac3eae2020-06-05 12:04:06 -0700457 main.log.debug( response )
kelvin-onlab9f541032015-02-04 16:19:53 -0800458 return main.FALSE
459 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700460 except pexpect.TIMEOUT:
461 main.log.exception( self.name + ": TIMEOUT exception found" )
Jon Hall43060f62020-06-23 13:13:33 -0700462 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700463 if noExit:
464 main.cleanup()
465 return None
466 else:
Devin Lim44075962017-08-11 10:56:37 -0700467 main.cleanAndExit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800468 except pexpect.EOF:
469 main.log.error( self.name + ": EOF exception found" )
470 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700471 if noExit:
472 main.cleanup()
473 return None
474 else:
Devin Lim44075962017-08-11 10:56:37 -0700475 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800476 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800477 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700478 if noExit:
479 main.cleanup()
480 return None
481 else:
Devin Lim44075962017-08-11 10:56:37 -0700482 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400483
Jon Hall0e240372018-05-02 11:21:57 -0700484 def clearBuffer( self, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800485 """
Jon Hall0e240372018-05-02 11:21:57 -0700486 Test cli connection and clear any left over output in the buffer
487 Optional Arguments:
488 debug - Defaults to False. If True, will enable debug logging.
489 timeout - Defaults to 10. Amount of time in seconds for a command to return
490 before a timeout.
491 noExit - Defaults to False. If True, will not exit TestON in the event of a
kelvin8ec71442015-01-15 16:57:00 -0800492 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400493 try:
Jon Halla495f562016-05-16 18:03:26 -0700494 # Try to reconnect if disconnected from cli
495 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700496 i = self.handle.expect( [ self.karafPrompt,
497 self.Prompt(),
498 pexpect.TIMEOUT ] )
Jon Hall0e240372018-05-02 11:21:57 -0700499 response = self.handle.before
Jon Halla495f562016-05-16 18:03:26 -0700500 if i == 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700501 main.log.error( self.name + ": onos cli session closed. " )
Jon Halla495f562016-05-16 18:03:26 -0700502 if self.onosIp:
503 main.log.warn( "Trying to reconnect " + self.onosIp )
504 reconnectResult = self.startOnosCli( self.onosIp )
505 if reconnectResult:
506 main.log.info( self.name + ": onos cli session reconnected." )
507 else:
508 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700509 if noExit:
510 return None
511 else:
Devin Lim44075962017-08-11 10:56:37 -0700512 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700513 else:
Devin Lim44075962017-08-11 10:56:37 -0700514 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700515 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700516 main.log.warn( "Timeout when testing cli responsiveness" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700517 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700518 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Hall6c9e2da2018-11-06 12:01:23 -0800519 self.handle.expect( self.karafPrompt )
Jon Halla495f562016-05-16 18:03:26 -0700520
Jon Hall0e240372018-05-02 11:21:57 -0700521 response += self.handle.before
Jon Hall14a03b52016-05-11 12:07:30 -0700522 if debug:
Jon Hall0e240372018-05-02 11:21:57 -0700523 main.log.debug( self.name + ": Raw output from sending ''" )
524 main.log.debug( self.name + ": " + repr( response ) )
525 except pexpect.TIMEOUT:
526 main.log.error( self.name + ": ONOS timeout" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700527 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
You Wang141b43b2018-06-26 16:50:18 -0700528 self.handle.send( "\x03" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800529 self.handle.expect( self.karafPrompt )
Jon Hall0e240372018-05-02 11:21:57 -0700530 return None
531 except pexpect.EOF:
532 main.log.error( self.name + ": EOF exception found" )
533 main.log.error( self.name + ": " + self.handle.before )
534 if noExit:
535 return None
536 else:
537 main.cleanAndExit()
538 except Exception:
539 main.log.exception( self.name + ": Uncaught exception!" )
540 if noExit:
541 return None
542 else:
543 main.cleanAndExit()
544
Jon Hall22e94ce2019-01-15 14:52:17 -0800545 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True, expectJson=False ):
Jon Hall0e240372018-05-02 11:21:57 -0700546 """
547 A wrapper around pexpect's sendline/expect. Will return all the output from a given command
548
549 Required Arguments:
550 cmdStr - String to send to the pexpect session
551
552 Optional Arguments:
553 showResponse - Defaults to False. If True will log the response.
554 debug - Defaults to False. If True, will enable debug logging.
555 timeout - Defaults to 10. Amount of time in seconds for a command to return
556 before a timeout.
557 noExit - Defaults to False. If True, will not exit TestON in the event of a
558 closed channel, but instead return None
Jon Hall6c9e2da2018-11-06 12:01:23 -0800559 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 -0700560
561 Warning: There are no sanity checking to commands sent using this method.
562
563 """
564 try:
565 # Try to reconnect if disconnected from cli
566 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
567 if debug:
568 # NOTE: This adds an average of .4 seconds per call
Jon Hall14a03b52016-05-11 12:07:30 -0700569 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700570 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800571 self.handle.sendline( cmdStr )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800572 self.handle.expect( self.karafPrompt, timeout )
Jon Hall63604932015-02-26 17:09:50 -0800573 response = self.handle.before
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000574 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
Jon Hallc6793552016-01-19 14:18:37 -0800575 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700576 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700577 main.log.debug( self.name + ": Raw output" )
578 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700579
Jon Hall3c0114c2020-08-11 15:07:42 -0700580 response = self.cleanOutput( response, debug=debug )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800581 # Remove control codes from karaf 4.2.1
Jon Hall3c0114c2020-08-11 15:07:42 -0700582 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 -0800583 response = karafEscape.sub( '', response )
584 if debug:
585 main.log.debug( self.name + ": karafEscape output" )
586 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700587 # Remove ANSI color control strings from output
Jon Hall43060f62020-06-23 13:13:33 -0700588 response = self.cleanOutput( response, debug )
Jon Hallc6358dd2015-04-10 12:44:28 -0700589
Jon Hall6c9e2da2018-11-06 12:01:23 -0800590 # Remove ANSI color control strings from output
Jon Hallcf31d0f2018-12-13 11:18:48 -0800591 # NOTE: karaf is sometimes adding a single character then two
592 # backspaces and sometimes adding 2 characters with 2 backspaces??
Jon Hall3c0114c2020-08-11 15:07:42 -0700593 backspaceEscape = re.compile( r'((.|\s)\x08)' )
594 unchanged = False
595 while not unchanged:
596 old = response
597 response = backspaceEscape.sub( '', response, count=1 )
598 if debug:
599 main.log.debug( self.name + ": backspaceEscape output" )
600 main.log.debug( self.name + ": " + repr( response ) )
601 unchanged = old == response
Jon Hall6c9e2da2018-11-06 12:01:23 -0800602
kelvin-onlabfb521662015-02-27 09:52:40 -0800603 # Remove extra return chars that get added
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000604 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700605 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700606 main.log.debug( self.name + ": Removed extra returns " +
607 "from output" )
608 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700609
610 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800611 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700612 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700613 main.log.debug( self.name + ": parsed and stripped output" )
614 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700615
Jon Hall63604932015-02-26 17:09:50 -0800616 # parse for just the output, remove the cmd from response
Jon Hallce0d70b2018-12-11 11:01:32 -0800617 cmdPattern = cmdStr.strip()
618 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
619 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800620 if relaxedRegex:
Jon Hallce0d70b2018-12-11 11:01:32 -0800621 cmdPattern = cmdPattern.split( '|' )[ -1 ].strip()
622 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
623 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800624 # This was added because karaf 4.2 is stripping some characters from the command echo
Jon Hallce0d70b2018-12-11 11:01:32 -0800625 output = response.split( cmdPattern, 1 )
Jon Hall22e94ce2019-01-15 14:52:17 -0800626 if expectJson:
627 main.log.warn( "Relaxed Regex: Searching for a json string amongst the output" )
628 jsonPattern = r'\{.*\}'
629 match = re.search( jsonPattern, output[ 0 ] )
630 if match:
631 output = [ '' , match.group( 0 ) ] # We expect a list with the second element to be the output
Jon Hall39e3ffe2018-12-05 11:40:29 -0800632 if len( output ) < 2:
633 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800634 cmdPattern = cmdPattern[ -5: ]
635 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
636 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
637 output = response.split( cmdPattern, 1 )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800638 else:
Jon Hallce0d70b2018-12-11 11:01:32 -0800639 output = response.split( cmdPattern, 1 )
640 if len( output ) < 2: # TODO: Should we do this without the relaxedRegex flag?
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800641 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800642 output = response.split( cmdPattern[ -5: ], 1 )
Jon Hall0e240372018-05-02 11:21:57 -0700643 if output:
644 if debug:
645 main.log.debug( self.name + ": split output" )
646 for r in output:
647 main.log.debug( self.name + ": " + repr( r ) )
Jon Hallce0d70b2018-12-11 11:01:32 -0800648 if len( output ) == 1:
649 main.log.error( "Could not remove sent command echo from output" )
650 return output
Jon Hall0e240372018-05-02 11:21:57 -0700651 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800652 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800653 main.log.info( "Response from ONOS: {}".format( output ) )
Jon Hall0e240372018-05-02 11:21:57 -0700654 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
GlennRC85870432015-11-23 11:45:51 -0800655 return output
GlennRCed771242016-01-13 17:02:47 -0800656 except pexpect.TIMEOUT:
Jon Hall0e240372018-05-02 11:21:57 -0700657 main.log.error( self.name + ": ONOS timeout" )
GlennRCed771242016-01-13 17:02:47 -0800658 if debug:
Jon Hall3c0114c2020-08-11 15:07:42 -0700659 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
You Wang6b5e5ba2019-01-31 15:32:40 -0800660 self.exitFromCmd( self.karafPrompt, 100 )
GlennRCed771242016-01-13 17:02:47 -0800661 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700662 except IndexError:
663 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700664 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700665 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800666 except TypeError:
667 main.log.exception( self.name + ": Object not as expected" )
668 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400669 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800670 main.log.error( self.name + ": EOF exception found" )
671 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700672 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700673 return None
674 else:
Devin Lim44075962017-08-11 10:56:37 -0700675 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800676 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800677 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700678 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700679 return None
680 else:
Devin Lim44075962017-08-11 10:56:37 -0700681 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400682
Jon Halld5a94fb2018-11-13 14:32:23 -0800683 def lineCount( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True ):
684 """
685 A wrapper around sendline(). Will return the number of lines returned or None on error
686
687 Required Arguments:
688 cmdStr - String to send to the pexpect session
689
690 Optional Arguments:
691 showResponse - Defaults to False. If True will log the response.
692 debug - Defaults to False. If True, will enable debug logging.
693 timeout - Defaults to 10. Amount of time in seconds for a command to return
694 before a timeout.
695 noExit - Defaults to False. If True, will not exit TestON in the event of a
696 closed channel, but instead return None
697 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.
698
699 Warning: There are no sanity checking to commands sent using this method.
700
701 """
702 try:
703 numLines = self.sendline( cmdStr, showResponse, debug, timeout, noExit, relaxedRegex )
You Wang0ce8e0c2019-02-22 12:22:26 -0800704 parsed = re.search( "(\d+)", numLines )
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800705 if not parsed:
706 main.log.error( "Warning, output of karaf's wc may have changed" )
707 return None
708 return parsed.group( 1 )
Jon Halld5a94fb2018-11-13 14:32:23 -0800709 except IndexError:
710 main.log.exception( self.name + ": Object not as expected" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800711 main.log.debug( "response: {}".format( repr( numLines ) ) )
Jon Halld5a94fb2018-11-13 14:32:23 -0800712 return None
713 except TypeError:
714 main.log.exception( self.name + ": Object not as expected" )
715 return None
716 except Exception:
717 main.log.exception( self.name + ": Uncaught exception!" )
718 if noExit:
719 return None
720 else:
721 main.cleanAndExit()
722
kelvin8ec71442015-01-15 16:57:00 -0800723 # IMPORTANT NOTE:
724 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800725 # the cli command changing 'a:b' with 'aB'.
726 # Ex ) onos:topology > onosTopology
727 # onos:links > onosLinks
728 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800729
kelvin-onlabd3b64892015-01-20 13:26:24 -0800730 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800731 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400732 Adds a new cluster node by ID and address information.
733 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800734 * nodeId
735 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400736 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800737 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800738 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400739 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800740 cmdStr = "add-node " + str( nodeId ) + " " +\
741 str( ONOSIp ) + " " + str( tcpPort )
742 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700743 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800744 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800745 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700746 main.log.error( self.name + ": Error in adding node" )
kelvin8ec71442015-01-15 16:57:00 -0800747 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800748 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400749 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800750 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400751 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800752 except AssertionError:
753 main.log.exception( "" )
754 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800755 except TypeError:
756 main.log.exception( self.name + ": Object not as expected" )
757 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400758 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800759 main.log.error( self.name + ": EOF exception found" )
760 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700761 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800762 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800763 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700764 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400765
kelvin-onlabd3b64892015-01-20 13:26:24 -0800766 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800767 """
andrewonlab86dc3082014-10-13 18:18:38 -0400768 Removes a cluster by ID
769 Issues command: 'remove-node [<node-id>]'
770 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800771 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800772 """
andrewonlab86dc3082014-10-13 18:18:38 -0400773 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400774
kelvin-onlabd3b64892015-01-20 13:26:24 -0800775 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700776 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700777 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800778 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700779 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700780 main.log.error( self.name + ": Error in removing node" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700781 main.log.error( handle )
782 return main.FALSE
783 else:
784 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800785 except AssertionError:
786 main.log.exception( "" )
787 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800788 except TypeError:
789 main.log.exception( self.name + ": Object not as expected" )
790 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400791 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800792 main.log.error( self.name + ": EOF exception found" )
793 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700794 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800795 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800796 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700797 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400798
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700799 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800800 """
andrewonlab7c211572014-10-15 16:45:20 -0400801 List the nodes currently visible
802 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700803 Optional argument:
804 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800805 """
andrewonlab7c211572014-10-15 16:45:20 -0400806 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700807 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700808 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700809 cmdStr += " -j"
810 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700811 assert output is not None, "Error in sendline"
Jon Halle37bd1f2020-09-10 12:16:41 -0700812 # "Command not found" or "Service org.onosproject.security.AuditService not found"
813 assert "not found" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700814 return output
Jon Hallc6793552016-01-19 14:18:37 -0800815 except AssertionError:
816 main.log.exception( "" )
817 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800818 except TypeError:
819 main.log.exception( self.name + ": Object not as expected" )
820 return None
andrewonlab7c211572014-10-15 16:45:20 -0400821 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800822 main.log.error( self.name + ": EOF exception found" )
823 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700824 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800825 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800826 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700827 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400828
kelvin8ec71442015-01-15 16:57:00 -0800829 def topology( self ):
830 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700831 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700832 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700833 Return:
834 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800835 """
andrewonlab95ce8322014-10-13 14:12:04 -0400836 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700837 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800838 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800839 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800840 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700841 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400842 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800843 except AssertionError:
844 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800845 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800846 except TypeError:
847 main.log.exception( self.name + ": Object not as expected" )
848 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400849 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800850 main.log.error( self.name + ": EOF exception found" )
851 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700852 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800853 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800854 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700855 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800856
jenkins7ead5a82015-03-13 10:28:21 -0700857 def deviceRemove( self, deviceId ):
858 """
859 Removes particular device from storage
860
861 TODO: refactor this function
862 """
863 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700864 cmdStr = "device-remove " + str( deviceId )
865 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800866 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800867 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700868 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700869 main.log.error( self.name + ": Error in removing device" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700870 main.log.error( handle )
871 return main.FALSE
872 else:
873 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800874 except AssertionError:
875 main.log.exception( "" )
876 return None
jenkins7ead5a82015-03-13 10:28:21 -0700877 except TypeError:
878 main.log.exception( self.name + ": Object not as expected" )
879 return None
880 except pexpect.EOF:
881 main.log.error( self.name + ": EOF exception found" )
882 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700883 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700884 except Exception:
885 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700886 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700887
You Wang3b9689a2018-08-30 12:24:00 -0700888 def devices( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800889 """
Jon Hall7b02d952014-10-17 20:14:54 -0400890 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400891 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800892 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800893 """
andrewonlab86dc3082014-10-13 18:18:38 -0400894 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700895 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800896 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700897 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700898 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800899 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800900 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700901 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800902 except AssertionError:
903 main.log.exception( "" )
904 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800905 except TypeError:
906 main.log.exception( self.name + ": Object not as expected" )
907 return None
andrewonlab7c211572014-10-15 16:45:20 -0400908 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800909 main.log.error( self.name + ": EOF exception found" )
910 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700911 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800912 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800913 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700914 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400915
kelvin-onlabd3b64892015-01-20 13:26:24 -0800916 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800917 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800918 This balances the devices across all controllers
919 by issuing command: 'onos> onos:balance-masters'
920 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800921 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800922 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800923 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700924 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800925 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800926 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700927 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700928 main.log.error( self.name + ": Error in balancing masters" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700929 main.log.error( handle )
930 return main.FALSE
931 else:
932 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800933 except AssertionError:
934 main.log.exception( "" )
935 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800936 except TypeError:
937 main.log.exception( self.name + ": Object not as expected" )
938 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800939 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800940 main.log.error( self.name + ": EOF exception found" )
941 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700942 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800943 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800944 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700945 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800946
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000947 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700948 """
949 Returns the output of the masters command.
950 Optional argument:
951 * jsonFormat - boolean indicating if you want output in json
952 """
953 try:
954 cmdStr = "onos:masters"
955 if jsonFormat:
956 cmdStr += " -j"
957 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700958 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800959 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700960 return output
Jon Hallc6793552016-01-19 14:18:37 -0800961 except AssertionError:
962 main.log.exception( "" )
963 return None
acsmars24950022015-07-30 18:00:43 -0700964 except TypeError:
965 main.log.exception( self.name + ": Object not as expected" )
966 return None
967 except pexpect.EOF:
968 main.log.error( self.name + ": EOF exception found" )
969 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700970 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700971 except Exception:
972 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700973 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700974
Jon Hallc6793552016-01-19 14:18:37 -0800975 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700976 """
977 Uses the master command to check that the devices' leadership
978 is evenly divided
979
980 Dependencies: checkMasters() and summary()
981
Jon Hall6509dbf2016-06-21 17:01:17 -0700982 Returns main.TRUE if the devices are balanced
983 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700984 Exits on Exception
985 Returns None on TypeError
986 """
987 try:
Jon Hallc6793552016-01-19 14:18:37 -0800988 summaryOutput = self.summary()
989 totalDevices = json.loads( summaryOutput )[ "devices" ]
990 except ( TypeError, ValueError ):
991 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
992 return None
993 try:
acsmars24950022015-07-30 18:00:43 -0700994 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800995 mastersOutput = self.checkMasters()
996 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700997 first = masters[ 0 ][ "size" ]
998 for master in masters:
999 totalOwnedDevices += master[ "size" ]
1000 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
1001 main.log.error( "Mastership not balanced" )
1002 main.log.info( "\n" + self.checkMasters( False ) )
1003 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -07001004 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001005 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -07001006 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001007 except ( TypeError, ValueError ):
1008 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -07001009 return None
1010 except pexpect.EOF:
1011 main.log.error( self.name + ": EOF exception found" )
1012 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001013 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -07001014 except Exception:
1015 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001016 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -07001017
YPZhangfebf7302016-05-24 16:45:56 -07001018 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -08001019 """
Jon Halle8217482014-10-17 13:49:14 -04001020 Lists all core links
1021 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001022 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001023 """
Jon Halle8217482014-10-17 13:49:14 -04001024 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001025 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001026 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001027 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07001028 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001029 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001030 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001031 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001032 except AssertionError:
1033 main.log.exception( "" )
1034 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001035 except TypeError:
1036 main.log.exception( self.name + ": Object not as expected" )
1037 return None
Jon Halle8217482014-10-17 13:49:14 -04001038 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001039 main.log.error( self.name + ": EOF exception found" )
1040 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001041 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001042 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001043 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001044 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001045
You Wang3b9689a2018-08-30 12:24:00 -07001046 def ports( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -08001047 """
Jon Halle8217482014-10-17 13:49:14 -04001048 Lists all ports
1049 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001050 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001051 """
Jon Halle8217482014-10-17 13:49:14 -04001052 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001053 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001054 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001055 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -07001056 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001057 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001058 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001059 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001060 except AssertionError:
1061 main.log.exception( "" )
1062 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001063 except TypeError:
1064 main.log.exception( self.name + ": Object not as expected" )
1065 return None
Jon Halle8217482014-10-17 13:49:14 -04001066 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001067 main.log.error( self.name + ": EOF exception found" )
1068 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001069 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001070 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001071 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001072 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001073
kelvin-onlabd3b64892015-01-20 13:26:24 -08001074 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001075 """
Jon Hall983a1702014-10-28 18:44:22 -04001076 Lists all devices and the controllers with roles assigned to them
1077 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001078 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001079 """
andrewonlab7c211572014-10-15 16:45:20 -04001080 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001081 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001082 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001083 cmdStr += " -j"
1084 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001085 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001086 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001087 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001088 except AssertionError:
1089 main.log.exception( "" )
1090 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001091 except TypeError:
1092 main.log.exception( self.name + ": Object not as expected" )
1093 return None
Jon Hall983a1702014-10-28 18:44:22 -04001094 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001095 main.log.error( self.name + ": EOF exception found" )
1096 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001097 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001098 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001099 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001100 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -04001101
kelvin-onlabd3b64892015-01-20 13:26:24 -08001102 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001103 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001104 Given the a string containing the json representation of the "roles"
1105 cli command and a partial or whole device id, returns a json object
1106 containing the roles output for the first device whose id contains
1107 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -04001108
1109 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -08001110 A dict of the role assignments for the given device or
1111 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001112 """
Jon Hall983a1702014-10-28 18:44:22 -04001113 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001114 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001115 return None
1116 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001117 rawRoles = self.roles()
1118 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001119 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001120 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001121 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001122 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001123 return device
1124 return None
Jon Hallc6793552016-01-19 14:18:37 -08001125 except ( TypeError, ValueError ):
1126 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001127 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001128 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001129 main.log.error( self.name + ": EOF exception found" )
1130 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001131 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001132 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001133 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001134 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001135
kelvin-onlabd3b64892015-01-20 13:26:24 -08001136 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001137 """
Jon Hall94fd0472014-12-08 11:52:42 -08001138 Iterates through each device and checks if there is a master assigned
1139 Returns: main.TRUE if each device has a master
1140 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001141 """
Jon Hall94fd0472014-12-08 11:52:42 -08001142 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001143 rawRoles = self.roles()
1144 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001145 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001146 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001147 # print device
1148 if device[ 'master' ] == "none":
1149 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001150 return main.FALSE
1151 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001152 except ( TypeError, ValueError ):
1153 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001154 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001155 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001156 main.log.error( self.name + ": EOF exception found" )
1157 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001158 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001159 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001160 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001161 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001162
kelvin-onlabd3b64892015-01-20 13:26:24 -08001163 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001164 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001165 Returns string of paths, and the cost.
1166 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001167 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001168 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001169 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1170 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001171 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001172 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001173 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001174 main.log.error( self.name + ": Error in getting paths" )
kelvin8ec71442015-01-15 16:57:00 -08001175 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001176 else:
kelvin8ec71442015-01-15 16:57:00 -08001177 path = handle.split( ";" )[ 0 ]
1178 cost = handle.split( ";" )[ 1 ]
1179 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001180 except AssertionError:
1181 main.log.exception( "" )
1182 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001183 except TypeError:
1184 main.log.exception( self.name + ": Object not as expected" )
1185 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001186 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001187 main.log.error( self.name + ": EOF exception found" )
1188 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001189 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001190 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001191 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001192 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001193
kelvin-onlabd3b64892015-01-20 13:26:24 -08001194 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001195 """
Jon Hallffb386d2014-11-21 13:43:38 -08001196 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001197 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001198 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001199 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001200 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001201 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001202 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001203 cmdStr += " -j"
1204 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001205 if handle:
1206 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001207 # TODO: Maybe make this less hardcoded
1208 # ConsistentMap Exceptions
1209 assert "org.onosproject.store.service" not in handle
1210 # Node not leader
1211 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001212 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001213 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07001214 main.log.exception( self.name + ": Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001215 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001216 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001217 except TypeError:
1218 main.log.exception( self.name + ": Object not as expected" )
1219 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001220 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001221 main.log.error( self.name + ": EOF exception found" )
1222 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001223 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001224 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001225 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001226 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001227
kelvin-onlabd3b64892015-01-20 13:26:24 -08001228 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001229 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001230 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001231
Jon Hallefbd9792015-03-05 16:11:36 -08001232 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001233 partial mac address
1234
Jon Hall42db6dc2014-10-24 19:03:48 -04001235 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001236 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001237 try:
kelvin8ec71442015-01-15 16:57:00 -08001238 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001239 return None
1240 else:
1241 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001242 rawHosts = self.hosts()
1243 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001244 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001245 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001246 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001247 if not host:
1248 pass
1249 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001250 return host
1251 return None
Jon Hallc6793552016-01-19 14:18:37 -08001252 except ( TypeError, ValueError ):
1253 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001254 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001255 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001256 main.log.error( self.name + ": EOF exception found" )
1257 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001258 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001259 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001260 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001261 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001262
kelvin-onlabd3b64892015-01-20 13:26:24 -08001263 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001264 """
1265 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001266 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001267
andrewonlab3f0a4af2014-10-17 12:25:14 -04001268 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001269 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001270 IMPORTANT:
1271 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001272 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001273 Furthermore, it assumes that value of VLAN is '-1'
1274 Description:
kelvin8ec71442015-01-15 16:57:00 -08001275 Converts mininet hosts ( h1, h2, h3... ) into
1276 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1277 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001278 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001279 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001280
kelvin-onlabd3b64892015-01-20 13:26:24 -08001281 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001282 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001283 hostHex = hex( int( host ) ).zfill( 12 )
1284 hostHex = str( hostHex ).replace( 'x', '0' )
1285 i = iter( str( hostHex ) )
1286 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1287 hostHex = hostHex + "/-1"
1288 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001289
kelvin-onlabd3b64892015-01-20 13:26:24 -08001290 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001291
Jon Halld4d4b372015-01-28 16:02:41 -08001292 except TypeError:
1293 main.log.exception( self.name + ": Object not as expected" )
1294 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001295 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001296 main.log.error( self.name + ": EOF exception found" )
1297 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001298 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001299 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001300 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001301 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001302
You Wangbc898b82018-05-03 16:22:34 -07001303 def verifyHostLocation( self, hostIp, location ):
1304 """
1305 Description:
1306 Verify the host given is discovered in all locations expected
1307 Required:
1308 hostIp: IP address of the host
1309 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1310 Could be a string or list
1311 Returns:
1312 main.TRUE if host is discovered on all locations provided
1313 main.FALSE otherwise
1314 """
You Wangbc898b82018-05-03 16:22:34 -07001315 locations = [ location ] if isinstance( location, str ) else location
1316 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1317 try:
1318 hosts = self.hosts()
1319 hosts = json.loads( hosts )
1320 targetHost = None
1321 for host in hosts:
1322 if hostIp in host[ "ipAddresses" ]:
1323 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001324 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001325 result = main.TRUE
1326 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1327 for loc in locations:
1328 discovered = False
1329 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001330 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1331 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001332 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001333 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001334 break
1335 if discovered:
1336 locationsDiscovered.remove( locDiscovered )
1337 else:
1338 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1339 result = main.FALSE
1340 if locationsDiscovered:
1341 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1342 result = main.FALSE
1343 return result
1344 except KeyError:
1345 main.log.exception( self.name + ": host data not as expected: " + hosts )
1346 return None
1347 except pexpect.EOF:
1348 main.log.error( self.name + ": EOF exception found" )
1349 main.log.error( self.name + ": " + self.handle.before )
1350 main.cleanAndExit()
1351 except Exception:
1352 main.log.exception( self.name + ": Uncaught exception" )
1353 return None
1354
You Wang53dba1e2018-02-02 17:45:44 -08001355 def verifyHostIp( self, hostList=[], prefix="" ):
1356 """
1357 Description:
1358 Verify that all hosts have IP address assigned to them
1359 Optional:
1360 hostList: If specified, verifications only happen to the hosts
1361 in hostList
1362 prefix: at least one of the ip address assigned to the host
1363 needs to have the specified prefix
1364 Returns:
1365 main.TRUE if all hosts have specific IP address assigned;
1366 main.FALSE otherwise
1367 """
You Wang53dba1e2018-02-02 17:45:44 -08001368 try:
1369 hosts = self.hosts()
1370 hosts = json.loads( hosts )
1371 if not hostList:
1372 hostList = [ host[ "id" ] for host in hosts ]
1373 for host in hosts:
1374 hostId = host[ "id" ]
1375 if hostId not in hostList:
1376 continue
1377 ipList = host[ "ipAddresses" ]
1378 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1379 if not ipList:
1380 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1381 else:
1382 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1383 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1384 else:
1385 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1386 hostList.remove( hostId )
1387 if hostList:
1388 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
Jon Hall43060f62020-06-23 13:13:33 -07001389 # Print info for debugging
1390 main.log.debug( self.name + ": hosts output: " + str( hosts ) )
You Wang53dba1e2018-02-02 17:45:44 -08001391 return main.FALSE
1392 else:
1393 return main.TRUE
1394 except KeyError:
1395 main.log.exception( self.name + ": host data not as expected: " + hosts )
1396 return None
1397 except pexpect.EOF:
1398 main.log.error( self.name + ": EOF exception found" )
1399 main.log.error( self.name + ": " + self.handle.before )
1400 main.cleanAndExit()
1401 except Exception:
1402 main.log.exception( self.name + ": Uncaught exception" )
1403 return None
1404
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001405 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001406 """
andrewonlabe6745342014-10-17 14:29:13 -04001407 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001408 * hostIdOne: ONOS host id for host1
1409 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001410 Optional:
1411 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001412 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001413 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001414 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001415 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001416 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001417 Returns:
1418 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001419 """
andrewonlabe6745342014-10-17 14:29:13 -04001420 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001421 cmdStr = "add-host-intent "
1422 if vlanId:
1423 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001424 if setVlan:
1425 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001426 if encap:
1427 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001428 if bandwidth:
1429 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001430 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001431 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001432 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001433 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001434 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001435 main.log.error( self.name + ": Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001436 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001437 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001438 else:
1439 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001440 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001441 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001442 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001443 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001444 else:
1445 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001446 main.log.debug( "Response from ONOS was: " +
1447 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001448 return None
Jon Hallc6793552016-01-19 14:18:37 -08001449 except AssertionError:
1450 main.log.exception( "" )
1451 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001452 except TypeError:
1453 main.log.exception( self.name + ": Object not as expected" )
1454 return None
andrewonlabe6745342014-10-17 14:29:13 -04001455 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001456 main.log.error( self.name + ": EOF exception found" )
1457 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001458 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001459 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001460 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001461 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001462
kelvin-onlabd3b64892015-01-20 13:26:24 -08001463 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001464 """
andrewonlab7b31d232014-10-24 13:31:47 -04001465 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001466 * ingressDevice: device id of ingress device
1467 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001468 Optional:
1469 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001470 Description:
1471 Adds an optical intent by specifying an ingress and egress device
1472 Returns:
1473 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001474 """
andrewonlab7b31d232014-10-24 13:31:47 -04001475 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001476 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1477 " " + str( egressDevice )
1478 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001479 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001480 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001481 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001482 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001483 main.log.error( self.name + ": Error in adding Optical intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001484 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001485 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001486 main.log.info( "Optical intent installed between " +
1487 str( ingressDevice ) + " and " +
1488 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001489 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001490 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001491 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001492 else:
1493 main.log.error( "Error, intent ID not found" )
1494 return None
Jon Hallc6793552016-01-19 14:18:37 -08001495 except AssertionError:
1496 main.log.exception( "" )
1497 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001498 except TypeError:
1499 main.log.exception( self.name + ": Object not as expected" )
1500 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001501 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001502 main.log.error( self.name + ": EOF exception found" )
1503 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001504 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001505 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001506 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001507 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001508
kelvin-onlabd3b64892015-01-20 13:26:24 -08001509 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001510 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001511 ingressDevice,
1512 egressDevice,
1513 portIngress="",
1514 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001515 ethType="",
1516 ethSrc="",
1517 ethDst="",
1518 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001519 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001520 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001521 ipProto="",
1522 ipSrc="",
1523 ipDst="",
1524 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001525 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001526 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001527 setVlan="",
1528 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001529 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001530 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001531 * ingressDevice: device id of ingress device
1532 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001533 Optional:
1534 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001535 * ethSrc: specify ethSrc ( i.e. src mac addr )
1536 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001537 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001538 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001539 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001540 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001541 * ipSrc: specify ip source address
1542 * ipDst: specify ip destination address
1543 * tcpSrc: specify tcp source port
1544 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001545 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001546 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001547 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001548 Description:
kelvin8ec71442015-01-15 16:57:00 -08001549 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001550 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001551 Returns:
1552 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001553
Jon Halle3f39ff2015-01-13 11:50:53 -08001554 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001555 options developers provide for point-to-point
1556 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001557 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001558 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001559 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001560
Jeremy Songsterff553672016-05-12 17:06:23 -07001561 if ethType:
1562 cmd += " --ethType " + str( ethType )
1563 if ethSrc:
1564 cmd += " --ethSrc " + str( ethSrc )
1565 if ethDst:
1566 cmd += " --ethDst " + str( ethDst )
1567 if bandwidth:
1568 cmd += " --bandwidth " + str( bandwidth )
1569 if lambdaAlloc:
1570 cmd += " --lambda "
1571 if ipProto:
1572 cmd += " --ipProto " + str( ipProto )
1573 if ipSrc:
1574 cmd += " --ipSrc " + str( ipSrc )
1575 if ipDst:
1576 cmd += " --ipDst " + str( ipDst )
1577 if tcpSrc:
1578 cmd += " --tcpSrc " + str( tcpSrc )
1579 if tcpDst:
1580 cmd += " --tcpDst " + str( tcpDst )
1581 if vlanId:
1582 cmd += " -v " + str( vlanId )
1583 if setVlan:
1584 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001585 if encap:
1586 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001587 if protected:
1588 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001589
kelvin8ec71442015-01-15 16:57:00 -08001590 # Check whether the user appended the port
1591 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001592 if "/" in ingressDevice:
1593 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001594 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001595 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001596 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001597 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001598 # Would it make sense to throw an exception and exit
1599 # the test?
1600 return None
andrewonlab36af3822014-11-18 17:48:18 -05001601
kelvin8ec71442015-01-15 16:57:00 -08001602 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001603 str( ingressDevice ) + "/" +\
1604 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001605
kelvin-onlabd3b64892015-01-20 13:26:24 -08001606 if "/" in egressDevice:
1607 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001608 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001609 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001610 main.log.error( "You must specify the egress port" )
1611 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001612
kelvin8ec71442015-01-15 16:57:00 -08001613 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001614 str( egressDevice ) + "/" +\
1615 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001616
kelvin-onlab898a6c62015-01-16 14:13:53 -08001617 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001618 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001619 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001620 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001621 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001622 main.log.error( self.name + ": Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001623 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001624 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001625 # TODO: print out all the options in this message?
1626 main.log.info( "Point-to-point intent installed between " +
1627 str( ingressDevice ) + " and " +
1628 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001629 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001630 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001631 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001632 else:
1633 main.log.error( "Error, intent ID not found" )
1634 return None
Jon Hallc6793552016-01-19 14:18:37 -08001635 except AssertionError:
1636 main.log.exception( "" )
1637 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001638 except TypeError:
1639 main.log.exception( self.name + ": Object not as expected" )
1640 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001641 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001642 main.log.error( self.name + ": EOF exception found" )
1643 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001644 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001645 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001646 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001647 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001648
kelvin-onlabd3b64892015-01-20 13:26:24 -08001649 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001650 self,
shahshreyac2f97072015-03-19 17:04:29 -07001651 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001652 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001653 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001654 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001655 ethType="",
1656 ethSrc="",
1657 ethDst="",
1658 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001659 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001660 ipProto="",
1661 ipSrc="",
1662 ipDst="",
1663 tcpSrc="",
1664 tcpDst="",
1665 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001666 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001667 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001668 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001669 partial=False,
1670 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001671 """
shahshreyad0c80432014-12-04 16:56:05 -08001672 Note:
shahshreya70622b12015-03-19 17:19:00 -07001673 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001674 is same. That is, all ingress devices include port numbers
1675 with a "/" or all ingress devices could specify device
1676 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001677 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001678 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001679 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001680 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001681 Optional:
1682 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001683 * ethSrc: specify ethSrc ( i.e. src mac addr )
1684 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001685 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001686 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001687 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001688 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001689 * ipSrc: specify ip source address
1690 * ipDst: specify ip destination address
1691 * tcpSrc: specify tcp source port
1692 * tcpDst: specify tcp destination port
1693 * setEthSrc: action to Rewrite Source MAC Address
1694 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001695 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001696 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001697 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001698 Description:
kelvin8ec71442015-01-15 16:57:00 -08001699 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001700 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001701 Returns:
1702 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001703
Jon Halle3f39ff2015-01-13 11:50:53 -08001704 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001705 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001706 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001707 """
shahshreyad0c80432014-12-04 16:56:05 -08001708 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001709 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001710
Jeremy Songsterff553672016-05-12 17:06:23 -07001711 if ethType:
1712 cmd += " --ethType " + str( ethType )
1713 if ethSrc:
1714 cmd += " --ethSrc " + str( ethSrc )
1715 if ethDst:
1716 cmd += " --ethDst " + str( ethDst )
1717 if bandwidth:
1718 cmd += " --bandwidth " + str( bandwidth )
1719 if lambdaAlloc:
1720 cmd += " --lambda "
1721 if ipProto:
1722 cmd += " --ipProto " + str( ipProto )
1723 if ipSrc:
1724 cmd += " --ipSrc " + str( ipSrc )
1725 if ipDst:
1726 cmd += " --ipDst " + str( ipDst )
1727 if tcpSrc:
1728 cmd += " --tcpSrc " + str( tcpSrc )
1729 if tcpDst:
1730 cmd += " --tcpDst " + str( tcpDst )
1731 if setEthSrc:
1732 cmd += " --setEthSrc " + str( setEthSrc )
1733 if setEthDst:
1734 cmd += " --setEthDst " + str( setEthDst )
1735 if vlanId:
1736 cmd += " -v " + str( vlanId )
1737 if setVlan:
1738 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001739 if partial:
1740 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001741 if encap:
1742 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001743
kelvin8ec71442015-01-15 16:57:00 -08001744 # Check whether the user appended the port
1745 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001746
1747 if portIngressList is None:
1748 for ingressDevice in ingressDeviceList:
1749 if "/" in ingressDevice:
1750 cmd += " " + str( ingressDevice )
1751 else:
1752 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001753 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001754 # TODO: perhaps more meaningful return
1755 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001756 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001757 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001758 for ingressDevice, portIngress in zip( ingressDeviceList,
1759 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001760 cmd += " " + \
1761 str( ingressDevice ) + "/" +\
1762 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001763 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001764 main.log.error( "Device list and port list does not " +
1765 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001766 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001767 if "/" in egressDevice:
1768 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001769 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001770 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001771 main.log.error( "You must specify " +
1772 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001773 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001774
kelvin8ec71442015-01-15 16:57:00 -08001775 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001776 str( egressDevice ) + "/" +\
1777 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001778 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001779 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001780 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001781 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001782 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001783 main.log.error( self.name + ": Error in adding multipoint-to-singlepoint " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001784 "intent" )
1785 return None
shahshreyad0c80432014-12-04 16:56:05 -08001786 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001787 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001788 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001789 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001790 else:
1791 main.log.error( "Error, intent ID not found" )
1792 return None
Jon Hallc6793552016-01-19 14:18:37 -08001793 except AssertionError:
1794 main.log.exception( "" )
1795 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001796 except TypeError:
1797 main.log.exception( self.name + ": Object not as expected" )
1798 return None
1799 except pexpect.EOF:
1800 main.log.error( self.name + ": EOF exception found" )
1801 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001802 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001803 except Exception:
1804 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001805 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001806
1807 def addSinglepointToMultipointIntent(
1808 self,
1809 ingressDevice,
1810 egressDeviceList,
1811 portIngress="",
1812 portEgressList=None,
1813 ethType="",
1814 ethSrc="",
1815 ethDst="",
1816 bandwidth="",
1817 lambdaAlloc=False,
1818 ipProto="",
1819 ipSrc="",
1820 ipDst="",
1821 tcpSrc="",
1822 tcpDst="",
1823 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001824 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001825 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001826 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001827 partial=False,
1828 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001829 """
1830 Note:
1831 This function assumes the format of all egress devices
1832 is same. That is, all egress devices include port numbers
1833 with a "/" or all egress devices could specify device
1834 ids and port numbers seperately.
1835 Required:
1836 * EgressDeviceList: List of device ids of egress device
1837 ( Atleast 2 eress devices required in the list )
1838 * ingressDevice: device id of ingress device
1839 Optional:
1840 * ethType: specify ethType
1841 * ethSrc: specify ethSrc ( i.e. src mac addr )
1842 * ethDst: specify ethDst ( i.e. dst mac addr )
1843 * bandwidth: specify bandwidth capacity of link
1844 * lambdaAlloc: if True, intent will allocate lambda
1845 for the specified intent
1846 * ipProto: specify ip protocol
1847 * ipSrc: specify ip source address
1848 * ipDst: specify ip destination address
1849 * tcpSrc: specify tcp source port
1850 * tcpDst: specify tcp destination port
1851 * setEthSrc: action to Rewrite Source MAC Address
1852 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001853 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001854 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001855 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001856 Description:
1857 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1858 specifying device id's and optional fields
1859 Returns:
1860 A string of the intent id or None on error
1861
1862 NOTE: This function may change depending on the
1863 options developers provide for singlepoint-to-multipoint
1864 intent via cli
1865 """
1866 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001867 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001868
Jeremy Songsterff553672016-05-12 17:06:23 -07001869 if ethType:
1870 cmd += " --ethType " + str( ethType )
1871 if ethSrc:
1872 cmd += " --ethSrc " + str( ethSrc )
1873 if ethDst:
1874 cmd += " --ethDst " + str( ethDst )
1875 if bandwidth:
1876 cmd += " --bandwidth " + str( bandwidth )
1877 if lambdaAlloc:
1878 cmd += " --lambda "
1879 if ipProto:
1880 cmd += " --ipProto " + str( ipProto )
1881 if ipSrc:
1882 cmd += " --ipSrc " + str( ipSrc )
1883 if ipDst:
1884 cmd += " --ipDst " + str( ipDst )
1885 if tcpSrc:
1886 cmd += " --tcpSrc " + str( tcpSrc )
1887 if tcpDst:
1888 cmd += " --tcpDst " + str( tcpDst )
1889 if setEthSrc:
1890 cmd += " --setEthSrc " + str( setEthSrc )
1891 if setEthDst:
1892 cmd += " --setEthDst " + str( setEthDst )
1893 if vlanId:
1894 cmd += " -v " + str( vlanId )
1895 if setVlan:
1896 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001897 if partial:
1898 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001899 if encap:
1900 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001901
1902 # Check whether the user appended the port
1903 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001904
kelvin-onlabb9408212015-04-01 13:34:04 -07001905 if "/" in ingressDevice:
1906 cmd += " " + str( ingressDevice )
1907 else:
1908 if not portIngress:
1909 main.log.error( "You must specify " +
1910 "the Ingress port" )
1911 return main.FALSE
1912
1913 cmd += " " +\
1914 str( ingressDevice ) + "/" +\
1915 str( portIngress )
1916
1917 if portEgressList is None:
1918 for egressDevice in egressDeviceList:
1919 if "/" in egressDevice:
1920 cmd += " " + str( egressDevice )
1921 else:
1922 main.log.error( "You must specify " +
1923 "the egress port" )
1924 # TODO: perhaps more meaningful return
1925 return main.FALSE
1926 else:
1927 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001928 for egressDevice, portEgress in zip( egressDeviceList,
1929 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001930 cmd += " " + \
1931 str( egressDevice ) + "/" +\
1932 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001933 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001934 main.log.error( "Device list and port list does not " +
1935 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001936 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001937 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001938 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001939 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001940 # If error, return error message
1941 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001942 main.log.error( self.name + ": Error in adding singlepoint-to-multipoint " +
kelvin-onlabb9408212015-04-01 13:34:04 -07001943 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001944 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001945 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001946 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001947 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001948 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001949 else:
1950 main.log.error( "Error, intent ID not found" )
1951 return None
Jon Hallc6793552016-01-19 14:18:37 -08001952 except AssertionError:
1953 main.log.exception( "" )
1954 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001955 except TypeError:
1956 main.log.exception( self.name + ": Object not as expected" )
1957 return None
shahshreyad0c80432014-12-04 16:56:05 -08001958 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001959 main.log.error( self.name + ": EOF exception found" )
1960 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001961 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001962 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001963 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001964 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001965
Hari Krishna9e232602015-04-13 17:29:08 -07001966 def addMplsIntent(
1967 self,
1968 ingressDevice,
1969 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001970 ingressPort="",
1971 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001972 ethType="",
1973 ethSrc="",
1974 ethDst="",
1975 bandwidth="",
1976 lambdaAlloc=False,
1977 ipProto="",
1978 ipSrc="",
1979 ipDst="",
1980 tcpSrc="",
1981 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001982 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001983 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001984 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001985 """
1986 Required:
1987 * ingressDevice: device id of ingress device
1988 * egressDevice: device id of egress device
1989 Optional:
1990 * ethType: specify ethType
1991 * ethSrc: specify ethSrc ( i.e. src mac addr )
1992 * ethDst: specify ethDst ( i.e. dst mac addr )
1993 * bandwidth: specify bandwidth capacity of link
1994 * lambdaAlloc: if True, intent will allocate lambda
1995 for the specified intent
1996 * ipProto: specify ip protocol
1997 * ipSrc: specify ip source address
1998 * ipDst: specify ip destination address
1999 * tcpSrc: specify tcp source port
2000 * tcpDst: specify tcp destination port
2001 * ingressLabel: Ingress MPLS label
2002 * egressLabel: Egress MPLS label
2003 Description:
2004 Adds MPLS intent by
2005 specifying device id's and optional fields
2006 Returns:
2007 A string of the intent id or None on error
2008
2009 NOTE: This function may change depending on the
2010 options developers provide for MPLS
2011 intent via cli
2012 """
2013 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07002014 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07002015
Jeremy Songsterff553672016-05-12 17:06:23 -07002016 if ethType:
2017 cmd += " --ethType " + str( ethType )
2018 if ethSrc:
2019 cmd += " --ethSrc " + str( ethSrc )
2020 if ethDst:
2021 cmd += " --ethDst " + str( ethDst )
2022 if bandwidth:
2023 cmd += " --bandwidth " + str( bandwidth )
2024 if lambdaAlloc:
2025 cmd += " --lambda "
2026 if ipProto:
2027 cmd += " --ipProto " + str( ipProto )
2028 if ipSrc:
2029 cmd += " --ipSrc " + str( ipSrc )
2030 if ipDst:
2031 cmd += " --ipDst " + str( ipDst )
2032 if tcpSrc:
2033 cmd += " --tcpSrc " + str( tcpSrc )
2034 if tcpDst:
2035 cmd += " --tcpDst " + str( tcpDst )
2036 if ingressLabel:
2037 cmd += " --ingressLabel " + str( ingressLabel )
2038 if egressLabel:
2039 cmd += " --egressLabel " + str( egressLabel )
2040 if priority:
2041 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07002042
2043 # Check whether the user appended the port
2044 # or provided it as an input
2045 if "/" in ingressDevice:
2046 cmd += " " + str( ingressDevice )
2047 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002048 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002049 main.log.error( "You must specify the ingress port" )
2050 return None
2051
2052 cmd += " " + \
2053 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002054 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07002055
2056 if "/" in egressDevice:
2057 cmd += " " + str( egressDevice )
2058 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002059 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002060 main.log.error( "You must specify the egress port" )
2061 return None
2062
2063 cmd += " " +\
2064 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002065 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07002066
2067 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08002068 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002069 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07002070 # If error, return error message
2071 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002072 main.log.error( self.name + ": Error in adding mpls intent" )
Hari Krishna9e232602015-04-13 17:29:08 -07002073 return None
2074 else:
2075 # TODO: print out all the options in this message?
2076 main.log.info( "MPLS intent installed between " +
2077 str( ingressDevice ) + " and " +
2078 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002079 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07002080 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002081 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07002082 else:
2083 main.log.error( "Error, intent ID not found" )
2084 return None
Jon Hallc6793552016-01-19 14:18:37 -08002085 except AssertionError:
2086 main.log.exception( "" )
2087 return None
Hari Krishna9e232602015-04-13 17:29:08 -07002088 except TypeError:
2089 main.log.exception( self.name + ": Object not as expected" )
2090 return None
2091 except pexpect.EOF:
2092 main.log.error( self.name + ": EOF exception found" )
2093 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002094 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002095 except Exception:
2096 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002097 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002098
Jon Hallefbd9792015-03-05 16:11:36 -08002099 def removeIntent( self, intentId, app='org.onosproject.cli',
2100 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002101 """
shahshreya1c818fc2015-02-26 13:44:08 -08002102 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07002103 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08002104 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07002105 -p or --purge: Purge the intent from the store after removal
2106
Jon Halle3f39ff2015-01-13 11:50:53 -08002107 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07002108 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08002109 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08002110 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002111 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002112 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08002113 if purge:
2114 cmdStr += " -p"
2115 if sync:
2116 cmdStr += " -s"
2117
2118 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002119 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002120 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002121 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08002122 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002123 main.log.error( self.name + ": Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002124 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04002125 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002126 # TODO: Should this be main.TRUE
2127 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002128 except AssertionError:
2129 main.log.exception( "" )
2130 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002131 except TypeError:
2132 main.log.exception( self.name + ": Object not as expected" )
2133 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002134 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002135 main.log.error( self.name + ": EOF exception found" )
2136 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002137 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002138 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002139 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002140 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002141
YPZhangfebf7302016-05-24 16:45:56 -07002142 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08002143 """
2144 Description:
2145 Remove all the intents
2146 Optional args:-
2147 -s or --sync: Waits for the removal before returning
2148 -p or --purge: Purge the intent from the store after removal
2149 Returns:
2150 Returns main.TRUE if all intents are removed, otherwise returns
2151 main.FALSE; Returns None for exception
2152 """
2153 try:
2154 cmdStr = "remove-intent"
2155 if purge:
2156 cmdStr += " -p"
2157 if sync:
2158 cmdStr += " -s"
2159
2160 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002161 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002162 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002163 assert "Command not found:" not in handle, handle
2164 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002165 main.log.error( self.name + ": Error in removing intent" )
Jeremy42df2e72016-02-23 16:37:46 -08002166 return main.FALSE
2167 else:
2168 return main.TRUE
2169 except AssertionError:
2170 main.log.exception( "" )
2171 return None
2172 except TypeError:
2173 main.log.exception( self.name + ": Object not as expected" )
2174 return None
2175 except pexpect.EOF:
2176 main.log.error( self.name + ": EOF exception found" )
2177 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002178 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002179 except Exception:
2180 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002181 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002182
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002183 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002184 """
2185 Purges all WITHDRAWN Intents
2186 """
2187 try:
2188 cmdStr = "purge-intents"
2189 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002190 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002191 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002192 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002193 main.log.error( self.name + ": Error in purging intents" )
Hari Krishna0ce0e152015-06-23 09:55:29 -07002194 return main.FALSE
2195 else:
2196 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002197 except AssertionError:
2198 main.log.exception( "" )
2199 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002200 except TypeError:
2201 main.log.exception( self.name + ": Object not as expected" )
2202 return None
2203 except pexpect.EOF:
2204 main.log.error( self.name + ": EOF exception found" )
2205 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002206 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002207 except Exception:
2208 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002209 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002210
Devin Lime6fe3c42017-10-18 16:28:40 -07002211 def wipeout( self ):
2212 """
2213 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2214 """
2215 try:
2216 cmdStr = "wipe-out please"
2217 handle = self.sendline( cmdStr, timeout=60 )
2218 assert handle is not None, "Error in sendline"
2219 assert "Command not found:" not in handle, handle
2220 return main.TRUE
2221 except AssertionError:
2222 main.log.exception( "" )
2223 return None
2224 except TypeError:
2225 main.log.exception( self.name + ": Object not as expected" )
2226 return None
2227 except pexpect.EOF:
2228 main.log.error( self.name + ": EOF exception found" )
2229 main.log.error( self.name + ": " + self.handle.before )
2230 main.cleanAndExit()
2231 except Exception:
2232 main.log.exception( self.name + ": Uncaught exception!" )
2233 main.cleanAndExit()
2234
kelvin-onlabd3b64892015-01-20 13:26:24 -08002235 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002236 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002237 NOTE: This method should be used after installing application:
2238 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002239 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002240 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002241 Description:
2242 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002243 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002244 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002245 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002246 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002247 cmdStr += " -j"
2248 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002249 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002250 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002251 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002252 except AssertionError:
2253 main.log.exception( "" )
2254 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002255 except TypeError:
2256 main.log.exception( self.name + ": Object not as expected" )
2257 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002258 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002259 main.log.error( self.name + ": EOF exception found" )
2260 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002261 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002262 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002263 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002264 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002265
pingping-lin54b03372015-08-13 14:43:10 -07002266 def ipv4RouteNumber( self ):
2267 """
2268 NOTE: This method should be used after installing application:
2269 onos-app-sdnip
2270 Description:
2271 Obtain the total IPv4 routes number in the system
2272 """
2273 try:
Pratik Parab57963572017-05-09 11:37:54 -07002274 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002275 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002276 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002277 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002278 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002279 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002280 except AssertionError:
2281 main.log.exception( "" )
2282 return None
2283 except ( TypeError, ValueError ):
2284 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002285 return None
2286 except pexpect.EOF:
2287 main.log.error( self.name + ": EOF exception found" )
2288 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002289 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002290 except Exception:
2291 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002292 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002293
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002294 # =============Function to check Bandwidth allocation========
Jon Hall0e240372018-05-02 11:21:57 -07002295 def allocations( self, jsonFormat = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002296 """
2297 Description:
2298 Obtain Bandwidth Allocation Information from ONOS cli.
2299 """
2300 try:
2301 cmdStr = "allocations"
2302 if jsonFormat:
2303 cmdStr += " -j"
Jon Hall0e240372018-05-02 11:21:57 -07002304 handle = self.sendline( cmdStr, timeout=300 )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002305 assert handle is not None, "Error in sendline"
2306 assert "Command not found:" not in handle, handle
2307 return handle
2308 except AssertionError:
2309 main.log.exception( "" )
2310 return None
2311 except ( TypeError, ValueError ):
2312 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2313 return None
2314 except pexpect.EOF:
2315 main.log.error( self.name + ": EOF exception found" )
2316 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002317 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002318 except Exception:
2319 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002320 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002321
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002322 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002323 """
andrewonlabe6745342014-10-17 14:29:13 -04002324 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002325 Obtain intents from the ONOS cli.
2326 Optional:
2327 * jsonFormat: Enable output formatting in json, default to True
2328 * summary: Whether only output the intent summary, defaults to False
2329 * type: Only output a certain type of intent. This options is valid
2330 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002331 """
andrewonlabe6745342014-10-17 14:29:13 -04002332 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002333 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002334 if summary:
2335 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002336 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002337 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002338 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002339 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002340 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002341 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002342 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002343 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002344 else:
Jon Hallff566d52016-01-15 14:45:36 -08002345 intentType = ""
2346 # IF we want the summary of a specific intent type
2347 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002348 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002349 if intentType in jsonResult.keys():
2350 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002351 else:
Jon Hallff566d52016-01-15 14:45:36 -08002352 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002353 return handle
2354 else:
2355 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002356 except AssertionError:
2357 main.log.exception( "" )
2358 return None
2359 except ( TypeError, ValueError ):
2360 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002361 return None
2362 except pexpect.EOF:
2363 main.log.error( self.name + ": EOF exception found" )
2364 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002365 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002366 except Exception:
2367 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002368 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002369
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002370 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002371 """
You Wangfdcbfc42016-05-16 12:16:53 -07002372 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002373 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002374 list of intent IDs.
2375 Parameters:
2376 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002377 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002378 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002379 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002380 accepted.
2381 Returns a list of dictionaries if a list of intent IDs is accepted,
2382 and each dictionary maps 'id' to the Intent ID and 'state' to
2383 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002384 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002385
kelvin-onlab54400a92015-02-26 18:05:51 -08002386 try:
2387 state = "State is Undefined"
2388 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002389 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002390 else:
Jon Hallc6793552016-01-19 14:18:37 -08002391 rawJson = intentsJson
2392 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002393 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002394 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002395 if intentsId == intent[ 'id' ]:
2396 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002397 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002398 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002399 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002400 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002401 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002402 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002403 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002404 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002405 for intent in parsedIntentsJson:
2406 if intentsId[ i ] == intent[ 'id' ]:
2407 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002408 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002409 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002410 break
Jon Hallefbd9792015-03-05 16:11:36 -08002411 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002412 main.log.warn( "Could not find all intents in ONOS output" )
2413 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002414 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002415 else:
Jon Hall53158082017-05-18 11:17:00 -07002416 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002417 return None
Jon Hallc6793552016-01-19 14:18:37 -08002418 except ( TypeError, ValueError ):
2419 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002420 return None
2421 except pexpect.EOF:
2422 main.log.error( self.name + ": EOF exception found" )
2423 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002424 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002425 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002426 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002427 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002428
Jon Hallf539eb92017-05-22 17:18:42 -07002429 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002430 """
2431 Description:
2432 Check intents state
2433 Required:
2434 intentsId - List of intents ID to be checked
2435 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002436 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002437 state in the list.
2438 *NOTE: You can pass in a list of expected state,
2439 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002440 Return:
Jon Hall53158082017-05-18 11:17:00 -07002441 Returns main.TRUE only if all intent are the same as expected states,
2442 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002443 """
2444 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002445 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002446 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002447
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002448 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002449 intentsDict = []
2450 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002451 if isinstance( intentsId, types.StringType ) \
2452 and intent.get( 'id' ) == intentsId:
2453 intentsDict.append( intent )
2454 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002455 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002456 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002457
2458 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002459 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002460 "getting intents state" )
2461 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002462
2463 if isinstance( expectedState, types.StringType ):
2464 for intents in intentsDict:
2465 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002466 main.log.debug( self.name + " : Intent ID - " +
2467 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002468 " actual state = " +
2469 intents.get( 'state' )
2470 + " does not equal expected state = "
2471 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002472 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002473 elif isinstance( expectedState, types.ListType ):
2474 for intents in intentsDict:
2475 if not any( state == intents.get( 'state' ) for state in
2476 expectedState ):
2477 main.log.debug( self.name + " : Intent ID - " +
2478 intents.get( 'id' ) +
2479 " actual state = " +
2480 intents.get( 'state' ) +
2481 " does not equal expected states = "
2482 + str( expectedState ) )
2483 returnValue = main.FALSE
2484
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002485 if returnValue == main.TRUE:
2486 main.log.info( self.name + ": All " +
2487 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002488 " intents are in " + str( expectedState ) +
2489 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002490 return returnValue
2491 except TypeError:
2492 main.log.exception( self.name + ": Object not as expected" )
2493 return None
2494 except pexpect.EOF:
2495 main.log.error( self.name + ": EOF exception found" )
2496 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002497 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002498 except Exception:
2499 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002500 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002501
Jon Hallf539eb92017-05-22 17:18:42 -07002502 def compareBandwidthAllocations( self, expectedAllocations ):
2503 """
2504 Description:
2505 Compare the allocated bandwidth with the given allocations
2506 Required:
2507 expectedAllocations - The expected ONOS output of the allocations command
2508 Return:
2509 Returns main.TRUE only if all intent are the same as expected states,
2510 otherwise returns main.FALSE.
2511 """
2512 # FIXME: Convert these string comparisons to object comparisons
2513 try:
2514 returnValue = main.TRUE
2515 bandwidthFailed = False
2516 rawAlloc = self.allocations()
2517 expectedFormat = StringIO( expectedAllocations )
2518 ONOSOutput = StringIO( rawAlloc )
2519 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2520 str( expectedFormat ) ) )
2521
2522 for actual, expected in izip( ONOSOutput, expectedFormat ):
2523 actual = actual.rstrip()
2524 expected = expected.rstrip()
2525 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2526 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002527 marker1 = actual.find( 'allocated' )
2528 m1 = actual[ :marker1 ]
2529 marker2 = expected.find( 'allocated' )
2530 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002531 if m1 != m2:
2532 bandwidthFailed = True
2533 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2534 bandwidthFailed = True
2535 expectedFormat.close()
2536 ONOSOutput.close()
2537
2538 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002539 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002540 returnValue = main.FALSE
2541 return returnValue
2542 except TypeError:
2543 main.log.exception( self.name + ": Object not as expected" )
2544 return None
2545 except pexpect.EOF:
2546 main.log.error( self.name + ": EOF exception found" )
2547 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002548 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002549 except Exception:
2550 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002551 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002552
You Wang66518af2016-05-16 15:32:59 -07002553 def compareIntent( self, intentDict ):
2554 """
2555 Description:
2556 Compare the intent ids and states provided in the argument with all intents in ONOS
2557 Return:
2558 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2559 Arguments:
2560 intentDict: a dictionary which maps intent ids to intent states
2561 """
2562 try:
2563 intentsRaw = self.intents()
2564 intentsJson = json.loads( intentsRaw )
2565 intentDictONOS = {}
2566 for intent in intentsJson:
2567 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002568 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002569 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002570 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002571 str( len( intentDict ) ) + " expected and " +
2572 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002573 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002574 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002575 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002576 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2577 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002578 else:
2579 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2580 main.log.debug( self.name + ": intent ID - " + intentID +
2581 " expected state is " + intentDict[ intentID ] +
2582 " but actual state is " + intentDictONOS[ intentID ] )
2583 returnValue = main.FALSE
2584 intentDictONOS.pop( intentID )
2585 if len( intentDictONOS ) > 0:
2586 returnValue = main.FALSE
2587 for intentID in intentDictONOS.keys():
2588 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002589 if returnValue == main.TRUE:
2590 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2591 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002592 except KeyError:
2593 main.log.exception( self.name + ": KeyError exception found" )
2594 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002595 except ( TypeError, ValueError ):
2596 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002597 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002598 except pexpect.EOF:
2599 main.log.error( self.name + ": EOF exception found" )
2600 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002601 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002602 except Exception:
2603 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002604 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002605
YPZhang14a4aa92016-07-15 13:37:15 -07002606 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002607 """
2608 Description:
2609 Check the number of installed intents.
2610 Optional:
2611 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002612 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002613 Return:
2614 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2615 , otherwise, returns main.FALSE.
2616 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002617
GlennRCed771242016-01-13 17:02:47 -08002618 try:
2619 cmd = "intents -s -j"
2620
2621 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002622 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002623 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002624 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002625 response = json.loads( response )
2626
2627 # get total and installed number, see if they are match
2628 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002629 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002630 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2631 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002632 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002633 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2634 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002635 return main.FALSE
2636
Jon Hallc6793552016-01-19 14:18:37 -08002637 except ( TypeError, ValueError ):
2638 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002639 return None
2640 except pexpect.EOF:
2641 main.log.error( self.name + ": EOF exception found" )
2642 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002643 if noExit:
2644 return main.FALSE
2645 else:
Devin Lim44075962017-08-11 10:56:37 -07002646 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002647 except pexpect.TIMEOUT:
2648 main.log.error( self.name + ": ONOS timeout" )
2649 return None
GlennRCed771242016-01-13 17:02:47 -08002650 except Exception:
2651 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002652 if noExit:
2653 return main.FALSE
2654 else:
Devin Lim44075962017-08-11 10:56:37 -07002655 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002656
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002657 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002658 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002659 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002660 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002661 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002662 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002663 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002664 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002665 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002666 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002667 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002668 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002669 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002670 cmdStr += " -n"
2671 cmdStr += " " + state
2672 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002673 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002674 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002675 assert "Command not found:" not in handle, handle
2676 if re.search( "Error:", handle ):
2677 main.log.error( self.name + ": flows() response: " +
2678 str( handle ) )
2679 return handle
2680 except AssertionError:
2681 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002682 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002683 except TypeError:
2684 main.log.exception( self.name + ": Object not as expected" )
2685 return None
Jon Hallc6793552016-01-19 14:18:37 -08002686 except pexpect.TIMEOUT:
2687 main.log.error( self.name + ": ONOS timeout" )
2688 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002689 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002690 main.log.error( self.name + ": EOF exception found" )
2691 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002692 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002693 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002694 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002695 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002696
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002697 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002698 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002699 count = int( count ) if count else 0
steven30801eccfe212019-01-24 13:00:42 +08002700 main.log.debug( "found {} flows".format( count ) )
Jon Hall39570262020-11-17 12:18:19 -08002701 return count if ( count >= min ) else False
GlennRCed771242016-01-13 17:02:47 -08002702
Jon Halle0f0b342017-04-18 11:43:47 -07002703 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002704 """
2705 Description:
GlennRCed771242016-01-13 17:02:47 -08002706 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002707 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2708 if the count of those states is 0, which means all current flows
2709 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002710 Optional:
GlennRCed771242016-01-13 17:02:47 -08002711 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002712 Return:
2713 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002714 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002715 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002716 """
2717 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002718 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002719 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002720 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002721 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002722 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002723 if rawFlows:
2724 # if we didn't get flows or flows function return None, we should return
2725 # main.Flase
2726 checkedStates.append( json.loads( rawFlows ) )
2727 else:
2728 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002729 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002730 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002731 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002732 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002733 except TypeError:
2734 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002735 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002736
GlennRCed771242016-01-13 17:02:47 -08002737 # We want to count PENDING_ADD if isPENDING is true
2738 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002739 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002740 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002741 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002742 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002743 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002744 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002745 except ( TypeError, ValueError ):
2746 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002747 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002748
YPZhang240842b2016-05-17 12:00:50 -07002749 except AssertionError:
2750 main.log.exception( "" )
2751 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002752 except pexpect.TIMEOUT:
2753 main.log.error( self.name + ": ONOS timeout" )
2754 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002755 except pexpect.EOF:
2756 main.log.error( self.name + ": EOF exception found" )
2757 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002758 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002759 except Exception:
2760 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002761 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002762
GlennRCed771242016-01-13 17:02:47 -08002763 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002764 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002765 """
andrewonlab87852b02014-11-19 18:44:19 -05002766 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002767 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002768 a specific point-to-point intent definition
2769 Required:
GlennRCed771242016-01-13 17:02:47 -08002770 * ingress: specify source dpid
2771 * egress: specify destination dpid
2772 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002773 Optional:
GlennRCed771242016-01-13 17:02:47 -08002774 * offset: the keyOffset is where the next batch of intents
2775 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002776 * noExit: If set to True, TestON will not exit if any error when issus command
2777 * getResponse: If set to True, function will return ONOS response.
2778
GlennRCed771242016-01-13 17:02:47 -08002779 Returns: If failed to push test intents, it will returen None,
2780 if successful, return true.
2781 Timeout expection will return None,
2782 TypeError will return false
2783 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002784 """
andrewonlab87852b02014-11-19 18:44:19 -05002785 try:
GlennRCed771242016-01-13 17:02:47 -08002786 if background:
2787 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002788 else:
GlennRCed771242016-01-13 17:02:47 -08002789 back = ""
2790 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002791 ingress,
2792 egress,
2793 batchSize,
2794 offset,
2795 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002796 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002797 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002798 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002799 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002800 if getResponse:
2801 return response
2802
GlennRCed771242016-01-13 17:02:47 -08002803 # TODO: We should handle if there is failure in installation
2804 return main.TRUE
2805
Jon Hallc6793552016-01-19 14:18:37 -08002806 except AssertionError:
2807 main.log.exception( "" )
2808 return None
GlennRCed771242016-01-13 17:02:47 -08002809 except pexpect.TIMEOUT:
2810 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002811 return None
andrewonlab87852b02014-11-19 18:44:19 -05002812 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002813 main.log.error( self.name + ": EOF exception found" )
2814 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002815 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002816 except TypeError:
2817 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002818 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002819 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002820 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002821 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002822
YPZhangebf9eb52016-05-12 15:20:24 -07002823 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002824 """
2825 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002826 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002827 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002828 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002829 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002830 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002831
YPZhangb5d3f832016-01-23 22:54:26 -08002832 try:
YPZhange3109a72016-02-02 11:25:37 -08002833 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002834 cmd = "flows -c added"
2835 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2836 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002837 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002838 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002839 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002840 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002841 else:
You Wang68568b12019-03-04 11:49:57 -08002842 main.log.warn( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002843 return None
2844 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002845
You Wangd3097f72018-12-12 11:56:03 -08002846 except IndexError:
2847 main.log.exception( "{}: Object not as expected!".format( self.name ) )
2848 main.log.debug( "rawFlows: {}".format( rawFlows ) )
2849 return None
You Wangd3cb2ce2016-05-16 14:01:24 -07002850 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002851 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002852 return None
2853 except pexpect.EOF:
2854 main.log.error( self.name + ": EOF exception found" )
2855 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002856 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002857 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002858 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002859 except pexpect.TIMEOUT:
2860 main.log.error( self.name + ": ONOS timeout" )
2861 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002862 except Exception:
2863 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002864 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002865 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002866 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002867
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002868 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002869 """
2870 Description:
2871 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002872 Optional:
2873 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002874 Return:
2875 The number of intents
2876 """
2877 try:
2878 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002879 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002880 if response is None:
2881 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002882 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002883 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002884 except ( TypeError, ValueError ):
2885 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002886 return None
2887 except pexpect.EOF:
2888 main.log.error( self.name + ": EOF exception found" )
2889 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002890 if noExit:
2891 return -1
2892 else:
Devin Lim44075962017-08-11 10:56:37 -07002893 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002894 except Exception:
2895 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002896 if noExit:
2897 return -1
2898 else:
Devin Lim44075962017-08-11 10:56:37 -07002899 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002900
kelvin-onlabd3b64892015-01-20 13:26:24 -08002901 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002902 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002903 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002904 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002905 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002906 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002907 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002908 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002909 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002910 cmdStr += " -j"
2911 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002912 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002913 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002914 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002915 except AssertionError:
2916 main.log.exception( "" )
2917 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002918 except TypeError:
2919 main.log.exception( self.name + ": Object not as expected" )
2920 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002921 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002922 main.log.error( self.name + ": EOF exception found" )
2923 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002924 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002925 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002926 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002927 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002928
kelvin-onlabd3b64892015-01-20 13:26:24 -08002929 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002930 """
2931 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002932 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002933 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002934 """
andrewonlab867212a2014-10-22 20:13:38 -04002935 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002936 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002937 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002938 cmdStr += " -j"
2939 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002940 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002941 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002942 if handle:
2943 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002944 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002945 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002946 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002947 else:
2948 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002949 except AssertionError:
2950 main.log.exception( "" )
2951 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002952 except TypeError:
2953 main.log.exception( self.name + ": Object not as expected" )
2954 return None
andrewonlab867212a2014-10-22 20:13:38 -04002955 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002956 main.log.error( self.name + ": EOF exception found" )
2957 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002958 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002959 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002960 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002961 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002962
kelvin8ec71442015-01-15 16:57:00 -08002963 # Wrapper functions ****************
2964 # Wrapper functions use existing driver
2965 # functions and extends their use case.
2966 # For example, we may use the output of
2967 # a normal driver function, and parse it
2968 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002969
kelvin-onlabd3b64892015-01-20 13:26:24 -08002970 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002971 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002972 Description:
2973 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002974 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002975 try:
kelvin8ec71442015-01-15 16:57:00 -08002976 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002977 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002978 if intentsStr is None:
2979 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002980 # Convert to a dictionary
2981 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002982 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002983 for intent in intents:
2984 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002985 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002986 except TypeError:
2987 main.log.exception( self.name + ": Object not as expected" )
2988 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002989 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002990 main.log.error( self.name + ": EOF exception found" )
2991 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002992 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002993 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002994 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002995 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002996
You Wang3c276252016-09-21 15:21:36 -07002997 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002998 """
2999 Determine the number of flow rules for the given device id that are
3000 in the added state
You Wang3c276252016-09-21 15:21:36 -07003001 Params:
3002 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08003003 """
3004 try:
You Wang3c276252016-09-21 15:21:36 -07003005 if core:
3006 cmdStr = "flows any " + str( deviceId ) + " | " +\
3007 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
3008 else:
3009 cmdStr = "flows any " + str( deviceId ) + " | " +\
3010 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003011 handle = self.lineCount( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003012 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003013 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08003014 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003015 except AssertionError:
3016 main.log.exception( "" )
3017 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08003018 except pexpect.EOF:
3019 main.log.error( self.name + ": EOF exception found" )
3020 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003021 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003022 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08003023 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003024 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04003025
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003026 def groupAddedCount( self, deviceId, core=False ):
3027 """
3028 Determine the number of group rules for the given device id that are
3029 in the added state
3030 Params:
3031 core: if True, only return the number of core groups added
3032 """
3033 try:
3034 if core:
3035 cmdStr = "groups any " + str( deviceId ) + " | " +\
3036 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
3037 else:
3038 cmdStr = "groups any " + str( deviceId ) + " | " +\
3039 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003040 handle = self.lineCount( cmdStr )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003041 assert handle is not None, "Error in sendline"
3042 assert "Command not found:" not in handle, handle
3043 return handle
3044 except AssertionError:
3045 main.log.exception( "" )
3046 return None
3047 except pexpect.EOF:
3048 main.log.error( self.name + ": EOF exception found" )
3049 main.log.error( self.name + ": " + self.handle.before )
3050 main.cleanAndExit()
3051 except Exception:
3052 main.log.exception( self.name + ": Uncaught exception!" )
3053 main.cleanAndExit()
3054
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003055 def addStaticRoute( self, subnet, intf):
3056 """
3057 Adds a static route to onos.
3058 Params:
3059 subnet: The subnet reaching through this route
3060 intf: The interface this route is reachable through
3061 """
3062 try:
3063 cmdStr = "route-add " + subnet + " " + intf
3064 handle = self.sendline( cmdStr )
3065 assert handle is not None, "Error in sendline"
3066 assert "Command not found:" not in handle, handle
3067 return handle
3068 except AssertionError:
3069 main.log.exception( "" )
3070 return None
3071 except pexpect.EOF:
3072 main.log.error( self.name + ": EOF exception found" )
3073 main.log.error( self.name + ": " + self.handle.before )
3074 main.cleanAndExit()
3075 except Exception:
3076 main.log.exception( self.name + ": Uncaught exception!" )
3077 main.cleanAndExit()
3078
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003079 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
3080 """
3081 Description:
3082 Check whether the number of groups for the given device id that
3083 are in ADDED state is bigger than minGroupCount.
3084 Required:
3085 * deviceId: device id to check the number of added group rules
3086 Optional:
3087 * minGroupCount: the number of groups to compare
3088 * core: if True, only check the number of core groups added
3089 * comparison: if 0, compare with greater than minFlowCount
3090 * if 1, compare with equal to minFlowCount
3091 Return:
3092 Returns the number of groups if it is bigger than minGroupCount,
3093 returns main.FALSE otherwise.
3094 """
3095 count = self.groupAddedCount( deviceId, core )
3096 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003097 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003098 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
3099
You Wangc02f3be2018-05-18 12:14:23 -07003100 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003101 """
3102 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07003103 deviceId: Id of the device from which we retrieve groups
3104 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003105 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003106 try:
You Wangc02f3be2018-05-18 12:14:23 -07003107 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
3108 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003109 assert handle is not None, "Error in sendline"
3110 assert "Command not found:" not in handle, handle
3111 return handle
3112 except AssertionError:
3113 main.log.exception( "" )
3114 return None
3115 except TypeError:
3116 main.log.exception( self.name + ": Object not as expected" )
3117 return None
3118 except pexpect.EOF:
3119 main.log.error( self.name + ": EOF exception found" )
3120 main.log.error( self.name + ": " + self.handle.before )
3121 main.cleanAndExit()
3122 except Exception:
3123 main.log.exception( self.name + ": Uncaught exception!" )
3124 main.cleanAndExit()
3125
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003126 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003127 """
3128 Description:
3129 Check whether the number of flow rules for the given device id that
3130 are in ADDED state is bigger than minFlowCount.
3131 Required:
3132 * deviceId: device id to check the number of added flow rules
3133 Optional:
3134 * minFlowCount: the number of flow rules to compare
3135 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003136 * comparison: if 0, compare with greater than minFlowCount
3137 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003138 Return:
3139 Returns the number of flow rules if it is bigger than minFlowCount,
3140 returns main.FALSE otherwise.
3141 """
3142 count = self.flowAddedCount( deviceId, core )
3143 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003144 main.log.debug( "found {} flows".format( count ) )
Jon Hall39570262020-11-17 12:18:19 -08003145 return count if ((count >= expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003146
kelvin-onlabd3b64892015-01-20 13:26:24 -08003147 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003148 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003149 Use 'devices' function to obtain list of all devices
3150 and parse the result to obtain a list of all device
3151 id's. Returns this list. Returns empty list if no
3152 devices exist
kelvin8ec71442015-01-15 16:57:00 -08003153 List is ordered sequentially
3154
andrewonlab3e15ead2014-10-15 14:21:34 -04003155 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003156 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003157 the ids. By obtaining the list of device ids on the fly,
3158 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003159 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003160 try:
kelvin8ec71442015-01-15 16:57:00 -08003161 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003162 devicesStr = self.devices( jsonFormat=False )
3163 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003164
kelvin-onlabd3b64892015-01-20 13:26:24 -08003165 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003166 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003167 return idList
kelvin8ec71442015-01-15 16:57:00 -08003168
3169 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003170 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003171 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003172 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003173 # Split list further into arguments before and after string
3174 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003175 # append to idList
3176 for arg in tempList:
3177 idList.append( arg.split( "id=" )[ 1 ] )
3178 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003179
Jon Halld4d4b372015-01-28 16:02:41 -08003180 except TypeError:
3181 main.log.exception( self.name + ": Object not as expected" )
3182 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003183 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003184 main.log.error( self.name + ": EOF exception found" )
3185 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003186 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003187 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003188 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003189 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003190
kelvin-onlabd3b64892015-01-20 13:26:24 -08003191 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003192 """
andrewonlab7c211572014-10-15 16:45:20 -04003193 Uses 'nodes' function to obtain list of all nodes
3194 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003195 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003196 Returns:
3197 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003198 """
andrewonlab7c211572014-10-15 16:45:20 -04003199 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003200 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003201 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003202 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003203 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003204 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003205 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003206 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003207 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003208 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003209 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003210 except ( TypeError, ValueError ):
3211 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003212 return None
andrewonlab7c211572014-10-15 16:45:20 -04003213 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003214 main.log.error( self.name + ": EOF exception found" )
3215 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003216 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003217 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003218 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003219 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003220
kelvin-onlabd3b64892015-01-20 13:26:24 -08003221 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003222 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003223 Return the first device from the devices api whose 'id' contains 'dpid'
3224 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003225 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003226 try:
kelvin8ec71442015-01-15 16:57:00 -08003227 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003228 return None
3229 else:
kelvin8ec71442015-01-15 16:57:00 -08003230 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003231 rawDevices = self.devices()
3232 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003233 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003234 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003235 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3236 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003237 return device
3238 return None
Jon Hallc6793552016-01-19 14:18:37 -08003239 except ( TypeError, ValueError ):
3240 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003241 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003242 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003243 main.log.error( self.name + ": EOF exception found" )
3244 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003245 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003246 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003247 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003248 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003249
You Wang24139872016-05-03 11:48:47 -07003250 def getTopology( self, topologyOutput ):
3251 """
3252 Definition:
3253 Loads a json topology output
3254 Return:
3255 topology = current ONOS topology
3256 """
You Wang24139872016-05-03 11:48:47 -07003257 try:
3258 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003259 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003260 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003261 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003262 except ( TypeError, ValueError ):
3263 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3264 return None
You Wang24139872016-05-03 11:48:47 -07003265 except pexpect.EOF:
3266 main.log.error( self.name + ": EOF exception found" )
3267 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003268 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003269 except Exception:
3270 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003271 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003272
Jon Hall39570262020-11-17 12:18:19 -08003273 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, numoSCCs=1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003274 """
Jon Hallefbd9792015-03-05 16:11:36 -08003275 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003276 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003277 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003278
Flavio Castro82ee2f62016-06-07 15:04:12 -07003279 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003280 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003281 numoctrl = expected number of controllers
Jon Hall39570262020-11-17 12:18:19 -08003282 numoSCCs = Number of expected SCCs
You Wang24139872016-05-03 11:48:47 -07003283 logLevel = level to log to.
3284 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003285
Jon Hallefbd9792015-03-05 16:11:36 -08003286 Returns: main.TRUE if the number of switches and links are correct,
3287 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003288 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003289 """
Jon Hall42db6dc2014-10-24 19:03:48 -04003290 try:
You Wang13310252016-07-31 10:56:14 -07003291 summary = self.summary()
3292 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003293 except ( TypeError, ValueError ):
3294 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3295 return main.ERROR
3296 try:
3297 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003298 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003299 return main.ERROR
3300 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003301 # Is the number of switches is what we expected
3302 devices = topology.get( 'devices', False )
3303 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003304 nodes = summary.get( 'nodes', False )
Jon Hall39570262020-11-17 12:18:19 -08003305 SCCs = summary.get( 'SCC(s)', False )
3306 if devices is False or links is False or nodes is False or SCCs is False:
3307 main.log.warn( "Issues parsing topology and summary output" )
3308 main.log.debug( topology )
3309 main.log.debug( summary )
Jon Hall42db6dc2014-10-24 19:03:48 -04003310 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003311 switchCheck = ( int( devices ) == int( numoswitch ) )
Jon Hall39570262020-11-17 12:18:19 -08003312 if not switchCheck:
3313 main.log.debug( "switch Check Failed" )
Pier6a0c4de2018-03-18 16:01:30 -07003314 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Jon Hall39570262020-11-17 12:18:19 -08003315 if not linkCheck:
3316 main.log.debug( "link Check Failed" )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003317 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
Jon Hall39570262020-11-17 12:18:19 -08003318 if not nodeCheck:
3319 main.log.debug( "node Check Failed" )
3320 SCCsCheck = ( int( SCCs ) == int( numoSCCs ) ) or int( numoSCCs ) == -1
3321 if not SCCsCheck:
3322 main.log.debug( "SCCs Check Failed" )
3323 if switchCheck and linkCheck and nodeCheck and SCCsCheck:
kelvin8ec71442015-01-15 16:57:00 -08003324 # We expected the correct numbers
Jon Hall39570262020-11-17 12:18:19 -08003325 output = output + "The number of links, switches, nodes, and SCCs match "\
You Wang24139872016-05-03 11:48:47 -07003326 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003327 result = main.TRUE
3328 else:
You Wang24139872016-05-03 11:48:47 -07003329 output = output + \
Jon Hall627b1572020-12-01 12:01:15 -08003330 "The number of links, switches, nodes, and SCCs does not match " + \
You Wang24139872016-05-03 11:48:47 -07003331 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003332 result = main.FALSE
Jon Hall39570262020-11-17 12:18:19 -08003333 output = output + "\n ONOS sees %i devices " % int( devices )
3334 output = output + "(%i expected) " % int( numoswitch )
3335 if int( numolink ) >= 0:
Pier6a0c4de2018-03-18 16:01:30 -07003336 output = output + "and %i links " % int( links )
Jon Hall39570262020-11-17 12:18:19 -08003337 output = output + "(%i expected) " % int( numolink )
3338 if int( numoctrl ) >= 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003339 output = output + "and %i controllers " % int( nodes )
Jon Hall39570262020-11-17 12:18:19 -08003340 output = output + "(%i expected) " % int( numoctrl )
3341 if int( numoSCCs ) >= 0:
3342 output = output + "and %i SCCs " % int( SCCs )
3343 output = output + "(%i expected)" % int( numoSCCs )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003344 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003345 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003346 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003347 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003348 else:
You Wang24139872016-05-03 11:48:47 -07003349 main.log.info( output )
Jon Hall39570262020-11-17 12:18:19 -08003350 main.TOPOOUTPUT = output
kelvin8ec71442015-01-15 16:57:00 -08003351 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003352 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003353 main.log.error( self.name + ": EOF exception found" )
3354 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003355 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003356 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003357 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003358 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003359
kelvin-onlabd3b64892015-01-20 13:26:24 -08003360 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003361 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003362 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003363 deviceId must be the id of a device as seen in the onos devices command
3364 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003365 role must be either master, standby, or none
3366
Jon Halle3f39ff2015-01-13 11:50:53 -08003367 Returns:
3368 main.TRUE or main.FALSE based on argument verification and
3369 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003370 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003371 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003372 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003373 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003374 cmdStr = "device-role " +\
3375 str( deviceId ) + " " +\
3376 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003377 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003378 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003379 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003380 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003381 if re.search( "Error", handle ):
3382 # end color output to escape any colours
3383 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003384 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003385 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003386 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003387 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003388 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003389 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003390 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003391 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003392 except AssertionError:
3393 main.log.exception( "" )
3394 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003395 except TypeError:
3396 main.log.exception( self.name + ": Object not as expected" )
3397 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003398 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003399 main.log.error( self.name + ": EOF exception found" )
3400 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003401 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003402 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003403 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003404 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003405
kelvin-onlabd3b64892015-01-20 13:26:24 -08003406 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003407 """
Jon Hall0dd09952018-04-19 09:59:11 -07003408 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003409 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003410 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003411 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003412 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003413 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003414 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003415 cmdStr += " -j"
3416 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003417 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003418 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003419 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003420 except AssertionError:
3421 main.log.exception( "" )
3422 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003423 except TypeError:
3424 main.log.exception( self.name + ": Object not as expected" )
3425 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003426 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003427 main.log.error( self.name + ": EOF exception found" )
3428 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003429 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003430 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003431 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003432 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003433
kelvin-onlabd3b64892015-01-20 13:26:24 -08003434 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003435 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003436 CLI command to get the current leader for the Election test application
3437 NOTE: Requires installation of the onos-app-election feature
3438 Returns: Node IP of the leader if one exists
3439 None if none exists
3440 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003441 """
Jon Hall94fd0472014-12-08 11:52:42 -08003442 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003443 cmdStr = "election-test-leader"
3444 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003445 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003446 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003447 # Leader
3448 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003449 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003450 nodeSearch = re.search( leaderPattern, response )
3451 if nodeSearch:
3452 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003453 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003454 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003455 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003456 # no leader
3457 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003458 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003459 nullSearch = re.search( nullPattern, response )
3460 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003461 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003462 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003463 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003464 # error
Jon Hall0e240372018-05-02 11:21:57 -07003465 main.log.error( self.name + ": Error in electionTestLeader on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003466 ": " + "unexpected response" )
3467 main.log.error( repr( response ) )
3468 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003469 except AssertionError:
3470 main.log.exception( "" )
3471 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003472 except TypeError:
3473 main.log.exception( self.name + ": Object not as expected" )
3474 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003475 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003476 main.log.error( self.name + ": EOF exception found" )
3477 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003478 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003479 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003480 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003481 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003482
kelvin-onlabd3b64892015-01-20 13:26:24 -08003483 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003484 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003485 CLI command to run for leadership of the Election test application.
3486 NOTE: Requires installation of the onos-app-election feature
3487 Returns: Main.TRUE on success
3488 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003489 """
Jon Hall94fd0472014-12-08 11:52:42 -08003490 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003491 cmdStr = "election-test-run"
3492 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003493 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003494 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003495 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003496 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003497 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003498 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003499 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003500 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003501 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003502 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003503 # error
Jon Hall0e240372018-05-02 11:21:57 -07003504 main.log.error( self.name + ": Error in electionTestRun on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003505 ": " + "unexpected response" )
3506 main.log.error( repr( response ) )
3507 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003508 except AssertionError:
3509 main.log.exception( "" )
3510 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003511 except TypeError:
3512 main.log.exception( self.name + ": Object not as expected" )
3513 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003514 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003515 main.log.error( self.name + ": EOF exception found" )
3516 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003517 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003518 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003519 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003520 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003521
kelvin-onlabd3b64892015-01-20 13:26:24 -08003522 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003523 """
Jon Hall94fd0472014-12-08 11:52:42 -08003524 * CLI command to withdraw the local node from leadership election for
3525 * the Election test application.
3526 #NOTE: Requires installation of the onos-app-election feature
3527 Returns: Main.TRUE on success
3528 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003529 """
Jon Hall94fd0472014-12-08 11:52:42 -08003530 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003531 cmdStr = "election-test-withdraw"
3532 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003533 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003534 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003535 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003536 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003537 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003538 if re.search( successPattern, response ):
3539 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003540 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003541 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003542 # error
Jon Hall0e240372018-05-02 11:21:57 -07003543 main.log.error( self.name + ": Error in electionTestWithdraw on " +
Jon Hall97cf84a2016-06-20 13:35:58 -07003544 self.name + ": " + "unexpected response" )
3545 main.log.error( repr( response ) )
3546 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003547 except AssertionError:
3548 main.log.exception( "" )
3549 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003550 except TypeError:
3551 main.log.exception( self.name + ": Object not as expected" )
3552 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003553 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003554 main.log.error( self.name + ": EOF exception found" )
3555 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003556 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003557 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003558 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003559 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003560
kelvin8ec71442015-01-15 16:57:00 -08003561 def getDevicePortsEnabledCount( self, dpid ):
3562 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003563 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003564 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003565 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003566 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003567 cmdStr = "onos:ports -e " + dpid + " | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003568 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003569 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003570 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003571 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003572 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003573 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003574 return output
Jon Hallc6793552016-01-19 14:18:37 -08003575 except AssertionError:
3576 main.log.exception( "" )
3577 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003578 except TypeError:
3579 main.log.exception( self.name + ": Object not as expected" )
3580 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003581 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003582 main.log.error( self.name + ": EOF exception found" )
3583 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003584 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003585 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003586 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003587 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003588
kelvin8ec71442015-01-15 16:57:00 -08003589 def getDeviceLinksActiveCount( self, dpid ):
3590 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003591 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003592 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003593 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003594 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003595 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003596 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003597 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003598 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003599 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003600 main.log.error( self.name + ": Error in getting ports " )
kelvin-onlab898a6c62015-01-16 14:13:53 -08003601 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003602 return output
Jon Hallc6793552016-01-19 14:18:37 -08003603 except AssertionError:
3604 main.log.exception( "" )
3605 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003606 except TypeError:
3607 main.log.exception( self.name + ": Object not as expected" )
3608 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003609 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003610 main.log.error( self.name + ": EOF exception found" )
3611 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003612 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003613 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003614 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003615 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003616
kelvin8ec71442015-01-15 16:57:00 -08003617 def getAllIntentIds( self ):
3618 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003619 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003620 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003621 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003622 cmdStr = "onos:intents | grep id="
3623 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003624 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003625 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003626 if re.search( "Error", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003627 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003628 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003629 return output
Jon Hallc6793552016-01-19 14:18:37 -08003630 except AssertionError:
3631 main.log.exception( "" )
3632 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003633 except TypeError:
3634 main.log.exception( self.name + ": Object not as expected" )
3635 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003636 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003637 main.log.error( self.name + ": EOF exception found" )
3638 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003639 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003640 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003641 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003642 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003643
Jon Hall73509952015-02-24 16:42:56 -08003644 def intentSummary( self ):
3645 """
Jon Hallefbd9792015-03-05 16:11:36 -08003646 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003647 """
3648 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003649 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003650 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003651 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003652 states.append( intent.get( 'state', None ) )
3653 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003654 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003655 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003656 except ( TypeError, ValueError ):
3657 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003658 return None
3659 except pexpect.EOF:
3660 main.log.error( self.name + ": EOF exception found" )
3661 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003662 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003663 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003664 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003665 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003666
Jon Hall61282e32015-03-19 11:34:11 -07003667 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003668 """
3669 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003670 Optional argument:
3671 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003672 """
Jon Hall63604932015-02-26 17:09:50 -08003673 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003674 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003675 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003676 cmdStr += " -j"
3677 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003678 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003679 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003680 return output
Jon Hallc6793552016-01-19 14:18:37 -08003681 except AssertionError:
3682 main.log.exception( "" )
3683 return None
Jon Hall63604932015-02-26 17:09:50 -08003684 except TypeError:
3685 main.log.exception( self.name + ": Object not as expected" )
3686 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003687 except pexpect.EOF:
3688 main.log.error( self.name + ": EOF exception found" )
3689 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003690 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003691 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003692 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003693 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003694
acsmarsa4a4d1e2015-07-10 16:01:24 -07003695 def leaderCandidates( self, jsonFormat=True ):
3696 """
3697 Returns the output of the leaders -c command.
3698 Optional argument:
3699 * jsonFormat - boolean indicating if you want output in json
3700 """
3701 try:
3702 cmdStr = "onos:leaders -c"
3703 if jsonFormat:
3704 cmdStr += " -j"
3705 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003706 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003707 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003708 return output
Jon Hallc6793552016-01-19 14:18:37 -08003709 except AssertionError:
3710 main.log.exception( "" )
3711 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003712 except TypeError:
3713 main.log.exception( self.name + ": Object not as expected" )
3714 return None
3715 except pexpect.EOF:
3716 main.log.error( self.name + ": EOF exception found" )
3717 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003718 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003719 except Exception:
3720 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003721 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003722
Jon Hallc6793552016-01-19 14:18:37 -08003723 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003724 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003725 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003726 topic parameter and an empty list if the topic doesn't exist
3727 If no leader is elected leader in the returned list will be "none"
3728 Returns None if there is a type error processing the json object
3729 """
3730 try:
Jon Hall6e709752016-02-01 13:38:46 -08003731 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003732 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003733 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003734 assert "Command not found:" not in rawOutput, rawOutput
3735 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003736 results = []
3737 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003738 if dict[ "topic" ] == topic:
3739 leader = dict[ "leader" ]
3740 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003741 results.append( leader )
3742 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003743 return results
Jon Hallc6793552016-01-19 14:18:37 -08003744 except AssertionError:
3745 main.log.exception( "" )
3746 return None
3747 except ( TypeError, ValueError ):
3748 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003749 return None
3750 except pexpect.EOF:
3751 main.log.error( self.name + ": EOF exception found" )
3752 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003753 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003754 except Exception:
3755 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003756 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003757
Jon Hall61282e32015-03-19 11:34:11 -07003758 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003759 """
3760 Returns the output of the intent Pending map.
3761 """
Jon Hall63604932015-02-26 17:09:50 -08003762 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003763 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003764 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003765 cmdStr += " -j"
3766 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003767 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003768 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003769 return output
Jon Hallc6793552016-01-19 14:18:37 -08003770 except AssertionError:
3771 main.log.exception( "" )
3772 return None
Jon Hall63604932015-02-26 17:09:50 -08003773 except TypeError:
3774 main.log.exception( self.name + ": Object not as expected" )
3775 return None
3776 except pexpect.EOF:
3777 main.log.error( self.name + ": EOF exception found" )
3778 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003779 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003780 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003781 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003782 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003783
Jon Hall2c8959e2016-12-16 12:17:34 -08003784 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003785 """
3786 Returns the output of the raft partitions command for ONOS.
3787 """
Jon Hall61282e32015-03-19 11:34:11 -07003788 # Sample JSON
3789 # {
3790 # "leader": "tcp://10.128.30.11:7238",
3791 # "members": [
3792 # "tcp://10.128.30.11:7238",
3793 # "tcp://10.128.30.17:7238",
3794 # "tcp://10.128.30.13:7238",
3795 # ],
3796 # "name": "p1",
3797 # "term": 3
3798 # },
Jon Hall63604932015-02-26 17:09:50 -08003799 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003800 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003801 if candidates:
3802 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003803 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003804 cmdStr += " -j"
3805 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003806 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003807 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003808 return output
Jon Hallc6793552016-01-19 14:18:37 -08003809 except AssertionError:
3810 main.log.exception( "" )
3811 return None
Jon Hall63604932015-02-26 17:09:50 -08003812 except TypeError:
3813 main.log.exception( self.name + ": Object not as expected" )
3814 return None
3815 except pexpect.EOF:
3816 main.log.error( self.name + ": EOF exception found" )
3817 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003818 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003819 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003820 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003821 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003822
Jon Halle9f909e2016-09-23 10:43:12 -07003823 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003824 """
3825 Returns the output of the apps command for ONOS. This command lists
3826 information about installed ONOS applications
3827 """
3828 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003829 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003830 # "description":"ONOS OpenFlow protocol southbound providers",
3831 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003832 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003833 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003834 cmdStr = "onos:apps"
Jon Hallf03ae762019-01-22 13:25:27 -08003835 expectJson = False
Jon Halle9f909e2016-09-23 10:43:12 -07003836 if summary:
3837 cmdStr += " -s"
3838 if active:
3839 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003840 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003841 cmdStr += " -j"
Jon Hallf03ae762019-01-22 13:25:27 -08003842 expectJson = True
3843 output = self.sendline( cmdStr, expectJson=expectJson )
Jon Halla495f562016-05-16 18:03:26 -07003844 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003845 assert "Command not found:" not in output, output
3846 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003847 return output
Jon Hallbe379602015-03-24 13:39:32 -07003848 # FIXME: look at specific exceptions/Errors
3849 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07003850 main.log.exception( self.name + ": Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003851 return None
3852 except TypeError:
3853 main.log.exception( self.name + ": Object not as expected" )
3854 return None
3855 except pexpect.EOF:
3856 main.log.error( self.name + ": EOF exception found" )
3857 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003858 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003859 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003860 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003861 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003862
You Wangcdc51fe2018-08-12 17:14:56 -07003863 def appStatus( self, appName ):
Jon Hall146f1522015-03-24 15:33:24 -07003864 """
3865 Uses the onos:apps cli command to return the status of an application.
3866 Returns:
3867 "ACTIVE" - If app is installed and activated
3868 "INSTALLED" - If app is installed and deactivated
3869 "UNINSTALLED" - If app is not installed
3870 None - on error
3871 """
Jon Hall146f1522015-03-24 15:33:24 -07003872 try:
3873 if not isinstance( appName, types.StringType ):
3874 main.log.error( self.name + ".appStatus(): appName must be" +
3875 " a string" )
3876 return None
3877 output = self.apps( jsonFormat=True )
3878 appsJson = json.loads( output )
3879 state = None
3880 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003881 if appName == app.get( 'name' ):
3882 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003883 break
3884 if state == "ACTIVE" or state == "INSTALLED":
3885 return state
3886 elif state is None:
You Wang0d9f2c02018-08-10 14:56:32 -07003887 main.log.warn( "{} app not found".format( appName ) )
Jon Hall146f1522015-03-24 15:33:24 -07003888 return "UNINSTALLED"
3889 elif state:
3890 main.log.error( "Unexpected state from 'onos:apps': " +
3891 str( state ) )
3892 return state
Jon Hallc6793552016-01-19 14:18:37 -08003893 except ( TypeError, ValueError ):
3894 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003895 return None
3896 except pexpect.EOF:
3897 main.log.error( self.name + ": EOF exception found" )
3898 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003899 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003900 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003901 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003902 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003903
Jon Hallbe379602015-03-24 13:39:32 -07003904 def app( self, appName, option ):
3905 """
3906 Interacts with the app command for ONOS. This command manages
3907 application inventory.
3908 """
Jon Hallbe379602015-03-24 13:39:32 -07003909 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003910 # Validate argument types
3911 valid = True
3912 if not isinstance( appName, types.StringType ):
3913 main.log.error( self.name + ".app(): appName must be a " +
3914 "string" )
3915 valid = False
3916 if not isinstance( option, types.StringType ):
3917 main.log.error( self.name + ".app(): option must be a string" )
3918 valid = False
3919 if not valid:
3920 return main.FALSE
3921 # Validate Option
3922 option = option.lower()
3923 # NOTE: Install may become a valid option
3924 if option == "activate":
3925 pass
3926 elif option == "deactivate":
3927 pass
3928 elif option == "uninstall":
3929 pass
3930 else:
3931 # Invalid option
3932 main.log.error( "The ONOS app command argument only takes " +
3933 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003934 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003935 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003936 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003937 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003938 assert output is not None, "Error in sendline"
3939 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003940 if "Error executing command" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003941 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hallbe379602015-03-24 13:39:32 -07003942 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003943 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003944 elif "No such application" in output:
3945 main.log.error( "The application '" + appName +
3946 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003947 return main.FALSE
3948 elif "Command not found:" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003949 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hall146f1522015-03-24 15:33:24 -07003950 str( output ) )
3951 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003952 elif "Unsupported command:" in output:
3953 main.log.error( "Incorrect command given to 'app': " +
3954 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003955 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003956 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003957 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003958 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003959 except AssertionError:
3960 main.log.exception( self.name + ": AssertionError exception found" )
3961 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003962 except TypeError:
3963 main.log.exception( self.name + ": Object not as expected" )
3964 return main.ERROR
3965 except pexpect.EOF:
3966 main.log.error( self.name + ": EOF exception found" )
3967 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003968 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003969 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003970 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003971 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003972
Jon Hallbd16b922015-03-26 17:53:15 -07003973 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003974 """
3975 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003976 appName is the hierarchical app name, not the feature name
3977 If check is True, method will check the status of the app after the
3978 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003979 Returns main.TRUE if the command was successfully sent
3980 main.FALSE if the cli responded with an error or given
3981 incorrect input
3982 """
3983 try:
3984 if not isinstance( appName, types.StringType ):
3985 main.log.error( self.name + ".activateApp(): appName must be" +
3986 " a string" )
3987 return main.FALSE
3988 status = self.appStatus( appName )
3989 if status == "INSTALLED":
3990 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003991 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003992 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003993 status = self.appStatus( appName )
3994 if status == "ACTIVE":
3995 return main.TRUE
3996 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003997 main.log.debug( "The state of application " +
3998 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003999 time.sleep( 1 )
4000 return main.FALSE
4001 else: # not 'check' or command didn't succeed
4002 return response
Jon Hall146f1522015-03-24 15:33:24 -07004003 elif status == "ACTIVE":
4004 return main.TRUE
4005 elif status == "UNINSTALLED":
4006 main.log.error( self.name + ": Tried to activate the " +
4007 "application '" + appName + "' which is not " +
4008 "installed." )
4009 else:
4010 main.log.error( "Unexpected return value from appStatus: " +
4011 str( status ) )
4012 return main.ERROR
4013 except TypeError:
4014 main.log.exception( self.name + ": Object not as expected" )
4015 return main.ERROR
4016 except pexpect.EOF:
4017 main.log.error( self.name + ": EOF exception found" )
4018 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004019 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004020 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004021 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004022 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07004023
Jon Hallbd16b922015-03-26 17:53:15 -07004024 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07004025 """
4026 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07004027 appName is the hierarchical app name, not the feature name
4028 If check is True, method will check the status of the app after the
4029 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07004030 Returns main.TRUE if the command was successfully sent
4031 main.FALSE if the cli responded with an error or given
4032 incorrect input
4033 """
4034 try:
4035 if not isinstance( appName, types.StringType ):
4036 main.log.error( self.name + ".deactivateApp(): appName must " +
4037 "be a string" )
4038 return main.FALSE
4039 status = self.appStatus( appName )
4040 if status == "INSTALLED":
4041 return main.TRUE
4042 elif status == "ACTIVE":
4043 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07004044 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004045 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004046 status = self.appStatus( appName )
4047 if status == "INSTALLED":
4048 return main.TRUE
4049 else:
4050 time.sleep( 1 )
4051 return main.FALSE
4052 else: # not check or command didn't succeed
4053 return response
Jon Hall146f1522015-03-24 15:33:24 -07004054 elif status == "UNINSTALLED":
4055 main.log.warn( self.name + ": Tried to deactivate the " +
4056 "application '" + appName + "' which is not " +
4057 "installed." )
4058 return main.TRUE
4059 else:
4060 main.log.error( "Unexpected return value from appStatus: " +
4061 str( status ) )
4062 return main.ERROR
4063 except TypeError:
4064 main.log.exception( self.name + ": Object not as expected" )
4065 return main.ERROR
4066 except pexpect.EOF:
4067 main.log.error( self.name + ": EOF exception found" )
4068 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004069 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004070 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004071 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004072 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07004073
Jon Hallbd16b922015-03-26 17:53:15 -07004074 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07004075 """
4076 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07004077 appName is the hierarchical app name, not the feature name
4078 If check is True, method will check the status of the app after the
4079 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07004080 Returns main.TRUE if the command was successfully sent
4081 main.FALSE if the cli responded with an error or given
4082 incorrect input
4083 """
4084 # TODO: check with Thomas about the state machine for apps
4085 try:
4086 if not isinstance( appName, types.StringType ):
4087 main.log.error( self.name + ".uninstallApp(): appName must " +
4088 "be a string" )
4089 return main.FALSE
4090 status = self.appStatus( appName )
4091 if status == "INSTALLED":
4092 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004093 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004094 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004095 status = self.appStatus( appName )
4096 if status == "UNINSTALLED":
4097 return main.TRUE
4098 else:
4099 time.sleep( 1 )
4100 return main.FALSE
4101 else: # not check or command didn't succeed
4102 return response
Jon Hall146f1522015-03-24 15:33:24 -07004103 elif status == "ACTIVE":
4104 main.log.warn( self.name + ": Tried to uninstall the " +
4105 "application '" + appName + "' which is " +
4106 "currently active." )
4107 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004108 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004109 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004110 status = self.appStatus( appName )
4111 if status == "UNINSTALLED":
4112 return main.TRUE
4113 else:
4114 time.sleep( 1 )
4115 return main.FALSE
4116 else: # not check or command didn't succeed
4117 return response
Jon Hall146f1522015-03-24 15:33:24 -07004118 elif status == "UNINSTALLED":
4119 return main.TRUE
4120 else:
4121 main.log.error( "Unexpected return value from appStatus: " +
4122 str( status ) )
4123 return main.ERROR
4124 except TypeError:
4125 main.log.exception( self.name + ": Object not as expected" )
4126 return main.ERROR
4127 except pexpect.EOF:
4128 main.log.error( self.name + ": EOF exception found" )
4129 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004130 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004131 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004132 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004133 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004134
4135 def appIDs( self, jsonFormat=True ):
4136 """
4137 Show the mappings between app id and app names given by the 'app-ids'
4138 cli command
4139 """
4140 try:
4141 cmdStr = "app-ids"
4142 if jsonFormat:
4143 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07004144 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004145 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004146 assert "Command not found:" not in output, output
4147 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07004148 return output
Jon Hallbd16b922015-03-26 17:53:15 -07004149 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004150 main.log.exception( self.name + ": Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07004151 return None
4152 except TypeError:
4153 main.log.exception( self.name + ": Object not as expected" )
4154 return None
4155 except pexpect.EOF:
4156 main.log.error( self.name + ": EOF exception found" )
4157 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004158 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004159 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004160 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004161 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004162
4163 def appToIDCheck( self ):
4164 """
4165 This method will check that each application's ID listed in 'apps' is
4166 the same as the ID listed in 'app-ids'. The check will also check that
4167 there are no duplicate IDs issued. Note that an app ID should be
4168 a globaly unique numerical identifier for app/app-like features. Once
4169 an ID is registered, the ID is never freed up so that if an app is
4170 reinstalled it will have the same ID.
4171
4172 Returns: main.TRUE if the check passes and
4173 main.FALSE if the check fails or
4174 main.ERROR if there is some error in processing the test
4175 """
4176 try:
Jon Hall0e240372018-05-02 11:21:57 -07004177 # Grab IDs
Jon Hallc6793552016-01-19 14:18:37 -08004178 rawJson = self.appIDs( jsonFormat=True )
4179 if rawJson:
4180 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004181 else:
Jon Hall0e240372018-05-02 11:21:57 -07004182 main.log.error( "app-ids returned nothing: " + repr( rawJson ) )
4183 return main.FALSE
4184
4185 # Grab Apps
Jon Hallc6793552016-01-19 14:18:37 -08004186 rawJson = self.apps( jsonFormat=True )
4187 if rawJson:
4188 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004189 else:
Jon Hallc6793552016-01-19 14:18:37 -08004190 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004191 return main.FALSE
Jon Hall0e240372018-05-02 11:21:57 -07004192
Jon Hallbd16b922015-03-26 17:53:15 -07004193 result = main.TRUE
4194 for app in apps:
4195 appID = app.get( 'id' )
4196 if appID is None:
4197 main.log.error( "Error parsing app: " + str( app ) )
4198 result = main.FALSE
4199 appName = app.get( 'name' )
4200 if appName is None:
4201 main.log.error( "Error parsing app: " + str( app ) )
4202 result = main.FALSE
4203 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004204 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004205 if not current: # if ids doesn't have this id
4206 result = main.FALSE
4207 main.log.error( "'app-ids' does not have the ID for " +
4208 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004209 main.log.debug( "apps command returned: " + str( app ) +
4210 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004211 elif len( current ) > 1:
4212 # there is more than one app with this ID
4213 result = main.FALSE
4214 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004215 elif not current[ 0 ][ 'name' ] == appName:
4216 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004217 result = main.FALSE
4218 main.log.error( "'app-ids' has " + str( currentName ) +
4219 " registered under id:" + str( appID ) +
4220 " but 'apps' has " + str( appName ) )
4221 else:
4222 pass # id and name match!
Jon Hall0e240372018-05-02 11:21:57 -07004223
Jon Hallbd16b922015-03-26 17:53:15 -07004224 # now make sure that app-ids has no duplicates
4225 idsList = []
4226 namesList = []
4227 for item in ids:
4228 idsList.append( item[ 'id' ] )
4229 namesList.append( item[ 'name' ] )
4230 if len( idsList ) != len( set( idsList ) ) or\
4231 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004232 main.log.error( "'app-ids' has some duplicate entries: \n"
4233 + json.dumps( ids,
4234 sort_keys=True,
4235 indent=4,
4236 separators=( ',', ': ' ) ) )
4237 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004238 return result
Jon Hallc6793552016-01-19 14:18:37 -08004239 except ( TypeError, ValueError ):
4240 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004241 return main.ERROR
4242 except pexpect.EOF:
4243 main.log.error( self.name + ": EOF exception found" )
4244 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004245 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004246 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004247 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004248 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004249
Jon Hallfb760a02015-04-13 15:35:03 -07004250 def getCfg( self, component=None, propName=None, short=False,
4251 jsonFormat=True ):
4252 """
4253 Get configuration settings from onos cli
4254 Optional arguments:
4255 component - Optionally only list configurations for a specific
4256 component. If None, all components with configurations
4257 are displayed. Case Sensitive string.
4258 propName - If component is specified, propName option will show
4259 only this specific configuration from that component.
4260 Case Sensitive string.
4261 jsonFormat - Returns output as json. Note that this will override
4262 the short option
4263 short - Short, less verbose, version of configurations.
4264 This is overridden by the json option
4265 returns:
4266 Output from cli as a string or None on error
4267 """
4268 try:
4269 baseStr = "cfg"
4270 cmdStr = " get"
4271 componentStr = ""
4272 if component:
4273 componentStr += " " + component
4274 if propName:
4275 componentStr += " " + propName
4276 if jsonFormat:
4277 baseStr += " -j"
Jon Hall22e94ce2019-01-15 14:52:17 -08004278 expectJson = True
Jon Hallfb760a02015-04-13 15:35:03 -07004279 elif short:
4280 baseStr += " -s"
Jon Hall22e94ce2019-01-15 14:52:17 -08004281 expectJson = False
4282 output = self.sendline( baseStr + cmdStr + componentStr, expectJson=expectJson )
Jon Halla495f562016-05-16 18:03:26 -07004283 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004284 assert "Command not found:" not in output, output
4285 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004286 return output
4287 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004288 main.log.exception( self.name + ": Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004289 return None
4290 except TypeError:
4291 main.log.exception( self.name + ": Object not as expected" )
4292 return None
4293 except pexpect.EOF:
4294 main.log.error( self.name + ": EOF exception found" )
4295 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004296 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004297 except Exception:
4298 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004299 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004300
4301 def setCfg( self, component, propName, value=None, check=True ):
4302 """
4303 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004304 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004305 component - The case sensitive name of the component whose
4306 property is to be set
4307 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004308 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004309 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004310 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004311 check - Boolean, Check whether the option was successfully set this
4312 only applies when a value is given.
4313 returns:
4314 main.TRUE on success or main.FALSE on failure. If check is False,
4315 will return main.TRUE unless there is an error
4316 """
4317 try:
4318 baseStr = "cfg"
4319 cmdStr = " set " + str( component ) + " " + str( propName )
4320 if value is not None:
4321 cmdStr += " " + str( value )
4322 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004323 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004324 assert "Command not found:" not in output, output
4325 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004326 if value and check:
4327 results = self.getCfg( component=str( component ),
4328 propName=str( propName ),
4329 jsonFormat=True )
4330 # Check if current value is what we just set
4331 try:
4332 jsonOutput = json.loads( results )
4333 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004334 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004335 main.log.exception( "Error parsing cfg output" )
4336 main.log.error( "output:" + repr( results ) )
4337 return main.FALSE
4338 if current == str( value ):
4339 return main.TRUE
4340 return main.FALSE
4341 return main.TRUE
4342 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004343 main.log.exception( self.name + ": Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004344 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004345 except ( TypeError, ValueError ):
4346 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004347 return main.FALSE
4348 except pexpect.EOF:
4349 main.log.error( self.name + ": EOF exception found" )
4350 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004351 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004352 except Exception:
4353 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004354 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004355
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004356 def distPrimitivesSend( self, cmd ):
4357 """
4358 Function to handle sending cli commands for the distributed primitives test app
4359
4360 This command will catch some exceptions and retry the command on some
4361 specific store exceptions.
4362
4363 Required arguments:
4364 cmd - The command to send to the cli
4365 returns:
4366 string containing the cli output
4367 None on Error
4368 """
4369 try:
4370 output = self.sendline( cmd )
4371 try:
4372 assert output is not None, "Error in sendline"
4373 # TODO: Maybe make this less hardcoded
4374 # ConsistentMap Exceptions
4375 assert "org.onosproject.store.service" not in output
4376 # Node not leader
4377 assert "java.lang.IllegalStateException" not in output
4378 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004379 main.log.error( self.name + ": Error in processing '" + cmd + "' " +
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004380 "command: " + str( output ) )
4381 retryTime = 30 # Conservative time, given by Madan
4382 main.log.info( "Waiting " + str( retryTime ) +
4383 "seconds before retrying." )
4384 time.sleep( retryTime ) # Due to change in mastership
4385 output = self.sendline( cmd )
4386 assert output is not None, "Error in sendline"
4387 assert "Command not found:" not in output, output
4388 assert "Error executing command" not in output, output
4389 main.log.info( self.name + ": " + output )
4390 return output
4391 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004392 main.log.exception( self.name + ": Error in processing '" + cmd + "' command." )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004393 return None
4394 except TypeError:
4395 main.log.exception( self.name + ": Object not as expected" )
4396 return None
4397 except pexpect.EOF:
4398 main.log.error( self.name + ": EOF exception found" )
4399 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004400 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004401 except Exception:
4402 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004403 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004404
Jon Hall390696c2015-05-05 17:13:41 -07004405 def setTestAdd( self, setName, values ):
4406 """
4407 CLI command to add elements to a distributed set.
4408 Arguments:
4409 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004410 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004411 Example usages:
4412 setTestAdd( "set1", "a b c" )
4413 setTestAdd( "set2", "1" )
4414 returns:
4415 main.TRUE on success OR
4416 main.FALSE if elements were already in the set OR
4417 main.ERROR on error
4418 """
4419 try:
4420 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004421 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004422 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4423 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004424 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004425 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004426 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004427 return main.FALSE
4428 else:
4429 main.log.error( self.name + ": setTestAdd did not" +
4430 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004431 main.log.debug( self.name + " actual: " + repr( output ) )
4432 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004433 except TypeError:
4434 main.log.exception( self.name + ": Object not as expected" )
4435 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004436 except Exception:
4437 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004438 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004439
4440 def setTestRemove( self, setName, values, clear=False, retain=False ):
4441 """
4442 CLI command to remove elements from a distributed set.
4443 Required arguments:
4444 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004445 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004446 Optional arguments:
4447 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004448 retain - Retain only the given values. (intersection of the
4449 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004450 returns:
4451 main.TRUE on success OR
4452 main.FALSE if the set was not changed OR
4453 main.ERROR on error
4454 """
4455 try:
4456 cmdStr = "set-test-remove "
4457 if clear:
4458 cmdStr += "-c " + str( setName )
4459 elif retain:
4460 cmdStr += "-r " + str( setName ) + " " + str( values )
4461 else:
4462 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004463 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004464 if clear:
4465 pattern = "Set " + str( setName ) + " cleared"
4466 if re.search( pattern, output ):
4467 return main.TRUE
4468 elif retain:
4469 positivePattern = str( setName ) + " was pruned to contain " +\
4470 "only elements of set \[(.*)\]"
4471 negativePattern = str( setName ) + " was not changed by " +\
4472 "retaining only elements of the set " +\
4473 "\[(.*)\]"
4474 if re.search( positivePattern, output ):
4475 return main.TRUE
4476 elif re.search( negativePattern, output ):
4477 return main.FALSE
4478 else:
4479 positivePattern = "\[(.*)\] was removed from the set " +\
4480 str( setName )
4481 if ( len( values.split() ) == 1 ):
4482 negativePattern = "\[(.*)\] was not in set " +\
4483 str( setName )
4484 else:
4485 negativePattern = "No element of \[(.*)\] was in set " +\
4486 str( setName )
4487 if re.search( positivePattern, output ):
4488 return main.TRUE
4489 elif re.search( negativePattern, output ):
4490 return main.FALSE
4491 main.log.error( self.name + ": setTestRemove did not" +
4492 " match expected output" )
4493 main.log.debug( self.name + " expected: " + pattern )
4494 main.log.debug( self.name + " actual: " + repr( output ) )
4495 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004496 except TypeError:
4497 main.log.exception( self.name + ": Object not as expected" )
4498 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004499 except Exception:
4500 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004501 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004502
4503 def setTestGet( self, setName, values="" ):
4504 """
4505 CLI command to get the elements in a distributed set.
4506 Required arguments:
4507 setName - The name of the set to remove from.
4508 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004509 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004510 returns:
4511 main.ERROR on error OR
4512 A list of elements in the set if no optional arguments are
4513 supplied OR
4514 A tuple containing the list then:
4515 main.FALSE if the given values are not in the set OR
4516 main.TRUE if the given values are in the set OR
4517 """
4518 try:
4519 values = str( values ).strip()
4520 setName = str( setName ).strip()
4521 length = len( values.split() )
4522 containsCheck = None
4523 # Patterns to match
4524 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004525 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004526 containsTrue = "Set " + setName + " contains the value " + values
4527 containsFalse = "Set " + setName + " did not contain the value " +\
4528 values
4529 containsAllTrue = "Set " + setName + " contains the the subset " +\
4530 setPattern
4531 containsAllFalse = "Set " + setName + " did not contain the the" +\
4532 " subset " + setPattern
4533
4534 cmdStr = "set-test-get "
4535 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004536 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004537 if length == 0:
4538 match = re.search( pattern, output )
4539 else: # if given values
4540 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004541 patternTrue = pattern + "\r\n" + containsTrue
4542 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004543 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004544 patternTrue = pattern + "\r\n" + containsAllTrue
4545 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004546 matchTrue = re.search( patternTrue, output )
4547 matchFalse = re.search( patternFalse, output )
4548 if matchTrue:
4549 containsCheck = main.TRUE
4550 match = matchTrue
4551 elif matchFalse:
4552 containsCheck = main.FALSE
4553 match = matchFalse
4554 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004555 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004556 "expected output" )
4557 main.log.debug( self.name + " expected: " + pattern )
4558 main.log.debug( self.name + " actual: " + repr( output ) )
4559 match = None
4560 if match:
4561 setMatch = match.group( 1 )
4562 if setMatch == '':
4563 setList = []
4564 else:
4565 setList = setMatch.split( ", " )
4566 if length > 0:
4567 return ( setList, containsCheck )
4568 else:
4569 return setList
4570 else: # no match
4571 main.log.error( self.name + ": setTestGet did not" +
4572 " match expected output" )
4573 main.log.debug( self.name + " expected: " + pattern )
4574 main.log.debug( self.name + " actual: " + repr( output ) )
4575 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004576 except TypeError:
4577 main.log.exception( self.name + ": Object not as expected" )
4578 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004579 except Exception:
4580 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004581 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004582
4583 def setTestSize( self, setName ):
4584 """
4585 CLI command to get the elements in a distributed set.
4586 Required arguments:
4587 setName - The name of the set to remove from.
4588 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004589 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004590 None on error
4591 """
4592 try:
4593 # TODO: Should this check against the number of elements returned
4594 # and then return true/false based on that?
4595 setName = str( setName ).strip()
4596 # Patterns to match
4597 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004598 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004599 setPattern
4600 cmdStr = "set-test-get -s "
4601 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004602 output = self.distPrimitivesSend( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -07004603 if output:
4604 match = re.search( pattern, output )
4605 if match:
4606 setSize = int( match.group( 1 ) )
4607 setMatch = match.group( 2 )
4608 if len( setMatch.split() ) == setSize:
4609 main.log.info( "The size returned by " + self.name +
4610 " matches the number of elements in " +
4611 "the returned set" )
4612 else:
4613 main.log.error( "The size returned by " + self.name +
4614 " does not match the number of " +
4615 "elements in the returned set." )
4616 return setSize
Jon Hall390696c2015-05-05 17:13:41 -07004617 else: # no match
4618 main.log.error( self.name + ": setTestGet did not" +
4619 " match expected output" )
4620 main.log.debug( self.name + " expected: " + pattern )
4621 main.log.debug( self.name + " actual: " + repr( output ) )
4622 return None
Jon Hall390696c2015-05-05 17:13:41 -07004623 except TypeError:
4624 main.log.exception( self.name + ": Object not as expected" )
4625 return None
Jon Hall390696c2015-05-05 17:13:41 -07004626 except Exception:
4627 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004628 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004629
Jon Hall80daded2015-05-27 16:07:00 -07004630 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004631 """
4632 Command to list the various counters in the system.
4633 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004634 if jsonFormat, a string of the json object returned by the cli
4635 command
4636 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004637 None on error
4638 """
Jon Hall390696c2015-05-05 17:13:41 -07004639 try:
Jon Hall390696c2015-05-05 17:13:41 -07004640 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004641 if jsonFormat:
4642 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004643 output = self.sendline( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08004644 main.log.debug( self.name + ": Counters unparsed: " + output )
4645 output = output.split( "\r\n" )[ -1 ]
4646 main.log.debug( self.name + ": Counters parsed: " + output )
Jon Halla495f562016-05-16 18:03:26 -07004647 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004648 assert "Command not found:" not in output, output
4649 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004650 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004651 return output
Jon Hall390696c2015-05-05 17:13:41 -07004652 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004653 main.log.exception( self.name + ": Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004654 return None
Jon Hall390696c2015-05-05 17:13:41 -07004655 except TypeError:
4656 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004657 return None
Jon Hall390696c2015-05-05 17:13:41 -07004658 except pexpect.EOF:
4659 main.log.error( self.name + ": EOF exception found" )
4660 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004661 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004662 except Exception:
4663 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004664 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004665
Jon Hall935db192016-04-19 00:22:04 -07004666 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004667 """
Jon Halle1a3b752015-07-22 13:02:46 -07004668 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004669 Required arguments:
4670 counter - The name of the counter to increment.
4671 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004672 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004673 returns:
4674 integer value of the counter or
4675 None on Error
4676 """
4677 try:
4678 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004679 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004680 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004681 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004682 if delta != 1:
4683 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004684 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004685 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004686 match = re.search( pattern, output )
4687 if match:
4688 return int( match.group( 1 ) )
4689 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004690 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004691 " match expected output." )
4692 main.log.debug( self.name + " expected: " + pattern )
4693 main.log.debug( self.name + " actual: " + repr( output ) )
4694 return None
Jon Hall390696c2015-05-05 17:13:41 -07004695 except TypeError:
4696 main.log.exception( self.name + ": Object not as expected" )
4697 return None
Jon Hall390696c2015-05-05 17:13:41 -07004698 except Exception:
4699 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004700 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004701
Jon Hall935db192016-04-19 00:22:04 -07004702 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004703 """
4704 CLI command to get a distributed counter then add a delta to it.
4705 Required arguments:
4706 counter - The name of the counter to increment.
4707 Optional arguments:
4708 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004709 returns:
4710 integer value of the counter or
4711 None on Error
4712 """
4713 try:
4714 counter = str( counter )
4715 delta = int( delta )
4716 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004717 cmdStr += counter
4718 if delta != 1:
4719 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004720 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004721 pattern = counter + " was updated to (-?\d+)"
4722 match = re.search( pattern, output )
4723 if match:
4724 return int( match.group( 1 ) )
4725 else:
4726 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4727 " match expected output." )
4728 main.log.debug( self.name + " expected: " + pattern )
4729 main.log.debug( self.name + " actual: " + repr( output ) )
4730 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004731 except TypeError:
4732 main.log.exception( self.name + ": Object not as expected" )
4733 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004734 except Exception:
4735 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004736 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004737
4738 def valueTestGet( self, valueName ):
4739 """
4740 CLI command to get the value of an atomic value.
4741 Required arguments:
4742 valueName - The name of the value to get.
4743 returns:
4744 string value of the value or
4745 None on Error
4746 """
4747 try:
4748 valueName = str( valueName )
4749 cmdStr = "value-test "
4750 operation = "get"
4751 cmdStr = "value-test {} {}".format( valueName,
4752 operation )
4753 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08004754 main.log.debug( self.name + ": value test unparsed: " + output )
4755 output = output.split( "\r\n" )[ -1 ]
4756 main.log.debug( self.name + ": value test parsed: " + output )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004757 pattern = "(\w+)"
4758 match = re.search( pattern, output )
4759 if match:
4760 return match.group( 1 )
4761 else:
4762 main.log.error( self.name + ": valueTestGet did not" +
4763 " match expected output." )
4764 main.log.debug( self.name + " expected: " + pattern )
4765 main.log.debug( self.name + " actual: " + repr( output ) )
4766 return None
4767 except TypeError:
4768 main.log.exception( self.name + ": Object not as expected" )
4769 return None
4770 except Exception:
4771 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004772 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004773
4774 def valueTestSet( self, valueName, newValue ):
4775 """
4776 CLI command to set the value of an atomic value.
4777 Required arguments:
4778 valueName - The name of the value to set.
4779 newValue - The value to assign to the given value.
4780 returns:
4781 main.TRUE on success or
4782 main.ERROR on Error
4783 """
4784 try:
4785 valueName = str( valueName )
4786 newValue = str( newValue )
4787 operation = "set"
4788 cmdStr = "value-test {} {} {}".format( valueName,
4789 operation,
4790 newValue )
4791 output = self.distPrimitivesSend( cmdStr )
4792 if output is not None:
4793 return main.TRUE
4794 else:
4795 return main.ERROR
4796 except TypeError:
4797 main.log.exception( self.name + ": Object not as expected" )
4798 return main.ERROR
4799 except Exception:
4800 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004801 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004802
4803 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4804 """
4805 CLI command to compareAndSet the value of an atomic value.
4806 Required arguments:
4807 valueName - The name of the value.
4808 oldValue - Compare the current value of the atomic value to this
4809 newValue - If the value equals oldValue, set the value to newValue
4810 returns:
4811 main.TRUE on success or
4812 main.FALSE on failure or
4813 main.ERROR on Error
4814 """
4815 try:
4816 valueName = str( valueName )
4817 oldValue = str( oldValue )
4818 newValue = str( newValue )
4819 operation = "compareAndSet"
4820 cmdStr = "value-test {} {} {} {}".format( valueName,
4821 operation,
4822 oldValue,
4823 newValue )
4824 output = self.distPrimitivesSend( cmdStr )
4825 pattern = "(\w+)"
4826 match = re.search( pattern, output )
4827 if match:
4828 result = match.group( 1 )
4829 if result == "true":
4830 return main.TRUE
4831 elif result == "false":
4832 return main.FALSE
4833 else:
4834 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4835 " match expected output." )
4836 main.log.debug( self.name + " expected: " + pattern )
4837 main.log.debug( self.name + " actual: " + repr( output ) )
4838 return main.ERROR
4839 except TypeError:
4840 main.log.exception( self.name + ": Object not as expected" )
4841 return main.ERROR
4842 except Exception:
4843 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004844 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004845
4846 def valueTestGetAndSet( self, valueName, newValue ):
4847 """
4848 CLI command to getAndSet the value of an atomic value.
4849 Required arguments:
4850 valueName - The name of the value to get.
4851 newValue - The value to assign to the given value
4852 returns:
4853 string value of the value or
4854 None on Error
4855 """
4856 try:
4857 valueName = str( valueName )
4858 cmdStr = "value-test "
4859 operation = "getAndSet"
4860 cmdStr += valueName + " " + operation
4861 cmdStr = "value-test {} {} {}".format( valueName,
4862 operation,
4863 newValue )
4864 output = self.distPrimitivesSend( cmdStr )
4865 pattern = "(\w+)"
4866 match = re.search( pattern, output )
4867 if match:
4868 return match.group( 1 )
4869 else:
4870 main.log.error( self.name + ": valueTestGetAndSet did not" +
4871 " match expected output." )
4872 main.log.debug( self.name + " expected: " + pattern )
4873 main.log.debug( self.name + " actual: " + repr( output ) )
4874 return None
4875 except TypeError:
4876 main.log.exception( self.name + ": Object not as expected" )
4877 return None
4878 except Exception:
4879 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004880 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004881
4882 def valueTestDestroy( self, valueName ):
4883 """
4884 CLI command to destroy an atomic value.
4885 Required arguments:
4886 valueName - The name of the value to destroy.
4887 returns:
4888 main.TRUE on success or
4889 main.ERROR on Error
4890 """
4891 try:
4892 valueName = str( valueName )
4893 cmdStr = "value-test "
4894 operation = "destroy"
4895 cmdStr += valueName + " " + operation
4896 output = self.distPrimitivesSend( cmdStr )
4897 if output is not None:
4898 return main.TRUE
4899 else:
4900 return main.ERROR
4901 except TypeError:
4902 main.log.exception( self.name + ": Object not as expected" )
4903 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004904 except Exception:
4905 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004906 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004907
YPZhangfebf7302016-05-24 16:45:56 -07004908 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004909 """
4910 Description: Execute summary command in onos
4911 Returns: json object ( summary -j ), returns main.FALSE if there is
4912 no output
4913
4914 """
4915 try:
4916 cmdStr = "summary"
4917 if jsonFormat:
4918 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004919 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004920 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004921 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004922 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004923 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004924 if not handle:
4925 main.log.error( self.name + ": There is no output in " +
4926 "summary command" )
4927 return main.FALSE
4928 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004929 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004930 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004931 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004932 except TypeError:
4933 main.log.exception( self.name + ": Object not as expected" )
4934 return None
4935 except pexpect.EOF:
4936 main.log.error( self.name + ": EOF exception found" )
4937 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004938 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004939 except Exception:
4940 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004941 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004942
Jon Hall06fd0df2021-01-25 15:50:06 -08004943 def getAddress( self):
4944 """
4945 Get the onos ip address from the cli. This is usefull when connecting using
4946 a container manager such as kubernetes. This function also sets self.address
4947 the value from ONOS.
4948
4949 Returns:
4950 The string value of the key or
4951 None on Error
4952 """
4953 try:
4954 output = self.summary()
4955 address = json.loads( output ).get( 'node' )
4956 self.address = address
4957 return address
You Wang327bad42021-03-24 14:19:58 -07004958 except ( TypeError, ValueError ):
Jon Hall06fd0df2021-01-25 15:50:06 -08004959 main.log.exception( self.name + ": Object not as expected" )
4960 return None
4961 except Exception:
4962 main.log.exception( self.name + ": Uncaught exception!" )
4963 main.cleanAndExit()
4964
Jon Hall935db192016-04-19 00:22:04 -07004965 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004966 """
4967 CLI command to get the value of a key in a consistent map using
4968 transactions. This a test function and can only get keys from the
4969 test map hard coded into the cli command
4970 Required arguments:
4971 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004972 returns:
4973 The string value of the key or
4974 None on Error
4975 """
4976 try:
4977 keyName = str( keyName )
4978 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004979 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004980 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004981 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4982 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004983 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004984 return None
4985 else:
4986 match = re.search( pattern, output )
4987 if match:
4988 return match.groupdict()[ 'value' ]
4989 else:
4990 main.log.error( self.name + ": transactionlMapGet did not" +
4991 " match expected output." )
4992 main.log.debug( self.name + " expected: " + pattern )
4993 main.log.debug( self.name + " actual: " + repr( output ) )
4994 return None
4995 except TypeError:
4996 main.log.exception( self.name + ": Object not as expected" )
4997 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004998 except Exception:
4999 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005000 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07005001
Jon Hall935db192016-04-19 00:22:04 -07005002 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07005003 """
5004 CLI command to put a value into 'numKeys' number of keys in a
5005 consistent map using transactions. This a test function and can only
5006 put into keys named 'Key#' of the test map hard coded into the cli command
5007 Required arguments:
5008 numKeys - Number of keys to add the value to
5009 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07005010 returns:
5011 A dictionary whose keys are the name of the keys put into the map
5012 and the values of the keys are dictionaries whose key-values are
5013 'value': value put into map and optionaly
5014 'oldValue': Previous value in the key or
5015 None on Error
5016
5017 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005018 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
5019 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07005020 """
5021 try:
5022 numKeys = str( numKeys )
5023 value = str( value )
5024 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07005025 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07005026 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07005027 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
5028 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
5029 results = {}
5030 for line in output.splitlines():
5031 new = re.search( newPattern, line )
5032 updated = re.search( updatedPattern, line )
5033 if new:
5034 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
5035 elif updated:
5036 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08005037 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07005038 else:
5039 main.log.error( self.name + ": transactionlMapGet did not" +
5040 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08005041 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
5042 newPattern,
5043 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07005044 main.log.debug( self.name + " actual: " + repr( output ) )
5045 return results
Jon Hall0e240372018-05-02 11:21:57 -07005046 except ( TypeError, AttributeError ):
Jon Hall2a5002c2015-08-21 16:49:11 -07005047 main.log.exception( self.name + ": Object not as expected" )
5048 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07005049 except Exception:
5050 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005051 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08005052
acsmarsdaea66c2015-09-03 11:44:06 -07005053 def maps( self, jsonFormat=True ):
5054 """
5055 Description: Returns result of onos:maps
5056 Optional:
5057 * jsonFormat: enable json formatting of output
5058 """
5059 try:
5060 cmdStr = "maps"
5061 if jsonFormat:
5062 cmdStr += " -j"
5063 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07005064 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005065 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07005066 return handle
Jon Hallc6793552016-01-19 14:18:37 -08005067 except AssertionError:
5068 main.log.exception( "" )
5069 return None
acsmarsdaea66c2015-09-03 11:44:06 -07005070 except TypeError:
5071 main.log.exception( self.name + ": Object not as expected" )
5072 return None
5073 except pexpect.EOF:
5074 main.log.error( self.name + ": EOF exception found" )
5075 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005076 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07005077 except Exception:
5078 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005079 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005080
5081 def getSwController( self, uri, jsonFormat=True ):
5082 """
5083 Descrition: Gets the controller information from the device
5084 """
5085 try:
5086 cmd = "device-controllers "
5087 if jsonFormat:
5088 cmd += "-j "
5089 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07005090 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005091 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005092 return response
Jon Hallc6793552016-01-19 14:18:37 -08005093 except AssertionError:
5094 main.log.exception( "" )
5095 return None
GlennRC050596c2015-11-18 17:06:41 -08005096 except TypeError:
5097 main.log.exception( self.name + ": Object not as expected" )
5098 return None
5099 except pexpect.EOF:
5100 main.log.error( self.name + ": EOF exception found" )
5101 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005102 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005103 except Exception:
5104 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005105 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005106
5107 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
5108 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005109 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08005110
5111 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005112 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08005113 ip - String or List: The ip address of the controller.
5114 This parameter can be formed in a couple of different ways.
5115 VALID:
5116 10.0.0.1 - just the ip address
5117 tcp:10.0.0.1 - the protocol and the ip address
5118 tcp:10.0.0.1:6653 - the protocol and port can be specified,
5119 so that you can add controllers with different
5120 protocols and ports
5121 INVALID:
5122 10.0.0.1:6653 - this is not supported by ONOS
5123
5124 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
5125 port - The port number.
5126 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
5127
5128 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
5129 """
5130 try:
5131 cmd = "device-setcontrollers"
5132
5133 if jsonFormat:
5134 cmd += " -j"
5135 cmd += " " + uri
5136 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005137 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08005138 for item in ip:
5139 if ":" in item:
5140 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005141 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08005142 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005143 elif "." in sitem[ 1 ]:
5144 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08005145 else:
5146 main.log.error( "Malformed entry: " + item )
5147 raise TypeError
5148 else:
5149 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08005150 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07005151 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005152 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005153 if "Error" in response:
5154 main.log.error( response )
5155 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005156 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005157 except AssertionError:
5158 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005159 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005160 except TypeError:
5161 main.log.exception( self.name + ": Object not as expected" )
5162 return main.FALSE
5163 except pexpect.EOF:
5164 main.log.error( self.name + ": EOF exception found" )
5165 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005166 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005167 except Exception:
5168 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005169 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005170
5171 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005172 '''
GlennRC20fc6522015-12-23 23:26:57 -08005173 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005174 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08005175 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005176 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08005177 Returns:
5178 Returns main.FALSE if an exception is thrown or an error is present
5179 in the response. Otherwise, returns main.TRUE.
5180 NOTE:
5181 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005182 '''
GlennRC20fc6522015-12-23 23:26:57 -08005183 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005184 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07005185 deviceStr = device
5186 device = []
5187 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08005188
5189 for d in device:
5190 time.sleep( 1 )
5191 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07005192 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005193 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005194 if "Error" in response:
5195 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
5196 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005197 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005198 except AssertionError:
5199 main.log.exception( "" )
5200 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005201 except TypeError:
5202 main.log.exception( self.name + ": Object not as expected" )
5203 return main.FALSE
5204 except pexpect.EOF:
5205 main.log.error( self.name + ": EOF exception found" )
5206 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005207 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005208 except Exception:
5209 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005210 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005211
5212 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005213 '''
GlennRC20fc6522015-12-23 23:26:57 -08005214 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005215 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005216 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005217 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005218 Returns:
5219 Returns main.FALSE if an exception is thrown or an error is present
5220 in the response. Otherwise, returns main.TRUE.
5221 NOTE:
5222 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005223 '''
GlennRC20fc6522015-12-23 23:26:57 -08005224 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005225 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005226 host = list( host )
5227
5228 for h in host:
5229 time.sleep( 1 )
5230 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005231 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005232 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005233 if "Error" in response:
5234 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5235 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005236 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005237 except AssertionError:
5238 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005239 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005240 except TypeError:
5241 main.log.exception( self.name + ": Object not as expected" )
5242 return main.FALSE
5243 except pexpect.EOF:
5244 main.log.error( self.name + ": EOF exception found" )
5245 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005246 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005247 except Exception:
5248 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005249 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005250
YPZhangfebf7302016-05-24 16:45:56 -07005251 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005252 '''
GlennRCed771242016-01-13 17:02:47 -08005253 Description:
5254 Bring link down or up in the null-provider.
5255 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005256 begin - (string) One end of a device or switch.
5257 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005258 returns:
5259 main.TRUE if no exceptions were thrown and no Errors are
5260 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005261 '''
GlennRCed771242016-01-13 17:02:47 -08005262 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005263 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005264 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005265 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005266 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005267 if "Error" in response or "Failure" in response:
5268 main.log.error( response )
5269 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005270 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005271 except AssertionError:
5272 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005273 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005274 except TypeError:
5275 main.log.exception( self.name + ": Object not as expected" )
5276 return main.FALSE
5277 except pexpect.EOF:
5278 main.log.error( self.name + ": EOF exception found" )
5279 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005280 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005281 except Exception:
5282 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005283 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005284
Jon Hall2c8959e2016-12-16 12:17:34 -08005285 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005286 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005287 Description:
5288 Changes the state of port in an OF switch by means of the
5289 PORTSTATUS OF messages.
5290 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005291 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5292 port - (string) target port in the device. Ex: '2'
5293 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005294 returns:
5295 main.TRUE if no exceptions were thrown and no Errors are
5296 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005297 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005298 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005299 state = state.lower()
5300 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005301 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005302 response = self.sendline( cmd, showResponse=True )
5303 assert response is not None, "Error in sendline"
5304 assert "Command not found:" not in response, response
5305 if "Error" in response or "Failure" in response:
5306 main.log.error( response )
5307 return main.FALSE
5308 return main.TRUE
5309 except AssertionError:
5310 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005311 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005312 except TypeError:
5313 main.log.exception( self.name + ": Object not as expected" )
5314 return main.FALSE
5315 except pexpect.EOF:
5316 main.log.error( self.name + ": EOF exception found" )
5317 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005318 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005319 except Exception:
5320 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005321 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005322
5323 def logSet( self, level="INFO", app="org.onosproject" ):
5324 """
5325 Set the logging level to lvl for a specific app
5326 returns main.TRUE on success
5327 returns main.FALSE if Error occurred
5328 if noExit is True, TestON will not exit, but clean up
5329 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5330 Level defaults to INFO
5331 """
5332 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005333 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -08005334 self.handle.expect( self.karafPrompt )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005335
5336 response = self.handle.before
5337 if re.search( "Error", response ):
5338 return main.FALSE
5339 return main.TRUE
5340 except pexpect.TIMEOUT:
5341 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005342 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005343 except pexpect.EOF:
5344 main.log.error( self.name + ": EOF exception found" )
5345 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005346 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005347 except Exception:
5348 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005349 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005350
Jon Hall06fd0df2021-01-25 15:50:06 -08005351 def logList( self, saveValues=True ):
5352 """
5353 Gets the current log levels and optionally saves them
5354 returns a dict of the log levels or
5355 returns main.FALSE if Error occurred
5356 """
5357 try:
5358 self.handle.sendline( "log:list" )
5359 self.handle.expect( self.karafPrompt )
5360
5361 response = self.handle.before
5362 logLevels = {}
5363 for line in response.splitlines():
5364 parsed = line.split('│')
5365 logger = parsed[0].strip()
5366 if len( parsed ) != 2 or 'Level' in parsed[1] or logger[0] == '─':
5367 continue
5368 level = parsed[1].strip()
5369 logLevels[ logger ] = level
5370 if saveValues:
5371 self.logLevels = logLevels
5372 return logLevels
5373 except pexpect.TIMEOUT:
5374 main.log.exception( self.name + ": TIMEOUT exception found" )
5375 main.cleanAndExit()
5376 except pexpect.EOF:
5377 main.log.error( self.name + ": EOF exception found" )
5378 main.log.error( self.name + ": " + self.handle.before )
5379 main.cleanAndExit()
5380 except Exception:
5381 main.log.exception( self.name + ": Uncaught exception!" )
5382 main.cleanAndExit()
5383
You Wangdb8cd0a2016-05-26 15:19:45 -07005384 def getGraphDict( self, timeout=60, includeHost=False ):
5385 """
5386 Return a dictionary which describes the latest network topology data as a
5387 graph.
5388 An example of the dictionary:
5389 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5390 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5391 Each vertex should at least have an 'edges' attribute which describes the
5392 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005393 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005394 list of attributes.
5395 An example of the edges dictionary:
5396 'edges': { vertex2: { 'port': ..., 'weight': ... },
5397 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005398 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005399 in topology data.
5400 """
5401 graphDict = {}
5402 try:
5403 links = self.links()
5404 links = json.loads( links )
5405 devices = self.devices()
5406 devices = json.loads( devices )
5407 idToDevice = {}
5408 for device in devices:
5409 idToDevice[ device[ 'id' ] ] = device
5410 if includeHost:
5411 hosts = self.hosts()
5412 # FIXME: support 'includeHost' argument
5413 for link in links:
5414 nodeA = link[ 'src' ][ 'device' ]
5415 nodeB = link[ 'dst' ][ 'device' ]
5416 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005417 if nodeA not in graphDict.keys():
5418 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005419 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005420 'type': idToDevice[ nodeA ][ 'type' ],
5421 'available': idToDevice[ nodeA ][ 'available' ],
5422 'role': idToDevice[ nodeA ][ 'role' ],
5423 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5424 'hw': idToDevice[ nodeA ][ 'hw' ],
5425 'sw': idToDevice[ nodeA ][ 'sw' ],
5426 'serial': idToDevice[ nodeA ][ 'serial' ],
5427 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005428 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005429 else:
5430 # Assert nodeB is not connected to any current links of nodeA
You Wang7d14d642019-01-23 15:10:08 -08005431 # assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
5432 pass
Jon Halle0f0b342017-04-18 11:43:47 -07005433 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5434 'type': link[ 'type' ],
5435 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005436 return graphDict
5437 except ( TypeError, ValueError ):
5438 main.log.exception( self.name + ": Object not as expected" )
5439 return None
5440 except KeyError:
5441 main.log.exception( self.name + ": KeyError exception found" )
5442 return None
5443 except AssertionError:
5444 main.log.exception( self.name + ": AssertionError exception found" )
5445 return None
5446 except pexpect.EOF:
5447 main.log.error( self.name + ": EOF exception found" )
5448 main.log.error( self.name + ": " + self.handle.before )
5449 return None
5450 except Exception:
5451 main.log.exception( self.name + ": Uncaught exception!" )
5452 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005453
5454 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005455 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005456 Send command to check intent-perf summary
5457 Returns: dictionary for intent-perf summary
5458 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005459 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005460 cmd = "intent-perf -s"
5461 respDic = {}
5462 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005463 assert resp is not None, "Error in sendline"
5464 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005465 try:
5466 # Generate the dictionary to return
5467 for l in resp.split( "\n" ):
5468 # Delete any white space in line
5469 temp = re.sub( r'\s+', '', l )
5470 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005471 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005472
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005473 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005474 main.log.exception( self.name + ": Object not as expected" )
5475 return None
5476 except KeyError:
5477 main.log.exception( self.name + ": KeyError exception found" )
5478 return None
5479 except AssertionError:
5480 main.log.exception( self.name + ": AssertionError exception found" )
5481 return None
5482 except pexpect.EOF:
5483 main.log.error( self.name + ": EOF exception found" )
5484 main.log.error( self.name + ": " + self.handle.before )
5485 return None
5486 except Exception:
5487 main.log.exception( self.name + ": Uncaught exception!" )
5488 return None
5489 return respDic
5490
Chiyu Chengec63bde2016-11-17 18:11:36 -08005491 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005492 """
5493 Searches the latest ONOS log file for the given search term and
5494 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005495
chengchiyu08303a02016-09-08 17:40:26 -07005496 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005497 searchTerm:
5498 The string to grep from the ONOS log.
5499 startLine:
5500 The term that decides which line is the start to search the searchTerm in
5501 the karaf log. For now, startTerm only works in 'first' mode.
5502 logNum:
5503 In some extreme cases, one karaf log is not big enough to contain all the
5504 information.Because of this, search mutiply logs is necessary to capture
5505 the right result. logNum is the number of karaf logs that we need to search
5506 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005507 mode:
5508 all: return all the strings that contain the search term
5509 last: return the last string that contains the search term
5510 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005511 num: return the number of times that the searchTerm appears in the log
5512 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005513 """
5514 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005515 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005516 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005517 logPath = '/opt/onos/log/karaf.log.'
5518 logPaths = '/opt/onos/log/karaf.log'
5519 for i in range( 1, logNum ):
5520 logPaths = logPath + str( i ) + " " + logPaths
5521 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005522 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005523 # 100000000 is just a extreme large number to make sure this function can
5524 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005525 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005526 if mode == 'all':
5527 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005528 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005529 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005530 elif mode == 'first':
5531 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5532 elif mode == 'num':
You Wangd91a70f2019-01-03 15:28:10 -08005533 cmd = cmd + " | grep \'" + searchTerm + "\' | wc -l"
5534 num = self.lineCount( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005535 return num
You Wang6d301d42017-04-21 10:49:33 -07005536 elif mode == 'total':
Jon Halld5a94fb2018-11-13 14:32:23 -08005537 totalLines = self.lineCount( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005538 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005539 else:
5540 main.log.error( self.name + " unsupported mode" )
5541 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005542 before = self.sendline( cmd )
5543 before = before.splitlines()
5544 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005545 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005546 return returnLines
5547 except AssertionError:
5548 main.log.error( self.name + " searchTerm is not string type" )
5549 return None
5550 except pexpect.EOF:
5551 main.log.error( self.name + ": EOF exception found" )
5552 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005553 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005554 except pexpect.TIMEOUT:
5555 main.log.error( self.name + ": TIMEOUT exception found" )
5556 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005557 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005558 except Exception:
5559 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005560 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005561
5562 def vplsShow( self, jsonFormat=True ):
5563 """
5564 Description: Returns result of onos:vpls show, which should list the
5565 configured VPLS networks and the assigned interfaces.
5566 Optional:
5567 * jsonFormat: enable json formatting of output
5568 Returns:
5569 The output of the command or None on error.
5570 """
5571 try:
5572 cmdStr = "vpls show"
5573 if jsonFormat:
5574 raise NotImplementedError
5575 cmdStr += " -j"
5576 handle = self.sendline( cmdStr )
5577 assert handle is not None, "Error in sendline"
5578 assert "Command not found:" not in handle, handle
5579 return handle
5580 except AssertionError:
5581 main.log.exception( "" )
5582 return None
5583 except TypeError:
5584 main.log.exception( self.name + ": Object not as expected" )
5585 return None
5586 except pexpect.EOF:
5587 main.log.error( self.name + ": EOF exception found" )
5588 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005589 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005590 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005591 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005592 return None
5593 except Exception:
5594 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005595 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005596
5597 def parseVplsShow( self ):
5598 """
5599 Parse the cli output of 'vpls show' into json output. This is required
5600 as there is currently no json output available.
5601 """
5602 try:
5603 output = []
5604 raw = self.vplsShow( jsonFormat=False )
5605 namePat = "VPLS name: (?P<name>\w+)"
5606 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5607 encapPat = "Encapsulation: (?P<encap>\w+)"
5608 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5609 mIter = re.finditer( pattern, raw )
5610 for match in mIter:
5611 item = {}
5612 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005613 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005614 if ifaces == [ "" ]:
5615 ifaces = []
5616 item[ 'interfaces' ] = ifaces
5617 encap = match.group( 'encap' )
5618 if encap != 'NONE':
5619 item[ 'encapsulation' ] = encap.lower()
5620 output.append( item )
5621 return output
5622 except Exception:
5623 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005624 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005625
5626 def vplsList( self, jsonFormat=True ):
5627 """
5628 Description: Returns result of onos:vpls list, which should list the
5629 configured VPLS networks.
5630 Optional:
5631 * jsonFormat: enable json formatting of output
5632 """
5633 try:
5634 cmdStr = "vpls list"
5635 if jsonFormat:
5636 raise NotImplementedError
5637 cmdStr += " -j"
5638 handle = self.sendline( cmdStr )
5639 assert handle is not None, "Error in sendline"
5640 assert "Command not found:" not in handle, handle
5641 return handle
5642 except AssertionError:
5643 main.log.exception( "" )
5644 return None
5645 except TypeError:
5646 main.log.exception( self.name + ": Object not as expected" )
5647 return None
5648 except pexpect.EOF:
5649 main.log.error( self.name + ": EOF exception found" )
5650 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005651 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005652 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005653 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005654 return None
5655 except Exception:
5656 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005657 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005658
5659 def vplsCreate( self, network ):
5660 """
5661 CLI command to create a new VPLS network.
5662 Required arguments:
5663 network - String name of the network to create.
5664 returns:
5665 main.TRUE on success and main.FALSE on failure
5666 """
5667 try:
5668 network = str( network )
5669 cmdStr = "vpls create "
5670 cmdStr += network
5671 output = self.sendline( cmdStr )
5672 assert output is not None, "Error in sendline"
5673 assert "Command not found:" not in output, output
5674 assert "Error executing command" not in output, output
5675 assert "VPLS already exists:" not in output, output
5676 return main.TRUE
5677 except AssertionError:
5678 main.log.exception( "" )
5679 return main.FALSE
5680 except TypeError:
5681 main.log.exception( self.name + ": Object not as expected" )
5682 return main.FALSE
5683 except pexpect.EOF:
5684 main.log.error( self.name + ": EOF exception found" )
5685 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005686 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005687 except Exception:
5688 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005689 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005690
5691 def vplsDelete( self, network ):
5692 """
5693 CLI command to delete a VPLS network.
5694 Required arguments:
5695 network - Name of the network to delete.
5696 returns:
5697 main.TRUE on success and main.FALSE on failure
5698 """
5699 try:
5700 network = str( network )
5701 cmdStr = "vpls delete "
5702 cmdStr += network
5703 output = self.sendline( cmdStr )
5704 assert output is not None, "Error in sendline"
5705 assert "Command not found:" not in output, output
5706 assert "Error executing command" not in output, output
5707 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005708 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005709 return main.TRUE
5710 except AssertionError:
5711 main.log.exception( "" )
5712 return main.FALSE
5713 except TypeError:
5714 main.log.exception( self.name + ": Object not as expected" )
5715 return main.FALSE
5716 except pexpect.EOF:
5717 main.log.error( self.name + ": EOF exception found" )
5718 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005719 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005720 except Exception:
5721 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005722 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005723
5724 def vplsAddIface( self, network, iface ):
5725 """
5726 CLI command to add an interface to a VPLS network.
5727 Required arguments:
5728 network - Name of the network to add the interface to.
5729 iface - The ONOS name for an interface.
5730 returns:
5731 main.TRUE on success and main.FALSE on failure
5732 """
5733 try:
5734 network = str( network )
5735 iface = str( iface )
5736 cmdStr = "vpls add-if "
5737 cmdStr += network + " " + iface
5738 output = self.sendline( cmdStr )
5739 assert output is not None, "Error in sendline"
5740 assert "Command not found:" not in output, output
5741 assert "Error executing command" not in output, output
5742 assert "already associated to network" not in output, output
5743 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005744 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005745 return main.TRUE
5746 except AssertionError:
5747 main.log.exception( "" )
5748 return main.FALSE
5749 except TypeError:
5750 main.log.exception( self.name + ": Object not as expected" )
5751 return main.FALSE
5752 except pexpect.EOF:
5753 main.log.error( self.name + ": EOF exception found" )
5754 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005755 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005756 except Exception:
5757 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005758 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005759
5760 def vplsRemIface( self, network, iface ):
5761 """
5762 CLI command to remove an interface from a VPLS network.
5763 Required arguments:
5764 network - Name of the network to remove the interface from.
5765 iface - Name of the interface to remove.
5766 returns:
5767 main.TRUE on success and main.FALSE on failure
5768 """
5769 try:
5770 iface = str( iface )
5771 cmdStr = "vpls rem-if "
5772 cmdStr += network + " " + iface
5773 output = self.sendline( cmdStr )
5774 assert output is not None, "Error in sendline"
5775 assert "Command not found:" not in output, output
5776 assert "Error executing command" not in output, output
5777 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005778 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005779 return main.TRUE
5780 except AssertionError:
5781 main.log.exception( "" )
5782 return main.FALSE
5783 except TypeError:
5784 main.log.exception( self.name + ": Object not as expected" )
5785 return main.FALSE
5786 except pexpect.EOF:
5787 main.log.error( self.name + ": EOF exception found" )
5788 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005789 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005790 except Exception:
5791 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005792 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005793
5794 def vplsClean( self ):
5795 """
5796 Description: Clears the VPLS app configuration.
5797 Returns: main.TRUE on success and main.FALSE on failure
5798 """
5799 try:
5800 cmdStr = "vpls clean"
5801 handle = self.sendline( cmdStr )
5802 assert handle is not None, "Error in sendline"
5803 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005804 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005805 return handle
5806 except AssertionError:
5807 main.log.exception( "" )
5808 return main.FALSE
5809 except TypeError:
5810 main.log.exception( self.name + ": Object not as expected" )
5811 return main.FALSE
5812 except pexpect.EOF:
5813 main.log.error( self.name + ": EOF exception found" )
5814 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005815 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005816 except Exception:
5817 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005818 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005819
5820 def vplsSetEncap( self, network, encapType ):
5821 """
5822 CLI command to add an interface to a VPLS network.
5823 Required arguments:
5824 network - Name of the network to create.
5825 encapType - Type of encapsulation.
5826 returns:
5827 main.TRUE on success and main.FALSE on failure
5828 """
5829 try:
5830 network = str( network )
5831 encapType = str( encapType ).upper()
5832 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5833 cmdStr = "vpls set-encap "
5834 cmdStr += network + " " + encapType
5835 output = self.sendline( cmdStr )
5836 assert output is not None, "Error in sendline"
5837 assert "Command not found:" not in output, output
5838 assert "Error executing command" not in output, output
5839 assert "already associated to network" not in output, output
5840 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005841 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005842 return main.TRUE
5843 except AssertionError:
5844 main.log.exception( "" )
5845 return main.FALSE
5846 except TypeError:
5847 main.log.exception( self.name + ": Object not as expected" )
5848 return main.FALSE
5849 except pexpect.EOF:
5850 main.log.error( self.name + ": EOF exception found" )
5851 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005852 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005853 except Exception:
5854 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005855 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005856
5857 def interfaces( self, jsonFormat=True ):
5858 """
5859 Description: Returns result of interfaces command.
5860 Optional:
5861 * jsonFormat: enable json formatting of output
5862 Returns:
5863 The output of the command or None on error.
5864 """
5865 try:
5866 cmdStr = "interfaces"
5867 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005868 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005869 cmdStr += " -j"
5870 handle = self.sendline( cmdStr )
5871 assert handle is not None, "Error in sendline"
5872 assert "Command not found:" not in handle, handle
5873 return handle
5874 except AssertionError:
5875 main.log.exception( "" )
5876 return None
5877 except TypeError:
5878 main.log.exception( self.name + ": Object not as expected" )
5879 return None
5880 except pexpect.EOF:
5881 main.log.error( self.name + ": EOF exception found" )
5882 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005883 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005884 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005885 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005886 return None
5887 except Exception:
5888 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005889 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005890
5891 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005892 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005893 Get the timestamp of searchTerm from karaf log.
5894
5895 Arguments:
5896 splitTerm_before and splitTerm_after:
5897
5898 The terms that split the string that contains the timeStamp of
5899 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5900 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5901 and the splitTerm_after is "x"
5902
5903 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005904 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005905 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005906 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005907 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005908 return main.ERROR
5909 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005910 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005911 main.log.warn( "Captured timestamp string is empty" )
5912 return main.ERROR
5913 lines = lines[ 0 ]
5914 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005915 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005916 # get the target value
5917 line = lines.split( splitTerm_before )
5918 key = line[ 1 ].split( splitTerm_after )
5919 return int( key[ 0 ] )
5920 except IndexError:
5921 main.log.warn( "Index Error!" )
5922 return main.ERROR
5923 except AssertionError:
5924 main.log.warn( "Search Term Not Found " )
5925 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005926
5927 def workQueueAdd( self, queueName, value ):
5928 """
5929 CLI command to add a string to the specified Work Queue.
5930 This function uses the distributed primitives test app, which
5931 gives some cli access to distributed primitives for testing
5932 purposes only.
5933
5934 Required arguments:
5935 queueName - The name of the queue to add to
5936 value - The value to add to the queue
5937 returns:
5938 main.TRUE on success, main.FALSE on failure and
5939 main.ERROR on error.
5940 """
5941 try:
5942 queueName = str( queueName )
5943 value = str( value )
5944 prefix = "work-queue-test"
5945 operation = "add"
5946 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5947 output = self.distPrimitivesSend( cmdStr )
5948 if "Invalid operation name" in output:
5949 main.log.warn( output )
5950 return main.ERROR
5951 elif "Done" in output:
5952 return main.TRUE
5953 except TypeError:
5954 main.log.exception( self.name + ": Object not as expected" )
5955 return main.ERROR
5956 except Exception:
5957 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005958 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005959
5960 def workQueueAddMultiple( self, queueName, value1, value2 ):
5961 """
5962 CLI command to add two strings to the specified Work Queue.
5963 This function uses the distributed primitives test app, which
5964 gives some cli access to distributed primitives for testing
5965 purposes only.
5966
5967 Required arguments:
5968 queueName - The name of the queue to add to
5969 value1 - The first value to add to the queue
5970 value2 - The second value to add to the queue
5971 returns:
5972 main.TRUE on success, main.FALSE on failure and
5973 main.ERROR on error.
5974 """
5975 try:
5976 queueName = str( queueName )
5977 value1 = str( value1 )
5978 value2 = str( value2 )
5979 prefix = "work-queue-test"
5980 operation = "addMultiple"
5981 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5982 output = self.distPrimitivesSend( cmdStr )
5983 if "Invalid operation name" in output:
5984 main.log.warn( output )
5985 return main.ERROR
5986 elif "Done" in output:
5987 return main.TRUE
5988 except TypeError:
5989 main.log.exception( self.name + ": Object not as expected" )
5990 return main.ERROR
5991 except Exception:
5992 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005993 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005994
5995 def workQueueTakeAndComplete( self, queueName, number=1 ):
5996 """
5997 CLI command to take a value from the specified Work Queue and compelte it.
5998 This function uses the distributed primitives test app, which
5999 gives some cli access to distributed primitives for testing
6000 purposes only.
6001
6002 Required arguments:
6003 queueName - The name of the queue to add to
6004 number - The number of items to take and complete
6005 returns:
6006 main.TRUE on success, main.FALSE on failure and
6007 main.ERROR on error.
6008 """
6009 try:
6010 queueName = str( queueName )
6011 number = str( int( number ) )
6012 prefix = "work-queue-test"
6013 operation = "takeAndComplete"
6014 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
6015 output = self.distPrimitivesSend( cmdStr )
6016 if "Invalid operation name" in output:
6017 main.log.warn( output )
6018 return main.ERROR
6019 elif "Done" in output:
6020 return main.TRUE
6021 except TypeError:
6022 main.log.exception( self.name + ": Object not as expected" )
6023 return main.ERROR
6024 except Exception:
6025 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006026 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006027
6028 def workQueueDestroy( self, queueName ):
6029 """
6030 CLI command to destroy the specified Work Queue.
6031 This function uses the distributed primitives test app, which
6032 gives some cli access to distributed primitives for testing
6033 purposes only.
6034
6035 Required arguments:
6036 queueName - The name of the queue to add to
6037 returns:
6038 main.TRUE on success, main.FALSE on failure and
6039 main.ERROR on error.
6040 """
6041 try:
6042 queueName = str( queueName )
6043 prefix = "work-queue-test"
6044 operation = "destroy"
6045 cmdStr = " ".join( [ prefix, queueName, operation ] )
6046 output = self.distPrimitivesSend( cmdStr )
6047 if "Invalid operation name" in output:
6048 main.log.warn( output )
6049 return main.ERROR
6050 return main.TRUE
6051 except TypeError:
6052 main.log.exception( self.name + ": Object not as expected" )
6053 return main.ERROR
6054 except Exception:
6055 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006056 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006057
6058 def workQueueTotalPending( self, queueName ):
6059 """
6060 CLI command to get the Total Pending items of the specified Work Queue.
6061 This function uses the distributed primitives test app, which
6062 gives some cli access to distributed primitives for testing
6063 purposes only.
6064
6065 Required arguments:
6066 queueName - The name of the queue to add to
6067 returns:
6068 The number of Pending items in the specified work queue or
6069 None on error
6070 """
6071 try:
6072 queueName = str( queueName )
6073 prefix = "work-queue-test"
6074 operation = "totalPending"
6075 cmdStr = " ".join( [ prefix, queueName, operation ] )
6076 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08006077 main.log.debug( self.name + ": work queue unparsed: " + output )
6078 output = output.split( "\r\n" )[ -1 ]
6079 main.log.debug( self.name + ": work queue parsed: " + output )
Jon Halle0f0b342017-04-18 11:43:47 -07006080 pattern = r'\d+'
6081 if "Invalid operation name" in output:
6082 main.log.warn( output )
6083 return None
6084 else:
6085 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006086 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006087 except ( AttributeError, TypeError ):
6088 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6089 return None
6090 except Exception:
6091 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006092 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006093
6094 def workQueueTotalCompleted( self, queueName ):
6095 """
6096 CLI command to get the Total Completed items of the specified Work Queue.
6097 This function uses the distributed primitives test app, which
6098 gives some cli access to distributed primitives for testing
6099 purposes only.
6100
6101 Required arguments:
6102 queueName - The name of the queue to add to
6103 returns:
6104 The number of complete items in the specified work queue or
6105 None on error
6106 """
6107 try:
6108 queueName = str( queueName )
6109 prefix = "work-queue-test"
6110 operation = "totalCompleted"
6111 cmdStr = " ".join( [ prefix, queueName, operation ] )
6112 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08006113 main.log.debug( self.name + ": work queue unparsed: " + output )
6114 output = output.split( "\r\n" )[ -1 ]
6115 main.log.debug( self.name + ": work queue parsed: " + output )
Jon Halle0f0b342017-04-18 11:43:47 -07006116 pattern = r'\d+'
6117 if "Invalid operation name" in output:
6118 main.log.warn( output )
6119 return None
6120 else:
6121 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006122 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006123 except ( AttributeError, TypeError ):
6124 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6125 return None
6126 except Exception:
6127 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006128 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006129
6130 def workQueueTotalInProgress( self, queueName ):
6131 """
6132 CLI command to get the Total In Progress items of the specified Work Queue.
6133 This function uses the distributed primitives test app, which
6134 gives some cli access to distributed primitives for testing
6135 purposes only.
6136
6137 Required arguments:
6138 queueName - The name of the queue to add to
6139 returns:
6140 The number of In Progress items in the specified work queue or
6141 None on error
6142 """
6143 try:
6144 queueName = str( queueName )
6145 prefix = "work-queue-test"
6146 operation = "totalInProgress"
6147 cmdStr = " ".join( [ prefix, queueName, operation ] )
6148 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08006149 main.log.debug( self.name + ": work queue unparsed: " + output )
6150 output = output.split( "\r\n" )[ -1 ]
6151 main.log.debug( self.name + ": work queue parsed: " + output )
Jon Halle0f0b342017-04-18 11:43:47 -07006152 pattern = r'\d+'
6153 if "Invalid operation name" in output:
6154 main.log.warn( output )
6155 return None
6156 else:
6157 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006158 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006159 except ( AttributeError, TypeError ):
6160 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6161 return None
6162 except Exception:
6163 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006164 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00006165
6166 def events( self, args='-a' ):
6167 """
6168 Description: Returns events -a command output
6169 Optional:
6170 add other arguments
6171 """
6172 try:
6173 cmdStr = "events"
6174 if args:
6175 cmdStr += " " + args
6176 handle = self.sendline( cmdStr )
6177 assert handle is not None, "Error in sendline"
6178 assert "Command not found:" not in handle, handle
6179 return handle
6180 except AssertionError:
6181 main.log.exception( "" )
6182 return None
6183 except TypeError:
6184 main.log.exception( self.name + ": Object not as expected" )
6185 return None
6186 except pexpect.EOF:
6187 main.log.error( self.name + ": EOF exception found" )
6188 main.log.error( self.name + ": " + self.handle.before )
6189 main.cleanAndExit()
6190 except Exception:
6191 main.log.exception( self.name + ": Uncaught exception!" )
6192 main.cleanAndExit()
6193
6194 def getMaster( self, deviceID ):
6195 """
6196 Description: Obtains current master using "roles" command for a specific deviceID
6197 """
6198 try:
6199 return str( self.getRole( deviceID )[ 'master' ] )
6200 except AssertionError:
6201 main.log.exception( "" )
6202 return None
6203 except TypeError:
6204 main.log.exception( self.name + ": Object not as expected" )
6205 return None
6206 except pexpect.EOF:
6207 main.log.error( self.name + ": EOF exception found" )
6208 main.log.error( self.name + ": " + self.handle.before )
6209 main.cleanAndExit()
6210 except Exception:
6211 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07006212 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08006213
6214 def issu( self ):
6215 """
6216 Short summary of In-Service Software Upgrade status
6217
6218 Returns the output of the cli command or None on Error
6219 """
6220 try:
6221 cmdStr = "issu"
6222 handle = self.sendline( cmdStr )
6223 assert handle is not None, "Error in sendline"
6224 assert "Command not found:" not in handle, handle
6225 assert "Unsupported command:" not in handle, handle
6226 return handle
6227 except AssertionError:
6228 main.log.exception( "" )
6229 return None
6230 except TypeError:
6231 main.log.exception( self.name + ": Object not as expected" )
6232 return None
6233 except pexpect.EOF:
6234 main.log.error( self.name + ": EOF exception found" )
6235 main.log.error( self.name + ": " + self.handle.before )
6236 main.cleanAndExit()
6237 except Exception:
6238 main.log.exception( self.name + ": Uncaught exception!" )
6239 main.cleanAndExit()
6240
6241 def issuInit( self ):
6242 """
6243 Initiates an In-Service Software Upgrade
6244
6245 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6246 """
6247 try:
6248 cmdStr = "issu init"
6249 handle = self.sendline( cmdStr )
6250 assert handle is not None, "Error in sendline"
6251 assert "Command not found:" not in handle, handle
6252 assert "Unsupported command:" not in handle, handle
6253 if "Initialized" in handle:
6254 return main.TRUE
6255 else:
6256 return main.FALSE
6257 except AssertionError:
6258 main.log.exception( "" )
6259 return main.ERROR
6260 except TypeError:
6261 main.log.exception( self.name + ": Object not as expected" )
6262 return main.ERROR
6263 except pexpect.EOF:
6264 main.log.error( self.name + ": EOF exception found" )
6265 main.log.error( self.name + ": " + self.handle.before )
6266 main.cleanAndExit()
6267 except Exception:
6268 main.log.exception( self.name + ": Uncaught exception!" )
6269 main.cleanAndExit()
6270
6271 def issuUpgrade( self ):
6272 """
6273 Transitions stores to upgraded nodes
6274
6275 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6276 """
6277 try:
6278 cmdStr = "issu upgrade"
6279 handle = self.sendline( cmdStr )
6280 assert handle is not None, "Error in sendline"
6281 assert "Command not found:" not in handle, handle
6282 assert "Unsupported command:" not in handle, handle
6283 if "Upgraded" in handle:
6284 return main.TRUE
6285 else:
6286 return main.FALSE
6287 except AssertionError:
6288 main.log.exception( "" )
6289 return main.ERROR
6290 except TypeError:
6291 main.log.exception( self.name + ": Object not as expected" )
6292 return main.ERROR
6293 except pexpect.EOF:
6294 main.log.error( self.name + ": EOF exception found" )
6295 main.log.error( self.name + ": " + self.handle.before )
6296 main.cleanAndExit()
6297 except Exception:
6298 main.log.exception( self.name + ": Uncaught exception!" )
6299 main.cleanAndExit()
6300
6301 def issuCommit( self ):
6302 """
6303 Finalizes an In-Service Software Upgrade
6304
6305 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6306 """
6307 try:
6308 cmdStr = "issu commit"
6309 handle = self.sendline( cmdStr )
6310 assert handle is not None, "Error in sendline"
6311 assert "Command not found:" not in handle, handle
6312 assert "Unsupported command:" not in handle, handle
6313 # TODO: Check the version returned by this command
6314 if "Committed version" in handle:
6315 return main.TRUE
6316 else:
6317 return main.FALSE
6318 except AssertionError:
6319 main.log.exception( "" )
6320 return main.ERROR
6321 except TypeError:
6322 main.log.exception( self.name + ": Object not as expected" )
6323 return main.ERROR
6324 except pexpect.EOF:
6325 main.log.error( self.name + ": EOF exception found" )
6326 main.log.error( self.name + ": " + self.handle.before )
6327 main.cleanAndExit()
6328 except Exception:
6329 main.log.exception( self.name + ": Uncaught exception!" )
6330 main.cleanAndExit()
6331
6332 def issuRollback( self ):
6333 """
6334 Rolls back an In-Service Software Upgrade
6335
6336 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6337 """
6338 try:
6339 cmdStr = "issu rollback"
6340 handle = self.sendline( cmdStr )
6341 assert handle is not None, "Error in sendline"
6342 assert "Command not found:" not in handle, handle
6343 assert "Unsupported command:" not in handle, handle
6344 # TODO: Check the version returned by this command
6345 if "Rolled back to version" in handle:
6346 return main.TRUE
6347 else:
6348 return main.FALSE
6349 except AssertionError:
6350 main.log.exception( "" )
6351 return main.ERROR
6352 except TypeError:
6353 main.log.exception( self.name + ": Object not as expected" )
6354 return main.ERROR
6355 except pexpect.EOF:
6356 main.log.error( self.name + ": EOF exception found" )
6357 main.log.error( self.name + ": " + self.handle.before )
6358 main.cleanAndExit()
6359 except Exception:
6360 main.log.exception( self.name + ": Uncaught exception!" )
6361 main.cleanAndExit()
6362
6363 def issuReset( self ):
6364 """
6365 Resets the In-Service Software Upgrade status after a rollback
6366
6367 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6368 """
6369 try:
6370 cmdStr = "issu reset"
6371 handle = self.sendline( cmdStr )
6372 assert handle is not None, "Error in sendline"
6373 assert "Command not found:" not in handle, handle
6374 assert "Unsupported command:" not in handle, handle
6375 # TODO: Check the version returned by this command
6376 if "Reset version" in handle:
6377 return main.TRUE
6378 else:
6379 return main.FALSE
6380 except AssertionError:
6381 main.log.exception( "" )
6382 return main.ERROR
6383 except TypeError:
6384 main.log.exception( self.name + ": Object not as expected" )
6385 return main.ERROR
6386 except pexpect.EOF:
6387 main.log.error( self.name + ": EOF exception found" )
6388 main.log.error( self.name + ": " + self.handle.before )
6389 main.cleanAndExit()
6390 except Exception:
6391 main.log.exception( self.name + ": Uncaught exception!" )
6392 main.cleanAndExit()
6393
6394 def issuStatus( self ):
6395 """
6396 Status of an In-Service Software Upgrade
6397
6398 Returns the output of the cli command or None on Error
6399 """
6400 try:
6401 cmdStr = "issu status"
6402 handle = self.sendline( cmdStr )
6403 assert handle is not None, "Error in sendline"
6404 assert "Command not found:" not in handle, handle
6405 assert "Unsupported command:" not in handle, handle
6406 return handle
6407 except AssertionError:
6408 main.log.exception( "" )
6409 return None
6410 except TypeError:
6411 main.log.exception( self.name + ": Object not as expected" )
6412 return None
6413 except pexpect.EOF:
6414 main.log.error( self.name + ": EOF exception found" )
6415 main.log.error( self.name + ": " + self.handle.before )
6416 main.cleanAndExit()
6417 except Exception:
6418 main.log.exception( self.name + ": Uncaught exception!" )
6419 main.cleanAndExit()
6420
6421 def issuVersion( self ):
6422 """
6423 Get the version of an In-Service Software Upgrade
6424
6425 Returns the output of the cli command or None on Error
6426 """
6427 try:
6428 cmdStr = "issu version"
6429 handle = self.sendline( cmdStr )
6430 assert handle is not None, "Error in sendline"
6431 assert "Command not found:" not in handle, handle
6432 assert "Unsupported command:" not in handle, handle
6433 return handle
6434 except AssertionError:
6435 main.log.exception( "" )
6436 return None
6437 except TypeError:
6438 main.log.exception( self.name + ": Object not as expected" )
6439 return None
6440 except pexpect.EOF:
6441 main.log.error( self.name + ": EOF exception found" )
6442 main.log.error( self.name + ": " + self.handle.before )
6443 main.cleanAndExit()
6444 except Exception:
6445 main.log.exception( self.name + ": Uncaught exception!" )
6446 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006447
6448 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6449 """
6450 Create a multicast route by calling 'mcast-join' command
6451 sIP: source IP of the multicast route
6452 groupIP: group IP of the multicast route
6453 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6454 dPorts: a list of destination ports of the multicast route
6455 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6456 """
6457 try:
6458 cmdStr = "mcast-join"
6459 cmdStr += " " + str( sIP )
6460 cmdStr += " " + str( groupIP )
6461 cmdStr += " " + str( sPort )
6462 assert isinstance( dPorts, list )
6463 for dPort in dPorts:
6464 cmdStr += " " + str( dPort )
6465 handle = self.sendline( cmdStr )
6466 assert handle is not None, "Error in sendline"
6467 assert "Command not found:" not in handle, handle
6468 assert "Unsupported command:" not in handle, handle
6469 assert "Error executing command" not in handle, handle
6470 if "Added the mcast route" in handle:
6471 return main.TRUE
6472 else:
6473 return main.FALSE
6474 except AssertionError:
6475 main.log.exception( "" )
6476 return None
6477 except TypeError:
6478 main.log.exception( self.name + ": Object not as expected" )
6479 return None
6480 except pexpect.EOF:
6481 main.log.error( self.name + ": EOF exception found" )
6482 main.log.error( self.name + ": " + self.handle.before )
6483 main.cleanAndExit()
6484 except Exception:
6485 main.log.exception( self.name + ": Uncaught exception!" )
6486 main.cleanAndExit()
6487
6488 def mcastDelete( self, sIP, groupIP, dPorts ):
6489 """
6490 Delete a multicast route by calling 'mcast-delete' command
6491 sIP: source IP of the multicast route
6492 groupIP: group IP of the multicast route
6493 dPorts: a list of destination ports of the multicast route
6494 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6495 """
6496 try:
6497 cmdStr = "mcast-delete"
6498 cmdStr += " " + str( sIP )
6499 cmdStr += " " + str( groupIP )
6500 assert isinstance( dPorts, list )
6501 for dPort in dPorts:
6502 cmdStr += " " + str( dPort )
6503 handle = self.sendline( cmdStr )
6504 assert handle is not None, "Error in sendline"
6505 assert "Command not found:" not in handle, handle
6506 assert "Unsupported command:" not in handle, handle
6507 assert "Error executing command" not in handle, handle
6508 if "Updated the mcast route" in handle:
6509 return main.TRUE
6510 else:
6511 return main.FALSE
6512 except AssertionError:
6513 main.log.exception( "" )
6514 return None
6515 except TypeError:
6516 main.log.exception( self.name + ": Object not as expected" )
6517 return None
6518 except pexpect.EOF:
6519 main.log.error( self.name + ": EOF exception found" )
6520 main.log.error( self.name + ": " + self.handle.before )
6521 main.cleanAndExit()
6522 except Exception:
6523 main.log.exception( self.name + ": Uncaught exception!" )
6524 main.cleanAndExit()
6525
6526 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6527 """
6528 Create a multicast route by calling 'mcast-host-join' command
6529 sAddr: we can provide * for ASM or a specific address for SSM
6530 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006531 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006532 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6533 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6534 """
6535 try:
6536 cmdStr = "mcast-host-join"
6537 cmdStr += " -sAddr " + str( sAddr )
6538 cmdStr += " -gAddr " + str( gAddr )
6539 assert isinstance( srcs, list )
6540 for src in srcs:
6541 cmdStr += " -srcs " + str( src )
6542 assert isinstance( sinks, list )
6543 for sink in sinks:
6544 cmdStr += " -sinks " + str( sink )
6545 handle = self.sendline( cmdStr )
6546 assert handle is not None, "Error in sendline"
6547 assert "Command not found:" not in handle, handle
6548 assert "Unsupported command:" not in handle, handle
6549 assert "Error executing command" not in handle, handle
6550 if "Added the mcast route" in handle:
6551 return main.TRUE
6552 else:
6553 return main.FALSE
6554 except AssertionError:
6555 main.log.exception( "" )
6556 return None
6557 except TypeError:
6558 main.log.exception( self.name + ": Object not as expected" )
6559 return None
6560 except pexpect.EOF:
6561 main.log.error( self.name + ": EOF exception found" )
6562 main.log.error( self.name + ": " + self.handle.before )
6563 main.cleanAndExit()
6564 except Exception:
6565 main.log.exception( self.name + ": Uncaught exception!" )
6566 main.cleanAndExit()
6567
6568 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6569 """
6570 Delete multicast sink(s) by calling 'mcast-host-delete' command
6571 sAddr: we can provide * for ASM or a specific address for SSM
6572 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006573 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006574 will delete the route if not specified
6575 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6576 """
6577 try:
6578 cmdStr = "mcast-host-delete"
6579 cmdStr += " -sAddr " + str( sAddr )
6580 cmdStr += " -gAddr " + str( gAddr )
6581 if host:
6582 cmdStr += " -h " + str( host )
6583 handle = self.sendline( cmdStr )
6584 assert handle is not None, "Error in sendline"
6585 assert "Command not found:" not in handle, handle
6586 assert "Unsupported command:" not in handle, handle
6587 assert "Error executing command" not in handle, handle
6588 if "Updated the mcast route" in handle:
6589 return main.TRUE
6590 elif "Deleted the mcast route" in handle:
6591 return main.TRUE
6592 else:
6593 return main.FALSE
6594 except AssertionError:
6595 main.log.exception( "" )
6596 return None
6597 except TypeError:
6598 main.log.exception( self.name + ": Object not as expected" )
6599 return None
6600 except pexpect.EOF:
6601 main.log.error( self.name + ": EOF exception found" )
6602 main.log.error( self.name + ": " + self.handle.before )
6603 main.cleanAndExit()
6604 except Exception:
6605 main.log.exception( self.name + ": Uncaught exception!" )
6606 main.cleanAndExit()
6607
You Wang547893e2018-05-08 13:34:59 -07006608 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6609 """
6610 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6611 sAddr: we can provide * for ASM or a specific address for SSM
6612 gAddr: specifies multicast group address
6613 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6614 will delete the route if not specified
6615 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6616 """
6617 try:
6618 cmdStr = "mcast-sink-delete"
6619 cmdStr += " -sAddr " + str( sAddr )
6620 cmdStr += " -gAddr " + str( gAddr )
6621 if sink:
6622 cmdStr += " -s " + str( sink )
6623 handle = self.sendline( cmdStr )
6624 assert handle is not None, "Error in sendline"
6625 assert "Command not found:" not in handle, handle
6626 assert "Unsupported command:" not in handle, handle
6627 assert "Error executing command" not in handle, handle
6628 if "Updated the mcast route" in handle:
6629 return main.TRUE
6630 elif "Deleted the mcast route" in handle:
6631 return main.TRUE
6632 else:
6633 return main.FALSE
6634 except AssertionError:
6635 main.log.exception( "" )
6636 return None
6637 except TypeError:
6638 main.log.exception( self.name + ": Object not as expected" )
6639 return None
6640 except pexpect.EOF:
6641 main.log.error( self.name + ": EOF exception found" )
6642 main.log.error( self.name + ": " + self.handle.before )
6643 main.cleanAndExit()
6644 except Exception:
6645 main.log.exception( self.name + ": Uncaught exception!" )
6646 main.cleanAndExit()
6647
You Wange24d6272018-03-27 21:18:50 -07006648 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6649 """
6650 Delete multicast src(s) by calling 'mcast-source-delete' command
6651 sAddr: we can provide * for ASM or a specific address for SSM
6652 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006653 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 -07006654 will delete the route if not specified
6655 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6656 """
6657 try:
6658 cmdStr = "mcast-source-delete"
6659 cmdStr += " -sAddr " + str( sAddr )
6660 cmdStr += " -gAddr " + str( gAddr )
6661 if srcs:
6662 assert isinstance( srcs, list )
6663 for src in srcs:
6664 cmdStr += " -src " + str( src )
6665 handle = self.sendline( cmdStr )
6666 assert handle is not None, "Error in sendline"
6667 assert "Command not found:" not in handle, handle
6668 assert "Unsupported command:" not in handle, handle
6669 assert "Error executing command" not in handle, handle
6670 if "Updated the mcast route" in handle:
6671 return main.TRUE
6672 elif "Deleted the mcast route" in handle:
6673 return main.TRUE
6674 else:
6675 return main.FALSE
6676 except AssertionError:
6677 main.log.exception( "" )
6678 return None
6679 except TypeError:
6680 main.log.exception( self.name + ": Object not as expected" )
6681 return None
6682 except pexpect.EOF:
6683 main.log.error( self.name + ": EOF exception found" )
6684 main.log.error( self.name + ": " + self.handle.before )
6685 main.cleanAndExit()
6686 except Exception:
6687 main.log.exception( self.name + ": Uncaught exception!" )
6688 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006689
6690 def netcfg( self, jsonFormat=True, args="" ):
6691 """
6692 Run netcfg cli command with given args
6693 """
6694 try:
6695 cmdStr = "netcfg"
6696 if jsonFormat:
6697 cmdStr = cmdStr + " -j"
6698 if args:
6699 cmdStr = cmdStr + " " + str( args )
6700 handle = self.sendline( cmdStr )
6701 assert handle is not None, "Error in sendline"
6702 assert "Command not found:" not in handle, handle
6703 assert "Unsupported command:" not in handle, handle
6704 assert "Error executing command" not in handle, handle
6705 return handle
6706 except AssertionError:
6707 main.log.exception( "" )
6708 return None
6709 except TypeError:
6710 main.log.exception( self.name + ": Object not as expected" )
6711 return None
6712 except pexpect.EOF:
6713 main.log.error( self.name + ": EOF exception found" )
6714 main.log.error( self.name + ": " + self.handle.before )
6715 main.cleanAndExit()
6716 except Exception:
6717 main.log.exception( self.name + ": Uncaught exception!" )
6718 main.cleanAndExit()
6719
You Wang0fa76e72018-05-18 11:33:25 -07006720 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True, simple=False ):
You Wang5da39c82018-04-26 22:55:08 -07006721 """
You Wang54b1d672018-06-11 16:44:13 -07006722 Compose and return a list of t3-troubleshoot cli commands for given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006723 Options:
6724 sAddr: IP address of the source host
6725 dAddr: IP address of the destination host
You Wang0fa76e72018-05-18 11:33:25 -07006726 ipv6: True if hosts are IPv6
6727 verbose: return verbose t3 output if True
6728 simple: compose command for t3-troubleshoot-simple if True
You Wang5da39c82018-04-26 22:55:08 -07006729 """
6730 try:
6731 # Collect information of both hosts from onos
6732 hosts = self.hosts()
6733 hosts = json.loads( hosts )
6734 sHost = None
6735 dHost = None
6736 for host in hosts:
6737 if sAddr in host[ "ipAddresses" ]:
6738 sHost = host
6739 elif dAddr in host[ "ipAddresses" ]:
6740 dHost = host
6741 if sHost and dHost:
6742 break
6743 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang54b1d672018-06-11 16:44:13 -07006744 cmdList = []
You Wang5d9527b2018-05-29 17:08:54 -07006745 if simple:
6746 assert dHost, "Not able to find host with IP {}".format( dAddr )
You Wang54b1d672018-06-11 16:44:13 -07006747 cmdStr = "t3-troubleshoot-simple"
6748 if verbose:
6749 cmdStr += " -vv"
6750 if ipv6:
6751 cmdStr += " -et ipv6"
You Wang0fa76e72018-05-18 11:33:25 -07006752 cmdStr += " {}/{} {}/{}".format( sHost[ "mac" ], sHost[ "vlan" ], dHost[ "mac" ], dHost[ "vlan" ] )
You Wang54b1d672018-06-11 16:44:13 -07006753 cmdList.append( cmdStr )
You Wang0fa76e72018-05-18 11:33:25 -07006754 else:
You Wang54b1d672018-06-11 16:44:13 -07006755 for location in sHost[ "locations" ]:
6756 cmdStr = "t3-troubleshoot"
6757 if verbose:
6758 cmdStr += " -vv"
6759 if ipv6:
6760 cmdStr += " -et ipv6"
6761 cmdStr += " -s " + str( sAddr )
6762 cmdStr += " -sp " + str( location[ "elementId" ] ) + "/" + str( location[ "port" ] )
6763 cmdStr += " -sm " + str( sHost[ "mac" ] )
6764 if sHost[ "vlan" ] != "None":
6765 cmdStr += " -vid " + sHost[ "vlan" ]
6766 cmdStr += " -d " + str( dAddr )
6767 netcfg = self.netcfg( args="devices {}".format( location[ "elementId" ] ) )
6768 netcfg = json.loads( netcfg )
6769 assert netcfg, "Failed to get netcfg"
6770 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6771 cmdList.append( cmdStr )
6772 return cmdList
You Wang5da39c82018-04-26 22:55:08 -07006773 except AssertionError:
6774 main.log.exception( "" )
6775 return None
6776 except ( KeyError, TypeError ):
6777 main.log.exception( self.name + ": Object not as expected" )
6778 return None
6779 except Exception:
6780 main.log.exception( self.name + ": Uncaught exception!" )
6781 main.cleanAndExit()
6782
6783 def t3( self, sAddr, dAddr, ipv6=False ):
6784 """
You Wang54b1d672018-06-11 16:44:13 -07006785 Run t3-troubleshoot cli commands for all posible routes given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006786 Options:
6787 sAddr: IP address of the source host
6788 dAddr: IP address of the destination host
6789 """
6790 try:
You Wang54b1d672018-06-11 16:44:13 -07006791 cmdList = self.composeT3Command( sAddr, dAddr, ipv6 )
6792 assert cmdList is not None, "composeT3Command returned None"
6793 t3Output = ""
6794 for cmdStr in cmdList:
6795 handle = self.sendline( cmdStr )
6796 assert handle is not None, "Error in sendline"
6797 assert "Command not found:" not in handle, handle
6798 assert "Unsupported command:" not in handle, handle
6799 assert "Error executing command" not in handle, handle
6800 assert "Tracing packet" in handle
6801 t3Output += handle
6802 return t3Output
You Wang5da39c82018-04-26 22:55:08 -07006803 except AssertionError:
6804 main.log.exception( "" )
6805 return None
6806 except pexpect.EOF:
6807 main.log.error( self.name + ": EOF exception found" )
6808 main.log.error( self.name + ": " + self.handle.before )
6809 main.cleanAndExit()
6810 except Exception:
6811 main.log.exception( self.name + ": Uncaught exception!" )
6812 main.cleanAndExit()
Jon Hall3c0114c2020-08-11 15:07:42 -07006813
6814 def prepareForCLI( self, debug=True, maxRetries=120 ):
6815 """
6816 Prepare docker container to connect to onos cli
6817 """
6818 try:
6819 # Wait for log files to be created
6820 ready = 0
6821 retries = 0
6822 while not ready and retries < maxRetries:
6823 retries += 1
6824 self.handle.sendline( "ls -al /root/onos/apache-karaf-*/data/log" )
6825 ready = self.handle.expect( [ "No such file or directory", self.dockerPrompt ] )
6826 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
6827 if not ready:
6828 self.handle.expect( self.dockerPrompt )
6829 time.sleep( 1 )
Jon Hall3c0114c2020-08-11 15:07:42 -07006830
6831 cmdList = []
6832 cmdList.append( "apt-get update" )
6833 cmdList.append( "apt-get install -y openssh-server" )
6834 # Some built in scripts are hardcoded
6835 cmdList.append( "ln -s /root/onos /opt/onos" )
6836 cmdList.append( "ln -s /root/onos/apache-karaf-*/data/log /opt/onos/log" )
6837 cmdList.append( "ls -al /opt/onos" )
6838 output = ""
6839 for cmdStr in cmdList:
6840 self.handle.sendline( cmdStr )
Jon Hall627b1572020-12-01 12:01:15 -08006841 self.handle.expect( self.dockerPrompt, timeout=420 )
Jon Hall3c0114c2020-08-11 15:07:42 -07006842 self.handle.sendline( "" )
6843 self.handle.expect( self.dockerPrompt )
6844 handle = self.handle.before
6845 assert "command not found" not in handle, handle
6846 assert "No such file or directory" not in handle, handle
6847 output += handle
6848 if debug:
6849 main.log.debug( "%s: %s" % ( self.name, output ) )
6850 return output
6851 except AssertionError:
6852 main.log.exception( "" )
6853 return None
6854 except pexpect.EOF:
6855 main.log.error( self.name + ": EOF exception found" )
6856 main.log.error( self.name + ": " + self.handle.before )
6857 main.cleanAndExit()
6858 except Exception:
6859 main.log.exception( self.name + ": Uncaught exception!" )
6860 main.cleanAndExit()
6861
6862 def onosSecureSSH( self, userName="onos", userPWD="rocks" ):
6863 """
6864 Enables secure access to ONOS console
6865 by removing default users & keys.
6866
6867 bin/onos-user-password onos rocks
6868
6869 Returns: main.TRUE on success and main.FALSE on failure
6870 """
6871
6872 try:
6873 self.handle.sendline( "" )
6874 self.handle.expect( self.dockerPrompt )
6875
6876 self.handle.sendline( "[ ! -f ~/.ssh/id_rsa.pub ] && ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' -q" )
6877 self.handle.expect( self.dockerPrompt )
6878 main.log.debug( "%s: %s%s" % ( self.name, self.handle.before, self.handle.after ) )
6879
6880 self.handle.sendline( "bin/onos-user-key $(id -un) $(cut -d\\\\ -f2 ~/.ssh/id_rsa.pub)" )
6881 self.handle.expect( pexpect.TIMEOUT, timeout=10 )
6882 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
6883
6884 self.handle.sendline( "bin/onos-user-password %s %s" % ( userName, userPWD ) )
6885 i = self.handle.expect( [ "usage",
6886 self.dockerPrompt,
6887 pexpect.TIMEOUT ] )
6888 if i == 0:
6889 # malformed command
6890 main.log.warn( self.name + ": Could not parse onos-user-password command" )
6891 self.handle.expect( self.dockerPrompt )
6892 return main.FALSE
6893 elif i == 1:
6894 # Process started
6895 main.log.info( self.name + ": SSH password added for user " + userName )
6896 return main.TRUE
6897 elif i == 2:
6898 # timeout
6899 main.log.error( self.name + ": Failed to secure onos ssh " )
6900 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
6901 except pexpect.EOF:
6902 main.log.error( self.name + ": EOF exception found" )
6903 main.log.error( self.name + ": " + self.handle.before )
6904 main.cleanAndExit()
6905 except Exception:
6906 main.log.exception( self.name + ": Uncaught exception!" )
6907 main.cleanAndExit()