blob: 2c63c0c66d0fa337757c1a2cd2f781352b2eb621 [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 """
You Wang22e807e2021-03-29 10:53:38 -0700438 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
You Wang22e807e2021-03-29 10:53:38 -0700450 handle = self.sendline( "log:log " + lvlStr + " " + cmdStr, noExit=noExit )
451 assert handle is not None, "Error in sendline"
452 assert "Command not found:" not in handle, handle
453 if re.search( "Error", handle ):
454 main.log.error( self.name + ": Error in logging message" )
455 main.log.error( handle )
kelvin-onlab9f541032015-02-04 16:19:53 -0800456 return main.FALSE
YPZhangebf9eb52016-05-12 15:20:24 -0700457 else:
You Wang22e807e2021-03-29 10:53:38 -0700458 return main.TRUE
459 except AssertionError:
460 main.log.exception( "" )
461 return None
462 except TypeError:
463 main.log.exception( self.name + ": Object not as expected" )
464 return None
kelvin-onlab9f541032015-02-04 16:19:53 -0800465 except pexpect.EOF:
466 main.log.error( self.name + ": EOF exception found" )
467 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700468 if noExit:
469 main.cleanup()
470 return None
471 else:
Devin Lim44075962017-08-11 10:56:37 -0700472 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800473 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800474 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700475 if noExit:
476 main.cleanup()
477 return None
478 else:
Devin Lim44075962017-08-11 10:56:37 -0700479 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400480
Jon Hall0e240372018-05-02 11:21:57 -0700481 def clearBuffer( self, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800482 """
Jon Hall0e240372018-05-02 11:21:57 -0700483 Test cli connection and clear any left over output in the buffer
484 Optional Arguments:
485 debug - Defaults to False. If True, will enable debug logging.
486 timeout - Defaults to 10. Amount of time in seconds for a command to return
487 before a timeout.
488 noExit - Defaults to False. If True, will not exit TestON in the event of a
kelvin8ec71442015-01-15 16:57:00 -0800489 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400490 try:
Jon Halla495f562016-05-16 18:03:26 -0700491 # Try to reconnect if disconnected from cli
492 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700493 i = self.handle.expect( [ self.karafPrompt,
494 self.Prompt(),
495 pexpect.TIMEOUT ] )
Jon Hall0e240372018-05-02 11:21:57 -0700496 response = self.handle.before
Jon Halla495f562016-05-16 18:03:26 -0700497 if i == 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700498 main.log.error( self.name + ": onos cli session closed. " )
Jon Halla495f562016-05-16 18:03:26 -0700499 if self.onosIp:
500 main.log.warn( "Trying to reconnect " + self.onosIp )
501 reconnectResult = self.startOnosCli( self.onosIp )
502 if reconnectResult:
503 main.log.info( self.name + ": onos cli session reconnected." )
504 else:
505 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700506 if noExit:
507 return None
508 else:
Devin Lim44075962017-08-11 10:56:37 -0700509 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700510 else:
Devin Lim44075962017-08-11 10:56:37 -0700511 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700512 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700513 main.log.warn( "Timeout when testing cli responsiveness" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700514 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700515 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Hall6c9e2da2018-11-06 12:01:23 -0800516 self.handle.expect( self.karafPrompt )
Jon Halla495f562016-05-16 18:03:26 -0700517
Jon Hall0e240372018-05-02 11:21:57 -0700518 response += self.handle.before
Jon Hall14a03b52016-05-11 12:07:30 -0700519 if debug:
Jon Hall0e240372018-05-02 11:21:57 -0700520 main.log.debug( self.name + ": Raw output from sending ''" )
521 main.log.debug( self.name + ": " + repr( response ) )
522 except pexpect.TIMEOUT:
523 main.log.error( self.name + ": ONOS timeout" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700524 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
You Wang141b43b2018-06-26 16:50:18 -0700525 self.handle.send( "\x03" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800526 self.handle.expect( self.karafPrompt )
Jon Hall0e240372018-05-02 11:21:57 -0700527 return None
528 except pexpect.EOF:
529 main.log.error( self.name + ": EOF exception found" )
530 main.log.error( self.name + ": " + self.handle.before )
531 if noExit:
532 return None
533 else:
534 main.cleanAndExit()
535 except Exception:
536 main.log.exception( self.name + ": Uncaught exception!" )
537 if noExit:
538 return None
539 else:
540 main.cleanAndExit()
541
Jon Hall22e94ce2019-01-15 14:52:17 -0800542 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True, expectJson=False ):
Jon Hall0e240372018-05-02 11:21:57 -0700543 """
544 A wrapper around pexpect's sendline/expect. Will return all the output from a given command
545
546 Required Arguments:
547 cmdStr - String to send to the pexpect session
548
549 Optional Arguments:
550 showResponse - Defaults to False. If True will log the response.
551 debug - Defaults to False. If True, will enable debug logging.
552 timeout - Defaults to 10. Amount of time in seconds for a command to return
553 before a timeout.
554 noExit - Defaults to False. If True, will not exit TestON in the event of a
555 closed channel, but instead return None
Jon Hall6c9e2da2018-11-06 12:01:23 -0800556 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 -0700557
558 Warning: There are no sanity checking to commands sent using this method.
559
560 """
561 try:
562 # Try to reconnect if disconnected from cli
563 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
564 if debug:
565 # NOTE: This adds an average of .4 seconds per call
Jon Hall14a03b52016-05-11 12:07:30 -0700566 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700567 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800568 self.handle.sendline( cmdStr )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800569 self.handle.expect( self.karafPrompt, timeout )
Jon Hall63604932015-02-26 17:09:50 -0800570 response = self.handle.before
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000571 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
Jon Hallc6793552016-01-19 14:18:37 -0800572 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700573 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700574 main.log.debug( self.name + ": Raw output" )
575 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700576
Jon Hall3c0114c2020-08-11 15:07:42 -0700577 response = self.cleanOutput( response, debug=debug )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800578 # Remove control codes from karaf 4.2.1
Jon Hall3c0114c2020-08-11 15:07:42 -0700579 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 -0800580 response = karafEscape.sub( '', response )
581 if debug:
582 main.log.debug( self.name + ": karafEscape output" )
583 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700584 # Remove ANSI color control strings from output
Jon Hall43060f62020-06-23 13:13:33 -0700585 response = self.cleanOutput( response, debug )
Jon Hallc6358dd2015-04-10 12:44:28 -0700586
Jon Hall6c9e2da2018-11-06 12:01:23 -0800587 # Remove ANSI color control strings from output
Jon Hallcf31d0f2018-12-13 11:18:48 -0800588 # NOTE: karaf is sometimes adding a single character then two
589 # backspaces and sometimes adding 2 characters with 2 backspaces??
Jon Hall3c0114c2020-08-11 15:07:42 -0700590 backspaceEscape = re.compile( r'((.|\s)\x08)' )
591 unchanged = False
592 while not unchanged:
593 old = response
594 response = backspaceEscape.sub( '', response, count=1 )
595 if debug:
596 main.log.debug( self.name + ": backspaceEscape output" )
597 main.log.debug( self.name + ": " + repr( response ) )
598 unchanged = old == response
Jon Hall6c9e2da2018-11-06 12:01:23 -0800599
kelvin-onlabfb521662015-02-27 09:52:40 -0800600 # Remove extra return chars that get added
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000601 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700602 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700603 main.log.debug( self.name + ": Removed extra returns " +
604 "from output" )
605 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700606
607 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800608 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700609 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700610 main.log.debug( self.name + ": parsed and stripped output" )
611 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700612
Jon Hall63604932015-02-26 17:09:50 -0800613 # parse for just the output, remove the cmd from response
Jon Hallce0d70b2018-12-11 11:01:32 -0800614 cmdPattern = cmdStr.strip()
615 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
616 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800617 if relaxedRegex:
Jon Hallce0d70b2018-12-11 11:01:32 -0800618 cmdPattern = cmdPattern.split( '|' )[ -1 ].strip()
619 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
620 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800621 # This was added because karaf 4.2 is stripping some characters from the command echo
Jon Hallce0d70b2018-12-11 11:01:32 -0800622 output = response.split( cmdPattern, 1 )
Jon Hall22e94ce2019-01-15 14:52:17 -0800623 if expectJson:
624 main.log.warn( "Relaxed Regex: Searching for a json string amongst the output" )
625 jsonPattern = r'\{.*\}'
626 match = re.search( jsonPattern, output[ 0 ] )
627 if match:
628 output = [ '' , match.group( 0 ) ] # We expect a list with the second element to be the output
Jon Hall39e3ffe2018-12-05 11:40:29 -0800629 if len( output ) < 2:
630 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800631 cmdPattern = cmdPattern[ -5: ]
632 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
633 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
634 output = response.split( cmdPattern, 1 )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800635 else:
Jon Hallce0d70b2018-12-11 11:01:32 -0800636 output = response.split( cmdPattern, 1 )
637 if len( output ) < 2: # TODO: Should we do this without the relaxedRegex flag?
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800638 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800639 output = response.split( cmdPattern[ -5: ], 1 )
Jon Hall0e240372018-05-02 11:21:57 -0700640 if output:
641 if debug:
642 main.log.debug( self.name + ": split output" )
643 for r in output:
644 main.log.debug( self.name + ": " + repr( r ) )
Jon Hallce0d70b2018-12-11 11:01:32 -0800645 if len( output ) == 1:
646 main.log.error( "Could not remove sent command echo from output" )
647 return output
Jon Hall0e240372018-05-02 11:21:57 -0700648 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800649 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800650 main.log.info( "Response from ONOS: {}".format( output ) )
Jon Hall0e240372018-05-02 11:21:57 -0700651 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
GlennRC85870432015-11-23 11:45:51 -0800652 return output
GlennRCed771242016-01-13 17:02:47 -0800653 except pexpect.TIMEOUT:
Jon Hall0e240372018-05-02 11:21:57 -0700654 main.log.error( self.name + ": ONOS timeout" )
GlennRCed771242016-01-13 17:02:47 -0800655 if debug:
Jon Hall3c0114c2020-08-11 15:07:42 -0700656 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
You Wang6b5e5ba2019-01-31 15:32:40 -0800657 self.exitFromCmd( self.karafPrompt, 100 )
GlennRCed771242016-01-13 17:02:47 -0800658 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700659 except IndexError:
660 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700661 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700662 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800663 except TypeError:
664 main.log.exception( self.name + ": Object not as expected" )
665 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400666 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800667 main.log.error( self.name + ": EOF exception found" )
668 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700669 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700670 return None
671 else:
Devin Lim44075962017-08-11 10:56:37 -0700672 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800673 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800674 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700675 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700676 return None
677 else:
Devin Lim44075962017-08-11 10:56:37 -0700678 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400679
Jon Halld5a94fb2018-11-13 14:32:23 -0800680 def lineCount( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True ):
681 """
682 A wrapper around sendline(). Will return the number of lines returned or None on error
683
684 Required Arguments:
685 cmdStr - String to send to the pexpect session
686
687 Optional Arguments:
688 showResponse - Defaults to False. If True will log the response.
689 debug - Defaults to False. If True, will enable debug logging.
690 timeout - Defaults to 10. Amount of time in seconds for a command to return
691 before a timeout.
692 noExit - Defaults to False. If True, will not exit TestON in the event of a
693 closed channel, but instead return None
694 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.
695
696 Warning: There are no sanity checking to commands sent using this method.
697
698 """
699 try:
700 numLines = self.sendline( cmdStr, showResponse, debug, timeout, noExit, relaxedRegex )
You Wang0ce8e0c2019-02-22 12:22:26 -0800701 parsed = re.search( "(\d+)", numLines )
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800702 if not parsed:
703 main.log.error( "Warning, output of karaf's wc may have changed" )
704 return None
705 return parsed.group( 1 )
Jon Halld5a94fb2018-11-13 14:32:23 -0800706 except IndexError:
707 main.log.exception( self.name + ": Object not as expected" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800708 main.log.debug( "response: {}".format( repr( numLines ) ) )
Jon Halld5a94fb2018-11-13 14:32:23 -0800709 return None
710 except TypeError:
711 main.log.exception( self.name + ": Object not as expected" )
712 return None
713 except Exception:
714 main.log.exception( self.name + ": Uncaught exception!" )
715 if noExit:
716 return None
717 else:
718 main.cleanAndExit()
719
kelvin8ec71442015-01-15 16:57:00 -0800720 # IMPORTANT NOTE:
721 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800722 # the cli command changing 'a:b' with 'aB'.
723 # Ex ) onos:topology > onosTopology
724 # onos:links > onosLinks
725 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800726
kelvin-onlabd3b64892015-01-20 13:26:24 -0800727 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800728 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400729 Adds a new cluster node by ID and address information.
730 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800731 * nodeId
732 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400733 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800734 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800735 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400736 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800737 cmdStr = "add-node " + str( nodeId ) + " " +\
738 str( ONOSIp ) + " " + str( tcpPort )
739 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700740 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800741 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800742 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700743 main.log.error( self.name + ": Error in adding node" )
kelvin8ec71442015-01-15 16:57:00 -0800744 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800745 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400746 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800747 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400748 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800749 except AssertionError:
750 main.log.exception( "" )
751 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800752 except TypeError:
753 main.log.exception( self.name + ": Object not as expected" )
754 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400755 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800756 main.log.error( self.name + ": EOF exception found" )
757 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700758 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800759 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800760 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700761 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400762
kelvin-onlabd3b64892015-01-20 13:26:24 -0800763 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800764 """
andrewonlab86dc3082014-10-13 18:18:38 -0400765 Removes a cluster by ID
766 Issues command: 'remove-node [<node-id>]'
767 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800768 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800769 """
andrewonlab86dc3082014-10-13 18:18:38 -0400770 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400771
kelvin-onlabd3b64892015-01-20 13:26:24 -0800772 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700773 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700774 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800775 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700776 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700777 main.log.error( self.name + ": Error in removing node" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700778 main.log.error( handle )
779 return main.FALSE
780 else:
781 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800782 except AssertionError:
783 main.log.exception( "" )
784 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800785 except TypeError:
786 main.log.exception( self.name + ": Object not as expected" )
787 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400788 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800789 main.log.error( self.name + ": EOF exception found" )
790 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700791 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800792 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800793 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700794 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400795
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700796 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800797 """
andrewonlab7c211572014-10-15 16:45:20 -0400798 List the nodes currently visible
799 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700800 Optional argument:
801 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800802 """
andrewonlab7c211572014-10-15 16:45:20 -0400803 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700804 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700805 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700806 cmdStr += " -j"
807 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700808 assert output is not None, "Error in sendline"
Jon Halle37bd1f2020-09-10 12:16:41 -0700809 # "Command not found" or "Service org.onosproject.security.AuditService not found"
810 assert "not found" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700811 return output
Jon Hallc6793552016-01-19 14:18:37 -0800812 except AssertionError:
813 main.log.exception( "" )
814 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800815 except TypeError:
816 main.log.exception( self.name + ": Object not as expected" )
817 return None
andrewonlab7c211572014-10-15 16:45:20 -0400818 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800819 main.log.error( self.name + ": EOF exception found" )
820 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700821 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800822 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800823 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700824 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400825
kelvin8ec71442015-01-15 16:57:00 -0800826 def topology( self ):
827 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700828 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700829 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700830 Return:
831 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800832 """
andrewonlab95ce8322014-10-13 14:12:04 -0400833 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700834 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800835 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800836 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800837 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700838 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400839 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800840 except AssertionError:
841 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800842 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800843 except TypeError:
844 main.log.exception( self.name + ": Object not as expected" )
845 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400846 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800847 main.log.error( self.name + ": EOF exception found" )
848 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700849 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800850 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800851 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700852 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800853
jenkins7ead5a82015-03-13 10:28:21 -0700854 def deviceRemove( self, deviceId ):
855 """
856 Removes particular device from storage
857
858 TODO: refactor this function
859 """
860 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700861 cmdStr = "device-remove " + str( deviceId )
862 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800863 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800864 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700865 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700866 main.log.error( self.name + ": Error in removing device" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700867 main.log.error( handle )
868 return main.FALSE
869 else:
870 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800871 except AssertionError:
872 main.log.exception( "" )
873 return None
jenkins7ead5a82015-03-13 10:28:21 -0700874 except TypeError:
875 main.log.exception( self.name + ": Object not as expected" )
876 return None
877 except pexpect.EOF:
878 main.log.error( self.name + ": EOF exception found" )
879 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700880 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700881 except Exception:
882 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700883 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700884
You Wang3b9689a2018-08-30 12:24:00 -0700885 def devices( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800886 """
Jon Hall7b02d952014-10-17 20:14:54 -0400887 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400888 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800889 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800890 """
andrewonlab86dc3082014-10-13 18:18:38 -0400891 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700892 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800893 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700894 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700895 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800896 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800897 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700898 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800899 except AssertionError:
900 main.log.exception( "" )
901 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800902 except TypeError:
903 main.log.exception( self.name + ": Object not as expected" )
904 return None
andrewonlab7c211572014-10-15 16:45:20 -0400905 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800906 main.log.error( self.name + ": EOF exception found" )
907 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700908 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800909 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800910 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700911 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400912
kelvin-onlabd3b64892015-01-20 13:26:24 -0800913 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800914 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800915 This balances the devices across all controllers
916 by issuing command: 'onos> onos:balance-masters'
917 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800918 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800919 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800920 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700921 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800922 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800923 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700924 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700925 main.log.error( self.name + ": Error in balancing masters" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700926 main.log.error( handle )
927 return main.FALSE
928 else:
929 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800930 except AssertionError:
931 main.log.exception( "" )
932 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800933 except TypeError:
934 main.log.exception( self.name + ": Object not as expected" )
935 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800936 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800937 main.log.error( self.name + ": EOF exception found" )
938 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700939 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800940 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800941 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700942 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800943
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000944 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700945 """
946 Returns the output of the masters command.
947 Optional argument:
948 * jsonFormat - boolean indicating if you want output in json
949 """
950 try:
951 cmdStr = "onos:masters"
952 if jsonFormat:
953 cmdStr += " -j"
954 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700955 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800956 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700957 return output
Jon Hallc6793552016-01-19 14:18:37 -0800958 except AssertionError:
959 main.log.exception( "" )
960 return None
acsmars24950022015-07-30 18:00:43 -0700961 except TypeError:
962 main.log.exception( self.name + ": Object not as expected" )
963 return None
964 except pexpect.EOF:
965 main.log.error( self.name + ": EOF exception found" )
966 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700967 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700968 except Exception:
969 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700970 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700971
Jon Hallc6793552016-01-19 14:18:37 -0800972 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700973 """
974 Uses the master command to check that the devices' leadership
975 is evenly divided
976
977 Dependencies: checkMasters() and summary()
978
Jon Hall6509dbf2016-06-21 17:01:17 -0700979 Returns main.TRUE if the devices are balanced
980 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700981 Exits on Exception
982 Returns None on TypeError
983 """
984 try:
Jon Hallc6793552016-01-19 14:18:37 -0800985 summaryOutput = self.summary()
986 totalDevices = json.loads( summaryOutput )[ "devices" ]
987 except ( TypeError, ValueError ):
988 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
989 return None
990 try:
acsmars24950022015-07-30 18:00:43 -0700991 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800992 mastersOutput = self.checkMasters()
993 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700994 first = masters[ 0 ][ "size" ]
995 for master in masters:
996 totalOwnedDevices += master[ "size" ]
997 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
998 main.log.error( "Mastership not balanced" )
999 main.log.info( "\n" + self.checkMasters( False ) )
1000 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -07001001 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001002 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -07001003 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001004 except ( TypeError, ValueError ):
1005 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -07001006 return None
1007 except pexpect.EOF:
1008 main.log.error( self.name + ": EOF exception found" )
1009 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001010 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -07001011 except Exception:
1012 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001013 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -07001014
YPZhangfebf7302016-05-24 16:45:56 -07001015 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -08001016 """
Jon Halle8217482014-10-17 13:49:14 -04001017 Lists all core links
1018 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001019 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001020 """
Jon Halle8217482014-10-17 13:49:14 -04001021 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001022 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001023 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001024 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07001025 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001026 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001027 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001028 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001029 except AssertionError:
1030 main.log.exception( "" )
1031 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001032 except TypeError:
1033 main.log.exception( self.name + ": Object not as expected" )
1034 return None
Jon Halle8217482014-10-17 13:49:14 -04001035 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001036 main.log.error( self.name + ": EOF exception found" )
1037 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001038 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001039 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001040 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001041 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001042
You Wang3b9689a2018-08-30 12:24:00 -07001043 def ports( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -08001044 """
Jon Halle8217482014-10-17 13:49:14 -04001045 Lists all ports
1046 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001047 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001048 """
Jon Halle8217482014-10-17 13:49:14 -04001049 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001050 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001051 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001052 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -07001053 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001054 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001055 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001056 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001057 except AssertionError:
1058 main.log.exception( "" )
1059 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001060 except TypeError:
1061 main.log.exception( self.name + ": Object not as expected" )
1062 return None
Jon Halle8217482014-10-17 13:49:14 -04001063 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001064 main.log.error( self.name + ": EOF exception found" )
1065 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001066 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001067 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001068 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001069 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001070
kelvin-onlabd3b64892015-01-20 13:26:24 -08001071 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001072 """
Jon Hall983a1702014-10-28 18:44:22 -04001073 Lists all devices and the controllers with roles assigned to them
1074 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001075 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001076 """
andrewonlab7c211572014-10-15 16:45:20 -04001077 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001078 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001079 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001080 cmdStr += " -j"
1081 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001082 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001083 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001084 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001085 except AssertionError:
1086 main.log.exception( "" )
1087 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001088 except TypeError:
1089 main.log.exception( self.name + ": Object not as expected" )
1090 return None
Jon Hall983a1702014-10-28 18:44:22 -04001091 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001092 main.log.error( self.name + ": EOF exception found" )
1093 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001094 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001095 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001096 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001097 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -04001098
kelvin-onlabd3b64892015-01-20 13:26:24 -08001099 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001100 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001101 Given the a string containing the json representation of the "roles"
1102 cli command and a partial or whole device id, returns a json object
1103 containing the roles output for the first device whose id contains
1104 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -04001105
1106 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -08001107 A dict of the role assignments for the given device or
1108 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001109 """
Jon Hall983a1702014-10-28 18:44:22 -04001110 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001111 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001112 return None
1113 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001114 rawRoles = self.roles()
1115 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001116 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001117 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001118 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001120 return device
1121 return None
Jon Hallc6793552016-01-19 14:18:37 -08001122 except ( TypeError, ValueError ):
1123 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001124 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001125 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001126 main.log.error( self.name + ": EOF exception found" )
1127 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001128 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001129 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001130 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001131 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001132
kelvin-onlabd3b64892015-01-20 13:26:24 -08001133 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001134 """
Jon Hall94fd0472014-12-08 11:52:42 -08001135 Iterates through each device and checks if there is a master assigned
1136 Returns: main.TRUE if each device has a master
1137 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001138 """
Jon Hall94fd0472014-12-08 11:52:42 -08001139 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001140 rawRoles = self.roles()
1141 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001142 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001143 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001144 # print device
1145 if device[ 'master' ] == "none":
1146 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001147 return main.FALSE
1148 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001149 except ( TypeError, ValueError ):
1150 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001151 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001152 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001153 main.log.error( self.name + ": EOF exception found" )
1154 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001155 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001156 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001157 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001158 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001159
kelvin-onlabd3b64892015-01-20 13:26:24 -08001160 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001161 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001162 Returns string of paths, and the cost.
1163 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001164 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001165 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001166 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1167 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001168 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001169 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001170 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001171 main.log.error( self.name + ": Error in getting paths" )
kelvin8ec71442015-01-15 16:57:00 -08001172 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001173 else:
kelvin8ec71442015-01-15 16:57:00 -08001174 path = handle.split( ";" )[ 0 ]
1175 cost = handle.split( ";" )[ 1 ]
1176 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001177 except AssertionError:
1178 main.log.exception( "" )
1179 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001180 except TypeError:
1181 main.log.exception( self.name + ": Object not as expected" )
1182 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001183 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001184 main.log.error( self.name + ": EOF exception found" )
1185 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001186 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001187 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001188 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001189 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001190
kelvin-onlabd3b64892015-01-20 13:26:24 -08001191 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001192 """
Jon Hallffb386d2014-11-21 13:43:38 -08001193 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001194 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001195 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001196 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001197 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001198 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001199 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001200 cmdStr += " -j"
1201 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001202 if handle:
1203 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001204 # TODO: Maybe make this less hardcoded
1205 # ConsistentMap Exceptions
1206 assert "org.onosproject.store.service" not in handle
1207 # Node not leader
1208 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001209 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001210 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07001211 main.log.exception( self.name + ": Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001212 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001213 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001214 except TypeError:
1215 main.log.exception( self.name + ": Object not as expected" )
1216 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001217 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001218 main.log.error( self.name + ": EOF exception found" )
1219 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001220 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001221 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001222 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001223 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001224
kelvin-onlabd3b64892015-01-20 13:26:24 -08001225 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001226 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001227 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001228
Jon Hallefbd9792015-03-05 16:11:36 -08001229 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001230 partial mac address
1231
Jon Hall42db6dc2014-10-24 19:03:48 -04001232 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001233 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001234 try:
kelvin8ec71442015-01-15 16:57:00 -08001235 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001236 return None
1237 else:
1238 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001239 rawHosts = self.hosts()
1240 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001241 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001242 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001243 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001244 if not host:
1245 pass
1246 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001247 return host
1248 return None
Jon Hallc6793552016-01-19 14:18:37 -08001249 except ( TypeError, ValueError ):
1250 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001251 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001252 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001253 main.log.error( self.name + ": EOF exception found" )
1254 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001255 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001256 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001257 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001258 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001259
kelvin-onlabd3b64892015-01-20 13:26:24 -08001260 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001261 """
1262 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001263 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001264
andrewonlab3f0a4af2014-10-17 12:25:14 -04001265 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001266 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001267 IMPORTANT:
1268 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001269 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001270 Furthermore, it assumes that value of VLAN is '-1'
1271 Description:
kelvin8ec71442015-01-15 16:57:00 -08001272 Converts mininet hosts ( h1, h2, h3... ) into
1273 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1274 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001275 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001276 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001277
kelvin-onlabd3b64892015-01-20 13:26:24 -08001278 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001279 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001280 hostHex = hex( int( host ) ).zfill( 12 )
1281 hostHex = str( hostHex ).replace( 'x', '0' )
1282 i = iter( str( hostHex ) )
1283 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1284 hostHex = hostHex + "/-1"
1285 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001286
kelvin-onlabd3b64892015-01-20 13:26:24 -08001287 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001288
Jon Halld4d4b372015-01-28 16:02:41 -08001289 except TypeError:
1290 main.log.exception( self.name + ": Object not as expected" )
1291 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001292 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001293 main.log.error( self.name + ": EOF exception found" )
1294 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001295 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001296 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001297 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001298 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001299
You Wangbc898b82018-05-03 16:22:34 -07001300 def verifyHostLocation( self, hostIp, location ):
1301 """
1302 Description:
1303 Verify the host given is discovered in all locations expected
1304 Required:
1305 hostIp: IP address of the host
1306 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1307 Could be a string or list
1308 Returns:
1309 main.TRUE if host is discovered on all locations provided
1310 main.FALSE otherwise
1311 """
You Wangbc898b82018-05-03 16:22:34 -07001312 locations = [ location ] if isinstance( location, str ) else location
1313 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1314 try:
1315 hosts = self.hosts()
1316 hosts = json.loads( hosts )
1317 targetHost = None
1318 for host in hosts:
1319 if hostIp in host[ "ipAddresses" ]:
1320 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001321 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001322 result = main.TRUE
1323 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1324 for loc in locations:
1325 discovered = False
1326 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001327 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1328 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001329 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001330 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001331 break
1332 if discovered:
1333 locationsDiscovered.remove( locDiscovered )
1334 else:
1335 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1336 result = main.FALSE
1337 if locationsDiscovered:
1338 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1339 result = main.FALSE
1340 return result
1341 except KeyError:
1342 main.log.exception( self.name + ": host data not as expected: " + hosts )
1343 return None
1344 except pexpect.EOF:
1345 main.log.error( self.name + ": EOF exception found" )
1346 main.log.error( self.name + ": " + self.handle.before )
1347 main.cleanAndExit()
1348 except Exception:
1349 main.log.exception( self.name + ": Uncaught exception" )
1350 return None
1351
You Wang53dba1e2018-02-02 17:45:44 -08001352 def verifyHostIp( self, hostList=[], prefix="" ):
1353 """
1354 Description:
1355 Verify that all hosts have IP address assigned to them
1356 Optional:
1357 hostList: If specified, verifications only happen to the hosts
1358 in hostList
1359 prefix: at least one of the ip address assigned to the host
1360 needs to have the specified prefix
1361 Returns:
1362 main.TRUE if all hosts have specific IP address assigned;
1363 main.FALSE otherwise
1364 """
You Wang53dba1e2018-02-02 17:45:44 -08001365 try:
1366 hosts = self.hosts()
1367 hosts = json.loads( hosts )
1368 if not hostList:
1369 hostList = [ host[ "id" ] for host in hosts ]
1370 for host in hosts:
1371 hostId = host[ "id" ]
1372 if hostId not in hostList:
1373 continue
1374 ipList = host[ "ipAddresses" ]
1375 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1376 if not ipList:
1377 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1378 else:
1379 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1380 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1381 else:
1382 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1383 hostList.remove( hostId )
1384 if hostList:
1385 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
Jon Hall43060f62020-06-23 13:13:33 -07001386 # Print info for debugging
1387 main.log.debug( self.name + ": hosts output: " + str( hosts ) )
You Wang53dba1e2018-02-02 17:45:44 -08001388 return main.FALSE
1389 else:
1390 return main.TRUE
1391 except KeyError:
1392 main.log.exception( self.name + ": host data not as expected: " + hosts )
1393 return None
1394 except pexpect.EOF:
1395 main.log.error( self.name + ": EOF exception found" )
1396 main.log.error( self.name + ": " + self.handle.before )
1397 main.cleanAndExit()
1398 except Exception:
1399 main.log.exception( self.name + ": Uncaught exception" )
1400 return None
1401
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001402 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001403 """
andrewonlabe6745342014-10-17 14:29:13 -04001404 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001405 * hostIdOne: ONOS host id for host1
1406 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001407 Optional:
1408 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001409 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001410 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001411 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001412 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001413 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001414 Returns:
1415 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001416 """
andrewonlabe6745342014-10-17 14:29:13 -04001417 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001418 cmdStr = "add-host-intent "
1419 if vlanId:
1420 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001421 if setVlan:
1422 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001423 if encap:
1424 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001425 if bandwidth:
1426 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001427 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001428 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001429 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001430 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001431 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001432 main.log.error( self.name + ": Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001433 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001434 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001435 else:
1436 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001437 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001438 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001439 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001440 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001441 else:
1442 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001443 main.log.debug( "Response from ONOS was: " +
1444 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001445 return None
Jon Hallc6793552016-01-19 14:18:37 -08001446 except AssertionError:
1447 main.log.exception( "" )
1448 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001449 except TypeError:
1450 main.log.exception( self.name + ": Object not as expected" )
1451 return None
andrewonlabe6745342014-10-17 14:29:13 -04001452 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001453 main.log.error( self.name + ": EOF exception found" )
1454 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001455 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001456 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001457 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001458 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001459
kelvin-onlabd3b64892015-01-20 13:26:24 -08001460 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001461 """
andrewonlab7b31d232014-10-24 13:31:47 -04001462 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001463 * ingressDevice: device id of ingress device
1464 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001465 Optional:
1466 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001467 Description:
1468 Adds an optical intent by specifying an ingress and egress device
1469 Returns:
1470 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001471 """
andrewonlab7b31d232014-10-24 13:31:47 -04001472 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001473 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1474 " " + str( egressDevice )
1475 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001476 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001477 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001478 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001479 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001480 main.log.error( self.name + ": Error in adding Optical intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001481 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001482 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001483 main.log.info( "Optical intent installed between " +
1484 str( ingressDevice ) + " and " +
1485 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001486 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001487 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001488 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001489 else:
1490 main.log.error( "Error, intent ID not found" )
1491 return None
Jon Hallc6793552016-01-19 14:18:37 -08001492 except AssertionError:
1493 main.log.exception( "" )
1494 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001495 except TypeError:
1496 main.log.exception( self.name + ": Object not as expected" )
1497 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001498 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001499 main.log.error( self.name + ": EOF exception found" )
1500 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001501 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001502 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001503 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001504 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001505
kelvin-onlabd3b64892015-01-20 13:26:24 -08001506 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001507 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001508 ingressDevice,
1509 egressDevice,
1510 portIngress="",
1511 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001512 ethType="",
1513 ethSrc="",
1514 ethDst="",
1515 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001516 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001517 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001518 ipProto="",
1519 ipSrc="",
1520 ipDst="",
1521 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001522 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001523 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001524 setVlan="",
1525 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001526 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001527 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001528 * ingressDevice: device id of ingress device
1529 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001530 Optional:
1531 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001532 * ethSrc: specify ethSrc ( i.e. src mac addr )
1533 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001534 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001535 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001536 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001537 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001538 * ipSrc: specify ip source address
1539 * ipDst: specify ip destination address
1540 * tcpSrc: specify tcp source port
1541 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001542 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001543 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001544 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001545 Description:
kelvin8ec71442015-01-15 16:57:00 -08001546 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001547 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001548 Returns:
1549 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001550
Jon Halle3f39ff2015-01-13 11:50:53 -08001551 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001552 options developers provide for point-to-point
1553 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001554 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001555 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001556 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001557
Jeremy Songsterff553672016-05-12 17:06:23 -07001558 if ethType:
1559 cmd += " --ethType " + str( ethType )
1560 if ethSrc:
1561 cmd += " --ethSrc " + str( ethSrc )
1562 if ethDst:
1563 cmd += " --ethDst " + str( ethDst )
1564 if bandwidth:
1565 cmd += " --bandwidth " + str( bandwidth )
1566 if lambdaAlloc:
1567 cmd += " --lambda "
1568 if ipProto:
1569 cmd += " --ipProto " + str( ipProto )
1570 if ipSrc:
1571 cmd += " --ipSrc " + str( ipSrc )
1572 if ipDst:
1573 cmd += " --ipDst " + str( ipDst )
1574 if tcpSrc:
1575 cmd += " --tcpSrc " + str( tcpSrc )
1576 if tcpDst:
1577 cmd += " --tcpDst " + str( tcpDst )
1578 if vlanId:
1579 cmd += " -v " + str( vlanId )
1580 if setVlan:
1581 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001582 if encap:
1583 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001584 if protected:
1585 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001586
kelvin8ec71442015-01-15 16:57:00 -08001587 # Check whether the user appended the port
1588 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001589 if "/" in ingressDevice:
1590 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001591 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001592 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001593 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001594 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001595 # Would it make sense to throw an exception and exit
1596 # the test?
1597 return None
andrewonlab36af3822014-11-18 17:48:18 -05001598
kelvin8ec71442015-01-15 16:57:00 -08001599 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001600 str( ingressDevice ) + "/" +\
1601 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001602
kelvin-onlabd3b64892015-01-20 13:26:24 -08001603 if "/" in egressDevice:
1604 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001605 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001606 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001607 main.log.error( "You must specify the egress port" )
1608 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001609
kelvin8ec71442015-01-15 16:57:00 -08001610 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001611 str( egressDevice ) + "/" +\
1612 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001613
kelvin-onlab898a6c62015-01-16 14:13:53 -08001614 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001615 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001616 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001617 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001618 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001619 main.log.error( self.name + ": Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001620 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001621 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001622 # TODO: print out all the options in this message?
1623 main.log.info( "Point-to-point intent installed between " +
1624 str( ingressDevice ) + " and " +
1625 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001626 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001627 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001628 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001629 else:
1630 main.log.error( "Error, intent ID not found" )
1631 return None
Jon Hallc6793552016-01-19 14:18:37 -08001632 except AssertionError:
1633 main.log.exception( "" )
1634 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001635 except TypeError:
1636 main.log.exception( self.name + ": Object not as expected" )
1637 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001638 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001639 main.log.error( self.name + ": EOF exception found" )
1640 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001641 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001642 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001643 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001644 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001645
kelvin-onlabd3b64892015-01-20 13:26:24 -08001646 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001647 self,
shahshreyac2f97072015-03-19 17:04:29 -07001648 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001649 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001650 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001651 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001652 ethType="",
1653 ethSrc="",
1654 ethDst="",
1655 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001656 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001657 ipProto="",
1658 ipSrc="",
1659 ipDst="",
1660 tcpSrc="",
1661 tcpDst="",
1662 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001663 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001664 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001665 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001666 partial=False,
1667 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001668 """
shahshreyad0c80432014-12-04 16:56:05 -08001669 Note:
shahshreya70622b12015-03-19 17:19:00 -07001670 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001671 is same. That is, all ingress devices include port numbers
1672 with a "/" or all ingress devices could specify device
1673 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001674 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001675 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001676 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001677 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001678 Optional:
1679 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001680 * ethSrc: specify ethSrc ( i.e. src mac addr )
1681 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001682 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001683 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001684 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001685 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001686 * ipSrc: specify ip source address
1687 * ipDst: specify ip destination address
1688 * tcpSrc: specify tcp source port
1689 * tcpDst: specify tcp destination port
1690 * setEthSrc: action to Rewrite Source MAC Address
1691 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001692 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001693 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001694 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001695 Description:
kelvin8ec71442015-01-15 16:57:00 -08001696 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001697 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001698 Returns:
1699 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001700
Jon Halle3f39ff2015-01-13 11:50:53 -08001701 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001702 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001703 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001704 """
shahshreyad0c80432014-12-04 16:56:05 -08001705 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001706 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001707
Jeremy Songsterff553672016-05-12 17:06:23 -07001708 if ethType:
1709 cmd += " --ethType " + str( ethType )
1710 if ethSrc:
1711 cmd += " --ethSrc " + str( ethSrc )
1712 if ethDst:
1713 cmd += " --ethDst " + str( ethDst )
1714 if bandwidth:
1715 cmd += " --bandwidth " + str( bandwidth )
1716 if lambdaAlloc:
1717 cmd += " --lambda "
1718 if ipProto:
1719 cmd += " --ipProto " + str( ipProto )
1720 if ipSrc:
1721 cmd += " --ipSrc " + str( ipSrc )
1722 if ipDst:
1723 cmd += " --ipDst " + str( ipDst )
1724 if tcpSrc:
1725 cmd += " --tcpSrc " + str( tcpSrc )
1726 if tcpDst:
1727 cmd += " --tcpDst " + str( tcpDst )
1728 if setEthSrc:
1729 cmd += " --setEthSrc " + str( setEthSrc )
1730 if setEthDst:
1731 cmd += " --setEthDst " + str( setEthDst )
1732 if vlanId:
1733 cmd += " -v " + str( vlanId )
1734 if setVlan:
1735 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001736 if partial:
1737 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001738 if encap:
1739 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001740
kelvin8ec71442015-01-15 16:57:00 -08001741 # Check whether the user appended the port
1742 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001743
1744 if portIngressList is None:
1745 for ingressDevice in ingressDeviceList:
1746 if "/" in ingressDevice:
1747 cmd += " " + str( ingressDevice )
1748 else:
1749 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001750 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001751 # TODO: perhaps more meaningful return
1752 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001753 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001754 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001755 for ingressDevice, portIngress in zip( ingressDeviceList,
1756 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001757 cmd += " " + \
1758 str( ingressDevice ) + "/" +\
1759 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001760 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001761 main.log.error( "Device list and port list does not " +
1762 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001763 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001764 if "/" in egressDevice:
1765 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001766 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001767 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001768 main.log.error( "You must specify " +
1769 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001770 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001771
kelvin8ec71442015-01-15 16:57:00 -08001772 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001773 str( egressDevice ) + "/" +\
1774 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001775 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001776 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001777 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001778 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001779 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001780 main.log.error( self.name + ": Error in adding multipoint-to-singlepoint " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001781 "intent" )
1782 return None
shahshreyad0c80432014-12-04 16:56:05 -08001783 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001784 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001785 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001786 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001787 else:
1788 main.log.error( "Error, intent ID not found" )
1789 return None
Jon Hallc6793552016-01-19 14:18:37 -08001790 except AssertionError:
1791 main.log.exception( "" )
1792 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001793 except TypeError:
1794 main.log.exception( self.name + ": Object not as expected" )
1795 return None
1796 except pexpect.EOF:
1797 main.log.error( self.name + ": EOF exception found" )
1798 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001799 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001800 except Exception:
1801 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001802 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001803
1804 def addSinglepointToMultipointIntent(
1805 self,
1806 ingressDevice,
1807 egressDeviceList,
1808 portIngress="",
1809 portEgressList=None,
1810 ethType="",
1811 ethSrc="",
1812 ethDst="",
1813 bandwidth="",
1814 lambdaAlloc=False,
1815 ipProto="",
1816 ipSrc="",
1817 ipDst="",
1818 tcpSrc="",
1819 tcpDst="",
1820 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001821 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001822 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001823 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001824 partial=False,
1825 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001826 """
1827 Note:
1828 This function assumes the format of all egress devices
1829 is same. That is, all egress devices include port numbers
1830 with a "/" or all egress devices could specify device
1831 ids and port numbers seperately.
1832 Required:
1833 * EgressDeviceList: List of device ids of egress device
1834 ( Atleast 2 eress devices required in the list )
1835 * ingressDevice: device id of ingress device
1836 Optional:
1837 * ethType: specify ethType
1838 * ethSrc: specify ethSrc ( i.e. src mac addr )
1839 * ethDst: specify ethDst ( i.e. dst mac addr )
1840 * bandwidth: specify bandwidth capacity of link
1841 * lambdaAlloc: if True, intent will allocate lambda
1842 for the specified intent
1843 * ipProto: specify ip protocol
1844 * ipSrc: specify ip source address
1845 * ipDst: specify ip destination address
1846 * tcpSrc: specify tcp source port
1847 * tcpDst: specify tcp destination port
1848 * setEthSrc: action to Rewrite Source MAC Address
1849 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001850 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001851 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001852 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001853 Description:
1854 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1855 specifying device id's and optional fields
1856 Returns:
1857 A string of the intent id or None on error
1858
1859 NOTE: This function may change depending on the
1860 options developers provide for singlepoint-to-multipoint
1861 intent via cli
1862 """
1863 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001864 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001865
Jeremy Songsterff553672016-05-12 17:06:23 -07001866 if ethType:
1867 cmd += " --ethType " + str( ethType )
1868 if ethSrc:
1869 cmd += " --ethSrc " + str( ethSrc )
1870 if ethDst:
1871 cmd += " --ethDst " + str( ethDst )
1872 if bandwidth:
1873 cmd += " --bandwidth " + str( bandwidth )
1874 if lambdaAlloc:
1875 cmd += " --lambda "
1876 if ipProto:
1877 cmd += " --ipProto " + str( ipProto )
1878 if ipSrc:
1879 cmd += " --ipSrc " + str( ipSrc )
1880 if ipDst:
1881 cmd += " --ipDst " + str( ipDst )
1882 if tcpSrc:
1883 cmd += " --tcpSrc " + str( tcpSrc )
1884 if tcpDst:
1885 cmd += " --tcpDst " + str( tcpDst )
1886 if setEthSrc:
1887 cmd += " --setEthSrc " + str( setEthSrc )
1888 if setEthDst:
1889 cmd += " --setEthDst " + str( setEthDst )
1890 if vlanId:
1891 cmd += " -v " + str( vlanId )
1892 if setVlan:
1893 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001894 if partial:
1895 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001896 if encap:
1897 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001898
1899 # Check whether the user appended the port
1900 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001901
kelvin-onlabb9408212015-04-01 13:34:04 -07001902 if "/" in ingressDevice:
1903 cmd += " " + str( ingressDevice )
1904 else:
1905 if not portIngress:
1906 main.log.error( "You must specify " +
1907 "the Ingress port" )
1908 return main.FALSE
1909
1910 cmd += " " +\
1911 str( ingressDevice ) + "/" +\
1912 str( portIngress )
1913
1914 if portEgressList is None:
1915 for egressDevice in egressDeviceList:
1916 if "/" in egressDevice:
1917 cmd += " " + str( egressDevice )
1918 else:
1919 main.log.error( "You must specify " +
1920 "the egress port" )
1921 # TODO: perhaps more meaningful return
1922 return main.FALSE
1923 else:
1924 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001925 for egressDevice, portEgress in zip( egressDeviceList,
1926 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001927 cmd += " " + \
1928 str( egressDevice ) + "/" +\
1929 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001930 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001931 main.log.error( "Device list and port list does not " +
1932 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001933 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001934 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001935 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001936 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001937 # If error, return error message
1938 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001939 main.log.error( self.name + ": Error in adding singlepoint-to-multipoint " +
kelvin-onlabb9408212015-04-01 13:34:04 -07001940 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001941 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001942 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001943 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001944 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001945 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001946 else:
1947 main.log.error( "Error, intent ID not found" )
1948 return None
Jon Hallc6793552016-01-19 14:18:37 -08001949 except AssertionError:
1950 main.log.exception( "" )
1951 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001952 except TypeError:
1953 main.log.exception( self.name + ": Object not as expected" )
1954 return None
shahshreyad0c80432014-12-04 16:56:05 -08001955 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001956 main.log.error( self.name + ": EOF exception found" )
1957 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001958 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001959 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001960 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001961 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001962
Hari Krishna9e232602015-04-13 17:29:08 -07001963 def addMplsIntent(
1964 self,
1965 ingressDevice,
1966 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001967 ingressPort="",
1968 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001969 ethType="",
1970 ethSrc="",
1971 ethDst="",
1972 bandwidth="",
1973 lambdaAlloc=False,
1974 ipProto="",
1975 ipSrc="",
1976 ipDst="",
1977 tcpSrc="",
1978 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001979 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001980 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001981 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001982 """
1983 Required:
1984 * ingressDevice: device id of ingress device
1985 * egressDevice: device id of egress device
1986 Optional:
1987 * ethType: specify ethType
1988 * ethSrc: specify ethSrc ( i.e. src mac addr )
1989 * ethDst: specify ethDst ( i.e. dst mac addr )
1990 * bandwidth: specify bandwidth capacity of link
1991 * lambdaAlloc: if True, intent will allocate lambda
1992 for the specified intent
1993 * ipProto: specify ip protocol
1994 * ipSrc: specify ip source address
1995 * ipDst: specify ip destination address
1996 * tcpSrc: specify tcp source port
1997 * tcpDst: specify tcp destination port
1998 * ingressLabel: Ingress MPLS label
1999 * egressLabel: Egress MPLS label
2000 Description:
2001 Adds MPLS intent by
2002 specifying device id's and optional fields
2003 Returns:
2004 A string of the intent id or None on error
2005
2006 NOTE: This function may change depending on the
2007 options developers provide for MPLS
2008 intent via cli
2009 """
2010 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07002011 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07002012
Jeremy Songsterff553672016-05-12 17:06:23 -07002013 if ethType:
2014 cmd += " --ethType " + str( ethType )
2015 if ethSrc:
2016 cmd += " --ethSrc " + str( ethSrc )
2017 if ethDst:
2018 cmd += " --ethDst " + str( ethDst )
2019 if bandwidth:
2020 cmd += " --bandwidth " + str( bandwidth )
2021 if lambdaAlloc:
2022 cmd += " --lambda "
2023 if ipProto:
2024 cmd += " --ipProto " + str( ipProto )
2025 if ipSrc:
2026 cmd += " --ipSrc " + str( ipSrc )
2027 if ipDst:
2028 cmd += " --ipDst " + str( ipDst )
2029 if tcpSrc:
2030 cmd += " --tcpSrc " + str( tcpSrc )
2031 if tcpDst:
2032 cmd += " --tcpDst " + str( tcpDst )
2033 if ingressLabel:
2034 cmd += " --ingressLabel " + str( ingressLabel )
2035 if egressLabel:
2036 cmd += " --egressLabel " + str( egressLabel )
2037 if priority:
2038 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07002039
2040 # Check whether the user appended the port
2041 # or provided it as an input
2042 if "/" in ingressDevice:
2043 cmd += " " + str( ingressDevice )
2044 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002045 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002046 main.log.error( "You must specify the ingress port" )
2047 return None
2048
2049 cmd += " " + \
2050 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002051 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07002052
2053 if "/" in egressDevice:
2054 cmd += " " + str( egressDevice )
2055 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002056 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002057 main.log.error( "You must specify the egress port" )
2058 return None
2059
2060 cmd += " " +\
2061 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002062 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07002063
2064 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08002065 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002066 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07002067 # If error, return error message
2068 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002069 main.log.error( self.name + ": Error in adding mpls intent" )
Hari Krishna9e232602015-04-13 17:29:08 -07002070 return None
2071 else:
2072 # TODO: print out all the options in this message?
2073 main.log.info( "MPLS intent installed between " +
2074 str( ingressDevice ) + " and " +
2075 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002076 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07002077 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002078 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07002079 else:
2080 main.log.error( "Error, intent ID not found" )
2081 return None
Jon Hallc6793552016-01-19 14:18:37 -08002082 except AssertionError:
2083 main.log.exception( "" )
2084 return None
Hari Krishna9e232602015-04-13 17:29:08 -07002085 except TypeError:
2086 main.log.exception( self.name + ": Object not as expected" )
2087 return None
2088 except pexpect.EOF:
2089 main.log.error( self.name + ": EOF exception found" )
2090 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002091 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002092 except Exception:
2093 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002094 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002095
Jon Hallefbd9792015-03-05 16:11:36 -08002096 def removeIntent( self, intentId, app='org.onosproject.cli',
2097 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002098 """
shahshreya1c818fc2015-02-26 13:44:08 -08002099 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07002100 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08002101 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07002102 -p or --purge: Purge the intent from the store after removal
2103
Jon Halle3f39ff2015-01-13 11:50:53 -08002104 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07002105 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08002106 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08002107 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002108 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002109 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08002110 if purge:
2111 cmdStr += " -p"
2112 if sync:
2113 cmdStr += " -s"
2114
2115 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002116 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002117 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002118 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08002119 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002120 main.log.error( self.name + ": Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002121 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04002122 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002123 # TODO: Should this be main.TRUE
2124 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002125 except AssertionError:
2126 main.log.exception( "" )
2127 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002128 except TypeError:
2129 main.log.exception( self.name + ": Object not as expected" )
2130 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002131 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002132 main.log.error( self.name + ": EOF exception found" )
2133 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002134 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002135 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002136 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002137 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002138
YPZhangfebf7302016-05-24 16:45:56 -07002139 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08002140 """
2141 Description:
2142 Remove all the intents
2143 Optional args:-
2144 -s or --sync: Waits for the removal before returning
2145 -p or --purge: Purge the intent from the store after removal
2146 Returns:
2147 Returns main.TRUE if all intents are removed, otherwise returns
2148 main.FALSE; Returns None for exception
2149 """
2150 try:
2151 cmdStr = "remove-intent"
2152 if purge:
2153 cmdStr += " -p"
2154 if sync:
2155 cmdStr += " -s"
2156
2157 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002158 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002159 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002160 assert "Command not found:" not in handle, handle
2161 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002162 main.log.error( self.name + ": Error in removing intent" )
Jeremy42df2e72016-02-23 16:37:46 -08002163 return main.FALSE
2164 else:
2165 return main.TRUE
2166 except AssertionError:
2167 main.log.exception( "" )
2168 return None
2169 except TypeError:
2170 main.log.exception( self.name + ": Object not as expected" )
2171 return None
2172 except pexpect.EOF:
2173 main.log.error( self.name + ": EOF exception found" )
2174 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002175 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002176 except Exception:
2177 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002178 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002179
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002180 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002181 """
2182 Purges all WITHDRAWN Intents
2183 """
2184 try:
2185 cmdStr = "purge-intents"
2186 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002187 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002188 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002189 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002190 main.log.error( self.name + ": Error in purging intents" )
Hari Krishna0ce0e152015-06-23 09:55:29 -07002191 return main.FALSE
2192 else:
2193 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002194 except AssertionError:
2195 main.log.exception( "" )
2196 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002197 except TypeError:
2198 main.log.exception( self.name + ": Object not as expected" )
2199 return None
2200 except pexpect.EOF:
2201 main.log.error( self.name + ": EOF exception found" )
2202 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002203 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002204 except Exception:
2205 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002206 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002207
Devin Lime6fe3c42017-10-18 16:28:40 -07002208 def wipeout( self ):
2209 """
2210 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2211 """
2212 try:
2213 cmdStr = "wipe-out please"
2214 handle = self.sendline( cmdStr, timeout=60 )
2215 assert handle is not None, "Error in sendline"
2216 assert "Command not found:" not in handle, handle
2217 return main.TRUE
2218 except AssertionError:
2219 main.log.exception( "" )
2220 return None
2221 except TypeError:
2222 main.log.exception( self.name + ": Object not as expected" )
2223 return None
2224 except pexpect.EOF:
2225 main.log.error( self.name + ": EOF exception found" )
2226 main.log.error( self.name + ": " + self.handle.before )
2227 main.cleanAndExit()
2228 except Exception:
2229 main.log.exception( self.name + ": Uncaught exception!" )
2230 main.cleanAndExit()
2231
kelvin-onlabd3b64892015-01-20 13:26:24 -08002232 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002233 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002234 NOTE: This method should be used after installing application:
2235 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002236 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002237 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002238 Description:
2239 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002240 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002241 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002242 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002243 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002244 cmdStr += " -j"
2245 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002246 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002247 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002248 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002249 except AssertionError:
2250 main.log.exception( "" )
2251 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002252 except TypeError:
2253 main.log.exception( self.name + ": Object not as expected" )
2254 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002255 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002256 main.log.error( self.name + ": EOF exception found" )
2257 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002258 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002259 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002260 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002261 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002262
pingping-lin54b03372015-08-13 14:43:10 -07002263 def ipv4RouteNumber( self ):
2264 """
2265 NOTE: This method should be used after installing application:
2266 onos-app-sdnip
2267 Description:
2268 Obtain the total IPv4 routes number in the system
2269 """
2270 try:
Pratik Parab57963572017-05-09 11:37:54 -07002271 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002272 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002273 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002274 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002275 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002276 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002277 except AssertionError:
2278 main.log.exception( "" )
2279 return None
2280 except ( TypeError, ValueError ):
2281 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002282 return None
2283 except pexpect.EOF:
2284 main.log.error( self.name + ": EOF exception found" )
2285 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002286 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002287 except Exception:
2288 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002289 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002290
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002291 # =============Function to check Bandwidth allocation========
Jon Hall0e240372018-05-02 11:21:57 -07002292 def allocations( self, jsonFormat = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002293 """
2294 Description:
2295 Obtain Bandwidth Allocation Information from ONOS cli.
2296 """
2297 try:
2298 cmdStr = "allocations"
2299 if jsonFormat:
2300 cmdStr += " -j"
Jon Hall0e240372018-05-02 11:21:57 -07002301 handle = self.sendline( cmdStr, timeout=300 )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002302 assert handle is not None, "Error in sendline"
2303 assert "Command not found:" not in handle, handle
2304 return handle
2305 except AssertionError:
2306 main.log.exception( "" )
2307 return None
2308 except ( TypeError, ValueError ):
2309 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2310 return None
2311 except pexpect.EOF:
2312 main.log.error( self.name + ": EOF exception found" )
2313 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002314 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002315 except Exception:
2316 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002317 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002318
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002319 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002320 """
andrewonlabe6745342014-10-17 14:29:13 -04002321 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002322 Obtain intents from the ONOS cli.
2323 Optional:
2324 * jsonFormat: Enable output formatting in json, default to True
2325 * summary: Whether only output the intent summary, defaults to False
2326 * type: Only output a certain type of intent. This options is valid
2327 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002328 """
andrewonlabe6745342014-10-17 14:29:13 -04002329 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002330 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002331 if summary:
2332 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002333 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002334 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002335 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002336 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002337 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002338 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002339 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002340 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002341 else:
Jon Hallff566d52016-01-15 14:45:36 -08002342 intentType = ""
2343 # IF we want the summary of a specific intent type
2344 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002345 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002346 if intentType in jsonResult.keys():
2347 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002348 else:
Jon Hallff566d52016-01-15 14:45:36 -08002349 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002350 return handle
2351 else:
2352 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002353 except AssertionError:
2354 main.log.exception( "" )
2355 return None
2356 except ( TypeError, ValueError ):
2357 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002358 return None
2359 except pexpect.EOF:
2360 main.log.error( self.name + ": EOF exception found" )
2361 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002362 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002363 except Exception:
2364 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002365 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002366
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002367 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002368 """
You Wangfdcbfc42016-05-16 12:16:53 -07002369 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002370 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002371 list of intent IDs.
2372 Parameters:
2373 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002374 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002375 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002376 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002377 accepted.
2378 Returns a list of dictionaries if a list of intent IDs is accepted,
2379 and each dictionary maps 'id' to the Intent ID and 'state' to
2380 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002381 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002382
kelvin-onlab54400a92015-02-26 18:05:51 -08002383 try:
2384 state = "State is Undefined"
2385 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002386 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002387 else:
Jon Hallc6793552016-01-19 14:18:37 -08002388 rawJson = intentsJson
2389 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002390 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002391 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002392 if intentsId == intent[ 'id' ]:
2393 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002394 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002395 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002396 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002397 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002398 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002399 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002400 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002401 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002402 for intent in parsedIntentsJson:
2403 if intentsId[ i ] == intent[ 'id' ]:
2404 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002405 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002406 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002407 break
Jon Hallefbd9792015-03-05 16:11:36 -08002408 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002409 main.log.warn( "Could not find all intents in ONOS output" )
2410 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002411 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002412 else:
Jon Hall53158082017-05-18 11:17:00 -07002413 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002414 return None
Jon Hallc6793552016-01-19 14:18:37 -08002415 except ( TypeError, ValueError ):
2416 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002417 return None
2418 except pexpect.EOF:
2419 main.log.error( self.name + ": EOF exception found" )
2420 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002421 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002422 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002423 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002424 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002425
Jon Hallf539eb92017-05-22 17:18:42 -07002426 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002427 """
2428 Description:
2429 Check intents state
2430 Required:
2431 intentsId - List of intents ID to be checked
2432 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002433 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002434 state in the list.
2435 *NOTE: You can pass in a list of expected state,
2436 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002437 Return:
Jon Hall53158082017-05-18 11:17:00 -07002438 Returns main.TRUE only if all intent are the same as expected states,
2439 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002440 """
2441 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002442 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002443 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002444
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002445 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002446 intentsDict = []
2447 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002448 if isinstance( intentsId, types.StringType ) \
2449 and intent.get( 'id' ) == intentsId:
2450 intentsDict.append( intent )
2451 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002452 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002453 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002454
2455 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002456 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002457 "getting intents state" )
2458 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002459
2460 if isinstance( expectedState, types.StringType ):
2461 for intents in intentsDict:
2462 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002463 main.log.debug( self.name + " : Intent ID - " +
2464 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002465 " actual state = " +
2466 intents.get( 'state' )
2467 + " does not equal expected state = "
2468 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002469 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002470 elif isinstance( expectedState, types.ListType ):
2471 for intents in intentsDict:
2472 if not any( state == intents.get( 'state' ) for state in
2473 expectedState ):
2474 main.log.debug( self.name + " : Intent ID - " +
2475 intents.get( 'id' ) +
2476 " actual state = " +
2477 intents.get( 'state' ) +
2478 " does not equal expected states = "
2479 + str( expectedState ) )
2480 returnValue = main.FALSE
2481
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002482 if returnValue == main.TRUE:
2483 main.log.info( self.name + ": All " +
2484 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002485 " intents are in " + str( expectedState ) +
2486 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002487 return returnValue
2488 except TypeError:
2489 main.log.exception( self.name + ": Object not as expected" )
2490 return None
2491 except pexpect.EOF:
2492 main.log.error( self.name + ": EOF exception found" )
2493 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002494 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002495 except Exception:
2496 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002497 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002498
Jon Hallf539eb92017-05-22 17:18:42 -07002499 def compareBandwidthAllocations( self, expectedAllocations ):
2500 """
2501 Description:
2502 Compare the allocated bandwidth with the given allocations
2503 Required:
2504 expectedAllocations - The expected ONOS output of the allocations command
2505 Return:
2506 Returns main.TRUE only if all intent are the same as expected states,
2507 otherwise returns main.FALSE.
2508 """
2509 # FIXME: Convert these string comparisons to object comparisons
2510 try:
2511 returnValue = main.TRUE
2512 bandwidthFailed = False
2513 rawAlloc = self.allocations()
2514 expectedFormat = StringIO( expectedAllocations )
2515 ONOSOutput = StringIO( rawAlloc )
2516 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2517 str( expectedFormat ) ) )
2518
2519 for actual, expected in izip( ONOSOutput, expectedFormat ):
2520 actual = actual.rstrip()
2521 expected = expected.rstrip()
2522 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2523 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002524 marker1 = actual.find( 'allocated' )
2525 m1 = actual[ :marker1 ]
2526 marker2 = expected.find( 'allocated' )
2527 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002528 if m1 != m2:
2529 bandwidthFailed = True
2530 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2531 bandwidthFailed = True
2532 expectedFormat.close()
2533 ONOSOutput.close()
2534
2535 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002536 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002537 returnValue = main.FALSE
2538 return returnValue
2539 except TypeError:
2540 main.log.exception( self.name + ": Object not as expected" )
2541 return None
2542 except pexpect.EOF:
2543 main.log.error( self.name + ": EOF exception found" )
2544 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002545 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002546 except Exception:
2547 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002548 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002549
You Wang66518af2016-05-16 15:32:59 -07002550 def compareIntent( self, intentDict ):
2551 """
2552 Description:
2553 Compare the intent ids and states provided in the argument with all intents in ONOS
2554 Return:
2555 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2556 Arguments:
2557 intentDict: a dictionary which maps intent ids to intent states
2558 """
2559 try:
2560 intentsRaw = self.intents()
2561 intentsJson = json.loads( intentsRaw )
2562 intentDictONOS = {}
2563 for intent in intentsJson:
2564 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002565 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002566 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002567 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002568 str( len( intentDict ) ) + " expected and " +
2569 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002570 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002571 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002572 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002573 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2574 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002575 else:
2576 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2577 main.log.debug( self.name + ": intent ID - " + intentID +
2578 " expected state is " + intentDict[ intentID ] +
2579 " but actual state is " + intentDictONOS[ intentID ] )
2580 returnValue = main.FALSE
2581 intentDictONOS.pop( intentID )
2582 if len( intentDictONOS ) > 0:
2583 returnValue = main.FALSE
2584 for intentID in intentDictONOS.keys():
2585 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002586 if returnValue == main.TRUE:
2587 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2588 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002589 except KeyError:
2590 main.log.exception( self.name + ": KeyError exception found" )
2591 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002592 except ( TypeError, ValueError ):
2593 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002594 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002595 except pexpect.EOF:
2596 main.log.error( self.name + ": EOF exception found" )
2597 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002598 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002599 except Exception:
2600 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002601 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002602
YPZhang14a4aa92016-07-15 13:37:15 -07002603 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002604 """
2605 Description:
2606 Check the number of installed intents.
2607 Optional:
2608 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002609 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002610 Return:
2611 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2612 , otherwise, returns main.FALSE.
2613 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002614
GlennRCed771242016-01-13 17:02:47 -08002615 try:
2616 cmd = "intents -s -j"
2617
2618 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002619 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002620 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002621 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002622 response = json.loads( response )
2623
2624 # get total and installed number, see if they are match
2625 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002626 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002627 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2628 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002629 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002630 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2631 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002632 return main.FALSE
2633
Jon Hallc6793552016-01-19 14:18:37 -08002634 except ( TypeError, ValueError ):
2635 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002636 return None
2637 except pexpect.EOF:
2638 main.log.error( self.name + ": EOF exception found" )
2639 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002640 if noExit:
2641 return main.FALSE
2642 else:
Devin Lim44075962017-08-11 10:56:37 -07002643 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002644 except pexpect.TIMEOUT:
2645 main.log.error( self.name + ": ONOS timeout" )
2646 return None
GlennRCed771242016-01-13 17:02:47 -08002647 except Exception:
2648 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002649 if noExit:
2650 return main.FALSE
2651 else:
Devin Lim44075962017-08-11 10:56:37 -07002652 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002653
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002654 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002655 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002656 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002657 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002658 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002659 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002660 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002661 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002662 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002663 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002664 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002665 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002666 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002667 cmdStr += " -n"
2668 cmdStr += " " + state
2669 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002670 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002671 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002672 assert "Command not found:" not in handle, handle
2673 if re.search( "Error:", handle ):
2674 main.log.error( self.name + ": flows() response: " +
2675 str( handle ) )
2676 return handle
2677 except AssertionError:
2678 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002679 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002680 except TypeError:
2681 main.log.exception( self.name + ": Object not as expected" )
2682 return None
Jon Hallc6793552016-01-19 14:18:37 -08002683 except pexpect.TIMEOUT:
2684 main.log.error( self.name + ": ONOS timeout" )
2685 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002686 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002687 main.log.error( self.name + ": EOF exception found" )
2688 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002689 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002690 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002691 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002692 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002693
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002694 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002695 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002696 count = int( count ) if count else 0
steven30801eccfe212019-01-24 13:00:42 +08002697 main.log.debug( "found {} flows".format( count ) )
Jon Hall39570262020-11-17 12:18:19 -08002698 return count if ( count >= min ) else False
GlennRCed771242016-01-13 17:02:47 -08002699
Jon Halle0f0b342017-04-18 11:43:47 -07002700 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002701 """
2702 Description:
GlennRCed771242016-01-13 17:02:47 -08002703 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002704 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2705 if the count of those states is 0, which means all current flows
2706 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002707 Optional:
GlennRCed771242016-01-13 17:02:47 -08002708 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002709 Return:
2710 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002711 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002712 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002713 """
2714 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002715 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002716 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002717 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002718 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002719 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002720 if rawFlows:
2721 # if we didn't get flows or flows function return None, we should return
2722 # main.Flase
2723 checkedStates.append( json.loads( rawFlows ) )
2724 else:
2725 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002726 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002727 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002728 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002729 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002730 except TypeError:
2731 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002732 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002733
GlennRCed771242016-01-13 17:02:47 -08002734 # We want to count PENDING_ADD if isPENDING is true
2735 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002736 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002737 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002738 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002739 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002740 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002741 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002742 except ( TypeError, ValueError ):
2743 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002744 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002745
YPZhang240842b2016-05-17 12:00:50 -07002746 except AssertionError:
2747 main.log.exception( "" )
2748 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002749 except pexpect.TIMEOUT:
2750 main.log.error( self.name + ": ONOS timeout" )
2751 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002752 except pexpect.EOF:
2753 main.log.error( self.name + ": EOF exception found" )
2754 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002755 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002756 except Exception:
2757 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002758 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002759
GlennRCed771242016-01-13 17:02:47 -08002760 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002761 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002762 """
andrewonlab87852b02014-11-19 18:44:19 -05002763 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002764 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002765 a specific point-to-point intent definition
2766 Required:
GlennRCed771242016-01-13 17:02:47 -08002767 * ingress: specify source dpid
2768 * egress: specify destination dpid
2769 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002770 Optional:
GlennRCed771242016-01-13 17:02:47 -08002771 * offset: the keyOffset is where the next batch of intents
2772 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002773 * noExit: If set to True, TestON will not exit if any error when issus command
2774 * getResponse: If set to True, function will return ONOS response.
2775
GlennRCed771242016-01-13 17:02:47 -08002776 Returns: If failed to push test intents, it will returen None,
2777 if successful, return true.
2778 Timeout expection will return None,
2779 TypeError will return false
2780 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002781 """
andrewonlab87852b02014-11-19 18:44:19 -05002782 try:
GlennRCed771242016-01-13 17:02:47 -08002783 if background:
2784 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002785 else:
GlennRCed771242016-01-13 17:02:47 -08002786 back = ""
2787 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002788 ingress,
2789 egress,
2790 batchSize,
2791 offset,
2792 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002793 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002794 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002795 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002796 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002797 if getResponse:
2798 return response
2799
GlennRCed771242016-01-13 17:02:47 -08002800 # TODO: We should handle if there is failure in installation
2801 return main.TRUE
2802
Jon Hallc6793552016-01-19 14:18:37 -08002803 except AssertionError:
2804 main.log.exception( "" )
2805 return None
GlennRCed771242016-01-13 17:02:47 -08002806 except pexpect.TIMEOUT:
2807 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002808 return None
andrewonlab87852b02014-11-19 18:44:19 -05002809 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002810 main.log.error( self.name + ": EOF exception found" )
2811 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002812 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002813 except TypeError:
2814 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002815 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002816 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002817 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002818 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002819
YPZhangebf9eb52016-05-12 15:20:24 -07002820 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002821 """
2822 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002823 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002824 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002825 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002826 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002827 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002828
YPZhangb5d3f832016-01-23 22:54:26 -08002829 try:
YPZhange3109a72016-02-02 11:25:37 -08002830 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002831 cmd = "flows -c added"
2832 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2833 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002834 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002835 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002836 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002837 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002838 else:
You Wang68568b12019-03-04 11:49:57 -08002839 main.log.warn( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002840 return None
2841 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002842
You Wangd3097f72018-12-12 11:56:03 -08002843 except IndexError:
2844 main.log.exception( "{}: Object not as expected!".format( self.name ) )
2845 main.log.debug( "rawFlows: {}".format( rawFlows ) )
2846 return None
You Wangd3cb2ce2016-05-16 14:01:24 -07002847 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002848 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002849 return None
2850 except pexpect.EOF:
2851 main.log.error( self.name + ": EOF exception found" )
2852 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002853 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002854 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002855 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002856 except pexpect.TIMEOUT:
2857 main.log.error( self.name + ": ONOS timeout" )
2858 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002859 except Exception:
2860 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002861 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002862 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002863 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002864
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002865 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002866 """
2867 Description:
2868 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002869 Optional:
2870 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002871 Return:
2872 The number of intents
2873 """
2874 try:
2875 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002876 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002877 if response is None:
2878 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002879 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002880 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002881 except ( TypeError, ValueError ):
2882 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002883 return None
2884 except pexpect.EOF:
2885 main.log.error( self.name + ": EOF exception found" )
2886 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002887 if noExit:
2888 return -1
2889 else:
Devin Lim44075962017-08-11 10:56:37 -07002890 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002891 except Exception:
2892 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002893 if noExit:
2894 return -1
2895 else:
Devin Lim44075962017-08-11 10:56:37 -07002896 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002897
kelvin-onlabd3b64892015-01-20 13:26:24 -08002898 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002899 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002900 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002901 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002902 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002903 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002904 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002905 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002906 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002907 cmdStr += " -j"
2908 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002909 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002910 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002911 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002912 except AssertionError:
2913 main.log.exception( "" )
2914 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002915 except TypeError:
2916 main.log.exception( self.name + ": Object not as expected" )
2917 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002918 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002919 main.log.error( self.name + ": EOF exception found" )
2920 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002921 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002922 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002923 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002924 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002925
kelvin-onlabd3b64892015-01-20 13:26:24 -08002926 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002927 """
2928 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002929 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002930 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002931 """
andrewonlab867212a2014-10-22 20:13:38 -04002932 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002933 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002934 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002935 cmdStr += " -j"
2936 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002937 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002938 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002939 if handle:
2940 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002941 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002942 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002943 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002944 else:
2945 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002946 except AssertionError:
2947 main.log.exception( "" )
2948 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002949 except TypeError:
2950 main.log.exception( self.name + ": Object not as expected" )
2951 return None
andrewonlab867212a2014-10-22 20:13:38 -04002952 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002953 main.log.error( self.name + ": EOF exception found" )
2954 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002955 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002956 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002957 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002958 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002959
kelvin8ec71442015-01-15 16:57:00 -08002960 # Wrapper functions ****************
2961 # Wrapper functions use existing driver
2962 # functions and extends their use case.
2963 # For example, we may use the output of
2964 # a normal driver function, and parse it
2965 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002966
kelvin-onlabd3b64892015-01-20 13:26:24 -08002967 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002968 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002969 Description:
2970 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002971 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002972 try:
kelvin8ec71442015-01-15 16:57:00 -08002973 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002974 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002975 if intentsStr is None:
2976 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002977 # Convert to a dictionary
2978 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002979 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002980 for intent in intents:
2981 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002982 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002983 except TypeError:
2984 main.log.exception( self.name + ": Object not as expected" )
2985 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002986 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002987 main.log.error( self.name + ": EOF exception found" )
2988 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002989 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002990 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002991 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002992 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002993
You Wang3c276252016-09-21 15:21:36 -07002994 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002995 """
2996 Determine the number of flow rules for the given device id that are
2997 in the added state
You Wang3c276252016-09-21 15:21:36 -07002998 Params:
2999 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08003000 """
3001 try:
You Wang3c276252016-09-21 15:21:36 -07003002 if core:
3003 cmdStr = "flows any " + str( deviceId ) + " | " +\
3004 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
3005 else:
3006 cmdStr = "flows any " + str( deviceId ) + " | " +\
3007 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003008 handle = self.lineCount( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003009 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003010 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08003011 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003012 except AssertionError:
3013 main.log.exception( "" )
3014 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08003015 except pexpect.EOF:
3016 main.log.error( self.name + ": EOF exception found" )
3017 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003018 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003019 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08003020 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003021 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04003022
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003023 def groupAddedCount( self, deviceId, core=False ):
3024 """
3025 Determine the number of group rules for the given device id that are
3026 in the added state
3027 Params:
3028 core: if True, only return the number of core groups added
3029 """
3030 try:
3031 if core:
3032 cmdStr = "groups any " + str( deviceId ) + " | " +\
3033 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
3034 else:
3035 cmdStr = "groups any " + str( deviceId ) + " | " +\
3036 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003037 handle = self.lineCount( cmdStr )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003038 assert handle is not None, "Error in sendline"
3039 assert "Command not found:" not in handle, handle
3040 return handle
3041 except AssertionError:
3042 main.log.exception( "" )
3043 return None
3044 except pexpect.EOF:
3045 main.log.error( self.name + ": EOF exception found" )
3046 main.log.error( self.name + ": " + self.handle.before )
3047 main.cleanAndExit()
3048 except Exception:
3049 main.log.exception( self.name + ": Uncaught exception!" )
3050 main.cleanAndExit()
3051
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003052 def addStaticRoute( self, subnet, intf):
3053 """
3054 Adds a static route to onos.
3055 Params:
3056 subnet: The subnet reaching through this route
3057 intf: The interface this route is reachable through
3058 """
3059 try:
3060 cmdStr = "route-add " + subnet + " " + intf
3061 handle = self.sendline( cmdStr )
3062 assert handle is not None, "Error in sendline"
3063 assert "Command not found:" not in handle, handle
3064 return handle
3065 except AssertionError:
3066 main.log.exception( "" )
3067 return None
3068 except pexpect.EOF:
3069 main.log.error( self.name + ": EOF exception found" )
3070 main.log.error( self.name + ": " + self.handle.before )
3071 main.cleanAndExit()
3072 except Exception:
3073 main.log.exception( self.name + ": Uncaught exception!" )
3074 main.cleanAndExit()
3075
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003076 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
3077 """
3078 Description:
3079 Check whether the number of groups for the given device id that
3080 are in ADDED state is bigger than minGroupCount.
3081 Required:
3082 * deviceId: device id to check the number of added group rules
3083 Optional:
3084 * minGroupCount: the number of groups to compare
3085 * core: if True, only check the number of core groups added
3086 * comparison: if 0, compare with greater than minFlowCount
3087 * if 1, compare with equal to minFlowCount
3088 Return:
3089 Returns the number of groups if it is bigger than minGroupCount,
3090 returns main.FALSE otherwise.
3091 """
3092 count = self.groupAddedCount( deviceId, core )
3093 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003094 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003095 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
3096
You Wangc02f3be2018-05-18 12:14:23 -07003097 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003098 """
3099 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07003100 deviceId: Id of the device from which we retrieve groups
3101 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003102 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003103 try:
You Wangc02f3be2018-05-18 12:14:23 -07003104 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
3105 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003106 assert handle is not None, "Error in sendline"
3107 assert "Command not found:" not in handle, handle
3108 return handle
3109 except AssertionError:
3110 main.log.exception( "" )
3111 return None
3112 except TypeError:
3113 main.log.exception( self.name + ": Object not as expected" )
3114 return None
3115 except pexpect.EOF:
3116 main.log.error( self.name + ": EOF exception found" )
3117 main.log.error( self.name + ": " + self.handle.before )
3118 main.cleanAndExit()
3119 except Exception:
3120 main.log.exception( self.name + ": Uncaught exception!" )
3121 main.cleanAndExit()
3122
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003123 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003124 """
3125 Description:
3126 Check whether the number of flow rules for the given device id that
3127 are in ADDED state is bigger than minFlowCount.
3128 Required:
3129 * deviceId: device id to check the number of added flow rules
3130 Optional:
3131 * minFlowCount: the number of flow rules to compare
3132 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003133 * comparison: if 0, compare with greater than minFlowCount
3134 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003135 Return:
3136 Returns the number of flow rules if it is bigger than minFlowCount,
3137 returns main.FALSE otherwise.
3138 """
3139 count = self.flowAddedCount( deviceId, core )
3140 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003141 main.log.debug( "found {} flows".format( count ) )
Jon Hall39570262020-11-17 12:18:19 -08003142 return count if ((count >= expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003143
kelvin-onlabd3b64892015-01-20 13:26:24 -08003144 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003145 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003146 Use 'devices' function to obtain list of all devices
3147 and parse the result to obtain a list of all device
3148 id's. Returns this list. Returns empty list if no
3149 devices exist
kelvin8ec71442015-01-15 16:57:00 -08003150 List is ordered sequentially
3151
andrewonlab3e15ead2014-10-15 14:21:34 -04003152 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003153 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003154 the ids. By obtaining the list of device ids on the fly,
3155 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003156 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003157 try:
kelvin8ec71442015-01-15 16:57:00 -08003158 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003159 devicesStr = self.devices( jsonFormat=False )
3160 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003161
kelvin-onlabd3b64892015-01-20 13:26:24 -08003162 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003163 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003164 return idList
kelvin8ec71442015-01-15 16:57:00 -08003165
3166 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003167 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003168 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003169 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003170 # Split list further into arguments before and after string
3171 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003172 # append to idList
3173 for arg in tempList:
3174 idList.append( arg.split( "id=" )[ 1 ] )
3175 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003176
Jon Halld4d4b372015-01-28 16:02:41 -08003177 except TypeError:
3178 main.log.exception( self.name + ": Object not as expected" )
3179 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003180 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003181 main.log.error( self.name + ": EOF exception found" )
3182 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003183 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003184 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003185 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003186 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003187
kelvin-onlabd3b64892015-01-20 13:26:24 -08003188 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003189 """
andrewonlab7c211572014-10-15 16:45:20 -04003190 Uses 'nodes' function to obtain list of all nodes
3191 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003192 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003193 Returns:
3194 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003195 """
andrewonlab7c211572014-10-15 16:45:20 -04003196 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003197 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003198 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003199 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003200 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003201 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003202 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003203 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003204 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003205 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003206 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003207 except ( TypeError, ValueError ):
3208 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003209 return None
andrewonlab7c211572014-10-15 16:45:20 -04003210 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003211 main.log.error( self.name + ": EOF exception found" )
3212 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003213 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003214 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003215 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003216 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003217
kelvin-onlabd3b64892015-01-20 13:26:24 -08003218 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003219 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003220 Return the first device from the devices api whose 'id' contains 'dpid'
3221 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003222 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003223 try:
kelvin8ec71442015-01-15 16:57:00 -08003224 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003225 return None
3226 else:
kelvin8ec71442015-01-15 16:57:00 -08003227 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003228 rawDevices = self.devices()
3229 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003230 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003231 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003232 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3233 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003234 return device
3235 return None
Jon Hallc6793552016-01-19 14:18:37 -08003236 except ( TypeError, ValueError ):
3237 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003238 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003239 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003240 main.log.error( self.name + ": EOF exception found" )
3241 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003242 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003243 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003244 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003245 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003246
You Wang24139872016-05-03 11:48:47 -07003247 def getTopology( self, topologyOutput ):
3248 """
3249 Definition:
3250 Loads a json topology output
3251 Return:
3252 topology = current ONOS topology
3253 """
You Wang24139872016-05-03 11:48:47 -07003254 try:
3255 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003256 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003257 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003258 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003259 except ( TypeError, ValueError ):
3260 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3261 return None
You Wang24139872016-05-03 11:48:47 -07003262 except pexpect.EOF:
3263 main.log.error( self.name + ": EOF exception found" )
3264 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003265 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003266 except Exception:
3267 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003268 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003269
Jon Hall39570262020-11-17 12:18:19 -08003270 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, numoSCCs=1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003271 """
Jon Hallefbd9792015-03-05 16:11:36 -08003272 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003273 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003274 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003275
Flavio Castro82ee2f62016-06-07 15:04:12 -07003276 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003277 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003278 numoctrl = expected number of controllers
Jon Hall39570262020-11-17 12:18:19 -08003279 numoSCCs = Number of expected SCCs
You Wang24139872016-05-03 11:48:47 -07003280 logLevel = level to log to.
3281 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003282
Jon Hallefbd9792015-03-05 16:11:36 -08003283 Returns: main.TRUE if the number of switches and links are correct,
3284 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003285 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003286 """
Jon Hall42db6dc2014-10-24 19:03:48 -04003287 try:
You Wang13310252016-07-31 10:56:14 -07003288 summary = self.summary()
3289 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003290 except ( TypeError, ValueError ):
3291 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3292 return main.ERROR
3293 try:
3294 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003295 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003296 return main.ERROR
3297 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003298 # Is the number of switches is what we expected
3299 devices = topology.get( 'devices', False )
3300 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003301 nodes = summary.get( 'nodes', False )
Jon Hall39570262020-11-17 12:18:19 -08003302 SCCs = summary.get( 'SCC(s)', False )
3303 if devices is False or links is False or nodes is False or SCCs is False:
3304 main.log.warn( "Issues parsing topology and summary output" )
3305 main.log.debug( topology )
3306 main.log.debug( summary )
Jon Hall42db6dc2014-10-24 19:03:48 -04003307 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003308 switchCheck = ( int( devices ) == int( numoswitch ) )
Jon Hall39570262020-11-17 12:18:19 -08003309 if not switchCheck:
3310 main.log.debug( "switch Check Failed" )
Pier6a0c4de2018-03-18 16:01:30 -07003311 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Jon Hall39570262020-11-17 12:18:19 -08003312 if not linkCheck:
3313 main.log.debug( "link Check Failed" )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003314 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
Jon Hall39570262020-11-17 12:18:19 -08003315 if not nodeCheck:
3316 main.log.debug( "node Check Failed" )
3317 SCCsCheck = ( int( SCCs ) == int( numoSCCs ) ) or int( numoSCCs ) == -1
3318 if not SCCsCheck:
3319 main.log.debug( "SCCs Check Failed" )
3320 if switchCheck and linkCheck and nodeCheck and SCCsCheck:
kelvin8ec71442015-01-15 16:57:00 -08003321 # We expected the correct numbers
Jon Hall39570262020-11-17 12:18:19 -08003322 output = output + "The number of links, switches, nodes, and SCCs match "\
You Wang24139872016-05-03 11:48:47 -07003323 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003324 result = main.TRUE
3325 else:
You Wang24139872016-05-03 11:48:47 -07003326 output = output + \
Jon Hall627b1572020-12-01 12:01:15 -08003327 "The number of links, switches, nodes, and SCCs does not match " + \
You Wang24139872016-05-03 11:48:47 -07003328 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003329 result = main.FALSE
Jon Hall39570262020-11-17 12:18:19 -08003330 output = output + "\n ONOS sees %i devices " % int( devices )
3331 output = output + "(%i expected) " % int( numoswitch )
3332 if int( numolink ) >= 0:
Pier6a0c4de2018-03-18 16:01:30 -07003333 output = output + "and %i links " % int( links )
Jon Hall39570262020-11-17 12:18:19 -08003334 output = output + "(%i expected) " % int( numolink )
3335 if int( numoctrl ) >= 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003336 output = output + "and %i controllers " % int( nodes )
Jon Hall39570262020-11-17 12:18:19 -08003337 output = output + "(%i expected) " % int( numoctrl )
3338 if int( numoSCCs ) >= 0:
3339 output = output + "and %i SCCs " % int( SCCs )
3340 output = output + "(%i expected)" % int( numoSCCs )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003341 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003342 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003343 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003344 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003345 else:
You Wang24139872016-05-03 11:48:47 -07003346 main.log.info( output )
Jon Hall39570262020-11-17 12:18:19 -08003347 main.TOPOOUTPUT = output
kelvin8ec71442015-01-15 16:57:00 -08003348 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003349 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003350 main.log.error( self.name + ": EOF exception found" )
3351 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003352 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003353 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003354 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003355 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003356
kelvin-onlabd3b64892015-01-20 13:26:24 -08003357 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003358 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003359 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003360 deviceId must be the id of a device as seen in the onos devices command
3361 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003362 role must be either master, standby, or none
3363
Jon Halle3f39ff2015-01-13 11:50:53 -08003364 Returns:
3365 main.TRUE or main.FALSE based on argument verification and
3366 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003367 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003368 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003369 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003370 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003371 cmdStr = "device-role " +\
3372 str( deviceId ) + " " +\
3373 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003374 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003375 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003376 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003377 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003378 if re.search( "Error", handle ):
3379 # end color output to escape any colours
3380 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003381 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003382 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003383 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003384 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003385 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003386 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003387 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003388 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003389 except AssertionError:
3390 main.log.exception( "" )
3391 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003392 except TypeError:
3393 main.log.exception( self.name + ": Object not as expected" )
3394 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003395 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003396 main.log.error( self.name + ": EOF exception found" )
3397 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003398 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003399 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003400 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003401 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003402
kelvin-onlabd3b64892015-01-20 13:26:24 -08003403 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003404 """
Jon Hall0dd09952018-04-19 09:59:11 -07003405 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003406 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003407 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003408 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003409 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003410 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003411 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003412 cmdStr += " -j"
3413 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003414 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003415 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003416 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003417 except AssertionError:
3418 main.log.exception( "" )
3419 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003420 except TypeError:
3421 main.log.exception( self.name + ": Object not as expected" )
3422 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003423 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003424 main.log.error( self.name + ": EOF exception found" )
3425 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003426 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003427 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003428 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003429 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003430
kelvin-onlabd3b64892015-01-20 13:26:24 -08003431 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003432 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003433 CLI command to get the current leader for the Election test application
3434 NOTE: Requires installation of the onos-app-election feature
3435 Returns: Node IP of the leader if one exists
3436 None if none exists
3437 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003438 """
Jon Hall94fd0472014-12-08 11:52:42 -08003439 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003440 cmdStr = "election-test-leader"
3441 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003442 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003443 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003444 # Leader
3445 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003446 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003447 nodeSearch = re.search( leaderPattern, response )
3448 if nodeSearch:
3449 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003450 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003451 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003452 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003453 # no leader
3454 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003455 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003456 nullSearch = re.search( nullPattern, response )
3457 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003458 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003459 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003460 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003461 # error
Jon Hall0e240372018-05-02 11:21:57 -07003462 main.log.error( self.name + ": Error in electionTestLeader on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003463 ": " + "unexpected response" )
3464 main.log.error( repr( response ) )
3465 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003466 except AssertionError:
3467 main.log.exception( "" )
3468 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003469 except TypeError:
3470 main.log.exception( self.name + ": Object not as expected" )
3471 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003472 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003473 main.log.error( self.name + ": EOF exception found" )
3474 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003475 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003476 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003477 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003478 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003479
kelvin-onlabd3b64892015-01-20 13:26:24 -08003480 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003481 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003482 CLI command to run for leadership of the Election test application.
3483 NOTE: Requires installation of the onos-app-election feature
3484 Returns: Main.TRUE on success
3485 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003486 """
Jon Hall94fd0472014-12-08 11:52:42 -08003487 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003488 cmdStr = "election-test-run"
3489 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003490 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003491 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003492 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003493 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003494 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003495 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003496 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003497 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003498 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003499 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003500 # error
Jon Hall0e240372018-05-02 11:21:57 -07003501 main.log.error( self.name + ": Error in electionTestRun on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003502 ": " + "unexpected response" )
3503 main.log.error( repr( response ) )
3504 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003505 except AssertionError:
3506 main.log.exception( "" )
3507 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003508 except TypeError:
3509 main.log.exception( self.name + ": Object not as expected" )
3510 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003511 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003512 main.log.error( self.name + ": EOF exception found" )
3513 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003514 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003515 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003516 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003517 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003518
kelvin-onlabd3b64892015-01-20 13:26:24 -08003519 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003520 """
Jon Hall94fd0472014-12-08 11:52:42 -08003521 * CLI command to withdraw the local node from leadership election for
3522 * the Election test application.
3523 #NOTE: Requires installation of the onos-app-election feature
3524 Returns: Main.TRUE on success
3525 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003526 """
Jon Hall94fd0472014-12-08 11:52:42 -08003527 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003528 cmdStr = "election-test-withdraw"
3529 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003530 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003531 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003532 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003533 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003534 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003535 if re.search( successPattern, response ):
3536 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003537 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003538 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003539 # error
Jon Hall0e240372018-05-02 11:21:57 -07003540 main.log.error( self.name + ": Error in electionTestWithdraw on " +
Jon Hall97cf84a2016-06-20 13:35:58 -07003541 self.name + ": " + "unexpected response" )
3542 main.log.error( repr( response ) )
3543 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003544 except AssertionError:
3545 main.log.exception( "" )
3546 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003547 except TypeError:
3548 main.log.exception( self.name + ": Object not as expected" )
3549 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003550 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003551 main.log.error( self.name + ": EOF exception found" )
3552 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003553 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003554 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003555 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003556 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003557
kelvin8ec71442015-01-15 16:57:00 -08003558 def getDevicePortsEnabledCount( self, dpid ):
3559 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003560 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003561 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003562 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003563 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003564 cmdStr = "onos:ports -e " + dpid + " | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003565 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003566 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003567 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003568 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003569 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003570 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003571 return output
Jon Hallc6793552016-01-19 14:18:37 -08003572 except AssertionError:
3573 main.log.exception( "" )
3574 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003575 except TypeError:
3576 main.log.exception( self.name + ": Object not as expected" )
3577 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003578 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003579 main.log.error( self.name + ": EOF exception found" )
3580 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003581 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003582 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003583 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003584 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003585
kelvin8ec71442015-01-15 16:57:00 -08003586 def getDeviceLinksActiveCount( self, dpid ):
3587 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003588 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003589 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003590 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003591 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003592 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003593 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003594 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003595 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003596 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003597 main.log.error( self.name + ": Error in getting ports " )
kelvin-onlab898a6c62015-01-16 14:13:53 -08003598 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003599 return output
Jon Hallc6793552016-01-19 14:18:37 -08003600 except AssertionError:
3601 main.log.exception( "" )
3602 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003603 except TypeError:
3604 main.log.exception( self.name + ": Object not as expected" )
3605 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003606 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003607 main.log.error( self.name + ": EOF exception found" )
3608 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003609 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003610 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003611 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003612 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003613
kelvin8ec71442015-01-15 16:57:00 -08003614 def getAllIntentIds( self ):
3615 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003616 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003617 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003618 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003619 cmdStr = "onos:intents | grep id="
3620 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003621 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003622 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003623 if re.search( "Error", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003624 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003625 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003626 return output
Jon Hallc6793552016-01-19 14:18:37 -08003627 except AssertionError:
3628 main.log.exception( "" )
3629 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003630 except TypeError:
3631 main.log.exception( self.name + ": Object not as expected" )
3632 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003633 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003634 main.log.error( self.name + ": EOF exception found" )
3635 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003636 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003637 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003638 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003639 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003640
Jon Hall73509952015-02-24 16:42:56 -08003641 def intentSummary( self ):
3642 """
Jon Hallefbd9792015-03-05 16:11:36 -08003643 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003644 """
3645 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003646 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003647 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003648 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003649 states.append( intent.get( 'state', None ) )
3650 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003651 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003652 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003653 except ( TypeError, ValueError ):
3654 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003655 return None
3656 except pexpect.EOF:
3657 main.log.error( self.name + ": EOF exception found" )
3658 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003659 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003660 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003661 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003662 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003663
Jon Hall61282e32015-03-19 11:34:11 -07003664 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003665 """
3666 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003667 Optional argument:
3668 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003669 """
Jon Hall63604932015-02-26 17:09:50 -08003670 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003671 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003672 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003673 cmdStr += " -j"
3674 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003675 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003676 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003677 return output
Jon Hallc6793552016-01-19 14:18:37 -08003678 except AssertionError:
3679 main.log.exception( "" )
3680 return None
Jon Hall63604932015-02-26 17:09:50 -08003681 except TypeError:
3682 main.log.exception( self.name + ": Object not as expected" )
3683 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003684 except pexpect.EOF:
3685 main.log.error( self.name + ": EOF exception found" )
3686 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003687 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003688 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003689 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003690 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003691
acsmarsa4a4d1e2015-07-10 16:01:24 -07003692 def leaderCandidates( self, jsonFormat=True ):
3693 """
3694 Returns the output of the leaders -c command.
3695 Optional argument:
3696 * jsonFormat - boolean indicating if you want output in json
3697 """
3698 try:
3699 cmdStr = "onos:leaders -c"
3700 if jsonFormat:
3701 cmdStr += " -j"
3702 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003703 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003704 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003705 return output
Jon Hallc6793552016-01-19 14:18:37 -08003706 except AssertionError:
3707 main.log.exception( "" )
3708 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003709 except TypeError:
3710 main.log.exception( self.name + ": Object not as expected" )
3711 return None
3712 except pexpect.EOF:
3713 main.log.error( self.name + ": EOF exception found" )
3714 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003715 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003716 except Exception:
3717 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003718 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003719
Jon Hallc6793552016-01-19 14:18:37 -08003720 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003721 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003722 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003723 topic parameter and an empty list if the topic doesn't exist
3724 If no leader is elected leader in the returned list will be "none"
3725 Returns None if there is a type error processing the json object
3726 """
3727 try:
Jon Hall6e709752016-02-01 13:38:46 -08003728 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003729 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003730 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003731 assert "Command not found:" not in rawOutput, rawOutput
3732 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003733 results = []
3734 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003735 if dict[ "topic" ] == topic:
3736 leader = dict[ "leader" ]
3737 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003738 results.append( leader )
3739 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003740 return results
Jon Hallc6793552016-01-19 14:18:37 -08003741 except AssertionError:
3742 main.log.exception( "" )
3743 return None
3744 except ( TypeError, ValueError ):
3745 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003746 return None
3747 except pexpect.EOF:
3748 main.log.error( self.name + ": EOF exception found" )
3749 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003750 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003751 except Exception:
3752 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003753 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003754
Jon Hall61282e32015-03-19 11:34:11 -07003755 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003756 """
3757 Returns the output of the intent Pending map.
3758 """
Jon Hall63604932015-02-26 17:09:50 -08003759 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003760 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003761 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003762 cmdStr += " -j"
3763 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003764 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003765 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003766 return output
Jon Hallc6793552016-01-19 14:18:37 -08003767 except AssertionError:
3768 main.log.exception( "" )
3769 return None
Jon Hall63604932015-02-26 17:09:50 -08003770 except TypeError:
3771 main.log.exception( self.name + ": Object not as expected" )
3772 return None
3773 except pexpect.EOF:
3774 main.log.error( self.name + ": EOF exception found" )
3775 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003776 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003777 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003778 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003779 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003780
Jon Hall2c8959e2016-12-16 12:17:34 -08003781 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003782 """
3783 Returns the output of the raft partitions command for ONOS.
3784 """
Jon Hall61282e32015-03-19 11:34:11 -07003785 # Sample JSON
3786 # {
3787 # "leader": "tcp://10.128.30.11:7238",
3788 # "members": [
3789 # "tcp://10.128.30.11:7238",
3790 # "tcp://10.128.30.17:7238",
3791 # "tcp://10.128.30.13:7238",
3792 # ],
3793 # "name": "p1",
3794 # "term": 3
3795 # },
Jon Hall63604932015-02-26 17:09:50 -08003796 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003797 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003798 if candidates:
3799 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003800 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003801 cmdStr += " -j"
3802 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003803 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003804 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003805 return output
Jon Hallc6793552016-01-19 14:18:37 -08003806 except AssertionError:
3807 main.log.exception( "" )
3808 return None
Jon Hall63604932015-02-26 17:09:50 -08003809 except TypeError:
3810 main.log.exception( self.name + ": Object not as expected" )
3811 return None
3812 except pexpect.EOF:
3813 main.log.error( self.name + ": EOF exception found" )
3814 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003815 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003816 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003817 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003818 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003819
Jon Halle9f909e2016-09-23 10:43:12 -07003820 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003821 """
3822 Returns the output of the apps command for ONOS. This command lists
3823 information about installed ONOS applications
3824 """
3825 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003826 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003827 # "description":"ONOS OpenFlow protocol southbound providers",
3828 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003829 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003830 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003831 cmdStr = "onos:apps"
Jon Hallf03ae762019-01-22 13:25:27 -08003832 expectJson = False
Jon Halle9f909e2016-09-23 10:43:12 -07003833 if summary:
3834 cmdStr += " -s"
3835 if active:
3836 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003837 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003838 cmdStr += " -j"
Jon Hallf03ae762019-01-22 13:25:27 -08003839 expectJson = True
3840 output = self.sendline( cmdStr, expectJson=expectJson )
Jon Halla495f562016-05-16 18:03:26 -07003841 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003842 assert "Command not found:" not in output, output
3843 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003844 return output
Jon Hallbe379602015-03-24 13:39:32 -07003845 # FIXME: look at specific exceptions/Errors
3846 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07003847 main.log.exception( self.name + ": Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003848 return None
3849 except TypeError:
3850 main.log.exception( self.name + ": Object not as expected" )
3851 return None
3852 except pexpect.EOF:
3853 main.log.error( self.name + ": EOF exception found" )
3854 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003855 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003856 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003857 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003858 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003859
You Wangcdc51fe2018-08-12 17:14:56 -07003860 def appStatus( self, appName ):
Jon Hall146f1522015-03-24 15:33:24 -07003861 """
3862 Uses the onos:apps cli command to return the status of an application.
3863 Returns:
3864 "ACTIVE" - If app is installed and activated
3865 "INSTALLED" - If app is installed and deactivated
3866 "UNINSTALLED" - If app is not installed
3867 None - on error
3868 """
Jon Hall146f1522015-03-24 15:33:24 -07003869 try:
3870 if not isinstance( appName, types.StringType ):
3871 main.log.error( self.name + ".appStatus(): appName must be" +
3872 " a string" )
3873 return None
3874 output = self.apps( jsonFormat=True )
3875 appsJson = json.loads( output )
3876 state = None
3877 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003878 if appName == app.get( 'name' ):
3879 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003880 break
3881 if state == "ACTIVE" or state == "INSTALLED":
3882 return state
3883 elif state is None:
You Wang0d9f2c02018-08-10 14:56:32 -07003884 main.log.warn( "{} app not found".format( appName ) )
Jon Hall146f1522015-03-24 15:33:24 -07003885 return "UNINSTALLED"
3886 elif state:
3887 main.log.error( "Unexpected state from 'onos:apps': " +
3888 str( state ) )
3889 return state
Jon Hallc6793552016-01-19 14:18:37 -08003890 except ( TypeError, ValueError ):
3891 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003892 return None
3893 except pexpect.EOF:
3894 main.log.error( self.name + ": EOF exception found" )
3895 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003896 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003897 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003898 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003899 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003900
Jon Hallbe379602015-03-24 13:39:32 -07003901 def app( self, appName, option ):
3902 """
3903 Interacts with the app command for ONOS. This command manages
3904 application inventory.
3905 """
Jon Hallbe379602015-03-24 13:39:32 -07003906 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003907 # Validate argument types
3908 valid = True
3909 if not isinstance( appName, types.StringType ):
3910 main.log.error( self.name + ".app(): appName must be a " +
3911 "string" )
3912 valid = False
3913 if not isinstance( option, types.StringType ):
3914 main.log.error( self.name + ".app(): option must be a string" )
3915 valid = False
3916 if not valid:
3917 return main.FALSE
3918 # Validate Option
3919 option = option.lower()
3920 # NOTE: Install may become a valid option
3921 if option == "activate":
3922 pass
3923 elif option == "deactivate":
3924 pass
3925 elif option == "uninstall":
3926 pass
3927 else:
3928 # Invalid option
3929 main.log.error( "The ONOS app command argument only takes " +
3930 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003931 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003932 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003933 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003934 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003935 assert output is not None, "Error in sendline"
3936 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003937 if "Error executing command" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003938 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hallbe379602015-03-24 13:39:32 -07003939 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003940 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003941 elif "No such application" in output:
3942 main.log.error( "The application '" + appName +
3943 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003944 return main.FALSE
3945 elif "Command not found:" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003946 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hall146f1522015-03-24 15:33:24 -07003947 str( output ) )
3948 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003949 elif "Unsupported command:" in output:
3950 main.log.error( "Incorrect command given to 'app': " +
3951 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003952 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003953 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003954 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003955 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003956 except AssertionError:
3957 main.log.exception( self.name + ": AssertionError exception found" )
3958 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003959 except TypeError:
3960 main.log.exception( self.name + ": Object not as expected" )
3961 return main.ERROR
3962 except pexpect.EOF:
3963 main.log.error( self.name + ": EOF exception found" )
3964 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003965 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003966 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003967 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003968 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003969
Jon Hallbd16b922015-03-26 17:53:15 -07003970 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003971 """
3972 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003973 appName is the hierarchical app name, not the feature name
3974 If check is True, method will check the status of the app after the
3975 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003976 Returns main.TRUE if the command was successfully sent
3977 main.FALSE if the cli responded with an error or given
3978 incorrect input
3979 """
3980 try:
3981 if not isinstance( appName, types.StringType ):
3982 main.log.error( self.name + ".activateApp(): appName must be" +
3983 " a string" )
3984 return main.FALSE
3985 status = self.appStatus( appName )
3986 if status == "INSTALLED":
3987 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003988 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003989 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003990 status = self.appStatus( appName )
3991 if status == "ACTIVE":
3992 return main.TRUE
3993 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003994 main.log.debug( "The state of application " +
3995 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003996 time.sleep( 1 )
3997 return main.FALSE
3998 else: # not 'check' or command didn't succeed
3999 return response
Jon Hall146f1522015-03-24 15:33:24 -07004000 elif status == "ACTIVE":
4001 return main.TRUE
4002 elif status == "UNINSTALLED":
4003 main.log.error( self.name + ": Tried to activate the " +
4004 "application '" + appName + "' which is not " +
4005 "installed." )
4006 else:
4007 main.log.error( "Unexpected return value from appStatus: " +
4008 str( status ) )
4009 return main.ERROR
4010 except TypeError:
4011 main.log.exception( self.name + ": Object not as expected" )
4012 return main.ERROR
4013 except pexpect.EOF:
4014 main.log.error( self.name + ": EOF exception found" )
4015 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004016 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004017 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004018 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004019 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07004020
Jon Hallbd16b922015-03-26 17:53:15 -07004021 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07004022 """
4023 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07004024 appName is the hierarchical app name, not the feature name
4025 If check is True, method will check the status of the app after the
4026 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07004027 Returns main.TRUE if the command was successfully sent
4028 main.FALSE if the cli responded with an error or given
4029 incorrect input
4030 """
4031 try:
4032 if not isinstance( appName, types.StringType ):
4033 main.log.error( self.name + ".deactivateApp(): appName must " +
4034 "be a string" )
4035 return main.FALSE
4036 status = self.appStatus( appName )
4037 if status == "INSTALLED":
4038 return main.TRUE
4039 elif status == "ACTIVE":
4040 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07004041 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004042 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004043 status = self.appStatus( appName )
4044 if status == "INSTALLED":
4045 return main.TRUE
4046 else:
4047 time.sleep( 1 )
4048 return main.FALSE
4049 else: # not check or command didn't succeed
4050 return response
Jon Hall146f1522015-03-24 15:33:24 -07004051 elif status == "UNINSTALLED":
4052 main.log.warn( self.name + ": Tried to deactivate the " +
4053 "application '" + appName + "' which is not " +
4054 "installed." )
4055 return main.TRUE
4056 else:
4057 main.log.error( "Unexpected return value from appStatus: " +
4058 str( status ) )
4059 return main.ERROR
4060 except TypeError:
4061 main.log.exception( self.name + ": Object not as expected" )
4062 return main.ERROR
4063 except pexpect.EOF:
4064 main.log.error( self.name + ": EOF exception found" )
4065 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004066 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004067 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004068 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004069 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07004070
Jon Hallbd16b922015-03-26 17:53:15 -07004071 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07004072 """
4073 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07004074 appName is the hierarchical app name, not the feature name
4075 If check is True, method will check the status of the app after the
4076 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07004077 Returns main.TRUE if the command was successfully sent
4078 main.FALSE if the cli responded with an error or given
4079 incorrect input
4080 """
4081 # TODO: check with Thomas about the state machine for apps
4082 try:
4083 if not isinstance( appName, types.StringType ):
4084 main.log.error( self.name + ".uninstallApp(): appName must " +
4085 "be a string" )
4086 return main.FALSE
4087 status = self.appStatus( appName )
4088 if status == "INSTALLED":
4089 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004090 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004091 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004092 status = self.appStatus( appName )
4093 if status == "UNINSTALLED":
4094 return main.TRUE
4095 else:
4096 time.sleep( 1 )
4097 return main.FALSE
4098 else: # not check or command didn't succeed
4099 return response
Jon Hall146f1522015-03-24 15:33:24 -07004100 elif status == "ACTIVE":
4101 main.log.warn( self.name + ": Tried to uninstall the " +
4102 "application '" + appName + "' which is " +
4103 "currently active." )
4104 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004105 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004106 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004107 status = self.appStatus( appName )
4108 if status == "UNINSTALLED":
4109 return main.TRUE
4110 else:
4111 time.sleep( 1 )
4112 return main.FALSE
4113 else: # not check or command didn't succeed
4114 return response
Jon Hall146f1522015-03-24 15:33:24 -07004115 elif status == "UNINSTALLED":
4116 return main.TRUE
4117 else:
4118 main.log.error( "Unexpected return value from appStatus: " +
4119 str( status ) )
4120 return main.ERROR
4121 except TypeError:
4122 main.log.exception( self.name + ": Object not as expected" )
4123 return main.ERROR
4124 except pexpect.EOF:
4125 main.log.error( self.name + ": EOF exception found" )
4126 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004127 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004128 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004129 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004130 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004131
4132 def appIDs( self, jsonFormat=True ):
4133 """
4134 Show the mappings between app id and app names given by the 'app-ids'
4135 cli command
4136 """
4137 try:
4138 cmdStr = "app-ids"
4139 if jsonFormat:
4140 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07004141 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004142 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004143 assert "Command not found:" not in output, output
4144 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07004145 return output
Jon Hallbd16b922015-03-26 17:53:15 -07004146 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004147 main.log.exception( self.name + ": Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07004148 return None
4149 except TypeError:
4150 main.log.exception( self.name + ": Object not as expected" )
4151 return None
4152 except pexpect.EOF:
4153 main.log.error( self.name + ": EOF exception found" )
4154 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004155 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004156 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004157 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004158 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004159
4160 def appToIDCheck( self ):
4161 """
4162 This method will check that each application's ID listed in 'apps' is
4163 the same as the ID listed in 'app-ids'. The check will also check that
4164 there are no duplicate IDs issued. Note that an app ID should be
4165 a globaly unique numerical identifier for app/app-like features. Once
4166 an ID is registered, the ID is never freed up so that if an app is
4167 reinstalled it will have the same ID.
4168
4169 Returns: main.TRUE if the check passes and
4170 main.FALSE if the check fails or
4171 main.ERROR if there is some error in processing the test
4172 """
4173 try:
Jon Hall0e240372018-05-02 11:21:57 -07004174 # Grab IDs
Jon Hallc6793552016-01-19 14:18:37 -08004175 rawJson = self.appIDs( jsonFormat=True )
4176 if rawJson:
4177 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004178 else:
Jon Hall0e240372018-05-02 11:21:57 -07004179 main.log.error( "app-ids returned nothing: " + repr( rawJson ) )
4180 return main.FALSE
4181
4182 # Grab Apps
Jon Hallc6793552016-01-19 14:18:37 -08004183 rawJson = self.apps( jsonFormat=True )
4184 if rawJson:
4185 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004186 else:
Jon Hallc6793552016-01-19 14:18:37 -08004187 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004188 return main.FALSE
Jon Hall0e240372018-05-02 11:21:57 -07004189
Jon Hallbd16b922015-03-26 17:53:15 -07004190 result = main.TRUE
4191 for app in apps:
4192 appID = app.get( 'id' )
4193 if appID is None:
4194 main.log.error( "Error parsing app: " + str( app ) )
4195 result = main.FALSE
4196 appName = app.get( 'name' )
4197 if appName is None:
4198 main.log.error( "Error parsing app: " + str( app ) )
4199 result = main.FALSE
4200 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004201 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004202 if not current: # if ids doesn't have this id
4203 result = main.FALSE
4204 main.log.error( "'app-ids' does not have the ID for " +
4205 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004206 main.log.debug( "apps command returned: " + str( app ) +
4207 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004208 elif len( current ) > 1:
4209 # there is more than one app with this ID
4210 result = main.FALSE
4211 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004212 elif not current[ 0 ][ 'name' ] == appName:
4213 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004214 result = main.FALSE
4215 main.log.error( "'app-ids' has " + str( currentName ) +
4216 " registered under id:" + str( appID ) +
4217 " but 'apps' has " + str( appName ) )
4218 else:
4219 pass # id and name match!
Jon Hall0e240372018-05-02 11:21:57 -07004220
Jon Hallbd16b922015-03-26 17:53:15 -07004221 # now make sure that app-ids has no duplicates
4222 idsList = []
4223 namesList = []
4224 for item in ids:
4225 idsList.append( item[ 'id' ] )
4226 namesList.append( item[ 'name' ] )
4227 if len( idsList ) != len( set( idsList ) ) or\
4228 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004229 main.log.error( "'app-ids' has some duplicate entries: \n"
4230 + json.dumps( ids,
4231 sort_keys=True,
4232 indent=4,
4233 separators=( ',', ': ' ) ) )
4234 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004235 return result
Jon Hallc6793552016-01-19 14:18:37 -08004236 except ( TypeError, ValueError ):
4237 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004238 return main.ERROR
4239 except pexpect.EOF:
4240 main.log.error( self.name + ": EOF exception found" )
4241 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004242 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004243 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004244 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004245 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004246
Jon Hallfb760a02015-04-13 15:35:03 -07004247 def getCfg( self, component=None, propName=None, short=False,
4248 jsonFormat=True ):
4249 """
4250 Get configuration settings from onos cli
4251 Optional arguments:
4252 component - Optionally only list configurations for a specific
4253 component. If None, all components with configurations
4254 are displayed. Case Sensitive string.
4255 propName - If component is specified, propName option will show
4256 only this specific configuration from that component.
4257 Case Sensitive string.
4258 jsonFormat - Returns output as json. Note that this will override
4259 the short option
4260 short - Short, less verbose, version of configurations.
4261 This is overridden by the json option
4262 returns:
4263 Output from cli as a string or None on error
4264 """
4265 try:
4266 baseStr = "cfg"
4267 cmdStr = " get"
4268 componentStr = ""
4269 if component:
4270 componentStr += " " + component
4271 if propName:
4272 componentStr += " " + propName
4273 if jsonFormat:
4274 baseStr += " -j"
Jon Hall22e94ce2019-01-15 14:52:17 -08004275 expectJson = True
Jon Hallfb760a02015-04-13 15:35:03 -07004276 elif short:
4277 baseStr += " -s"
Jon Hall22e94ce2019-01-15 14:52:17 -08004278 expectJson = False
4279 output = self.sendline( baseStr + cmdStr + componentStr, expectJson=expectJson )
Jon Halla495f562016-05-16 18:03:26 -07004280 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004281 assert "Command not found:" not in output, output
4282 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004283 return output
4284 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004285 main.log.exception( self.name + ": Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004286 return None
4287 except TypeError:
4288 main.log.exception( self.name + ": Object not as expected" )
4289 return None
4290 except pexpect.EOF:
4291 main.log.error( self.name + ": EOF exception found" )
4292 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004293 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004294 except Exception:
4295 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004296 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004297
4298 def setCfg( self, component, propName, value=None, check=True ):
4299 """
4300 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004301 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004302 component - The case sensitive name of the component whose
4303 property is to be set
4304 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004305 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004306 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004307 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004308 check - Boolean, Check whether the option was successfully set this
4309 only applies when a value is given.
4310 returns:
4311 main.TRUE on success or main.FALSE on failure. If check is False,
4312 will return main.TRUE unless there is an error
4313 """
4314 try:
4315 baseStr = "cfg"
4316 cmdStr = " set " + str( component ) + " " + str( propName )
4317 if value is not None:
4318 cmdStr += " " + str( value )
4319 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004320 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004321 assert "Command not found:" not in output, output
4322 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004323 if value and check:
4324 results = self.getCfg( component=str( component ),
4325 propName=str( propName ),
4326 jsonFormat=True )
4327 # Check if current value is what we just set
4328 try:
4329 jsonOutput = json.loads( results )
4330 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004331 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004332 main.log.exception( "Error parsing cfg output" )
4333 main.log.error( "output:" + repr( results ) )
4334 return main.FALSE
4335 if current == str( value ):
4336 return main.TRUE
4337 return main.FALSE
4338 return main.TRUE
4339 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004340 main.log.exception( self.name + ": Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004341 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004342 except ( TypeError, ValueError ):
4343 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004344 return main.FALSE
4345 except pexpect.EOF:
4346 main.log.error( self.name + ": EOF exception found" )
4347 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004348 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004349 except Exception:
4350 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004351 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004352
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004353 def distPrimitivesSend( self, cmd ):
4354 """
4355 Function to handle sending cli commands for the distributed primitives test app
4356
4357 This command will catch some exceptions and retry the command on some
4358 specific store exceptions.
4359
4360 Required arguments:
4361 cmd - The command to send to the cli
4362 returns:
4363 string containing the cli output
4364 None on Error
4365 """
4366 try:
4367 output = self.sendline( cmd )
4368 try:
4369 assert output is not None, "Error in sendline"
4370 # TODO: Maybe make this less hardcoded
4371 # ConsistentMap Exceptions
4372 assert "org.onosproject.store.service" not in output
4373 # Node not leader
4374 assert "java.lang.IllegalStateException" not in output
4375 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004376 main.log.error( self.name + ": Error in processing '" + cmd + "' " +
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004377 "command: " + str( output ) )
4378 retryTime = 30 # Conservative time, given by Madan
4379 main.log.info( "Waiting " + str( retryTime ) +
4380 "seconds before retrying." )
4381 time.sleep( retryTime ) # Due to change in mastership
4382 output = self.sendline( cmd )
4383 assert output is not None, "Error in sendline"
4384 assert "Command not found:" not in output, output
4385 assert "Error executing command" not in output, output
4386 main.log.info( self.name + ": " + output )
4387 return output
4388 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004389 main.log.exception( self.name + ": Error in processing '" + cmd + "' command." )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004390 return None
4391 except TypeError:
4392 main.log.exception( self.name + ": Object not as expected" )
4393 return None
4394 except pexpect.EOF:
4395 main.log.error( self.name + ": EOF exception found" )
4396 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004397 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004398 except Exception:
4399 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004400 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004401
Jon Hall390696c2015-05-05 17:13:41 -07004402 def setTestAdd( self, setName, values ):
4403 """
4404 CLI command to add elements to a distributed set.
4405 Arguments:
4406 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004407 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004408 Example usages:
4409 setTestAdd( "set1", "a b c" )
4410 setTestAdd( "set2", "1" )
4411 returns:
4412 main.TRUE on success OR
4413 main.FALSE if elements were already in the set OR
4414 main.ERROR on error
4415 """
4416 try:
4417 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004418 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004419 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4420 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004421 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004422 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004423 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004424 return main.FALSE
4425 else:
4426 main.log.error( self.name + ": setTestAdd did not" +
4427 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004428 main.log.debug( self.name + " actual: " + repr( output ) )
4429 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004430 except TypeError:
4431 main.log.exception( self.name + ": Object not as expected" )
4432 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004433 except Exception:
4434 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004435 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004436
4437 def setTestRemove( self, setName, values, clear=False, retain=False ):
4438 """
4439 CLI command to remove elements from a distributed set.
4440 Required arguments:
4441 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004442 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004443 Optional arguments:
4444 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004445 retain - Retain only the given values. (intersection of the
4446 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004447 returns:
4448 main.TRUE on success OR
4449 main.FALSE if the set was not changed OR
4450 main.ERROR on error
4451 """
4452 try:
4453 cmdStr = "set-test-remove "
4454 if clear:
4455 cmdStr += "-c " + str( setName )
4456 elif retain:
4457 cmdStr += "-r " + str( setName ) + " " + str( values )
4458 else:
4459 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004460 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004461 if clear:
4462 pattern = "Set " + str( setName ) + " cleared"
4463 if re.search( pattern, output ):
4464 return main.TRUE
4465 elif retain:
4466 positivePattern = str( setName ) + " was pruned to contain " +\
4467 "only elements of set \[(.*)\]"
4468 negativePattern = str( setName ) + " was not changed by " +\
4469 "retaining only elements of the set " +\
4470 "\[(.*)\]"
4471 if re.search( positivePattern, output ):
4472 return main.TRUE
4473 elif re.search( negativePattern, output ):
4474 return main.FALSE
4475 else:
4476 positivePattern = "\[(.*)\] was removed from the set " +\
4477 str( setName )
4478 if ( len( values.split() ) == 1 ):
4479 negativePattern = "\[(.*)\] was not in set " +\
4480 str( setName )
4481 else:
4482 negativePattern = "No element of \[(.*)\] was in set " +\
4483 str( setName )
4484 if re.search( positivePattern, output ):
4485 return main.TRUE
4486 elif re.search( negativePattern, output ):
4487 return main.FALSE
4488 main.log.error( self.name + ": setTestRemove did not" +
4489 " match expected output" )
4490 main.log.debug( self.name + " expected: " + pattern )
4491 main.log.debug( self.name + " actual: " + repr( output ) )
4492 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004493 except TypeError:
4494 main.log.exception( self.name + ": Object not as expected" )
4495 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004496 except Exception:
4497 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004498 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004499
4500 def setTestGet( self, setName, values="" ):
4501 """
4502 CLI command to get the elements in a distributed set.
4503 Required arguments:
4504 setName - The name of the set to remove from.
4505 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004506 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004507 returns:
4508 main.ERROR on error OR
4509 A list of elements in the set if no optional arguments are
4510 supplied OR
4511 A tuple containing the list then:
4512 main.FALSE if the given values are not in the set OR
4513 main.TRUE if the given values are in the set OR
4514 """
4515 try:
4516 values = str( values ).strip()
4517 setName = str( setName ).strip()
4518 length = len( values.split() )
4519 containsCheck = None
4520 # Patterns to match
4521 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004522 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004523 containsTrue = "Set " + setName + " contains the value " + values
4524 containsFalse = "Set " + setName + " did not contain the value " +\
4525 values
4526 containsAllTrue = "Set " + setName + " contains the the subset " +\
4527 setPattern
4528 containsAllFalse = "Set " + setName + " did not contain the the" +\
4529 " subset " + setPattern
4530
4531 cmdStr = "set-test-get "
4532 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004533 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004534 if length == 0:
4535 match = re.search( pattern, output )
4536 else: # if given values
4537 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004538 patternTrue = pattern + "\r\n" + containsTrue
4539 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004540 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004541 patternTrue = pattern + "\r\n" + containsAllTrue
4542 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004543 matchTrue = re.search( patternTrue, output )
4544 matchFalse = re.search( patternFalse, output )
4545 if matchTrue:
4546 containsCheck = main.TRUE
4547 match = matchTrue
4548 elif matchFalse:
4549 containsCheck = main.FALSE
4550 match = matchFalse
4551 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004552 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004553 "expected output" )
4554 main.log.debug( self.name + " expected: " + pattern )
4555 main.log.debug( self.name + " actual: " + repr( output ) )
4556 match = None
4557 if match:
4558 setMatch = match.group( 1 )
4559 if setMatch == '':
4560 setList = []
4561 else:
4562 setList = setMatch.split( ", " )
4563 if length > 0:
4564 return ( setList, containsCheck )
4565 else:
4566 return setList
4567 else: # no match
4568 main.log.error( self.name + ": setTestGet did not" +
4569 " match expected output" )
4570 main.log.debug( self.name + " expected: " + pattern )
4571 main.log.debug( self.name + " actual: " + repr( output ) )
4572 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004573 except TypeError:
4574 main.log.exception( self.name + ": Object not as expected" )
4575 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004576 except Exception:
4577 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004578 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004579
4580 def setTestSize( self, setName ):
4581 """
4582 CLI command to get the elements in a distributed set.
4583 Required arguments:
4584 setName - The name of the set to remove from.
4585 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004586 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004587 None on error
4588 """
4589 try:
4590 # TODO: Should this check against the number of elements returned
4591 # and then return true/false based on that?
4592 setName = str( setName ).strip()
4593 # Patterns to match
4594 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004595 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004596 setPattern
4597 cmdStr = "set-test-get -s "
4598 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004599 output = self.distPrimitivesSend( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -07004600 if output:
4601 match = re.search( pattern, output )
4602 if match:
4603 setSize = int( match.group( 1 ) )
4604 setMatch = match.group( 2 )
4605 if len( setMatch.split() ) == setSize:
4606 main.log.info( "The size returned by " + self.name +
4607 " matches the number of elements in " +
4608 "the returned set" )
4609 else:
4610 main.log.error( "The size returned by " + self.name +
4611 " does not match the number of " +
4612 "elements in the returned set." )
4613 return setSize
Jon Hall390696c2015-05-05 17:13:41 -07004614 else: # no match
4615 main.log.error( self.name + ": setTestGet did not" +
4616 " match expected output" )
4617 main.log.debug( self.name + " expected: " + pattern )
4618 main.log.debug( self.name + " actual: " + repr( output ) )
4619 return None
Jon Hall390696c2015-05-05 17:13:41 -07004620 except TypeError:
4621 main.log.exception( self.name + ": Object not as expected" )
4622 return None
Jon Hall390696c2015-05-05 17:13:41 -07004623 except Exception:
4624 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004625 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004626
Jon Hall80daded2015-05-27 16:07:00 -07004627 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004628 """
4629 Command to list the various counters in the system.
4630 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004631 if jsonFormat, a string of the json object returned by the cli
4632 command
4633 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004634 None on error
4635 """
Jon Hall390696c2015-05-05 17:13:41 -07004636 try:
Jon Hall390696c2015-05-05 17:13:41 -07004637 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004638 if jsonFormat:
4639 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004640 output = self.sendline( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08004641 main.log.debug( self.name + ": Counters unparsed: " + output )
4642 output = output.split( "\r\n" )[ -1 ]
4643 main.log.debug( self.name + ": Counters parsed: " + output )
Jon Halla495f562016-05-16 18:03:26 -07004644 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004645 assert "Command not found:" not in output, output
4646 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004647 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004648 return output
Jon Hall390696c2015-05-05 17:13:41 -07004649 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004650 main.log.exception( self.name + ": Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004651 return None
Jon Hall390696c2015-05-05 17:13:41 -07004652 except TypeError:
4653 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004654 return None
Jon Hall390696c2015-05-05 17:13:41 -07004655 except pexpect.EOF:
4656 main.log.error( self.name + ": EOF exception found" )
4657 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004658 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004659 except Exception:
4660 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004661 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004662
Jon Hall935db192016-04-19 00:22:04 -07004663 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004664 """
Jon Halle1a3b752015-07-22 13:02:46 -07004665 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004666 Required arguments:
4667 counter - The name of the counter to increment.
4668 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004669 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004670 returns:
4671 integer value of the counter or
4672 None on Error
4673 """
4674 try:
4675 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004676 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004677 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004678 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004679 if delta != 1:
4680 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004681 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004682 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004683 match = re.search( pattern, output )
4684 if match:
4685 return int( match.group( 1 ) )
4686 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004687 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004688 " match expected output." )
4689 main.log.debug( self.name + " expected: " + pattern )
4690 main.log.debug( self.name + " actual: " + repr( output ) )
4691 return None
Jon Hall390696c2015-05-05 17:13:41 -07004692 except TypeError:
4693 main.log.exception( self.name + ": Object not as expected" )
4694 return None
Jon Hall390696c2015-05-05 17:13:41 -07004695 except Exception:
4696 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004697 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004698
Jon Hall935db192016-04-19 00:22:04 -07004699 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004700 """
4701 CLI command to get a distributed counter then add a delta to it.
4702 Required arguments:
4703 counter - The name of the counter to increment.
4704 Optional arguments:
4705 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004706 returns:
4707 integer value of the counter or
4708 None on Error
4709 """
4710 try:
4711 counter = str( counter )
4712 delta = int( delta )
4713 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004714 cmdStr += counter
4715 if delta != 1:
4716 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004717 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004718 pattern = counter + " was updated to (-?\d+)"
4719 match = re.search( pattern, output )
4720 if match:
4721 return int( match.group( 1 ) )
4722 else:
4723 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4724 " match expected output." )
4725 main.log.debug( self.name + " expected: " + pattern )
4726 main.log.debug( self.name + " actual: " + repr( output ) )
4727 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004728 except TypeError:
4729 main.log.exception( self.name + ": Object not as expected" )
4730 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004731 except Exception:
4732 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004733 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004734
4735 def valueTestGet( self, valueName ):
4736 """
4737 CLI command to get the value of an atomic value.
4738 Required arguments:
4739 valueName - The name of the value to get.
4740 returns:
4741 string value of the value or
4742 None on Error
4743 """
4744 try:
4745 valueName = str( valueName )
4746 cmdStr = "value-test "
4747 operation = "get"
4748 cmdStr = "value-test {} {}".format( valueName,
4749 operation )
4750 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08004751 main.log.debug( self.name + ": value test unparsed: " + output )
4752 output = output.split( "\r\n" )[ -1 ]
4753 main.log.debug( self.name + ": value test parsed: " + output )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004754 pattern = "(\w+)"
4755 match = re.search( pattern, output )
4756 if match:
4757 return match.group( 1 )
4758 else:
4759 main.log.error( self.name + ": valueTestGet did not" +
4760 " match expected output." )
4761 main.log.debug( self.name + " expected: " + pattern )
4762 main.log.debug( self.name + " actual: " + repr( output ) )
4763 return None
4764 except TypeError:
4765 main.log.exception( self.name + ": Object not as expected" )
4766 return None
4767 except Exception:
4768 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004769 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004770
4771 def valueTestSet( self, valueName, newValue ):
4772 """
4773 CLI command to set the value of an atomic value.
4774 Required arguments:
4775 valueName - The name of the value to set.
4776 newValue - The value to assign to the given value.
4777 returns:
4778 main.TRUE on success or
4779 main.ERROR on Error
4780 """
4781 try:
4782 valueName = str( valueName )
4783 newValue = str( newValue )
4784 operation = "set"
4785 cmdStr = "value-test {} {} {}".format( valueName,
4786 operation,
4787 newValue )
4788 output = self.distPrimitivesSend( cmdStr )
4789 if output is not None:
4790 return main.TRUE
4791 else:
4792 return main.ERROR
4793 except TypeError:
4794 main.log.exception( self.name + ": Object not as expected" )
4795 return main.ERROR
4796 except Exception:
4797 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004798 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004799
4800 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4801 """
4802 CLI command to compareAndSet the value of an atomic value.
4803 Required arguments:
4804 valueName - The name of the value.
4805 oldValue - Compare the current value of the atomic value to this
4806 newValue - If the value equals oldValue, set the value to newValue
4807 returns:
4808 main.TRUE on success or
4809 main.FALSE on failure or
4810 main.ERROR on Error
4811 """
4812 try:
4813 valueName = str( valueName )
4814 oldValue = str( oldValue )
4815 newValue = str( newValue )
4816 operation = "compareAndSet"
4817 cmdStr = "value-test {} {} {} {}".format( valueName,
4818 operation,
4819 oldValue,
4820 newValue )
4821 output = self.distPrimitivesSend( cmdStr )
4822 pattern = "(\w+)"
4823 match = re.search( pattern, output )
4824 if match:
4825 result = match.group( 1 )
4826 if result == "true":
4827 return main.TRUE
4828 elif result == "false":
4829 return main.FALSE
4830 else:
4831 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4832 " match expected output." )
4833 main.log.debug( self.name + " expected: " + pattern )
4834 main.log.debug( self.name + " actual: " + repr( output ) )
4835 return main.ERROR
4836 except TypeError:
4837 main.log.exception( self.name + ": Object not as expected" )
4838 return main.ERROR
4839 except Exception:
4840 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004841 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004842
4843 def valueTestGetAndSet( self, valueName, newValue ):
4844 """
4845 CLI command to getAndSet the value of an atomic value.
4846 Required arguments:
4847 valueName - The name of the value to get.
4848 newValue - The value to assign to the given value
4849 returns:
4850 string value of the value or
4851 None on Error
4852 """
4853 try:
4854 valueName = str( valueName )
4855 cmdStr = "value-test "
4856 operation = "getAndSet"
4857 cmdStr += valueName + " " + operation
4858 cmdStr = "value-test {} {} {}".format( valueName,
4859 operation,
4860 newValue )
4861 output = self.distPrimitivesSend( cmdStr )
4862 pattern = "(\w+)"
4863 match = re.search( pattern, output )
4864 if match:
4865 return match.group( 1 )
4866 else:
4867 main.log.error( self.name + ": valueTestGetAndSet did not" +
4868 " match expected output." )
4869 main.log.debug( self.name + " expected: " + pattern )
4870 main.log.debug( self.name + " actual: " + repr( output ) )
4871 return None
4872 except TypeError:
4873 main.log.exception( self.name + ": Object not as expected" )
4874 return None
4875 except Exception:
4876 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004877 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004878
4879 def valueTestDestroy( self, valueName ):
4880 """
4881 CLI command to destroy an atomic value.
4882 Required arguments:
4883 valueName - The name of the value to destroy.
4884 returns:
4885 main.TRUE on success or
4886 main.ERROR on Error
4887 """
4888 try:
4889 valueName = str( valueName )
4890 cmdStr = "value-test "
4891 operation = "destroy"
4892 cmdStr += valueName + " " + operation
4893 output = self.distPrimitivesSend( cmdStr )
4894 if output is not None:
4895 return main.TRUE
4896 else:
4897 return main.ERROR
4898 except TypeError:
4899 main.log.exception( self.name + ": Object not as expected" )
4900 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004901 except Exception:
4902 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004903 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004904
YPZhangfebf7302016-05-24 16:45:56 -07004905 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004906 """
4907 Description: Execute summary command in onos
4908 Returns: json object ( summary -j ), returns main.FALSE if there is
4909 no output
4910
4911 """
4912 try:
4913 cmdStr = "summary"
4914 if jsonFormat:
4915 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004916 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004917 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004918 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004919 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004920 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004921 if not handle:
4922 main.log.error( self.name + ": There is no output in " +
4923 "summary command" )
4924 return main.FALSE
4925 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004926 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004927 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004928 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004929 except TypeError:
4930 main.log.exception( self.name + ": Object not as expected" )
4931 return None
4932 except pexpect.EOF:
4933 main.log.error( self.name + ": EOF exception found" )
4934 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004935 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004936 except Exception:
4937 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004938 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004939
Jon Hall06fd0df2021-01-25 15:50:06 -08004940 def getAddress( self):
4941 """
4942 Get the onos ip address from the cli. This is usefull when connecting using
4943 a container manager such as kubernetes. This function also sets self.address
4944 the value from ONOS.
4945
4946 Returns:
4947 The string value of the key or
4948 None on Error
4949 """
4950 try:
4951 output = self.summary()
4952 address = json.loads( output ).get( 'node' )
4953 self.address = address
4954 return address
4955 except TypeError:
4956 main.log.exception( self.name + ": Object not as expected" )
4957 return None
4958 except Exception:
4959 main.log.exception( self.name + ": Uncaught exception!" )
4960 main.cleanAndExit()
4961
Jon Hall935db192016-04-19 00:22:04 -07004962 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004963 """
4964 CLI command to get the value of a key in a consistent map using
4965 transactions. This a test function and can only get keys from the
4966 test map hard coded into the cli command
4967 Required arguments:
4968 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004969 returns:
4970 The string value of the key or
4971 None on Error
4972 """
4973 try:
4974 keyName = str( keyName )
4975 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004976 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004977 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004978 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4979 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004980 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004981 return None
4982 else:
4983 match = re.search( pattern, output )
4984 if match:
4985 return match.groupdict()[ 'value' ]
4986 else:
4987 main.log.error( self.name + ": transactionlMapGet did not" +
4988 " match expected output." )
4989 main.log.debug( self.name + " expected: " + pattern )
4990 main.log.debug( self.name + " actual: " + repr( output ) )
4991 return None
4992 except TypeError:
4993 main.log.exception( self.name + ": Object not as expected" )
4994 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004995 except Exception:
4996 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004997 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004998
Jon Hall935db192016-04-19 00:22:04 -07004999 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07005000 """
5001 CLI command to put a value into 'numKeys' number of keys in a
5002 consistent map using transactions. This a test function and can only
5003 put into keys named 'Key#' of the test map hard coded into the cli command
5004 Required arguments:
5005 numKeys - Number of keys to add the value to
5006 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07005007 returns:
5008 A dictionary whose keys are the name of the keys put into the map
5009 and the values of the keys are dictionaries whose key-values are
5010 'value': value put into map and optionaly
5011 'oldValue': Previous value in the key or
5012 None on Error
5013
5014 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005015 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
5016 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07005017 """
5018 try:
5019 numKeys = str( numKeys )
5020 value = str( value )
5021 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07005022 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07005023 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07005024 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
5025 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
5026 results = {}
5027 for line in output.splitlines():
5028 new = re.search( newPattern, line )
5029 updated = re.search( updatedPattern, line )
5030 if new:
5031 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
5032 elif updated:
5033 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08005034 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07005035 else:
5036 main.log.error( self.name + ": transactionlMapGet did not" +
5037 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08005038 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
5039 newPattern,
5040 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07005041 main.log.debug( self.name + " actual: " + repr( output ) )
5042 return results
Jon Hall0e240372018-05-02 11:21:57 -07005043 except ( TypeError, AttributeError ):
Jon Hall2a5002c2015-08-21 16:49:11 -07005044 main.log.exception( self.name + ": Object not as expected" )
5045 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07005046 except Exception:
5047 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005048 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08005049
acsmarsdaea66c2015-09-03 11:44:06 -07005050 def maps( self, jsonFormat=True ):
5051 """
5052 Description: Returns result of onos:maps
5053 Optional:
5054 * jsonFormat: enable json formatting of output
5055 """
5056 try:
5057 cmdStr = "maps"
5058 if jsonFormat:
5059 cmdStr += " -j"
5060 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07005061 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005062 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07005063 return handle
Jon Hallc6793552016-01-19 14:18:37 -08005064 except AssertionError:
5065 main.log.exception( "" )
5066 return None
acsmarsdaea66c2015-09-03 11:44:06 -07005067 except TypeError:
5068 main.log.exception( self.name + ": Object not as expected" )
5069 return None
5070 except pexpect.EOF:
5071 main.log.error( self.name + ": EOF exception found" )
5072 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005073 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07005074 except Exception:
5075 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005076 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005077
5078 def getSwController( self, uri, jsonFormat=True ):
5079 """
5080 Descrition: Gets the controller information from the device
5081 """
5082 try:
5083 cmd = "device-controllers "
5084 if jsonFormat:
5085 cmd += "-j "
5086 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07005087 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005088 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005089 return response
Jon Hallc6793552016-01-19 14:18:37 -08005090 except AssertionError:
5091 main.log.exception( "" )
5092 return None
GlennRC050596c2015-11-18 17:06:41 -08005093 except TypeError:
5094 main.log.exception( self.name + ": Object not as expected" )
5095 return None
5096 except pexpect.EOF:
5097 main.log.error( self.name + ": EOF exception found" )
5098 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005099 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005100 except Exception:
5101 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005102 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005103
5104 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
5105 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005106 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08005107
5108 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005109 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08005110 ip - String or List: The ip address of the controller.
5111 This parameter can be formed in a couple of different ways.
5112 VALID:
5113 10.0.0.1 - just the ip address
5114 tcp:10.0.0.1 - the protocol and the ip address
5115 tcp:10.0.0.1:6653 - the protocol and port can be specified,
5116 so that you can add controllers with different
5117 protocols and ports
5118 INVALID:
5119 10.0.0.1:6653 - this is not supported by ONOS
5120
5121 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
5122 port - The port number.
5123 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
5124
5125 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
5126 """
5127 try:
5128 cmd = "device-setcontrollers"
5129
5130 if jsonFormat:
5131 cmd += " -j"
5132 cmd += " " + uri
5133 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005134 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08005135 for item in ip:
5136 if ":" in item:
5137 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005138 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08005139 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005140 elif "." in sitem[ 1 ]:
5141 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08005142 else:
5143 main.log.error( "Malformed entry: " + item )
5144 raise TypeError
5145 else:
5146 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08005147 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07005148 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005149 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005150 if "Error" in response:
5151 main.log.error( response )
5152 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005153 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005154 except AssertionError:
5155 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005156 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005157 except TypeError:
5158 main.log.exception( self.name + ": Object not as expected" )
5159 return main.FALSE
5160 except pexpect.EOF:
5161 main.log.error( self.name + ": EOF exception found" )
5162 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005163 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005164 except Exception:
5165 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005166 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005167
5168 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005169 '''
GlennRC20fc6522015-12-23 23:26:57 -08005170 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005171 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08005172 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005173 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08005174 Returns:
5175 Returns main.FALSE if an exception is thrown or an error is present
5176 in the response. Otherwise, returns main.TRUE.
5177 NOTE:
5178 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005179 '''
GlennRC20fc6522015-12-23 23:26:57 -08005180 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005181 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07005182 deviceStr = device
5183 device = []
5184 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08005185
5186 for d in device:
5187 time.sleep( 1 )
5188 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07005189 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005190 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005191 if "Error" in response:
5192 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
5193 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005194 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005195 except AssertionError:
5196 main.log.exception( "" )
5197 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005198 except TypeError:
5199 main.log.exception( self.name + ": Object not as expected" )
5200 return main.FALSE
5201 except pexpect.EOF:
5202 main.log.error( self.name + ": EOF exception found" )
5203 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005204 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005205 except Exception:
5206 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005207 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005208
5209 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005210 '''
GlennRC20fc6522015-12-23 23:26:57 -08005211 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005212 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005213 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005214 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005215 Returns:
5216 Returns main.FALSE if an exception is thrown or an error is present
5217 in the response. Otherwise, returns main.TRUE.
5218 NOTE:
5219 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005220 '''
GlennRC20fc6522015-12-23 23:26:57 -08005221 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005222 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005223 host = list( host )
5224
5225 for h in host:
5226 time.sleep( 1 )
5227 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005228 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005229 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005230 if "Error" in response:
5231 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5232 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005233 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005234 except AssertionError:
5235 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005236 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005237 except TypeError:
5238 main.log.exception( self.name + ": Object not as expected" )
5239 return main.FALSE
5240 except pexpect.EOF:
5241 main.log.error( self.name + ": EOF exception found" )
5242 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005243 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005244 except Exception:
5245 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005246 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005247
YPZhangfebf7302016-05-24 16:45:56 -07005248 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005249 '''
GlennRCed771242016-01-13 17:02:47 -08005250 Description:
5251 Bring link down or up in the null-provider.
5252 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005253 begin - (string) One end of a device or switch.
5254 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005255 returns:
5256 main.TRUE if no exceptions were thrown and no Errors are
5257 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005258 '''
GlennRCed771242016-01-13 17:02:47 -08005259 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005260 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005261 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005262 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005263 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005264 if "Error" in response or "Failure" in response:
5265 main.log.error( response )
5266 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005267 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005268 except AssertionError:
5269 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005270 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005271 except TypeError:
5272 main.log.exception( self.name + ": Object not as expected" )
5273 return main.FALSE
5274 except pexpect.EOF:
5275 main.log.error( self.name + ": EOF exception found" )
5276 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005277 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005278 except Exception:
5279 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005280 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005281
Jon Hall2c8959e2016-12-16 12:17:34 -08005282 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005283 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005284 Description:
5285 Changes the state of port in an OF switch by means of the
5286 PORTSTATUS OF messages.
5287 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005288 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5289 port - (string) target port in the device. Ex: '2'
5290 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005291 returns:
5292 main.TRUE if no exceptions were thrown and no Errors are
5293 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005294 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005295 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005296 state = state.lower()
5297 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005298 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005299 response = self.sendline( cmd, showResponse=True )
5300 assert response is not None, "Error in sendline"
5301 assert "Command not found:" not in response, response
5302 if "Error" in response or "Failure" in response:
5303 main.log.error( response )
5304 return main.FALSE
5305 return main.TRUE
5306 except AssertionError:
5307 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005308 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005309 except TypeError:
5310 main.log.exception( self.name + ": Object not as expected" )
5311 return main.FALSE
5312 except pexpect.EOF:
5313 main.log.error( self.name + ": EOF exception found" )
5314 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005315 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005316 except Exception:
5317 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005318 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005319
5320 def logSet( self, level="INFO", app="org.onosproject" ):
5321 """
5322 Set the logging level to lvl for a specific app
5323 returns main.TRUE on success
5324 returns main.FALSE if Error occurred
5325 if noExit is True, TestON will not exit, but clean up
5326 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5327 Level defaults to INFO
5328 """
5329 try:
You Wang22e807e2021-03-29 10:53:38 -07005330 handle = self.sendline( "log:set %s %s" % ( level, app ) )
5331 assert handle is not None, "Error in sendline"
5332 assert "Command not found:" not in handle, handle
5333 if re.search( "Error", handle ):
5334 main.log.error( self.name + ": Error in setting log level" )
5335 main.log.error( handle )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005336 return main.FALSE
You Wang22e807e2021-03-29 10:53:38 -07005337 else:
5338 return main.TRUE
5339 except AssertionError:
5340 main.log.exception( "" )
5341 return None
5342 except TypeError:
5343 main.log.exception( self.name + ": Object not as expected" )
5344 return None
Flavio Castro82ee2f62016-06-07 15:04:12 -07005345 except pexpect.EOF:
5346 main.log.error( self.name + ": EOF exception found" )
5347 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005348 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005349 except Exception:
5350 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005351 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005352
Jon Hall06fd0df2021-01-25 15:50:06 -08005353 def logList( self, saveValues=True ):
5354 """
5355 Gets the current log levels and optionally saves them
5356 returns a dict of the log levels or
5357 returns main.FALSE if Error occurred
5358 """
5359 try:
5360 self.handle.sendline( "log:list" )
5361 self.handle.expect( self.karafPrompt )
5362
5363 response = self.handle.before
5364 logLevels = {}
5365 for line in response.splitlines():
5366 parsed = line.split('│')
5367 logger = parsed[0].strip()
5368 if len( parsed ) != 2 or 'Level' in parsed[1] or logger[0] == '─':
5369 continue
5370 level = parsed[1].strip()
5371 logLevels[ logger ] = level
5372 if saveValues:
5373 self.logLevels = logLevels
5374 return logLevels
5375 except pexpect.TIMEOUT:
5376 main.log.exception( self.name + ": TIMEOUT exception found" )
5377 main.cleanAndExit()
5378 except pexpect.EOF:
5379 main.log.error( self.name + ": EOF exception found" )
5380 main.log.error( self.name + ": " + self.handle.before )
5381 main.cleanAndExit()
5382 except Exception:
5383 main.log.exception( self.name + ": Uncaught exception!" )
5384 main.cleanAndExit()
5385
You Wangdb8cd0a2016-05-26 15:19:45 -07005386 def getGraphDict( self, timeout=60, includeHost=False ):
5387 """
5388 Return a dictionary which describes the latest network topology data as a
5389 graph.
5390 An example of the dictionary:
5391 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5392 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5393 Each vertex should at least have an 'edges' attribute which describes the
5394 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005395 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005396 list of attributes.
5397 An example of the edges dictionary:
5398 'edges': { vertex2: { 'port': ..., 'weight': ... },
5399 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005400 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005401 in topology data.
5402 """
5403 graphDict = {}
5404 try:
5405 links = self.links()
5406 links = json.loads( links )
5407 devices = self.devices()
5408 devices = json.loads( devices )
5409 idToDevice = {}
5410 for device in devices:
5411 idToDevice[ device[ 'id' ] ] = device
5412 if includeHost:
5413 hosts = self.hosts()
5414 # FIXME: support 'includeHost' argument
5415 for link in links:
5416 nodeA = link[ 'src' ][ 'device' ]
5417 nodeB = link[ 'dst' ][ 'device' ]
5418 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005419 if nodeA not in graphDict.keys():
5420 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005421 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005422 'type': idToDevice[ nodeA ][ 'type' ],
5423 'available': idToDevice[ nodeA ][ 'available' ],
5424 'role': idToDevice[ nodeA ][ 'role' ],
5425 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5426 'hw': idToDevice[ nodeA ][ 'hw' ],
5427 'sw': idToDevice[ nodeA ][ 'sw' ],
5428 'serial': idToDevice[ nodeA ][ 'serial' ],
5429 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005430 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005431 else:
5432 # Assert nodeB is not connected to any current links of nodeA
You Wang7d14d642019-01-23 15:10:08 -08005433 # assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
5434 pass
Jon Halle0f0b342017-04-18 11:43:47 -07005435 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5436 'type': link[ 'type' ],
5437 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005438 return graphDict
5439 except ( TypeError, ValueError ):
5440 main.log.exception( self.name + ": Object not as expected" )
5441 return None
5442 except KeyError:
5443 main.log.exception( self.name + ": KeyError exception found" )
5444 return None
5445 except AssertionError:
5446 main.log.exception( self.name + ": AssertionError exception found" )
5447 return None
5448 except pexpect.EOF:
5449 main.log.error( self.name + ": EOF exception found" )
5450 main.log.error( self.name + ": " + self.handle.before )
5451 return None
5452 except Exception:
5453 main.log.exception( self.name + ": Uncaught exception!" )
5454 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005455
5456 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005457 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005458 Send command to check intent-perf summary
5459 Returns: dictionary for intent-perf summary
5460 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005461 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005462 cmd = "intent-perf -s"
5463 respDic = {}
5464 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005465 assert resp is not None, "Error in sendline"
5466 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005467 try:
5468 # Generate the dictionary to return
5469 for l in resp.split( "\n" ):
5470 # Delete any white space in line
5471 temp = re.sub( r'\s+', '', l )
5472 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005473 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005474
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005475 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005476 main.log.exception( self.name + ": Object not as expected" )
5477 return None
5478 except KeyError:
5479 main.log.exception( self.name + ": KeyError exception found" )
5480 return None
5481 except AssertionError:
5482 main.log.exception( self.name + ": AssertionError exception found" )
5483 return None
5484 except pexpect.EOF:
5485 main.log.error( self.name + ": EOF exception found" )
5486 main.log.error( self.name + ": " + self.handle.before )
5487 return None
5488 except Exception:
5489 main.log.exception( self.name + ": Uncaught exception!" )
5490 return None
5491 return respDic
5492
Chiyu Chengec63bde2016-11-17 18:11:36 -08005493 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005494 """
5495 Searches the latest ONOS log file for the given search term and
5496 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005497
chengchiyu08303a02016-09-08 17:40:26 -07005498 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005499 searchTerm:
5500 The string to grep from the ONOS log.
5501 startLine:
5502 The term that decides which line is the start to search the searchTerm in
5503 the karaf log. For now, startTerm only works in 'first' mode.
5504 logNum:
5505 In some extreme cases, one karaf log is not big enough to contain all the
5506 information.Because of this, search mutiply logs is necessary to capture
5507 the right result. logNum is the number of karaf logs that we need to search
5508 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005509 mode:
5510 all: return all the strings that contain the search term
5511 last: return the last string that contains the search term
5512 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005513 num: return the number of times that the searchTerm appears in the log
5514 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005515 """
5516 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005517 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005518 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005519 logPath = '/opt/onos/log/karaf.log.'
5520 logPaths = '/opt/onos/log/karaf.log'
5521 for i in range( 1, logNum ):
5522 logPaths = logPath + str( i ) + " " + logPaths
5523 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005524 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005525 # 100000000 is just a extreme large number to make sure this function can
5526 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005527 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005528 if mode == 'all':
5529 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005530 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005531 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005532 elif mode == 'first':
5533 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5534 elif mode == 'num':
You Wangd91a70f2019-01-03 15:28:10 -08005535 cmd = cmd + " | grep \'" + searchTerm + "\' | wc -l"
5536 num = self.lineCount( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005537 return num
You Wang6d301d42017-04-21 10:49:33 -07005538 elif mode == 'total':
Jon Halld5a94fb2018-11-13 14:32:23 -08005539 totalLines = self.lineCount( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005540 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005541 else:
5542 main.log.error( self.name + " unsupported mode" )
5543 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005544 before = self.sendline( cmd )
5545 before = before.splitlines()
5546 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005547 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005548 return returnLines
5549 except AssertionError:
5550 main.log.error( self.name + " searchTerm is not string type" )
5551 return None
5552 except pexpect.EOF:
5553 main.log.error( self.name + ": EOF exception found" )
5554 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005555 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005556 except pexpect.TIMEOUT:
5557 main.log.error( self.name + ": TIMEOUT exception found" )
5558 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005559 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005560 except Exception:
5561 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005562 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005563
5564 def vplsShow( self, jsonFormat=True ):
5565 """
5566 Description: Returns result of onos:vpls show, which should list the
5567 configured VPLS networks and the assigned interfaces.
5568 Optional:
5569 * jsonFormat: enable json formatting of output
5570 Returns:
5571 The output of the command or None on error.
5572 """
5573 try:
5574 cmdStr = "vpls show"
5575 if jsonFormat:
5576 raise NotImplementedError
5577 cmdStr += " -j"
5578 handle = self.sendline( cmdStr )
5579 assert handle is not None, "Error in sendline"
5580 assert "Command not found:" not in handle, handle
5581 return handle
5582 except AssertionError:
5583 main.log.exception( "" )
5584 return None
5585 except TypeError:
5586 main.log.exception( self.name + ": Object not as expected" )
5587 return None
5588 except pexpect.EOF:
5589 main.log.error( self.name + ": EOF exception found" )
5590 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005591 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005592 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005593 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005594 return None
5595 except Exception:
5596 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005597 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005598
5599 def parseVplsShow( self ):
5600 """
5601 Parse the cli output of 'vpls show' into json output. This is required
5602 as there is currently no json output available.
5603 """
5604 try:
5605 output = []
5606 raw = self.vplsShow( jsonFormat=False )
5607 namePat = "VPLS name: (?P<name>\w+)"
5608 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5609 encapPat = "Encapsulation: (?P<encap>\w+)"
5610 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5611 mIter = re.finditer( pattern, raw )
5612 for match in mIter:
5613 item = {}
5614 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005615 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005616 if ifaces == [ "" ]:
5617 ifaces = []
5618 item[ 'interfaces' ] = ifaces
5619 encap = match.group( 'encap' )
5620 if encap != 'NONE':
5621 item[ 'encapsulation' ] = encap.lower()
5622 output.append( item )
5623 return output
5624 except Exception:
5625 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005626 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005627
5628 def vplsList( self, jsonFormat=True ):
5629 """
5630 Description: Returns result of onos:vpls list, which should list the
5631 configured VPLS networks.
5632 Optional:
5633 * jsonFormat: enable json formatting of output
5634 """
5635 try:
5636 cmdStr = "vpls list"
5637 if jsonFormat:
5638 raise NotImplementedError
5639 cmdStr += " -j"
5640 handle = self.sendline( cmdStr )
5641 assert handle is not None, "Error in sendline"
5642 assert "Command not found:" not in handle, handle
5643 return handle
5644 except AssertionError:
5645 main.log.exception( "" )
5646 return None
5647 except TypeError:
5648 main.log.exception( self.name + ": Object not as expected" )
5649 return None
5650 except pexpect.EOF:
5651 main.log.error( self.name + ": EOF exception found" )
5652 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005653 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005654 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005655 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005656 return None
5657 except Exception:
5658 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005659 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005660
5661 def vplsCreate( self, network ):
5662 """
5663 CLI command to create a new VPLS network.
5664 Required arguments:
5665 network - String name of the network to create.
5666 returns:
5667 main.TRUE on success and main.FALSE on failure
5668 """
5669 try:
5670 network = str( network )
5671 cmdStr = "vpls create "
5672 cmdStr += network
5673 output = self.sendline( cmdStr )
5674 assert output is not None, "Error in sendline"
5675 assert "Command not found:" not in output, output
5676 assert "Error executing command" not in output, output
5677 assert "VPLS already exists:" not in output, output
5678 return main.TRUE
5679 except AssertionError:
5680 main.log.exception( "" )
5681 return main.FALSE
5682 except TypeError:
5683 main.log.exception( self.name + ": Object not as expected" )
5684 return main.FALSE
5685 except pexpect.EOF:
5686 main.log.error( self.name + ": EOF exception found" )
5687 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005688 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005689 except Exception:
5690 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005691 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005692
5693 def vplsDelete( self, network ):
5694 """
5695 CLI command to delete a VPLS network.
5696 Required arguments:
5697 network - Name of the network to delete.
5698 returns:
5699 main.TRUE on success and main.FALSE on failure
5700 """
5701 try:
5702 network = str( network )
5703 cmdStr = "vpls delete "
5704 cmdStr += network
5705 output = self.sendline( cmdStr )
5706 assert output is not None, "Error in sendline"
5707 assert "Command not found:" not in output, output
5708 assert "Error executing command" not in output, output
5709 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005710 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005711 return main.TRUE
5712 except AssertionError:
5713 main.log.exception( "" )
5714 return main.FALSE
5715 except TypeError:
5716 main.log.exception( self.name + ": Object not as expected" )
5717 return main.FALSE
5718 except pexpect.EOF:
5719 main.log.error( self.name + ": EOF exception found" )
5720 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005721 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005722 except Exception:
5723 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005724 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005725
5726 def vplsAddIface( self, network, iface ):
5727 """
5728 CLI command to add an interface to a VPLS network.
5729 Required arguments:
5730 network - Name of the network to add the interface to.
5731 iface - The ONOS name for an interface.
5732 returns:
5733 main.TRUE on success and main.FALSE on failure
5734 """
5735 try:
5736 network = str( network )
5737 iface = str( iface )
5738 cmdStr = "vpls add-if "
5739 cmdStr += network + " " + iface
5740 output = self.sendline( cmdStr )
5741 assert output is not None, "Error in sendline"
5742 assert "Command not found:" not in output, output
5743 assert "Error executing command" not in output, output
5744 assert "already associated to network" not in output, output
5745 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005746 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005747 return main.TRUE
5748 except AssertionError:
5749 main.log.exception( "" )
5750 return main.FALSE
5751 except TypeError:
5752 main.log.exception( self.name + ": Object not as expected" )
5753 return main.FALSE
5754 except pexpect.EOF:
5755 main.log.error( self.name + ": EOF exception found" )
5756 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005757 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005758 except Exception:
5759 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005760 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005761
5762 def vplsRemIface( self, network, iface ):
5763 """
5764 CLI command to remove an interface from a VPLS network.
5765 Required arguments:
5766 network - Name of the network to remove the interface from.
5767 iface - Name of the interface to remove.
5768 returns:
5769 main.TRUE on success and main.FALSE on failure
5770 """
5771 try:
5772 iface = str( iface )
5773 cmdStr = "vpls rem-if "
5774 cmdStr += network + " " + iface
5775 output = self.sendline( cmdStr )
5776 assert output is not None, "Error in sendline"
5777 assert "Command not found:" not in output, output
5778 assert "Error executing command" not in output, output
5779 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005780 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005781 return main.TRUE
5782 except AssertionError:
5783 main.log.exception( "" )
5784 return main.FALSE
5785 except TypeError:
5786 main.log.exception( self.name + ": Object not as expected" )
5787 return main.FALSE
5788 except pexpect.EOF:
5789 main.log.error( self.name + ": EOF exception found" )
5790 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005791 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005792 except Exception:
5793 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005794 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005795
5796 def vplsClean( self ):
5797 """
5798 Description: Clears the VPLS app configuration.
5799 Returns: main.TRUE on success and main.FALSE on failure
5800 """
5801 try:
5802 cmdStr = "vpls clean"
5803 handle = self.sendline( cmdStr )
5804 assert handle is not None, "Error in sendline"
5805 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005806 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005807 return handle
5808 except AssertionError:
5809 main.log.exception( "" )
5810 return main.FALSE
5811 except TypeError:
5812 main.log.exception( self.name + ": Object not as expected" )
5813 return main.FALSE
5814 except pexpect.EOF:
5815 main.log.error( self.name + ": EOF exception found" )
5816 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005817 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005818 except Exception:
5819 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005820 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005821
5822 def vplsSetEncap( self, network, encapType ):
5823 """
5824 CLI command to add an interface to a VPLS network.
5825 Required arguments:
5826 network - Name of the network to create.
5827 encapType - Type of encapsulation.
5828 returns:
5829 main.TRUE on success and main.FALSE on failure
5830 """
5831 try:
5832 network = str( network )
5833 encapType = str( encapType ).upper()
5834 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5835 cmdStr = "vpls set-encap "
5836 cmdStr += network + " " + encapType
5837 output = self.sendline( cmdStr )
5838 assert output is not None, "Error in sendline"
5839 assert "Command not found:" not in output, output
5840 assert "Error executing command" not in output, output
5841 assert "already associated to network" not in output, output
5842 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005843 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005844 return main.TRUE
5845 except AssertionError:
5846 main.log.exception( "" )
5847 return main.FALSE
5848 except TypeError:
5849 main.log.exception( self.name + ": Object not as expected" )
5850 return main.FALSE
5851 except pexpect.EOF:
5852 main.log.error( self.name + ": EOF exception found" )
5853 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005854 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005855 except Exception:
5856 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005857 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005858
5859 def interfaces( self, jsonFormat=True ):
5860 """
5861 Description: Returns result of interfaces command.
5862 Optional:
5863 * jsonFormat: enable json formatting of output
5864 Returns:
5865 The output of the command or None on error.
5866 """
5867 try:
5868 cmdStr = "interfaces"
5869 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005870 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005871 cmdStr += " -j"
5872 handle = self.sendline( cmdStr )
5873 assert handle is not None, "Error in sendline"
5874 assert "Command not found:" not in handle, handle
5875 return handle
5876 except AssertionError:
5877 main.log.exception( "" )
5878 return None
5879 except TypeError:
5880 main.log.exception( self.name + ": Object not as expected" )
5881 return None
5882 except pexpect.EOF:
5883 main.log.error( self.name + ": EOF exception found" )
5884 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005885 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005886 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005887 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005888 return None
5889 except Exception:
5890 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005891 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005892
5893 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005894 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005895 Get the timestamp of searchTerm from karaf log.
5896
5897 Arguments:
5898 splitTerm_before and splitTerm_after:
5899
5900 The terms that split the string that contains the timeStamp of
5901 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5902 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5903 and the splitTerm_after is "x"
5904
5905 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005906 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005907 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005908 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005909 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005910 return main.ERROR
5911 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005912 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005913 main.log.warn( "Captured timestamp string is empty" )
5914 return main.ERROR
5915 lines = lines[ 0 ]
5916 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005917 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005918 # get the target value
5919 line = lines.split( splitTerm_before )
5920 key = line[ 1 ].split( splitTerm_after )
5921 return int( key[ 0 ] )
5922 except IndexError:
5923 main.log.warn( "Index Error!" )
5924 return main.ERROR
5925 except AssertionError:
5926 main.log.warn( "Search Term Not Found " )
5927 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005928
5929 def workQueueAdd( self, queueName, value ):
5930 """
5931 CLI command to add a string to the specified Work Queue.
5932 This function uses the distributed primitives test app, which
5933 gives some cli access to distributed primitives for testing
5934 purposes only.
5935
5936 Required arguments:
5937 queueName - The name of the queue to add to
5938 value - The value to add to the queue
5939 returns:
5940 main.TRUE on success, main.FALSE on failure and
5941 main.ERROR on error.
5942 """
5943 try:
5944 queueName = str( queueName )
5945 value = str( value )
5946 prefix = "work-queue-test"
5947 operation = "add"
5948 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5949 output = self.distPrimitivesSend( cmdStr )
5950 if "Invalid operation name" in output:
5951 main.log.warn( output )
5952 return main.ERROR
5953 elif "Done" in output:
5954 return main.TRUE
5955 except TypeError:
5956 main.log.exception( self.name + ": Object not as expected" )
5957 return main.ERROR
5958 except Exception:
5959 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005960 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005961
5962 def workQueueAddMultiple( self, queueName, value1, value2 ):
5963 """
5964 CLI command to add two strings to the specified Work Queue.
5965 This function uses the distributed primitives test app, which
5966 gives some cli access to distributed primitives for testing
5967 purposes only.
5968
5969 Required arguments:
5970 queueName - The name of the queue to add to
5971 value1 - The first value to add to the queue
5972 value2 - The second value to add to the queue
5973 returns:
5974 main.TRUE on success, main.FALSE on failure and
5975 main.ERROR on error.
5976 """
5977 try:
5978 queueName = str( queueName )
5979 value1 = str( value1 )
5980 value2 = str( value2 )
5981 prefix = "work-queue-test"
5982 operation = "addMultiple"
5983 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5984 output = self.distPrimitivesSend( cmdStr )
5985 if "Invalid operation name" in output:
5986 main.log.warn( output )
5987 return main.ERROR
5988 elif "Done" in output:
5989 return main.TRUE
5990 except TypeError:
5991 main.log.exception( self.name + ": Object not as expected" )
5992 return main.ERROR
5993 except Exception:
5994 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005995 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005996
5997 def workQueueTakeAndComplete( self, queueName, number=1 ):
5998 """
5999 CLI command to take a value from the specified Work Queue and compelte it.
6000 This function uses the distributed primitives test app, which
6001 gives some cli access to distributed primitives for testing
6002 purposes only.
6003
6004 Required arguments:
6005 queueName - The name of the queue to add to
6006 number - The number of items to take and complete
6007 returns:
6008 main.TRUE on success, main.FALSE on failure and
6009 main.ERROR on error.
6010 """
6011 try:
6012 queueName = str( queueName )
6013 number = str( int( number ) )
6014 prefix = "work-queue-test"
6015 operation = "takeAndComplete"
6016 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
6017 output = self.distPrimitivesSend( cmdStr )
6018 if "Invalid operation name" in output:
6019 main.log.warn( output )
6020 return main.ERROR
6021 elif "Done" in output:
6022 return main.TRUE
6023 except TypeError:
6024 main.log.exception( self.name + ": Object not as expected" )
6025 return main.ERROR
6026 except Exception:
6027 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006028 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006029
6030 def workQueueDestroy( self, queueName ):
6031 """
6032 CLI command to destroy the specified Work Queue.
6033 This function uses the distributed primitives test app, which
6034 gives some cli access to distributed primitives for testing
6035 purposes only.
6036
6037 Required arguments:
6038 queueName - The name of the queue to add to
6039 returns:
6040 main.TRUE on success, main.FALSE on failure and
6041 main.ERROR on error.
6042 """
6043 try:
6044 queueName = str( queueName )
6045 prefix = "work-queue-test"
6046 operation = "destroy"
6047 cmdStr = " ".join( [ prefix, queueName, operation ] )
6048 output = self.distPrimitivesSend( cmdStr )
6049 if "Invalid operation name" in output:
6050 main.log.warn( output )
6051 return main.ERROR
6052 return main.TRUE
6053 except TypeError:
6054 main.log.exception( self.name + ": Object not as expected" )
6055 return main.ERROR
6056 except Exception:
6057 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006058 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006059
6060 def workQueueTotalPending( self, queueName ):
6061 """
6062 CLI command to get the Total Pending items of the specified Work Queue.
6063 This function uses the distributed primitives test app, which
6064 gives some cli access to distributed primitives for testing
6065 purposes only.
6066
6067 Required arguments:
6068 queueName - The name of the queue to add to
6069 returns:
6070 The number of Pending items in the specified work queue or
6071 None on error
6072 """
6073 try:
6074 queueName = str( queueName )
6075 prefix = "work-queue-test"
6076 operation = "totalPending"
6077 cmdStr = " ".join( [ prefix, queueName, operation ] )
6078 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08006079 main.log.debug( self.name + ": work queue unparsed: " + output )
6080 output = output.split( "\r\n" )[ -1 ]
6081 main.log.debug( self.name + ": work queue parsed: " + output )
Jon Halle0f0b342017-04-18 11:43:47 -07006082 pattern = r'\d+'
6083 if "Invalid operation name" in output:
6084 main.log.warn( output )
6085 return None
6086 else:
6087 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006088 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006089 except ( AttributeError, TypeError ):
6090 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6091 return None
6092 except Exception:
6093 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006094 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006095
6096 def workQueueTotalCompleted( self, queueName ):
6097 """
6098 CLI command to get the Total Completed items of the specified Work Queue.
6099 This function uses the distributed primitives test app, which
6100 gives some cli access to distributed primitives for testing
6101 purposes only.
6102
6103 Required arguments:
6104 queueName - The name of the queue to add to
6105 returns:
6106 The number of complete items in the specified work queue or
6107 None on error
6108 """
6109 try:
6110 queueName = str( queueName )
6111 prefix = "work-queue-test"
6112 operation = "totalCompleted"
6113 cmdStr = " ".join( [ prefix, queueName, operation ] )
6114 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08006115 main.log.debug( self.name + ": work queue unparsed: " + output )
6116 output = output.split( "\r\n" )[ -1 ]
6117 main.log.debug( self.name + ": work queue parsed: " + output )
Jon Halle0f0b342017-04-18 11:43:47 -07006118 pattern = r'\d+'
6119 if "Invalid operation name" in output:
6120 main.log.warn( output )
6121 return None
6122 else:
6123 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006124 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006125 except ( AttributeError, TypeError ):
6126 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6127 return None
6128 except Exception:
6129 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006130 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006131
6132 def workQueueTotalInProgress( self, queueName ):
6133 """
6134 CLI command to get the Total In Progress items of the specified Work Queue.
6135 This function uses the distributed primitives test app, which
6136 gives some cli access to distributed primitives for testing
6137 purposes only.
6138
6139 Required arguments:
6140 queueName - The name of the queue to add to
6141 returns:
6142 The number of In Progress items in the specified work queue or
6143 None on error
6144 """
6145 try:
6146 queueName = str( queueName )
6147 prefix = "work-queue-test"
6148 operation = "totalInProgress"
6149 cmdStr = " ".join( [ prefix, queueName, operation ] )
6150 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08006151 main.log.debug( self.name + ": work queue unparsed: " + output )
6152 output = output.split( "\r\n" )[ -1 ]
6153 main.log.debug( self.name + ": work queue parsed: " + output )
Jon Halle0f0b342017-04-18 11:43:47 -07006154 pattern = r'\d+'
6155 if "Invalid operation name" in output:
6156 main.log.warn( output )
6157 return None
6158 else:
6159 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006160 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006161 except ( AttributeError, TypeError ):
6162 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6163 return None
6164 except Exception:
6165 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006166 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00006167
6168 def events( self, args='-a' ):
6169 """
6170 Description: Returns events -a command output
6171 Optional:
6172 add other arguments
6173 """
6174 try:
6175 cmdStr = "events"
6176 if args:
6177 cmdStr += " " + args
6178 handle = self.sendline( cmdStr )
6179 assert handle is not None, "Error in sendline"
6180 assert "Command not found:" not in handle, handle
6181 return handle
6182 except AssertionError:
6183 main.log.exception( "" )
6184 return None
6185 except TypeError:
6186 main.log.exception( self.name + ": Object not as expected" )
6187 return None
6188 except pexpect.EOF:
6189 main.log.error( self.name + ": EOF exception found" )
6190 main.log.error( self.name + ": " + self.handle.before )
6191 main.cleanAndExit()
6192 except Exception:
6193 main.log.exception( self.name + ": Uncaught exception!" )
6194 main.cleanAndExit()
6195
6196 def getMaster( self, deviceID ):
6197 """
6198 Description: Obtains current master using "roles" command for a specific deviceID
6199 """
6200 try:
6201 return str( self.getRole( deviceID )[ 'master' ] )
6202 except AssertionError:
6203 main.log.exception( "" )
6204 return None
6205 except TypeError:
6206 main.log.exception( self.name + ": Object not as expected" )
6207 return None
6208 except pexpect.EOF:
6209 main.log.error( self.name + ": EOF exception found" )
6210 main.log.error( self.name + ": " + self.handle.before )
6211 main.cleanAndExit()
6212 except Exception:
6213 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07006214 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08006215
6216 def issu( self ):
6217 """
6218 Short summary of In-Service Software Upgrade status
6219
6220 Returns the output of the cli command or None on Error
6221 """
6222 try:
6223 cmdStr = "issu"
6224 handle = self.sendline( cmdStr )
6225 assert handle is not None, "Error in sendline"
6226 assert "Command not found:" not in handle, handle
6227 assert "Unsupported command:" not in handle, handle
6228 return handle
6229 except AssertionError:
6230 main.log.exception( "" )
6231 return None
6232 except TypeError:
6233 main.log.exception( self.name + ": Object not as expected" )
6234 return None
6235 except pexpect.EOF:
6236 main.log.error( self.name + ": EOF exception found" )
6237 main.log.error( self.name + ": " + self.handle.before )
6238 main.cleanAndExit()
6239 except Exception:
6240 main.log.exception( self.name + ": Uncaught exception!" )
6241 main.cleanAndExit()
6242
6243 def issuInit( self ):
6244 """
6245 Initiates an In-Service Software Upgrade
6246
6247 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6248 """
6249 try:
6250 cmdStr = "issu init"
6251 handle = self.sendline( cmdStr )
6252 assert handle is not None, "Error in sendline"
6253 assert "Command not found:" not in handle, handle
6254 assert "Unsupported command:" not in handle, handle
6255 if "Initialized" in handle:
6256 return main.TRUE
6257 else:
6258 return main.FALSE
6259 except AssertionError:
6260 main.log.exception( "" )
6261 return main.ERROR
6262 except TypeError:
6263 main.log.exception( self.name + ": Object not as expected" )
6264 return main.ERROR
6265 except pexpect.EOF:
6266 main.log.error( self.name + ": EOF exception found" )
6267 main.log.error( self.name + ": " + self.handle.before )
6268 main.cleanAndExit()
6269 except Exception:
6270 main.log.exception( self.name + ": Uncaught exception!" )
6271 main.cleanAndExit()
6272
6273 def issuUpgrade( self ):
6274 """
6275 Transitions stores to upgraded nodes
6276
6277 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6278 """
6279 try:
6280 cmdStr = "issu upgrade"
6281 handle = self.sendline( cmdStr )
6282 assert handle is not None, "Error in sendline"
6283 assert "Command not found:" not in handle, handle
6284 assert "Unsupported command:" not in handle, handle
6285 if "Upgraded" in handle:
6286 return main.TRUE
6287 else:
6288 return main.FALSE
6289 except AssertionError:
6290 main.log.exception( "" )
6291 return main.ERROR
6292 except TypeError:
6293 main.log.exception( self.name + ": Object not as expected" )
6294 return main.ERROR
6295 except pexpect.EOF:
6296 main.log.error( self.name + ": EOF exception found" )
6297 main.log.error( self.name + ": " + self.handle.before )
6298 main.cleanAndExit()
6299 except Exception:
6300 main.log.exception( self.name + ": Uncaught exception!" )
6301 main.cleanAndExit()
6302
6303 def issuCommit( self ):
6304 """
6305 Finalizes an In-Service Software Upgrade
6306
6307 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6308 """
6309 try:
6310 cmdStr = "issu commit"
6311 handle = self.sendline( cmdStr )
6312 assert handle is not None, "Error in sendline"
6313 assert "Command not found:" not in handle, handle
6314 assert "Unsupported command:" not in handle, handle
6315 # TODO: Check the version returned by this command
6316 if "Committed version" in handle:
6317 return main.TRUE
6318 else:
6319 return main.FALSE
6320 except AssertionError:
6321 main.log.exception( "" )
6322 return main.ERROR
6323 except TypeError:
6324 main.log.exception( self.name + ": Object not as expected" )
6325 return main.ERROR
6326 except pexpect.EOF:
6327 main.log.error( self.name + ": EOF exception found" )
6328 main.log.error( self.name + ": " + self.handle.before )
6329 main.cleanAndExit()
6330 except Exception:
6331 main.log.exception( self.name + ": Uncaught exception!" )
6332 main.cleanAndExit()
6333
6334 def issuRollback( self ):
6335 """
6336 Rolls back an In-Service Software Upgrade
6337
6338 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6339 """
6340 try:
6341 cmdStr = "issu rollback"
6342 handle = self.sendline( cmdStr )
6343 assert handle is not None, "Error in sendline"
6344 assert "Command not found:" not in handle, handle
6345 assert "Unsupported command:" not in handle, handle
6346 # TODO: Check the version returned by this command
6347 if "Rolled back to version" in handle:
6348 return main.TRUE
6349 else:
6350 return main.FALSE
6351 except AssertionError:
6352 main.log.exception( "" )
6353 return main.ERROR
6354 except TypeError:
6355 main.log.exception( self.name + ": Object not as expected" )
6356 return main.ERROR
6357 except pexpect.EOF:
6358 main.log.error( self.name + ": EOF exception found" )
6359 main.log.error( self.name + ": " + self.handle.before )
6360 main.cleanAndExit()
6361 except Exception:
6362 main.log.exception( self.name + ": Uncaught exception!" )
6363 main.cleanAndExit()
6364
6365 def issuReset( self ):
6366 """
6367 Resets the In-Service Software Upgrade status after a rollback
6368
6369 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6370 """
6371 try:
6372 cmdStr = "issu reset"
6373 handle = self.sendline( cmdStr )
6374 assert handle is not None, "Error in sendline"
6375 assert "Command not found:" not in handle, handle
6376 assert "Unsupported command:" not in handle, handle
6377 # TODO: Check the version returned by this command
6378 if "Reset version" in handle:
6379 return main.TRUE
6380 else:
6381 return main.FALSE
6382 except AssertionError:
6383 main.log.exception( "" )
6384 return main.ERROR
6385 except TypeError:
6386 main.log.exception( self.name + ": Object not as expected" )
6387 return main.ERROR
6388 except pexpect.EOF:
6389 main.log.error( self.name + ": EOF exception found" )
6390 main.log.error( self.name + ": " + self.handle.before )
6391 main.cleanAndExit()
6392 except Exception:
6393 main.log.exception( self.name + ": Uncaught exception!" )
6394 main.cleanAndExit()
6395
6396 def issuStatus( self ):
6397 """
6398 Status of an In-Service Software Upgrade
6399
6400 Returns the output of the cli command or None on Error
6401 """
6402 try:
6403 cmdStr = "issu status"
6404 handle = self.sendline( cmdStr )
6405 assert handle is not None, "Error in sendline"
6406 assert "Command not found:" not in handle, handle
6407 assert "Unsupported command:" not in handle, handle
6408 return handle
6409 except AssertionError:
6410 main.log.exception( "" )
6411 return None
6412 except TypeError:
6413 main.log.exception( self.name + ": Object not as expected" )
6414 return None
6415 except pexpect.EOF:
6416 main.log.error( self.name + ": EOF exception found" )
6417 main.log.error( self.name + ": " + self.handle.before )
6418 main.cleanAndExit()
6419 except Exception:
6420 main.log.exception( self.name + ": Uncaught exception!" )
6421 main.cleanAndExit()
6422
6423 def issuVersion( self ):
6424 """
6425 Get the version of an In-Service Software Upgrade
6426
6427 Returns the output of the cli command or None on Error
6428 """
6429 try:
6430 cmdStr = "issu version"
6431 handle = self.sendline( cmdStr )
6432 assert handle is not None, "Error in sendline"
6433 assert "Command not found:" not in handle, handle
6434 assert "Unsupported command:" not in handle, handle
6435 return handle
6436 except AssertionError:
6437 main.log.exception( "" )
6438 return None
6439 except TypeError:
6440 main.log.exception( self.name + ": Object not as expected" )
6441 return None
6442 except pexpect.EOF:
6443 main.log.error( self.name + ": EOF exception found" )
6444 main.log.error( self.name + ": " + self.handle.before )
6445 main.cleanAndExit()
6446 except Exception:
6447 main.log.exception( self.name + ": Uncaught exception!" )
6448 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006449
6450 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6451 """
6452 Create a multicast route by calling 'mcast-join' command
6453 sIP: source IP of the multicast route
6454 groupIP: group IP of the multicast route
6455 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6456 dPorts: a list of destination ports of the multicast route
6457 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6458 """
6459 try:
6460 cmdStr = "mcast-join"
6461 cmdStr += " " + str( sIP )
6462 cmdStr += " " + str( groupIP )
6463 cmdStr += " " + str( sPort )
6464 assert isinstance( dPorts, list )
6465 for dPort in dPorts:
6466 cmdStr += " " + str( dPort )
6467 handle = self.sendline( cmdStr )
6468 assert handle is not None, "Error in sendline"
6469 assert "Command not found:" not in handle, handle
6470 assert "Unsupported command:" not in handle, handle
6471 assert "Error executing command" not in handle, handle
6472 if "Added the mcast route" in handle:
6473 return main.TRUE
6474 else:
6475 return main.FALSE
6476 except AssertionError:
6477 main.log.exception( "" )
6478 return None
6479 except TypeError:
6480 main.log.exception( self.name + ": Object not as expected" )
6481 return None
6482 except pexpect.EOF:
6483 main.log.error( self.name + ": EOF exception found" )
6484 main.log.error( self.name + ": " + self.handle.before )
6485 main.cleanAndExit()
6486 except Exception:
6487 main.log.exception( self.name + ": Uncaught exception!" )
6488 main.cleanAndExit()
6489
6490 def mcastDelete( self, sIP, groupIP, dPorts ):
6491 """
6492 Delete a multicast route by calling 'mcast-delete' command
6493 sIP: source IP of the multicast route
6494 groupIP: group IP of the multicast route
6495 dPorts: a list of destination ports of the multicast route
6496 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6497 """
6498 try:
6499 cmdStr = "mcast-delete"
6500 cmdStr += " " + str( sIP )
6501 cmdStr += " " + str( groupIP )
6502 assert isinstance( dPorts, list )
6503 for dPort in dPorts:
6504 cmdStr += " " + str( dPort )
6505 handle = self.sendline( cmdStr )
6506 assert handle is not None, "Error in sendline"
6507 assert "Command not found:" not in handle, handle
6508 assert "Unsupported command:" not in handle, handle
6509 assert "Error executing command" not in handle, handle
6510 if "Updated the mcast route" in handle:
6511 return main.TRUE
6512 else:
6513 return main.FALSE
6514 except AssertionError:
6515 main.log.exception( "" )
6516 return None
6517 except TypeError:
6518 main.log.exception( self.name + ": Object not as expected" )
6519 return None
6520 except pexpect.EOF:
6521 main.log.error( self.name + ": EOF exception found" )
6522 main.log.error( self.name + ": " + self.handle.before )
6523 main.cleanAndExit()
6524 except Exception:
6525 main.log.exception( self.name + ": Uncaught exception!" )
6526 main.cleanAndExit()
6527
6528 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6529 """
6530 Create a multicast route by calling 'mcast-host-join' command
6531 sAddr: we can provide * for ASM or a specific address for SSM
6532 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006533 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006534 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6535 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6536 """
6537 try:
6538 cmdStr = "mcast-host-join"
6539 cmdStr += " -sAddr " + str( sAddr )
6540 cmdStr += " -gAddr " + str( gAddr )
6541 assert isinstance( srcs, list )
6542 for src in srcs:
6543 cmdStr += " -srcs " + str( src )
6544 assert isinstance( sinks, list )
6545 for sink in sinks:
6546 cmdStr += " -sinks " + str( sink )
6547 handle = self.sendline( cmdStr )
6548 assert handle is not None, "Error in sendline"
6549 assert "Command not found:" not in handle, handle
6550 assert "Unsupported command:" not in handle, handle
6551 assert "Error executing command" not in handle, handle
6552 if "Added the mcast route" in handle:
6553 return main.TRUE
6554 else:
6555 return main.FALSE
6556 except AssertionError:
6557 main.log.exception( "" )
6558 return None
6559 except TypeError:
6560 main.log.exception( self.name + ": Object not as expected" )
6561 return None
6562 except pexpect.EOF:
6563 main.log.error( self.name + ": EOF exception found" )
6564 main.log.error( self.name + ": " + self.handle.before )
6565 main.cleanAndExit()
6566 except Exception:
6567 main.log.exception( self.name + ": Uncaught exception!" )
6568 main.cleanAndExit()
6569
6570 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6571 """
6572 Delete multicast sink(s) by calling 'mcast-host-delete' command
6573 sAddr: we can provide * for ASM or a specific address for SSM
6574 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006575 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006576 will delete the route if not specified
6577 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6578 """
6579 try:
6580 cmdStr = "mcast-host-delete"
6581 cmdStr += " -sAddr " + str( sAddr )
6582 cmdStr += " -gAddr " + str( gAddr )
6583 if host:
6584 cmdStr += " -h " + str( host )
6585 handle = self.sendline( cmdStr )
6586 assert handle is not None, "Error in sendline"
6587 assert "Command not found:" not in handle, handle
6588 assert "Unsupported command:" not in handle, handle
6589 assert "Error executing command" not in handle, handle
6590 if "Updated the mcast route" in handle:
6591 return main.TRUE
6592 elif "Deleted the mcast route" in handle:
6593 return main.TRUE
6594 else:
6595 return main.FALSE
6596 except AssertionError:
6597 main.log.exception( "" )
6598 return None
6599 except TypeError:
6600 main.log.exception( self.name + ": Object not as expected" )
6601 return None
6602 except pexpect.EOF:
6603 main.log.error( self.name + ": EOF exception found" )
6604 main.log.error( self.name + ": " + self.handle.before )
6605 main.cleanAndExit()
6606 except Exception:
6607 main.log.exception( self.name + ": Uncaught exception!" )
6608 main.cleanAndExit()
6609
You Wang547893e2018-05-08 13:34:59 -07006610 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6611 """
6612 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6613 sAddr: we can provide * for ASM or a specific address for SSM
6614 gAddr: specifies multicast group address
6615 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6616 will delete the route if not specified
6617 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6618 """
6619 try:
6620 cmdStr = "mcast-sink-delete"
6621 cmdStr += " -sAddr " + str( sAddr )
6622 cmdStr += " -gAddr " + str( gAddr )
6623 if sink:
6624 cmdStr += " -s " + str( sink )
6625 handle = self.sendline( cmdStr )
6626 assert handle is not None, "Error in sendline"
6627 assert "Command not found:" not in handle, handle
6628 assert "Unsupported command:" not in handle, handle
6629 assert "Error executing command" not in handle, handle
6630 if "Updated the mcast route" in handle:
6631 return main.TRUE
6632 elif "Deleted the mcast route" in handle:
6633 return main.TRUE
6634 else:
6635 return main.FALSE
6636 except AssertionError:
6637 main.log.exception( "" )
6638 return None
6639 except TypeError:
6640 main.log.exception( self.name + ": Object not as expected" )
6641 return None
6642 except pexpect.EOF:
6643 main.log.error( self.name + ": EOF exception found" )
6644 main.log.error( self.name + ": " + self.handle.before )
6645 main.cleanAndExit()
6646 except Exception:
6647 main.log.exception( self.name + ": Uncaught exception!" )
6648 main.cleanAndExit()
6649
You Wange24d6272018-03-27 21:18:50 -07006650 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6651 """
6652 Delete multicast src(s) by calling 'mcast-source-delete' command
6653 sAddr: we can provide * for ASM or a specific address for SSM
6654 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006655 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 -07006656 will delete the route if not specified
6657 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6658 """
6659 try:
6660 cmdStr = "mcast-source-delete"
6661 cmdStr += " -sAddr " + str( sAddr )
6662 cmdStr += " -gAddr " + str( gAddr )
6663 if srcs:
6664 assert isinstance( srcs, list )
6665 for src in srcs:
6666 cmdStr += " -src " + str( src )
6667 handle = self.sendline( cmdStr )
6668 assert handle is not None, "Error in sendline"
6669 assert "Command not found:" not in handle, handle
6670 assert "Unsupported command:" not in handle, handle
6671 assert "Error executing command" not in handle, handle
6672 if "Updated the mcast route" in handle:
6673 return main.TRUE
6674 elif "Deleted the mcast route" in handle:
6675 return main.TRUE
6676 else:
6677 return main.FALSE
6678 except AssertionError:
6679 main.log.exception( "" )
6680 return None
6681 except TypeError:
6682 main.log.exception( self.name + ": Object not as expected" )
6683 return None
6684 except pexpect.EOF:
6685 main.log.error( self.name + ": EOF exception found" )
6686 main.log.error( self.name + ": " + self.handle.before )
6687 main.cleanAndExit()
6688 except Exception:
6689 main.log.exception( self.name + ": Uncaught exception!" )
6690 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006691
6692 def netcfg( self, jsonFormat=True, args="" ):
6693 """
6694 Run netcfg cli command with given args
6695 """
6696 try:
6697 cmdStr = "netcfg"
6698 if jsonFormat:
6699 cmdStr = cmdStr + " -j"
6700 if args:
6701 cmdStr = cmdStr + " " + str( args )
6702 handle = self.sendline( cmdStr )
6703 assert handle is not None, "Error in sendline"
6704 assert "Command not found:" not in handle, handle
6705 assert "Unsupported command:" not in handle, handle
6706 assert "Error executing command" not in handle, handle
6707 return handle
6708 except AssertionError:
6709 main.log.exception( "" )
6710 return None
6711 except TypeError:
6712 main.log.exception( self.name + ": Object not as expected" )
6713 return None
6714 except pexpect.EOF:
6715 main.log.error( self.name + ": EOF exception found" )
6716 main.log.error( self.name + ": " + self.handle.before )
6717 main.cleanAndExit()
6718 except Exception:
6719 main.log.exception( self.name + ": Uncaught exception!" )
6720 main.cleanAndExit()
6721
You Wang0fa76e72018-05-18 11:33:25 -07006722 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True, simple=False ):
You Wang5da39c82018-04-26 22:55:08 -07006723 """
You Wang54b1d672018-06-11 16:44:13 -07006724 Compose and return a list of t3-troubleshoot cli commands for given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006725 Options:
6726 sAddr: IP address of the source host
6727 dAddr: IP address of the destination host
You Wang0fa76e72018-05-18 11:33:25 -07006728 ipv6: True if hosts are IPv6
6729 verbose: return verbose t3 output if True
6730 simple: compose command for t3-troubleshoot-simple if True
You Wang5da39c82018-04-26 22:55:08 -07006731 """
6732 try:
6733 # Collect information of both hosts from onos
6734 hosts = self.hosts()
6735 hosts = json.loads( hosts )
6736 sHost = None
6737 dHost = None
6738 for host in hosts:
6739 if sAddr in host[ "ipAddresses" ]:
6740 sHost = host
6741 elif dAddr in host[ "ipAddresses" ]:
6742 dHost = host
6743 if sHost and dHost:
6744 break
6745 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang54b1d672018-06-11 16:44:13 -07006746 cmdList = []
You Wang5d9527b2018-05-29 17:08:54 -07006747 if simple:
6748 assert dHost, "Not able to find host with IP {}".format( dAddr )
You Wang54b1d672018-06-11 16:44:13 -07006749 cmdStr = "t3-troubleshoot-simple"
6750 if verbose:
6751 cmdStr += " -vv"
6752 if ipv6:
6753 cmdStr += " -et ipv6"
You Wang0fa76e72018-05-18 11:33:25 -07006754 cmdStr += " {}/{} {}/{}".format( sHost[ "mac" ], sHost[ "vlan" ], dHost[ "mac" ], dHost[ "vlan" ] )
You Wang54b1d672018-06-11 16:44:13 -07006755 cmdList.append( cmdStr )
You Wang0fa76e72018-05-18 11:33:25 -07006756 else:
You Wang54b1d672018-06-11 16:44:13 -07006757 for location in sHost[ "locations" ]:
6758 cmdStr = "t3-troubleshoot"
6759 if verbose:
6760 cmdStr += " -vv"
6761 if ipv6:
6762 cmdStr += " -et ipv6"
6763 cmdStr += " -s " + str( sAddr )
6764 cmdStr += " -sp " + str( location[ "elementId" ] ) + "/" + str( location[ "port" ] )
6765 cmdStr += " -sm " + str( sHost[ "mac" ] )
6766 if sHost[ "vlan" ] != "None":
6767 cmdStr += " -vid " + sHost[ "vlan" ]
6768 cmdStr += " -d " + str( dAddr )
6769 netcfg = self.netcfg( args="devices {}".format( location[ "elementId" ] ) )
6770 netcfg = json.loads( netcfg )
6771 assert netcfg, "Failed to get netcfg"
6772 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6773 cmdList.append( cmdStr )
6774 return cmdList
You Wang5da39c82018-04-26 22:55:08 -07006775 except AssertionError:
6776 main.log.exception( "" )
6777 return None
6778 except ( KeyError, TypeError ):
6779 main.log.exception( self.name + ": Object not as expected" )
6780 return None
6781 except Exception:
6782 main.log.exception( self.name + ": Uncaught exception!" )
6783 main.cleanAndExit()
6784
6785 def t3( self, sAddr, dAddr, ipv6=False ):
6786 """
You Wang54b1d672018-06-11 16:44:13 -07006787 Run t3-troubleshoot cli commands for all posible routes given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006788 Options:
6789 sAddr: IP address of the source host
6790 dAddr: IP address of the destination host
6791 """
6792 try:
You Wang54b1d672018-06-11 16:44:13 -07006793 cmdList = self.composeT3Command( sAddr, dAddr, ipv6 )
6794 assert cmdList is not None, "composeT3Command returned None"
6795 t3Output = ""
6796 for cmdStr in cmdList:
6797 handle = self.sendline( cmdStr )
6798 assert handle is not None, "Error in sendline"
6799 assert "Command not found:" not in handle, handle
6800 assert "Unsupported command:" not in handle, handle
6801 assert "Error executing command" not in handle, handle
6802 assert "Tracing packet" in handle
6803 t3Output += handle
6804 return t3Output
You Wang5da39c82018-04-26 22:55:08 -07006805 except AssertionError:
6806 main.log.exception( "" )
6807 return None
6808 except pexpect.EOF:
6809 main.log.error( self.name + ": EOF exception found" )
6810 main.log.error( self.name + ": " + self.handle.before )
6811 main.cleanAndExit()
6812 except Exception:
6813 main.log.exception( self.name + ": Uncaught exception!" )
6814 main.cleanAndExit()
Jon Hall3c0114c2020-08-11 15:07:42 -07006815
6816 def prepareForCLI( self, debug=True, maxRetries=120 ):
6817 """
6818 Prepare docker container to connect to onos cli
6819 """
6820 try:
6821 # Wait for log files to be created
6822 ready = 0
6823 retries = 0
6824 while not ready and retries < maxRetries:
6825 retries += 1
6826 self.handle.sendline( "ls -al /root/onos/apache-karaf-*/data/log" )
6827 ready = self.handle.expect( [ "No such file or directory", self.dockerPrompt ] )
6828 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
6829 if not ready:
6830 self.handle.expect( self.dockerPrompt )
6831 time.sleep( 1 )
Jon Hall3c0114c2020-08-11 15:07:42 -07006832
6833 cmdList = []
6834 cmdList.append( "apt-get update" )
6835 cmdList.append( "apt-get install -y openssh-server" )
6836 # Some built in scripts are hardcoded
6837 cmdList.append( "ln -s /root/onos /opt/onos" )
6838 cmdList.append( "ln -s /root/onos/apache-karaf-*/data/log /opt/onos/log" )
6839 cmdList.append( "ls -al /opt/onos" )
6840 output = ""
6841 for cmdStr in cmdList:
6842 self.handle.sendline( cmdStr )
Jon Hall627b1572020-12-01 12:01:15 -08006843 self.handle.expect( self.dockerPrompt, timeout=420 )
Jon Hall3c0114c2020-08-11 15:07:42 -07006844 self.handle.sendline( "" )
6845 self.handle.expect( self.dockerPrompt )
6846 handle = self.handle.before
6847 assert "command not found" not in handle, handle
6848 assert "No such file or directory" not in handle, handle
6849 output += handle
6850 if debug:
6851 main.log.debug( "%s: %s" % ( self.name, output ) )
6852 return output
6853 except AssertionError:
6854 main.log.exception( "" )
6855 return None
6856 except pexpect.EOF:
6857 main.log.error( self.name + ": EOF exception found" )
6858 main.log.error( self.name + ": " + self.handle.before )
6859 main.cleanAndExit()
6860 except Exception:
6861 main.log.exception( self.name + ": Uncaught exception!" )
6862 main.cleanAndExit()
6863
6864 def onosSecureSSH( self, userName="onos", userPWD="rocks" ):
6865 """
6866 Enables secure access to ONOS console
6867 by removing default users & keys.
6868
6869 bin/onos-user-password onos rocks
6870
6871 Returns: main.TRUE on success and main.FALSE on failure
6872 """
6873
6874 try:
6875 self.handle.sendline( "" )
6876 self.handle.expect( self.dockerPrompt )
6877
6878 self.handle.sendline( "[ ! -f ~/.ssh/id_rsa.pub ] && ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' -q" )
6879 self.handle.expect( self.dockerPrompt )
6880 main.log.debug( "%s: %s%s" % ( self.name, self.handle.before, self.handle.after ) )
6881
6882 self.handle.sendline( "bin/onos-user-key $(id -un) $(cut -d\\\\ -f2 ~/.ssh/id_rsa.pub)" )
6883 self.handle.expect( pexpect.TIMEOUT, timeout=10 )
6884 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
6885
6886 self.handle.sendline( "bin/onos-user-password %s %s" % ( userName, userPWD ) )
6887 i = self.handle.expect( [ "usage",
6888 self.dockerPrompt,
6889 pexpect.TIMEOUT ] )
6890 if i == 0:
6891 # malformed command
6892 main.log.warn( self.name + ": Could not parse onos-user-password command" )
6893 self.handle.expect( self.dockerPrompt )
6894 return main.FALSE
6895 elif i == 1:
6896 # Process started
6897 main.log.info( self.name + ": SSH password added for user " + userName )
6898 return main.TRUE
6899 elif i == 2:
6900 # timeout
6901 main.log.error( self.name + ": Failed to secure onos ssh " )
6902 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
6903 except pexpect.EOF:
6904 main.log.error( self.name + ": EOF exception found" )
6905 main.log.error( self.name + ": " + self.handle.before )
6906 main.cleanAndExit()
6907 except Exception:
6908 main.log.exception( self.name + ": Uncaught exception!" )
6909 main.cleanAndExit()