blob: 2447717b6216dcc35e3697148cfda28059f18648 [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"""
Siddesh715a9192021-11-03 19:51:20 +000039import ipaddress
andrewonlab95ce8322014-10-13 14:12:04 -040040import pexpect
41import re
Jon Hall30b82fa2015-03-04 17:15:43 -080042import json
43import types
Jon Hallbd16b922015-03-26 17:53:15 -070044import time
kelvin-onlaba4074292015-07-09 15:19:49 -070045import os
andrewonlab95ce8322014-10-13 14:12:04 -040046from drivers.common.clidriver import CLI
You Wangdb8cd0a2016-05-26 15:19:45 -070047from core.graph import Graph
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -070048from cStringIO import StringIO
49from itertools import izip
andrewonlab95ce8322014-10-13 14:12:04 -040050
kelvin8ec71442015-01-15 16:57:00 -080051class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040052
kelvin8ec71442015-01-15 16:57:00 -080053 def __init__( self ):
54 """
55 Initialize client
56 """
Jon Hallefbd9792015-03-05 16:11:36 -080057 self.name = None
58 self.home = None
59 self.handle = None
Devin Limdc78e202017-06-09 18:30:07 -070060 self.karafUser = None
61 self.karafPass = None
Jon Hall06fd0df2021-01-25 15:50:06 -080062 self.karafPort = None
Jon Hall9b0de1f2020-08-24 15:38:04 -070063 self.karafTimeout = None
Jon Hall06fd0df2021-01-25 15:50:06 -080064 self.address = None
Siddesh52750622021-03-05 19:52:03 +000065 self.karafPromptUser = None
Jon Hall3c0114c2020-08-11 15:07:42 -070066 self.dockerPrompt = None
You Wangdb8cd0a2016-05-26 15:19:45 -070067 self.graph = Graph()
Devin Limdc78e202017-06-09 18:30:07 -070068 super( OnosCliDriver, self ).__init__()
kelvin8ec71442015-01-15 16:57:00 -080069
70 def connect( self, **connectargs ):
71 """
andrewonlab95ce8322014-10-13 14:12:04 -040072 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080073 """
andrewonlab95ce8322014-10-13 14:12:04 -040074 try:
75 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080076 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070077 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040078 for key in self.options:
79 if key == "home":
Devin Limdc78e202017-06-09 18:30:07 -070080 self.home = self.options[ key ]
81 elif key == "karaf_username":
82 self.karafUser = self.options[ key ]
83 elif key == "karaf_password":
84 self.karafPass = self.options[ key ]
Jon Hall3c0114c2020-08-11 15:07:42 -070085 elif key == "docker_prompt":
86 self.dockerPrompt = self.options[ key ]
Jon Hall9b0de1f2020-08-24 15:38:04 -070087 elif key == "karaf_timeout":
88 self.karafTimeout = self.options[ key ]
Jon Hall06fd0df2021-01-25 15:50:06 -080089 elif key == "karaf_port":
90 self.karafPort = self.options[ key ]
Siddesh52750622021-03-05 19:52:03 +000091 elif key == "karafPromptUser":
92 self.karafPromptUser = self.options[ key ]
Jeremy Ronquillo82705492017-10-18 14:19:55 -070093 self.home = self.checkOptions( self.home, "~/onos" )
94 self.karafUser = self.checkOptions( self.karafUser, self.user_name )
95 self.karafPass = self.checkOptions( self.karafPass, self.pwd )
Jon Hall06fd0df2021-01-25 15:50:06 -080096 self.karafPort = self.checkOptions( self.karafPort, 8101 )
Jon Hall3c0114c2020-08-11 15:07:42 -070097 self.dockerPrompt = self.checkOptions( self.dockerPrompt, "~/onos#" )
Jon Hall9b0de1f2020-08-24 15:38:04 -070098 self.karafTimeout = self.checkOptions( self.karafTimeout, 7200000 )
andrewonlab95ce8322014-10-13 14:12:04 -040099
Siddesh52750622021-03-05 19:52:03 +0000100 self.karafPrompt = self.karafPromptUser + "@root >"
kelvin-onlaba4074292015-07-09 15:19:49 -0700101 for key in self.options:
102 if key == 'onosIp':
103 self.onosIp = self.options[ 'onosIp' ]
104 break
105
kelvin8ec71442015-01-15 16:57:00 -0800106 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -0700107
108 try:
Jon Hallc6793552016-01-19 14:18:37 -0800109 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -0700110 self.ip_address = os.getenv( str( self.ip_address ) )
111 else:
112 main.log.info( self.name +
113 ": Trying to connect to " +
114 self.ip_address )
115
116 except KeyError:
117 main.log.info( "Invalid host name," +
118 " connecting to local host instead" )
119 self.ip_address = 'localhost'
120 except Exception as inst:
121 main.log.error( "Uncaught exception: " + str( inst ) )
122
kelvin8ec71442015-01-15 16:57:00 -0800123 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -0800124 user_name=self.user_name,
125 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -0800126 port=self.port,
127 pwd=self.pwd,
128 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -0400129
kelvin8ec71442015-01-15 16:57:00 -0800130 self.handle.sendline( "cd " + self.home )
Devin Limdc78e202017-06-09 18:30:07 -0700131 self.handle.expect( self.prompt )
andrewonlab95ce8322014-10-13 14:12:04 -0400132 if self.handle:
Jon Hall06fd0df2021-01-25 15:50:06 -0800133 self.address = self.ip_address
andrewonlab95ce8322014-10-13 14:12:04 -0400134 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800135 else:
136 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -0400137 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800138 except TypeError:
139 main.log.exception( self.name + ": Object not as expected" )
140 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400141 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800142 main.log.error( self.name + ": EOF exception found" )
143 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700144 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800145 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800146 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700147 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400148
kelvin8ec71442015-01-15 16:57:00 -0800149 def disconnect( self ):
150 """
andrewonlab95ce8322014-10-13 14:12:04 -0400151 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800152 """
Jon Halld61331b2015-02-17 16:35:47 -0800153 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400154 try:
Jon Hall61282e32015-03-19 11:34:11 -0700155 if self.handle:
156 i = self.logout()
157 if i == main.TRUE:
158 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700159 for l in range( 3 ):
160 p = self.handle.expect( [ self.prompt, self.dockerPrompt ] )
161 if p == 1:
162 self.inDocker = False
163 self.handle.sendline( "exit" )
164 j = self.handle.expect( [ "closed", pexpect.TIMEOUT ], timeout=3 )
165 if j == 0:
166 return response
167 response = main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800168 except TypeError:
169 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800170 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400171 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800172 main.log.error( self.name + ": EOF exception found" )
173 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700174 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700175 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700176 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800177 except Exception:
Jon Hall3c0114c2020-08-11 15:07:42 -0700178 main.log.exception( self.name + ": disconnection failed from the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400179 response = main.FALSE
180 return response
181
kelvin8ec71442015-01-15 16:57:00 -0800182 def logout( self ):
183 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500184 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700185 Returns main.TRUE if exited CLI and
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000186 main.FALSE on timeout (not guranteed you are disconnected)
Jon Hall61282e32015-03-19 11:34:11 -0700187 None on TypeError
188 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800189 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500190 try:
Jon Hall61282e32015-03-19 11:34:11 -0700191 if self.handle:
192 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700193 i = self.handle.expect( [ self.karafPrompt,
194 self.Prompt(),
195 pexpect.TIMEOUT ],
196
Jon Hall61282e32015-03-19 11:34:11 -0700197 timeout=10 )
198 if i == 0: # In ONOS CLI
199 self.handle.sendline( "logout" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700200 j = self.handle.expect( [ self.Prompt(),
Jon Hallbfe00002016-04-05 10:23:54 -0700201 "Command not found:",
202 pexpect.TIMEOUT ] )
203 if j == 0: # Successfully logged out
204 return main.TRUE
205 elif j == 1 or j == 2:
206 # ONOS didn't fully load, and logout command isn't working
207 # or the command timed out
208 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700209 try:
Jon Hall3c0114c2020-08-11 15:07:42 -0700210 self.handle.expect( self.Prompt() )
Jon Hall64ab3bd2016-05-13 11:29:44 -0700211 except pexpect.TIMEOUT:
212 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700213 return main.TRUE
Jon Halle0f0b342017-04-18 11:43:47 -0700214 else: # some other output
Jon Hallbfe00002016-04-05 10:23:54 -0700215 main.log.warn( "Unknown repsonse to logout command: '{}'",
216 repr( self.handle.before ) )
217 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700218 elif i == 1: # not in CLI
219 return main.TRUE
steven30801e42f1fb2019-01-17 11:31:45 +0800220 elif i == 2: # Timeout
Jon Hall61282e32015-03-19 11:34:11 -0700221 return main.FALSE
222 else:
andrewonlab9627f432014-11-14 12:45:10 -0500223 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800224 except TypeError:
225 main.log.exception( self.name + ": Object not as expected" )
226 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500227 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800228 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700229 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700230 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700231 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700232 main.log.error( self.name +
233 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800234 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800235 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700236 main.cleanAndExit()
andrewonlab38d2b4a2014-11-13 16:28:47 -0500237
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800239 """
andrewonlab95ce8322014-10-13 14:12:04 -0400240 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800241
andrewonlab95ce8322014-10-13 14:12:04 -0400242 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800243 """
andrewonlab95ce8322014-10-13 14:12:04 -0400244 try:
245 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800246 main.log.error( "Must define cellname" )
Devin Lim44075962017-08-11 10:56:37 -0700247 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400248 else:
kelvin8ec71442015-01-15 16:57:00 -0800249 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800250 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800251 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400252 # and that this driver will have to change accordingly
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700253 self.handle.expect( str( cellname ) )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800254 handleBefore = self.handle.before
255 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800256 # Get the rest of the handle
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700257 self.handle.sendline( "" )
258 self.handle.expect( self.prompt )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800259 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400260
kelvin-onlabd3b64892015-01-20 13:26:24 -0800261 main.log.info( "Cell call returned: " + handleBefore +
262 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400263
264 return main.TRUE
265
Jon Halld4d4b372015-01-28 16:02:41 -0800266 except TypeError:
267 main.log.exception( self.name + ": Object not as expected" )
268 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400269 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800270 main.log.error( self.name + ": eof exception found" )
271 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700272 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800273 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800274 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700275 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -0800276
pingping-lin57a56ce2015-05-20 16:43:48 -0700277 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800278 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800279 """
Jon Hallefbd9792015-03-05 16:11:36 -0800280 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800281 by user would be used to set the current karaf shell idle timeout.
282 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800283 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800284 Below is an example to start a session with 60 seconds idle timeout
285 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800286
Hari Krishna25d42f72015-01-05 15:08:28 -0800287 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800288 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800289
kelvin-onlabd3b64892015-01-20 13:26:24 -0800290 Note: karafTimeout is left as str so that this could be read
291 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800292 """
You Wangf69ab392016-01-26 16:34:38 -0800293 self.onosIp = ONOSIp
Jon Hall06fd0df2021-01-25 15:50:06 -0800294 self.address = self.onosIp
andrewonlab95ce8322014-10-13 14:12:04 -0400295 try:
Jon Hall67253832016-12-05 09:47:13 -0800296 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800297 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700298 x = self.handle.expect( [ self.Prompt(), self.karafPrompt ], commandlineTimeout )
andrewonlab48829f62014-11-17 13:49:01 -0500299 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800300 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500301 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400302
Jon Hall67253832016-12-05 09:47:13 -0800303 # Not in CLI so login
Jon Hall3c0114c2020-08-11 15:07:42 -0700304 if self.inDocker:
305 # The Docker does not have all the wrapper scripts
Jon Hall06fd0df2021-01-25 15:50:06 -0800306 startCliCommand = "ssh -p %s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null %s@localhost" % ( self.karafPort, self.karafUser )
Jon Hall3c0114c2020-08-11 15:07:42 -0700307 elif waitForStart:
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800308 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
Jon Hall3c0114c2020-08-11 15:07:42 -0700309 startCliCommand = "onos-wait-for-start " + str( ONOSIp )
Chiyu Chengef109502016-11-21 15:51:38 -0800310 else:
Jon Hall3c0114c2020-08-11 15:07:42 -0700311 startCliCommand = "onos " + str( ONOSIp )
312 self.handle.sendline( startCliCommand )
313 tries = 0
Jon Hallf69e3162020-09-01 09:08:44 -0700314 timeoutSet = False
Jon Hall3c0114c2020-08-11 15:07:42 -0700315 while tries < 5:
316 i = self.handle.expect( [
317 self.karafPrompt,
318 "Password:",
319 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400320
andrewonlab3a7c3c72014-10-24 17:21:03 -0400321 if i == 0:
Jon Hallf69e3162020-09-01 09:08:44 -0700322 if not karafTimeout or timeoutSet:
Jon Hall9b0de1f2020-08-24 15:38:04 -0700323 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
324 return main.TRUE
Hari Krishnae36ef212015-01-04 14:09:13 -0800325 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800326 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800327 "config:property-set -p org.apache.karaf.shell\
Jon Hall3c0114c2020-08-11 15:07:42 -0700328 sshIdleTimeout " +
Jon Hall9b0de1f2020-08-24 15:38:04 -0700329 str( karafTimeout ) )
330 self.handle.expect( "closed by remote host" )
Jon Hallf69e3162020-09-01 09:08:44 -0700331 self.handle.expect( self.Prompt() )
Jon Hall9b0de1f2020-08-24 15:38:04 -0700332 self.handle.sendline( startCliCommand )
Jon Hallf69e3162020-09-01 09:08:44 -0700333 timeoutSet = True
Jon Hall3c0114c2020-08-11 15:07:42 -0700334 elif i == 1:
335 main.log.info( str( ONOSIp ) + " CLI asking for password" )
336 main.log.debug( "Sending %s" % self.karafPass )
337 self.handle.sendline( self.karafPass )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400338 else:
Jon Hall3c0114c2020-08-11 15:07:42 -0700339 # If failed, send ctrl+c to process and try again
340 main.log.info( "Starting CLI failed. Retrying..." )
Jon Hallf69e3162020-09-01 09:08:44 -0700341 time.sleep( 5 )
Jon Hall3c0114c2020-08-11 15:07:42 -0700342 self.handle.send( "\x03" )
343 self.handle.sendline( startCliCommand )
344 tries += 1
345 main.log.error( "Connection to CLI " + str( ONOSIp ) + " timeout" )
346 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800347 except TypeError:
348 main.log.exception( self.name + ": Object not as expected" )
349 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400350 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800351 main.log.error( self.name + ": EOF exception found" )
352 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700353 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800354 except Exception:
Jon Hall06fd0df2021-01-25 15:50:06 -0800355 main.log.debug( self.handle.before + str( self.handle.after ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800356 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700357 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400358
suibin zhang116647a2016-05-06 16:30:09 -0700359 def startCellCli( self, karafTimeout="",
360 commandlineTimeout=10, onosStartTimeout=60 ):
361 """
Jon Hall3c0114c2020-08-11 15:07:42 -0700362 Start CLI on onos cell handle.
suibin zhang116647a2016-05-06 16:30:09 -0700363
364 karafTimeout is an optional argument. karafTimeout value passed
365 by user would be used to set the current karaf shell idle timeout.
366 Note that when ever this property is modified the shell will exit and
367 the subsequent login would reflect new idle timeout.
368 Below is an example to start a session with 60 seconds idle timeout
369 ( input value is in milliseconds ):
370
371 tValue = "60000"
372
373 Note: karafTimeout is left as str so that this could be read
374 and passed to startOnosCli from PARAMS file as str.
375 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000376
suibin zhang116647a2016-05-06 16:30:09 -0700377 try:
378 self.handle.sendline( "" )
379 x = self.handle.expect( [
Jon Hall3c0114c2020-08-11 15:07:42 -0700380 self.Prompt(), self.karafPrompt ], commandlineTimeout )
suibin zhang116647a2016-05-06 16:30:09 -0700381
382 if x == 1:
383 main.log.info( "ONOS cli is already running" )
384 return main.TRUE
385
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800386 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
suibin zhang116647a2016-05-06 16:30:09 -0700387 self.handle.sendline( "/opt/onos/bin/onos" )
388 i = self.handle.expect( [
Jon Hall6c9e2da2018-11-06 12:01:23 -0800389 self.karafPrompt,
suibin zhang116647a2016-05-06 16:30:09 -0700390 pexpect.TIMEOUT ], onosStartTimeout )
391
392 if i == 0:
393 main.log.info( self.name + " CLI Started successfully" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800394 if karafTimeout: # FIXME: This doesn't look right
suibin zhang116647a2016-05-06 16:30:09 -0700395 self.handle.sendline(
396 "config:property-set -p org.apache.karaf.shell\
397 sshIdleTimeout " +
398 karafTimeout )
Jon Hall3c0114c2020-08-11 15:07:42 -0700399 self.handle.expect( self.Prompt() )
suibin zhang116647a2016-05-06 16:30:09 -0700400 self.handle.sendline( "/opt/onos/bin/onos" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800401 self.handle.expect( self.karafPrompt )
suibin zhang116647a2016-05-06 16:30:09 -0700402 return main.TRUE
403 else:
404 # If failed, send ctrl+c to process and try again
405 main.log.info( "Starting CLI failed. Retrying..." )
406 self.handle.send( "\x03" )
407 self.handle.sendline( "/opt/onos/bin/onos" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800408 i = self.handle.expect( [ self.karafPrompt, pexpect.TIMEOUT ],
suibin zhang116647a2016-05-06 16:30:09 -0700409 timeout=30 )
410 if i == 0:
411 main.log.info( self.name + " CLI Started " +
412 "successfully after retry attempt" )
413 if karafTimeout:
414 self.handle.sendline(
415 "config:property-set -p org.apache.karaf.shell\
416 sshIdleTimeout " +
417 karafTimeout )
Jon Hall3c0114c2020-08-11 15:07:42 -0700418 self.handle.expect( self.Prompt() )
suibin zhang116647a2016-05-06 16:30:09 -0700419 self.handle.sendline( "/opt/onos/bin/onos" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800420 self.handle.expect( self.karafPrompt )
suibin zhang116647a2016-05-06 16:30:09 -0700421 return main.TRUE
422 else:
423 main.log.error( "Connection to CLI " +
424 self.name + " timeout" )
425 return main.FALSE
426
427 except TypeError:
428 main.log.exception( self.name + ": Object not as expected" )
429 return None
430 except pexpect.EOF:
431 main.log.error( self.name + ": EOF exception found" )
432 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700433 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700434 except Exception:
435 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700436 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700437
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800438 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800439 """
You Wang22e807e2021-03-29 10:53:38 -0700440 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800441 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800442 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700443 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800444 Available level: DEBUG, TRACE, INFO, WARN, ERROR
445 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800446 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800447 """
448 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800449 lvlStr = ""
450 if level:
451 lvlStr = "--level=" + level
You Wang22e807e2021-03-29 10:53:38 -0700452 handle = self.sendline( "log:log " + lvlStr + " " + cmdStr, noExit=noExit )
453 assert handle is not None, "Error in sendline"
454 assert "Command not found:" not in handle, handle
455 if re.search( "Error", handle ):
456 main.log.error( self.name + ": Error in logging message" )
457 main.log.error( handle )
kelvin-onlab9f541032015-02-04 16:19:53 -0800458 return main.FALSE
YPZhangebf9eb52016-05-12 15:20:24 -0700459 else:
You Wang22e807e2021-03-29 10:53:38 -0700460 return main.TRUE
461 except AssertionError:
462 main.log.exception( "" )
463 return None
464 except TypeError:
465 main.log.exception( self.name + ": Object not as expected" )
466 return None
kelvin-onlab9f541032015-02-04 16:19:53 -0800467 except pexpect.EOF:
468 main.log.error( self.name + ": EOF exception found" )
469 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700470 if noExit:
471 main.cleanup()
472 return None
473 else:
Devin Lim44075962017-08-11 10:56:37 -0700474 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800475 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800476 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700477 if noExit:
478 main.cleanup()
479 return None
480 else:
Devin Lim44075962017-08-11 10:56:37 -0700481 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400482
Jon Hall0e240372018-05-02 11:21:57 -0700483 def clearBuffer( self, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800484 """
Jon Hall0e240372018-05-02 11:21:57 -0700485 Test cli connection and clear any left over output in the buffer
486 Optional Arguments:
487 debug - Defaults to False. If True, will enable debug logging.
488 timeout - Defaults to 10. Amount of time in seconds for a command to return
489 before a timeout.
490 noExit - Defaults to False. If True, will not exit TestON in the event of a
kelvin8ec71442015-01-15 16:57:00 -0800491 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400492 try:
Jon Halla495f562016-05-16 18:03:26 -0700493 # Try to reconnect if disconnected from cli
494 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700495 i = self.handle.expect( [ self.karafPrompt,
496 self.Prompt(),
497 pexpect.TIMEOUT ] )
Jon Hall0e240372018-05-02 11:21:57 -0700498 response = self.handle.before
Jon Halla495f562016-05-16 18:03:26 -0700499 if i == 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700500 main.log.error( self.name + ": onos cli session closed. " )
Jon Halla495f562016-05-16 18:03:26 -0700501 if self.onosIp:
502 main.log.warn( "Trying to reconnect " + self.onosIp )
503 reconnectResult = self.startOnosCli( self.onosIp )
504 if reconnectResult:
505 main.log.info( self.name + ": onos cli session reconnected." )
506 else:
507 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700508 if noExit:
509 return None
510 else:
Devin Lim44075962017-08-11 10:56:37 -0700511 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700512 else:
Devin Lim44075962017-08-11 10:56:37 -0700513 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700514 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700515 main.log.warn( "Timeout when testing cli responsiveness" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700516 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700517 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Hall6c9e2da2018-11-06 12:01:23 -0800518 self.handle.expect( self.karafPrompt )
Jon Halla495f562016-05-16 18:03:26 -0700519
Jon Hall0e240372018-05-02 11:21:57 -0700520 response += self.handle.before
Jon Hall14a03b52016-05-11 12:07:30 -0700521 if debug:
Jon Hall0e240372018-05-02 11:21:57 -0700522 main.log.debug( self.name + ": Raw output from sending ''" )
523 main.log.debug( self.name + ": " + repr( response ) )
524 except pexpect.TIMEOUT:
525 main.log.error( self.name + ": ONOS timeout" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700526 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
You Wang141b43b2018-06-26 16:50:18 -0700527 self.handle.send( "\x03" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800528 self.handle.expect( self.karafPrompt )
Jon Hall0e240372018-05-02 11:21:57 -0700529 return None
530 except pexpect.EOF:
531 main.log.error( self.name + ": EOF exception found" )
532 main.log.error( self.name + ": " + self.handle.before )
533 if noExit:
534 return None
535 else:
536 main.cleanAndExit()
537 except Exception:
538 main.log.exception( self.name + ": Uncaught exception!" )
539 if noExit:
540 return None
541 else:
542 main.cleanAndExit()
543
Jon Hall22e94ce2019-01-15 14:52:17 -0800544 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True, expectJson=False ):
Jon Hall0e240372018-05-02 11:21:57 -0700545 """
546 A wrapper around pexpect's sendline/expect. Will return all the output from a given command
547
548 Required Arguments:
549 cmdStr - String to send to the pexpect session
550
551 Optional Arguments:
552 showResponse - Defaults to False. If True will log the response.
553 debug - Defaults to False. If True, will enable debug logging.
554 timeout - Defaults to 10. Amount of time in seconds for a command to return
555 before a timeout.
556 noExit - Defaults to False. If True, will not exit TestON in the event of a
557 closed channel, but instead return None
Jon Hall6c9e2da2018-11-06 12:01:23 -0800558 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 -0700559
560 Warning: There are no sanity checking to commands sent using this method.
561
562 """
563 try:
564 # Try to reconnect if disconnected from cli
565 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
566 if debug:
567 # NOTE: This adds an average of .4 seconds per call
Jon Hall14a03b52016-05-11 12:07:30 -0700568 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700569 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800570 self.handle.sendline( cmdStr )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800571 self.handle.expect( self.karafPrompt, timeout )
Jon Hall63604932015-02-26 17:09:50 -0800572 response = self.handle.before
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000573 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
Jon Hallc6793552016-01-19 14:18:37 -0800574 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700575 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700576 main.log.debug( self.name + ": Raw output" )
577 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700578
Jon Hall3c0114c2020-08-11 15:07:42 -0700579 response = self.cleanOutput( response, debug=debug )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800580 # Remove control codes from karaf 4.2.1
Jon Hall3c0114c2020-08-11 15:07:42 -0700581 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 -0800582 response = karafEscape.sub( '', response )
583 if debug:
584 main.log.debug( self.name + ": karafEscape output" )
585 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700586 # Remove ANSI color control strings from output
Jon Hall43060f62020-06-23 13:13:33 -0700587 response = self.cleanOutput( response, debug )
Jon Hallc6358dd2015-04-10 12:44:28 -0700588
Jon Hall6c9e2da2018-11-06 12:01:23 -0800589 # Remove ANSI color control strings from output
Jon Hallcf31d0f2018-12-13 11:18:48 -0800590 # NOTE: karaf is sometimes adding a single character then two
591 # backspaces and sometimes adding 2 characters with 2 backspaces??
Jon Hall3c0114c2020-08-11 15:07:42 -0700592 backspaceEscape = re.compile( r'((.|\s)\x08)' )
593 unchanged = False
594 while not unchanged:
595 old = response
596 response = backspaceEscape.sub( '', response, count=1 )
597 if debug:
598 main.log.debug( self.name + ": backspaceEscape output" )
599 main.log.debug( self.name + ": " + repr( response ) )
600 unchanged = old == response
Jon Hall6c9e2da2018-11-06 12:01:23 -0800601
kelvin-onlabfb521662015-02-27 09:52:40 -0800602 # Remove extra return chars that get added
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000603 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700604 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700605 main.log.debug( self.name + ": Removed extra returns " +
606 "from output" )
607 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700608
609 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800610 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700611 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700612 main.log.debug( self.name + ": parsed and stripped output" )
613 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700614
Jon Hall63604932015-02-26 17:09:50 -0800615 # parse for just the output, remove the cmd from response
Jon Hallce0d70b2018-12-11 11:01:32 -0800616 cmdPattern = cmdStr.strip()
617 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
618 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800619 if relaxedRegex:
Jon Hallce0d70b2018-12-11 11:01:32 -0800620 cmdPattern = cmdPattern.split( '|' )[ -1 ].strip()
621 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
622 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800623 # This was added because karaf 4.2 is stripping some characters from the command echo
Jon Hallce0d70b2018-12-11 11:01:32 -0800624 output = response.split( cmdPattern, 1 )
Jon Hall22e94ce2019-01-15 14:52:17 -0800625 if expectJson:
626 main.log.warn( "Relaxed Regex: Searching for a json string amongst the output" )
627 jsonPattern = r'\{.*\}'
628 match = re.search( jsonPattern, output[ 0 ] )
629 if match:
630 output = [ '' , match.group( 0 ) ] # We expect a list with the second element to be the output
Jon Hall39e3ffe2018-12-05 11:40:29 -0800631 if len( output ) < 2:
632 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800633 cmdPattern = cmdPattern[ -5: ]
634 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
635 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
636 output = response.split( cmdPattern, 1 )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800637 else:
Jon Hallce0d70b2018-12-11 11:01:32 -0800638 output = response.split( cmdPattern, 1 )
639 if len( output ) < 2: # TODO: Should we do this without the relaxedRegex flag?
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800640 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800641 output = response.split( cmdPattern[ -5: ], 1 )
Jon Hall0e240372018-05-02 11:21:57 -0700642 if output:
643 if debug:
644 main.log.debug( self.name + ": split output" )
645 for r in output:
646 main.log.debug( self.name + ": " + repr( r ) )
Jon Hallce0d70b2018-12-11 11:01:32 -0800647 if len( output ) == 1:
648 main.log.error( "Could not remove sent command echo from output" )
649 return output
Jon Hall0e240372018-05-02 11:21:57 -0700650 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800651 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800652 main.log.info( "Response from ONOS: {}".format( output ) )
Jon Hall0e240372018-05-02 11:21:57 -0700653 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
GlennRC85870432015-11-23 11:45:51 -0800654 return output
GlennRCed771242016-01-13 17:02:47 -0800655 except pexpect.TIMEOUT:
Jon Hall0e240372018-05-02 11:21:57 -0700656 main.log.error( self.name + ": ONOS timeout" )
GlennRCed771242016-01-13 17:02:47 -0800657 if debug:
Jon Hall3c0114c2020-08-11 15:07:42 -0700658 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
You Wang6b5e5ba2019-01-31 15:32:40 -0800659 self.exitFromCmd( self.karafPrompt, 100 )
GlennRCed771242016-01-13 17:02:47 -0800660 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700661 except IndexError:
662 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700663 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700664 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800665 except TypeError:
666 main.log.exception( self.name + ": Object not as expected" )
667 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400668 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800669 main.log.error( self.name + ": EOF exception found" )
670 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700671 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700672 return None
673 else:
Devin Lim44075962017-08-11 10:56:37 -0700674 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800675 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800676 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700677 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700678 return None
679 else:
Devin Lim44075962017-08-11 10:56:37 -0700680 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400681
Jon Halld5a94fb2018-11-13 14:32:23 -0800682 def lineCount( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True ):
683 """
684 A wrapper around sendline(). Will return the number of lines returned or None on error
685
686 Required Arguments:
687 cmdStr - String to send to the pexpect session
688
689 Optional Arguments:
690 showResponse - Defaults to False. If True will log the response.
691 debug - Defaults to False. If True, will enable debug logging.
692 timeout - Defaults to 10. Amount of time in seconds for a command to return
693 before a timeout.
694 noExit - Defaults to False. If True, will not exit TestON in the event of a
695 closed channel, but instead return None
696 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.
697
698 Warning: There are no sanity checking to commands sent using this method.
699
700 """
701 try:
702 numLines = self.sendline( cmdStr, showResponse, debug, timeout, noExit, relaxedRegex )
You Wang0ce8e0c2019-02-22 12:22:26 -0800703 parsed = re.search( "(\d+)", numLines )
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800704 if not parsed:
705 main.log.error( "Warning, output of karaf's wc may have changed" )
706 return None
707 return parsed.group( 1 )
Jon Halld5a94fb2018-11-13 14:32:23 -0800708 except IndexError:
709 main.log.exception( self.name + ": Object not as expected" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800710 main.log.debug( "response: {}".format( repr( numLines ) ) )
Jon Halld5a94fb2018-11-13 14:32:23 -0800711 return None
712 except TypeError:
713 main.log.exception( self.name + ": Object not as expected" )
714 return None
715 except Exception:
716 main.log.exception( self.name + ": Uncaught exception!" )
717 if noExit:
718 return None
719 else:
720 main.cleanAndExit()
721
kelvin8ec71442015-01-15 16:57:00 -0800722 # IMPORTANT NOTE:
723 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800724 # the cli command changing 'a:b' with 'aB'.
725 # Ex ) onos:topology > onosTopology
726 # onos:links > onosLinks
727 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800728
kelvin-onlabd3b64892015-01-20 13:26:24 -0800729 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800730 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400731 Adds a new cluster node by ID and address information.
732 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800733 * nodeId
734 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400735 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800736 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800737 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400738 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800739 cmdStr = "add-node " + str( nodeId ) + " " +\
740 str( ONOSIp ) + " " + str( tcpPort )
741 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700742 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800743 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800744 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700745 main.log.error( self.name + ": Error in adding node" )
kelvin8ec71442015-01-15 16:57:00 -0800746 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800747 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400748 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800749 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400750 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800751 except AssertionError:
752 main.log.exception( "" )
753 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800754 except TypeError:
755 main.log.exception( self.name + ": Object not as expected" )
756 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400757 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800758 main.log.error( self.name + ": EOF exception found" )
759 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700760 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800761 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800762 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700763 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400764
kelvin-onlabd3b64892015-01-20 13:26:24 -0800765 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800766 """
andrewonlab86dc3082014-10-13 18:18:38 -0400767 Removes a cluster by ID
768 Issues command: 'remove-node [<node-id>]'
769 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800770 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800771 """
andrewonlab86dc3082014-10-13 18:18:38 -0400772 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400773
kelvin-onlabd3b64892015-01-20 13:26:24 -0800774 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700775 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700776 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800777 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700778 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700779 main.log.error( self.name + ": Error in removing node" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700780 main.log.error( handle )
781 return main.FALSE
782 else:
783 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800784 except AssertionError:
785 main.log.exception( "" )
786 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800787 except TypeError:
788 main.log.exception( self.name + ": Object not as expected" )
789 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400790 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800791 main.log.error( self.name + ": EOF exception found" )
792 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700793 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800794 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800795 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700796 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400797
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700798 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800799 """
andrewonlab7c211572014-10-15 16:45:20 -0400800 List the nodes currently visible
801 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700802 Optional argument:
803 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800804 """
andrewonlab7c211572014-10-15 16:45:20 -0400805 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700806 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700807 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700808 cmdStr += " -j"
809 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700810 assert output is not None, "Error in sendline"
Jon Halle37bd1f2020-09-10 12:16:41 -0700811 # "Command not found" or "Service org.onosproject.security.AuditService not found"
812 assert "not found" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700813 return output
Jon Hallc6793552016-01-19 14:18:37 -0800814 except AssertionError:
815 main.log.exception( "" )
816 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800817 except TypeError:
818 main.log.exception( self.name + ": Object not as expected" )
819 return None
andrewonlab7c211572014-10-15 16:45:20 -0400820 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800821 main.log.error( self.name + ": EOF exception found" )
822 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700823 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800824 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800825 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700826 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400827
kelvin8ec71442015-01-15 16:57:00 -0800828 def topology( self ):
829 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700830 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700831 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700832 Return:
833 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800834 """
andrewonlab95ce8322014-10-13 14:12:04 -0400835 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700836 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800837 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800838 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800839 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700840 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400841 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800842 except AssertionError:
843 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800844 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800845 except TypeError:
846 main.log.exception( self.name + ": Object not as expected" )
847 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400848 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800849 main.log.error( self.name + ": EOF exception found" )
850 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700851 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800852 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800853 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700854 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800855
jenkins7ead5a82015-03-13 10:28:21 -0700856 def deviceRemove( self, deviceId ):
857 """
858 Removes particular device from storage
859
860 TODO: refactor this function
861 """
862 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700863 cmdStr = "device-remove " + str( deviceId )
864 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800865 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800866 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700867 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700868 main.log.error( self.name + ": Error in removing device" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700869 main.log.error( handle )
870 return main.FALSE
871 else:
872 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800873 except AssertionError:
874 main.log.exception( "" )
875 return None
jenkins7ead5a82015-03-13 10:28:21 -0700876 except TypeError:
877 main.log.exception( self.name + ": Object not as expected" )
878 return None
879 except pexpect.EOF:
880 main.log.error( self.name + ": EOF exception found" )
881 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700882 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700883 except Exception:
884 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700885 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700886
You Wang3b9689a2018-08-30 12:24:00 -0700887 def devices( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800888 """
Jon Hall7b02d952014-10-17 20:14:54 -0400889 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400890 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800891 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800892 """
andrewonlab86dc3082014-10-13 18:18:38 -0400893 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700894 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800895 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700896 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700897 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800898 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800899 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700900 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800901 except AssertionError:
902 main.log.exception( "" )
903 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800904 except TypeError:
905 main.log.exception( self.name + ": Object not as expected" )
906 return None
andrewonlab7c211572014-10-15 16:45:20 -0400907 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800908 main.log.error( self.name + ": EOF exception found" )
909 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700910 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800911 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800912 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700913 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400914
kelvin-onlabd3b64892015-01-20 13:26:24 -0800915 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800916 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800917 This balances the devices across all controllers
918 by issuing command: 'onos> onos:balance-masters'
919 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800920 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800921 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800922 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700923 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800924 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800925 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700926 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700927 main.log.error( self.name + ": Error in balancing masters" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700928 main.log.error( handle )
929 return main.FALSE
930 else:
931 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800932 except AssertionError:
933 main.log.exception( "" )
934 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800935 except TypeError:
936 main.log.exception( self.name + ": Object not as expected" )
937 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800938 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800939 main.log.error( self.name + ": EOF exception found" )
940 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700941 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800942 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800943 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700944 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800945
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000946 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700947 """
948 Returns the output of the masters command.
949 Optional argument:
950 * jsonFormat - boolean indicating if you want output in json
951 """
952 try:
953 cmdStr = "onos:masters"
954 if jsonFormat:
955 cmdStr += " -j"
956 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700957 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800958 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700959 return output
Jon Hallc6793552016-01-19 14:18:37 -0800960 except AssertionError:
961 main.log.exception( "" )
962 return None
acsmars24950022015-07-30 18:00:43 -0700963 except TypeError:
964 main.log.exception( self.name + ": Object not as expected" )
965 return None
966 except pexpect.EOF:
967 main.log.error( self.name + ": EOF exception found" )
968 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700969 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700970 except Exception:
971 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700972 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700973
Jon Hallc6793552016-01-19 14:18:37 -0800974 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700975 """
976 Uses the master command to check that the devices' leadership
977 is evenly divided
978
979 Dependencies: checkMasters() and summary()
980
Jon Hall6509dbf2016-06-21 17:01:17 -0700981 Returns main.TRUE if the devices are balanced
982 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700983 Exits on Exception
984 Returns None on TypeError
985 """
986 try:
Jon Hallc6793552016-01-19 14:18:37 -0800987 summaryOutput = self.summary()
988 totalDevices = json.loads( summaryOutput )[ "devices" ]
989 except ( TypeError, ValueError ):
990 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
991 return None
992 try:
acsmars24950022015-07-30 18:00:43 -0700993 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800994 mastersOutput = self.checkMasters()
995 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700996 first = masters[ 0 ][ "size" ]
997 for master in masters:
998 totalOwnedDevices += master[ "size" ]
999 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
1000 main.log.error( "Mastership not balanced" )
1001 main.log.info( "\n" + self.checkMasters( False ) )
1002 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -07001003 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001004 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -07001005 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001006 except ( TypeError, ValueError ):
1007 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -07001008 return None
1009 except pexpect.EOF:
1010 main.log.error( self.name + ": EOF exception found" )
1011 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001012 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -07001013 except Exception:
1014 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001015 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -07001016
YPZhangfebf7302016-05-24 16:45:56 -07001017 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -08001018 """
Jon Halle8217482014-10-17 13:49:14 -04001019 Lists all core links
1020 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001021 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001022 """
Jon Halle8217482014-10-17 13:49:14 -04001023 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001024 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001025 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001026 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07001027 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001028 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001029 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001030 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001031 except AssertionError:
1032 main.log.exception( "" )
1033 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001034 except TypeError:
1035 main.log.exception( self.name + ": Object not as expected" )
1036 return None
Jon Halle8217482014-10-17 13:49:14 -04001037 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001038 main.log.error( self.name + ": EOF exception found" )
1039 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001040 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001041 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001042 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001043 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001044
You Wang3b9689a2018-08-30 12:24:00 -07001045 def ports( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -08001046 """
Jon Halle8217482014-10-17 13:49:14 -04001047 Lists all ports
1048 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001049 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001050 """
Jon Halle8217482014-10-17 13:49:14 -04001051 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001052 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001054 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -07001055 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001056 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001057 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001058 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001059 except AssertionError:
1060 main.log.exception( "" )
1061 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001062 except TypeError:
1063 main.log.exception( self.name + ": Object not as expected" )
1064 return None
Jon Halle8217482014-10-17 13:49:14 -04001065 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001066 main.log.error( self.name + ": EOF exception found" )
1067 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001068 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001069 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001070 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001071 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001072
kelvin-onlabd3b64892015-01-20 13:26:24 -08001073 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001074 """
Jon Hall983a1702014-10-28 18:44:22 -04001075 Lists all devices and the controllers with roles assigned to them
1076 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001077 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001078 """
andrewonlab7c211572014-10-15 16:45:20 -04001079 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001080 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001081 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001082 cmdStr += " -j"
1083 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001084 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001085 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001086 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001087 except AssertionError:
1088 main.log.exception( "" )
1089 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001090 except TypeError:
1091 main.log.exception( self.name + ": Object not as expected" )
1092 return None
Jon Hall983a1702014-10-28 18:44:22 -04001093 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001094 main.log.error( self.name + ": EOF exception found" )
1095 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001096 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001097 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001098 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001099 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -04001100
kelvin-onlabd3b64892015-01-20 13:26:24 -08001101 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001102 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001103 Given the a string containing the json representation of the "roles"
1104 cli command and a partial or whole device id, returns a json object
1105 containing the roles output for the first device whose id contains
1106 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -04001107
1108 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -08001109 A dict of the role assignments for the given device or
1110 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001111 """
Jon Hall983a1702014-10-28 18:44:22 -04001112 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001113 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001114 return None
1115 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001116 rawRoles = self.roles()
1117 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001118 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001120 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001121 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001122 return device
1123 return None
Jon Hallc6793552016-01-19 14:18:37 -08001124 except ( TypeError, ValueError ):
1125 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001126 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001127 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001128 main.log.error( self.name + ": EOF exception found" )
1129 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001130 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001131 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001132 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001133 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001134
kelvin-onlabd3b64892015-01-20 13:26:24 -08001135 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001136 """
Jon Hall94fd0472014-12-08 11:52:42 -08001137 Iterates through each device and checks if there is a master assigned
1138 Returns: main.TRUE if each device has a master
1139 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001140 """
Jon Hall94fd0472014-12-08 11:52:42 -08001141 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001142 rawRoles = self.roles()
1143 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001144 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001145 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001146 # print device
1147 if device[ 'master' ] == "none":
1148 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001149 return main.FALSE
1150 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001151 except ( TypeError, ValueError ):
1152 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001153 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001154 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001155 main.log.error( self.name + ": EOF exception found" )
1156 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001157 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001158 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001159 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001160 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001161
kelvin-onlabd3b64892015-01-20 13:26:24 -08001162 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001163 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001164 Returns string of paths, and the cost.
1165 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001166 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001167 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001168 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1169 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001170 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001171 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001172 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001173 main.log.error( self.name + ": Error in getting paths" )
kelvin8ec71442015-01-15 16:57:00 -08001174 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001175 else:
kelvin8ec71442015-01-15 16:57:00 -08001176 path = handle.split( ";" )[ 0 ]
1177 cost = handle.split( ";" )[ 1 ]
1178 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001179 except AssertionError:
1180 main.log.exception( "" )
1181 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001182 except TypeError:
1183 main.log.exception( self.name + ": Object not as expected" )
1184 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001185 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001186 main.log.error( self.name + ": EOF exception found" )
1187 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001188 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001189 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001190 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001191 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001192
kelvin-onlabd3b64892015-01-20 13:26:24 -08001193 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001194 """
Jon Hallffb386d2014-11-21 13:43:38 -08001195 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001196 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001197 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001198 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001199 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001200 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001201 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001202 cmdStr += " -j"
1203 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001204 if handle:
1205 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001206 # TODO: Maybe make this less hardcoded
1207 # ConsistentMap Exceptions
1208 assert "org.onosproject.store.service" not in handle
1209 # Node not leader
1210 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001211 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001212 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07001213 main.log.exception( self.name + ": Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001214 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001215 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001216 except TypeError:
1217 main.log.exception( self.name + ": Object not as expected" )
1218 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001219 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001220 main.log.error( self.name + ": EOF exception found" )
1221 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001222 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001223 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001224 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001225 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001226
kelvin-onlabd3b64892015-01-20 13:26:24 -08001227 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001228 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001229 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001230
Jon Hallefbd9792015-03-05 16:11:36 -08001231 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001232 partial mac address
1233
Jon Hall42db6dc2014-10-24 19:03:48 -04001234 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001235 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001236 try:
kelvin8ec71442015-01-15 16:57:00 -08001237 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001238 return None
1239 else:
1240 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001241 rawHosts = self.hosts()
1242 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001243 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001244 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001245 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001246 if not host:
1247 pass
1248 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001249 return host
1250 return None
Jon Hallc6793552016-01-19 14:18:37 -08001251 except ( TypeError, ValueError ):
1252 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001253 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001254 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001255 main.log.error( self.name + ": EOF exception found" )
1256 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001257 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001258 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001259 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001260 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001261
kelvin-onlabd3b64892015-01-20 13:26:24 -08001262 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001263 """
1264 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001265 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001266
andrewonlab3f0a4af2014-10-17 12:25:14 -04001267 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001268 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001269 IMPORTANT:
1270 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001271 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001272 Furthermore, it assumes that value of VLAN is '-1'
1273 Description:
kelvin8ec71442015-01-15 16:57:00 -08001274 Converts mininet hosts ( h1, h2, h3... ) into
1275 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1276 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001277 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001278 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001279
kelvin-onlabd3b64892015-01-20 13:26:24 -08001280 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001281 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001282 hostHex = hex( int( host ) ).zfill( 12 )
1283 hostHex = str( hostHex ).replace( 'x', '0' )
1284 i = iter( str( hostHex ) )
1285 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1286 hostHex = hostHex + "/-1"
1287 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001288
kelvin-onlabd3b64892015-01-20 13:26:24 -08001289 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001290
Jon Halld4d4b372015-01-28 16:02:41 -08001291 except TypeError:
1292 main.log.exception( self.name + ": Object not as expected" )
1293 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001294 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001295 main.log.error( self.name + ": EOF exception found" )
1296 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001297 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001298 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001299 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001300 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001301
You Wangbc898b82018-05-03 16:22:34 -07001302 def verifyHostLocation( self, hostIp, location ):
1303 """
1304 Description:
1305 Verify the host given is discovered in all locations expected
1306 Required:
1307 hostIp: IP address of the host
1308 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1309 Could be a string or list
1310 Returns:
1311 main.TRUE if host is discovered on all locations provided
1312 main.FALSE otherwise
1313 """
You Wangbc898b82018-05-03 16:22:34 -07001314 locations = [ location ] if isinstance( location, str ) else location
1315 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1316 try:
1317 hosts = self.hosts()
1318 hosts = json.loads( hosts )
1319 targetHost = None
1320 for host in hosts:
1321 if hostIp in host[ "ipAddresses" ]:
1322 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001323 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001324 result = main.TRUE
1325 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1326 for loc in locations:
1327 discovered = False
1328 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001329 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1330 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001331 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001332 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001333 break
1334 if discovered:
1335 locationsDiscovered.remove( locDiscovered )
1336 else:
1337 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1338 result = main.FALSE
1339 if locationsDiscovered:
1340 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1341 result = main.FALSE
1342 return result
1343 except KeyError:
1344 main.log.exception( self.name + ": host data not as expected: " + hosts )
1345 return None
1346 except pexpect.EOF:
1347 main.log.error( self.name + ": EOF exception found" )
1348 main.log.error( self.name + ": " + self.handle.before )
1349 main.cleanAndExit()
1350 except Exception:
1351 main.log.exception( self.name + ": Uncaught exception" )
1352 return None
1353
Siddesh715a9192021-11-03 19:51:20 +00001354 def verifyHostIp( self, hostList=[], prefix="", prefixLength=24 ):
You Wang53dba1e2018-02-02 17:45:44 -08001355 """
1356 Description:
1357 Verify that all hosts have IP address assigned to them
1358 Optional:
1359 hostList: If specified, verifications only happen to the hosts
1360 in hostList
1361 prefix: at least one of the ip address assigned to the host
1362 needs to have the specified prefix
1363 Returns:
1364 main.TRUE if all hosts have specific IP address assigned;
1365 main.FALSE otherwise
1366 """
You Wang53dba1e2018-02-02 17:45:44 -08001367 try:
1368 hosts = self.hosts()
Siddesh715a9192021-11-03 19:51:20 +00001369 hosts = json.loads( hosts, "utf-8" )
You Wang53dba1e2018-02-02 17:45:44 -08001370 if not hostList:
1371 hostList = [ host[ "id" ] for host in hosts ]
Siddesh715a9192021-11-03 19:51:20 +00001372 hostList = [ str( h.lower() ) for h in hostList ]
You Wang53dba1e2018-02-02 17:45:44 -08001373 for host in hosts:
1374 hostId = host[ "id" ]
Siddesh715a9192021-11-03 19:51:20 +00001375 hostId = str( hostId.lower() )
1376 match = False
1377 for onosHostId in hostList:
1378 if onosHostId == hostId:
1379 match = True
1380 if not match:
You Wang53dba1e2018-02-02 17:45:44 -08001381 continue
1382 ipList = host[ "ipAddresses" ]
1383 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1384 if not ipList:
1385 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1386 else:
Siddesh715a9192021-11-03 19:51:20 +00001387 # if no hostIp in subnet: Get warning otherwise remove hostId from hostList
1388 subnetString = u"%s/%s" % (prefix, prefixLength)
1389 subnet = ipaddress.ip_network( subnetString, strict=False )
1390 if not any( ipaddress.ip_address( ip ) in subnet for ip in ipList ):
You Wang53dba1e2018-02-02 17:45:44 -08001391 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1392 else:
1393 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1394 hostList.remove( hostId )
1395 if hostList:
1396 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
Jon Hall43060f62020-06-23 13:13:33 -07001397 # Print info for debugging
1398 main.log.debug( self.name + ": hosts output: " + str( hosts ) )
You Wang53dba1e2018-02-02 17:45:44 -08001399 return main.FALSE
1400 else:
1401 return main.TRUE
1402 except KeyError:
1403 main.log.exception( self.name + ": host data not as expected: " + hosts )
1404 return None
1405 except pexpect.EOF:
1406 main.log.error( self.name + ": EOF exception found" )
1407 main.log.error( self.name + ": " + self.handle.before )
1408 main.cleanAndExit()
1409 except Exception:
1410 main.log.exception( self.name + ": Uncaught exception" )
1411 return None
1412
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001413 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001414 """
andrewonlabe6745342014-10-17 14:29:13 -04001415 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001416 * hostIdOne: ONOS host id for host1
1417 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001418 Optional:
1419 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001420 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001421 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001422 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001423 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001424 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001425 Returns:
1426 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001427 """
andrewonlabe6745342014-10-17 14:29:13 -04001428 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001429 cmdStr = "add-host-intent "
1430 if vlanId:
1431 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001432 if setVlan:
1433 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001434 if encap:
1435 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001436 if bandwidth:
1437 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001438 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001439 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001440 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001441 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001442 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001443 main.log.error( self.name + ": Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001444 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001445 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001446 else:
1447 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001448 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001449 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001450 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001451 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001452 else:
1453 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001454 main.log.debug( "Response from ONOS was: " +
1455 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001456 return None
Jon Hallc6793552016-01-19 14:18:37 -08001457 except AssertionError:
1458 main.log.exception( "" )
1459 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001460 except TypeError:
1461 main.log.exception( self.name + ": Object not as expected" )
1462 return None
andrewonlabe6745342014-10-17 14:29:13 -04001463 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001464 main.log.error( self.name + ": EOF exception found" )
1465 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001466 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001467 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001468 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001469 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001470
kelvin-onlabd3b64892015-01-20 13:26:24 -08001471 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001472 """
andrewonlab7b31d232014-10-24 13:31:47 -04001473 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001474 * ingressDevice: device id of ingress device
1475 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001476 Optional:
1477 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001478 Description:
1479 Adds an optical intent by specifying an ingress and egress device
1480 Returns:
1481 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001482 """
andrewonlab7b31d232014-10-24 13:31:47 -04001483 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001484 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1485 " " + str( egressDevice )
1486 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001487 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001488 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001489 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001490 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001491 main.log.error( self.name + ": Error in adding Optical intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001492 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001493 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001494 main.log.info( "Optical intent installed between " +
1495 str( ingressDevice ) + " and " +
1496 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001497 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001498 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001499 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001500 else:
1501 main.log.error( "Error, intent ID not found" )
1502 return None
Jon Hallc6793552016-01-19 14:18:37 -08001503 except AssertionError:
1504 main.log.exception( "" )
1505 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001506 except TypeError:
1507 main.log.exception( self.name + ": Object not as expected" )
1508 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001509 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001510 main.log.error( self.name + ": EOF exception found" )
1511 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001512 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001513 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001514 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001515 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001516
kelvin-onlabd3b64892015-01-20 13:26:24 -08001517 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001518 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001519 ingressDevice,
1520 egressDevice,
1521 portIngress="",
1522 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001523 ethType="",
1524 ethSrc="",
1525 ethDst="",
1526 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001527 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001528 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001529 ipProto="",
1530 ipSrc="",
1531 ipDst="",
1532 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001533 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001534 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001535 setVlan="",
1536 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001537 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001538 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001539 * ingressDevice: device id of ingress device
1540 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001541 Optional:
1542 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001543 * ethSrc: specify ethSrc ( i.e. src mac addr )
1544 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001545 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001546 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001547 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001548 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001549 * ipSrc: specify ip source address
1550 * ipDst: specify ip destination address
1551 * tcpSrc: specify tcp source port
1552 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001553 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001554 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001555 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001556 Description:
kelvin8ec71442015-01-15 16:57:00 -08001557 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001558 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001559 Returns:
1560 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001561
Jon Halle3f39ff2015-01-13 11:50:53 -08001562 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001563 options developers provide for point-to-point
1564 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001565 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001566 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001567 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001568
Jeremy Songsterff553672016-05-12 17:06:23 -07001569 if ethType:
1570 cmd += " --ethType " + str( ethType )
1571 if ethSrc:
1572 cmd += " --ethSrc " + str( ethSrc )
1573 if ethDst:
1574 cmd += " --ethDst " + str( ethDst )
1575 if bandwidth:
1576 cmd += " --bandwidth " + str( bandwidth )
1577 if lambdaAlloc:
1578 cmd += " --lambda "
1579 if ipProto:
1580 cmd += " --ipProto " + str( ipProto )
1581 if ipSrc:
1582 cmd += " --ipSrc " + str( ipSrc )
1583 if ipDst:
1584 cmd += " --ipDst " + str( ipDst )
1585 if tcpSrc:
1586 cmd += " --tcpSrc " + str( tcpSrc )
1587 if tcpDst:
1588 cmd += " --tcpDst " + str( tcpDst )
1589 if vlanId:
1590 cmd += " -v " + str( vlanId )
1591 if setVlan:
1592 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001593 if encap:
1594 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001595 if protected:
1596 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001597
kelvin8ec71442015-01-15 16:57:00 -08001598 # Check whether the user appended the port
1599 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001600 if "/" in ingressDevice:
1601 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001602 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001603 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001604 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001605 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001606 # Would it make sense to throw an exception and exit
1607 # the test?
1608 return None
andrewonlab36af3822014-11-18 17:48:18 -05001609
kelvin8ec71442015-01-15 16:57:00 -08001610 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001611 str( ingressDevice ) + "/" +\
1612 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001613
kelvin-onlabd3b64892015-01-20 13:26:24 -08001614 if "/" in egressDevice:
1615 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001616 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001617 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001618 main.log.error( "You must specify the egress port" )
1619 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001620
kelvin8ec71442015-01-15 16:57:00 -08001621 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001622 str( egressDevice ) + "/" +\
1623 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001624
kelvin-onlab898a6c62015-01-16 14:13:53 -08001625 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001626 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001627 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001628 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001629 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001630 main.log.error( self.name + ": Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001631 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001632 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001633 # TODO: print out all the options in this message?
1634 main.log.info( "Point-to-point intent installed between " +
1635 str( ingressDevice ) + " and " +
1636 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001637 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001638 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001639 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001640 else:
1641 main.log.error( "Error, intent ID not found" )
1642 return None
Jon Hallc6793552016-01-19 14:18:37 -08001643 except AssertionError:
1644 main.log.exception( "" )
1645 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001646 except TypeError:
1647 main.log.exception( self.name + ": Object not as expected" )
1648 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001649 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001650 main.log.error( self.name + ": EOF exception found" )
1651 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001652 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001653 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001654 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001655 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001656
kelvin-onlabd3b64892015-01-20 13:26:24 -08001657 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001658 self,
shahshreyac2f97072015-03-19 17:04:29 -07001659 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001660 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001661 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001662 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001663 ethType="",
1664 ethSrc="",
1665 ethDst="",
1666 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001667 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001668 ipProto="",
1669 ipSrc="",
1670 ipDst="",
1671 tcpSrc="",
1672 tcpDst="",
1673 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001674 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001675 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001676 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001677 partial=False,
1678 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001679 """
shahshreyad0c80432014-12-04 16:56:05 -08001680 Note:
shahshreya70622b12015-03-19 17:19:00 -07001681 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001682 is same. That is, all ingress devices include port numbers
1683 with a "/" or all ingress devices could specify device
1684 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001685 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001686 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001687 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001688 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001689 Optional:
1690 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001691 * ethSrc: specify ethSrc ( i.e. src mac addr )
1692 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001693 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001694 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001695 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001696 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001697 * ipSrc: specify ip source address
1698 * ipDst: specify ip destination address
1699 * tcpSrc: specify tcp source port
1700 * tcpDst: specify tcp destination port
1701 * setEthSrc: action to Rewrite Source MAC Address
1702 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001703 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001704 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001705 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001706 Description:
kelvin8ec71442015-01-15 16:57:00 -08001707 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001708 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001709 Returns:
1710 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001711
Jon Halle3f39ff2015-01-13 11:50:53 -08001712 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001713 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001714 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001715 """
shahshreyad0c80432014-12-04 16:56:05 -08001716 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001717 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001718
Jeremy Songsterff553672016-05-12 17:06:23 -07001719 if ethType:
1720 cmd += " --ethType " + str( ethType )
1721 if ethSrc:
1722 cmd += " --ethSrc " + str( ethSrc )
1723 if ethDst:
1724 cmd += " --ethDst " + str( ethDst )
1725 if bandwidth:
1726 cmd += " --bandwidth " + str( bandwidth )
1727 if lambdaAlloc:
1728 cmd += " --lambda "
1729 if ipProto:
1730 cmd += " --ipProto " + str( ipProto )
1731 if ipSrc:
1732 cmd += " --ipSrc " + str( ipSrc )
1733 if ipDst:
1734 cmd += " --ipDst " + str( ipDst )
1735 if tcpSrc:
1736 cmd += " --tcpSrc " + str( tcpSrc )
1737 if tcpDst:
1738 cmd += " --tcpDst " + str( tcpDst )
1739 if setEthSrc:
1740 cmd += " --setEthSrc " + str( setEthSrc )
1741 if setEthDst:
1742 cmd += " --setEthDst " + str( setEthDst )
1743 if vlanId:
1744 cmd += " -v " + str( vlanId )
1745 if setVlan:
1746 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001747 if partial:
1748 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001749 if encap:
1750 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001751
kelvin8ec71442015-01-15 16:57:00 -08001752 # Check whether the user appended the port
1753 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001754
1755 if portIngressList is None:
1756 for ingressDevice in ingressDeviceList:
1757 if "/" in ingressDevice:
1758 cmd += " " + str( ingressDevice )
1759 else:
1760 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001761 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001762 # TODO: perhaps more meaningful return
1763 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001764 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001765 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001766 for ingressDevice, portIngress in zip( ingressDeviceList,
1767 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001768 cmd += " " + \
1769 str( ingressDevice ) + "/" +\
1770 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001771 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001772 main.log.error( "Device list and port list does not " +
1773 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001774 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001775 if "/" in egressDevice:
1776 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001777 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001778 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001779 main.log.error( "You must specify " +
1780 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001781 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001782
kelvin8ec71442015-01-15 16:57:00 -08001783 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001784 str( egressDevice ) + "/" +\
1785 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001786 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001787 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001788 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001789 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001790 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001791 main.log.error( self.name + ": Error in adding multipoint-to-singlepoint " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001792 "intent" )
1793 return None
shahshreyad0c80432014-12-04 16:56:05 -08001794 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001795 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001796 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001797 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001798 else:
1799 main.log.error( "Error, intent ID not found" )
1800 return None
Jon Hallc6793552016-01-19 14:18:37 -08001801 except AssertionError:
1802 main.log.exception( "" )
1803 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001804 except TypeError:
1805 main.log.exception( self.name + ": Object not as expected" )
1806 return None
1807 except pexpect.EOF:
1808 main.log.error( self.name + ": EOF exception found" )
1809 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001810 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001811 except Exception:
1812 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001813 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001814
1815 def addSinglepointToMultipointIntent(
1816 self,
1817 ingressDevice,
1818 egressDeviceList,
1819 portIngress="",
1820 portEgressList=None,
1821 ethType="",
1822 ethSrc="",
1823 ethDst="",
1824 bandwidth="",
1825 lambdaAlloc=False,
1826 ipProto="",
1827 ipSrc="",
1828 ipDst="",
1829 tcpSrc="",
1830 tcpDst="",
1831 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001832 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001833 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001834 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001835 partial=False,
1836 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001837 """
1838 Note:
1839 This function assumes the format of all egress devices
1840 is same. That is, all egress devices include port numbers
1841 with a "/" or all egress devices could specify device
1842 ids and port numbers seperately.
1843 Required:
1844 * EgressDeviceList: List of device ids of egress device
1845 ( Atleast 2 eress devices required in the list )
1846 * ingressDevice: device id of ingress device
1847 Optional:
1848 * ethType: specify ethType
1849 * ethSrc: specify ethSrc ( i.e. src mac addr )
1850 * ethDst: specify ethDst ( i.e. dst mac addr )
1851 * bandwidth: specify bandwidth capacity of link
1852 * lambdaAlloc: if True, intent will allocate lambda
1853 for the specified intent
1854 * ipProto: specify ip protocol
1855 * ipSrc: specify ip source address
1856 * ipDst: specify ip destination address
1857 * tcpSrc: specify tcp source port
1858 * tcpDst: specify tcp destination port
1859 * setEthSrc: action to Rewrite Source MAC Address
1860 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001861 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001862 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001863 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001864 Description:
1865 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1866 specifying device id's and optional fields
1867 Returns:
1868 A string of the intent id or None on error
1869
1870 NOTE: This function may change depending on the
1871 options developers provide for singlepoint-to-multipoint
1872 intent via cli
1873 """
1874 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001875 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001876
Jeremy Songsterff553672016-05-12 17:06:23 -07001877 if ethType:
1878 cmd += " --ethType " + str( ethType )
1879 if ethSrc:
1880 cmd += " --ethSrc " + str( ethSrc )
1881 if ethDst:
1882 cmd += " --ethDst " + str( ethDst )
1883 if bandwidth:
1884 cmd += " --bandwidth " + str( bandwidth )
1885 if lambdaAlloc:
1886 cmd += " --lambda "
1887 if ipProto:
1888 cmd += " --ipProto " + str( ipProto )
1889 if ipSrc:
1890 cmd += " --ipSrc " + str( ipSrc )
1891 if ipDst:
1892 cmd += " --ipDst " + str( ipDst )
1893 if tcpSrc:
1894 cmd += " --tcpSrc " + str( tcpSrc )
1895 if tcpDst:
1896 cmd += " --tcpDst " + str( tcpDst )
1897 if setEthSrc:
1898 cmd += " --setEthSrc " + str( setEthSrc )
1899 if setEthDst:
1900 cmd += " --setEthDst " + str( setEthDst )
1901 if vlanId:
1902 cmd += " -v " + str( vlanId )
1903 if setVlan:
1904 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001905 if partial:
1906 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001907 if encap:
1908 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001909
1910 # Check whether the user appended the port
1911 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001912
kelvin-onlabb9408212015-04-01 13:34:04 -07001913 if "/" in ingressDevice:
1914 cmd += " " + str( ingressDevice )
1915 else:
1916 if not portIngress:
1917 main.log.error( "You must specify " +
1918 "the Ingress port" )
1919 return main.FALSE
1920
1921 cmd += " " +\
1922 str( ingressDevice ) + "/" +\
1923 str( portIngress )
1924
1925 if portEgressList is None:
1926 for egressDevice in egressDeviceList:
1927 if "/" in egressDevice:
1928 cmd += " " + str( egressDevice )
1929 else:
1930 main.log.error( "You must specify " +
1931 "the egress port" )
1932 # TODO: perhaps more meaningful return
1933 return main.FALSE
1934 else:
1935 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001936 for egressDevice, portEgress in zip( egressDeviceList,
1937 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001938 cmd += " " + \
1939 str( egressDevice ) + "/" +\
1940 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001941 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001942 main.log.error( "Device list and port list does not " +
1943 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001944 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001945 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001946 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001947 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001948 # If error, return error message
1949 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001950 main.log.error( self.name + ": Error in adding singlepoint-to-multipoint " +
kelvin-onlabb9408212015-04-01 13:34:04 -07001951 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001952 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001953 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001954 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001955 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001956 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001957 else:
1958 main.log.error( "Error, intent ID not found" )
1959 return None
Jon Hallc6793552016-01-19 14:18:37 -08001960 except AssertionError:
1961 main.log.exception( "" )
1962 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001963 except TypeError:
1964 main.log.exception( self.name + ": Object not as expected" )
1965 return None
shahshreyad0c80432014-12-04 16:56:05 -08001966 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001967 main.log.error( self.name + ": EOF exception found" )
1968 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001969 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001970 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001971 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001972 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001973
Hari Krishna9e232602015-04-13 17:29:08 -07001974 def addMplsIntent(
1975 self,
1976 ingressDevice,
1977 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001978 ingressPort="",
1979 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001980 ethType="",
1981 ethSrc="",
1982 ethDst="",
1983 bandwidth="",
1984 lambdaAlloc=False,
1985 ipProto="",
1986 ipSrc="",
1987 ipDst="",
1988 tcpSrc="",
1989 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001990 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001991 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001992 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001993 """
1994 Required:
1995 * ingressDevice: device id of ingress device
1996 * egressDevice: device id of egress device
1997 Optional:
1998 * ethType: specify ethType
1999 * ethSrc: specify ethSrc ( i.e. src mac addr )
2000 * ethDst: specify ethDst ( i.e. dst mac addr )
2001 * bandwidth: specify bandwidth capacity of link
2002 * lambdaAlloc: if True, intent will allocate lambda
2003 for the specified intent
2004 * ipProto: specify ip protocol
2005 * ipSrc: specify ip source address
2006 * ipDst: specify ip destination address
2007 * tcpSrc: specify tcp source port
2008 * tcpDst: specify tcp destination port
2009 * ingressLabel: Ingress MPLS label
2010 * egressLabel: Egress MPLS label
2011 Description:
2012 Adds MPLS intent by
2013 specifying device id's and optional fields
2014 Returns:
2015 A string of the intent id or None on error
2016
2017 NOTE: This function may change depending on the
2018 options developers provide for MPLS
2019 intent via cli
2020 """
2021 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07002022 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07002023
Jeremy Songsterff553672016-05-12 17:06:23 -07002024 if ethType:
2025 cmd += " --ethType " + str( ethType )
2026 if ethSrc:
2027 cmd += " --ethSrc " + str( ethSrc )
2028 if ethDst:
2029 cmd += " --ethDst " + str( ethDst )
2030 if bandwidth:
2031 cmd += " --bandwidth " + str( bandwidth )
2032 if lambdaAlloc:
2033 cmd += " --lambda "
2034 if ipProto:
2035 cmd += " --ipProto " + str( ipProto )
2036 if ipSrc:
2037 cmd += " --ipSrc " + str( ipSrc )
2038 if ipDst:
2039 cmd += " --ipDst " + str( ipDst )
2040 if tcpSrc:
2041 cmd += " --tcpSrc " + str( tcpSrc )
2042 if tcpDst:
2043 cmd += " --tcpDst " + str( tcpDst )
2044 if ingressLabel:
2045 cmd += " --ingressLabel " + str( ingressLabel )
2046 if egressLabel:
2047 cmd += " --egressLabel " + str( egressLabel )
2048 if priority:
2049 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07002050
2051 # Check whether the user appended the port
2052 # or provided it as an input
2053 if "/" in ingressDevice:
2054 cmd += " " + str( ingressDevice )
2055 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002056 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002057 main.log.error( "You must specify the ingress port" )
2058 return None
2059
2060 cmd += " " + \
2061 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002062 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07002063
2064 if "/" in egressDevice:
2065 cmd += " " + str( egressDevice )
2066 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002067 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002068 main.log.error( "You must specify the egress port" )
2069 return None
2070
2071 cmd += " " +\
2072 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002073 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07002074
2075 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08002076 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002077 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07002078 # If error, return error message
2079 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002080 main.log.error( self.name + ": Error in adding mpls intent" )
Hari Krishna9e232602015-04-13 17:29:08 -07002081 return None
2082 else:
2083 # TODO: print out all the options in this message?
2084 main.log.info( "MPLS intent installed between " +
2085 str( ingressDevice ) + " and " +
2086 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002087 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07002088 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002089 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07002090 else:
2091 main.log.error( "Error, intent ID not found" )
2092 return None
Jon Hallc6793552016-01-19 14:18:37 -08002093 except AssertionError:
2094 main.log.exception( "" )
2095 return None
Hari Krishna9e232602015-04-13 17:29:08 -07002096 except TypeError:
2097 main.log.exception( self.name + ": Object not as expected" )
2098 return None
2099 except pexpect.EOF:
2100 main.log.error( self.name + ": EOF exception found" )
2101 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002102 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002103 except Exception:
2104 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002105 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002106
Jon Hallefbd9792015-03-05 16:11:36 -08002107 def removeIntent( self, intentId, app='org.onosproject.cli',
2108 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002109 """
shahshreya1c818fc2015-02-26 13:44:08 -08002110 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07002111 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08002112 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07002113 -p or --purge: Purge the intent from the store after removal
2114
Jon Halle3f39ff2015-01-13 11:50:53 -08002115 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07002116 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08002117 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08002118 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002119 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002120 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08002121 if purge:
2122 cmdStr += " -p"
2123 if sync:
2124 cmdStr += " -s"
2125
2126 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002127 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002128 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002129 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08002130 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002131 main.log.error( self.name + ": Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002132 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04002133 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002134 # TODO: Should this be main.TRUE
2135 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002136 except AssertionError:
2137 main.log.exception( "" )
2138 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002139 except TypeError:
2140 main.log.exception( self.name + ": Object not as expected" )
2141 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002142 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002143 main.log.error( self.name + ": EOF exception found" )
2144 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002145 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002146 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002147 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002148 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002149
YPZhangfebf7302016-05-24 16:45:56 -07002150 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08002151 """
2152 Description:
2153 Remove all the intents
2154 Optional args:-
2155 -s or --sync: Waits for the removal before returning
2156 -p or --purge: Purge the intent from the store after removal
2157 Returns:
2158 Returns main.TRUE if all intents are removed, otherwise returns
2159 main.FALSE; Returns None for exception
2160 """
2161 try:
2162 cmdStr = "remove-intent"
2163 if purge:
2164 cmdStr += " -p"
2165 if sync:
2166 cmdStr += " -s"
2167
2168 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002169 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002170 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002171 assert "Command not found:" not in handle, handle
2172 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002173 main.log.error( self.name + ": Error in removing intent" )
Jeremy42df2e72016-02-23 16:37:46 -08002174 return main.FALSE
2175 else:
2176 return main.TRUE
2177 except AssertionError:
2178 main.log.exception( "" )
2179 return None
2180 except TypeError:
2181 main.log.exception( self.name + ": Object not as expected" )
2182 return None
2183 except pexpect.EOF:
2184 main.log.error( self.name + ": EOF exception found" )
2185 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002186 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002187 except Exception:
2188 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002189 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002190
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002191 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002192 """
2193 Purges all WITHDRAWN Intents
2194 """
2195 try:
2196 cmdStr = "purge-intents"
2197 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002198 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002199 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002200 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002201 main.log.error( self.name + ": Error in purging intents" )
Hari Krishna0ce0e152015-06-23 09:55:29 -07002202 return main.FALSE
2203 else:
2204 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002205 except AssertionError:
2206 main.log.exception( "" )
2207 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002208 except TypeError:
2209 main.log.exception( self.name + ": Object not as expected" )
2210 return None
2211 except pexpect.EOF:
2212 main.log.error( self.name + ": EOF exception found" )
2213 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002214 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002215 except Exception:
2216 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002217 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002218
Devin Lime6fe3c42017-10-18 16:28:40 -07002219 def wipeout( self ):
2220 """
2221 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2222 """
2223 try:
2224 cmdStr = "wipe-out please"
2225 handle = self.sendline( cmdStr, timeout=60 )
2226 assert handle is not None, "Error in sendline"
2227 assert "Command not found:" not in handle, handle
2228 return main.TRUE
2229 except AssertionError:
2230 main.log.exception( "" )
2231 return None
2232 except TypeError:
2233 main.log.exception( self.name + ": Object not as expected" )
2234 return None
2235 except pexpect.EOF:
2236 main.log.error( self.name + ": EOF exception found" )
2237 main.log.error( self.name + ": " + self.handle.before )
2238 main.cleanAndExit()
2239 except Exception:
2240 main.log.exception( self.name + ": Uncaught exception!" )
2241 main.cleanAndExit()
2242
kelvin-onlabd3b64892015-01-20 13:26:24 -08002243 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002244 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002245 NOTE: This method should be used after installing application:
2246 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002247 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002248 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002249 Description:
2250 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002251 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002252 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002253 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002254 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002255 cmdStr += " -j"
2256 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002257 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002258 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002259 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002260 except AssertionError:
2261 main.log.exception( "" )
2262 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002263 except TypeError:
2264 main.log.exception( self.name + ": Object not as expected" )
2265 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002266 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002267 main.log.error( self.name + ": EOF exception found" )
2268 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002269 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002270 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002271 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002272 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002273
pingping-lin54b03372015-08-13 14:43:10 -07002274 def ipv4RouteNumber( self ):
2275 """
2276 NOTE: This method should be used after installing application:
2277 onos-app-sdnip
2278 Description:
2279 Obtain the total IPv4 routes number in the system
2280 """
2281 try:
Pratik Parab57963572017-05-09 11:37:54 -07002282 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002283 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002284 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002285 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002286 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002287 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002288 except AssertionError:
2289 main.log.exception( "" )
2290 return None
2291 except ( TypeError, ValueError ):
2292 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002293 return None
2294 except pexpect.EOF:
2295 main.log.error( self.name + ": EOF exception found" )
2296 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002297 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002298 except Exception:
2299 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002300 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002301
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002302 # =============Function to check Bandwidth allocation========
Jon Hall0e240372018-05-02 11:21:57 -07002303 def allocations( self, jsonFormat = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002304 """
2305 Description:
2306 Obtain Bandwidth Allocation Information from ONOS cli.
2307 """
2308 try:
2309 cmdStr = "allocations"
2310 if jsonFormat:
2311 cmdStr += " -j"
Jon Hall0e240372018-05-02 11:21:57 -07002312 handle = self.sendline( cmdStr, timeout=300 )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002313 assert handle is not None, "Error in sendline"
2314 assert "Command not found:" not in handle, handle
2315 return handle
2316 except AssertionError:
2317 main.log.exception( "" )
2318 return None
2319 except ( TypeError, ValueError ):
2320 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2321 return None
2322 except pexpect.EOF:
2323 main.log.error( self.name + ": EOF exception found" )
2324 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002325 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002326 except Exception:
2327 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002328 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002329
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002330 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002331 """
andrewonlabe6745342014-10-17 14:29:13 -04002332 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002333 Obtain intents from the ONOS cli.
2334 Optional:
2335 * jsonFormat: Enable output formatting in json, default to True
2336 * summary: Whether only output the intent summary, defaults to False
2337 * type: Only output a certain type of intent. This options is valid
2338 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002339 """
andrewonlabe6745342014-10-17 14:29:13 -04002340 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002341 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002342 if summary:
2343 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002344 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002345 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002346 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002347 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002348 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002349 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002350 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002351 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002352 else:
Jon Hallff566d52016-01-15 14:45:36 -08002353 intentType = ""
2354 # IF we want the summary of a specific intent type
2355 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002356 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002357 if intentType in jsonResult.keys():
2358 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002359 else:
Jon Hallff566d52016-01-15 14:45:36 -08002360 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002361 return handle
2362 else:
2363 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002364 except AssertionError:
2365 main.log.exception( "" )
2366 return None
2367 except ( TypeError, ValueError ):
2368 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002369 return None
2370 except pexpect.EOF:
2371 main.log.error( self.name + ": EOF exception found" )
2372 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002373 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002374 except Exception:
2375 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002376 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002377
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002378 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002379 """
You Wangfdcbfc42016-05-16 12:16:53 -07002380 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002381 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002382 list of intent IDs.
2383 Parameters:
2384 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002385 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002386 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002387 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002388 accepted.
2389 Returns a list of dictionaries if a list of intent IDs is accepted,
2390 and each dictionary maps 'id' to the Intent ID and 'state' to
2391 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002392 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002393
kelvin-onlab54400a92015-02-26 18:05:51 -08002394 try:
2395 state = "State is Undefined"
2396 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002397 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002398 else:
Jon Hallc6793552016-01-19 14:18:37 -08002399 rawJson = intentsJson
2400 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002401 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002402 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002403 if intentsId == intent[ 'id' ]:
2404 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002405 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002406 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002407 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002408 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002409 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002410 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002411 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002412 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002413 for intent in parsedIntentsJson:
2414 if intentsId[ i ] == intent[ 'id' ]:
2415 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002416 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002417 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002418 break
Jon Hallefbd9792015-03-05 16:11:36 -08002419 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002420 main.log.warn( "Could not find all intents in ONOS output" )
2421 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002422 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002423 else:
Jon Hall53158082017-05-18 11:17:00 -07002424 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002425 return None
Jon Hallc6793552016-01-19 14:18:37 -08002426 except ( TypeError, ValueError ):
2427 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002428 return None
2429 except pexpect.EOF:
2430 main.log.error( self.name + ": EOF exception found" )
2431 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002432 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002433 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002434 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002435 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002436
Jon Hallf539eb92017-05-22 17:18:42 -07002437 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002438 """
2439 Description:
2440 Check intents state
2441 Required:
2442 intentsId - List of intents ID to be checked
2443 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002444 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002445 state in the list.
2446 *NOTE: You can pass in a list of expected state,
2447 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002448 Return:
Jon Hall53158082017-05-18 11:17:00 -07002449 Returns main.TRUE only if all intent are the same as expected states,
2450 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002451 """
2452 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002453 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002454 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002455
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002456 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002457 intentsDict = []
2458 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002459 if isinstance( intentsId, types.StringType ) \
2460 and intent.get( 'id' ) == intentsId:
2461 intentsDict.append( intent )
2462 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002463 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002464 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002465
2466 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002467 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002468 "getting intents state" )
2469 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002470
2471 if isinstance( expectedState, types.StringType ):
2472 for intents in intentsDict:
2473 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002474 main.log.debug( self.name + " : Intent ID - " +
2475 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002476 " actual state = " +
2477 intents.get( 'state' )
2478 + " does not equal expected state = "
2479 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002480 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002481 elif isinstance( expectedState, types.ListType ):
2482 for intents in intentsDict:
2483 if not any( state == intents.get( 'state' ) for state in
2484 expectedState ):
2485 main.log.debug( self.name + " : Intent ID - " +
2486 intents.get( 'id' ) +
2487 " actual state = " +
2488 intents.get( 'state' ) +
2489 " does not equal expected states = "
2490 + str( expectedState ) )
2491 returnValue = main.FALSE
2492
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002493 if returnValue == main.TRUE:
2494 main.log.info( self.name + ": All " +
2495 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002496 " intents are in " + str( expectedState ) +
2497 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002498 return returnValue
2499 except TypeError:
2500 main.log.exception( self.name + ": Object not as expected" )
2501 return None
2502 except pexpect.EOF:
2503 main.log.error( self.name + ": EOF exception found" )
2504 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002505 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002506 except Exception:
2507 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002508 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002509
Jon Hallf539eb92017-05-22 17:18:42 -07002510 def compareBandwidthAllocations( self, expectedAllocations ):
2511 """
2512 Description:
2513 Compare the allocated bandwidth with the given allocations
2514 Required:
2515 expectedAllocations - The expected ONOS output of the allocations command
2516 Return:
2517 Returns main.TRUE only if all intent are the same as expected states,
2518 otherwise returns main.FALSE.
2519 """
2520 # FIXME: Convert these string comparisons to object comparisons
2521 try:
2522 returnValue = main.TRUE
2523 bandwidthFailed = False
2524 rawAlloc = self.allocations()
2525 expectedFormat = StringIO( expectedAllocations )
2526 ONOSOutput = StringIO( rawAlloc )
2527 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2528 str( expectedFormat ) ) )
2529
2530 for actual, expected in izip( ONOSOutput, expectedFormat ):
2531 actual = actual.rstrip()
2532 expected = expected.rstrip()
2533 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2534 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002535 marker1 = actual.find( 'allocated' )
2536 m1 = actual[ :marker1 ]
2537 marker2 = expected.find( 'allocated' )
2538 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002539 if m1 != m2:
2540 bandwidthFailed = True
2541 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2542 bandwidthFailed = True
2543 expectedFormat.close()
2544 ONOSOutput.close()
2545
2546 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002547 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002548 returnValue = main.FALSE
2549 return returnValue
2550 except TypeError:
2551 main.log.exception( self.name + ": Object not as expected" )
2552 return None
2553 except pexpect.EOF:
2554 main.log.error( self.name + ": EOF exception found" )
2555 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002556 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002557 except Exception:
2558 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002559 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002560
You Wang66518af2016-05-16 15:32:59 -07002561 def compareIntent( self, intentDict ):
2562 """
2563 Description:
2564 Compare the intent ids and states provided in the argument with all intents in ONOS
2565 Return:
2566 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2567 Arguments:
2568 intentDict: a dictionary which maps intent ids to intent states
2569 """
2570 try:
2571 intentsRaw = self.intents()
2572 intentsJson = json.loads( intentsRaw )
2573 intentDictONOS = {}
2574 for intent in intentsJson:
2575 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002576 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002577 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002578 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002579 str( len( intentDict ) ) + " expected and " +
2580 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002581 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002582 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002583 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002584 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2585 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002586 else:
2587 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2588 main.log.debug( self.name + ": intent ID - " + intentID +
2589 " expected state is " + intentDict[ intentID ] +
2590 " but actual state is " + intentDictONOS[ intentID ] )
2591 returnValue = main.FALSE
2592 intentDictONOS.pop( intentID )
2593 if len( intentDictONOS ) > 0:
2594 returnValue = main.FALSE
2595 for intentID in intentDictONOS.keys():
2596 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002597 if returnValue == main.TRUE:
2598 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2599 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002600 except KeyError:
2601 main.log.exception( self.name + ": KeyError exception found" )
2602 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002603 except ( TypeError, ValueError ):
2604 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002605 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002606 except pexpect.EOF:
2607 main.log.error( self.name + ": EOF exception found" )
2608 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002609 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002610 except Exception:
2611 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002612 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002613
YPZhang14a4aa92016-07-15 13:37:15 -07002614 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002615 """
2616 Description:
2617 Check the number of installed intents.
2618 Optional:
2619 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002620 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002621 Return:
2622 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2623 , otherwise, returns main.FALSE.
2624 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002625
GlennRCed771242016-01-13 17:02:47 -08002626 try:
2627 cmd = "intents -s -j"
2628
2629 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002630 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002631 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002632 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002633 response = json.loads( response )
2634
2635 # get total and installed number, see if they are match
2636 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002637 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002638 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2639 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002640 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002641 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2642 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002643 return main.FALSE
2644
Jon Hallc6793552016-01-19 14:18:37 -08002645 except ( TypeError, ValueError ):
2646 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002647 return None
2648 except pexpect.EOF:
2649 main.log.error( self.name + ": EOF exception found" )
2650 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002651 if noExit:
2652 return main.FALSE
2653 else:
Devin Lim44075962017-08-11 10:56:37 -07002654 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002655 except pexpect.TIMEOUT:
2656 main.log.error( self.name + ": ONOS timeout" )
2657 return None
GlennRCed771242016-01-13 17:02:47 -08002658 except Exception:
2659 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002660 if noExit:
2661 return main.FALSE
2662 else:
Devin Lim44075962017-08-11 10:56:37 -07002663 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002664
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002665 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002666 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002667 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002668 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002669 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002670 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002671 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002672 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002673 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002674 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002675 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002676 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002677 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002678 cmdStr += " -n"
2679 cmdStr += " " + state
2680 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002681 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002682 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002683 assert "Command not found:" not in handle, handle
2684 if re.search( "Error:", handle ):
2685 main.log.error( self.name + ": flows() response: " +
2686 str( handle ) )
2687 return handle
2688 except AssertionError:
2689 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002690 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002691 except TypeError:
2692 main.log.exception( self.name + ": Object not as expected" )
2693 return None
Jon Hallc6793552016-01-19 14:18:37 -08002694 except pexpect.TIMEOUT:
2695 main.log.error( self.name + ": ONOS timeout" )
2696 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002697 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002698 main.log.error( self.name + ": EOF exception found" )
2699 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002700 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002701 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002702 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002703 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002704
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002705 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002706 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002707 count = int( count ) if count else 0
steven30801eccfe212019-01-24 13:00:42 +08002708 main.log.debug( "found {} flows".format( count ) )
Jon Hall39570262020-11-17 12:18:19 -08002709 return count if ( count >= min ) else False
GlennRCed771242016-01-13 17:02:47 -08002710
Jon Halle0f0b342017-04-18 11:43:47 -07002711 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002712 """
2713 Description:
GlennRCed771242016-01-13 17:02:47 -08002714 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002715 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2716 if the count of those states is 0, which means all current flows
2717 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002718 Optional:
GlennRCed771242016-01-13 17:02:47 -08002719 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002720 Return:
2721 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002722 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002723 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002724 """
2725 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002726 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002727 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002728 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002729 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002730 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002731 if rawFlows:
2732 # if we didn't get flows or flows function return None, we should return
2733 # main.Flase
2734 checkedStates.append( json.loads( rawFlows ) )
2735 else:
2736 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002737 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002738 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002739 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002740 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002741 except TypeError:
2742 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002743 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002744
GlennRCed771242016-01-13 17:02:47 -08002745 # We want to count PENDING_ADD if isPENDING is true
2746 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002747 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002748 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002749 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002750 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002751 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002752 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002753 except ( TypeError, ValueError ):
2754 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002755 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002756
YPZhang240842b2016-05-17 12:00:50 -07002757 except AssertionError:
2758 main.log.exception( "" )
2759 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002760 except pexpect.TIMEOUT:
2761 main.log.error( self.name + ": ONOS timeout" )
2762 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002763 except pexpect.EOF:
2764 main.log.error( self.name + ": EOF exception found" )
2765 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002766 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002767 except Exception:
2768 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002769 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002770
GlennRCed771242016-01-13 17:02:47 -08002771 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002772 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002773 """
andrewonlab87852b02014-11-19 18:44:19 -05002774 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002775 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002776 a specific point-to-point intent definition
2777 Required:
GlennRCed771242016-01-13 17:02:47 -08002778 * ingress: specify source dpid
2779 * egress: specify destination dpid
2780 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002781 Optional:
GlennRCed771242016-01-13 17:02:47 -08002782 * offset: the keyOffset is where the next batch of intents
2783 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002784 * noExit: If set to True, TestON will not exit if any error when issus command
2785 * getResponse: If set to True, function will return ONOS response.
2786
GlennRCed771242016-01-13 17:02:47 -08002787 Returns: If failed to push test intents, it will returen None,
2788 if successful, return true.
2789 Timeout expection will return None,
2790 TypeError will return false
2791 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002792 """
andrewonlab87852b02014-11-19 18:44:19 -05002793 try:
GlennRCed771242016-01-13 17:02:47 -08002794 if background:
2795 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002796 else:
GlennRCed771242016-01-13 17:02:47 -08002797 back = ""
2798 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002799 ingress,
2800 egress,
2801 batchSize,
2802 offset,
2803 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002804 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002805 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002806 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002807 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002808 if getResponse:
2809 return response
2810
GlennRCed771242016-01-13 17:02:47 -08002811 # TODO: We should handle if there is failure in installation
2812 return main.TRUE
2813
Jon Hallc6793552016-01-19 14:18:37 -08002814 except AssertionError:
2815 main.log.exception( "" )
2816 return None
GlennRCed771242016-01-13 17:02:47 -08002817 except pexpect.TIMEOUT:
2818 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002819 return None
andrewonlab87852b02014-11-19 18:44:19 -05002820 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002821 main.log.error( self.name + ": EOF exception found" )
2822 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002823 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002824 except TypeError:
2825 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002826 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002827 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002828 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002829 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002830
YPZhangebf9eb52016-05-12 15:20:24 -07002831 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002832 """
2833 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002834 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002835 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002836 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002837 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002838 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002839
YPZhangb5d3f832016-01-23 22:54:26 -08002840 try:
YPZhange3109a72016-02-02 11:25:37 -08002841 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002842 cmd = "flows -c added"
2843 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2844 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002845 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002846 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002847 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002848 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002849 else:
You Wang68568b12019-03-04 11:49:57 -08002850 main.log.warn( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002851 return None
2852 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002853
You Wangd3097f72018-12-12 11:56:03 -08002854 except IndexError:
2855 main.log.exception( "{}: Object not as expected!".format( self.name ) )
2856 main.log.debug( "rawFlows: {}".format( rawFlows ) )
2857 return None
You Wangd3cb2ce2016-05-16 14:01:24 -07002858 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002859 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002860 return None
2861 except pexpect.EOF:
2862 main.log.error( self.name + ": EOF exception found" )
2863 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002864 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002865 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002866 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002867 except pexpect.TIMEOUT:
2868 main.log.error( self.name + ": ONOS timeout" )
2869 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002870 except Exception:
2871 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002872 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002873 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002874 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002875
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002876 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002877 """
2878 Description:
2879 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002880 Optional:
2881 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002882 Return:
2883 The number of intents
2884 """
2885 try:
2886 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002887 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002888 if response is None:
2889 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002890 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002891 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002892 except ( TypeError, ValueError ):
2893 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002894 return None
2895 except pexpect.EOF:
2896 main.log.error( self.name + ": EOF exception found" )
2897 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002898 if noExit:
2899 return -1
2900 else:
Devin Lim44075962017-08-11 10:56:37 -07002901 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002902 except Exception:
2903 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002904 if noExit:
2905 return -1
2906 else:
Devin Lim44075962017-08-11 10:56:37 -07002907 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002908
kelvin-onlabd3b64892015-01-20 13:26:24 -08002909 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002910 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002911 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002912 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002913 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002914 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002915 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002916 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002917 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002918 cmdStr += " -j"
2919 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002920 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002921 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002922 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002923 except AssertionError:
2924 main.log.exception( "" )
2925 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002926 except TypeError:
2927 main.log.exception( self.name + ": Object not as expected" )
2928 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002929 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002930 main.log.error( self.name + ": EOF exception found" )
2931 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002932 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002933 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002934 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002935 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002936
kelvin-onlabd3b64892015-01-20 13:26:24 -08002937 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002938 """
2939 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002940 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002941 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002942 """
andrewonlab867212a2014-10-22 20:13:38 -04002943 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002944 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002945 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002946 cmdStr += " -j"
2947 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002948 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002949 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002950 if handle:
2951 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002952 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002953 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002954 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002955 else:
2956 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002957 except AssertionError:
2958 main.log.exception( "" )
2959 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002960 except TypeError:
2961 main.log.exception( self.name + ": Object not as expected" )
2962 return None
andrewonlab867212a2014-10-22 20:13:38 -04002963 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002964 main.log.error( self.name + ": EOF exception found" )
2965 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002966 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002967 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002968 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002969 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002970
kelvin8ec71442015-01-15 16:57:00 -08002971 # Wrapper functions ****************
2972 # Wrapper functions use existing driver
2973 # functions and extends their use case.
2974 # For example, we may use the output of
2975 # a normal driver function, and parse it
2976 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002977
kelvin-onlabd3b64892015-01-20 13:26:24 -08002978 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002979 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002980 Description:
2981 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002982 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002983 try:
kelvin8ec71442015-01-15 16:57:00 -08002984 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002985 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002986 if intentsStr is None:
2987 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002988 # Convert to a dictionary
2989 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002990 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002991 for intent in intents:
2992 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002993 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002994 except TypeError:
2995 main.log.exception( self.name + ": Object not as expected" )
2996 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002997 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002998 main.log.error( self.name + ": EOF exception found" )
2999 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003000 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003001 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003002 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003003 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04003004
You Wang3c276252016-09-21 15:21:36 -07003005 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08003006 """
3007 Determine the number of flow rules for the given device id that are
3008 in the added state
You Wang3c276252016-09-21 15:21:36 -07003009 Params:
3010 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08003011 """
3012 try:
You Wang3c276252016-09-21 15:21:36 -07003013 if core:
3014 cmdStr = "flows any " + str( deviceId ) + " | " +\
3015 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
3016 else:
3017 cmdStr = "flows any " + str( deviceId ) + " | " +\
3018 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003019 handle = self.lineCount( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003020 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003021 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08003022 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003023 except AssertionError:
3024 main.log.exception( "" )
3025 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08003026 except pexpect.EOF:
3027 main.log.error( self.name + ": EOF exception found" )
3028 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003029 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003030 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08003031 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003032 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04003033
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003034 def groupAddedCount( self, deviceId, core=False ):
3035 """
3036 Determine the number of group rules for the given device id that are
3037 in the added state
3038 Params:
3039 core: if True, only return the number of core groups added
3040 """
3041 try:
3042 if core:
3043 cmdStr = "groups any " + str( deviceId ) + " | " +\
3044 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
3045 else:
3046 cmdStr = "groups any " + str( deviceId ) + " | " +\
3047 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003048 handle = self.lineCount( cmdStr )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003049 assert handle is not None, "Error in sendline"
3050 assert "Command not found:" not in handle, handle
3051 return handle
3052 except AssertionError:
3053 main.log.exception( "" )
3054 return None
3055 except pexpect.EOF:
3056 main.log.error( self.name + ": EOF exception found" )
3057 main.log.error( self.name + ": " + self.handle.before )
3058 main.cleanAndExit()
3059 except Exception:
3060 main.log.exception( self.name + ": Uncaught exception!" )
3061 main.cleanAndExit()
3062
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003063 def addStaticRoute( self, subnet, intf):
3064 """
3065 Adds a static route to onos.
3066 Params:
3067 subnet: The subnet reaching through this route
3068 intf: The interface this route is reachable through
3069 """
3070 try:
3071 cmdStr = "route-add " + subnet + " " + intf
3072 handle = self.sendline( cmdStr )
3073 assert handle is not None, "Error in sendline"
3074 assert "Command not found:" not in handle, handle
3075 return handle
3076 except AssertionError:
3077 main.log.exception( "" )
3078 return None
3079 except pexpect.EOF:
3080 main.log.error( self.name + ": EOF exception found" )
3081 main.log.error( self.name + ": " + self.handle.before )
3082 main.cleanAndExit()
3083 except Exception:
3084 main.log.exception( self.name + ": Uncaught exception!" )
3085 main.cleanAndExit()
3086
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003087 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
3088 """
3089 Description:
3090 Check whether the number of groups for the given device id that
3091 are in ADDED state is bigger than minGroupCount.
3092 Required:
3093 * deviceId: device id to check the number of added group rules
3094 Optional:
3095 * minGroupCount: the number of groups to compare
3096 * core: if True, only check the number of core groups added
3097 * comparison: if 0, compare with greater than minFlowCount
3098 * if 1, compare with equal to minFlowCount
3099 Return:
3100 Returns the number of groups if it is bigger than minGroupCount,
3101 returns main.FALSE otherwise.
3102 """
3103 count = self.groupAddedCount( deviceId, core )
3104 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003105 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003106 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
3107
You Wangc02f3be2018-05-18 12:14:23 -07003108 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003109 """
3110 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07003111 deviceId: Id of the device from which we retrieve groups
3112 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003113 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003114 try:
You Wangc02f3be2018-05-18 12:14:23 -07003115 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
3116 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003117 assert handle is not None, "Error in sendline"
3118 assert "Command not found:" not in handle, handle
3119 return handle
3120 except AssertionError:
3121 main.log.exception( "" )
3122 return None
3123 except TypeError:
3124 main.log.exception( self.name + ": Object not as expected" )
3125 return None
3126 except pexpect.EOF:
3127 main.log.error( self.name + ": EOF exception found" )
3128 main.log.error( self.name + ": " + self.handle.before )
3129 main.cleanAndExit()
3130 except Exception:
3131 main.log.exception( self.name + ": Uncaught exception!" )
3132 main.cleanAndExit()
3133
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003134 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003135 """
3136 Description:
3137 Check whether the number of flow rules for the given device id that
3138 are in ADDED state is bigger than minFlowCount.
3139 Required:
3140 * deviceId: device id to check the number of added flow rules
3141 Optional:
3142 * minFlowCount: the number of flow rules to compare
3143 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003144 * comparison: if 0, compare with greater than minFlowCount
3145 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003146 Return:
3147 Returns the number of flow rules if it is bigger than minFlowCount,
3148 returns main.FALSE otherwise.
3149 """
3150 count = self.flowAddedCount( deviceId, core )
3151 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003152 main.log.debug( "found {} flows".format( count ) )
Jon Hall39570262020-11-17 12:18:19 -08003153 return count if ((count >= expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003154
kelvin-onlabd3b64892015-01-20 13:26:24 -08003155 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003156 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003157 Use 'devices' function to obtain list of all devices
3158 and parse the result to obtain a list of all device
3159 id's. Returns this list. Returns empty list if no
3160 devices exist
kelvin8ec71442015-01-15 16:57:00 -08003161 List is ordered sequentially
3162
andrewonlab3e15ead2014-10-15 14:21:34 -04003163 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003164 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003165 the ids. By obtaining the list of device ids on the fly,
3166 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003167 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003168 try:
kelvin8ec71442015-01-15 16:57:00 -08003169 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003170 devicesStr = self.devices( jsonFormat=False )
3171 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003172
kelvin-onlabd3b64892015-01-20 13:26:24 -08003173 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003174 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003175 return idList
kelvin8ec71442015-01-15 16:57:00 -08003176
3177 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003178 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003179 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003180 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003181 # Split list further into arguments before and after string
3182 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003183 # append to idList
3184 for arg in tempList:
3185 idList.append( arg.split( "id=" )[ 1 ] )
3186 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003187
Jon Halld4d4b372015-01-28 16:02:41 -08003188 except TypeError:
3189 main.log.exception( self.name + ": Object not as expected" )
3190 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003191 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003192 main.log.error( self.name + ": EOF exception found" )
3193 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003194 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003195 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003196 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003197 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003198
kelvin-onlabd3b64892015-01-20 13:26:24 -08003199 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003200 """
andrewonlab7c211572014-10-15 16:45:20 -04003201 Uses 'nodes' function to obtain list of all nodes
3202 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003203 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003204 Returns:
3205 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003206 """
andrewonlab7c211572014-10-15 16:45:20 -04003207 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003208 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003209 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003210 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003211 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003212 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003213 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003214 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003215 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003216 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003217 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003218 except ( TypeError, ValueError ):
3219 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003220 return None
andrewonlab7c211572014-10-15 16:45:20 -04003221 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003222 main.log.error( self.name + ": EOF exception found" )
3223 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003224 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003225 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003226 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003227 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003228
kelvin-onlabd3b64892015-01-20 13:26:24 -08003229 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003230 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003231 Return the first device from the devices api whose 'id' contains 'dpid'
3232 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003233 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003234 try:
kelvin8ec71442015-01-15 16:57:00 -08003235 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003236 return None
3237 else:
kelvin8ec71442015-01-15 16:57:00 -08003238 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003239 rawDevices = self.devices()
3240 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003241 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003242 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003243 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3244 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003245 return device
3246 return None
Jon Hallc6793552016-01-19 14:18:37 -08003247 except ( TypeError, ValueError ):
3248 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003249 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003250 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003251 main.log.error( self.name + ": EOF exception found" )
3252 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003253 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003254 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003255 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003256 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003257
You Wang24139872016-05-03 11:48:47 -07003258 def getTopology( self, topologyOutput ):
3259 """
3260 Definition:
3261 Loads a json topology output
3262 Return:
3263 topology = current ONOS topology
3264 """
You Wang24139872016-05-03 11:48:47 -07003265 try:
3266 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003267 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003268 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003269 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003270 except ( TypeError, ValueError ):
3271 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3272 return None
You Wang24139872016-05-03 11:48:47 -07003273 except pexpect.EOF:
3274 main.log.error( self.name + ": EOF exception found" )
3275 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003276 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003277 except Exception:
3278 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003279 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003280
Jon Hall39570262020-11-17 12:18:19 -08003281 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, numoSCCs=1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003282 """
Jon Hallefbd9792015-03-05 16:11:36 -08003283 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003284 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003285 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003286
Flavio Castro82ee2f62016-06-07 15:04:12 -07003287 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003288 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003289 numoctrl = expected number of controllers
Jon Hall39570262020-11-17 12:18:19 -08003290 numoSCCs = Number of expected SCCs
You Wang24139872016-05-03 11:48:47 -07003291 logLevel = level to log to.
3292 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003293
Jon Hallefbd9792015-03-05 16:11:36 -08003294 Returns: main.TRUE if the number of switches and links are correct,
3295 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003296 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003297 """
Jon Hall42db6dc2014-10-24 19:03:48 -04003298 try:
You Wang13310252016-07-31 10:56:14 -07003299 summary = self.summary()
3300 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003301 except ( TypeError, ValueError ):
3302 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3303 return main.ERROR
3304 try:
3305 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003306 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003307 return main.ERROR
3308 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003309 # Is the number of switches is what we expected
3310 devices = topology.get( 'devices', False )
3311 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003312 nodes = summary.get( 'nodes', False )
Jon Hall39570262020-11-17 12:18:19 -08003313 SCCs = summary.get( 'SCC(s)', False )
3314 if devices is False or links is False or nodes is False or SCCs is False:
3315 main.log.warn( "Issues parsing topology and summary output" )
3316 main.log.debug( topology )
3317 main.log.debug( summary )
Jon Hall42db6dc2014-10-24 19:03:48 -04003318 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003319 switchCheck = ( int( devices ) == int( numoswitch ) )
Jon Hall39570262020-11-17 12:18:19 -08003320 if not switchCheck:
3321 main.log.debug( "switch Check Failed" )
Pier6a0c4de2018-03-18 16:01:30 -07003322 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Jon Hall39570262020-11-17 12:18:19 -08003323 if not linkCheck:
3324 main.log.debug( "link Check Failed" )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003325 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
Jon Hall39570262020-11-17 12:18:19 -08003326 if not nodeCheck:
3327 main.log.debug( "node Check Failed" )
3328 SCCsCheck = ( int( SCCs ) == int( numoSCCs ) ) or int( numoSCCs ) == -1
3329 if not SCCsCheck:
3330 main.log.debug( "SCCs Check Failed" )
3331 if switchCheck and linkCheck and nodeCheck and SCCsCheck:
kelvin8ec71442015-01-15 16:57:00 -08003332 # We expected the correct numbers
Jon Hall39570262020-11-17 12:18:19 -08003333 output = output + "The number of links, switches, nodes, and SCCs match "\
You Wang24139872016-05-03 11:48:47 -07003334 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003335 result = main.TRUE
3336 else:
You Wang24139872016-05-03 11:48:47 -07003337 output = output + \
Jon Hall627b1572020-12-01 12:01:15 -08003338 "The number of links, switches, nodes, and SCCs does not match " + \
You Wang24139872016-05-03 11:48:47 -07003339 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003340 result = main.FALSE
Jon Hall39570262020-11-17 12:18:19 -08003341 output = output + "\n ONOS sees %i devices " % int( devices )
3342 output = output + "(%i expected) " % int( numoswitch )
3343 if int( numolink ) >= 0:
Pier6a0c4de2018-03-18 16:01:30 -07003344 output = output + "and %i links " % int( links )
Jon Hall39570262020-11-17 12:18:19 -08003345 output = output + "(%i expected) " % int( numolink )
3346 if int( numoctrl ) >= 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003347 output = output + "and %i controllers " % int( nodes )
Jon Hall39570262020-11-17 12:18:19 -08003348 output = output + "(%i expected) " % int( numoctrl )
3349 if int( numoSCCs ) >= 0:
3350 output = output + "and %i SCCs " % int( SCCs )
3351 output = output + "(%i expected)" % int( numoSCCs )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003352 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003353 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003354 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003355 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003356 else:
You Wang24139872016-05-03 11:48:47 -07003357 main.log.info( output )
Jon Hall39570262020-11-17 12:18:19 -08003358 main.TOPOOUTPUT = output
kelvin8ec71442015-01-15 16:57:00 -08003359 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003360 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003361 main.log.error( self.name + ": EOF exception found" )
3362 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003363 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003364 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003365 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003366 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003367
kelvin-onlabd3b64892015-01-20 13:26:24 -08003368 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003369 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003370 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003371 deviceId must be the id of a device as seen in the onos devices command
3372 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003373 role must be either master, standby, or none
3374
Jon Halle3f39ff2015-01-13 11:50:53 -08003375 Returns:
3376 main.TRUE or main.FALSE based on argument verification and
3377 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003378 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003379 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003380 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003381 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003382 cmdStr = "device-role " +\
3383 str( deviceId ) + " " +\
3384 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003385 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003386 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003387 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003388 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003389 if re.search( "Error", handle ):
3390 # end color output to escape any colours
3391 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003392 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003393 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003394 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003395 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003396 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003397 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003398 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003399 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003400 except AssertionError:
3401 main.log.exception( "" )
3402 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003403 except TypeError:
3404 main.log.exception( self.name + ": Object not as expected" )
3405 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003406 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003407 main.log.error( self.name + ": EOF exception found" )
3408 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003409 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003410 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003411 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003412 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003413
kelvin-onlabd3b64892015-01-20 13:26:24 -08003414 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003415 """
Jon Hall0dd09952018-04-19 09:59:11 -07003416 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003417 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003418 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003419 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003420 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003421 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003422 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003423 cmdStr += " -j"
3424 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003425 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003426 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003427 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003428 except AssertionError:
3429 main.log.exception( "" )
3430 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003431 except TypeError:
3432 main.log.exception( self.name + ": Object not as expected" )
3433 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003434 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003435 main.log.error( self.name + ": EOF exception found" )
3436 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003437 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003438 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003439 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003440 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003441
kelvin-onlabd3b64892015-01-20 13:26:24 -08003442 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003443 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003444 CLI command to get the current leader for the Election test application
3445 NOTE: Requires installation of the onos-app-election feature
3446 Returns: Node IP of the leader if one exists
3447 None if none exists
3448 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003449 """
Jon Hall94fd0472014-12-08 11:52:42 -08003450 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003451 cmdStr = "election-test-leader"
3452 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003453 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003454 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003455 # Leader
3456 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003457 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003458 nodeSearch = re.search( leaderPattern, response )
3459 if nodeSearch:
3460 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003461 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003462 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003463 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003464 # no leader
3465 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003466 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003467 nullSearch = re.search( nullPattern, response )
3468 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003469 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003470 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003471 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003472 # error
Jon Hall0e240372018-05-02 11:21:57 -07003473 main.log.error( self.name + ": Error in electionTestLeader on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003474 ": " + "unexpected response" )
3475 main.log.error( repr( response ) )
3476 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003477 except AssertionError:
3478 main.log.exception( "" )
3479 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003480 except TypeError:
3481 main.log.exception( self.name + ": Object not as expected" )
3482 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003483 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003484 main.log.error( self.name + ": EOF exception found" )
3485 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003486 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003487 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003488 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003489 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003490
kelvin-onlabd3b64892015-01-20 13:26:24 -08003491 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003492 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003493 CLI command to run for leadership of the Election test application.
3494 NOTE: Requires installation of the onos-app-election feature
3495 Returns: Main.TRUE on success
3496 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003497 """
Jon Hall94fd0472014-12-08 11:52:42 -08003498 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003499 cmdStr = "election-test-run"
3500 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003501 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003502 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003503 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003504 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003505 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003506 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003507 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003508 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003509 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003510 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003511 # error
Jon Hall0e240372018-05-02 11:21:57 -07003512 main.log.error( self.name + ": Error in electionTestRun on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003513 ": " + "unexpected response" )
3514 main.log.error( repr( response ) )
3515 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003516 except AssertionError:
3517 main.log.exception( "" )
3518 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003519 except TypeError:
3520 main.log.exception( self.name + ": Object not as expected" )
3521 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003522 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003523 main.log.error( self.name + ": EOF exception found" )
3524 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003525 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003526 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003527 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003528 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003529
kelvin-onlabd3b64892015-01-20 13:26:24 -08003530 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003531 """
Jon Hall94fd0472014-12-08 11:52:42 -08003532 * CLI command to withdraw the local node from leadership election for
3533 * the Election test application.
3534 #NOTE: Requires installation of the onos-app-election feature
3535 Returns: Main.TRUE on success
3536 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003537 """
Jon Hall94fd0472014-12-08 11:52:42 -08003538 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003539 cmdStr = "election-test-withdraw"
3540 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003541 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003542 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003543 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003544 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003545 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003546 if re.search( successPattern, response ):
3547 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003548 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003549 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003550 # error
Jon Hall0e240372018-05-02 11:21:57 -07003551 main.log.error( self.name + ": Error in electionTestWithdraw on " +
Jon Hall97cf84a2016-06-20 13:35:58 -07003552 self.name + ": " + "unexpected response" )
3553 main.log.error( repr( response ) )
3554 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003555 except AssertionError:
3556 main.log.exception( "" )
3557 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003558 except TypeError:
3559 main.log.exception( self.name + ": Object not as expected" )
3560 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003561 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003562 main.log.error( self.name + ": EOF exception found" )
3563 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003564 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003565 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003566 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003567 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003568
kelvin8ec71442015-01-15 16:57:00 -08003569 def getDevicePortsEnabledCount( self, dpid ):
3570 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003571 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003572 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003573 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003574 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003575 cmdStr = "onos:ports -e " + dpid + " | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003576 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003577 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003578 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003579 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003580 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003581 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003582 return output
Jon Hallc6793552016-01-19 14:18:37 -08003583 except AssertionError:
3584 main.log.exception( "" )
3585 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003586 except TypeError:
3587 main.log.exception( self.name + ": Object not as expected" )
3588 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003589 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003590 main.log.error( self.name + ": EOF exception found" )
3591 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003592 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003593 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003594 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003595 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003596
kelvin8ec71442015-01-15 16:57:00 -08003597 def getDeviceLinksActiveCount( self, dpid ):
3598 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003599 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003600 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003601 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003602 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003603 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003604 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003605 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003606 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003607 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003608 main.log.error( self.name + ": Error in getting ports " )
kelvin-onlab898a6c62015-01-16 14:13:53 -08003609 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003610 return output
Jon Hallc6793552016-01-19 14:18:37 -08003611 except AssertionError:
3612 main.log.exception( "" )
3613 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003614 except TypeError:
3615 main.log.exception( self.name + ": Object not as expected" )
3616 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003617 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003618 main.log.error( self.name + ": EOF exception found" )
3619 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003620 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003621 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003622 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003623 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003624
kelvin8ec71442015-01-15 16:57:00 -08003625 def getAllIntentIds( self ):
3626 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003627 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003628 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003629 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003630 cmdStr = "onos:intents | grep id="
3631 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003632 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003633 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003634 if re.search( "Error", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003635 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003636 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003637 return output
Jon Hallc6793552016-01-19 14:18:37 -08003638 except AssertionError:
3639 main.log.exception( "" )
3640 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003641 except TypeError:
3642 main.log.exception( self.name + ": Object not as expected" )
3643 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003644 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003645 main.log.error( self.name + ": EOF exception found" )
3646 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003647 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003648 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003649 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003650 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003651
Jon Hall73509952015-02-24 16:42:56 -08003652 def intentSummary( self ):
3653 """
Jon Hallefbd9792015-03-05 16:11:36 -08003654 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003655 """
3656 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003657 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003658 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003659 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003660 states.append( intent.get( 'state', None ) )
3661 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003662 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003663 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003664 except ( TypeError, ValueError ):
3665 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003666 return None
3667 except pexpect.EOF:
3668 main.log.error( self.name + ": EOF exception found" )
3669 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003670 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003671 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003672 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003673 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003674
Jon Hall61282e32015-03-19 11:34:11 -07003675 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003676 """
3677 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003678 Optional argument:
3679 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003680 """
Jon Hall63604932015-02-26 17:09:50 -08003681 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003682 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003683 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003684 cmdStr += " -j"
3685 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003686 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003687 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003688 return output
Jon Hallc6793552016-01-19 14:18:37 -08003689 except AssertionError:
3690 main.log.exception( "" )
3691 return None
Jon Hall63604932015-02-26 17:09:50 -08003692 except TypeError:
3693 main.log.exception( self.name + ": Object not as expected" )
3694 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003695 except pexpect.EOF:
3696 main.log.error( self.name + ": EOF exception found" )
3697 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003698 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003699 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003700 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003701 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003702
acsmarsa4a4d1e2015-07-10 16:01:24 -07003703 def leaderCandidates( self, jsonFormat=True ):
3704 """
3705 Returns the output of the leaders -c command.
3706 Optional argument:
3707 * jsonFormat - boolean indicating if you want output in json
3708 """
3709 try:
3710 cmdStr = "onos:leaders -c"
3711 if jsonFormat:
3712 cmdStr += " -j"
3713 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003714 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003715 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003716 return output
Jon Hallc6793552016-01-19 14:18:37 -08003717 except AssertionError:
3718 main.log.exception( "" )
3719 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003720 except TypeError:
3721 main.log.exception( self.name + ": Object not as expected" )
3722 return None
3723 except pexpect.EOF:
3724 main.log.error( self.name + ": EOF exception found" )
3725 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003726 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003727 except Exception:
3728 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003729 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003730
Jon Hallc6793552016-01-19 14:18:37 -08003731 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003732 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003733 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003734 topic parameter and an empty list if the topic doesn't exist
3735 If no leader is elected leader in the returned list will be "none"
3736 Returns None if there is a type error processing the json object
3737 """
3738 try:
Jon Hall6e709752016-02-01 13:38:46 -08003739 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003740 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003741 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003742 assert "Command not found:" not in rawOutput, rawOutput
3743 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003744 results = []
3745 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003746 if dict[ "topic" ] == topic:
3747 leader = dict[ "leader" ]
3748 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003749 results.append( leader )
3750 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003751 return results
Jon Hallc6793552016-01-19 14:18:37 -08003752 except AssertionError:
3753 main.log.exception( "" )
3754 return None
3755 except ( TypeError, ValueError ):
3756 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003757 return None
3758 except pexpect.EOF:
3759 main.log.error( self.name + ": EOF exception found" )
3760 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003761 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003762 except Exception:
3763 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003764 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003765
Jon Hall61282e32015-03-19 11:34:11 -07003766 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003767 """
3768 Returns the output of the intent Pending map.
3769 """
Jon Hall63604932015-02-26 17:09:50 -08003770 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003771 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003772 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003773 cmdStr += " -j"
3774 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003775 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003776 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003777 return output
Jon Hallc6793552016-01-19 14:18:37 -08003778 except AssertionError:
3779 main.log.exception( "" )
3780 return None
Jon Hall63604932015-02-26 17:09:50 -08003781 except TypeError:
3782 main.log.exception( self.name + ": Object not as expected" )
3783 return None
3784 except pexpect.EOF:
3785 main.log.error( self.name + ": EOF exception found" )
3786 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003787 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003788 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003789 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003790 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003791
Jon Hall2c8959e2016-12-16 12:17:34 -08003792 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003793 """
3794 Returns the output of the raft partitions command for ONOS.
3795 """
Jon Hall61282e32015-03-19 11:34:11 -07003796 # Sample JSON
3797 # {
3798 # "leader": "tcp://10.128.30.11:7238",
3799 # "members": [
3800 # "tcp://10.128.30.11:7238",
3801 # "tcp://10.128.30.17:7238",
3802 # "tcp://10.128.30.13:7238",
3803 # ],
3804 # "name": "p1",
3805 # "term": 3
3806 # },
Jon Hall63604932015-02-26 17:09:50 -08003807 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003808 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003809 if candidates:
3810 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003811 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003812 cmdStr += " -j"
3813 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003814 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003815 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003816 return output
Jon Hallc6793552016-01-19 14:18:37 -08003817 except AssertionError:
3818 main.log.exception( "" )
3819 return None
Jon Hall63604932015-02-26 17:09:50 -08003820 except TypeError:
3821 main.log.exception( self.name + ": Object not as expected" )
3822 return None
3823 except pexpect.EOF:
3824 main.log.error( self.name + ": EOF exception found" )
3825 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003826 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003827 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003828 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003829 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003830
Jon Halle9f909e2016-09-23 10:43:12 -07003831 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003832 """
3833 Returns the output of the apps command for ONOS. This command lists
3834 information about installed ONOS applications
3835 """
3836 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003837 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003838 # "description":"ONOS OpenFlow protocol southbound providers",
3839 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003840 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003841 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003842 cmdStr = "onos:apps"
Jon Hallf03ae762019-01-22 13:25:27 -08003843 expectJson = False
Jon Halle9f909e2016-09-23 10:43:12 -07003844 if summary:
3845 cmdStr += " -s"
3846 if active:
3847 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003848 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003849 cmdStr += " -j"
Jon Hallf03ae762019-01-22 13:25:27 -08003850 expectJson = True
3851 output = self.sendline( cmdStr, expectJson=expectJson )
Jon Halla495f562016-05-16 18:03:26 -07003852 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003853 assert "Command not found:" not in output, output
3854 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003855 return output
Jon Hallbe379602015-03-24 13:39:32 -07003856 # FIXME: look at specific exceptions/Errors
3857 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07003858 main.log.exception( self.name + ": Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003859 return None
3860 except TypeError:
3861 main.log.exception( self.name + ": Object not as expected" )
3862 return None
3863 except pexpect.EOF:
3864 main.log.error( self.name + ": EOF exception found" )
3865 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003866 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003867 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003868 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003869 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003870
You Wangcdc51fe2018-08-12 17:14:56 -07003871 def appStatus( self, appName ):
Jon Hall146f1522015-03-24 15:33:24 -07003872 """
3873 Uses the onos:apps cli command to return the status of an application.
3874 Returns:
3875 "ACTIVE" - If app is installed and activated
3876 "INSTALLED" - If app is installed and deactivated
3877 "UNINSTALLED" - If app is not installed
3878 None - on error
3879 """
Jon Hall146f1522015-03-24 15:33:24 -07003880 try:
3881 if not isinstance( appName, types.StringType ):
3882 main.log.error( self.name + ".appStatus(): appName must be" +
3883 " a string" )
3884 return None
3885 output = self.apps( jsonFormat=True )
3886 appsJson = json.loads( output )
3887 state = None
3888 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003889 if appName == app.get( 'name' ):
3890 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003891 break
3892 if state == "ACTIVE" or state == "INSTALLED":
3893 return state
3894 elif state is None:
You Wang0d9f2c02018-08-10 14:56:32 -07003895 main.log.warn( "{} app not found".format( appName ) )
Jon Hall146f1522015-03-24 15:33:24 -07003896 return "UNINSTALLED"
3897 elif state:
3898 main.log.error( "Unexpected state from 'onos:apps': " +
3899 str( state ) )
3900 return state
Jon Hallc6793552016-01-19 14:18:37 -08003901 except ( TypeError, ValueError ):
3902 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003903 return None
3904 except pexpect.EOF:
3905 main.log.error( self.name + ": EOF exception found" )
3906 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003907 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003908 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003909 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003910 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003911
Jon Hallbe379602015-03-24 13:39:32 -07003912 def app( self, appName, option ):
3913 """
3914 Interacts with the app command for ONOS. This command manages
3915 application inventory.
3916 """
Jon Hallbe379602015-03-24 13:39:32 -07003917 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003918 # Validate argument types
3919 valid = True
3920 if not isinstance( appName, types.StringType ):
3921 main.log.error( self.name + ".app(): appName must be a " +
3922 "string" )
3923 valid = False
3924 if not isinstance( option, types.StringType ):
3925 main.log.error( self.name + ".app(): option must be a string" )
3926 valid = False
3927 if not valid:
3928 return main.FALSE
3929 # Validate Option
3930 option = option.lower()
3931 # NOTE: Install may become a valid option
3932 if option == "activate":
3933 pass
3934 elif option == "deactivate":
3935 pass
3936 elif option == "uninstall":
3937 pass
3938 else:
3939 # Invalid option
3940 main.log.error( "The ONOS app command argument only takes " +
3941 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003942 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003943 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003944 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003945 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003946 assert output is not None, "Error in sendline"
3947 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003948 if "Error executing command" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003949 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hallbe379602015-03-24 13:39:32 -07003950 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003951 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003952 elif "No such application" in output:
3953 main.log.error( "The application '" + appName +
3954 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003955 return main.FALSE
3956 elif "Command not found:" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003957 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hall146f1522015-03-24 15:33:24 -07003958 str( output ) )
3959 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003960 elif "Unsupported command:" in output:
3961 main.log.error( "Incorrect command given to 'app': " +
3962 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003963 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003964 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003965 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003966 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003967 except AssertionError:
3968 main.log.exception( self.name + ": AssertionError exception found" )
3969 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003970 except TypeError:
3971 main.log.exception( self.name + ": Object not as expected" )
3972 return main.ERROR
3973 except pexpect.EOF:
3974 main.log.error( self.name + ": EOF exception found" )
3975 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003976 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003977 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003978 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003979 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003980
Jon Hallbd16b922015-03-26 17:53:15 -07003981 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003982 """
3983 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003984 appName is the hierarchical app name, not the feature name
3985 If check is True, method will check the status of the app after the
3986 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003987 Returns main.TRUE if the command was successfully sent
3988 main.FALSE if the cli responded with an error or given
3989 incorrect input
3990 """
3991 try:
3992 if not isinstance( appName, types.StringType ):
3993 main.log.error( self.name + ".activateApp(): appName must be" +
3994 " a string" )
3995 return main.FALSE
3996 status = self.appStatus( appName )
3997 if status == "INSTALLED":
3998 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003999 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004000 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004001 status = self.appStatus( appName )
4002 if status == "ACTIVE":
4003 return main.TRUE
4004 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07004005 main.log.debug( "The state of application " +
4006 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07004007 time.sleep( 1 )
4008 return main.FALSE
4009 else: # not 'check' or command didn't succeed
4010 return response
Jon Hall146f1522015-03-24 15:33:24 -07004011 elif status == "ACTIVE":
4012 return main.TRUE
4013 elif status == "UNINSTALLED":
4014 main.log.error( self.name + ": Tried to activate the " +
4015 "application '" + appName + "' which is not " +
4016 "installed." )
4017 else:
4018 main.log.error( "Unexpected return value from appStatus: " +
4019 str( status ) )
4020 return main.ERROR
4021 except TypeError:
4022 main.log.exception( self.name + ": Object not as expected" )
4023 return main.ERROR
4024 except pexpect.EOF:
4025 main.log.error( self.name + ": EOF exception found" )
4026 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004027 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004028 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004029 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004030 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07004031
Jon Hallbd16b922015-03-26 17:53:15 -07004032 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07004033 """
4034 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07004035 appName is the hierarchical app name, not the feature name
4036 If check is True, method will check the status of the app after the
4037 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07004038 Returns main.TRUE if the command was successfully sent
4039 main.FALSE if the cli responded with an error or given
4040 incorrect input
4041 """
4042 try:
4043 if not isinstance( appName, types.StringType ):
4044 main.log.error( self.name + ".deactivateApp(): appName must " +
4045 "be a string" )
4046 return main.FALSE
4047 status = self.appStatus( appName )
4048 if status == "INSTALLED":
4049 return main.TRUE
4050 elif status == "ACTIVE":
4051 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07004052 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004053 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004054 status = self.appStatus( appName )
4055 if status == "INSTALLED":
4056 return main.TRUE
4057 else:
4058 time.sleep( 1 )
4059 return main.FALSE
4060 else: # not check or command didn't succeed
4061 return response
Jon Hall146f1522015-03-24 15:33:24 -07004062 elif status == "UNINSTALLED":
4063 main.log.warn( self.name + ": Tried to deactivate the " +
4064 "application '" + appName + "' which is not " +
4065 "installed." )
4066 return main.TRUE
4067 else:
4068 main.log.error( "Unexpected return value from appStatus: " +
4069 str( status ) )
4070 return main.ERROR
4071 except TypeError:
4072 main.log.exception( self.name + ": Object not as expected" )
4073 return main.ERROR
4074 except pexpect.EOF:
4075 main.log.error( self.name + ": EOF exception found" )
4076 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004077 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004078 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004079 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004080 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07004081
Jon Hallbd16b922015-03-26 17:53:15 -07004082 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07004083 """
4084 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07004085 appName is the hierarchical app name, not the feature name
4086 If check is True, method will check the status of the app after the
4087 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07004088 Returns main.TRUE if the command was successfully sent
4089 main.FALSE if the cli responded with an error or given
4090 incorrect input
4091 """
4092 # TODO: check with Thomas about the state machine for apps
4093 try:
4094 if not isinstance( appName, types.StringType ):
4095 main.log.error( self.name + ".uninstallApp(): appName must " +
4096 "be a string" )
4097 return main.FALSE
4098 status = self.appStatus( appName )
4099 if status == "INSTALLED":
4100 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004101 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004102 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004103 status = self.appStatus( appName )
4104 if status == "UNINSTALLED":
4105 return main.TRUE
4106 else:
4107 time.sleep( 1 )
4108 return main.FALSE
4109 else: # not check or command didn't succeed
4110 return response
Jon Hall146f1522015-03-24 15:33:24 -07004111 elif status == "ACTIVE":
4112 main.log.warn( self.name + ": Tried to uninstall the " +
4113 "application '" + appName + "' which is " +
4114 "currently active." )
4115 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004116 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004117 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004118 status = self.appStatus( appName )
4119 if status == "UNINSTALLED":
4120 return main.TRUE
4121 else:
4122 time.sleep( 1 )
4123 return main.FALSE
4124 else: # not check or command didn't succeed
4125 return response
Jon Hall146f1522015-03-24 15:33:24 -07004126 elif status == "UNINSTALLED":
4127 return main.TRUE
4128 else:
4129 main.log.error( "Unexpected return value from appStatus: " +
4130 str( status ) )
4131 return main.ERROR
4132 except TypeError:
4133 main.log.exception( self.name + ": Object not as expected" )
4134 return main.ERROR
4135 except pexpect.EOF:
4136 main.log.error( self.name + ": EOF exception found" )
4137 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004138 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004139 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004140 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004141 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004142
4143 def appIDs( self, jsonFormat=True ):
4144 """
4145 Show the mappings between app id and app names given by the 'app-ids'
4146 cli command
4147 """
4148 try:
4149 cmdStr = "app-ids"
4150 if jsonFormat:
4151 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07004152 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004153 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004154 assert "Command not found:" not in output, output
4155 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07004156 return output
Jon Hallbd16b922015-03-26 17:53:15 -07004157 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004158 main.log.exception( self.name + ": Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07004159 return None
4160 except TypeError:
4161 main.log.exception( self.name + ": Object not as expected" )
4162 return None
4163 except pexpect.EOF:
4164 main.log.error( self.name + ": EOF exception found" )
4165 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004166 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004167 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004168 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004169 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004170
4171 def appToIDCheck( self ):
4172 """
4173 This method will check that each application's ID listed in 'apps' is
4174 the same as the ID listed in 'app-ids'. The check will also check that
4175 there are no duplicate IDs issued. Note that an app ID should be
4176 a globaly unique numerical identifier for app/app-like features. Once
4177 an ID is registered, the ID is never freed up so that if an app is
4178 reinstalled it will have the same ID.
4179
4180 Returns: main.TRUE if the check passes and
4181 main.FALSE if the check fails or
4182 main.ERROR if there is some error in processing the test
4183 """
4184 try:
Jon Hall0e240372018-05-02 11:21:57 -07004185 # Grab IDs
Jon Hallc6793552016-01-19 14:18:37 -08004186 rawJson = self.appIDs( jsonFormat=True )
4187 if rawJson:
4188 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004189 else:
Jon Hall0e240372018-05-02 11:21:57 -07004190 main.log.error( "app-ids returned nothing: " + repr( rawJson ) )
4191 return main.FALSE
4192
4193 # Grab Apps
Jon Hallc6793552016-01-19 14:18:37 -08004194 rawJson = self.apps( jsonFormat=True )
4195 if rawJson:
4196 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004197 else:
Jon Hallc6793552016-01-19 14:18:37 -08004198 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004199 return main.FALSE
Jon Hall0e240372018-05-02 11:21:57 -07004200
Jon Hallbd16b922015-03-26 17:53:15 -07004201 result = main.TRUE
4202 for app in apps:
4203 appID = app.get( 'id' )
4204 if appID is None:
4205 main.log.error( "Error parsing app: " + str( app ) )
4206 result = main.FALSE
4207 appName = app.get( 'name' )
4208 if appName is None:
4209 main.log.error( "Error parsing app: " + str( app ) )
4210 result = main.FALSE
4211 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004212 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004213 if not current: # if ids doesn't have this id
4214 result = main.FALSE
4215 main.log.error( "'app-ids' does not have the ID for " +
4216 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004217 main.log.debug( "apps command returned: " + str( app ) +
4218 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004219 elif len( current ) > 1:
4220 # there is more than one app with this ID
4221 result = main.FALSE
4222 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004223 elif not current[ 0 ][ 'name' ] == appName:
4224 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004225 result = main.FALSE
4226 main.log.error( "'app-ids' has " + str( currentName ) +
4227 " registered under id:" + str( appID ) +
4228 " but 'apps' has " + str( appName ) )
4229 else:
4230 pass # id and name match!
Jon Hall0e240372018-05-02 11:21:57 -07004231
Jon Hallbd16b922015-03-26 17:53:15 -07004232 # now make sure that app-ids has no duplicates
4233 idsList = []
4234 namesList = []
4235 for item in ids:
4236 idsList.append( item[ 'id' ] )
4237 namesList.append( item[ 'name' ] )
4238 if len( idsList ) != len( set( idsList ) ) or\
4239 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004240 main.log.error( "'app-ids' has some duplicate entries: \n"
4241 + json.dumps( ids,
4242 sort_keys=True,
4243 indent=4,
4244 separators=( ',', ': ' ) ) )
4245 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004246 return result
Jon Hallc6793552016-01-19 14:18:37 -08004247 except ( TypeError, ValueError ):
4248 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004249 return main.ERROR
4250 except pexpect.EOF:
4251 main.log.error( self.name + ": EOF exception found" )
4252 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004253 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004254 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004255 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004256 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004257
Jon Hallfb760a02015-04-13 15:35:03 -07004258 def getCfg( self, component=None, propName=None, short=False,
4259 jsonFormat=True ):
4260 """
4261 Get configuration settings from onos cli
4262 Optional arguments:
4263 component - Optionally only list configurations for a specific
4264 component. If None, all components with configurations
4265 are displayed. Case Sensitive string.
4266 propName - If component is specified, propName option will show
4267 only this specific configuration from that component.
4268 Case Sensitive string.
4269 jsonFormat - Returns output as json. Note that this will override
4270 the short option
4271 short - Short, less verbose, version of configurations.
4272 This is overridden by the json option
4273 returns:
4274 Output from cli as a string or None on error
4275 """
4276 try:
4277 baseStr = "cfg"
4278 cmdStr = " get"
4279 componentStr = ""
4280 if component:
4281 componentStr += " " + component
4282 if propName:
4283 componentStr += " " + propName
4284 if jsonFormat:
4285 baseStr += " -j"
Jon Hall22e94ce2019-01-15 14:52:17 -08004286 expectJson = True
Jon Hallfb760a02015-04-13 15:35:03 -07004287 elif short:
4288 baseStr += " -s"
Jon Hall22e94ce2019-01-15 14:52:17 -08004289 expectJson = False
4290 output = self.sendline( baseStr + cmdStr + componentStr, expectJson=expectJson )
Jon Halla495f562016-05-16 18:03:26 -07004291 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004292 assert "Command not found:" not in output, output
4293 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004294 return output
4295 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004296 main.log.exception( self.name + ": Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004297 return None
4298 except TypeError:
4299 main.log.exception( self.name + ": Object not as expected" )
4300 return None
4301 except pexpect.EOF:
4302 main.log.error( self.name + ": EOF exception found" )
4303 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004304 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004305 except Exception:
4306 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004307 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004308
4309 def setCfg( self, component, propName, value=None, check=True ):
4310 """
4311 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004312 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004313 component - The case sensitive name of the component whose
4314 property is to be set
4315 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004316 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004317 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004318 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004319 check - Boolean, Check whether the option was successfully set this
4320 only applies when a value is given.
4321 returns:
4322 main.TRUE on success or main.FALSE on failure. If check is False,
4323 will return main.TRUE unless there is an error
4324 """
4325 try:
4326 baseStr = "cfg"
4327 cmdStr = " set " + str( component ) + " " + str( propName )
4328 if value is not None:
4329 cmdStr += " " + str( value )
4330 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004331 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004332 assert "Command not found:" not in output, output
4333 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004334 if value and check:
4335 results = self.getCfg( component=str( component ),
4336 propName=str( propName ),
4337 jsonFormat=True )
4338 # Check if current value is what we just set
4339 try:
4340 jsonOutput = json.loads( results )
4341 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004342 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004343 main.log.exception( "Error parsing cfg output" )
4344 main.log.error( "output:" + repr( results ) )
4345 return main.FALSE
4346 if current == str( value ):
4347 return main.TRUE
4348 return main.FALSE
4349 return main.TRUE
4350 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004351 main.log.exception( self.name + ": Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004352 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004353 except ( TypeError, ValueError ):
4354 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004355 return main.FALSE
4356 except pexpect.EOF:
4357 main.log.error( self.name + ": EOF exception found" )
4358 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004359 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004360 except Exception:
4361 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004362 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004363
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004364 def distPrimitivesSend( self, cmd ):
4365 """
4366 Function to handle sending cli commands for the distributed primitives test app
4367
4368 This command will catch some exceptions and retry the command on some
4369 specific store exceptions.
4370
4371 Required arguments:
4372 cmd - The command to send to the cli
4373 returns:
4374 string containing the cli output
4375 None on Error
4376 """
4377 try:
4378 output = self.sendline( cmd )
4379 try:
4380 assert output is not None, "Error in sendline"
4381 # TODO: Maybe make this less hardcoded
4382 # ConsistentMap Exceptions
4383 assert "org.onosproject.store.service" not in output
4384 # Node not leader
4385 assert "java.lang.IllegalStateException" not in output
4386 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004387 main.log.error( self.name + ": Error in processing '" + cmd + "' " +
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004388 "command: " + str( output ) )
4389 retryTime = 30 # Conservative time, given by Madan
4390 main.log.info( "Waiting " + str( retryTime ) +
4391 "seconds before retrying." )
4392 time.sleep( retryTime ) # Due to change in mastership
4393 output = self.sendline( cmd )
4394 assert output is not None, "Error in sendline"
4395 assert "Command not found:" not in output, output
4396 assert "Error executing command" not in output, output
4397 main.log.info( self.name + ": " + output )
4398 return output
4399 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004400 main.log.exception( self.name + ": Error in processing '" + cmd + "' command." )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004401 return None
4402 except TypeError:
4403 main.log.exception( self.name + ": Object not as expected" )
4404 return None
4405 except pexpect.EOF:
4406 main.log.error( self.name + ": EOF exception found" )
4407 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004408 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004409 except Exception:
4410 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004411 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004412
Jon Hall390696c2015-05-05 17:13:41 -07004413 def setTestAdd( self, setName, values ):
4414 """
4415 CLI command to add elements to a distributed set.
4416 Arguments:
4417 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004418 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004419 Example usages:
4420 setTestAdd( "set1", "a b c" )
4421 setTestAdd( "set2", "1" )
4422 returns:
4423 main.TRUE on success OR
4424 main.FALSE if elements were already in the set OR
4425 main.ERROR on error
4426 """
4427 try:
4428 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004429 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004430 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4431 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004432 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004433 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004434 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004435 return main.FALSE
4436 else:
4437 main.log.error( self.name + ": setTestAdd did not" +
4438 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004439 main.log.debug( self.name + " actual: " + repr( output ) )
4440 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004441 except TypeError:
4442 main.log.exception( self.name + ": Object not as expected" )
4443 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004444 except Exception:
4445 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004446 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004447
4448 def setTestRemove( self, setName, values, clear=False, retain=False ):
4449 """
4450 CLI command to remove elements from a distributed set.
4451 Required arguments:
4452 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004453 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004454 Optional arguments:
4455 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004456 retain - Retain only the given values. (intersection of the
4457 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004458 returns:
4459 main.TRUE on success OR
4460 main.FALSE if the set was not changed OR
4461 main.ERROR on error
4462 """
4463 try:
4464 cmdStr = "set-test-remove "
4465 if clear:
4466 cmdStr += "-c " + str( setName )
4467 elif retain:
4468 cmdStr += "-r " + str( setName ) + " " + str( values )
4469 else:
4470 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004471 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004472 if clear:
4473 pattern = "Set " + str( setName ) + " cleared"
4474 if re.search( pattern, output ):
4475 return main.TRUE
4476 elif retain:
4477 positivePattern = str( setName ) + " was pruned to contain " +\
4478 "only elements of set \[(.*)\]"
4479 negativePattern = str( setName ) + " was not changed by " +\
4480 "retaining only elements of the set " +\
4481 "\[(.*)\]"
4482 if re.search( positivePattern, output ):
4483 return main.TRUE
4484 elif re.search( negativePattern, output ):
4485 return main.FALSE
4486 else:
4487 positivePattern = "\[(.*)\] was removed from the set " +\
4488 str( setName )
4489 if ( len( values.split() ) == 1 ):
4490 negativePattern = "\[(.*)\] was not in set " +\
4491 str( setName )
4492 else:
4493 negativePattern = "No element of \[(.*)\] was in set " +\
4494 str( setName )
4495 if re.search( positivePattern, output ):
4496 return main.TRUE
4497 elif re.search( negativePattern, output ):
4498 return main.FALSE
4499 main.log.error( self.name + ": setTestRemove did not" +
4500 " match expected output" )
4501 main.log.debug( self.name + " expected: " + pattern )
4502 main.log.debug( self.name + " actual: " + repr( output ) )
4503 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004504 except TypeError:
4505 main.log.exception( self.name + ": Object not as expected" )
4506 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004507 except Exception:
4508 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004509 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004510
4511 def setTestGet( self, setName, values="" ):
4512 """
4513 CLI command to get the elements in a distributed set.
4514 Required arguments:
4515 setName - The name of the set to remove from.
4516 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004517 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004518 returns:
4519 main.ERROR on error OR
4520 A list of elements in the set if no optional arguments are
4521 supplied OR
4522 A tuple containing the list then:
4523 main.FALSE if the given values are not in the set OR
4524 main.TRUE if the given values are in the set OR
4525 """
4526 try:
4527 values = str( values ).strip()
4528 setName = str( setName ).strip()
4529 length = len( values.split() )
4530 containsCheck = None
4531 # Patterns to match
4532 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004533 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004534 containsTrue = "Set " + setName + " contains the value " + values
4535 containsFalse = "Set " + setName + " did not contain the value " +\
4536 values
4537 containsAllTrue = "Set " + setName + " contains the the subset " +\
4538 setPattern
4539 containsAllFalse = "Set " + setName + " did not contain the the" +\
4540 " subset " + setPattern
4541
4542 cmdStr = "set-test-get "
4543 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004544 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004545 if length == 0:
4546 match = re.search( pattern, output )
4547 else: # if given values
4548 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004549 patternTrue = pattern + "\r\n" + containsTrue
4550 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004551 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004552 patternTrue = pattern + "\r\n" + containsAllTrue
4553 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004554 matchTrue = re.search( patternTrue, output )
4555 matchFalse = re.search( patternFalse, output )
4556 if matchTrue:
4557 containsCheck = main.TRUE
4558 match = matchTrue
4559 elif matchFalse:
4560 containsCheck = main.FALSE
4561 match = matchFalse
4562 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004563 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004564 "expected output" )
4565 main.log.debug( self.name + " expected: " + pattern )
4566 main.log.debug( self.name + " actual: " + repr( output ) )
4567 match = None
4568 if match:
4569 setMatch = match.group( 1 )
4570 if setMatch == '':
4571 setList = []
4572 else:
4573 setList = setMatch.split( ", " )
4574 if length > 0:
4575 return ( setList, containsCheck )
4576 else:
4577 return setList
4578 else: # no match
4579 main.log.error( self.name + ": setTestGet did not" +
4580 " match expected output" )
4581 main.log.debug( self.name + " expected: " + pattern )
4582 main.log.debug( self.name + " actual: " + repr( output ) )
4583 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004584 except TypeError:
4585 main.log.exception( self.name + ": Object not as expected" )
4586 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004587 except Exception:
4588 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004589 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004590
4591 def setTestSize( self, setName ):
4592 """
4593 CLI command to get the elements in a distributed set.
4594 Required arguments:
4595 setName - The name of the set to remove from.
4596 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004597 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004598 None on error
4599 """
4600 try:
4601 # TODO: Should this check against the number of elements returned
4602 # and then return true/false based on that?
4603 setName = str( setName ).strip()
4604 # Patterns to match
4605 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004606 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004607 setPattern
4608 cmdStr = "set-test-get -s "
4609 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004610 output = self.distPrimitivesSend( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -07004611 if output:
4612 match = re.search( pattern, output )
4613 if match:
4614 setSize = int( match.group( 1 ) )
4615 setMatch = match.group( 2 )
4616 if len( setMatch.split() ) == setSize:
4617 main.log.info( "The size returned by " + self.name +
4618 " matches the number of elements in " +
4619 "the returned set" )
4620 else:
4621 main.log.error( "The size returned by " + self.name +
4622 " does not match the number of " +
4623 "elements in the returned set." )
4624 return setSize
Jon Hall390696c2015-05-05 17:13:41 -07004625 else: # no match
4626 main.log.error( self.name + ": setTestGet did not" +
4627 " match expected output" )
4628 main.log.debug( self.name + " expected: " + pattern )
4629 main.log.debug( self.name + " actual: " + repr( output ) )
4630 return None
Jon Hall390696c2015-05-05 17:13:41 -07004631 except TypeError:
4632 main.log.exception( self.name + ": Object not as expected" )
4633 return None
Jon Hall390696c2015-05-05 17:13:41 -07004634 except Exception:
4635 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004636 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004637
Jon Hall80daded2015-05-27 16:07:00 -07004638 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004639 """
4640 Command to list the various counters in the system.
4641 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004642 if jsonFormat, a string of the json object returned by the cli
4643 command
4644 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004645 None on error
4646 """
Jon Hall390696c2015-05-05 17:13:41 -07004647 try:
Jon Hall390696c2015-05-05 17:13:41 -07004648 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004649 if jsonFormat:
4650 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004651 output = self.sendline( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08004652 main.log.debug( self.name + ": Counters unparsed: " + output )
4653 output = output.split( "\r\n" )[ -1 ]
4654 main.log.debug( self.name + ": Counters parsed: " + output )
Jon Halla495f562016-05-16 18:03:26 -07004655 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004656 assert "Command not found:" not in output, output
4657 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004658 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004659 return output
Jon Hall390696c2015-05-05 17:13:41 -07004660 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004661 main.log.exception( self.name + ": Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004662 return None
Jon Hall390696c2015-05-05 17:13:41 -07004663 except TypeError:
4664 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004665 return None
Jon Hall390696c2015-05-05 17:13:41 -07004666 except pexpect.EOF:
4667 main.log.error( self.name + ": EOF exception found" )
4668 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004669 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004670 except Exception:
4671 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004672 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004673
Jon Hall935db192016-04-19 00:22:04 -07004674 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004675 """
Jon Halle1a3b752015-07-22 13:02:46 -07004676 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004677 Required arguments:
4678 counter - The name of the counter to increment.
4679 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004680 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004681 returns:
4682 integer value of the counter or
4683 None on Error
4684 """
4685 try:
4686 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004687 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004688 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004689 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004690 if delta != 1:
4691 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004692 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004693 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004694 match = re.search( pattern, output )
4695 if match:
4696 return int( match.group( 1 ) )
4697 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004698 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004699 " match expected output." )
4700 main.log.debug( self.name + " expected: " + pattern )
4701 main.log.debug( self.name + " actual: " + repr( output ) )
4702 return None
Jon Hall390696c2015-05-05 17:13:41 -07004703 except TypeError:
4704 main.log.exception( self.name + ": Object not as expected" )
4705 return None
Jon Hall390696c2015-05-05 17:13:41 -07004706 except Exception:
4707 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004708 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004709
Jon Hall935db192016-04-19 00:22:04 -07004710 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004711 """
4712 CLI command to get a distributed counter then add a delta to it.
4713 Required arguments:
4714 counter - The name of the counter to increment.
4715 Optional arguments:
4716 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004717 returns:
4718 integer value of the counter or
4719 None on Error
4720 """
4721 try:
4722 counter = str( counter )
4723 delta = int( delta )
4724 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004725 cmdStr += counter
4726 if delta != 1:
4727 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004728 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004729 pattern = counter + " was updated to (-?\d+)"
4730 match = re.search( pattern, output )
4731 if match:
4732 return int( match.group( 1 ) )
4733 else:
4734 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4735 " match expected output." )
4736 main.log.debug( self.name + " expected: " + pattern )
4737 main.log.debug( self.name + " actual: " + repr( output ) )
4738 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004739 except TypeError:
4740 main.log.exception( self.name + ": Object not as expected" )
4741 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004742 except Exception:
4743 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004744 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004745
4746 def valueTestGet( self, valueName ):
4747 """
4748 CLI command to get the value of an atomic value.
4749 Required arguments:
4750 valueName - The name of the value to get.
4751 returns:
4752 string value of the value or
4753 None on Error
4754 """
4755 try:
4756 valueName = str( valueName )
4757 cmdStr = "value-test "
4758 operation = "get"
4759 cmdStr = "value-test {} {}".format( valueName,
4760 operation )
4761 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08004762 main.log.debug( self.name + ": value test unparsed: " + output )
4763 output = output.split( "\r\n" )[ -1 ]
4764 main.log.debug( self.name + ": value test parsed: " + output )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004765 pattern = "(\w+)"
4766 match = re.search( pattern, output )
4767 if match:
4768 return match.group( 1 )
4769 else:
4770 main.log.error( self.name + ": valueTestGet did not" +
4771 " match expected output." )
4772 main.log.debug( self.name + " expected: " + pattern )
4773 main.log.debug( self.name + " actual: " + repr( output ) )
4774 return None
4775 except TypeError:
4776 main.log.exception( self.name + ": Object not as expected" )
4777 return None
4778 except Exception:
4779 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004780 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004781
4782 def valueTestSet( self, valueName, newValue ):
4783 """
4784 CLI command to set the value of an atomic value.
4785 Required arguments:
4786 valueName - The name of the value to set.
4787 newValue - The value to assign to the given value.
4788 returns:
4789 main.TRUE on success or
4790 main.ERROR on Error
4791 """
4792 try:
4793 valueName = str( valueName )
4794 newValue = str( newValue )
4795 operation = "set"
4796 cmdStr = "value-test {} {} {}".format( valueName,
4797 operation,
4798 newValue )
4799 output = self.distPrimitivesSend( cmdStr )
4800 if output is not None:
4801 return main.TRUE
4802 else:
4803 return main.ERROR
4804 except TypeError:
4805 main.log.exception( self.name + ": Object not as expected" )
4806 return main.ERROR
4807 except Exception:
4808 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004809 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004810
4811 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4812 """
4813 CLI command to compareAndSet the value of an atomic value.
4814 Required arguments:
4815 valueName - The name of the value.
4816 oldValue - Compare the current value of the atomic value to this
4817 newValue - If the value equals oldValue, set the value to newValue
4818 returns:
4819 main.TRUE on success or
4820 main.FALSE on failure or
4821 main.ERROR on Error
4822 """
4823 try:
4824 valueName = str( valueName )
4825 oldValue = str( oldValue )
4826 newValue = str( newValue )
4827 operation = "compareAndSet"
4828 cmdStr = "value-test {} {} {} {}".format( valueName,
4829 operation,
4830 oldValue,
4831 newValue )
4832 output = self.distPrimitivesSend( cmdStr )
4833 pattern = "(\w+)"
4834 match = re.search( pattern, output )
4835 if match:
4836 result = match.group( 1 )
4837 if result == "true":
4838 return main.TRUE
4839 elif result == "false":
4840 return main.FALSE
4841 else:
4842 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4843 " match expected output." )
4844 main.log.debug( self.name + " expected: " + pattern )
4845 main.log.debug( self.name + " actual: " + repr( output ) )
4846 return main.ERROR
4847 except TypeError:
4848 main.log.exception( self.name + ": Object not as expected" )
4849 return main.ERROR
4850 except Exception:
4851 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004852 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004853
4854 def valueTestGetAndSet( self, valueName, newValue ):
4855 """
4856 CLI command to getAndSet the value of an atomic value.
4857 Required arguments:
4858 valueName - The name of the value to get.
4859 newValue - The value to assign to the given value
4860 returns:
4861 string value of the value or
4862 None on Error
4863 """
4864 try:
4865 valueName = str( valueName )
4866 cmdStr = "value-test "
4867 operation = "getAndSet"
4868 cmdStr += valueName + " " + operation
4869 cmdStr = "value-test {} {} {}".format( valueName,
4870 operation,
4871 newValue )
4872 output = self.distPrimitivesSend( cmdStr )
4873 pattern = "(\w+)"
4874 match = re.search( pattern, output )
4875 if match:
4876 return match.group( 1 )
4877 else:
4878 main.log.error( self.name + ": valueTestGetAndSet did not" +
4879 " match expected output." )
4880 main.log.debug( self.name + " expected: " + pattern )
4881 main.log.debug( self.name + " actual: " + repr( output ) )
4882 return None
4883 except TypeError:
4884 main.log.exception( self.name + ": Object not as expected" )
4885 return None
4886 except Exception:
4887 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004888 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004889
4890 def valueTestDestroy( self, valueName ):
4891 """
4892 CLI command to destroy an atomic value.
4893 Required arguments:
4894 valueName - The name of the value to destroy.
4895 returns:
4896 main.TRUE on success or
4897 main.ERROR on Error
4898 """
4899 try:
4900 valueName = str( valueName )
4901 cmdStr = "value-test "
4902 operation = "destroy"
4903 cmdStr += valueName + " " + operation
4904 output = self.distPrimitivesSend( cmdStr )
4905 if output is not None:
4906 return main.TRUE
4907 else:
4908 return main.ERROR
4909 except TypeError:
4910 main.log.exception( self.name + ": Object not as expected" )
4911 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004912 except Exception:
4913 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004914 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004915
YPZhangfebf7302016-05-24 16:45:56 -07004916 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004917 """
4918 Description: Execute summary command in onos
4919 Returns: json object ( summary -j ), returns main.FALSE if there is
4920 no output
4921
4922 """
4923 try:
4924 cmdStr = "summary"
4925 if jsonFormat:
4926 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004927 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004928 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004929 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004930 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004931 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004932 if not handle:
4933 main.log.error( self.name + ": There is no output in " +
4934 "summary command" )
4935 return main.FALSE
4936 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004937 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004938 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004939 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004940 except TypeError:
4941 main.log.exception( self.name + ": Object not as expected" )
4942 return None
4943 except pexpect.EOF:
4944 main.log.error( self.name + ": EOF exception found" )
4945 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004946 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004947 except Exception:
4948 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004949 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004950
Jon Hall06fd0df2021-01-25 15:50:06 -08004951 def getAddress( self):
4952 """
4953 Get the onos ip address from the cli. This is usefull when connecting using
4954 a container manager such as kubernetes. This function also sets self.address
4955 the value from ONOS.
4956
4957 Returns:
4958 The string value of the key or
4959 None on Error
4960 """
4961 try:
4962 output = self.summary()
4963 address = json.loads( output ).get( 'node' )
4964 self.address = address
4965 return address
You Wang327bad42021-03-24 14:19:58 -07004966 except ( TypeError, ValueError ):
Jon Hall06fd0df2021-01-25 15:50:06 -08004967 main.log.exception( self.name + ": Object not as expected" )
4968 return None
4969 except Exception:
4970 main.log.exception( self.name + ": Uncaught exception!" )
4971 main.cleanAndExit()
4972
Jon Hall935db192016-04-19 00:22:04 -07004973 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004974 """
4975 CLI command to get the value of a key in a consistent map using
4976 transactions. This a test function and can only get keys from the
4977 test map hard coded into the cli command
4978 Required arguments:
4979 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004980 returns:
4981 The string value of the key or
4982 None on Error
4983 """
4984 try:
4985 keyName = str( keyName )
4986 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004987 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004988 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004989 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4990 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004991 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004992 return None
4993 else:
4994 match = re.search( pattern, output )
4995 if match:
4996 return match.groupdict()[ 'value' ]
4997 else:
4998 main.log.error( self.name + ": transactionlMapGet did not" +
4999 " match expected output." )
5000 main.log.debug( self.name + " expected: " + pattern )
5001 main.log.debug( self.name + " actual: " + repr( output ) )
5002 return None
5003 except TypeError:
5004 main.log.exception( self.name + ": Object not as expected" )
5005 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07005006 except Exception:
5007 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005008 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07005009
Jon Hall935db192016-04-19 00:22:04 -07005010 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07005011 """
5012 CLI command to put a value into 'numKeys' number of keys in a
5013 consistent map using transactions. This a test function and can only
5014 put into keys named 'Key#' of the test map hard coded into the cli command
5015 Required arguments:
5016 numKeys - Number of keys to add the value to
5017 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07005018 returns:
5019 A dictionary whose keys are the name of the keys put into the map
5020 and the values of the keys are dictionaries whose key-values are
5021 'value': value put into map and optionaly
5022 'oldValue': Previous value in the key or
5023 None on Error
5024
5025 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005026 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
5027 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07005028 """
5029 try:
5030 numKeys = str( numKeys )
5031 value = str( value )
5032 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07005033 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07005034 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07005035 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
5036 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
5037 results = {}
5038 for line in output.splitlines():
5039 new = re.search( newPattern, line )
5040 updated = re.search( updatedPattern, line )
5041 if new:
5042 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
5043 elif updated:
5044 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08005045 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07005046 else:
5047 main.log.error( self.name + ": transactionlMapGet did not" +
5048 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08005049 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
5050 newPattern,
5051 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07005052 main.log.debug( self.name + " actual: " + repr( output ) )
5053 return results
Jon Hall0e240372018-05-02 11:21:57 -07005054 except ( TypeError, AttributeError ):
Jon Hall2a5002c2015-08-21 16:49:11 -07005055 main.log.exception( self.name + ": Object not as expected" )
5056 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07005057 except Exception:
5058 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005059 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08005060
acsmarsdaea66c2015-09-03 11:44:06 -07005061 def maps( self, jsonFormat=True ):
5062 """
5063 Description: Returns result of onos:maps
5064 Optional:
5065 * jsonFormat: enable json formatting of output
5066 """
5067 try:
5068 cmdStr = "maps"
5069 if jsonFormat:
5070 cmdStr += " -j"
5071 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07005072 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005073 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07005074 return handle
Jon Hallc6793552016-01-19 14:18:37 -08005075 except AssertionError:
5076 main.log.exception( "" )
5077 return None
acsmarsdaea66c2015-09-03 11:44:06 -07005078 except TypeError:
5079 main.log.exception( self.name + ": Object not as expected" )
5080 return None
5081 except pexpect.EOF:
5082 main.log.error( self.name + ": EOF exception found" )
5083 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005084 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07005085 except Exception:
5086 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005087 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005088
5089 def getSwController( self, uri, jsonFormat=True ):
5090 """
5091 Descrition: Gets the controller information from the device
5092 """
5093 try:
5094 cmd = "device-controllers "
5095 if jsonFormat:
5096 cmd += "-j "
5097 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07005098 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005099 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005100 return response
Jon Hallc6793552016-01-19 14:18:37 -08005101 except AssertionError:
5102 main.log.exception( "" )
5103 return None
GlennRC050596c2015-11-18 17:06:41 -08005104 except TypeError:
5105 main.log.exception( self.name + ": Object not as expected" )
5106 return None
5107 except pexpect.EOF:
5108 main.log.error( self.name + ": EOF exception found" )
5109 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005110 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005111 except Exception:
5112 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005113 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005114
5115 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
5116 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005117 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08005118
5119 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005120 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08005121 ip - String or List: The ip address of the controller.
5122 This parameter can be formed in a couple of different ways.
5123 VALID:
5124 10.0.0.1 - just the ip address
5125 tcp:10.0.0.1 - the protocol and the ip address
5126 tcp:10.0.0.1:6653 - the protocol and port can be specified,
5127 so that you can add controllers with different
5128 protocols and ports
5129 INVALID:
5130 10.0.0.1:6653 - this is not supported by ONOS
5131
5132 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
5133 port - The port number.
5134 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
5135
5136 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
5137 """
5138 try:
5139 cmd = "device-setcontrollers"
5140
5141 if jsonFormat:
5142 cmd += " -j"
5143 cmd += " " + uri
5144 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005145 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08005146 for item in ip:
5147 if ":" in item:
5148 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005149 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08005150 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005151 elif "." in sitem[ 1 ]:
5152 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08005153 else:
5154 main.log.error( "Malformed entry: " + item )
5155 raise TypeError
5156 else:
5157 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08005158 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07005159 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005160 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005161 if "Error" in response:
5162 main.log.error( response )
5163 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005164 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005165 except AssertionError:
5166 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005167 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005168 except TypeError:
5169 main.log.exception( self.name + ": Object not as expected" )
5170 return main.FALSE
5171 except pexpect.EOF:
5172 main.log.error( self.name + ": EOF exception found" )
5173 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005174 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005175 except Exception:
5176 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005177 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005178
5179 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005180 '''
GlennRC20fc6522015-12-23 23:26:57 -08005181 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005182 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08005183 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005184 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08005185 Returns:
5186 Returns main.FALSE if an exception is thrown or an error is present
5187 in the response. Otherwise, returns main.TRUE.
5188 NOTE:
5189 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005190 '''
GlennRC20fc6522015-12-23 23:26:57 -08005191 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005192 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07005193 deviceStr = device
5194 device = []
5195 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08005196
5197 for d in device:
5198 time.sleep( 1 )
5199 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07005200 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005201 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005202 if "Error" in response:
5203 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
5204 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005205 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005206 except AssertionError:
5207 main.log.exception( "" )
5208 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005209 except TypeError:
5210 main.log.exception( self.name + ": Object not as expected" )
5211 return main.FALSE
5212 except pexpect.EOF:
5213 main.log.error( self.name + ": EOF exception found" )
5214 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005215 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005216 except Exception:
5217 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005218 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005219
5220 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005221 '''
GlennRC20fc6522015-12-23 23:26:57 -08005222 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005223 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005224 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005225 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005226 Returns:
5227 Returns main.FALSE if an exception is thrown or an error is present
5228 in the response. Otherwise, returns main.TRUE.
5229 NOTE:
5230 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005231 '''
GlennRC20fc6522015-12-23 23:26:57 -08005232 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005233 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005234 host = list( host )
5235
5236 for h in host:
5237 time.sleep( 1 )
5238 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005239 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005240 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005241 if "Error" in response:
5242 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5243 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005244 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005245 except AssertionError:
5246 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005247 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005248 except TypeError:
5249 main.log.exception( self.name + ": Object not as expected" )
5250 return main.FALSE
5251 except pexpect.EOF:
5252 main.log.error( self.name + ": EOF exception found" )
5253 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005254 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005255 except Exception:
5256 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005257 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005258
YPZhangfebf7302016-05-24 16:45:56 -07005259 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005260 '''
GlennRCed771242016-01-13 17:02:47 -08005261 Description:
5262 Bring link down or up in the null-provider.
5263 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005264 begin - (string) One end of a device or switch.
5265 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005266 returns:
5267 main.TRUE if no exceptions were thrown and no Errors are
5268 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005269 '''
GlennRCed771242016-01-13 17:02:47 -08005270 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005271 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005272 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005273 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005274 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005275 if "Error" in response or "Failure" in response:
5276 main.log.error( response )
5277 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005278 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005279 except AssertionError:
5280 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005281 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005282 except TypeError:
5283 main.log.exception( self.name + ": Object not as expected" )
5284 return main.FALSE
5285 except pexpect.EOF:
5286 main.log.error( self.name + ": EOF exception found" )
5287 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005288 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005289 except Exception:
5290 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005291 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005292
Jon Hall2c8959e2016-12-16 12:17:34 -08005293 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005294 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005295 Description:
5296 Changes the state of port in an OF switch by means of the
5297 PORTSTATUS OF messages.
5298 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005299 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5300 port - (string) target port in the device. Ex: '2'
5301 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005302 returns:
5303 main.TRUE if no exceptions were thrown and no Errors are
5304 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005305 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005306 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005307 state = state.lower()
5308 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005309 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005310 response = self.sendline( cmd, showResponse=True )
5311 assert response is not None, "Error in sendline"
5312 assert "Command not found:" not in response, response
5313 if "Error" in response or "Failure" in response:
5314 main.log.error( response )
5315 return main.FALSE
5316 return main.TRUE
5317 except AssertionError:
5318 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005319 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005320 except TypeError:
5321 main.log.exception( self.name + ": Object not as expected" )
5322 return main.FALSE
5323 except pexpect.EOF:
5324 main.log.error( self.name + ": EOF exception found" )
5325 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005326 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005327 except Exception:
5328 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005329 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005330
5331 def logSet( self, level="INFO", app="org.onosproject" ):
5332 """
5333 Set the logging level to lvl for a specific app
5334 returns main.TRUE on success
5335 returns main.FALSE if Error occurred
5336 if noExit is True, TestON will not exit, but clean up
5337 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5338 Level defaults to INFO
5339 """
5340 try:
You Wang22e807e2021-03-29 10:53:38 -07005341 handle = self.sendline( "log:set %s %s" % ( level, app ) )
5342 assert handle is not None, "Error in sendline"
5343 assert "Command not found:" not in handle, handle
5344 if re.search( "Error", handle ):
5345 main.log.error( self.name + ": Error in setting log level" )
5346 main.log.error( handle )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005347 return main.FALSE
You Wang22e807e2021-03-29 10:53:38 -07005348 else:
5349 return main.TRUE
5350 except AssertionError:
5351 main.log.exception( "" )
5352 return None
5353 except TypeError:
5354 main.log.exception( self.name + ": Object not as expected" )
5355 return None
Flavio Castro82ee2f62016-06-07 15:04:12 -07005356 except pexpect.EOF:
5357 main.log.error( self.name + ": EOF exception found" )
5358 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005359 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005360 except Exception:
5361 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005362 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005363
Jon Hall06fd0df2021-01-25 15:50:06 -08005364 def logList( self, saveValues=True ):
5365 """
5366 Gets the current log levels and optionally saves them
5367 returns a dict of the log levels or
5368 returns main.FALSE if Error occurred
5369 """
5370 try:
5371 self.handle.sendline( "log:list" )
5372 self.handle.expect( self.karafPrompt )
5373
5374 response = self.handle.before
5375 logLevels = {}
5376 for line in response.splitlines():
5377 parsed = line.split('│')
5378 logger = parsed[0].strip()
5379 if len( parsed ) != 2 or 'Level' in parsed[1] or logger[0] == '─':
5380 continue
5381 level = parsed[1].strip()
5382 logLevels[ logger ] = level
5383 if saveValues:
5384 self.logLevels = logLevels
5385 return logLevels
5386 except pexpect.TIMEOUT:
5387 main.log.exception( self.name + ": TIMEOUT exception found" )
5388 main.cleanAndExit()
5389 except pexpect.EOF:
5390 main.log.error( self.name + ": EOF exception found" )
5391 main.log.error( self.name + ": " + self.handle.before )
5392 main.cleanAndExit()
5393 except Exception:
5394 main.log.exception( self.name + ": Uncaught exception!" )
5395 main.cleanAndExit()
5396
You Wangdb8cd0a2016-05-26 15:19:45 -07005397 def getGraphDict( self, timeout=60, includeHost=False ):
5398 """
5399 Return a dictionary which describes the latest network topology data as a
5400 graph.
5401 An example of the dictionary:
5402 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5403 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5404 Each vertex should at least have an 'edges' attribute which describes the
5405 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005406 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005407 list of attributes.
5408 An example of the edges dictionary:
5409 'edges': { vertex2: { 'port': ..., 'weight': ... },
5410 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005411 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005412 in topology data.
5413 """
5414 graphDict = {}
5415 try:
5416 links = self.links()
5417 links = json.loads( links )
5418 devices = self.devices()
5419 devices = json.loads( devices )
5420 idToDevice = {}
5421 for device in devices:
5422 idToDevice[ device[ 'id' ] ] = device
5423 if includeHost:
5424 hosts = self.hosts()
5425 # FIXME: support 'includeHost' argument
5426 for link in links:
5427 nodeA = link[ 'src' ][ 'device' ]
5428 nodeB = link[ 'dst' ][ 'device' ]
5429 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005430 if nodeA not in graphDict.keys():
5431 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005432 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005433 'type': idToDevice[ nodeA ][ 'type' ],
5434 'available': idToDevice[ nodeA ][ 'available' ],
5435 'role': idToDevice[ nodeA ][ 'role' ],
5436 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5437 'hw': idToDevice[ nodeA ][ 'hw' ],
5438 'sw': idToDevice[ nodeA ][ 'sw' ],
5439 'serial': idToDevice[ nodeA ][ 'serial' ],
5440 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005441 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005442 else:
5443 # Assert nodeB is not connected to any current links of nodeA
You Wang7d14d642019-01-23 15:10:08 -08005444 # assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
5445 pass
Jon Halle0f0b342017-04-18 11:43:47 -07005446 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5447 'type': link[ 'type' ],
5448 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005449 return graphDict
5450 except ( TypeError, ValueError ):
5451 main.log.exception( self.name + ": Object not as expected" )
5452 return None
5453 except KeyError:
5454 main.log.exception( self.name + ": KeyError exception found" )
5455 return None
5456 except AssertionError:
5457 main.log.exception( self.name + ": AssertionError exception found" )
5458 return None
5459 except pexpect.EOF:
5460 main.log.error( self.name + ": EOF exception found" )
5461 main.log.error( self.name + ": " + self.handle.before )
5462 return None
5463 except Exception:
5464 main.log.exception( self.name + ": Uncaught exception!" )
5465 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005466
5467 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005468 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005469 Send command to check intent-perf summary
5470 Returns: dictionary for intent-perf summary
5471 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005472 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005473 cmd = "intent-perf -s"
5474 respDic = {}
5475 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005476 assert resp is not None, "Error in sendline"
5477 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005478 try:
5479 # Generate the dictionary to return
5480 for l in resp.split( "\n" ):
5481 # Delete any white space in line
5482 temp = re.sub( r'\s+', '', l )
5483 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005484 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005485
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005486 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005487 main.log.exception( self.name + ": Object not as expected" )
5488 return None
5489 except KeyError:
5490 main.log.exception( self.name + ": KeyError exception found" )
5491 return None
5492 except AssertionError:
5493 main.log.exception( self.name + ": AssertionError exception found" )
5494 return None
5495 except pexpect.EOF:
5496 main.log.error( self.name + ": EOF exception found" )
5497 main.log.error( self.name + ": " + self.handle.before )
5498 return None
5499 except Exception:
5500 main.log.exception( self.name + ": Uncaught exception!" )
5501 return None
5502 return respDic
5503
Chiyu Chengec63bde2016-11-17 18:11:36 -08005504 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005505 """
5506 Searches the latest ONOS log file for the given search term and
5507 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005508
chengchiyu08303a02016-09-08 17:40:26 -07005509 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005510 searchTerm:
5511 The string to grep from the ONOS log.
5512 startLine:
5513 The term that decides which line is the start to search the searchTerm in
5514 the karaf log. For now, startTerm only works in 'first' mode.
5515 logNum:
5516 In some extreme cases, one karaf log is not big enough to contain all the
5517 information.Because of this, search mutiply logs is necessary to capture
5518 the right result. logNum is the number of karaf logs that we need to search
5519 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005520 mode:
5521 all: return all the strings that contain the search term
5522 last: return the last string that contains the search term
5523 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005524 num: return the number of times that the searchTerm appears in the log
5525 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005526 """
5527 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005528 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005529 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005530 logPath = '/opt/onos/log/karaf.log.'
5531 logPaths = '/opt/onos/log/karaf.log'
5532 for i in range( 1, logNum ):
5533 logPaths = logPath + str( i ) + " " + logPaths
5534 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005535 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005536 # 100000000 is just a extreme large number to make sure this function can
5537 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005538 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005539 if mode == 'all':
5540 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005541 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005542 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005543 elif mode == 'first':
5544 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5545 elif mode == 'num':
You Wangd91a70f2019-01-03 15:28:10 -08005546 cmd = cmd + " | grep \'" + searchTerm + "\' | wc -l"
5547 num = self.lineCount( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005548 return num
You Wang6d301d42017-04-21 10:49:33 -07005549 elif mode == 'total':
Jon Halld5a94fb2018-11-13 14:32:23 -08005550 totalLines = self.lineCount( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005551 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005552 else:
5553 main.log.error( self.name + " unsupported mode" )
5554 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005555 before = self.sendline( cmd )
5556 before = before.splitlines()
5557 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005558 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005559 return returnLines
5560 except AssertionError:
5561 main.log.error( self.name + " searchTerm is not string type" )
5562 return None
5563 except pexpect.EOF:
5564 main.log.error( self.name + ": EOF exception found" )
5565 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005566 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005567 except pexpect.TIMEOUT:
5568 main.log.error( self.name + ": TIMEOUT exception found" )
5569 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005570 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005571 except Exception:
5572 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005573 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005574
5575 def vplsShow( self, jsonFormat=True ):
5576 """
5577 Description: Returns result of onos:vpls show, which should list the
5578 configured VPLS networks and the assigned interfaces.
5579 Optional:
5580 * jsonFormat: enable json formatting of output
5581 Returns:
5582 The output of the command or None on error.
5583 """
5584 try:
5585 cmdStr = "vpls show"
5586 if jsonFormat:
5587 raise NotImplementedError
5588 cmdStr += " -j"
5589 handle = self.sendline( cmdStr )
5590 assert handle is not None, "Error in sendline"
5591 assert "Command not found:" not in handle, handle
5592 return handle
5593 except AssertionError:
5594 main.log.exception( "" )
5595 return None
5596 except TypeError:
5597 main.log.exception( self.name + ": Object not as expected" )
5598 return None
5599 except pexpect.EOF:
5600 main.log.error( self.name + ": EOF exception found" )
5601 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005602 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005603 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005604 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005605 return None
5606 except Exception:
5607 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005608 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005609
5610 def parseVplsShow( self ):
5611 """
5612 Parse the cli output of 'vpls show' into json output. This is required
5613 as there is currently no json output available.
5614 """
5615 try:
5616 output = []
5617 raw = self.vplsShow( jsonFormat=False )
5618 namePat = "VPLS name: (?P<name>\w+)"
5619 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5620 encapPat = "Encapsulation: (?P<encap>\w+)"
5621 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5622 mIter = re.finditer( pattern, raw )
5623 for match in mIter:
5624 item = {}
5625 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005626 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005627 if ifaces == [ "" ]:
5628 ifaces = []
5629 item[ 'interfaces' ] = ifaces
5630 encap = match.group( 'encap' )
5631 if encap != 'NONE':
5632 item[ 'encapsulation' ] = encap.lower()
5633 output.append( item )
5634 return output
5635 except Exception:
5636 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005637 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005638
5639 def vplsList( self, jsonFormat=True ):
5640 """
5641 Description: Returns result of onos:vpls list, which should list the
5642 configured VPLS networks.
5643 Optional:
5644 * jsonFormat: enable json formatting of output
5645 """
5646 try:
5647 cmdStr = "vpls list"
5648 if jsonFormat:
5649 raise NotImplementedError
5650 cmdStr += " -j"
5651 handle = self.sendline( cmdStr )
5652 assert handle is not None, "Error in sendline"
5653 assert "Command not found:" not in handle, handle
5654 return handle
5655 except AssertionError:
5656 main.log.exception( "" )
5657 return None
5658 except TypeError:
5659 main.log.exception( self.name + ": Object not as expected" )
5660 return None
5661 except pexpect.EOF:
5662 main.log.error( self.name + ": EOF exception found" )
5663 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005664 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005665 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005666 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005667 return None
5668 except Exception:
5669 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005670 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005671
5672 def vplsCreate( self, network ):
5673 """
5674 CLI command to create a new VPLS network.
5675 Required arguments:
5676 network - String name of the network to create.
5677 returns:
5678 main.TRUE on success and main.FALSE on failure
5679 """
5680 try:
5681 network = str( network )
5682 cmdStr = "vpls create "
5683 cmdStr += network
5684 output = self.sendline( cmdStr )
5685 assert output is not None, "Error in sendline"
5686 assert "Command not found:" not in output, output
5687 assert "Error executing command" not in output, output
5688 assert "VPLS already exists:" not in output, output
5689 return main.TRUE
5690 except AssertionError:
5691 main.log.exception( "" )
5692 return main.FALSE
5693 except TypeError:
5694 main.log.exception( self.name + ": Object not as expected" )
5695 return main.FALSE
5696 except pexpect.EOF:
5697 main.log.error( self.name + ": EOF exception found" )
5698 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005699 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005700 except Exception:
5701 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005702 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005703
5704 def vplsDelete( self, network ):
5705 """
5706 CLI command to delete a VPLS network.
5707 Required arguments:
5708 network - Name of the network to delete.
5709 returns:
5710 main.TRUE on success and main.FALSE on failure
5711 """
5712 try:
5713 network = str( network )
5714 cmdStr = "vpls delete "
5715 cmdStr += network
5716 output = self.sendline( cmdStr )
5717 assert output is not None, "Error in sendline"
5718 assert "Command not found:" not in output, output
5719 assert "Error executing command" not in output, output
5720 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005721 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005722 return main.TRUE
5723 except AssertionError:
5724 main.log.exception( "" )
5725 return main.FALSE
5726 except TypeError:
5727 main.log.exception( self.name + ": Object not as expected" )
5728 return main.FALSE
5729 except pexpect.EOF:
5730 main.log.error( self.name + ": EOF exception found" )
5731 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005732 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005733 except Exception:
5734 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005735 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005736
5737 def vplsAddIface( self, network, iface ):
5738 """
5739 CLI command to add an interface to a VPLS network.
5740 Required arguments:
5741 network - Name of the network to add the interface to.
5742 iface - The ONOS name for an interface.
5743 returns:
5744 main.TRUE on success and main.FALSE on failure
5745 """
5746 try:
5747 network = str( network )
5748 iface = str( iface )
5749 cmdStr = "vpls add-if "
5750 cmdStr += network + " " + iface
5751 output = self.sendline( cmdStr )
5752 assert output is not None, "Error in sendline"
5753 assert "Command not found:" not in output, output
5754 assert "Error executing command" not in output, output
5755 assert "already associated to network" not in output, output
5756 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005757 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005758 return main.TRUE
5759 except AssertionError:
5760 main.log.exception( "" )
5761 return main.FALSE
5762 except TypeError:
5763 main.log.exception( self.name + ": Object not as expected" )
5764 return main.FALSE
5765 except pexpect.EOF:
5766 main.log.error( self.name + ": EOF exception found" )
5767 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005768 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005769 except Exception:
5770 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005771 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005772
5773 def vplsRemIface( self, network, iface ):
5774 """
5775 CLI command to remove an interface from a VPLS network.
5776 Required arguments:
5777 network - Name of the network to remove the interface from.
5778 iface - Name of the interface to remove.
5779 returns:
5780 main.TRUE on success and main.FALSE on failure
5781 """
5782 try:
5783 iface = str( iface )
5784 cmdStr = "vpls rem-if "
5785 cmdStr += network + " " + iface
5786 output = self.sendline( cmdStr )
5787 assert output is not None, "Error in sendline"
5788 assert "Command not found:" not in output, output
5789 assert "Error executing command" not in output, output
5790 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005791 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005792 return main.TRUE
5793 except AssertionError:
5794 main.log.exception( "" )
5795 return main.FALSE
5796 except TypeError:
5797 main.log.exception( self.name + ": Object not as expected" )
5798 return main.FALSE
5799 except pexpect.EOF:
5800 main.log.error( self.name + ": EOF exception found" )
5801 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005802 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005803 except Exception:
5804 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005805 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005806
5807 def vplsClean( self ):
5808 """
5809 Description: Clears the VPLS app configuration.
5810 Returns: main.TRUE on success and main.FALSE on failure
5811 """
5812 try:
5813 cmdStr = "vpls clean"
5814 handle = self.sendline( cmdStr )
5815 assert handle is not None, "Error in sendline"
5816 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005817 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005818 return handle
5819 except AssertionError:
5820 main.log.exception( "" )
5821 return main.FALSE
5822 except TypeError:
5823 main.log.exception( self.name + ": Object not as expected" )
5824 return main.FALSE
5825 except pexpect.EOF:
5826 main.log.error( self.name + ": EOF exception found" )
5827 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005828 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005829 except Exception:
5830 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005831 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005832
5833 def vplsSetEncap( self, network, encapType ):
5834 """
5835 CLI command to add an interface to a VPLS network.
5836 Required arguments:
5837 network - Name of the network to create.
5838 encapType - Type of encapsulation.
5839 returns:
5840 main.TRUE on success and main.FALSE on failure
5841 """
5842 try:
5843 network = str( network )
5844 encapType = str( encapType ).upper()
5845 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5846 cmdStr = "vpls set-encap "
5847 cmdStr += network + " " + encapType
5848 output = self.sendline( cmdStr )
5849 assert output is not None, "Error in sendline"
5850 assert "Command not found:" not in output, output
5851 assert "Error executing command" not in output, output
5852 assert "already associated to network" not in output, output
5853 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005854 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005855 return main.TRUE
5856 except AssertionError:
5857 main.log.exception( "" )
5858 return main.FALSE
5859 except TypeError:
5860 main.log.exception( self.name + ": Object not as expected" )
5861 return main.FALSE
5862 except pexpect.EOF:
5863 main.log.error( self.name + ": EOF exception found" )
5864 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005865 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005866 except Exception:
5867 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005868 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005869
5870 def interfaces( self, jsonFormat=True ):
5871 """
5872 Description: Returns result of interfaces command.
5873 Optional:
5874 * jsonFormat: enable json formatting of output
5875 Returns:
5876 The output of the command or None on error.
5877 """
5878 try:
5879 cmdStr = "interfaces"
5880 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005881 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005882 cmdStr += " -j"
5883 handle = self.sendline( cmdStr )
5884 assert handle is not None, "Error in sendline"
5885 assert "Command not found:" not in handle, handle
5886 return handle
5887 except AssertionError:
5888 main.log.exception( "" )
5889 return None
5890 except TypeError:
5891 main.log.exception( self.name + ": Object not as expected" )
5892 return None
5893 except pexpect.EOF:
5894 main.log.error( self.name + ": EOF exception found" )
5895 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005896 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005897 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005898 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005899 return None
5900 except Exception:
5901 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005902 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005903
5904 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005905 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005906 Get the timestamp of searchTerm from karaf log.
5907
5908 Arguments:
5909 splitTerm_before and splitTerm_after:
5910
5911 The terms that split the string that contains the timeStamp of
5912 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5913 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5914 and the splitTerm_after is "x"
5915
5916 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005917 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005918 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005919 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005920 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005921 return main.ERROR
5922 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005923 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005924 main.log.warn( "Captured timestamp string is empty" )
5925 return main.ERROR
5926 lines = lines[ 0 ]
5927 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005928 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005929 # get the target value
5930 line = lines.split( splitTerm_before )
5931 key = line[ 1 ].split( splitTerm_after )
5932 return int( key[ 0 ] )
5933 except IndexError:
5934 main.log.warn( "Index Error!" )
5935 return main.ERROR
5936 except AssertionError:
5937 main.log.warn( "Search Term Not Found " )
5938 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005939
5940 def workQueueAdd( self, queueName, value ):
5941 """
5942 CLI command to add a string to the specified Work Queue.
5943 This function uses the distributed primitives test app, which
5944 gives some cli access to distributed primitives for testing
5945 purposes only.
5946
5947 Required arguments:
5948 queueName - The name of the queue to add to
5949 value - The value to add to the queue
5950 returns:
5951 main.TRUE on success, main.FALSE on failure and
5952 main.ERROR on error.
5953 """
5954 try:
5955 queueName = str( queueName )
5956 value = str( value )
5957 prefix = "work-queue-test"
5958 operation = "add"
5959 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5960 output = self.distPrimitivesSend( cmdStr )
5961 if "Invalid operation name" in output:
5962 main.log.warn( output )
5963 return main.ERROR
5964 elif "Done" in output:
5965 return main.TRUE
5966 except TypeError:
5967 main.log.exception( self.name + ": Object not as expected" )
5968 return main.ERROR
5969 except Exception:
5970 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005971 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005972
5973 def workQueueAddMultiple( self, queueName, value1, value2 ):
5974 """
5975 CLI command to add two strings to the specified Work Queue.
5976 This function uses the distributed primitives test app, which
5977 gives some cli access to distributed primitives for testing
5978 purposes only.
5979
5980 Required arguments:
5981 queueName - The name of the queue to add to
5982 value1 - The first value to add to the queue
5983 value2 - The second value to add to the queue
5984 returns:
5985 main.TRUE on success, main.FALSE on failure and
5986 main.ERROR on error.
5987 """
5988 try:
5989 queueName = str( queueName )
5990 value1 = str( value1 )
5991 value2 = str( value2 )
5992 prefix = "work-queue-test"
5993 operation = "addMultiple"
5994 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5995 output = self.distPrimitivesSend( cmdStr )
5996 if "Invalid operation name" in output:
5997 main.log.warn( output )
5998 return main.ERROR
5999 elif "Done" in output:
6000 return main.TRUE
6001 except TypeError:
6002 main.log.exception( self.name + ": Object not as expected" )
6003 return main.ERROR
6004 except Exception:
6005 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006006 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006007
6008 def workQueueTakeAndComplete( self, queueName, number=1 ):
6009 """
6010 CLI command to take a value from the specified Work Queue and compelte it.
6011 This function uses the distributed primitives test app, which
6012 gives some cli access to distributed primitives for testing
6013 purposes only.
6014
6015 Required arguments:
6016 queueName - The name of the queue to add to
6017 number - The number of items to take and complete
6018 returns:
6019 main.TRUE on success, main.FALSE on failure and
6020 main.ERROR on error.
6021 """
6022 try:
6023 queueName = str( queueName )
6024 number = str( int( number ) )
6025 prefix = "work-queue-test"
6026 operation = "takeAndComplete"
6027 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
6028 output = self.distPrimitivesSend( cmdStr )
6029 if "Invalid operation name" in output:
6030 main.log.warn( output )
6031 return main.ERROR
6032 elif "Done" in output:
6033 return main.TRUE
6034 except TypeError:
6035 main.log.exception( self.name + ": Object not as expected" )
6036 return main.ERROR
6037 except Exception:
6038 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006039 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006040
6041 def workQueueDestroy( self, queueName ):
6042 """
6043 CLI command to destroy the specified Work Queue.
6044 This function uses the distributed primitives test app, which
6045 gives some cli access to distributed primitives for testing
6046 purposes only.
6047
6048 Required arguments:
6049 queueName - The name of the queue to add to
6050 returns:
6051 main.TRUE on success, main.FALSE on failure and
6052 main.ERROR on error.
6053 """
6054 try:
6055 queueName = str( queueName )
6056 prefix = "work-queue-test"
6057 operation = "destroy"
6058 cmdStr = " ".join( [ prefix, queueName, operation ] )
6059 output = self.distPrimitivesSend( cmdStr )
6060 if "Invalid operation name" in output:
6061 main.log.warn( output )
6062 return main.ERROR
6063 return main.TRUE
6064 except TypeError:
6065 main.log.exception( self.name + ": Object not as expected" )
6066 return main.ERROR
6067 except Exception:
6068 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006069 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006070
6071 def workQueueTotalPending( self, queueName ):
6072 """
6073 CLI command to get the Total Pending items of the specified Work Queue.
6074 This function uses the distributed primitives test app, which
6075 gives some cli access to distributed primitives for testing
6076 purposes only.
6077
6078 Required arguments:
6079 queueName - The name of the queue to add to
6080 returns:
6081 The number of Pending items in the specified work queue or
6082 None on error
6083 """
6084 try:
6085 queueName = str( queueName )
6086 prefix = "work-queue-test"
6087 operation = "totalPending"
6088 cmdStr = " ".join( [ prefix, queueName, operation ] )
6089 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08006090 main.log.debug( self.name + ": work queue unparsed: " + output )
6091 output = output.split( "\r\n" )[ -1 ]
6092 main.log.debug( self.name + ": work queue parsed: " + output )
Jon Halle0f0b342017-04-18 11:43:47 -07006093 pattern = r'\d+'
6094 if "Invalid operation name" in output:
6095 main.log.warn( output )
6096 return None
6097 else:
6098 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006099 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006100 except ( AttributeError, TypeError ):
6101 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6102 return None
6103 except Exception:
6104 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006105 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006106
6107 def workQueueTotalCompleted( self, queueName ):
6108 """
6109 CLI command to get the Total Completed items of the specified Work Queue.
6110 This function uses the distributed primitives test app, which
6111 gives some cli access to distributed primitives for testing
6112 purposes only.
6113
6114 Required arguments:
6115 queueName - The name of the queue to add to
6116 returns:
6117 The number of complete items in the specified work queue or
6118 None on error
6119 """
6120 try:
6121 queueName = str( queueName )
6122 prefix = "work-queue-test"
6123 operation = "totalCompleted"
6124 cmdStr = " ".join( [ prefix, queueName, operation ] )
6125 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08006126 main.log.debug( self.name + ": work queue unparsed: " + output )
6127 output = output.split( "\r\n" )[ -1 ]
6128 main.log.debug( self.name + ": work queue parsed: " + output )
Jon Halle0f0b342017-04-18 11:43:47 -07006129 pattern = r'\d+'
6130 if "Invalid operation name" in output:
6131 main.log.warn( output )
6132 return None
6133 else:
6134 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006135 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006136 except ( AttributeError, TypeError ):
6137 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6138 return None
6139 except Exception:
6140 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006141 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006142
6143 def workQueueTotalInProgress( self, queueName ):
6144 """
6145 CLI command to get the Total In Progress items of the specified Work Queue.
6146 This function uses the distributed primitives test app, which
6147 gives some cli access to distributed primitives for testing
6148 purposes only.
6149
6150 Required arguments:
6151 queueName - The name of the queue to add to
6152 returns:
6153 The number of In Progress items in the specified work queue or
6154 None on error
6155 """
6156 try:
6157 queueName = str( queueName )
6158 prefix = "work-queue-test"
6159 operation = "totalInProgress"
6160 cmdStr = " ".join( [ prefix, queueName, operation ] )
6161 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08006162 main.log.debug( self.name + ": work queue unparsed: " + output )
6163 output = output.split( "\r\n" )[ -1 ]
6164 main.log.debug( self.name + ": work queue parsed: " + output )
Jon Halle0f0b342017-04-18 11:43:47 -07006165 pattern = r'\d+'
6166 if "Invalid operation name" in output:
6167 main.log.warn( output )
6168 return None
6169 else:
6170 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006171 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006172 except ( AttributeError, TypeError ):
6173 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6174 return None
6175 except Exception:
6176 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006177 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00006178
6179 def events( self, args='-a' ):
6180 """
6181 Description: Returns events -a command output
6182 Optional:
6183 add other arguments
6184 """
6185 try:
6186 cmdStr = "events"
6187 if args:
6188 cmdStr += " " + args
6189 handle = self.sendline( cmdStr )
6190 assert handle is not None, "Error in sendline"
6191 assert "Command not found:" not in handle, handle
6192 return handle
6193 except AssertionError:
6194 main.log.exception( "" )
6195 return None
6196 except TypeError:
6197 main.log.exception( self.name + ": Object not as expected" )
6198 return None
6199 except pexpect.EOF:
6200 main.log.error( self.name + ": EOF exception found" )
6201 main.log.error( self.name + ": " + self.handle.before )
6202 main.cleanAndExit()
6203 except Exception:
6204 main.log.exception( self.name + ": Uncaught exception!" )
6205 main.cleanAndExit()
6206
6207 def getMaster( self, deviceID ):
6208 """
6209 Description: Obtains current master using "roles" command for a specific deviceID
6210 """
6211 try:
6212 return str( self.getRole( deviceID )[ 'master' ] )
6213 except AssertionError:
6214 main.log.exception( "" )
6215 return None
6216 except TypeError:
6217 main.log.exception( self.name + ": Object not as expected" )
6218 return None
6219 except pexpect.EOF:
6220 main.log.error( self.name + ": EOF exception found" )
6221 main.log.error( self.name + ": " + self.handle.before )
6222 main.cleanAndExit()
6223 except Exception:
6224 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07006225 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08006226
6227 def issu( self ):
6228 """
6229 Short summary of In-Service Software Upgrade status
6230
6231 Returns the output of the cli command or None on Error
6232 """
6233 try:
6234 cmdStr = "issu"
6235 handle = self.sendline( cmdStr )
6236 assert handle is not None, "Error in sendline"
6237 assert "Command not found:" not in handle, handle
6238 assert "Unsupported command:" not in handle, handle
6239 return handle
6240 except AssertionError:
6241 main.log.exception( "" )
6242 return None
6243 except TypeError:
6244 main.log.exception( self.name + ": Object not as expected" )
6245 return None
6246 except pexpect.EOF:
6247 main.log.error( self.name + ": EOF exception found" )
6248 main.log.error( self.name + ": " + self.handle.before )
6249 main.cleanAndExit()
6250 except Exception:
6251 main.log.exception( self.name + ": Uncaught exception!" )
6252 main.cleanAndExit()
6253
6254 def issuInit( self ):
6255 """
6256 Initiates an In-Service Software Upgrade
6257
6258 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6259 """
6260 try:
6261 cmdStr = "issu init"
6262 handle = self.sendline( cmdStr )
6263 assert handle is not None, "Error in sendline"
6264 assert "Command not found:" not in handle, handle
6265 assert "Unsupported command:" not in handle, handle
6266 if "Initialized" in handle:
6267 return main.TRUE
6268 else:
6269 return main.FALSE
6270 except AssertionError:
6271 main.log.exception( "" )
6272 return main.ERROR
6273 except TypeError:
6274 main.log.exception( self.name + ": Object not as expected" )
6275 return main.ERROR
6276 except pexpect.EOF:
6277 main.log.error( self.name + ": EOF exception found" )
6278 main.log.error( self.name + ": " + self.handle.before )
6279 main.cleanAndExit()
6280 except Exception:
6281 main.log.exception( self.name + ": Uncaught exception!" )
6282 main.cleanAndExit()
6283
6284 def issuUpgrade( self ):
6285 """
6286 Transitions stores to upgraded nodes
6287
6288 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6289 """
6290 try:
6291 cmdStr = "issu upgrade"
6292 handle = self.sendline( cmdStr )
6293 assert handle is not None, "Error in sendline"
6294 assert "Command not found:" not in handle, handle
6295 assert "Unsupported command:" not in handle, handle
6296 if "Upgraded" in handle:
6297 return main.TRUE
6298 else:
6299 return main.FALSE
6300 except AssertionError:
6301 main.log.exception( "" )
6302 return main.ERROR
6303 except TypeError:
6304 main.log.exception( self.name + ": Object not as expected" )
6305 return main.ERROR
6306 except pexpect.EOF:
6307 main.log.error( self.name + ": EOF exception found" )
6308 main.log.error( self.name + ": " + self.handle.before )
6309 main.cleanAndExit()
6310 except Exception:
6311 main.log.exception( self.name + ": Uncaught exception!" )
6312 main.cleanAndExit()
6313
6314 def issuCommit( self ):
6315 """
6316 Finalizes an In-Service Software Upgrade
6317
6318 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6319 """
6320 try:
6321 cmdStr = "issu commit"
6322 handle = self.sendline( cmdStr )
6323 assert handle is not None, "Error in sendline"
6324 assert "Command not found:" not in handle, handle
6325 assert "Unsupported command:" not in handle, handle
6326 # TODO: Check the version returned by this command
6327 if "Committed version" in handle:
6328 return main.TRUE
6329 else:
6330 return main.FALSE
6331 except AssertionError:
6332 main.log.exception( "" )
6333 return main.ERROR
6334 except TypeError:
6335 main.log.exception( self.name + ": Object not as expected" )
6336 return main.ERROR
6337 except pexpect.EOF:
6338 main.log.error( self.name + ": EOF exception found" )
6339 main.log.error( self.name + ": " + self.handle.before )
6340 main.cleanAndExit()
6341 except Exception:
6342 main.log.exception( self.name + ": Uncaught exception!" )
6343 main.cleanAndExit()
6344
6345 def issuRollback( self ):
6346 """
6347 Rolls back an In-Service Software Upgrade
6348
6349 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6350 """
6351 try:
6352 cmdStr = "issu rollback"
6353 handle = self.sendline( cmdStr )
6354 assert handle is not None, "Error in sendline"
6355 assert "Command not found:" not in handle, handle
6356 assert "Unsupported command:" not in handle, handle
6357 # TODO: Check the version returned by this command
6358 if "Rolled back to version" in handle:
6359 return main.TRUE
6360 else:
6361 return main.FALSE
6362 except AssertionError:
6363 main.log.exception( "" )
6364 return main.ERROR
6365 except TypeError:
6366 main.log.exception( self.name + ": Object not as expected" )
6367 return main.ERROR
6368 except pexpect.EOF:
6369 main.log.error( self.name + ": EOF exception found" )
6370 main.log.error( self.name + ": " + self.handle.before )
6371 main.cleanAndExit()
6372 except Exception:
6373 main.log.exception( self.name + ": Uncaught exception!" )
6374 main.cleanAndExit()
6375
6376 def issuReset( self ):
6377 """
6378 Resets the In-Service Software Upgrade status after a rollback
6379
6380 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6381 """
6382 try:
6383 cmdStr = "issu reset"
6384 handle = self.sendline( cmdStr )
6385 assert handle is not None, "Error in sendline"
6386 assert "Command not found:" not in handle, handle
6387 assert "Unsupported command:" not in handle, handle
6388 # TODO: Check the version returned by this command
6389 if "Reset version" in handle:
6390 return main.TRUE
6391 else:
6392 return main.FALSE
6393 except AssertionError:
6394 main.log.exception( "" )
6395 return main.ERROR
6396 except TypeError:
6397 main.log.exception( self.name + ": Object not as expected" )
6398 return main.ERROR
6399 except pexpect.EOF:
6400 main.log.error( self.name + ": EOF exception found" )
6401 main.log.error( self.name + ": " + self.handle.before )
6402 main.cleanAndExit()
6403 except Exception:
6404 main.log.exception( self.name + ": Uncaught exception!" )
6405 main.cleanAndExit()
6406
6407 def issuStatus( self ):
6408 """
6409 Status of an In-Service Software Upgrade
6410
6411 Returns the output of the cli command or None on Error
6412 """
6413 try:
6414 cmdStr = "issu status"
6415 handle = self.sendline( cmdStr )
6416 assert handle is not None, "Error in sendline"
6417 assert "Command not found:" not in handle, handle
6418 assert "Unsupported command:" not in handle, handle
6419 return handle
6420 except AssertionError:
6421 main.log.exception( "" )
6422 return None
6423 except TypeError:
6424 main.log.exception( self.name + ": Object not as expected" )
6425 return None
6426 except pexpect.EOF:
6427 main.log.error( self.name + ": EOF exception found" )
6428 main.log.error( self.name + ": " + self.handle.before )
6429 main.cleanAndExit()
6430 except Exception:
6431 main.log.exception( self.name + ": Uncaught exception!" )
6432 main.cleanAndExit()
6433
6434 def issuVersion( self ):
6435 """
6436 Get the version of an In-Service Software Upgrade
6437
6438 Returns the output of the cli command or None on Error
6439 """
6440 try:
6441 cmdStr = "issu version"
6442 handle = self.sendline( cmdStr )
6443 assert handle is not None, "Error in sendline"
6444 assert "Command not found:" not in handle, handle
6445 assert "Unsupported command:" not in handle, handle
6446 return handle
6447 except AssertionError:
6448 main.log.exception( "" )
6449 return None
6450 except TypeError:
6451 main.log.exception( self.name + ": Object not as expected" )
6452 return None
6453 except pexpect.EOF:
6454 main.log.error( self.name + ": EOF exception found" )
6455 main.log.error( self.name + ": " + self.handle.before )
6456 main.cleanAndExit()
6457 except Exception:
6458 main.log.exception( self.name + ": Uncaught exception!" )
6459 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006460
6461 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6462 """
6463 Create a multicast route by calling 'mcast-join' command
6464 sIP: source IP of the multicast route
6465 groupIP: group IP of the multicast route
6466 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6467 dPorts: a list of destination ports of the multicast route
6468 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6469 """
6470 try:
6471 cmdStr = "mcast-join"
6472 cmdStr += " " + str( sIP )
6473 cmdStr += " " + str( groupIP )
6474 cmdStr += " " + str( sPort )
6475 assert isinstance( dPorts, list )
6476 for dPort in dPorts:
6477 cmdStr += " " + str( dPort )
6478 handle = self.sendline( cmdStr )
6479 assert handle is not None, "Error in sendline"
6480 assert "Command not found:" not in handle, handle
6481 assert "Unsupported command:" not in handle, handle
6482 assert "Error executing command" not in handle, handle
6483 if "Added the mcast route" in handle:
6484 return main.TRUE
6485 else:
6486 return main.FALSE
6487 except AssertionError:
6488 main.log.exception( "" )
6489 return None
6490 except TypeError:
6491 main.log.exception( self.name + ": Object not as expected" )
6492 return None
6493 except pexpect.EOF:
6494 main.log.error( self.name + ": EOF exception found" )
6495 main.log.error( self.name + ": " + self.handle.before )
6496 main.cleanAndExit()
6497 except Exception:
6498 main.log.exception( self.name + ": Uncaught exception!" )
6499 main.cleanAndExit()
6500
6501 def mcastDelete( self, sIP, groupIP, dPorts ):
6502 """
6503 Delete a multicast route by calling 'mcast-delete' command
6504 sIP: source IP of the multicast route
6505 groupIP: group IP of the multicast route
6506 dPorts: a list of destination ports of the multicast route
6507 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6508 """
6509 try:
6510 cmdStr = "mcast-delete"
6511 cmdStr += " " + str( sIP )
6512 cmdStr += " " + str( groupIP )
6513 assert isinstance( dPorts, list )
6514 for dPort in dPorts:
6515 cmdStr += " " + str( dPort )
6516 handle = self.sendline( cmdStr )
6517 assert handle is not None, "Error in sendline"
6518 assert "Command not found:" not in handle, handle
6519 assert "Unsupported command:" not in handle, handle
6520 assert "Error executing command" not in handle, handle
6521 if "Updated the mcast route" in handle:
6522 return main.TRUE
6523 else:
6524 return main.FALSE
6525 except AssertionError:
6526 main.log.exception( "" )
6527 return None
6528 except TypeError:
6529 main.log.exception( self.name + ": Object not as expected" )
6530 return None
6531 except pexpect.EOF:
6532 main.log.error( self.name + ": EOF exception found" )
6533 main.log.error( self.name + ": " + self.handle.before )
6534 main.cleanAndExit()
6535 except Exception:
6536 main.log.exception( self.name + ": Uncaught exception!" )
6537 main.cleanAndExit()
6538
6539 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6540 """
6541 Create a multicast route by calling 'mcast-host-join' command
6542 sAddr: we can provide * for ASM or a specific address for SSM
6543 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006544 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006545 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6546 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6547 """
6548 try:
6549 cmdStr = "mcast-host-join"
6550 cmdStr += " -sAddr " + str( sAddr )
6551 cmdStr += " -gAddr " + str( gAddr )
6552 assert isinstance( srcs, list )
6553 for src in srcs:
6554 cmdStr += " -srcs " + str( src )
6555 assert isinstance( sinks, list )
6556 for sink in sinks:
6557 cmdStr += " -sinks " + str( sink )
6558 handle = self.sendline( cmdStr )
6559 assert handle is not None, "Error in sendline"
6560 assert "Command not found:" not in handle, handle
6561 assert "Unsupported command:" not in handle, handle
6562 assert "Error executing command" not in handle, handle
6563 if "Added the mcast route" in handle:
6564 return main.TRUE
6565 else:
6566 return main.FALSE
6567 except AssertionError:
6568 main.log.exception( "" )
6569 return None
6570 except TypeError:
6571 main.log.exception( self.name + ": Object not as expected" )
6572 return None
6573 except pexpect.EOF:
6574 main.log.error( self.name + ": EOF exception found" )
6575 main.log.error( self.name + ": " + self.handle.before )
6576 main.cleanAndExit()
6577 except Exception:
6578 main.log.exception( self.name + ": Uncaught exception!" )
6579 main.cleanAndExit()
6580
6581 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6582 """
6583 Delete multicast sink(s) by calling 'mcast-host-delete' command
6584 sAddr: we can provide * for ASM or a specific address for SSM
6585 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006586 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006587 will delete the route if not specified
6588 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6589 """
6590 try:
6591 cmdStr = "mcast-host-delete"
6592 cmdStr += " -sAddr " + str( sAddr )
6593 cmdStr += " -gAddr " + str( gAddr )
6594 if host:
6595 cmdStr += " -h " + str( host )
6596 handle = self.sendline( cmdStr )
6597 assert handle is not None, "Error in sendline"
6598 assert "Command not found:" not in handle, handle
6599 assert "Unsupported command:" not in handle, handle
6600 assert "Error executing command" not in handle, handle
6601 if "Updated the mcast route" in handle:
6602 return main.TRUE
6603 elif "Deleted the mcast route" in handle:
6604 return main.TRUE
6605 else:
6606 return main.FALSE
6607 except AssertionError:
6608 main.log.exception( "" )
6609 return None
6610 except TypeError:
6611 main.log.exception( self.name + ": Object not as expected" )
6612 return None
6613 except pexpect.EOF:
6614 main.log.error( self.name + ": EOF exception found" )
6615 main.log.error( self.name + ": " + self.handle.before )
6616 main.cleanAndExit()
6617 except Exception:
6618 main.log.exception( self.name + ": Uncaught exception!" )
6619 main.cleanAndExit()
6620
You Wang547893e2018-05-08 13:34:59 -07006621 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6622 """
6623 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6624 sAddr: we can provide * for ASM or a specific address for SSM
6625 gAddr: specifies multicast group address
6626 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6627 will delete the route if not specified
6628 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6629 """
6630 try:
6631 cmdStr = "mcast-sink-delete"
6632 cmdStr += " -sAddr " + str( sAddr )
6633 cmdStr += " -gAddr " + str( gAddr )
6634 if sink:
6635 cmdStr += " -s " + str( sink )
6636 handle = self.sendline( cmdStr )
6637 assert handle is not None, "Error in sendline"
6638 assert "Command not found:" not in handle, handle
6639 assert "Unsupported command:" not in handle, handle
6640 assert "Error executing command" not in handle, handle
6641 if "Updated the mcast route" in handle:
6642 return main.TRUE
6643 elif "Deleted the mcast route" in handle:
6644 return main.TRUE
6645 else:
6646 return main.FALSE
6647 except AssertionError:
6648 main.log.exception( "" )
6649 return None
6650 except TypeError:
6651 main.log.exception( self.name + ": Object not as expected" )
6652 return None
6653 except pexpect.EOF:
6654 main.log.error( self.name + ": EOF exception found" )
6655 main.log.error( self.name + ": " + self.handle.before )
6656 main.cleanAndExit()
6657 except Exception:
6658 main.log.exception( self.name + ": Uncaught exception!" )
6659 main.cleanAndExit()
6660
You Wange24d6272018-03-27 21:18:50 -07006661 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6662 """
6663 Delete multicast src(s) by calling 'mcast-source-delete' command
6664 sAddr: we can provide * for ASM or a specific address for SSM
6665 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006666 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 -07006667 will delete the route if not specified
6668 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6669 """
6670 try:
6671 cmdStr = "mcast-source-delete"
6672 cmdStr += " -sAddr " + str( sAddr )
6673 cmdStr += " -gAddr " + str( gAddr )
6674 if srcs:
6675 assert isinstance( srcs, list )
6676 for src in srcs:
6677 cmdStr += " -src " + str( src )
6678 handle = self.sendline( cmdStr )
6679 assert handle is not None, "Error in sendline"
6680 assert "Command not found:" not in handle, handle
6681 assert "Unsupported command:" not in handle, handle
6682 assert "Error executing command" not in handle, handle
6683 if "Updated the mcast route" in handle:
6684 return main.TRUE
6685 elif "Deleted the mcast route" in handle:
6686 return main.TRUE
6687 else:
6688 return main.FALSE
6689 except AssertionError:
6690 main.log.exception( "" )
6691 return None
6692 except TypeError:
6693 main.log.exception( self.name + ": Object not as expected" )
6694 return None
6695 except pexpect.EOF:
6696 main.log.error( self.name + ": EOF exception found" )
6697 main.log.error( self.name + ": " + self.handle.before )
6698 main.cleanAndExit()
6699 except Exception:
6700 main.log.exception( self.name + ": Uncaught exception!" )
6701 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006702
6703 def netcfg( self, jsonFormat=True, args="" ):
6704 """
6705 Run netcfg cli command with given args
6706 """
6707 try:
6708 cmdStr = "netcfg"
6709 if jsonFormat:
6710 cmdStr = cmdStr + " -j"
6711 if args:
6712 cmdStr = cmdStr + " " + str( args )
6713 handle = self.sendline( cmdStr )
6714 assert handle is not None, "Error in sendline"
6715 assert "Command not found:" not in handle, handle
6716 assert "Unsupported command:" not in handle, handle
6717 assert "Error executing command" not in handle, handle
6718 return handle
6719 except AssertionError:
6720 main.log.exception( "" )
6721 return None
6722 except TypeError:
6723 main.log.exception( self.name + ": Object not as expected" )
6724 return None
6725 except pexpect.EOF:
6726 main.log.error( self.name + ": EOF exception found" )
6727 main.log.error( self.name + ": " + self.handle.before )
6728 main.cleanAndExit()
6729 except Exception:
6730 main.log.exception( self.name + ": Uncaught exception!" )
6731 main.cleanAndExit()
6732
You Wang0fa76e72018-05-18 11:33:25 -07006733 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True, simple=False ):
You Wang5da39c82018-04-26 22:55:08 -07006734 """
You Wang54b1d672018-06-11 16:44:13 -07006735 Compose and return a list of t3-troubleshoot cli commands for given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006736 Options:
6737 sAddr: IP address of the source host
6738 dAddr: IP address of the destination host
You Wang0fa76e72018-05-18 11:33:25 -07006739 ipv6: True if hosts are IPv6
6740 verbose: return verbose t3 output if True
6741 simple: compose command for t3-troubleshoot-simple if True
You Wang5da39c82018-04-26 22:55:08 -07006742 """
6743 try:
6744 # Collect information of both hosts from onos
6745 hosts = self.hosts()
6746 hosts = json.loads( hosts )
6747 sHost = None
6748 dHost = None
6749 for host in hosts:
6750 if sAddr in host[ "ipAddresses" ]:
6751 sHost = host
6752 elif dAddr in host[ "ipAddresses" ]:
6753 dHost = host
6754 if sHost and dHost:
6755 break
6756 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang54b1d672018-06-11 16:44:13 -07006757 cmdList = []
You Wang5d9527b2018-05-29 17:08:54 -07006758 if simple:
6759 assert dHost, "Not able to find host with IP {}".format( dAddr )
You Wang54b1d672018-06-11 16:44:13 -07006760 cmdStr = "t3-troubleshoot-simple"
6761 if verbose:
6762 cmdStr += " -vv"
6763 if ipv6:
6764 cmdStr += " -et ipv6"
You Wang0fa76e72018-05-18 11:33:25 -07006765 cmdStr += " {}/{} {}/{}".format( sHost[ "mac" ], sHost[ "vlan" ], dHost[ "mac" ], dHost[ "vlan" ] )
You Wang54b1d672018-06-11 16:44:13 -07006766 cmdList.append( cmdStr )
You Wang0fa76e72018-05-18 11:33:25 -07006767 else:
You Wang54b1d672018-06-11 16:44:13 -07006768 for location in sHost[ "locations" ]:
6769 cmdStr = "t3-troubleshoot"
6770 if verbose:
6771 cmdStr += " -vv"
6772 if ipv6:
6773 cmdStr += " -et ipv6"
6774 cmdStr += " -s " + str( sAddr )
6775 cmdStr += " -sp " + str( location[ "elementId" ] ) + "/" + str( location[ "port" ] )
6776 cmdStr += " -sm " + str( sHost[ "mac" ] )
6777 if sHost[ "vlan" ] != "None":
6778 cmdStr += " -vid " + sHost[ "vlan" ]
6779 cmdStr += " -d " + str( dAddr )
6780 netcfg = self.netcfg( args="devices {}".format( location[ "elementId" ] ) )
6781 netcfg = json.loads( netcfg )
6782 assert netcfg, "Failed to get netcfg"
6783 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6784 cmdList.append( cmdStr )
6785 return cmdList
You Wang5da39c82018-04-26 22:55:08 -07006786 except AssertionError:
6787 main.log.exception( "" )
6788 return None
6789 except ( KeyError, TypeError ):
6790 main.log.exception( self.name + ": Object not as expected" )
6791 return None
6792 except Exception:
6793 main.log.exception( self.name + ": Uncaught exception!" )
6794 main.cleanAndExit()
6795
6796 def t3( self, sAddr, dAddr, ipv6=False ):
6797 """
You Wang54b1d672018-06-11 16:44:13 -07006798 Run t3-troubleshoot cli commands for all posible routes given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006799 Options:
6800 sAddr: IP address of the source host
6801 dAddr: IP address of the destination host
6802 """
6803 try:
You Wang54b1d672018-06-11 16:44:13 -07006804 cmdList = self.composeT3Command( sAddr, dAddr, ipv6 )
6805 assert cmdList is not None, "composeT3Command returned None"
6806 t3Output = ""
6807 for cmdStr in cmdList:
6808 handle = self.sendline( cmdStr )
6809 assert handle is not None, "Error in sendline"
6810 assert "Command not found:" not in handle, handle
6811 assert "Unsupported command:" not in handle, handle
6812 assert "Error executing command" not in handle, handle
6813 assert "Tracing packet" in handle
6814 t3Output += handle
6815 return t3Output
You Wang5da39c82018-04-26 22:55:08 -07006816 except AssertionError:
6817 main.log.exception( "" )
6818 return None
6819 except pexpect.EOF:
6820 main.log.error( self.name + ": EOF exception found" )
6821 main.log.error( self.name + ": " + self.handle.before )
6822 main.cleanAndExit()
6823 except Exception:
6824 main.log.exception( self.name + ": Uncaught exception!" )
6825 main.cleanAndExit()
Jon Hall3c0114c2020-08-11 15:07:42 -07006826
6827 def prepareForCLI( self, debug=True, maxRetries=120 ):
6828 """
6829 Prepare docker container to connect to onos cli
6830 """
6831 try:
6832 # Wait for log files to be created
6833 ready = 0
6834 retries = 0
6835 while not ready and retries < maxRetries:
6836 retries += 1
6837 self.handle.sendline( "ls -al /root/onos/apache-karaf-*/data/log" )
6838 ready = self.handle.expect( [ "No such file or directory", self.dockerPrompt ] )
6839 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
6840 if not ready:
6841 self.handle.expect( self.dockerPrompt )
6842 time.sleep( 1 )
Jon Hall3c0114c2020-08-11 15:07:42 -07006843
6844 cmdList = []
6845 cmdList.append( "apt-get update" )
6846 cmdList.append( "apt-get install -y openssh-server" )
6847 # Some built in scripts are hardcoded
6848 cmdList.append( "ln -s /root/onos /opt/onos" )
6849 cmdList.append( "ln -s /root/onos/apache-karaf-*/data/log /opt/onos/log" )
6850 cmdList.append( "ls -al /opt/onos" )
6851 output = ""
6852 for cmdStr in cmdList:
6853 self.handle.sendline( cmdStr )
Jon Hall627b1572020-12-01 12:01:15 -08006854 self.handle.expect( self.dockerPrompt, timeout=420 )
Jon Hall3c0114c2020-08-11 15:07:42 -07006855 self.handle.sendline( "" )
6856 self.handle.expect( self.dockerPrompt )
6857 handle = self.handle.before
6858 assert "command not found" not in handle, handle
6859 assert "No such file or directory" not in handle, handle
6860 output += handle
6861 if debug:
6862 main.log.debug( "%s: %s" % ( self.name, output ) )
6863 return output
6864 except AssertionError:
6865 main.log.exception( "" )
6866 return None
6867 except pexpect.EOF:
6868 main.log.error( self.name + ": EOF exception found" )
6869 main.log.error( self.name + ": " + self.handle.before )
6870 main.cleanAndExit()
6871 except Exception:
6872 main.log.exception( self.name + ": Uncaught exception!" )
6873 main.cleanAndExit()
6874
6875 def onosSecureSSH( self, userName="onos", userPWD="rocks" ):
6876 """
6877 Enables secure access to ONOS console
6878 by removing default users & keys.
6879
6880 bin/onos-user-password onos rocks
6881
6882 Returns: main.TRUE on success and main.FALSE on failure
6883 """
6884
6885 try:
6886 self.handle.sendline( "" )
6887 self.handle.expect( self.dockerPrompt )
6888
6889 self.handle.sendline( "[ ! -f ~/.ssh/id_rsa.pub ] && ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' -q" )
6890 self.handle.expect( self.dockerPrompt )
6891 main.log.debug( "%s: %s%s" % ( self.name, self.handle.before, self.handle.after ) )
6892
6893 self.handle.sendline( "bin/onos-user-key $(id -un) $(cut -d\\\\ -f2 ~/.ssh/id_rsa.pub)" )
6894 self.handle.expect( pexpect.TIMEOUT, timeout=10 )
6895 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
6896
6897 self.handle.sendline( "bin/onos-user-password %s %s" % ( userName, userPWD ) )
6898 i = self.handle.expect( [ "usage",
6899 self.dockerPrompt,
6900 pexpect.TIMEOUT ] )
6901 if i == 0:
6902 # malformed command
6903 main.log.warn( self.name + ": Could not parse onos-user-password command" )
6904 self.handle.expect( self.dockerPrompt )
6905 return main.FALSE
6906 elif i == 1:
6907 # Process started
6908 main.log.info( self.name + ": SSH password added for user " + userName )
6909 return main.TRUE
6910 elif i == 2:
6911 # timeout
6912 main.log.error( self.name + ": Failed to secure onos ssh " )
6913 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
6914 except pexpect.EOF:
6915 main.log.error( self.name + ": EOF exception found" )
6916 main.log.error( self.name + ": " + self.handle.before )
6917 main.cleanAndExit()
6918 except Exception:
6919 main.log.exception( self.name + ": Uncaught exception!" )
6920 main.cleanAndExit()
Jon Hall62ab6752021-08-22 16:47:43 -07006921
6922 def routeAdd( self, prefix, nextHop, jsonFormat=True ):
6923 """
6924 Add a route with the given prefix and nextHop
6925 """
6926 try:
6927 cmdStr = "route-add %s %s %s" % ( "-j" if jsonFormat else "", prefix, nextHop )
6928 handle = self.sendline( cmdStr )
6929 assert handle is not None, "Error in sendline"
6930 assert "Command not found:" not in handle, handle
6931 assert "Unsupported command:" not in handle, handle
6932 assert "Error executing command" not in handle, handle
6933 return handle
6934 except AssertionError:
6935 main.log.exception( "" )
6936 return None
6937 except TypeError:
6938 main.log.exception( self.name + ": Object not as expected" )
6939 return None
6940 except pexpect.EOF:
6941 main.log.error( self.name + ": EOF exception found" )
6942 main.log.error( self.name + ": " + self.handle.before )
6943 main.cleanAndExit()
6944 except Exception:
6945 main.log.exception( self.name + ": Uncaught exception!" )
6946 main.cleanAndExit()
6947
6948 def routeRemove( self, prefix, nextHop, source=None, jsonFormat=True ):
6949 """
6950 Remove a route with the given prefix and nextHop
6951 """
6952 try:
6953 if source:
6954 raise NotImplemented
6955 cmdStr = "route-remove %s %s %s" % ( "-j" if jsonFormat else "", prefix, nextHop )
6956 handle = self.sendline( cmdStr )
6957 assert handle is not None, "Error in sendline"
6958 assert "Command not found:" not in handle, handle
6959 assert "Unsupported command:" not in handle, handle
6960 assert "Error executing command" not in handle, handle
6961 return handle
6962 except AssertionError:
6963 main.log.exception( "" )
6964 return None
6965 except TypeError:
6966 main.log.exception( self.name + ": Object not as expected" )
6967 return None
6968 except pexpect.EOF:
6969 main.log.error( self.name + ": EOF exception found" )
6970 main.log.error( self.name + ": " + self.handle.before )
6971 main.cleanAndExit()
6972 except Exception:
6973 main.log.exception( self.name + ": Uncaught exception!" )
6974 main.cleanAndExit()
6975
6976 def routes( self, jsonFormat=True, args="" ):
6977 """
6978 Get routes from ONOS
6979 """
6980 try:
6981 cmdStr = "routes"
6982 if jsonFormat:
6983 cmdStr = cmdStr + " -j"
6984 handle = self.sendline( cmdStr )
6985 assert handle is not None, "Error in sendline"
6986 assert "Command not found:" not in handle, handle
6987 assert "Unsupported command:" not in handle, handle
6988 assert "Error executing command" not in handle, handle
6989 return handle
6990 except AssertionError:
6991 main.log.exception( "" )
6992 return None
6993 except TypeError:
6994 main.log.exception( self.name + ": Object not as expected" )
6995 return None
6996 except pexpect.EOF:
6997 main.log.error( self.name + ": EOF exception found" )
6998 main.log.error( self.name + ": " + self.handle.before )
6999 main.cleanAndExit()
7000 except Exception:
7001 main.log.exception( self.name + ": Uncaught exception!" )
7002 main.cleanAndExit()