blob: 4112977a7f22d6d9d9458a72b75af035387336e9 [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07004OCT 13 2014
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005Copyright 2014 Open Networking Foundation (ONF)
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07006
7Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
8the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
9or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
10
11 TestON is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 2 of the License, or
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000014 (at your option) any later version.
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -070015
16 TestON is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with TestON. If not, see <http://www.gnu.org/licenses/>.
23"""
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000024
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -070025"""
andrewonlab95ce8322014-10-13 14:12:04 -040026This driver enters the onos> prompt to issue commands.
27
kelvin8ec71442015-01-15 16:57:00 -080028Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -040029functions and document properly.
30
31If you are a contributor to the driver, please
32list your email here for future contact:
33
34jhall@onlab.us
35andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040036shreya@onlab.us
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +000037jeremyr@opennetworking.org
kelvin8ec71442015-01-15 16:57:00 -080038"""
andrewonlab95ce8322014-10-13 14:12:04 -040039import pexpect
40import re
Jon Hall30b82fa2015-03-04 17:15:43 -080041import json
42import types
Jon Hallbd16b922015-03-26 17:53:15 -070043import time
kelvin-onlaba4074292015-07-09 15:19:49 -070044import os
andrewonlab95ce8322014-10-13 14:12:04 -040045from drivers.common.clidriver import CLI
You Wangdb8cd0a2016-05-26 15:19:45 -070046from core.graph import Graph
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -070047from cStringIO import StringIO
48from itertools import izip
andrewonlab95ce8322014-10-13 14:12:04 -040049
kelvin8ec71442015-01-15 16:57:00 -080050class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040051
kelvin8ec71442015-01-15 16:57:00 -080052 def __init__( self ):
53 """
54 Initialize client
55 """
Jon Hallefbd9792015-03-05 16:11:36 -080056 self.name = None
57 self.home = None
58 self.handle = None
Devin Limdc78e202017-06-09 18:30:07 -070059 self.karafUser = None
60 self.karafPass = None
Jon Hall9b0de1f2020-08-24 15:38:04 -070061 self.karafTimeout = None
62
Jon Hall3c0114c2020-08-11 15:07:42 -070063 self.dockerPrompt = None
You Wangdb8cd0a2016-05-26 15:19:45 -070064 self.graph = Graph()
Devin Limdc78e202017-06-09 18:30:07 -070065 super( OnosCliDriver, self ).__init__()
kelvin8ec71442015-01-15 16:57:00 -080066
67 def connect( self, **connectargs ):
68 """
andrewonlab95ce8322014-10-13 14:12:04 -040069 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080070 """
andrewonlab95ce8322014-10-13 14:12:04 -040071 try:
72 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080073 vars( self )[ key ] = connectargs[ key ]
Author Namee1c79982019-06-04 23:38:42 +010074 self.karafPrompt = self.user_name + "@root >"
andrew@onlab.us658ec012015-03-11 15:13:09 -070075 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040076 for key in self.options:
77 if key == "home":
Devin Limdc78e202017-06-09 18:30:07 -070078 self.home = self.options[ key ]
79 elif key == "karaf_username":
80 self.karafUser = self.options[ key ]
81 elif key == "karaf_password":
82 self.karafPass = self.options[ key ]
Jon Hall3c0114c2020-08-11 15:07:42 -070083 elif key == "docker_prompt":
84 self.dockerPrompt = self.options[ key ]
Jon Hall9b0de1f2020-08-24 15:38:04 -070085 elif key == "karaf_timeout":
86 self.karafTimeout = self.options[ key ]
Jeremy Ronquillo82705492017-10-18 14:19:55 -070087 self.home = self.checkOptions( self.home, "~/onos" )
88 self.karafUser = self.checkOptions( self.karafUser, self.user_name )
89 self.karafPass = self.checkOptions( self.karafPass, self.pwd )
Jon Hall3c0114c2020-08-11 15:07:42 -070090 self.dockerPrompt = self.checkOptions( self.dockerPrompt, "~/onos#" )
Jon Hall9b0de1f2020-08-24 15:38:04 -070091 self.karafTimeout = self.checkOptions( self.karafTimeout, 7200000 )
andrewonlab95ce8322014-10-13 14:12:04 -040092
kelvin-onlaba4074292015-07-09 15:19:49 -070093 for key in self.options:
94 if key == 'onosIp':
95 self.onosIp = self.options[ 'onosIp' ]
96 break
97
kelvin8ec71442015-01-15 16:57:00 -080098 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070099
100 try:
Jon Hallc6793552016-01-19 14:18:37 -0800101 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -0700102 self.ip_address = os.getenv( str( self.ip_address ) )
103 else:
104 main.log.info( self.name +
105 ": Trying to connect to " +
106 self.ip_address )
107
108 except KeyError:
109 main.log.info( "Invalid host name," +
110 " connecting to local host instead" )
111 self.ip_address = 'localhost'
112 except Exception as inst:
113 main.log.error( "Uncaught exception: " + str( inst ) )
114
kelvin8ec71442015-01-15 16:57:00 -0800115 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -0800116 user_name=self.user_name,
117 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -0800118 port=self.port,
119 pwd=self.pwd,
120 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -0400121
kelvin8ec71442015-01-15 16:57:00 -0800122 self.handle.sendline( "cd " + self.home )
Devin Limdc78e202017-06-09 18:30:07 -0700123 self.handle.expect( self.prompt )
andrewonlab95ce8322014-10-13 14:12:04 -0400124 if self.handle:
125 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800126 else:
127 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -0400128 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800129 except TypeError:
130 main.log.exception( self.name + ": Object not as expected" )
131 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400132 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800133 main.log.error( self.name + ": EOF exception found" )
134 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700135 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800136 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800137 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700138 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400139
kelvin8ec71442015-01-15 16:57:00 -0800140 def disconnect( self ):
141 """
andrewonlab95ce8322014-10-13 14:12:04 -0400142 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800143 """
Jon Halld61331b2015-02-17 16:35:47 -0800144 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400145 try:
Jon Hall61282e32015-03-19 11:34:11 -0700146 if self.handle:
147 i = self.logout()
148 if i == main.TRUE:
149 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700150 for l in range( 3 ):
151 p = self.handle.expect( [ self.prompt, self.dockerPrompt ] )
152 if p == 1:
153 self.inDocker = False
154 self.handle.sendline( "exit" )
155 j = self.handle.expect( [ "closed", pexpect.TIMEOUT ], timeout=3 )
156 if j == 0:
157 return response
158 response = main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800159 except TypeError:
160 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800161 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400162 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800163 main.log.error( self.name + ": EOF exception found" )
164 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700165 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700166 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700167 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800168 except Exception:
Jon Hall3c0114c2020-08-11 15:07:42 -0700169 main.log.exception( self.name + ": disconnection failed from the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400170 response = main.FALSE
171 return response
172
kelvin8ec71442015-01-15 16:57:00 -0800173 def logout( self ):
174 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500175 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700176 Returns main.TRUE if exited CLI and
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000177 main.FALSE on timeout (not guranteed you are disconnected)
Jon Hall61282e32015-03-19 11:34:11 -0700178 None on TypeError
179 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800180 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500181 try:
Jon Hall61282e32015-03-19 11:34:11 -0700182 if self.handle:
183 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700184 i = self.handle.expect( [ self.karafPrompt,
185 self.Prompt(),
186 pexpect.TIMEOUT ],
187
Jon Hall61282e32015-03-19 11:34:11 -0700188 timeout=10 )
189 if i == 0: # In ONOS CLI
190 self.handle.sendline( "logout" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700191 j = self.handle.expect( [ self.Prompt(),
Jon Hallbfe00002016-04-05 10:23:54 -0700192 "Command not found:",
193 pexpect.TIMEOUT ] )
194 if j == 0: # Successfully logged out
195 return main.TRUE
196 elif j == 1 or j == 2:
197 # ONOS didn't fully load, and logout command isn't working
198 # or the command timed out
199 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700200 try:
Jon Hall3c0114c2020-08-11 15:07:42 -0700201 self.handle.expect( self.Prompt() )
Jon Hall64ab3bd2016-05-13 11:29:44 -0700202 except pexpect.TIMEOUT:
203 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700204 return main.TRUE
Jon Halle0f0b342017-04-18 11:43:47 -0700205 else: # some other output
Jon Hallbfe00002016-04-05 10:23:54 -0700206 main.log.warn( "Unknown repsonse to logout command: '{}'",
207 repr( self.handle.before ) )
208 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700209 elif i == 1: # not in CLI
210 return main.TRUE
steven30801e42f1fb2019-01-17 11:31:45 +0800211 elif i == 2: # Timeout
Jon Hall61282e32015-03-19 11:34:11 -0700212 return main.FALSE
213 else:
andrewonlab9627f432014-11-14 12:45:10 -0500214 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800215 except TypeError:
216 main.log.exception( self.name + ": Object not as expected" )
217 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500218 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800219 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700220 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700221 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700222 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700223 main.log.error( self.name +
224 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800225 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800226 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700227 main.cleanAndExit()
andrewonlab38d2b4a2014-11-13 16:28:47 -0500228
kelvin-onlabd3b64892015-01-20 13:26:24 -0800229 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800230 """
andrewonlab95ce8322014-10-13 14:12:04 -0400231 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800232
andrewonlab95ce8322014-10-13 14:12:04 -0400233 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800234 """
andrewonlab95ce8322014-10-13 14:12:04 -0400235 try:
236 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800237 main.log.error( "Must define cellname" )
Devin Lim44075962017-08-11 10:56:37 -0700238 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400239 else:
kelvin8ec71442015-01-15 16:57:00 -0800240 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800241 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800242 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400243 # and that this driver will have to change accordingly
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700244 self.handle.expect( str( cellname ) )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800245 handleBefore = self.handle.before
246 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800247 # Get the rest of the handle
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700248 self.handle.sendline( "" )
249 self.handle.expect( self.prompt )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800250 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400251
kelvin-onlabd3b64892015-01-20 13:26:24 -0800252 main.log.info( "Cell call returned: " + handleBefore +
253 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400254
255 return main.TRUE
256
Jon Halld4d4b372015-01-28 16:02:41 -0800257 except TypeError:
258 main.log.exception( self.name + ": Object not as expected" )
259 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400260 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800261 main.log.error( self.name + ": eof exception found" )
262 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700263 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800264 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800265 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700266 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -0800267
pingping-lin57a56ce2015-05-20 16:43:48 -0700268 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800269 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800270 """
Jon Hallefbd9792015-03-05 16:11:36 -0800271 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800272 by user would be used to set the current karaf shell idle timeout.
273 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800274 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800275 Below is an example to start a session with 60 seconds idle timeout
276 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800277
Hari Krishna25d42f72015-01-05 15:08:28 -0800278 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800279 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800280
kelvin-onlabd3b64892015-01-20 13:26:24 -0800281 Note: karafTimeout is left as str so that this could be read
282 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800283 """
You Wangf69ab392016-01-26 16:34:38 -0800284 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400285 try:
Jon Hall67253832016-12-05 09:47:13 -0800286 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800287 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700288 x = self.handle.expect( [ self.Prompt(), self.karafPrompt ], commandlineTimeout )
andrewonlab48829f62014-11-17 13:49:01 -0500289 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800290 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500291 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400292
Jon Hall67253832016-12-05 09:47:13 -0800293 # Not in CLI so login
Jon Hall3c0114c2020-08-11 15:07:42 -0700294 if self.inDocker:
295 # The Docker does not have all the wrapper scripts
296 startCliCommand = "ssh -p 8101 -o StrictHostKeyChecking=no %s@localhost" % self.karafUser
297 elif waitForStart:
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800298 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
Jon Hall3c0114c2020-08-11 15:07:42 -0700299 startCliCommand = "onos-wait-for-start " + str( ONOSIp )
Chiyu Chengef109502016-11-21 15:51:38 -0800300 else:
Jon Hall3c0114c2020-08-11 15:07:42 -0700301 startCliCommand = "onos " + str( ONOSIp )
302 self.handle.sendline( startCliCommand )
303 tries = 0
Jon Hallf69e3162020-09-01 09:08:44 -0700304 timeoutSet = False
Jon Hall3c0114c2020-08-11 15:07:42 -0700305 while tries < 5:
306 i = self.handle.expect( [
307 self.karafPrompt,
308 "Password:",
309 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400310
andrewonlab3a7c3c72014-10-24 17:21:03 -0400311 if i == 0:
Jon Hallf69e3162020-09-01 09:08:44 -0700312 if not karafTimeout or timeoutSet:
Jon Hall9b0de1f2020-08-24 15:38:04 -0700313 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
314 return main.TRUE
Hari Krishnae36ef212015-01-04 14:09:13 -0800315 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800316 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800317 "config:property-set -p org.apache.karaf.shell\
Jon Hall3c0114c2020-08-11 15:07:42 -0700318 sshIdleTimeout " +
Jon Hall9b0de1f2020-08-24 15:38:04 -0700319 str( karafTimeout ) )
320 self.handle.expect( "closed by remote host" )
Jon Hallf69e3162020-09-01 09:08:44 -0700321 self.handle.expect( self.Prompt() )
Jon Hall9b0de1f2020-08-24 15:38:04 -0700322 self.handle.sendline( startCliCommand )
Jon Hallf69e3162020-09-01 09:08:44 -0700323 timeoutSet = True
Jon Hall3c0114c2020-08-11 15:07:42 -0700324 elif i == 1:
325 main.log.info( str( ONOSIp ) + " CLI asking for password" )
326 main.log.debug( "Sending %s" % self.karafPass )
327 self.handle.sendline( self.karafPass )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400328 else:
Jon Hall3c0114c2020-08-11 15:07:42 -0700329 # If failed, send ctrl+c to process and try again
330 main.log.info( "Starting CLI failed. Retrying..." )
Jon Hallf69e3162020-09-01 09:08:44 -0700331 time.sleep( 5 )
Jon Hall3c0114c2020-08-11 15:07:42 -0700332 self.handle.send( "\x03" )
333 self.handle.sendline( startCliCommand )
334 tries += 1
335 main.log.error( "Connection to CLI " + str( ONOSIp ) + " timeout" )
336 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800337 except TypeError:
338 main.log.exception( self.name + ": Object not as expected" )
339 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400340 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800341 main.log.error( self.name + ": EOF exception found" )
342 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700343 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800344 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800345 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700346 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400347
suibin zhang116647a2016-05-06 16:30:09 -0700348 def startCellCli( self, karafTimeout="",
349 commandlineTimeout=10, onosStartTimeout=60 ):
350 """
Jon Hall3c0114c2020-08-11 15:07:42 -0700351 Start CLI on onos cell handle.
suibin zhang116647a2016-05-06 16:30:09 -0700352
353 karafTimeout is an optional argument. karafTimeout value passed
354 by user would be used to set the current karaf shell idle timeout.
355 Note that when ever this property is modified the shell will exit and
356 the subsequent login would reflect new idle timeout.
357 Below is an example to start a session with 60 seconds idle timeout
358 ( input value is in milliseconds ):
359
360 tValue = "60000"
361
362 Note: karafTimeout is left as str so that this could be read
363 and passed to startOnosCli from PARAMS file as str.
364 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000365
suibin zhang116647a2016-05-06 16:30:09 -0700366 try:
367 self.handle.sendline( "" )
368 x = self.handle.expect( [
Jon Hall3c0114c2020-08-11 15:07:42 -0700369 self.Prompt(), self.karafPrompt ], commandlineTimeout )
suibin zhang116647a2016-05-06 16:30:09 -0700370
371 if x == 1:
372 main.log.info( "ONOS cli is already running" )
373 return main.TRUE
374
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800375 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
suibin zhang116647a2016-05-06 16:30:09 -0700376 self.handle.sendline( "/opt/onos/bin/onos" )
377 i = self.handle.expect( [
Jon Hall6c9e2da2018-11-06 12:01:23 -0800378 self.karafPrompt,
suibin zhang116647a2016-05-06 16:30:09 -0700379 pexpect.TIMEOUT ], onosStartTimeout )
380
381 if i == 0:
382 main.log.info( self.name + " CLI Started successfully" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800383 if karafTimeout: # FIXME: This doesn't look right
suibin zhang116647a2016-05-06 16:30:09 -0700384 self.handle.sendline(
385 "config:property-set -p org.apache.karaf.shell\
386 sshIdleTimeout " +
387 karafTimeout )
Jon Hall3c0114c2020-08-11 15:07:42 -0700388 self.handle.expect( self.Prompt() )
suibin zhang116647a2016-05-06 16:30:09 -0700389 self.handle.sendline( "/opt/onos/bin/onos" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800390 self.handle.expect( self.karafPrompt )
suibin zhang116647a2016-05-06 16:30:09 -0700391 return main.TRUE
392 else:
393 # If failed, send ctrl+c to process and try again
394 main.log.info( "Starting CLI failed. Retrying..." )
395 self.handle.send( "\x03" )
396 self.handle.sendline( "/opt/onos/bin/onos" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800397 i = self.handle.expect( [ self.karafPrompt, pexpect.TIMEOUT ],
suibin zhang116647a2016-05-06 16:30:09 -0700398 timeout=30 )
399 if i == 0:
400 main.log.info( self.name + " CLI Started " +
401 "successfully after retry attempt" )
402 if karafTimeout:
403 self.handle.sendline(
404 "config:property-set -p org.apache.karaf.shell\
405 sshIdleTimeout " +
406 karafTimeout )
Jon Hall3c0114c2020-08-11 15:07:42 -0700407 self.handle.expect( self.Prompt() )
suibin zhang116647a2016-05-06 16:30:09 -0700408 self.handle.sendline( "/opt/onos/bin/onos" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800409 self.handle.expect( self.karafPrompt )
suibin zhang116647a2016-05-06 16:30:09 -0700410 return main.TRUE
411 else:
412 main.log.error( "Connection to CLI " +
413 self.name + " timeout" )
414 return main.FALSE
415
416 except TypeError:
417 main.log.exception( self.name + ": Object not as expected" )
418 return None
419 except pexpect.EOF:
420 main.log.error( self.name + ": EOF exception found" )
421 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700422 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700423 except Exception:
424 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700425 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700426
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800427 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800428 """
429 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800430 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800431 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700432 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800433 Available level: DEBUG, TRACE, INFO, WARN, ERROR
434 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800435 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800436 """
437 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800438 lvlStr = ""
439 if level:
440 lvlStr = "--level=" + level
441
kelvin-onlab338f5512015-02-06 10:53:16 -0800442 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700443 self.handle.expect( "log:log" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800444 self.handle.expect( self.karafPrompt )
kelvin-onlabfb521662015-02-27 09:52:40 -0800445
kelvin-onlab9f541032015-02-04 16:19:53 -0800446 response = self.handle.before
447 if re.search( "Error", response ):
Jon Halldac3eae2020-06-05 12:04:06 -0700448 main.log.debug( response )
kelvin-onlab9f541032015-02-04 16:19:53 -0800449 return main.FALSE
450 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700451 except pexpect.TIMEOUT:
452 main.log.exception( self.name + ": TIMEOUT exception found" )
Jon Hall43060f62020-06-23 13:13:33 -0700453 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700454 if noExit:
455 main.cleanup()
456 return None
457 else:
Devin Lim44075962017-08-11 10:56:37 -0700458 main.cleanAndExit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800459 except pexpect.EOF:
460 main.log.error( self.name + ": EOF exception found" )
461 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700462 if noExit:
463 main.cleanup()
464 return None
465 else:
Devin Lim44075962017-08-11 10:56:37 -0700466 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800467 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800468 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700469 if noExit:
470 main.cleanup()
471 return None
472 else:
Devin Lim44075962017-08-11 10:56:37 -0700473 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400474
Jon Hall0e240372018-05-02 11:21:57 -0700475 def clearBuffer( self, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800476 """
Jon Hall0e240372018-05-02 11:21:57 -0700477 Test cli connection and clear any left over output in the buffer
478 Optional Arguments:
479 debug - Defaults to False. If True, will enable debug logging.
480 timeout - Defaults to 10. Amount of time in seconds for a command to return
481 before a timeout.
482 noExit - Defaults to False. If True, will not exit TestON in the event of a
kelvin8ec71442015-01-15 16:57:00 -0800483 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400484 try:
Jon Halla495f562016-05-16 18:03:26 -0700485 # Try to reconnect if disconnected from cli
486 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700487 i = self.handle.expect( [ self.karafPrompt,
488 self.Prompt(),
489 pexpect.TIMEOUT ] )
Jon Hall0e240372018-05-02 11:21:57 -0700490 response = self.handle.before
Jon Halla495f562016-05-16 18:03:26 -0700491 if i == 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700492 main.log.error( self.name + ": onos cli session closed. " )
Jon Halla495f562016-05-16 18:03:26 -0700493 if self.onosIp:
494 main.log.warn( "Trying to reconnect " + self.onosIp )
495 reconnectResult = self.startOnosCli( self.onosIp )
496 if reconnectResult:
497 main.log.info( self.name + ": onos cli session reconnected." )
498 else:
499 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700500 if noExit:
501 return None
502 else:
Devin Lim44075962017-08-11 10:56:37 -0700503 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700504 else:
Devin Lim44075962017-08-11 10:56:37 -0700505 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700506 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700507 main.log.warn( "Timeout when testing cli responsiveness" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700508 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700509 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Hall6c9e2da2018-11-06 12:01:23 -0800510 self.handle.expect( self.karafPrompt )
Jon Halla495f562016-05-16 18:03:26 -0700511
Jon Hall0e240372018-05-02 11:21:57 -0700512 response += self.handle.before
Jon Hall14a03b52016-05-11 12:07:30 -0700513 if debug:
Jon Hall0e240372018-05-02 11:21:57 -0700514 main.log.debug( self.name + ": Raw output from sending ''" )
515 main.log.debug( self.name + ": " + repr( response ) )
516 except pexpect.TIMEOUT:
517 main.log.error( self.name + ": ONOS timeout" )
Jon Hall3c0114c2020-08-11 15:07:42 -0700518 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
You Wang141b43b2018-06-26 16:50:18 -0700519 self.handle.send( "\x03" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800520 self.handle.expect( self.karafPrompt )
Jon Hall0e240372018-05-02 11:21:57 -0700521 return None
522 except pexpect.EOF:
523 main.log.error( self.name + ": EOF exception found" )
524 main.log.error( self.name + ": " + self.handle.before )
525 if noExit:
526 return None
527 else:
528 main.cleanAndExit()
529 except Exception:
530 main.log.exception( self.name + ": Uncaught exception!" )
531 if noExit:
532 return None
533 else:
534 main.cleanAndExit()
535
Jon Hall22e94ce2019-01-15 14:52:17 -0800536 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True, expectJson=False ):
Jon Hall0e240372018-05-02 11:21:57 -0700537 """
538 A wrapper around pexpect's sendline/expect. Will return all the output from a given command
539
540 Required Arguments:
541 cmdStr - String to send to the pexpect session
542
543 Optional Arguments:
544 showResponse - Defaults to False. If True will log the response.
545 debug - Defaults to False. If True, will enable debug logging.
546 timeout - Defaults to 10. Amount of time in seconds for a command to return
547 before a timeout.
548 noExit - Defaults to False. If True, will not exit TestON in the event of a
549 closed channel, but instead return None
Jon Hall6c9e2da2018-11-06 12:01:23 -0800550 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 -0700551
552 Warning: There are no sanity checking to commands sent using this method.
553
554 """
555 try:
556 # Try to reconnect if disconnected from cli
557 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
558 if debug:
559 # NOTE: This adds an average of .4 seconds per call
Jon Hall14a03b52016-05-11 12:07:30 -0700560 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700561 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800562 self.handle.sendline( cmdStr )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800563 self.handle.expect( self.karafPrompt, timeout )
Jon Hall63604932015-02-26 17:09:50 -0800564 response = self.handle.before
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000565 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
Jon Hallc6793552016-01-19 14:18:37 -0800566 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700567 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700568 main.log.debug( self.name + ": Raw output" )
569 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700570
Jon Hall3c0114c2020-08-11 15:07:42 -0700571 response = self.cleanOutput( response, debug=debug )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800572 # Remove control codes from karaf 4.2.1
Jon Hall3c0114c2020-08-11 15:07:42 -0700573 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 -0800574 response = karafEscape.sub( '', response )
575 if debug:
576 main.log.debug( self.name + ": karafEscape output" )
577 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700578 # Remove ANSI color control strings from output
Jon Hall43060f62020-06-23 13:13:33 -0700579 response = self.cleanOutput( response, debug )
Jon Hallc6358dd2015-04-10 12:44:28 -0700580
Jon Hall6c9e2da2018-11-06 12:01:23 -0800581 # Remove ANSI color control strings from output
Jon Hallcf31d0f2018-12-13 11:18:48 -0800582 # NOTE: karaf is sometimes adding a single character then two
583 # backspaces and sometimes adding 2 characters with 2 backspaces??
Jon Hall3c0114c2020-08-11 15:07:42 -0700584 backspaceEscape = re.compile( r'((.|\s)\x08)' )
585 unchanged = False
586 while not unchanged:
587 old = response
588 response = backspaceEscape.sub( '', response, count=1 )
589 if debug:
590 main.log.debug( self.name + ": backspaceEscape output" )
591 main.log.debug( self.name + ": " + repr( response ) )
592 unchanged = old == response
Jon Hall6c9e2da2018-11-06 12:01:23 -0800593
kelvin-onlabfb521662015-02-27 09:52:40 -0800594 # Remove extra return chars that get added
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000595 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700596 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700597 main.log.debug( self.name + ": Removed extra returns " +
598 "from output" )
599 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700600
601 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800602 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700603 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700604 main.log.debug( self.name + ": parsed and stripped output" )
605 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700606
Jon Hall63604932015-02-26 17:09:50 -0800607 # parse for just the output, remove the cmd from response
Jon Hallce0d70b2018-12-11 11:01:32 -0800608 cmdPattern = cmdStr.strip()
609 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
610 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800611 if relaxedRegex:
Jon Hallce0d70b2018-12-11 11:01:32 -0800612 cmdPattern = cmdPattern.split( '|' )[ -1 ].strip()
613 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
614 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800615 # This was added because karaf 4.2 is stripping some characters from the command echo
Jon Hallce0d70b2018-12-11 11:01:32 -0800616 output = response.split( cmdPattern, 1 )
Jon Hall22e94ce2019-01-15 14:52:17 -0800617 if expectJson:
618 main.log.warn( "Relaxed Regex: Searching for a json string amongst the output" )
619 jsonPattern = r'\{.*\}'
620 match = re.search( jsonPattern, output[ 0 ] )
621 if match:
622 output = [ '' , match.group( 0 ) ] # We expect a list with the second element to be the output
Jon Hall39e3ffe2018-12-05 11:40:29 -0800623 if len( output ) < 2:
624 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800625 cmdPattern = cmdPattern[ -5: ]
626 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
627 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
628 output = response.split( cmdPattern, 1 )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800629 else:
Jon Hallce0d70b2018-12-11 11:01:32 -0800630 output = response.split( cmdPattern, 1 )
631 if len( output ) < 2: # TODO: Should we do this without the relaxedRegex flag?
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800632 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800633 output = response.split( cmdPattern[ -5: ], 1 )
Jon Hall0e240372018-05-02 11:21:57 -0700634 if output:
635 if debug:
636 main.log.debug( self.name + ": split output" )
637 for r in output:
638 main.log.debug( self.name + ": " + repr( r ) )
Jon Hallce0d70b2018-12-11 11:01:32 -0800639 if len( output ) == 1:
640 main.log.error( "Could not remove sent command echo from output" )
641 return output
Jon Hall0e240372018-05-02 11:21:57 -0700642 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800643 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800644 main.log.info( "Response from ONOS: {}".format( output ) )
Jon Hall0e240372018-05-02 11:21:57 -0700645 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
GlennRC85870432015-11-23 11:45:51 -0800646 return output
GlennRCed771242016-01-13 17:02:47 -0800647 except pexpect.TIMEOUT:
Jon Hall0e240372018-05-02 11:21:57 -0700648 main.log.error( self.name + ": ONOS timeout" )
GlennRCed771242016-01-13 17:02:47 -0800649 if debug:
Jon Hall3c0114c2020-08-11 15:07:42 -0700650 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
You Wang6b5e5ba2019-01-31 15:32:40 -0800651 self.exitFromCmd( self.karafPrompt, 100 )
GlennRCed771242016-01-13 17:02:47 -0800652 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700653 except IndexError:
654 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700655 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700656 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800657 except TypeError:
658 main.log.exception( self.name + ": Object not as expected" )
659 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400660 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800661 main.log.error( self.name + ": EOF exception found" )
662 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700663 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700664 return None
665 else:
Devin Lim44075962017-08-11 10:56:37 -0700666 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800667 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800668 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700669 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700670 return None
671 else:
Devin Lim44075962017-08-11 10:56:37 -0700672 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400673
Jon Halld5a94fb2018-11-13 14:32:23 -0800674 def lineCount( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True ):
675 """
676 A wrapper around sendline(). Will return the number of lines returned or None on error
677
678 Required Arguments:
679 cmdStr - String to send to the pexpect session
680
681 Optional Arguments:
682 showResponse - Defaults to False. If True will log the response.
683 debug - Defaults to False. If True, will enable debug logging.
684 timeout - Defaults to 10. Amount of time in seconds for a command to return
685 before a timeout.
686 noExit - Defaults to False. If True, will not exit TestON in the event of a
687 closed channel, but instead return None
688 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.
689
690 Warning: There are no sanity checking to commands sent using this method.
691
692 """
693 try:
694 numLines = self.sendline( cmdStr, showResponse, debug, timeout, noExit, relaxedRegex )
You Wang0ce8e0c2019-02-22 12:22:26 -0800695 parsed = re.search( "(\d+)", numLines )
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800696 if not parsed:
697 main.log.error( "Warning, output of karaf's wc may have changed" )
698 return None
699 return parsed.group( 1 )
Jon Halld5a94fb2018-11-13 14:32:23 -0800700 except IndexError:
701 main.log.exception( self.name + ": Object not as expected" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800702 main.log.debug( "response: {}".format( repr( numLines ) ) )
Jon Halld5a94fb2018-11-13 14:32:23 -0800703 return None
704 except TypeError:
705 main.log.exception( self.name + ": Object not as expected" )
706 return None
707 except Exception:
708 main.log.exception( self.name + ": Uncaught exception!" )
709 if noExit:
710 return None
711 else:
712 main.cleanAndExit()
713
kelvin8ec71442015-01-15 16:57:00 -0800714 # IMPORTANT NOTE:
715 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800716 # the cli command changing 'a:b' with 'aB'.
717 # Ex ) onos:topology > onosTopology
718 # onos:links > onosLinks
719 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800720
kelvin-onlabd3b64892015-01-20 13:26:24 -0800721 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800722 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400723 Adds a new cluster node by ID and address information.
724 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800725 * nodeId
726 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400727 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800728 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800729 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400730 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800731 cmdStr = "add-node " + str( nodeId ) + " " +\
732 str( ONOSIp ) + " " + str( tcpPort )
733 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700734 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800735 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800736 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700737 main.log.error( self.name + ": Error in adding node" )
kelvin8ec71442015-01-15 16:57:00 -0800738 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800739 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400740 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800741 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400742 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800743 except AssertionError:
744 main.log.exception( "" )
745 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800746 except TypeError:
747 main.log.exception( self.name + ": Object not as expected" )
748 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400749 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800750 main.log.error( self.name + ": EOF exception found" )
751 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700752 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800753 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800754 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700755 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400756
kelvin-onlabd3b64892015-01-20 13:26:24 -0800757 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800758 """
andrewonlab86dc3082014-10-13 18:18:38 -0400759 Removes a cluster by ID
760 Issues command: 'remove-node [<node-id>]'
761 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800762 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800763 """
andrewonlab86dc3082014-10-13 18:18:38 -0400764 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400765
kelvin-onlabd3b64892015-01-20 13:26:24 -0800766 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700767 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700768 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800769 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700770 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700771 main.log.error( self.name + ": Error in removing node" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700772 main.log.error( handle )
773 return main.FALSE
774 else:
775 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800776 except AssertionError:
777 main.log.exception( "" )
778 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800779 except TypeError:
780 main.log.exception( self.name + ": Object not as expected" )
781 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400782 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800783 main.log.error( self.name + ": EOF exception found" )
784 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700785 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800786 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800787 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700788 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400789
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700790 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800791 """
andrewonlab7c211572014-10-15 16:45:20 -0400792 List the nodes currently visible
793 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700794 Optional argument:
795 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800796 """
andrewonlab7c211572014-10-15 16:45:20 -0400797 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700798 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700799 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700800 cmdStr += " -j"
801 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700802 assert output is not None, "Error in sendline"
Jon Halle37bd1f2020-09-10 12:16:41 -0700803 # "Command not found" or "Service org.onosproject.security.AuditService not found"
804 assert "not found" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700805 return output
Jon Hallc6793552016-01-19 14:18:37 -0800806 except AssertionError:
807 main.log.exception( "" )
808 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800809 except TypeError:
810 main.log.exception( self.name + ": Object not as expected" )
811 return None
andrewonlab7c211572014-10-15 16:45:20 -0400812 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800813 main.log.error( self.name + ": EOF exception found" )
814 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700815 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800816 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800817 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700818 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400819
kelvin8ec71442015-01-15 16:57:00 -0800820 def topology( self ):
821 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700822 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700823 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700824 Return:
825 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800826 """
andrewonlab95ce8322014-10-13 14:12:04 -0400827 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700828 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800829 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800830 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800831 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700832 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400833 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800834 except AssertionError:
835 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800836 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800837 except TypeError:
838 main.log.exception( self.name + ": Object not as expected" )
839 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400840 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800841 main.log.error( self.name + ": EOF exception found" )
842 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700843 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800844 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800845 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700846 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800847
jenkins7ead5a82015-03-13 10:28:21 -0700848 def deviceRemove( self, deviceId ):
849 """
850 Removes particular device from storage
851
852 TODO: refactor this function
853 """
854 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700855 cmdStr = "device-remove " + str( deviceId )
856 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800857 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800858 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700859 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700860 main.log.error( self.name + ": Error in removing device" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700861 main.log.error( handle )
862 return main.FALSE
863 else:
864 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800865 except AssertionError:
866 main.log.exception( "" )
867 return None
jenkins7ead5a82015-03-13 10:28:21 -0700868 except TypeError:
869 main.log.exception( self.name + ": Object not as expected" )
870 return None
871 except pexpect.EOF:
872 main.log.error( self.name + ": EOF exception found" )
873 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700874 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700875 except Exception:
876 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700877 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700878
You Wang3b9689a2018-08-30 12:24:00 -0700879 def devices( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800880 """
Jon Hall7b02d952014-10-17 20:14:54 -0400881 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400882 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800883 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800884 """
andrewonlab86dc3082014-10-13 18:18:38 -0400885 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700886 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800887 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700888 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700889 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800890 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800891 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700892 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800893 except AssertionError:
894 main.log.exception( "" )
895 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800896 except TypeError:
897 main.log.exception( self.name + ": Object not as expected" )
898 return None
andrewonlab7c211572014-10-15 16:45:20 -0400899 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800900 main.log.error( self.name + ": EOF exception found" )
901 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700902 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800903 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800904 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700905 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400906
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800908 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800909 This balances the devices across all controllers
910 by issuing command: 'onos> onos:balance-masters'
911 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800912 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800913 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800914 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700915 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800916 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800917 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700918 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700919 main.log.error( self.name + ": Error in balancing masters" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700920 main.log.error( handle )
921 return main.FALSE
922 else:
923 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800924 except AssertionError:
925 main.log.exception( "" )
926 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800927 except TypeError:
928 main.log.exception( self.name + ": Object not as expected" )
929 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800930 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800931 main.log.error( self.name + ": EOF exception found" )
932 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700933 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800934 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800935 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700936 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800937
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000938 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700939 """
940 Returns the output of the masters command.
941 Optional argument:
942 * jsonFormat - boolean indicating if you want output in json
943 """
944 try:
945 cmdStr = "onos:masters"
946 if jsonFormat:
947 cmdStr += " -j"
948 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700949 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800950 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700951 return output
Jon Hallc6793552016-01-19 14:18:37 -0800952 except AssertionError:
953 main.log.exception( "" )
954 return None
acsmars24950022015-07-30 18:00:43 -0700955 except TypeError:
956 main.log.exception( self.name + ": Object not as expected" )
957 return None
958 except pexpect.EOF:
959 main.log.error( self.name + ": EOF exception found" )
960 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700961 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700962 except Exception:
963 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700964 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700965
Jon Hallc6793552016-01-19 14:18:37 -0800966 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700967 """
968 Uses the master command to check that the devices' leadership
969 is evenly divided
970
971 Dependencies: checkMasters() and summary()
972
Jon Hall6509dbf2016-06-21 17:01:17 -0700973 Returns main.TRUE if the devices are balanced
974 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700975 Exits on Exception
976 Returns None on TypeError
977 """
978 try:
Jon Hallc6793552016-01-19 14:18:37 -0800979 summaryOutput = self.summary()
980 totalDevices = json.loads( summaryOutput )[ "devices" ]
981 except ( TypeError, ValueError ):
982 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
983 return None
984 try:
acsmars24950022015-07-30 18:00:43 -0700985 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800986 mastersOutput = self.checkMasters()
987 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700988 first = masters[ 0 ][ "size" ]
989 for master in masters:
990 totalOwnedDevices += master[ "size" ]
991 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
992 main.log.error( "Mastership not balanced" )
993 main.log.info( "\n" + self.checkMasters( False ) )
994 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700995 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700996 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700997 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800998 except ( TypeError, ValueError ):
999 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -07001000 return None
1001 except pexpect.EOF:
1002 main.log.error( self.name + ": EOF exception found" )
1003 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001004 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -07001005 except Exception:
1006 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001007 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -07001008
YPZhangfebf7302016-05-24 16:45:56 -07001009 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -08001010 """
Jon Halle8217482014-10-17 13:49:14 -04001011 Lists all core links
1012 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001013 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001014 """
Jon Halle8217482014-10-17 13:49:14 -04001015 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001016 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001017 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001018 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07001019 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001020 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001021 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001022 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001023 except AssertionError:
1024 main.log.exception( "" )
1025 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001026 except TypeError:
1027 main.log.exception( self.name + ": Object not as expected" )
1028 return None
Jon Halle8217482014-10-17 13:49:14 -04001029 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001030 main.log.error( self.name + ": EOF exception found" )
1031 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001032 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001033 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001034 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001035 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001036
You Wang3b9689a2018-08-30 12:24:00 -07001037 def ports( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -08001038 """
Jon Halle8217482014-10-17 13:49:14 -04001039 Lists all ports
1040 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001041 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001042 """
Jon Halle8217482014-10-17 13:49:14 -04001043 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001044 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001045 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001046 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -07001047 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001048 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001049 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001050 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001051 except AssertionError:
1052 main.log.exception( "" )
1053 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001054 except TypeError:
1055 main.log.exception( self.name + ": Object not as expected" )
1056 return None
Jon Halle8217482014-10-17 13:49:14 -04001057 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001058 main.log.error( self.name + ": EOF exception found" )
1059 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001060 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001061 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001062 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001063 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001064
kelvin-onlabd3b64892015-01-20 13:26:24 -08001065 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001066 """
Jon Hall983a1702014-10-28 18:44:22 -04001067 Lists all devices and the controllers with roles assigned to them
1068 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001069 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001070 """
andrewonlab7c211572014-10-15 16:45:20 -04001071 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001072 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001073 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001074 cmdStr += " -j"
1075 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001076 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001077 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001078 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001079 except AssertionError:
1080 main.log.exception( "" )
1081 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001082 except TypeError:
1083 main.log.exception( self.name + ": Object not as expected" )
1084 return None
Jon Hall983a1702014-10-28 18:44:22 -04001085 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001086 main.log.error( self.name + ": EOF exception found" )
1087 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001088 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001089 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001090 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001091 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -04001092
kelvin-onlabd3b64892015-01-20 13:26:24 -08001093 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001094 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001095 Given the a string containing the json representation of the "roles"
1096 cli command and a partial or whole device id, returns a json object
1097 containing the roles output for the first device whose id contains
1098 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -04001099
1100 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -08001101 A dict of the role assignments for the given device or
1102 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001103 """
Jon Hall983a1702014-10-28 18:44:22 -04001104 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001105 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001106 return None
1107 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001108 rawRoles = self.roles()
1109 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001110 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001111 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001112 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001113 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001114 return device
1115 return None
Jon Hallc6793552016-01-19 14:18:37 -08001116 except ( TypeError, ValueError ):
1117 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001118 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001119 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001120 main.log.error( self.name + ": EOF exception found" )
1121 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001122 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001123 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001124 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001125 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001126
kelvin-onlabd3b64892015-01-20 13:26:24 -08001127 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001128 """
Jon Hall94fd0472014-12-08 11:52:42 -08001129 Iterates through each device and checks if there is a master assigned
1130 Returns: main.TRUE if each device has a master
1131 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001132 """
Jon Hall94fd0472014-12-08 11:52:42 -08001133 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 rawRoles = self.roles()
1135 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001136 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001137 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001138 # print device
1139 if device[ 'master' ] == "none":
1140 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001141 return main.FALSE
1142 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001143 except ( TypeError, ValueError ):
1144 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001145 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001146 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001147 main.log.error( self.name + ": EOF exception found" )
1148 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001149 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001150 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001151 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001152 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001153
kelvin-onlabd3b64892015-01-20 13:26:24 -08001154 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001155 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001156 Returns string of paths, and the cost.
1157 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001158 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001159 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001160 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1161 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001162 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001163 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001164 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001165 main.log.error( self.name + ": Error in getting paths" )
kelvin8ec71442015-01-15 16:57:00 -08001166 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001167 else:
kelvin8ec71442015-01-15 16:57:00 -08001168 path = handle.split( ";" )[ 0 ]
1169 cost = handle.split( ";" )[ 1 ]
1170 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001171 except AssertionError:
1172 main.log.exception( "" )
1173 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001174 except TypeError:
1175 main.log.exception( self.name + ": Object not as expected" )
1176 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001177 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001178 main.log.error( self.name + ": EOF exception found" )
1179 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001180 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001181 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001182 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001183 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001184
kelvin-onlabd3b64892015-01-20 13:26:24 -08001185 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001186 """
Jon Hallffb386d2014-11-21 13:43:38 -08001187 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001188 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001189 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001190 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001191 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001192 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001193 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001194 cmdStr += " -j"
1195 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001196 if handle:
1197 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001198 # TODO: Maybe make this less hardcoded
1199 # ConsistentMap Exceptions
1200 assert "org.onosproject.store.service" not in handle
1201 # Node not leader
1202 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001203 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001204 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07001205 main.log.exception( self.name + ": Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001206 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001207 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001208 except TypeError:
1209 main.log.exception( self.name + ": Object not as expected" )
1210 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001211 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001212 main.log.error( self.name + ": EOF exception found" )
1213 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001214 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001215 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001216 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001217 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001218
kelvin-onlabd3b64892015-01-20 13:26:24 -08001219 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001220 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001221 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001222
Jon Hallefbd9792015-03-05 16:11:36 -08001223 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001224 partial mac address
1225
Jon Hall42db6dc2014-10-24 19:03:48 -04001226 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001227 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001228 try:
kelvin8ec71442015-01-15 16:57:00 -08001229 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001230 return None
1231 else:
1232 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001233 rawHosts = self.hosts()
1234 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001235 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001236 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001237 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001238 if not host:
1239 pass
1240 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001241 return host
1242 return None
Jon Hallc6793552016-01-19 14:18:37 -08001243 except ( TypeError, ValueError ):
1244 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001245 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001246 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001247 main.log.error( self.name + ": EOF exception found" )
1248 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001249 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001250 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001251 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001252 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001253
kelvin-onlabd3b64892015-01-20 13:26:24 -08001254 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001255 """
1256 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001257 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001258
andrewonlab3f0a4af2014-10-17 12:25:14 -04001259 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001260 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001261 IMPORTANT:
1262 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001263 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001264 Furthermore, it assumes that value of VLAN is '-1'
1265 Description:
kelvin8ec71442015-01-15 16:57:00 -08001266 Converts mininet hosts ( h1, h2, h3... ) into
1267 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1268 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001269 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001270 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001271
kelvin-onlabd3b64892015-01-20 13:26:24 -08001272 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001273 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001274 hostHex = hex( int( host ) ).zfill( 12 )
1275 hostHex = str( hostHex ).replace( 'x', '0' )
1276 i = iter( str( hostHex ) )
1277 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1278 hostHex = hostHex + "/-1"
1279 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001280
kelvin-onlabd3b64892015-01-20 13:26:24 -08001281 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001282
Jon Halld4d4b372015-01-28 16:02:41 -08001283 except TypeError:
1284 main.log.exception( self.name + ": Object not as expected" )
1285 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001286 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001287 main.log.error( self.name + ": EOF exception found" )
1288 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001289 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001290 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001291 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001292 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001293
You Wangbc898b82018-05-03 16:22:34 -07001294 def verifyHostLocation( self, hostIp, location ):
1295 """
1296 Description:
1297 Verify the host given is discovered in all locations expected
1298 Required:
1299 hostIp: IP address of the host
1300 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1301 Could be a string or list
1302 Returns:
1303 main.TRUE if host is discovered on all locations provided
1304 main.FALSE otherwise
1305 """
You Wangbc898b82018-05-03 16:22:34 -07001306 locations = [ location ] if isinstance( location, str ) else location
1307 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1308 try:
1309 hosts = self.hosts()
1310 hosts = json.loads( hosts )
1311 targetHost = None
1312 for host in hosts:
1313 if hostIp in host[ "ipAddresses" ]:
1314 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001315 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001316 result = main.TRUE
1317 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1318 for loc in locations:
1319 discovered = False
1320 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001321 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1322 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001323 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001324 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001325 break
1326 if discovered:
1327 locationsDiscovered.remove( locDiscovered )
1328 else:
1329 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1330 result = main.FALSE
1331 if locationsDiscovered:
1332 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1333 result = main.FALSE
1334 return result
1335 except KeyError:
1336 main.log.exception( self.name + ": host data not as expected: " + hosts )
1337 return None
1338 except pexpect.EOF:
1339 main.log.error( self.name + ": EOF exception found" )
1340 main.log.error( self.name + ": " + self.handle.before )
1341 main.cleanAndExit()
1342 except Exception:
1343 main.log.exception( self.name + ": Uncaught exception" )
1344 return None
1345
You Wang53dba1e2018-02-02 17:45:44 -08001346 def verifyHostIp( self, hostList=[], prefix="" ):
1347 """
1348 Description:
1349 Verify that all hosts have IP address assigned to them
1350 Optional:
1351 hostList: If specified, verifications only happen to the hosts
1352 in hostList
1353 prefix: at least one of the ip address assigned to the host
1354 needs to have the specified prefix
1355 Returns:
1356 main.TRUE if all hosts have specific IP address assigned;
1357 main.FALSE otherwise
1358 """
You Wang53dba1e2018-02-02 17:45:44 -08001359 try:
1360 hosts = self.hosts()
1361 hosts = json.loads( hosts )
1362 if not hostList:
1363 hostList = [ host[ "id" ] for host in hosts ]
1364 for host in hosts:
1365 hostId = host[ "id" ]
1366 if hostId not in hostList:
1367 continue
1368 ipList = host[ "ipAddresses" ]
1369 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1370 if not ipList:
1371 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1372 else:
1373 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1374 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1375 else:
1376 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1377 hostList.remove( hostId )
1378 if hostList:
1379 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
Jon Hall43060f62020-06-23 13:13:33 -07001380 # Print info for debugging
1381 main.log.debug( self.name + ": hosts output: " + str( hosts ) )
You Wang53dba1e2018-02-02 17:45:44 -08001382 return main.FALSE
1383 else:
1384 return main.TRUE
1385 except KeyError:
1386 main.log.exception( self.name + ": host data not as expected: " + hosts )
1387 return None
1388 except pexpect.EOF:
1389 main.log.error( self.name + ": EOF exception found" )
1390 main.log.error( self.name + ": " + self.handle.before )
1391 main.cleanAndExit()
1392 except Exception:
1393 main.log.exception( self.name + ": Uncaught exception" )
1394 return None
1395
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001396 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001397 """
andrewonlabe6745342014-10-17 14:29:13 -04001398 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001399 * hostIdOne: ONOS host id for host1
1400 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001401 Optional:
1402 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001403 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001404 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001405 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001406 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001407 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001408 Returns:
1409 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001410 """
andrewonlabe6745342014-10-17 14:29:13 -04001411 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001412 cmdStr = "add-host-intent "
1413 if vlanId:
1414 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001415 if setVlan:
1416 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001417 if encap:
1418 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001419 if bandwidth:
1420 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001421 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001422 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001423 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001424 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001425 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001426 main.log.error( self.name + ": Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001427 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001428 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001429 else:
1430 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001431 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001432 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001433 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001434 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001435 else:
1436 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001437 main.log.debug( "Response from ONOS was: " +
1438 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001439 return None
Jon Hallc6793552016-01-19 14:18:37 -08001440 except AssertionError:
1441 main.log.exception( "" )
1442 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001443 except TypeError:
1444 main.log.exception( self.name + ": Object not as expected" )
1445 return None
andrewonlabe6745342014-10-17 14:29:13 -04001446 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001447 main.log.error( self.name + ": EOF exception found" )
1448 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001449 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001450 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001451 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001452 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001453
kelvin-onlabd3b64892015-01-20 13:26:24 -08001454 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001455 """
andrewonlab7b31d232014-10-24 13:31:47 -04001456 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001457 * ingressDevice: device id of ingress device
1458 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001459 Optional:
1460 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001461 Description:
1462 Adds an optical intent by specifying an ingress and egress device
1463 Returns:
1464 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001465 """
andrewonlab7b31d232014-10-24 13:31:47 -04001466 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001467 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1468 " " + str( egressDevice )
1469 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001470 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001471 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001472 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001473 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001474 main.log.error( self.name + ": Error in adding Optical intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001475 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001476 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001477 main.log.info( "Optical intent installed between " +
1478 str( ingressDevice ) + " and " +
1479 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001480 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001481 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001482 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001483 else:
1484 main.log.error( "Error, intent ID not found" )
1485 return None
Jon Hallc6793552016-01-19 14:18:37 -08001486 except AssertionError:
1487 main.log.exception( "" )
1488 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001489 except TypeError:
1490 main.log.exception( self.name + ": Object not as expected" )
1491 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001492 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001493 main.log.error( self.name + ": EOF exception found" )
1494 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001495 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001496 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001497 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001498 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001499
kelvin-onlabd3b64892015-01-20 13:26:24 -08001500 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001501 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001502 ingressDevice,
1503 egressDevice,
1504 portIngress="",
1505 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001506 ethType="",
1507 ethSrc="",
1508 ethDst="",
1509 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001510 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001511 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001512 ipProto="",
1513 ipSrc="",
1514 ipDst="",
1515 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001516 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001517 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001518 setVlan="",
1519 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001520 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001521 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001522 * ingressDevice: device id of ingress device
1523 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001524 Optional:
1525 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001526 * ethSrc: specify ethSrc ( i.e. src mac addr )
1527 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001528 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001529 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001530 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001531 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001532 * ipSrc: specify ip source address
1533 * ipDst: specify ip destination address
1534 * tcpSrc: specify tcp source port
1535 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001536 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001537 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001538 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001539 Description:
kelvin8ec71442015-01-15 16:57:00 -08001540 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001541 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001542 Returns:
1543 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001544
Jon Halle3f39ff2015-01-13 11:50:53 -08001545 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001546 options developers provide for point-to-point
1547 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001548 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001549 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001550 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001551
Jeremy Songsterff553672016-05-12 17:06:23 -07001552 if ethType:
1553 cmd += " --ethType " + str( ethType )
1554 if ethSrc:
1555 cmd += " --ethSrc " + str( ethSrc )
1556 if ethDst:
1557 cmd += " --ethDst " + str( ethDst )
1558 if bandwidth:
1559 cmd += " --bandwidth " + str( bandwidth )
1560 if lambdaAlloc:
1561 cmd += " --lambda "
1562 if ipProto:
1563 cmd += " --ipProto " + str( ipProto )
1564 if ipSrc:
1565 cmd += " --ipSrc " + str( ipSrc )
1566 if ipDst:
1567 cmd += " --ipDst " + str( ipDst )
1568 if tcpSrc:
1569 cmd += " --tcpSrc " + str( tcpSrc )
1570 if tcpDst:
1571 cmd += " --tcpDst " + str( tcpDst )
1572 if vlanId:
1573 cmd += " -v " + str( vlanId )
1574 if setVlan:
1575 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001576 if encap:
1577 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001578 if protected:
1579 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001580
kelvin8ec71442015-01-15 16:57:00 -08001581 # Check whether the user appended the port
1582 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001583 if "/" in ingressDevice:
1584 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001585 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001586 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001587 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001588 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001589 # Would it make sense to throw an exception and exit
1590 # the test?
1591 return None
andrewonlab36af3822014-11-18 17:48:18 -05001592
kelvin8ec71442015-01-15 16:57:00 -08001593 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001594 str( ingressDevice ) + "/" +\
1595 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001596
kelvin-onlabd3b64892015-01-20 13:26:24 -08001597 if "/" in egressDevice:
1598 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001599 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001600 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001601 main.log.error( "You must specify the egress port" )
1602 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001603
kelvin8ec71442015-01-15 16:57:00 -08001604 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001605 str( egressDevice ) + "/" +\
1606 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001607
kelvin-onlab898a6c62015-01-16 14:13:53 -08001608 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001609 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001610 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001611 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001612 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001613 main.log.error( self.name + ": Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001614 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001615 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001616 # TODO: print out all the options in this message?
1617 main.log.info( "Point-to-point intent installed between " +
1618 str( ingressDevice ) + " and " +
1619 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001620 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001621 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001622 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001623 else:
1624 main.log.error( "Error, intent ID not found" )
1625 return None
Jon Hallc6793552016-01-19 14:18:37 -08001626 except AssertionError:
1627 main.log.exception( "" )
1628 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001629 except TypeError:
1630 main.log.exception( self.name + ": Object not as expected" )
1631 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001632 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001633 main.log.error( self.name + ": EOF exception found" )
1634 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001635 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001636 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001637 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001638 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001639
kelvin-onlabd3b64892015-01-20 13:26:24 -08001640 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001641 self,
shahshreyac2f97072015-03-19 17:04:29 -07001642 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001643 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001644 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001645 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001646 ethType="",
1647 ethSrc="",
1648 ethDst="",
1649 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001650 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001651 ipProto="",
1652 ipSrc="",
1653 ipDst="",
1654 tcpSrc="",
1655 tcpDst="",
1656 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001657 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001658 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001659 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001660 partial=False,
1661 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001662 """
shahshreyad0c80432014-12-04 16:56:05 -08001663 Note:
shahshreya70622b12015-03-19 17:19:00 -07001664 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001665 is same. That is, all ingress devices include port numbers
1666 with a "/" or all ingress devices could specify device
1667 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001668 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001669 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001670 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001671 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001672 Optional:
1673 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001674 * ethSrc: specify ethSrc ( i.e. src mac addr )
1675 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001676 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001677 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001678 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001679 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001680 * ipSrc: specify ip source address
1681 * ipDst: specify ip destination address
1682 * tcpSrc: specify tcp source port
1683 * tcpDst: specify tcp destination port
1684 * setEthSrc: action to Rewrite Source MAC Address
1685 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001686 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001687 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001688 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001689 Description:
kelvin8ec71442015-01-15 16:57:00 -08001690 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001691 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001692 Returns:
1693 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001694
Jon Halle3f39ff2015-01-13 11:50:53 -08001695 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001696 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001697 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001698 """
shahshreyad0c80432014-12-04 16:56:05 -08001699 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001700 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001701
Jeremy Songsterff553672016-05-12 17:06:23 -07001702 if ethType:
1703 cmd += " --ethType " + str( ethType )
1704 if ethSrc:
1705 cmd += " --ethSrc " + str( ethSrc )
1706 if ethDst:
1707 cmd += " --ethDst " + str( ethDst )
1708 if bandwidth:
1709 cmd += " --bandwidth " + str( bandwidth )
1710 if lambdaAlloc:
1711 cmd += " --lambda "
1712 if ipProto:
1713 cmd += " --ipProto " + str( ipProto )
1714 if ipSrc:
1715 cmd += " --ipSrc " + str( ipSrc )
1716 if ipDst:
1717 cmd += " --ipDst " + str( ipDst )
1718 if tcpSrc:
1719 cmd += " --tcpSrc " + str( tcpSrc )
1720 if tcpDst:
1721 cmd += " --tcpDst " + str( tcpDst )
1722 if setEthSrc:
1723 cmd += " --setEthSrc " + str( setEthSrc )
1724 if setEthDst:
1725 cmd += " --setEthDst " + str( setEthDst )
1726 if vlanId:
1727 cmd += " -v " + str( vlanId )
1728 if setVlan:
1729 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001730 if partial:
1731 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001732 if encap:
1733 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001734
kelvin8ec71442015-01-15 16:57:00 -08001735 # Check whether the user appended the port
1736 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001737
1738 if portIngressList is None:
1739 for ingressDevice in ingressDeviceList:
1740 if "/" in ingressDevice:
1741 cmd += " " + str( ingressDevice )
1742 else:
1743 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001744 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001745 # TODO: perhaps more meaningful return
1746 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001747 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001748 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001749 for ingressDevice, portIngress in zip( ingressDeviceList,
1750 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001751 cmd += " " + \
1752 str( ingressDevice ) + "/" +\
1753 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001754 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001755 main.log.error( "Device list and port list does not " +
1756 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001757 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001758 if "/" in egressDevice:
1759 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001760 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001761 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001762 main.log.error( "You must specify " +
1763 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001764 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001765
kelvin8ec71442015-01-15 16:57:00 -08001766 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001767 str( egressDevice ) + "/" +\
1768 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001769 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001770 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001771 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001772 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001773 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001774 main.log.error( self.name + ": Error in adding multipoint-to-singlepoint " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001775 "intent" )
1776 return None
shahshreyad0c80432014-12-04 16:56:05 -08001777 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001778 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001779 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001780 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001781 else:
1782 main.log.error( "Error, intent ID not found" )
1783 return None
Jon Hallc6793552016-01-19 14:18:37 -08001784 except AssertionError:
1785 main.log.exception( "" )
1786 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001787 except TypeError:
1788 main.log.exception( self.name + ": Object not as expected" )
1789 return None
1790 except pexpect.EOF:
1791 main.log.error( self.name + ": EOF exception found" )
1792 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001793 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001794 except Exception:
1795 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001796 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001797
1798 def addSinglepointToMultipointIntent(
1799 self,
1800 ingressDevice,
1801 egressDeviceList,
1802 portIngress="",
1803 portEgressList=None,
1804 ethType="",
1805 ethSrc="",
1806 ethDst="",
1807 bandwidth="",
1808 lambdaAlloc=False,
1809 ipProto="",
1810 ipSrc="",
1811 ipDst="",
1812 tcpSrc="",
1813 tcpDst="",
1814 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001815 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001816 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001817 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001818 partial=False,
1819 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001820 """
1821 Note:
1822 This function assumes the format of all egress devices
1823 is same. That is, all egress devices include port numbers
1824 with a "/" or all egress devices could specify device
1825 ids and port numbers seperately.
1826 Required:
1827 * EgressDeviceList: List of device ids of egress device
1828 ( Atleast 2 eress devices required in the list )
1829 * ingressDevice: device id of ingress device
1830 Optional:
1831 * ethType: specify ethType
1832 * ethSrc: specify ethSrc ( i.e. src mac addr )
1833 * ethDst: specify ethDst ( i.e. dst mac addr )
1834 * bandwidth: specify bandwidth capacity of link
1835 * lambdaAlloc: if True, intent will allocate lambda
1836 for the specified intent
1837 * ipProto: specify ip protocol
1838 * ipSrc: specify ip source address
1839 * ipDst: specify ip destination address
1840 * tcpSrc: specify tcp source port
1841 * tcpDst: specify tcp destination port
1842 * setEthSrc: action to Rewrite Source MAC Address
1843 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001844 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001845 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001846 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001847 Description:
1848 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1849 specifying device id's and optional fields
1850 Returns:
1851 A string of the intent id or None on error
1852
1853 NOTE: This function may change depending on the
1854 options developers provide for singlepoint-to-multipoint
1855 intent via cli
1856 """
1857 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001858 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001859
Jeremy Songsterff553672016-05-12 17:06:23 -07001860 if ethType:
1861 cmd += " --ethType " + str( ethType )
1862 if ethSrc:
1863 cmd += " --ethSrc " + str( ethSrc )
1864 if ethDst:
1865 cmd += " --ethDst " + str( ethDst )
1866 if bandwidth:
1867 cmd += " --bandwidth " + str( bandwidth )
1868 if lambdaAlloc:
1869 cmd += " --lambda "
1870 if ipProto:
1871 cmd += " --ipProto " + str( ipProto )
1872 if ipSrc:
1873 cmd += " --ipSrc " + str( ipSrc )
1874 if ipDst:
1875 cmd += " --ipDst " + str( ipDst )
1876 if tcpSrc:
1877 cmd += " --tcpSrc " + str( tcpSrc )
1878 if tcpDst:
1879 cmd += " --tcpDst " + str( tcpDst )
1880 if setEthSrc:
1881 cmd += " --setEthSrc " + str( setEthSrc )
1882 if setEthDst:
1883 cmd += " --setEthDst " + str( setEthDst )
1884 if vlanId:
1885 cmd += " -v " + str( vlanId )
1886 if setVlan:
1887 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001888 if partial:
1889 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001890 if encap:
1891 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001892
1893 # Check whether the user appended the port
1894 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001895
kelvin-onlabb9408212015-04-01 13:34:04 -07001896 if "/" in ingressDevice:
1897 cmd += " " + str( ingressDevice )
1898 else:
1899 if not portIngress:
1900 main.log.error( "You must specify " +
1901 "the Ingress port" )
1902 return main.FALSE
1903
1904 cmd += " " +\
1905 str( ingressDevice ) + "/" +\
1906 str( portIngress )
1907
1908 if portEgressList is None:
1909 for egressDevice in egressDeviceList:
1910 if "/" in egressDevice:
1911 cmd += " " + str( egressDevice )
1912 else:
1913 main.log.error( "You must specify " +
1914 "the egress port" )
1915 # TODO: perhaps more meaningful return
1916 return main.FALSE
1917 else:
1918 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001919 for egressDevice, portEgress in zip( egressDeviceList,
1920 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001921 cmd += " " + \
1922 str( egressDevice ) + "/" +\
1923 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001924 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001925 main.log.error( "Device list and port list does not " +
1926 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001927 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001928 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001929 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001930 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001931 # If error, return error message
1932 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001933 main.log.error( self.name + ": Error in adding singlepoint-to-multipoint " +
kelvin-onlabb9408212015-04-01 13:34:04 -07001934 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001935 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001936 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001937 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001938 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001939 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001940 else:
1941 main.log.error( "Error, intent ID not found" )
1942 return None
Jon Hallc6793552016-01-19 14:18:37 -08001943 except AssertionError:
1944 main.log.exception( "" )
1945 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001946 except TypeError:
1947 main.log.exception( self.name + ": Object not as expected" )
1948 return None
shahshreyad0c80432014-12-04 16:56:05 -08001949 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001950 main.log.error( self.name + ": EOF exception found" )
1951 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001952 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001953 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001954 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001955 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001956
Hari Krishna9e232602015-04-13 17:29:08 -07001957 def addMplsIntent(
1958 self,
1959 ingressDevice,
1960 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001961 ingressPort="",
1962 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001963 ethType="",
1964 ethSrc="",
1965 ethDst="",
1966 bandwidth="",
1967 lambdaAlloc=False,
1968 ipProto="",
1969 ipSrc="",
1970 ipDst="",
1971 tcpSrc="",
1972 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001973 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001974 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001975 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001976 """
1977 Required:
1978 * ingressDevice: device id of ingress device
1979 * egressDevice: device id of egress device
1980 Optional:
1981 * ethType: specify ethType
1982 * ethSrc: specify ethSrc ( i.e. src mac addr )
1983 * ethDst: specify ethDst ( i.e. dst mac addr )
1984 * bandwidth: specify bandwidth capacity of link
1985 * lambdaAlloc: if True, intent will allocate lambda
1986 for the specified intent
1987 * ipProto: specify ip protocol
1988 * ipSrc: specify ip source address
1989 * ipDst: specify ip destination address
1990 * tcpSrc: specify tcp source port
1991 * tcpDst: specify tcp destination port
1992 * ingressLabel: Ingress MPLS label
1993 * egressLabel: Egress MPLS label
1994 Description:
1995 Adds MPLS intent by
1996 specifying device id's and optional fields
1997 Returns:
1998 A string of the intent id or None on error
1999
2000 NOTE: This function may change depending on the
2001 options developers provide for MPLS
2002 intent via cli
2003 """
2004 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07002005 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07002006
Jeremy Songsterff553672016-05-12 17:06:23 -07002007 if ethType:
2008 cmd += " --ethType " + str( ethType )
2009 if ethSrc:
2010 cmd += " --ethSrc " + str( ethSrc )
2011 if ethDst:
2012 cmd += " --ethDst " + str( ethDst )
2013 if bandwidth:
2014 cmd += " --bandwidth " + str( bandwidth )
2015 if lambdaAlloc:
2016 cmd += " --lambda "
2017 if ipProto:
2018 cmd += " --ipProto " + str( ipProto )
2019 if ipSrc:
2020 cmd += " --ipSrc " + str( ipSrc )
2021 if ipDst:
2022 cmd += " --ipDst " + str( ipDst )
2023 if tcpSrc:
2024 cmd += " --tcpSrc " + str( tcpSrc )
2025 if tcpDst:
2026 cmd += " --tcpDst " + str( tcpDst )
2027 if ingressLabel:
2028 cmd += " --ingressLabel " + str( ingressLabel )
2029 if egressLabel:
2030 cmd += " --egressLabel " + str( egressLabel )
2031 if priority:
2032 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07002033
2034 # Check whether the user appended the port
2035 # or provided it as an input
2036 if "/" in ingressDevice:
2037 cmd += " " + str( ingressDevice )
2038 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002039 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002040 main.log.error( "You must specify the ingress port" )
2041 return None
2042
2043 cmd += " " + \
2044 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002045 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07002046
2047 if "/" in egressDevice:
2048 cmd += " " + str( egressDevice )
2049 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002050 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002051 main.log.error( "You must specify the egress port" )
2052 return None
2053
2054 cmd += " " +\
2055 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002056 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07002057
2058 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08002059 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002060 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07002061 # If error, return error message
2062 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002063 main.log.error( self.name + ": Error in adding mpls intent" )
Hari Krishna9e232602015-04-13 17:29:08 -07002064 return None
2065 else:
2066 # TODO: print out all the options in this message?
2067 main.log.info( "MPLS intent installed between " +
2068 str( ingressDevice ) + " and " +
2069 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002070 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07002071 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002072 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07002073 else:
2074 main.log.error( "Error, intent ID not found" )
2075 return None
Jon Hallc6793552016-01-19 14:18:37 -08002076 except AssertionError:
2077 main.log.exception( "" )
2078 return None
Hari Krishna9e232602015-04-13 17:29:08 -07002079 except TypeError:
2080 main.log.exception( self.name + ": Object not as expected" )
2081 return None
2082 except pexpect.EOF:
2083 main.log.error( self.name + ": EOF exception found" )
2084 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002085 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002086 except Exception:
2087 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002088 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002089
Jon Hallefbd9792015-03-05 16:11:36 -08002090 def removeIntent( self, intentId, app='org.onosproject.cli',
2091 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002092 """
shahshreya1c818fc2015-02-26 13:44:08 -08002093 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07002094 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08002095 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07002096 -p or --purge: Purge the intent from the store after removal
2097
Jon Halle3f39ff2015-01-13 11:50:53 -08002098 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07002099 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08002100 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08002101 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002102 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002103 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08002104 if purge:
2105 cmdStr += " -p"
2106 if sync:
2107 cmdStr += " -s"
2108
2109 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002110 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002111 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002112 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08002113 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002114 main.log.error( self.name + ": Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002115 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04002116 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002117 # TODO: Should this be main.TRUE
2118 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002119 except AssertionError:
2120 main.log.exception( "" )
2121 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002122 except TypeError:
2123 main.log.exception( self.name + ": Object not as expected" )
2124 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002125 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002126 main.log.error( self.name + ": EOF exception found" )
2127 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002128 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002129 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002130 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002131 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002132
YPZhangfebf7302016-05-24 16:45:56 -07002133 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08002134 """
2135 Description:
2136 Remove all the intents
2137 Optional args:-
2138 -s or --sync: Waits for the removal before returning
2139 -p or --purge: Purge the intent from the store after removal
2140 Returns:
2141 Returns main.TRUE if all intents are removed, otherwise returns
2142 main.FALSE; Returns None for exception
2143 """
2144 try:
2145 cmdStr = "remove-intent"
2146 if purge:
2147 cmdStr += " -p"
2148 if sync:
2149 cmdStr += " -s"
2150
2151 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002152 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002153 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002154 assert "Command not found:" not in handle, handle
2155 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002156 main.log.error( self.name + ": Error in removing intent" )
Jeremy42df2e72016-02-23 16:37:46 -08002157 return main.FALSE
2158 else:
2159 return main.TRUE
2160 except AssertionError:
2161 main.log.exception( "" )
2162 return None
2163 except TypeError:
2164 main.log.exception( self.name + ": Object not as expected" )
2165 return None
2166 except pexpect.EOF:
2167 main.log.error( self.name + ": EOF exception found" )
2168 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002169 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002170 except Exception:
2171 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002172 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002173
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002174 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002175 """
2176 Purges all WITHDRAWN Intents
2177 """
2178 try:
2179 cmdStr = "purge-intents"
2180 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002181 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002182 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002183 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002184 main.log.error( self.name + ": Error in purging intents" )
Hari Krishna0ce0e152015-06-23 09:55:29 -07002185 return main.FALSE
2186 else:
2187 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002188 except AssertionError:
2189 main.log.exception( "" )
2190 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002191 except TypeError:
2192 main.log.exception( self.name + ": Object not as expected" )
2193 return None
2194 except pexpect.EOF:
2195 main.log.error( self.name + ": EOF exception found" )
2196 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002197 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002198 except Exception:
2199 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002200 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002201
Devin Lime6fe3c42017-10-18 16:28:40 -07002202 def wipeout( self ):
2203 """
2204 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2205 """
2206 try:
2207 cmdStr = "wipe-out please"
2208 handle = self.sendline( cmdStr, timeout=60 )
2209 assert handle is not None, "Error in sendline"
2210 assert "Command not found:" not in handle, handle
2211 return main.TRUE
2212 except AssertionError:
2213 main.log.exception( "" )
2214 return None
2215 except TypeError:
2216 main.log.exception( self.name + ": Object not as expected" )
2217 return None
2218 except pexpect.EOF:
2219 main.log.error( self.name + ": EOF exception found" )
2220 main.log.error( self.name + ": " + self.handle.before )
2221 main.cleanAndExit()
2222 except Exception:
2223 main.log.exception( self.name + ": Uncaught exception!" )
2224 main.cleanAndExit()
2225
kelvin-onlabd3b64892015-01-20 13:26:24 -08002226 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002227 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002228 NOTE: This method should be used after installing application:
2229 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002230 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002231 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002232 Description:
2233 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002234 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002235 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002236 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002237 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002238 cmdStr += " -j"
2239 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002240 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002241 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002242 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002243 except AssertionError:
2244 main.log.exception( "" )
2245 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002246 except TypeError:
2247 main.log.exception( self.name + ": Object not as expected" )
2248 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002249 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002250 main.log.error( self.name + ": EOF exception found" )
2251 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002252 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002253 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002254 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002255 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002256
pingping-lin54b03372015-08-13 14:43:10 -07002257 def ipv4RouteNumber( self ):
2258 """
2259 NOTE: This method should be used after installing application:
2260 onos-app-sdnip
2261 Description:
2262 Obtain the total IPv4 routes number in the system
2263 """
2264 try:
Pratik Parab57963572017-05-09 11:37:54 -07002265 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002266 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002267 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002268 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002269 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002270 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002271 except AssertionError:
2272 main.log.exception( "" )
2273 return None
2274 except ( TypeError, ValueError ):
2275 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002276 return None
2277 except pexpect.EOF:
2278 main.log.error( self.name + ": EOF exception found" )
2279 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002280 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002281 except Exception:
2282 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002283 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002284
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002285 # =============Function to check Bandwidth allocation========
Jon Hall0e240372018-05-02 11:21:57 -07002286 def allocations( self, jsonFormat = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002287 """
2288 Description:
2289 Obtain Bandwidth Allocation Information from ONOS cli.
2290 """
2291 try:
2292 cmdStr = "allocations"
2293 if jsonFormat:
2294 cmdStr += " -j"
Jon Hall0e240372018-05-02 11:21:57 -07002295 handle = self.sendline( cmdStr, timeout=300 )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002296 assert handle is not None, "Error in sendline"
2297 assert "Command not found:" not in handle, handle
2298 return handle
2299 except AssertionError:
2300 main.log.exception( "" )
2301 return None
2302 except ( TypeError, ValueError ):
2303 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2304 return None
2305 except pexpect.EOF:
2306 main.log.error( self.name + ": EOF exception found" )
2307 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002308 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002309 except Exception:
2310 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002311 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002312
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002313 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002314 """
andrewonlabe6745342014-10-17 14:29:13 -04002315 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002316 Obtain intents from the ONOS cli.
2317 Optional:
2318 * jsonFormat: Enable output formatting in json, default to True
2319 * summary: Whether only output the intent summary, defaults to False
2320 * type: Only output a certain type of intent. This options is valid
2321 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002322 """
andrewonlabe6745342014-10-17 14:29:13 -04002323 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002324 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002325 if summary:
2326 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002327 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002328 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002329 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002330 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002331 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002332 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002333 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002334 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002335 else:
Jon Hallff566d52016-01-15 14:45:36 -08002336 intentType = ""
2337 # IF we want the summary of a specific intent type
2338 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002339 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002340 if intentType in jsonResult.keys():
2341 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002342 else:
Jon Hallff566d52016-01-15 14:45:36 -08002343 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002344 return handle
2345 else:
2346 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002347 except AssertionError:
2348 main.log.exception( "" )
2349 return None
2350 except ( TypeError, ValueError ):
2351 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002352 return None
2353 except pexpect.EOF:
2354 main.log.error( self.name + ": EOF exception found" )
2355 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002356 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002357 except Exception:
2358 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002359 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002360
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002361 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002362 """
You Wangfdcbfc42016-05-16 12:16:53 -07002363 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002364 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002365 list of intent IDs.
2366 Parameters:
2367 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002368 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002369 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002370 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002371 accepted.
2372 Returns a list of dictionaries if a list of intent IDs is accepted,
2373 and each dictionary maps 'id' to the Intent ID and 'state' to
2374 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002375 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002376
kelvin-onlab54400a92015-02-26 18:05:51 -08002377 try:
2378 state = "State is Undefined"
2379 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002380 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002381 else:
Jon Hallc6793552016-01-19 14:18:37 -08002382 rawJson = intentsJson
2383 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002384 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002385 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002386 if intentsId == intent[ 'id' ]:
2387 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002388 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002389 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002390 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002391 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002392 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002393 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002394 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002395 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002396 for intent in parsedIntentsJson:
2397 if intentsId[ i ] == intent[ 'id' ]:
2398 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002399 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002400 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002401 break
Jon Hallefbd9792015-03-05 16:11:36 -08002402 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002403 main.log.warn( "Could not find all intents in ONOS output" )
2404 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002405 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002406 else:
Jon Hall53158082017-05-18 11:17:00 -07002407 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002408 return None
Jon Hallc6793552016-01-19 14:18:37 -08002409 except ( TypeError, ValueError ):
2410 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002411 return None
2412 except pexpect.EOF:
2413 main.log.error( self.name + ": EOF exception found" )
2414 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002415 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002416 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002417 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002418 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002419
Jon Hallf539eb92017-05-22 17:18:42 -07002420 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002421 """
2422 Description:
2423 Check intents state
2424 Required:
2425 intentsId - List of intents ID to be checked
2426 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002427 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002428 state in the list.
2429 *NOTE: You can pass in a list of expected state,
2430 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002431 Return:
Jon Hall53158082017-05-18 11:17:00 -07002432 Returns main.TRUE only if all intent are the same as expected states,
2433 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002434 """
2435 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002436 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002437 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002438
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002439 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002440 intentsDict = []
2441 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002442 if isinstance( intentsId, types.StringType ) \
2443 and intent.get( 'id' ) == intentsId:
2444 intentsDict.append( intent )
2445 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002446 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002447 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002448
2449 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002450 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002451 "getting intents state" )
2452 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002453
2454 if isinstance( expectedState, types.StringType ):
2455 for intents in intentsDict:
2456 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002457 main.log.debug( self.name + " : Intent ID - " +
2458 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002459 " actual state = " +
2460 intents.get( 'state' )
2461 + " does not equal expected state = "
2462 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002463 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002464 elif isinstance( expectedState, types.ListType ):
2465 for intents in intentsDict:
2466 if not any( state == intents.get( 'state' ) for state in
2467 expectedState ):
2468 main.log.debug( self.name + " : Intent ID - " +
2469 intents.get( 'id' ) +
2470 " actual state = " +
2471 intents.get( 'state' ) +
2472 " does not equal expected states = "
2473 + str( expectedState ) )
2474 returnValue = main.FALSE
2475
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002476 if returnValue == main.TRUE:
2477 main.log.info( self.name + ": All " +
2478 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002479 " intents are in " + str( expectedState ) +
2480 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002481 return returnValue
2482 except TypeError:
2483 main.log.exception( self.name + ": Object not as expected" )
2484 return None
2485 except pexpect.EOF:
2486 main.log.error( self.name + ": EOF exception found" )
2487 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002488 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002489 except Exception:
2490 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002491 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002492
Jon Hallf539eb92017-05-22 17:18:42 -07002493 def compareBandwidthAllocations( self, expectedAllocations ):
2494 """
2495 Description:
2496 Compare the allocated bandwidth with the given allocations
2497 Required:
2498 expectedAllocations - The expected ONOS output of the allocations command
2499 Return:
2500 Returns main.TRUE only if all intent are the same as expected states,
2501 otherwise returns main.FALSE.
2502 """
2503 # FIXME: Convert these string comparisons to object comparisons
2504 try:
2505 returnValue = main.TRUE
2506 bandwidthFailed = False
2507 rawAlloc = self.allocations()
2508 expectedFormat = StringIO( expectedAllocations )
2509 ONOSOutput = StringIO( rawAlloc )
2510 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2511 str( expectedFormat ) ) )
2512
2513 for actual, expected in izip( ONOSOutput, expectedFormat ):
2514 actual = actual.rstrip()
2515 expected = expected.rstrip()
2516 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2517 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002518 marker1 = actual.find( 'allocated' )
2519 m1 = actual[ :marker1 ]
2520 marker2 = expected.find( 'allocated' )
2521 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002522 if m1 != m2:
2523 bandwidthFailed = True
2524 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2525 bandwidthFailed = True
2526 expectedFormat.close()
2527 ONOSOutput.close()
2528
2529 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002530 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002531 returnValue = main.FALSE
2532 return returnValue
2533 except TypeError:
2534 main.log.exception( self.name + ": Object not as expected" )
2535 return None
2536 except pexpect.EOF:
2537 main.log.error( self.name + ": EOF exception found" )
2538 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002539 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002540 except Exception:
2541 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002542 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002543
You Wang66518af2016-05-16 15:32:59 -07002544 def compareIntent( self, intentDict ):
2545 """
2546 Description:
2547 Compare the intent ids and states provided in the argument with all intents in ONOS
2548 Return:
2549 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2550 Arguments:
2551 intentDict: a dictionary which maps intent ids to intent states
2552 """
2553 try:
2554 intentsRaw = self.intents()
2555 intentsJson = json.loads( intentsRaw )
2556 intentDictONOS = {}
2557 for intent in intentsJson:
2558 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002559 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002560 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002561 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002562 str( len( intentDict ) ) + " expected and " +
2563 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002564 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002565 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002566 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002567 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2568 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002569 else:
2570 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2571 main.log.debug( self.name + ": intent ID - " + intentID +
2572 " expected state is " + intentDict[ intentID ] +
2573 " but actual state is " + intentDictONOS[ intentID ] )
2574 returnValue = main.FALSE
2575 intentDictONOS.pop( intentID )
2576 if len( intentDictONOS ) > 0:
2577 returnValue = main.FALSE
2578 for intentID in intentDictONOS.keys():
2579 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002580 if returnValue == main.TRUE:
2581 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2582 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002583 except KeyError:
2584 main.log.exception( self.name + ": KeyError exception found" )
2585 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002586 except ( TypeError, ValueError ):
2587 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002588 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002589 except pexpect.EOF:
2590 main.log.error( self.name + ": EOF exception found" )
2591 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002592 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002593 except Exception:
2594 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002595 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002596
YPZhang14a4aa92016-07-15 13:37:15 -07002597 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002598 """
2599 Description:
2600 Check the number of installed intents.
2601 Optional:
2602 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002603 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002604 Return:
2605 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2606 , otherwise, returns main.FALSE.
2607 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002608
GlennRCed771242016-01-13 17:02:47 -08002609 try:
2610 cmd = "intents -s -j"
2611
2612 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002613 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002614 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002615 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002616 response = json.loads( response )
2617
2618 # get total and installed number, see if they are match
2619 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002620 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002621 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2622 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002623 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002624 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2625 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002626 return main.FALSE
2627
Jon Hallc6793552016-01-19 14:18:37 -08002628 except ( TypeError, ValueError ):
2629 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002630 return None
2631 except pexpect.EOF:
2632 main.log.error( self.name + ": EOF exception found" )
2633 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002634 if noExit:
2635 return main.FALSE
2636 else:
Devin Lim44075962017-08-11 10:56:37 -07002637 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002638 except pexpect.TIMEOUT:
2639 main.log.error( self.name + ": ONOS timeout" )
2640 return None
GlennRCed771242016-01-13 17:02:47 -08002641 except Exception:
2642 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002643 if noExit:
2644 return main.FALSE
2645 else:
Devin Lim44075962017-08-11 10:56:37 -07002646 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002647
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002648 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002649 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002650 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002651 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002652 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002653 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002654 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002655 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002656 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002657 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002658 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002659 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002660 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002661 cmdStr += " -n"
2662 cmdStr += " " + state
2663 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002664 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002665 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002666 assert "Command not found:" not in handle, handle
2667 if re.search( "Error:", handle ):
2668 main.log.error( self.name + ": flows() response: " +
2669 str( handle ) )
2670 return handle
2671 except AssertionError:
2672 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002673 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002674 except TypeError:
2675 main.log.exception( self.name + ": Object not as expected" )
2676 return None
Jon Hallc6793552016-01-19 14:18:37 -08002677 except pexpect.TIMEOUT:
2678 main.log.error( self.name + ": ONOS timeout" )
2679 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002680 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002681 main.log.error( self.name + ": EOF exception found" )
2682 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002683 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002684 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002685 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002686 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002687
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002688 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002689 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002690 count = int( count ) if count else 0
steven30801eccfe212019-01-24 13:00:42 +08002691 main.log.debug( "found {} flows".format( count ) )
Jon Halle0f0b342017-04-18 11:43:47 -07002692 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002693
Jon Halle0f0b342017-04-18 11:43:47 -07002694 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002695 """
2696 Description:
GlennRCed771242016-01-13 17:02:47 -08002697 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002698 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2699 if the count of those states is 0, which means all current flows
2700 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002701 Optional:
GlennRCed771242016-01-13 17:02:47 -08002702 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002703 Return:
2704 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002705 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002706 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002707 """
2708 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002709 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002710 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002711 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002712 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002713 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002714 if rawFlows:
2715 # if we didn't get flows or flows function return None, we should return
2716 # main.Flase
2717 checkedStates.append( json.loads( rawFlows ) )
2718 else:
2719 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002720 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002721 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002722 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002723 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002724 except TypeError:
2725 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002726 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002727
GlennRCed771242016-01-13 17:02:47 -08002728 # We want to count PENDING_ADD if isPENDING is true
2729 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002730 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002731 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002732 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002733 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002734 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002735 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002736 except ( TypeError, ValueError ):
2737 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002738 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002739
YPZhang240842b2016-05-17 12:00:50 -07002740 except AssertionError:
2741 main.log.exception( "" )
2742 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002743 except pexpect.TIMEOUT:
2744 main.log.error( self.name + ": ONOS timeout" )
2745 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002746 except pexpect.EOF:
2747 main.log.error( self.name + ": EOF exception found" )
2748 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002749 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002750 except Exception:
2751 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002752 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002753
GlennRCed771242016-01-13 17:02:47 -08002754 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002755 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002756 """
andrewonlab87852b02014-11-19 18:44:19 -05002757 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002758 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002759 a specific point-to-point intent definition
2760 Required:
GlennRCed771242016-01-13 17:02:47 -08002761 * ingress: specify source dpid
2762 * egress: specify destination dpid
2763 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002764 Optional:
GlennRCed771242016-01-13 17:02:47 -08002765 * offset: the keyOffset is where the next batch of intents
2766 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002767 * noExit: If set to True, TestON will not exit if any error when issus command
2768 * getResponse: If set to True, function will return ONOS response.
2769
GlennRCed771242016-01-13 17:02:47 -08002770 Returns: If failed to push test intents, it will returen None,
2771 if successful, return true.
2772 Timeout expection will return None,
2773 TypeError will return false
2774 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002775 """
andrewonlab87852b02014-11-19 18:44:19 -05002776 try:
GlennRCed771242016-01-13 17:02:47 -08002777 if background:
2778 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002779 else:
GlennRCed771242016-01-13 17:02:47 -08002780 back = ""
2781 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002782 ingress,
2783 egress,
2784 batchSize,
2785 offset,
2786 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002787 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002788 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002789 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002790 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002791 if getResponse:
2792 return response
2793
GlennRCed771242016-01-13 17:02:47 -08002794 # TODO: We should handle if there is failure in installation
2795 return main.TRUE
2796
Jon Hallc6793552016-01-19 14:18:37 -08002797 except AssertionError:
2798 main.log.exception( "" )
2799 return None
GlennRCed771242016-01-13 17:02:47 -08002800 except pexpect.TIMEOUT:
2801 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002802 return None
andrewonlab87852b02014-11-19 18:44:19 -05002803 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002804 main.log.error( self.name + ": EOF exception found" )
2805 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002806 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002807 except TypeError:
2808 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002809 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002810 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002811 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002812 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002813
YPZhangebf9eb52016-05-12 15:20:24 -07002814 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002815 """
2816 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002817 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002818 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002819 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002820 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002821 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002822
YPZhangb5d3f832016-01-23 22:54:26 -08002823 try:
YPZhange3109a72016-02-02 11:25:37 -08002824 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002825 cmd = "flows -c added"
2826 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2827 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002828 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002829 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002830 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002831 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002832 else:
You Wang68568b12019-03-04 11:49:57 -08002833 main.log.warn( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002834 return None
2835 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002836
You Wangd3097f72018-12-12 11:56:03 -08002837 except IndexError:
2838 main.log.exception( "{}: Object not as expected!".format( self.name ) )
2839 main.log.debug( "rawFlows: {}".format( rawFlows ) )
2840 return None
You Wangd3cb2ce2016-05-16 14:01:24 -07002841 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002842 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002843 return None
2844 except pexpect.EOF:
2845 main.log.error( self.name + ": EOF exception found" )
2846 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002847 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002848 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002849 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002850 except pexpect.TIMEOUT:
2851 main.log.error( self.name + ": ONOS timeout" )
2852 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002853 except Exception:
2854 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002855 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002856 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002857 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002858
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002859 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002860 """
2861 Description:
2862 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002863 Optional:
2864 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002865 Return:
2866 The number of intents
2867 """
2868 try:
2869 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002870 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002871 if response is None:
2872 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002873 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002874 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002875 except ( TypeError, ValueError ):
2876 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002877 return None
2878 except pexpect.EOF:
2879 main.log.error( self.name + ": EOF exception found" )
2880 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002881 if noExit:
2882 return -1
2883 else:
Devin Lim44075962017-08-11 10:56:37 -07002884 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002885 except Exception:
2886 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002887 if noExit:
2888 return -1
2889 else:
Devin Lim44075962017-08-11 10:56:37 -07002890 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002891
kelvin-onlabd3b64892015-01-20 13:26:24 -08002892 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002893 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002894 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002895 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002896 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002897 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002898 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002899 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002900 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002901 cmdStr += " -j"
2902 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002903 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002904 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002905 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002906 except AssertionError:
2907 main.log.exception( "" )
2908 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002909 except TypeError:
2910 main.log.exception( self.name + ": Object not as expected" )
2911 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002912 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002913 main.log.error( self.name + ": EOF exception found" )
2914 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002915 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002916 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002917 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002918 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002919
kelvin-onlabd3b64892015-01-20 13:26:24 -08002920 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002921 """
2922 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002923 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002924 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002925 """
andrewonlab867212a2014-10-22 20:13:38 -04002926 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002927 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002928 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002929 cmdStr += " -j"
2930 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002931 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002932 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002933 if handle:
2934 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002935 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002936 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002937 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002938 else:
2939 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002940 except AssertionError:
2941 main.log.exception( "" )
2942 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002943 except TypeError:
2944 main.log.exception( self.name + ": Object not as expected" )
2945 return None
andrewonlab867212a2014-10-22 20:13:38 -04002946 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002947 main.log.error( self.name + ": EOF exception found" )
2948 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002949 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002950 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002951 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002952 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002953
kelvin8ec71442015-01-15 16:57:00 -08002954 # Wrapper functions ****************
2955 # Wrapper functions use existing driver
2956 # functions and extends their use case.
2957 # For example, we may use the output of
2958 # a normal driver function, and parse it
2959 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002960
kelvin-onlabd3b64892015-01-20 13:26:24 -08002961 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002962 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002963 Description:
2964 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002965 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002966 try:
kelvin8ec71442015-01-15 16:57:00 -08002967 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002968 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002969 if intentsStr is None:
2970 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002971 # Convert to a dictionary
2972 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002973 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002974 for intent in intents:
2975 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002976 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002977 except TypeError:
2978 main.log.exception( self.name + ": Object not as expected" )
2979 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002980 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002981 main.log.error( self.name + ": EOF exception found" )
2982 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002983 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002984 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002985 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002986 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002987
You Wang3c276252016-09-21 15:21:36 -07002988 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002989 """
2990 Determine the number of flow rules for the given device id that are
2991 in the added state
You Wang3c276252016-09-21 15:21:36 -07002992 Params:
2993 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002994 """
2995 try:
You Wang3c276252016-09-21 15:21:36 -07002996 if core:
2997 cmdStr = "flows any " + str( deviceId ) + " | " +\
2998 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2999 else:
3000 cmdStr = "flows any " + str( deviceId ) + " | " +\
3001 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003002 handle = self.lineCount( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003003 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003004 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08003005 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003006 except AssertionError:
3007 main.log.exception( "" )
3008 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08003009 except pexpect.EOF:
3010 main.log.error( self.name + ": EOF exception found" )
3011 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003012 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003013 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08003014 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003015 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04003016
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003017 def groupAddedCount( self, deviceId, core=False ):
3018 """
3019 Determine the number of group rules for the given device id that are
3020 in the added state
3021 Params:
3022 core: if True, only return the number of core groups added
3023 """
3024 try:
3025 if core:
3026 cmdStr = "groups any " + str( deviceId ) + " | " +\
3027 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
3028 else:
3029 cmdStr = "groups any " + str( deviceId ) + " | " +\
3030 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003031 handle = self.lineCount( cmdStr )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003032 assert handle is not None, "Error in sendline"
3033 assert "Command not found:" not in handle, handle
3034 return handle
3035 except AssertionError:
3036 main.log.exception( "" )
3037 return None
3038 except pexpect.EOF:
3039 main.log.error( self.name + ": EOF exception found" )
3040 main.log.error( self.name + ": " + self.handle.before )
3041 main.cleanAndExit()
3042 except Exception:
3043 main.log.exception( self.name + ": Uncaught exception!" )
3044 main.cleanAndExit()
3045
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003046 def addStaticRoute( self, subnet, intf):
3047 """
3048 Adds a static route to onos.
3049 Params:
3050 subnet: The subnet reaching through this route
3051 intf: The interface this route is reachable through
3052 """
3053 try:
3054 cmdStr = "route-add " + subnet + " " + intf
3055 handle = self.sendline( cmdStr )
3056 assert handle is not None, "Error in sendline"
3057 assert "Command not found:" not in handle, handle
3058 return handle
3059 except AssertionError:
3060 main.log.exception( "" )
3061 return None
3062 except pexpect.EOF:
3063 main.log.error( self.name + ": EOF exception found" )
3064 main.log.error( self.name + ": " + self.handle.before )
3065 main.cleanAndExit()
3066 except Exception:
3067 main.log.exception( self.name + ": Uncaught exception!" )
3068 main.cleanAndExit()
3069
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003070 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
3071 """
3072 Description:
3073 Check whether the number of groups for the given device id that
3074 are in ADDED state is bigger than minGroupCount.
3075 Required:
3076 * deviceId: device id to check the number of added group rules
3077 Optional:
3078 * minGroupCount: the number of groups to compare
3079 * core: if True, only check the number of core groups added
3080 * comparison: if 0, compare with greater than minFlowCount
3081 * if 1, compare with equal to minFlowCount
3082 Return:
3083 Returns the number of groups if it is bigger than minGroupCount,
3084 returns main.FALSE otherwise.
3085 """
3086 count = self.groupAddedCount( deviceId, core )
3087 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003088 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003089 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
3090
You Wangc02f3be2018-05-18 12:14:23 -07003091 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003092 """
3093 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07003094 deviceId: Id of the device from which we retrieve groups
3095 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003096 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003097 try:
You Wangc02f3be2018-05-18 12:14:23 -07003098 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
3099 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003100 assert handle is not None, "Error in sendline"
3101 assert "Command not found:" not in handle, handle
3102 return handle
3103 except AssertionError:
3104 main.log.exception( "" )
3105 return None
3106 except TypeError:
3107 main.log.exception( self.name + ": Object not as expected" )
3108 return None
3109 except pexpect.EOF:
3110 main.log.error( self.name + ": EOF exception found" )
3111 main.log.error( self.name + ": " + self.handle.before )
3112 main.cleanAndExit()
3113 except Exception:
3114 main.log.exception( self.name + ": Uncaught exception!" )
3115 main.cleanAndExit()
3116
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003117 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003118 """
3119 Description:
3120 Check whether the number of flow rules for the given device id that
3121 are in ADDED state is bigger than minFlowCount.
3122 Required:
3123 * deviceId: device id to check the number of added flow rules
3124 Optional:
3125 * minFlowCount: the number of flow rules to compare
3126 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003127 * comparison: if 0, compare with greater than minFlowCount
3128 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003129 Return:
3130 Returns the number of flow rules if it is bigger than minFlowCount,
3131 returns main.FALSE otherwise.
3132 """
3133 count = self.flowAddedCount( deviceId, core )
3134 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003135 main.log.debug( "found {} flows".format( count ) )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003136 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003137
kelvin-onlabd3b64892015-01-20 13:26:24 -08003138 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003139 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003140 Use 'devices' function to obtain list of all devices
3141 and parse the result to obtain a list of all device
3142 id's. Returns this list. Returns empty list if no
3143 devices exist
kelvin8ec71442015-01-15 16:57:00 -08003144 List is ordered sequentially
3145
andrewonlab3e15ead2014-10-15 14:21:34 -04003146 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003147 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003148 the ids. By obtaining the list of device ids on the fly,
3149 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003150 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003151 try:
kelvin8ec71442015-01-15 16:57:00 -08003152 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003153 devicesStr = self.devices( jsonFormat=False )
3154 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003155
kelvin-onlabd3b64892015-01-20 13:26:24 -08003156 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003157 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003158 return idList
kelvin8ec71442015-01-15 16:57:00 -08003159
3160 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003161 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003162 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003163 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003164 # Split list further into arguments before and after string
3165 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003166 # append to idList
3167 for arg in tempList:
3168 idList.append( arg.split( "id=" )[ 1 ] )
3169 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003170
Jon Halld4d4b372015-01-28 16:02:41 -08003171 except TypeError:
3172 main.log.exception( self.name + ": Object not as expected" )
3173 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003174 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003175 main.log.error( self.name + ": EOF exception found" )
3176 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003177 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003178 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003179 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003180 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003181
kelvin-onlabd3b64892015-01-20 13:26:24 -08003182 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003183 """
andrewonlab7c211572014-10-15 16:45:20 -04003184 Uses 'nodes' function to obtain list of all nodes
3185 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003186 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003187 Returns:
3188 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003189 """
andrewonlab7c211572014-10-15 16:45:20 -04003190 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003191 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003192 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003193 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003194 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003195 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003196 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003197 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003198 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003199 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003200 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003201 except ( TypeError, ValueError ):
3202 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003203 return None
andrewonlab7c211572014-10-15 16:45:20 -04003204 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003205 main.log.error( self.name + ": EOF exception found" )
3206 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003207 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003208 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003209 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003210 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003211
kelvin-onlabd3b64892015-01-20 13:26:24 -08003212 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003213 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003214 Return the first device from the devices api whose 'id' contains 'dpid'
3215 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003216 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003217 try:
kelvin8ec71442015-01-15 16:57:00 -08003218 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003219 return None
3220 else:
kelvin8ec71442015-01-15 16:57:00 -08003221 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003222 rawDevices = self.devices()
3223 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003224 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003225 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003226 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3227 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003228 return device
3229 return None
Jon Hallc6793552016-01-19 14:18:37 -08003230 except ( TypeError, ValueError ):
3231 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003232 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003233 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003234 main.log.error( self.name + ": EOF exception found" )
3235 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003236 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003237 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003238 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003239 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003240
You Wang24139872016-05-03 11:48:47 -07003241 def getTopology( self, topologyOutput ):
3242 """
3243 Definition:
3244 Loads a json topology output
3245 Return:
3246 topology = current ONOS topology
3247 """
You Wang24139872016-05-03 11:48:47 -07003248 try:
3249 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003250 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003251 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003252 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003253 except ( TypeError, ValueError ):
3254 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3255 return None
You Wang24139872016-05-03 11:48:47 -07003256 except pexpect.EOF:
3257 main.log.error( self.name + ": EOF exception found" )
3258 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003259 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003260 except Exception:
3261 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003262 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003263
Pier6a0c4de2018-03-18 16:01:30 -07003264 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003265 """
Jon Hallefbd9792015-03-05 16:11:36 -08003266 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003267 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003268 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003269
Flavio Castro82ee2f62016-06-07 15:04:12 -07003270 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003271 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003272 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003273 logLevel = level to log to.
3274 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003275
Jon Hallefbd9792015-03-05 16:11:36 -08003276 Returns: main.TRUE if the number of switches and links are correct,
3277 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003278 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003279 """
Jon Hall42db6dc2014-10-24 19:03:48 -04003280 try:
You Wang13310252016-07-31 10:56:14 -07003281 summary = self.summary()
3282 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003283 except ( TypeError, ValueError ):
3284 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3285 return main.ERROR
3286 try:
3287 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003288 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003289 return main.ERROR
3290 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003291 # Is the number of switches is what we expected
3292 devices = topology.get( 'devices', False )
3293 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003294 nodes = summary.get( 'nodes', False )
3295 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003296 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003297 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003298 # Is the number of links is what we expected
Pier6a0c4de2018-03-18 16:01:30 -07003299 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Flavio Castro82ee2f62016-06-07 15:04:12 -07003300 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3301 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003302 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003303 output = output + "The number of links and switches match "\
3304 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003305 result = main.TRUE
3306 else:
You Wang24139872016-05-03 11:48:47 -07003307 output = output + \
3308 "The number of links and switches does not match " + \
3309 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003310 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003311 output = output + "\n ONOS sees %i devices" % int( devices )
3312 output = output + " (%i expected) " % int( numoswitch )
Pier6a0c4de2018-03-18 16:01:30 -07003313 if int( numolink ) > 0:
3314 output = output + "and %i links " % int( links )
3315 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003316 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003317 output = output + "and %i controllers " % int( nodes )
3318 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003319 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003320 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003321 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003322 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003323 else:
You Wang24139872016-05-03 11:48:47 -07003324 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003325 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003326 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003327 main.log.error( self.name + ": EOF exception found" )
3328 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003329 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003330 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003331 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003332 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003333
kelvin-onlabd3b64892015-01-20 13:26:24 -08003334 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003335 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003336 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003337 deviceId must be the id of a device as seen in the onos devices command
3338 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003339 role must be either master, standby, or none
3340
Jon Halle3f39ff2015-01-13 11:50:53 -08003341 Returns:
3342 main.TRUE or main.FALSE based on argument verification and
3343 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003344 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003345 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003346 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003347 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003348 cmdStr = "device-role " +\
3349 str( deviceId ) + " " +\
3350 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003351 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003352 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003353 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003354 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003355 if re.search( "Error", handle ):
3356 # end color output to escape any colours
3357 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003358 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003359 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003360 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003361 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003362 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003363 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003364 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003365 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003366 except AssertionError:
3367 main.log.exception( "" )
3368 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003369 except TypeError:
3370 main.log.exception( self.name + ": Object not as expected" )
3371 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003372 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003373 main.log.error( self.name + ": EOF exception found" )
3374 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003375 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003376 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003377 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003378 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003379
kelvin-onlabd3b64892015-01-20 13:26:24 -08003380 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003381 """
Jon Hall0dd09952018-04-19 09:59:11 -07003382 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003383 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003384 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003385 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003386 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003387 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003388 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003389 cmdStr += " -j"
3390 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003391 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003392 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003393 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003394 except AssertionError:
3395 main.log.exception( "" )
3396 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003397 except TypeError:
3398 main.log.exception( self.name + ": Object not as expected" )
3399 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003400 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003401 main.log.error( self.name + ": EOF exception found" )
3402 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003403 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003404 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003405 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003406 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003407
kelvin-onlabd3b64892015-01-20 13:26:24 -08003408 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003409 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003410 CLI command to get the current leader for the Election test application
3411 NOTE: Requires installation of the onos-app-election feature
3412 Returns: Node IP of the leader if one exists
3413 None if none exists
3414 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003415 """
Jon Hall94fd0472014-12-08 11:52:42 -08003416 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003417 cmdStr = "election-test-leader"
3418 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003419 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003420 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003421 # Leader
3422 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003423 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003424 nodeSearch = re.search( leaderPattern, response )
3425 if nodeSearch:
3426 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003427 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003428 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003429 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003430 # no leader
3431 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003432 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003433 nullSearch = re.search( nullPattern, response )
3434 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003435 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003436 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003437 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003438 # error
Jon Hall0e240372018-05-02 11:21:57 -07003439 main.log.error( self.name + ": Error in electionTestLeader on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003440 ": " + "unexpected response" )
3441 main.log.error( repr( response ) )
3442 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003443 except AssertionError:
3444 main.log.exception( "" )
3445 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003446 except TypeError:
3447 main.log.exception( self.name + ": Object not as expected" )
3448 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003449 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003450 main.log.error( self.name + ": EOF exception found" )
3451 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003452 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003453 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003454 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003455 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003456
kelvin-onlabd3b64892015-01-20 13:26:24 -08003457 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003458 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003459 CLI command to run for leadership of the Election test application.
3460 NOTE: Requires installation of the onos-app-election feature
3461 Returns: Main.TRUE on success
3462 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003463 """
Jon Hall94fd0472014-12-08 11:52:42 -08003464 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003465 cmdStr = "election-test-run"
3466 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003467 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003468 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003469 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003470 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003471 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003472 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003473 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003474 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003475 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003476 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003477 # error
Jon Hall0e240372018-05-02 11:21:57 -07003478 main.log.error( self.name + ": Error in electionTestRun on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003479 ": " + "unexpected response" )
3480 main.log.error( repr( response ) )
3481 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003482 except AssertionError:
3483 main.log.exception( "" )
3484 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003485 except TypeError:
3486 main.log.exception( self.name + ": Object not as expected" )
3487 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003488 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003489 main.log.error( self.name + ": EOF exception found" )
3490 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003491 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003492 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003493 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003494 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003495
kelvin-onlabd3b64892015-01-20 13:26:24 -08003496 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003497 """
Jon Hall94fd0472014-12-08 11:52:42 -08003498 * CLI command to withdraw the local node from leadership election for
3499 * the Election test application.
3500 #NOTE: Requires installation of the onos-app-election feature
3501 Returns: Main.TRUE on success
3502 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003503 """
Jon Hall94fd0472014-12-08 11:52:42 -08003504 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003505 cmdStr = "election-test-withdraw"
3506 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003507 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003508 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003509 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003510 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003511 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003512 if re.search( successPattern, response ):
3513 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003514 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003515 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003516 # error
Jon Hall0e240372018-05-02 11:21:57 -07003517 main.log.error( self.name + ": Error in electionTestWithdraw on " +
Jon Hall97cf84a2016-06-20 13:35:58 -07003518 self.name + ": " + "unexpected response" )
3519 main.log.error( repr( response ) )
3520 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003521 except AssertionError:
3522 main.log.exception( "" )
3523 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003524 except TypeError:
3525 main.log.exception( self.name + ": Object not as expected" )
3526 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003527 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003528 main.log.error( self.name + ": EOF exception found" )
3529 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003530 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003531 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003532 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003533 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003534
kelvin8ec71442015-01-15 16:57:00 -08003535 def getDevicePortsEnabledCount( self, dpid ):
3536 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003537 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003538 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003539 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003540 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003541 cmdStr = "onos:ports -e " + dpid + " | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003542 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003543 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003544 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003545 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003546 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003547 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003548 return output
Jon Hallc6793552016-01-19 14:18:37 -08003549 except AssertionError:
3550 main.log.exception( "" )
3551 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003552 except TypeError:
3553 main.log.exception( self.name + ": Object not as expected" )
3554 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003555 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003556 main.log.error( self.name + ": EOF exception found" )
3557 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003558 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003559 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003560 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003561 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003562
kelvin8ec71442015-01-15 16:57:00 -08003563 def getDeviceLinksActiveCount( self, dpid ):
3564 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003565 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003566 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003567 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003568 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003569 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003570 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003571 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003572 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003573 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003574 main.log.error( self.name + ": Error in getting ports " )
kelvin-onlab898a6c62015-01-16 14:13:53 -08003575 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003576 return output
Jon Hallc6793552016-01-19 14:18:37 -08003577 except AssertionError:
3578 main.log.exception( "" )
3579 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003580 except TypeError:
3581 main.log.exception( self.name + ": Object not as expected" )
3582 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003583 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003584 main.log.error( self.name + ": EOF exception found" )
3585 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003586 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003587 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003588 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003589 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003590
kelvin8ec71442015-01-15 16:57:00 -08003591 def getAllIntentIds( self ):
3592 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003593 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003594 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003595 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003596 cmdStr = "onos:intents | grep id="
3597 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003598 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003599 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003600 if re.search( "Error", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003601 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003602 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003603 return output
Jon Hallc6793552016-01-19 14:18:37 -08003604 except AssertionError:
3605 main.log.exception( "" )
3606 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003607 except TypeError:
3608 main.log.exception( self.name + ": Object not as expected" )
3609 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003610 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003611 main.log.error( self.name + ": EOF exception found" )
3612 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003613 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003614 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003615 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003616 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003617
Jon Hall73509952015-02-24 16:42:56 -08003618 def intentSummary( self ):
3619 """
Jon Hallefbd9792015-03-05 16:11:36 -08003620 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003621 """
3622 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003623 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003624 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003625 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003626 states.append( intent.get( 'state', None ) )
3627 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003628 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003629 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003630 except ( TypeError, ValueError ):
3631 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003632 return None
3633 except pexpect.EOF:
3634 main.log.error( self.name + ": EOF exception found" )
3635 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003636 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003637 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003638 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003639 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003640
Jon Hall61282e32015-03-19 11:34:11 -07003641 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003642 """
3643 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003644 Optional argument:
3645 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003646 """
Jon Hall63604932015-02-26 17:09:50 -08003647 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003648 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003649 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003650 cmdStr += " -j"
3651 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003652 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003653 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003654 return output
Jon Hallc6793552016-01-19 14:18:37 -08003655 except AssertionError:
3656 main.log.exception( "" )
3657 return None
Jon Hall63604932015-02-26 17:09:50 -08003658 except TypeError:
3659 main.log.exception( self.name + ": Object not as expected" )
3660 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003661 except pexpect.EOF:
3662 main.log.error( self.name + ": EOF exception found" )
3663 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003664 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003665 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003666 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003667 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003668
acsmarsa4a4d1e2015-07-10 16:01:24 -07003669 def leaderCandidates( self, jsonFormat=True ):
3670 """
3671 Returns the output of the leaders -c command.
3672 Optional argument:
3673 * jsonFormat - boolean indicating if you want output in json
3674 """
3675 try:
3676 cmdStr = "onos:leaders -c"
3677 if jsonFormat:
3678 cmdStr += " -j"
3679 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003680 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003681 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003682 return output
Jon Hallc6793552016-01-19 14:18:37 -08003683 except AssertionError:
3684 main.log.exception( "" )
3685 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003686 except TypeError:
3687 main.log.exception( self.name + ": Object not as expected" )
3688 return None
3689 except pexpect.EOF:
3690 main.log.error( self.name + ": EOF exception found" )
3691 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003692 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003693 except Exception:
3694 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003695 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003696
Jon Hallc6793552016-01-19 14:18:37 -08003697 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003698 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003699 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003700 topic parameter and an empty list if the topic doesn't exist
3701 If no leader is elected leader in the returned list will be "none"
3702 Returns None if there is a type error processing the json object
3703 """
3704 try:
Jon Hall6e709752016-02-01 13:38:46 -08003705 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003706 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003707 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003708 assert "Command not found:" not in rawOutput, rawOutput
3709 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003710 results = []
3711 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003712 if dict[ "topic" ] == topic:
3713 leader = dict[ "leader" ]
3714 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003715 results.append( leader )
3716 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003717 return results
Jon Hallc6793552016-01-19 14:18:37 -08003718 except AssertionError:
3719 main.log.exception( "" )
3720 return None
3721 except ( TypeError, ValueError ):
3722 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003723 return None
3724 except pexpect.EOF:
3725 main.log.error( self.name + ": EOF exception found" )
3726 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003727 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003728 except Exception:
3729 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003730 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003731
Jon Hall61282e32015-03-19 11:34:11 -07003732 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003733 """
3734 Returns the output of the intent Pending map.
3735 """
Jon Hall63604932015-02-26 17:09:50 -08003736 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003737 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003738 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003739 cmdStr += " -j"
3740 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003741 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003742 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003743 return output
Jon Hallc6793552016-01-19 14:18:37 -08003744 except AssertionError:
3745 main.log.exception( "" )
3746 return None
Jon Hall63604932015-02-26 17:09:50 -08003747 except TypeError:
3748 main.log.exception( self.name + ": Object not as expected" )
3749 return None
3750 except pexpect.EOF:
3751 main.log.error( self.name + ": EOF exception found" )
3752 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003753 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003754 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003755 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003756 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003757
Jon Hall2c8959e2016-12-16 12:17:34 -08003758 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003759 """
3760 Returns the output of the raft partitions command for ONOS.
3761 """
Jon Hall61282e32015-03-19 11:34:11 -07003762 # Sample JSON
3763 # {
3764 # "leader": "tcp://10.128.30.11:7238",
3765 # "members": [
3766 # "tcp://10.128.30.11:7238",
3767 # "tcp://10.128.30.17:7238",
3768 # "tcp://10.128.30.13:7238",
3769 # ],
3770 # "name": "p1",
3771 # "term": 3
3772 # },
Jon Hall63604932015-02-26 17:09:50 -08003773 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003774 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003775 if candidates:
3776 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003777 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003778 cmdStr += " -j"
3779 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003780 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003781 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003782 return output
Jon Hallc6793552016-01-19 14:18:37 -08003783 except AssertionError:
3784 main.log.exception( "" )
3785 return None
Jon Hall63604932015-02-26 17:09:50 -08003786 except TypeError:
3787 main.log.exception( self.name + ": Object not as expected" )
3788 return None
3789 except pexpect.EOF:
3790 main.log.error( self.name + ": EOF exception found" )
3791 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003792 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003793 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003794 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003795 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003796
Jon Halle9f909e2016-09-23 10:43:12 -07003797 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003798 """
3799 Returns the output of the apps command for ONOS. This command lists
3800 information about installed ONOS applications
3801 """
3802 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003803 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003804 # "description":"ONOS OpenFlow protocol southbound providers",
3805 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003806 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003807 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003808 cmdStr = "onos:apps"
Jon Hallf03ae762019-01-22 13:25:27 -08003809 expectJson = False
Jon Halle9f909e2016-09-23 10:43:12 -07003810 if summary:
3811 cmdStr += " -s"
3812 if active:
3813 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003814 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003815 cmdStr += " -j"
Jon Hallf03ae762019-01-22 13:25:27 -08003816 expectJson = True
3817 output = self.sendline( cmdStr, expectJson=expectJson )
Jon Halla495f562016-05-16 18:03:26 -07003818 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003819 assert "Command not found:" not in output, output
3820 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003821 return output
Jon Hallbe379602015-03-24 13:39:32 -07003822 # FIXME: look at specific exceptions/Errors
3823 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07003824 main.log.exception( self.name + ": Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003825 return None
3826 except TypeError:
3827 main.log.exception( self.name + ": Object not as expected" )
3828 return None
3829 except pexpect.EOF:
3830 main.log.error( self.name + ": EOF exception found" )
3831 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003832 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003833 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003834 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003835 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003836
You Wangcdc51fe2018-08-12 17:14:56 -07003837 def appStatus( self, appName ):
Jon Hall146f1522015-03-24 15:33:24 -07003838 """
3839 Uses the onos:apps cli command to return the status of an application.
3840 Returns:
3841 "ACTIVE" - If app is installed and activated
3842 "INSTALLED" - If app is installed and deactivated
3843 "UNINSTALLED" - If app is not installed
3844 None - on error
3845 """
Jon Hall146f1522015-03-24 15:33:24 -07003846 try:
3847 if not isinstance( appName, types.StringType ):
3848 main.log.error( self.name + ".appStatus(): appName must be" +
3849 " a string" )
3850 return None
3851 output = self.apps( jsonFormat=True )
3852 appsJson = json.loads( output )
3853 state = None
3854 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003855 if appName == app.get( 'name' ):
3856 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003857 break
3858 if state == "ACTIVE" or state == "INSTALLED":
3859 return state
3860 elif state is None:
You Wang0d9f2c02018-08-10 14:56:32 -07003861 main.log.warn( "{} app not found".format( appName ) )
Jon Hall146f1522015-03-24 15:33:24 -07003862 return "UNINSTALLED"
3863 elif state:
3864 main.log.error( "Unexpected state from 'onos:apps': " +
3865 str( state ) )
3866 return state
Jon Hallc6793552016-01-19 14:18:37 -08003867 except ( TypeError, ValueError ):
3868 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003869 return None
3870 except pexpect.EOF:
3871 main.log.error( self.name + ": EOF exception found" )
3872 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003873 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003874 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003875 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003876 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003877
Jon Hallbe379602015-03-24 13:39:32 -07003878 def app( self, appName, option ):
3879 """
3880 Interacts with the app command for ONOS. This command manages
3881 application inventory.
3882 """
Jon Hallbe379602015-03-24 13:39:32 -07003883 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003884 # Validate argument types
3885 valid = True
3886 if not isinstance( appName, types.StringType ):
3887 main.log.error( self.name + ".app(): appName must be a " +
3888 "string" )
3889 valid = False
3890 if not isinstance( option, types.StringType ):
3891 main.log.error( self.name + ".app(): option must be a string" )
3892 valid = False
3893 if not valid:
3894 return main.FALSE
3895 # Validate Option
3896 option = option.lower()
3897 # NOTE: Install may become a valid option
3898 if option == "activate":
3899 pass
3900 elif option == "deactivate":
3901 pass
3902 elif option == "uninstall":
3903 pass
3904 else:
3905 # Invalid option
3906 main.log.error( "The ONOS app command argument only takes " +
3907 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003908 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003909 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003910 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003911 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003912 assert output is not None, "Error in sendline"
3913 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003914 if "Error executing command" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003915 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hallbe379602015-03-24 13:39:32 -07003916 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003917 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003918 elif "No such application" in output:
3919 main.log.error( "The application '" + appName +
3920 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003921 return main.FALSE
3922 elif "Command not found:" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003923 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hall146f1522015-03-24 15:33:24 -07003924 str( output ) )
3925 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003926 elif "Unsupported command:" in output:
3927 main.log.error( "Incorrect command given to 'app': " +
3928 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003929 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003930 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003931 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003932 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003933 except AssertionError:
3934 main.log.exception( self.name + ": AssertionError exception found" )
3935 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003936 except TypeError:
3937 main.log.exception( self.name + ": Object not as expected" )
3938 return main.ERROR
3939 except pexpect.EOF:
3940 main.log.error( self.name + ": EOF exception found" )
3941 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003942 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003943 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003944 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003945 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003946
Jon Hallbd16b922015-03-26 17:53:15 -07003947 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003948 """
3949 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003950 appName is the hierarchical app name, not the feature name
3951 If check is True, method will check the status of the app after the
3952 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003953 Returns main.TRUE if the command was successfully sent
3954 main.FALSE if the cli responded with an error or given
3955 incorrect input
3956 """
3957 try:
3958 if not isinstance( appName, types.StringType ):
3959 main.log.error( self.name + ".activateApp(): appName must be" +
3960 " a string" )
3961 return main.FALSE
3962 status = self.appStatus( appName )
3963 if status == "INSTALLED":
3964 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003965 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003966 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003967 status = self.appStatus( appName )
3968 if status == "ACTIVE":
3969 return main.TRUE
3970 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003971 main.log.debug( "The state of application " +
3972 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003973 time.sleep( 1 )
3974 return main.FALSE
3975 else: # not 'check' or command didn't succeed
3976 return response
Jon Hall146f1522015-03-24 15:33:24 -07003977 elif status == "ACTIVE":
3978 return main.TRUE
3979 elif status == "UNINSTALLED":
3980 main.log.error( self.name + ": Tried to activate the " +
3981 "application '" + appName + "' which is not " +
3982 "installed." )
3983 else:
3984 main.log.error( "Unexpected return value from appStatus: " +
3985 str( status ) )
3986 return main.ERROR
3987 except TypeError:
3988 main.log.exception( self.name + ": Object not as expected" )
3989 return main.ERROR
3990 except pexpect.EOF:
3991 main.log.error( self.name + ": EOF exception found" )
3992 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003993 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003994 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003995 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003996 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003997
Jon Hallbd16b922015-03-26 17:53:15 -07003998 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003999 """
4000 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07004001 appName is the hierarchical app name, not the feature name
4002 If check is True, method will check the status of the app after the
4003 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07004004 Returns main.TRUE if the command was successfully sent
4005 main.FALSE if the cli responded with an error or given
4006 incorrect input
4007 """
4008 try:
4009 if not isinstance( appName, types.StringType ):
4010 main.log.error( self.name + ".deactivateApp(): appName must " +
4011 "be a string" )
4012 return main.FALSE
4013 status = self.appStatus( appName )
4014 if status == "INSTALLED":
4015 return main.TRUE
4016 elif status == "ACTIVE":
4017 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07004018 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004019 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004020 status = self.appStatus( appName )
4021 if status == "INSTALLED":
4022 return main.TRUE
4023 else:
4024 time.sleep( 1 )
4025 return main.FALSE
4026 else: # not check or command didn't succeed
4027 return response
Jon Hall146f1522015-03-24 15:33:24 -07004028 elif status == "UNINSTALLED":
4029 main.log.warn( self.name + ": Tried to deactivate the " +
4030 "application '" + appName + "' which is not " +
4031 "installed." )
4032 return main.TRUE
4033 else:
4034 main.log.error( "Unexpected return value from appStatus: " +
4035 str( status ) )
4036 return main.ERROR
4037 except TypeError:
4038 main.log.exception( self.name + ": Object not as expected" )
4039 return main.ERROR
4040 except pexpect.EOF:
4041 main.log.error( self.name + ": EOF exception found" )
4042 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004043 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004044 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004045 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004046 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07004047
Jon Hallbd16b922015-03-26 17:53:15 -07004048 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07004049 """
4050 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07004051 appName is the hierarchical app name, not the feature name
4052 If check is True, method will check the status of the app after the
4053 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07004054 Returns main.TRUE if the command was successfully sent
4055 main.FALSE if the cli responded with an error or given
4056 incorrect input
4057 """
4058 # TODO: check with Thomas about the state machine for apps
4059 try:
4060 if not isinstance( appName, types.StringType ):
4061 main.log.error( self.name + ".uninstallApp(): appName must " +
4062 "be a string" )
4063 return main.FALSE
4064 status = self.appStatus( appName )
4065 if status == "INSTALLED":
4066 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004067 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004068 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004069 status = self.appStatus( appName )
4070 if status == "UNINSTALLED":
4071 return main.TRUE
4072 else:
4073 time.sleep( 1 )
4074 return main.FALSE
4075 else: # not check or command didn't succeed
4076 return response
Jon Hall146f1522015-03-24 15:33:24 -07004077 elif status == "ACTIVE":
4078 main.log.warn( self.name + ": Tried to uninstall the " +
4079 "application '" + appName + "' which is " +
4080 "currently active." )
4081 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004082 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004083 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004084 status = self.appStatus( appName )
4085 if status == "UNINSTALLED":
4086 return main.TRUE
4087 else:
4088 time.sleep( 1 )
4089 return main.FALSE
4090 else: # not check or command didn't succeed
4091 return response
Jon Hall146f1522015-03-24 15:33:24 -07004092 elif status == "UNINSTALLED":
4093 return main.TRUE
4094 else:
4095 main.log.error( "Unexpected return value from appStatus: " +
4096 str( status ) )
4097 return main.ERROR
4098 except TypeError:
4099 main.log.exception( self.name + ": Object not as expected" )
4100 return main.ERROR
4101 except pexpect.EOF:
4102 main.log.error( self.name + ": EOF exception found" )
4103 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004104 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004105 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004106 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004107 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004108
4109 def appIDs( self, jsonFormat=True ):
4110 """
4111 Show the mappings between app id and app names given by the 'app-ids'
4112 cli command
4113 """
4114 try:
4115 cmdStr = "app-ids"
4116 if jsonFormat:
4117 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07004118 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004119 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004120 assert "Command not found:" not in output, output
4121 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07004122 return output
Jon Hallbd16b922015-03-26 17:53:15 -07004123 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004124 main.log.exception( self.name + ": Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07004125 return None
4126 except TypeError:
4127 main.log.exception( self.name + ": Object not as expected" )
4128 return None
4129 except pexpect.EOF:
4130 main.log.error( self.name + ": EOF exception found" )
4131 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004132 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004133 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004134 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004135 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004136
4137 def appToIDCheck( self ):
4138 """
4139 This method will check that each application's ID listed in 'apps' is
4140 the same as the ID listed in 'app-ids'. The check will also check that
4141 there are no duplicate IDs issued. Note that an app ID should be
4142 a globaly unique numerical identifier for app/app-like features. Once
4143 an ID is registered, the ID is never freed up so that if an app is
4144 reinstalled it will have the same ID.
4145
4146 Returns: main.TRUE if the check passes and
4147 main.FALSE if the check fails or
4148 main.ERROR if there is some error in processing the test
4149 """
4150 try:
Jon Hall0e240372018-05-02 11:21:57 -07004151 # Grab IDs
Jon Hallc6793552016-01-19 14:18:37 -08004152 rawJson = self.appIDs( jsonFormat=True )
4153 if rawJson:
4154 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004155 else:
Jon Hall0e240372018-05-02 11:21:57 -07004156 main.log.error( "app-ids returned nothing: " + repr( rawJson ) )
4157 return main.FALSE
4158
4159 # Grab Apps
Jon Hallc6793552016-01-19 14:18:37 -08004160 rawJson = self.apps( jsonFormat=True )
4161 if rawJson:
4162 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004163 else:
Jon Hallc6793552016-01-19 14:18:37 -08004164 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004165 return main.FALSE
Jon Hall0e240372018-05-02 11:21:57 -07004166
Jon Hallbd16b922015-03-26 17:53:15 -07004167 result = main.TRUE
4168 for app in apps:
4169 appID = app.get( 'id' )
4170 if appID is None:
4171 main.log.error( "Error parsing app: " + str( app ) )
4172 result = main.FALSE
4173 appName = app.get( 'name' )
4174 if appName is None:
4175 main.log.error( "Error parsing app: " + str( app ) )
4176 result = main.FALSE
4177 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004178 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004179 if not current: # if ids doesn't have this id
4180 result = main.FALSE
4181 main.log.error( "'app-ids' does not have the ID for " +
4182 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004183 main.log.debug( "apps command returned: " + str( app ) +
4184 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004185 elif len( current ) > 1:
4186 # there is more than one app with this ID
4187 result = main.FALSE
4188 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004189 elif not current[ 0 ][ 'name' ] == appName:
4190 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004191 result = main.FALSE
4192 main.log.error( "'app-ids' has " + str( currentName ) +
4193 " registered under id:" + str( appID ) +
4194 " but 'apps' has " + str( appName ) )
4195 else:
4196 pass # id and name match!
Jon Hall0e240372018-05-02 11:21:57 -07004197
Jon Hallbd16b922015-03-26 17:53:15 -07004198 # now make sure that app-ids has no duplicates
4199 idsList = []
4200 namesList = []
4201 for item in ids:
4202 idsList.append( item[ 'id' ] )
4203 namesList.append( item[ 'name' ] )
4204 if len( idsList ) != len( set( idsList ) ) or\
4205 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004206 main.log.error( "'app-ids' has some duplicate entries: \n"
4207 + json.dumps( ids,
4208 sort_keys=True,
4209 indent=4,
4210 separators=( ',', ': ' ) ) )
4211 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004212 return result
Jon Hallc6793552016-01-19 14:18:37 -08004213 except ( TypeError, ValueError ):
4214 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004215 return main.ERROR
4216 except pexpect.EOF:
4217 main.log.error( self.name + ": EOF exception found" )
4218 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004219 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004220 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004221 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004222 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004223
Jon Hallfb760a02015-04-13 15:35:03 -07004224 def getCfg( self, component=None, propName=None, short=False,
4225 jsonFormat=True ):
4226 """
4227 Get configuration settings from onos cli
4228 Optional arguments:
4229 component - Optionally only list configurations for a specific
4230 component. If None, all components with configurations
4231 are displayed. Case Sensitive string.
4232 propName - If component is specified, propName option will show
4233 only this specific configuration from that component.
4234 Case Sensitive string.
4235 jsonFormat - Returns output as json. Note that this will override
4236 the short option
4237 short - Short, less verbose, version of configurations.
4238 This is overridden by the json option
4239 returns:
4240 Output from cli as a string or None on error
4241 """
4242 try:
4243 baseStr = "cfg"
4244 cmdStr = " get"
4245 componentStr = ""
4246 if component:
4247 componentStr += " " + component
4248 if propName:
4249 componentStr += " " + propName
4250 if jsonFormat:
4251 baseStr += " -j"
Jon Hall22e94ce2019-01-15 14:52:17 -08004252 expectJson = True
Jon Hallfb760a02015-04-13 15:35:03 -07004253 elif short:
4254 baseStr += " -s"
Jon Hall22e94ce2019-01-15 14:52:17 -08004255 expectJson = False
4256 output = self.sendline( baseStr + cmdStr + componentStr, expectJson=expectJson )
Jon Halla495f562016-05-16 18:03:26 -07004257 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004258 assert "Command not found:" not in output, output
4259 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004260 return output
4261 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004262 main.log.exception( self.name + ": Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004263 return None
4264 except TypeError:
4265 main.log.exception( self.name + ": Object not as expected" )
4266 return None
4267 except pexpect.EOF:
4268 main.log.error( self.name + ": EOF exception found" )
4269 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004270 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004271 except Exception:
4272 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004273 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004274
4275 def setCfg( self, component, propName, value=None, check=True ):
4276 """
4277 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004278 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004279 component - The case sensitive name of the component whose
4280 property is to be set
4281 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004282 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004283 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004284 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004285 check - Boolean, Check whether the option was successfully set this
4286 only applies when a value is given.
4287 returns:
4288 main.TRUE on success or main.FALSE on failure. If check is False,
4289 will return main.TRUE unless there is an error
4290 """
4291 try:
4292 baseStr = "cfg"
4293 cmdStr = " set " + str( component ) + " " + str( propName )
4294 if value is not None:
4295 cmdStr += " " + str( value )
4296 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004297 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004298 assert "Command not found:" not in output, output
4299 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004300 if value and check:
4301 results = self.getCfg( component=str( component ),
4302 propName=str( propName ),
4303 jsonFormat=True )
4304 # Check if current value is what we just set
4305 try:
4306 jsonOutput = json.loads( results )
4307 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004308 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004309 main.log.exception( "Error parsing cfg output" )
4310 main.log.error( "output:" + repr( results ) )
4311 return main.FALSE
4312 if current == str( value ):
4313 return main.TRUE
4314 return main.FALSE
4315 return main.TRUE
4316 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004317 main.log.exception( self.name + ": Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004318 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004319 except ( TypeError, ValueError ):
4320 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004321 return main.FALSE
4322 except pexpect.EOF:
4323 main.log.error( self.name + ": EOF exception found" )
4324 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004325 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004326 except Exception:
4327 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004328 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004329
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004330 def distPrimitivesSend( self, cmd ):
4331 """
4332 Function to handle sending cli commands for the distributed primitives test app
4333
4334 This command will catch some exceptions and retry the command on some
4335 specific store exceptions.
4336
4337 Required arguments:
4338 cmd - The command to send to the cli
4339 returns:
4340 string containing the cli output
4341 None on Error
4342 """
4343 try:
4344 output = self.sendline( cmd )
4345 try:
4346 assert output is not None, "Error in sendline"
4347 # TODO: Maybe make this less hardcoded
4348 # ConsistentMap Exceptions
4349 assert "org.onosproject.store.service" not in output
4350 # Node not leader
4351 assert "java.lang.IllegalStateException" not in output
4352 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004353 main.log.error( self.name + ": Error in processing '" + cmd + "' " +
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004354 "command: " + str( output ) )
4355 retryTime = 30 # Conservative time, given by Madan
4356 main.log.info( "Waiting " + str( retryTime ) +
4357 "seconds before retrying." )
4358 time.sleep( retryTime ) # Due to change in mastership
4359 output = self.sendline( cmd )
4360 assert output is not None, "Error in sendline"
4361 assert "Command not found:" not in output, output
4362 assert "Error executing command" not in output, output
4363 main.log.info( self.name + ": " + output )
4364 return output
4365 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004366 main.log.exception( self.name + ": Error in processing '" + cmd + "' command." )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004367 return None
4368 except TypeError:
4369 main.log.exception( self.name + ": Object not as expected" )
4370 return None
4371 except pexpect.EOF:
4372 main.log.error( self.name + ": EOF exception found" )
4373 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004374 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004375 except Exception:
4376 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004377 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004378
Jon Hall390696c2015-05-05 17:13:41 -07004379 def setTestAdd( self, setName, values ):
4380 """
4381 CLI command to add elements to a distributed set.
4382 Arguments:
4383 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004384 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004385 Example usages:
4386 setTestAdd( "set1", "a b c" )
4387 setTestAdd( "set2", "1" )
4388 returns:
4389 main.TRUE on success OR
4390 main.FALSE if elements were already in the set OR
4391 main.ERROR on error
4392 """
4393 try:
4394 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004395 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004396 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4397 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004398 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004399 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004400 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004401 return main.FALSE
4402 else:
4403 main.log.error( self.name + ": setTestAdd did not" +
4404 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004405 main.log.debug( self.name + " actual: " + repr( output ) )
4406 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004407 except TypeError:
4408 main.log.exception( self.name + ": Object not as expected" )
4409 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004410 except Exception:
4411 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004412 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004413
4414 def setTestRemove( self, setName, values, clear=False, retain=False ):
4415 """
4416 CLI command to remove elements from a distributed set.
4417 Required arguments:
4418 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004419 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004420 Optional arguments:
4421 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004422 retain - Retain only the given values. (intersection of the
4423 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004424 returns:
4425 main.TRUE on success OR
4426 main.FALSE if the set was not changed OR
4427 main.ERROR on error
4428 """
4429 try:
4430 cmdStr = "set-test-remove "
4431 if clear:
4432 cmdStr += "-c " + str( setName )
4433 elif retain:
4434 cmdStr += "-r " + str( setName ) + " " + str( values )
4435 else:
4436 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004437 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004438 if clear:
4439 pattern = "Set " + str( setName ) + " cleared"
4440 if re.search( pattern, output ):
4441 return main.TRUE
4442 elif retain:
4443 positivePattern = str( setName ) + " was pruned to contain " +\
4444 "only elements of set \[(.*)\]"
4445 negativePattern = str( setName ) + " was not changed by " +\
4446 "retaining only elements of the set " +\
4447 "\[(.*)\]"
4448 if re.search( positivePattern, output ):
4449 return main.TRUE
4450 elif re.search( negativePattern, output ):
4451 return main.FALSE
4452 else:
4453 positivePattern = "\[(.*)\] was removed from the set " +\
4454 str( setName )
4455 if ( len( values.split() ) == 1 ):
4456 negativePattern = "\[(.*)\] was not in set " +\
4457 str( setName )
4458 else:
4459 negativePattern = "No element of \[(.*)\] was in set " +\
4460 str( setName )
4461 if re.search( positivePattern, output ):
4462 return main.TRUE
4463 elif re.search( negativePattern, output ):
4464 return main.FALSE
4465 main.log.error( self.name + ": setTestRemove did not" +
4466 " match expected output" )
4467 main.log.debug( self.name + " expected: " + pattern )
4468 main.log.debug( self.name + " actual: " + repr( output ) )
4469 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004470 except TypeError:
4471 main.log.exception( self.name + ": Object not as expected" )
4472 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004473 except Exception:
4474 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004475 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004476
4477 def setTestGet( self, setName, values="" ):
4478 """
4479 CLI command to get the elements in a distributed set.
4480 Required arguments:
4481 setName - The name of the set to remove from.
4482 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004483 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004484 returns:
4485 main.ERROR on error OR
4486 A list of elements in the set if no optional arguments are
4487 supplied OR
4488 A tuple containing the list then:
4489 main.FALSE if the given values are not in the set OR
4490 main.TRUE if the given values are in the set OR
4491 """
4492 try:
4493 values = str( values ).strip()
4494 setName = str( setName ).strip()
4495 length = len( values.split() )
4496 containsCheck = None
4497 # Patterns to match
4498 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004499 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004500 containsTrue = "Set " + setName + " contains the value " + values
4501 containsFalse = "Set " + setName + " did not contain the value " +\
4502 values
4503 containsAllTrue = "Set " + setName + " contains the the subset " +\
4504 setPattern
4505 containsAllFalse = "Set " + setName + " did not contain the the" +\
4506 " subset " + setPattern
4507
4508 cmdStr = "set-test-get "
4509 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004510 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004511 if length == 0:
4512 match = re.search( pattern, output )
4513 else: # if given values
4514 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004515 patternTrue = pattern + "\r\n" + containsTrue
4516 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004517 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004518 patternTrue = pattern + "\r\n" + containsAllTrue
4519 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004520 matchTrue = re.search( patternTrue, output )
4521 matchFalse = re.search( patternFalse, output )
4522 if matchTrue:
4523 containsCheck = main.TRUE
4524 match = matchTrue
4525 elif matchFalse:
4526 containsCheck = main.FALSE
4527 match = matchFalse
4528 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004529 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004530 "expected output" )
4531 main.log.debug( self.name + " expected: " + pattern )
4532 main.log.debug( self.name + " actual: " + repr( output ) )
4533 match = None
4534 if match:
4535 setMatch = match.group( 1 )
4536 if setMatch == '':
4537 setList = []
4538 else:
4539 setList = setMatch.split( ", " )
4540 if length > 0:
4541 return ( setList, containsCheck )
4542 else:
4543 return setList
4544 else: # no match
4545 main.log.error( self.name + ": setTestGet did not" +
4546 " match expected output" )
4547 main.log.debug( self.name + " expected: " + pattern )
4548 main.log.debug( self.name + " actual: " + repr( output ) )
4549 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004550 except TypeError:
4551 main.log.exception( self.name + ": Object not as expected" )
4552 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004553 except Exception:
4554 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004555 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004556
4557 def setTestSize( self, setName ):
4558 """
4559 CLI command to get the elements in a distributed set.
4560 Required arguments:
4561 setName - The name of the set to remove from.
4562 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004563 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004564 None on error
4565 """
4566 try:
4567 # TODO: Should this check against the number of elements returned
4568 # and then return true/false based on that?
4569 setName = str( setName ).strip()
4570 # Patterns to match
4571 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004572 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004573 setPattern
4574 cmdStr = "set-test-get -s "
4575 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004576 output = self.distPrimitivesSend( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -07004577 if output:
4578 match = re.search( pattern, output )
4579 if match:
4580 setSize = int( match.group( 1 ) )
4581 setMatch = match.group( 2 )
4582 if len( setMatch.split() ) == setSize:
4583 main.log.info( "The size returned by " + self.name +
4584 " matches the number of elements in " +
4585 "the returned set" )
4586 else:
4587 main.log.error( "The size returned by " + self.name +
4588 " does not match the number of " +
4589 "elements in the returned set." )
4590 return setSize
Jon Hall390696c2015-05-05 17:13:41 -07004591 else: # no match
4592 main.log.error( self.name + ": setTestGet did not" +
4593 " match expected output" )
4594 main.log.debug( self.name + " expected: " + pattern )
4595 main.log.debug( self.name + " actual: " + repr( output ) )
4596 return None
Jon Hall390696c2015-05-05 17:13:41 -07004597 except TypeError:
4598 main.log.exception( self.name + ": Object not as expected" )
4599 return None
Jon Hall390696c2015-05-05 17:13:41 -07004600 except Exception:
4601 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004602 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004603
Jon Hall80daded2015-05-27 16:07:00 -07004604 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004605 """
4606 Command to list the various counters in the system.
4607 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004608 if jsonFormat, a string of the json object returned by the cli
4609 command
4610 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004611 None on error
4612 """
Jon Hall390696c2015-05-05 17:13:41 -07004613 try:
Jon Hall390696c2015-05-05 17:13:41 -07004614 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004615 if jsonFormat:
4616 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004617 output = self.sendline( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08004618 main.log.debug( self.name + ": Counters unparsed: " + output )
4619 output = output.split( "\r\n" )[ -1 ]
4620 main.log.debug( self.name + ": Counters parsed: " + output )
Jon Halla495f562016-05-16 18:03:26 -07004621 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004622 assert "Command not found:" not in output, output
4623 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004624 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004625 return output
Jon Hall390696c2015-05-05 17:13:41 -07004626 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004627 main.log.exception( self.name + ": Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004628 return None
Jon Hall390696c2015-05-05 17:13:41 -07004629 except TypeError:
4630 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004631 return None
Jon Hall390696c2015-05-05 17:13:41 -07004632 except pexpect.EOF:
4633 main.log.error( self.name + ": EOF exception found" )
4634 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004635 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004636 except Exception:
4637 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004638 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004639
Jon Hall935db192016-04-19 00:22:04 -07004640 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004641 """
Jon Halle1a3b752015-07-22 13:02:46 -07004642 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004643 Required arguments:
4644 counter - The name of the counter to increment.
4645 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004646 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004647 returns:
4648 integer value of the counter or
4649 None on Error
4650 """
4651 try:
4652 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004653 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004654 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004655 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004656 if delta != 1:
4657 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004658 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004659 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004660 match = re.search( pattern, output )
4661 if match:
4662 return int( match.group( 1 ) )
4663 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004664 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004665 " match expected output." )
4666 main.log.debug( self.name + " expected: " + pattern )
4667 main.log.debug( self.name + " actual: " + repr( output ) )
4668 return None
Jon Hall390696c2015-05-05 17:13:41 -07004669 except TypeError:
4670 main.log.exception( self.name + ": Object not as expected" )
4671 return None
Jon Hall390696c2015-05-05 17:13:41 -07004672 except Exception:
4673 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004674 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004675
Jon Hall935db192016-04-19 00:22:04 -07004676 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004677 """
4678 CLI command to get a distributed counter then add a delta to it.
4679 Required arguments:
4680 counter - The name of the counter to increment.
4681 Optional arguments:
4682 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004683 returns:
4684 integer value of the counter or
4685 None on Error
4686 """
4687 try:
4688 counter = str( counter )
4689 delta = int( delta )
4690 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004691 cmdStr += counter
4692 if delta != 1:
4693 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004694 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004695 pattern = counter + " was updated to (-?\d+)"
4696 match = re.search( pattern, output )
4697 if match:
4698 return int( match.group( 1 ) )
4699 else:
4700 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4701 " match expected output." )
4702 main.log.debug( self.name + " expected: " + pattern )
4703 main.log.debug( self.name + " actual: " + repr( output ) )
4704 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004705 except TypeError:
4706 main.log.exception( self.name + ": Object not as expected" )
4707 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004708 except Exception:
4709 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004710 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004711
4712 def valueTestGet( self, valueName ):
4713 """
4714 CLI command to get the value of an atomic value.
4715 Required arguments:
4716 valueName - The name of the value to get.
4717 returns:
4718 string value of the value or
4719 None on Error
4720 """
4721 try:
4722 valueName = str( valueName )
4723 cmdStr = "value-test "
4724 operation = "get"
4725 cmdStr = "value-test {} {}".format( valueName,
4726 operation )
4727 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08004728 main.log.debug( self.name + ": value test unparsed: " + output )
4729 output = output.split( "\r\n" )[ -1 ]
4730 main.log.debug( self.name + ": value test parsed: " + output )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004731 pattern = "(\w+)"
4732 match = re.search( pattern, output )
4733 if match:
4734 return match.group( 1 )
4735 else:
4736 main.log.error( self.name + ": valueTestGet did not" +
4737 " match expected output." )
4738 main.log.debug( self.name + " expected: " + pattern )
4739 main.log.debug( self.name + " actual: " + repr( output ) )
4740 return None
4741 except TypeError:
4742 main.log.exception( self.name + ": Object not as expected" )
4743 return None
4744 except Exception:
4745 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004746 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004747
4748 def valueTestSet( self, valueName, newValue ):
4749 """
4750 CLI command to set the value of an atomic value.
4751 Required arguments:
4752 valueName - The name of the value to set.
4753 newValue - The value to assign to the given value.
4754 returns:
4755 main.TRUE on success or
4756 main.ERROR on Error
4757 """
4758 try:
4759 valueName = str( valueName )
4760 newValue = str( newValue )
4761 operation = "set"
4762 cmdStr = "value-test {} {} {}".format( valueName,
4763 operation,
4764 newValue )
4765 output = self.distPrimitivesSend( cmdStr )
4766 if output is not None:
4767 return main.TRUE
4768 else:
4769 return main.ERROR
4770 except TypeError:
4771 main.log.exception( self.name + ": Object not as expected" )
4772 return main.ERROR
4773 except Exception:
4774 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004775 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004776
4777 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4778 """
4779 CLI command to compareAndSet the value of an atomic value.
4780 Required arguments:
4781 valueName - The name of the value.
4782 oldValue - Compare the current value of the atomic value to this
4783 newValue - If the value equals oldValue, set the value to newValue
4784 returns:
4785 main.TRUE on success or
4786 main.FALSE on failure or
4787 main.ERROR on Error
4788 """
4789 try:
4790 valueName = str( valueName )
4791 oldValue = str( oldValue )
4792 newValue = str( newValue )
4793 operation = "compareAndSet"
4794 cmdStr = "value-test {} {} {} {}".format( valueName,
4795 operation,
4796 oldValue,
4797 newValue )
4798 output = self.distPrimitivesSend( cmdStr )
4799 pattern = "(\w+)"
4800 match = re.search( pattern, output )
4801 if match:
4802 result = match.group( 1 )
4803 if result == "true":
4804 return main.TRUE
4805 elif result == "false":
4806 return main.FALSE
4807 else:
4808 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4809 " match expected output." )
4810 main.log.debug( self.name + " expected: " + pattern )
4811 main.log.debug( self.name + " actual: " + repr( output ) )
4812 return main.ERROR
4813 except TypeError:
4814 main.log.exception( self.name + ": Object not as expected" )
4815 return main.ERROR
4816 except Exception:
4817 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004818 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004819
4820 def valueTestGetAndSet( self, valueName, newValue ):
4821 """
4822 CLI command to getAndSet the value of an atomic value.
4823 Required arguments:
4824 valueName - The name of the value to get.
4825 newValue - The value to assign to the given value
4826 returns:
4827 string value of the value or
4828 None on Error
4829 """
4830 try:
4831 valueName = str( valueName )
4832 cmdStr = "value-test "
4833 operation = "getAndSet"
4834 cmdStr += valueName + " " + operation
4835 cmdStr = "value-test {} {} {}".format( valueName,
4836 operation,
4837 newValue )
4838 output = self.distPrimitivesSend( cmdStr )
4839 pattern = "(\w+)"
4840 match = re.search( pattern, output )
4841 if match:
4842 return match.group( 1 )
4843 else:
4844 main.log.error( self.name + ": valueTestGetAndSet did not" +
4845 " match expected output." )
4846 main.log.debug( self.name + " expected: " + pattern )
4847 main.log.debug( self.name + " actual: " + repr( output ) )
4848 return None
4849 except TypeError:
4850 main.log.exception( self.name + ": Object not as expected" )
4851 return None
4852 except Exception:
4853 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004854 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004855
4856 def valueTestDestroy( self, valueName ):
4857 """
4858 CLI command to destroy an atomic value.
4859 Required arguments:
4860 valueName - The name of the value to destroy.
4861 returns:
4862 main.TRUE on success or
4863 main.ERROR on Error
4864 """
4865 try:
4866 valueName = str( valueName )
4867 cmdStr = "value-test "
4868 operation = "destroy"
4869 cmdStr += valueName + " " + operation
4870 output = self.distPrimitivesSend( cmdStr )
4871 if output is not None:
4872 return main.TRUE
4873 else:
4874 return main.ERROR
4875 except TypeError:
4876 main.log.exception( self.name + ": Object not as expected" )
4877 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004878 except Exception:
4879 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004880 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004881
YPZhangfebf7302016-05-24 16:45:56 -07004882 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004883 """
4884 Description: Execute summary command in onos
4885 Returns: json object ( summary -j ), returns main.FALSE if there is
4886 no output
4887
4888 """
4889 try:
4890 cmdStr = "summary"
4891 if jsonFormat:
4892 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004893 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004894 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004895 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004896 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004897 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004898 if not handle:
4899 main.log.error( self.name + ": There is no output in " +
4900 "summary command" )
4901 return main.FALSE
4902 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004903 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004904 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004905 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004906 except TypeError:
4907 main.log.exception( self.name + ": Object not as expected" )
4908 return None
4909 except pexpect.EOF:
4910 main.log.error( self.name + ": EOF exception found" )
4911 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004912 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004913 except Exception:
4914 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004915 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004916
Jon Hall935db192016-04-19 00:22:04 -07004917 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004918 """
4919 CLI command to get the value of a key in a consistent map using
4920 transactions. This a test function and can only get keys from the
4921 test map hard coded into the cli command
4922 Required arguments:
4923 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004924 returns:
4925 The string value of the key or
4926 None on Error
4927 """
4928 try:
4929 keyName = str( keyName )
4930 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004931 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004932 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004933 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4934 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004935 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004936 return None
4937 else:
4938 match = re.search( pattern, output )
4939 if match:
4940 return match.groupdict()[ 'value' ]
4941 else:
4942 main.log.error( self.name + ": transactionlMapGet did not" +
4943 " match expected output." )
4944 main.log.debug( self.name + " expected: " + pattern )
4945 main.log.debug( self.name + " actual: " + repr( output ) )
4946 return None
4947 except TypeError:
4948 main.log.exception( self.name + ": Object not as expected" )
4949 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004950 except Exception:
4951 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004952 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004953
Jon Hall935db192016-04-19 00:22:04 -07004954 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004955 """
4956 CLI command to put a value into 'numKeys' number of keys in a
4957 consistent map using transactions. This a test function and can only
4958 put into keys named 'Key#' of the test map hard coded into the cli command
4959 Required arguments:
4960 numKeys - Number of keys to add the value to
4961 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004962 returns:
4963 A dictionary whose keys are the name of the keys put into the map
4964 and the values of the keys are dictionaries whose key-values are
4965 'value': value put into map and optionaly
4966 'oldValue': Previous value in the key or
4967 None on Error
4968
4969 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004970 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4971 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004972 """
4973 try:
4974 numKeys = str( numKeys )
4975 value = str( value )
4976 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004977 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004978 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004979 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4980 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4981 results = {}
4982 for line in output.splitlines():
4983 new = re.search( newPattern, line )
4984 updated = re.search( updatedPattern, line )
4985 if new:
4986 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4987 elif updated:
4988 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004989 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004990 else:
4991 main.log.error( self.name + ": transactionlMapGet did not" +
4992 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004993 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4994 newPattern,
4995 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004996 main.log.debug( self.name + " actual: " + repr( output ) )
4997 return results
Jon Hall0e240372018-05-02 11:21:57 -07004998 except ( TypeError, AttributeError ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004999 main.log.exception( self.name + ": Object not as expected" )
5000 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07005001 except Exception:
5002 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005003 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08005004
acsmarsdaea66c2015-09-03 11:44:06 -07005005 def maps( self, jsonFormat=True ):
5006 """
5007 Description: Returns result of onos:maps
5008 Optional:
5009 * jsonFormat: enable json formatting of output
5010 """
5011 try:
5012 cmdStr = "maps"
5013 if jsonFormat:
5014 cmdStr += " -j"
5015 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07005016 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005017 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07005018 return handle
Jon Hallc6793552016-01-19 14:18:37 -08005019 except AssertionError:
5020 main.log.exception( "" )
5021 return None
acsmarsdaea66c2015-09-03 11:44:06 -07005022 except TypeError:
5023 main.log.exception( self.name + ": Object not as expected" )
5024 return None
5025 except pexpect.EOF:
5026 main.log.error( self.name + ": EOF exception found" )
5027 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005028 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07005029 except Exception:
5030 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005031 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005032
5033 def getSwController( self, uri, jsonFormat=True ):
5034 """
5035 Descrition: Gets the controller information from the device
5036 """
5037 try:
5038 cmd = "device-controllers "
5039 if jsonFormat:
5040 cmd += "-j "
5041 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07005042 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005043 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005044 return response
Jon Hallc6793552016-01-19 14:18:37 -08005045 except AssertionError:
5046 main.log.exception( "" )
5047 return None
GlennRC050596c2015-11-18 17:06:41 -08005048 except TypeError:
5049 main.log.exception( self.name + ": Object not as expected" )
5050 return None
5051 except pexpect.EOF:
5052 main.log.error( self.name + ": EOF exception found" )
5053 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005054 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005055 except Exception:
5056 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005057 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005058
5059 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
5060 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005061 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08005062
5063 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005064 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08005065 ip - String or List: The ip address of the controller.
5066 This parameter can be formed in a couple of different ways.
5067 VALID:
5068 10.0.0.1 - just the ip address
5069 tcp:10.0.0.1 - the protocol and the ip address
5070 tcp:10.0.0.1:6653 - the protocol and port can be specified,
5071 so that you can add controllers with different
5072 protocols and ports
5073 INVALID:
5074 10.0.0.1:6653 - this is not supported by ONOS
5075
5076 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
5077 port - The port number.
5078 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
5079
5080 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
5081 """
5082 try:
5083 cmd = "device-setcontrollers"
5084
5085 if jsonFormat:
5086 cmd += " -j"
5087 cmd += " " + uri
5088 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005089 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08005090 for item in ip:
5091 if ":" in item:
5092 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005093 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08005094 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005095 elif "." in sitem[ 1 ]:
5096 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08005097 else:
5098 main.log.error( "Malformed entry: " + item )
5099 raise TypeError
5100 else:
5101 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08005102 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07005103 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005104 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005105 if "Error" in response:
5106 main.log.error( response )
5107 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005108 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005109 except AssertionError:
5110 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005111 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005112 except TypeError:
5113 main.log.exception( self.name + ": Object not as expected" )
5114 return main.FALSE
5115 except pexpect.EOF:
5116 main.log.error( self.name + ": EOF exception found" )
5117 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005118 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005119 except Exception:
5120 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005121 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005122
5123 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005124 '''
GlennRC20fc6522015-12-23 23:26:57 -08005125 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005126 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08005127 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005128 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08005129 Returns:
5130 Returns main.FALSE if an exception is thrown or an error is present
5131 in the response. Otherwise, returns main.TRUE.
5132 NOTE:
5133 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005134 '''
GlennRC20fc6522015-12-23 23:26:57 -08005135 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005136 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07005137 deviceStr = device
5138 device = []
5139 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08005140
5141 for d in device:
5142 time.sleep( 1 )
5143 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07005144 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005145 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005146 if "Error" in response:
5147 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
5148 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005149 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005150 except AssertionError:
5151 main.log.exception( "" )
5152 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005153 except TypeError:
5154 main.log.exception( self.name + ": Object not as expected" )
5155 return main.FALSE
5156 except pexpect.EOF:
5157 main.log.error( self.name + ": EOF exception found" )
5158 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005159 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005160 except Exception:
5161 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005162 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005163
5164 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005165 '''
GlennRC20fc6522015-12-23 23:26:57 -08005166 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005167 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005168 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005169 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005170 Returns:
5171 Returns main.FALSE if an exception is thrown or an error is present
5172 in the response. Otherwise, returns main.TRUE.
5173 NOTE:
5174 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005175 '''
GlennRC20fc6522015-12-23 23:26:57 -08005176 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005177 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005178 host = list( host )
5179
5180 for h in host:
5181 time.sleep( 1 )
5182 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005183 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005184 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005185 if "Error" in response:
5186 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5187 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005188 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005189 except AssertionError:
5190 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005191 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005192 except TypeError:
5193 main.log.exception( self.name + ": Object not as expected" )
5194 return main.FALSE
5195 except pexpect.EOF:
5196 main.log.error( self.name + ": EOF exception found" )
5197 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005198 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005199 except Exception:
5200 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005201 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005202
YPZhangfebf7302016-05-24 16:45:56 -07005203 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005204 '''
GlennRCed771242016-01-13 17:02:47 -08005205 Description:
5206 Bring link down or up in the null-provider.
5207 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005208 begin - (string) One end of a device or switch.
5209 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005210 returns:
5211 main.TRUE if no exceptions were thrown and no Errors are
5212 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005213 '''
GlennRCed771242016-01-13 17:02:47 -08005214 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005215 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005216 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005217 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005218 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005219 if "Error" in response or "Failure" in response:
5220 main.log.error( response )
5221 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005222 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005223 except AssertionError:
5224 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005225 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005226 except TypeError:
5227 main.log.exception( self.name + ": Object not as expected" )
5228 return main.FALSE
5229 except pexpect.EOF:
5230 main.log.error( self.name + ": EOF exception found" )
5231 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005232 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005233 except Exception:
5234 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005235 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005236
Jon Hall2c8959e2016-12-16 12:17:34 -08005237 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005238 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005239 Description:
5240 Changes the state of port in an OF switch by means of the
5241 PORTSTATUS OF messages.
5242 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005243 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5244 port - (string) target port in the device. Ex: '2'
5245 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005246 returns:
5247 main.TRUE if no exceptions were thrown and no Errors are
5248 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005249 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005250 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005251 state = state.lower()
5252 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005253 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005254 response = self.sendline( cmd, showResponse=True )
5255 assert response is not None, "Error in sendline"
5256 assert "Command not found:" not in response, response
5257 if "Error" in response or "Failure" in response:
5258 main.log.error( response )
5259 return main.FALSE
5260 return main.TRUE
5261 except AssertionError:
5262 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005263 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005264 except TypeError:
5265 main.log.exception( self.name + ": Object not as expected" )
5266 return main.FALSE
5267 except pexpect.EOF:
5268 main.log.error( self.name + ": EOF exception found" )
5269 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005270 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005271 except Exception:
5272 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005273 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005274
5275 def logSet( self, level="INFO", app="org.onosproject" ):
5276 """
5277 Set the logging level to lvl for a specific app
5278 returns main.TRUE on success
5279 returns main.FALSE if Error occurred
5280 if noExit is True, TestON will not exit, but clean up
5281 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5282 Level defaults to INFO
5283 """
5284 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005285 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -08005286 self.handle.expect( self.karafPrompt )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005287
5288 response = self.handle.before
5289 if re.search( "Error", response ):
5290 return main.FALSE
5291 return main.TRUE
5292 except pexpect.TIMEOUT:
5293 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005294 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005295 except pexpect.EOF:
5296 main.log.error( self.name + ": EOF exception found" )
5297 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005298 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005299 except Exception:
5300 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005301 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005302
5303 def getGraphDict( self, timeout=60, includeHost=False ):
5304 """
5305 Return a dictionary which describes the latest network topology data as a
5306 graph.
5307 An example of the dictionary:
5308 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5309 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5310 Each vertex should at least have an 'edges' attribute which describes the
5311 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005312 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005313 list of attributes.
5314 An example of the edges dictionary:
5315 'edges': { vertex2: { 'port': ..., 'weight': ... },
5316 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005317 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005318 in topology data.
5319 """
5320 graphDict = {}
5321 try:
5322 links = self.links()
5323 links = json.loads( links )
5324 devices = self.devices()
5325 devices = json.loads( devices )
5326 idToDevice = {}
5327 for device in devices:
5328 idToDevice[ device[ 'id' ] ] = device
5329 if includeHost:
5330 hosts = self.hosts()
5331 # FIXME: support 'includeHost' argument
5332 for link in links:
5333 nodeA = link[ 'src' ][ 'device' ]
5334 nodeB = link[ 'dst' ][ 'device' ]
5335 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005336 if nodeA not in graphDict.keys():
5337 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005338 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005339 'type': idToDevice[ nodeA ][ 'type' ],
5340 'available': idToDevice[ nodeA ][ 'available' ],
5341 'role': idToDevice[ nodeA ][ 'role' ],
5342 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5343 'hw': idToDevice[ nodeA ][ 'hw' ],
5344 'sw': idToDevice[ nodeA ][ 'sw' ],
5345 'serial': idToDevice[ nodeA ][ 'serial' ],
5346 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005347 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005348 else:
5349 # Assert nodeB is not connected to any current links of nodeA
You Wang7d14d642019-01-23 15:10:08 -08005350 # assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
5351 pass
Jon Halle0f0b342017-04-18 11:43:47 -07005352 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5353 'type': link[ 'type' ],
5354 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005355 return graphDict
5356 except ( TypeError, ValueError ):
5357 main.log.exception( self.name + ": Object not as expected" )
5358 return None
5359 except KeyError:
5360 main.log.exception( self.name + ": KeyError exception found" )
5361 return None
5362 except AssertionError:
5363 main.log.exception( self.name + ": AssertionError exception found" )
5364 return None
5365 except pexpect.EOF:
5366 main.log.error( self.name + ": EOF exception found" )
5367 main.log.error( self.name + ": " + self.handle.before )
5368 return None
5369 except Exception:
5370 main.log.exception( self.name + ": Uncaught exception!" )
5371 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005372
5373 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005374 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005375 Send command to check intent-perf summary
5376 Returns: dictionary for intent-perf summary
5377 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005378 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005379 cmd = "intent-perf -s"
5380 respDic = {}
5381 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005382 assert resp is not None, "Error in sendline"
5383 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005384 try:
5385 # Generate the dictionary to return
5386 for l in resp.split( "\n" ):
5387 # Delete any white space in line
5388 temp = re.sub( r'\s+', '', l )
5389 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005390 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005391
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005392 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005393 main.log.exception( self.name + ": Object not as expected" )
5394 return None
5395 except KeyError:
5396 main.log.exception( self.name + ": KeyError exception found" )
5397 return None
5398 except AssertionError:
5399 main.log.exception( self.name + ": AssertionError exception found" )
5400 return None
5401 except pexpect.EOF:
5402 main.log.error( self.name + ": EOF exception found" )
5403 main.log.error( self.name + ": " + self.handle.before )
5404 return None
5405 except Exception:
5406 main.log.exception( self.name + ": Uncaught exception!" )
5407 return None
5408 return respDic
5409
Chiyu Chengec63bde2016-11-17 18:11:36 -08005410 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005411 """
5412 Searches the latest ONOS log file for the given search term and
5413 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005414
chengchiyu08303a02016-09-08 17:40:26 -07005415 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005416 searchTerm:
5417 The string to grep from the ONOS log.
5418 startLine:
5419 The term that decides which line is the start to search the searchTerm in
5420 the karaf log. For now, startTerm only works in 'first' mode.
5421 logNum:
5422 In some extreme cases, one karaf log is not big enough to contain all the
5423 information.Because of this, search mutiply logs is necessary to capture
5424 the right result. logNum is the number of karaf logs that we need to search
5425 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005426 mode:
5427 all: return all the strings that contain the search term
5428 last: return the last string that contains the search term
5429 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005430 num: return the number of times that the searchTerm appears in the log
5431 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005432 """
5433 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005434 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005435 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005436 logPath = '/opt/onos/log/karaf.log.'
5437 logPaths = '/opt/onos/log/karaf.log'
5438 for i in range( 1, logNum ):
5439 logPaths = logPath + str( i ) + " " + logPaths
5440 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005441 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005442 # 100000000 is just a extreme large number to make sure this function can
5443 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005444 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005445 if mode == 'all':
5446 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005447 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005448 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005449 elif mode == 'first':
5450 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5451 elif mode == 'num':
You Wangd91a70f2019-01-03 15:28:10 -08005452 cmd = cmd + " | grep \'" + searchTerm + "\' | wc -l"
5453 num = self.lineCount( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005454 return num
You Wang6d301d42017-04-21 10:49:33 -07005455 elif mode == 'total':
Jon Halld5a94fb2018-11-13 14:32:23 -08005456 totalLines = self.lineCount( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005457 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005458 else:
5459 main.log.error( self.name + " unsupported mode" )
5460 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005461 before = self.sendline( cmd )
5462 before = before.splitlines()
5463 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005464 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005465 return returnLines
5466 except AssertionError:
5467 main.log.error( self.name + " searchTerm is not string type" )
5468 return None
5469 except pexpect.EOF:
5470 main.log.error( self.name + ": EOF exception found" )
5471 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005472 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005473 except pexpect.TIMEOUT:
5474 main.log.error( self.name + ": TIMEOUT exception found" )
5475 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005476 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005477 except Exception:
5478 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005479 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005480
5481 def vplsShow( self, jsonFormat=True ):
5482 """
5483 Description: Returns result of onos:vpls show, which should list the
5484 configured VPLS networks and the assigned interfaces.
5485 Optional:
5486 * jsonFormat: enable json formatting of output
5487 Returns:
5488 The output of the command or None on error.
5489 """
5490 try:
5491 cmdStr = "vpls show"
5492 if jsonFormat:
5493 raise NotImplementedError
5494 cmdStr += " -j"
5495 handle = self.sendline( cmdStr )
5496 assert handle is not None, "Error in sendline"
5497 assert "Command not found:" not in handle, handle
5498 return handle
5499 except AssertionError:
5500 main.log.exception( "" )
5501 return None
5502 except TypeError:
5503 main.log.exception( self.name + ": Object not as expected" )
5504 return None
5505 except pexpect.EOF:
5506 main.log.error( self.name + ": EOF exception found" )
5507 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005508 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005509 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005510 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005511 return None
5512 except Exception:
5513 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005514 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005515
5516 def parseVplsShow( self ):
5517 """
5518 Parse the cli output of 'vpls show' into json output. This is required
5519 as there is currently no json output available.
5520 """
5521 try:
5522 output = []
5523 raw = self.vplsShow( jsonFormat=False )
5524 namePat = "VPLS name: (?P<name>\w+)"
5525 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5526 encapPat = "Encapsulation: (?P<encap>\w+)"
5527 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5528 mIter = re.finditer( pattern, raw )
5529 for match in mIter:
5530 item = {}
5531 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005532 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005533 if ifaces == [ "" ]:
5534 ifaces = []
5535 item[ 'interfaces' ] = ifaces
5536 encap = match.group( 'encap' )
5537 if encap != 'NONE':
5538 item[ 'encapsulation' ] = encap.lower()
5539 output.append( item )
5540 return output
5541 except Exception:
5542 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005543 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005544
5545 def vplsList( self, jsonFormat=True ):
5546 """
5547 Description: Returns result of onos:vpls list, which should list the
5548 configured VPLS networks.
5549 Optional:
5550 * jsonFormat: enable json formatting of output
5551 """
5552 try:
5553 cmdStr = "vpls list"
5554 if jsonFormat:
5555 raise NotImplementedError
5556 cmdStr += " -j"
5557 handle = self.sendline( cmdStr )
5558 assert handle is not None, "Error in sendline"
5559 assert "Command not found:" not in handle, handle
5560 return handle
5561 except AssertionError:
5562 main.log.exception( "" )
5563 return None
5564 except TypeError:
5565 main.log.exception( self.name + ": Object not as expected" )
5566 return None
5567 except pexpect.EOF:
5568 main.log.error( self.name + ": EOF exception found" )
5569 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005570 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005571 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005572 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005573 return None
5574 except Exception:
5575 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005576 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005577
5578 def vplsCreate( self, network ):
5579 """
5580 CLI command to create a new VPLS network.
5581 Required arguments:
5582 network - String name of the network to create.
5583 returns:
5584 main.TRUE on success and main.FALSE on failure
5585 """
5586 try:
5587 network = str( network )
5588 cmdStr = "vpls create "
5589 cmdStr += network
5590 output = self.sendline( cmdStr )
5591 assert output is not None, "Error in sendline"
5592 assert "Command not found:" not in output, output
5593 assert "Error executing command" not in output, output
5594 assert "VPLS already exists:" not in output, output
5595 return main.TRUE
5596 except AssertionError:
5597 main.log.exception( "" )
5598 return main.FALSE
5599 except TypeError:
5600 main.log.exception( self.name + ": Object not as expected" )
5601 return main.FALSE
5602 except pexpect.EOF:
5603 main.log.error( self.name + ": EOF exception found" )
5604 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005605 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005606 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 vplsDelete( self, network ):
5611 """
5612 CLI command to delete a VPLS network.
5613 Required arguments:
5614 network - Name of the network to delete.
5615 returns:
5616 main.TRUE on success and main.FALSE on failure
5617 """
5618 try:
5619 network = str( network )
5620 cmdStr = "vpls delete "
5621 cmdStr += network
5622 output = self.sendline( cmdStr )
5623 assert output is not None, "Error in sendline"
5624 assert "Command not found:" not in output, output
5625 assert "Error executing command" not in output, output
5626 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005627 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005628 return main.TRUE
5629 except AssertionError:
5630 main.log.exception( "" )
5631 return main.FALSE
5632 except TypeError:
5633 main.log.exception( self.name + ": Object not as expected" )
5634 return main.FALSE
5635 except pexpect.EOF:
5636 main.log.error( self.name + ": EOF exception found" )
5637 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005638 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005639 except Exception:
5640 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005641 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005642
5643 def vplsAddIface( self, network, iface ):
5644 """
5645 CLI command to add an interface to a VPLS network.
5646 Required arguments:
5647 network - Name of the network to add the interface to.
5648 iface - The ONOS name for an interface.
5649 returns:
5650 main.TRUE on success and main.FALSE on failure
5651 """
5652 try:
5653 network = str( network )
5654 iface = str( iface )
5655 cmdStr = "vpls add-if "
5656 cmdStr += network + " " + iface
5657 output = self.sendline( cmdStr )
5658 assert output is not None, "Error in sendline"
5659 assert "Command not found:" not in output, output
5660 assert "Error executing command" not in output, output
5661 assert "already associated to network" not in output, output
5662 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005663 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005664 return main.TRUE
5665 except AssertionError:
5666 main.log.exception( "" )
5667 return main.FALSE
5668 except TypeError:
5669 main.log.exception( self.name + ": Object not as expected" )
5670 return main.FALSE
5671 except pexpect.EOF:
5672 main.log.error( self.name + ": EOF exception found" )
5673 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005674 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005675 except Exception:
5676 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005677 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005678
5679 def vplsRemIface( self, network, iface ):
5680 """
5681 CLI command to remove an interface from a VPLS network.
5682 Required arguments:
5683 network - Name of the network to remove the interface from.
5684 iface - Name of the interface to remove.
5685 returns:
5686 main.TRUE on success and main.FALSE on failure
5687 """
5688 try:
5689 iface = str( iface )
5690 cmdStr = "vpls rem-if "
5691 cmdStr += network + " " + iface
5692 output = self.sendline( cmdStr )
5693 assert output is not None, "Error in sendline"
5694 assert "Command not found:" not in output, output
5695 assert "Error executing command" not in output, output
5696 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005697 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005698 return main.TRUE
5699 except AssertionError:
5700 main.log.exception( "" )
5701 return main.FALSE
5702 except TypeError:
5703 main.log.exception( self.name + ": Object not as expected" )
5704 return main.FALSE
5705 except pexpect.EOF:
5706 main.log.error( self.name + ": EOF exception found" )
5707 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005708 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005709 except Exception:
5710 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005711 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005712
5713 def vplsClean( self ):
5714 """
5715 Description: Clears the VPLS app configuration.
5716 Returns: main.TRUE on success and main.FALSE on failure
5717 """
5718 try:
5719 cmdStr = "vpls clean"
5720 handle = self.sendline( cmdStr )
5721 assert handle is not None, "Error in sendline"
5722 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005723 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005724 return handle
5725 except AssertionError:
5726 main.log.exception( "" )
5727 return main.FALSE
5728 except TypeError:
5729 main.log.exception( self.name + ": Object not as expected" )
5730 return main.FALSE
5731 except pexpect.EOF:
5732 main.log.error( self.name + ": EOF exception found" )
5733 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005734 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005735 except Exception:
5736 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005737 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005738
5739 def vplsSetEncap( self, network, encapType ):
5740 """
5741 CLI command to add an interface to a VPLS network.
5742 Required arguments:
5743 network - Name of the network to create.
5744 encapType - Type of encapsulation.
5745 returns:
5746 main.TRUE on success and main.FALSE on failure
5747 """
5748 try:
5749 network = str( network )
5750 encapType = str( encapType ).upper()
5751 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5752 cmdStr = "vpls set-encap "
5753 cmdStr += network + " " + encapType
5754 output = self.sendline( cmdStr )
5755 assert output is not None, "Error in sendline"
5756 assert "Command not found:" not in output, output
5757 assert "Error executing command" not in output, output
5758 assert "already associated to network" not in output, output
5759 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005760 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005761 return main.TRUE
5762 except AssertionError:
5763 main.log.exception( "" )
5764 return main.FALSE
5765 except TypeError:
5766 main.log.exception( self.name + ": Object not as expected" )
5767 return main.FALSE
5768 except pexpect.EOF:
5769 main.log.error( self.name + ": EOF exception found" )
5770 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005771 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005772 except Exception:
5773 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005774 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005775
5776 def interfaces( self, jsonFormat=True ):
5777 """
5778 Description: Returns result of interfaces command.
5779 Optional:
5780 * jsonFormat: enable json formatting of output
5781 Returns:
5782 The output of the command or None on error.
5783 """
5784 try:
5785 cmdStr = "interfaces"
5786 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005787 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005788 cmdStr += " -j"
5789 handle = self.sendline( cmdStr )
5790 assert handle is not None, "Error in sendline"
5791 assert "Command not found:" not in handle, handle
5792 return handle
5793 except AssertionError:
5794 main.log.exception( "" )
5795 return None
5796 except TypeError:
5797 main.log.exception( self.name + ": Object not as expected" )
5798 return None
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 NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005804 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005805 return None
5806 except Exception:
5807 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005808 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005809
5810 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005811 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005812 Get the timestamp of searchTerm from karaf log.
5813
5814 Arguments:
5815 splitTerm_before and splitTerm_after:
5816
5817 The terms that split the string that contains the timeStamp of
5818 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5819 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5820 and the splitTerm_after is "x"
5821
5822 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005823 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005824 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005825 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005826 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005827 return main.ERROR
5828 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005829 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005830 main.log.warn( "Captured timestamp string is empty" )
5831 return main.ERROR
5832 lines = lines[ 0 ]
5833 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005834 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005835 # get the target value
5836 line = lines.split( splitTerm_before )
5837 key = line[ 1 ].split( splitTerm_after )
5838 return int( key[ 0 ] )
5839 except IndexError:
5840 main.log.warn( "Index Error!" )
5841 return main.ERROR
5842 except AssertionError:
5843 main.log.warn( "Search Term Not Found " )
5844 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005845
5846 def workQueueAdd( self, queueName, value ):
5847 """
5848 CLI command to add a string to the specified Work Queue.
5849 This function uses the distributed primitives test app, which
5850 gives some cli access to distributed primitives for testing
5851 purposes only.
5852
5853 Required arguments:
5854 queueName - The name of the queue to add to
5855 value - The value to add to the queue
5856 returns:
5857 main.TRUE on success, main.FALSE on failure and
5858 main.ERROR on error.
5859 """
5860 try:
5861 queueName = str( queueName )
5862 value = str( value )
5863 prefix = "work-queue-test"
5864 operation = "add"
5865 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5866 output = self.distPrimitivesSend( cmdStr )
5867 if "Invalid operation name" in output:
5868 main.log.warn( output )
5869 return main.ERROR
5870 elif "Done" in output:
5871 return main.TRUE
5872 except TypeError:
5873 main.log.exception( self.name + ": Object not as expected" )
5874 return main.ERROR
5875 except Exception:
5876 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005877 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005878
5879 def workQueueAddMultiple( self, queueName, value1, value2 ):
5880 """
5881 CLI command to add two strings to the specified Work Queue.
5882 This function uses the distributed primitives test app, which
5883 gives some cli access to distributed primitives for testing
5884 purposes only.
5885
5886 Required arguments:
5887 queueName - The name of the queue to add to
5888 value1 - The first value to add to the queue
5889 value2 - The second value to add to the queue
5890 returns:
5891 main.TRUE on success, main.FALSE on failure and
5892 main.ERROR on error.
5893 """
5894 try:
5895 queueName = str( queueName )
5896 value1 = str( value1 )
5897 value2 = str( value2 )
5898 prefix = "work-queue-test"
5899 operation = "addMultiple"
5900 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5901 output = self.distPrimitivesSend( cmdStr )
5902 if "Invalid operation name" in output:
5903 main.log.warn( output )
5904 return main.ERROR
5905 elif "Done" in output:
5906 return main.TRUE
5907 except TypeError:
5908 main.log.exception( self.name + ": Object not as expected" )
5909 return main.ERROR
5910 except Exception:
5911 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005912 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005913
5914 def workQueueTakeAndComplete( self, queueName, number=1 ):
5915 """
5916 CLI command to take a value from the specified Work Queue and compelte it.
5917 This function uses the distributed primitives test app, which
5918 gives some cli access to distributed primitives for testing
5919 purposes only.
5920
5921 Required arguments:
5922 queueName - The name of the queue to add to
5923 number - The number of items to take and complete
5924 returns:
5925 main.TRUE on success, main.FALSE on failure and
5926 main.ERROR on error.
5927 """
5928 try:
5929 queueName = str( queueName )
5930 number = str( int( number ) )
5931 prefix = "work-queue-test"
5932 operation = "takeAndComplete"
5933 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5934 output = self.distPrimitivesSend( cmdStr )
5935 if "Invalid operation name" in output:
5936 main.log.warn( output )
5937 return main.ERROR
5938 elif "Done" in output:
5939 return main.TRUE
5940 except TypeError:
5941 main.log.exception( self.name + ": Object not as expected" )
5942 return main.ERROR
5943 except Exception:
5944 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005945 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005946
5947 def workQueueDestroy( self, queueName ):
5948 """
5949 CLI command to destroy the specified Work Queue.
5950 This function uses the distributed primitives test app, which
5951 gives some cli access to distributed primitives for testing
5952 purposes only.
5953
5954 Required arguments:
5955 queueName - The name of the queue to add to
5956 returns:
5957 main.TRUE on success, main.FALSE on failure and
5958 main.ERROR on error.
5959 """
5960 try:
5961 queueName = str( queueName )
5962 prefix = "work-queue-test"
5963 operation = "destroy"
5964 cmdStr = " ".join( [ prefix, queueName, operation ] )
5965 output = self.distPrimitivesSend( cmdStr )
5966 if "Invalid operation name" in output:
5967 main.log.warn( output )
5968 return main.ERROR
5969 return main.TRUE
5970 except TypeError:
5971 main.log.exception( self.name + ": Object not as expected" )
5972 return main.ERROR
5973 except Exception:
5974 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005975 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005976
5977 def workQueueTotalPending( self, queueName ):
5978 """
5979 CLI command to get the Total Pending items of the specified Work Queue.
5980 This function uses the distributed primitives test app, which
5981 gives some cli access to distributed primitives for testing
5982 purposes only.
5983
5984 Required arguments:
5985 queueName - The name of the queue to add to
5986 returns:
5987 The number of Pending items in the specified work queue or
5988 None on error
5989 """
5990 try:
5991 queueName = str( queueName )
5992 prefix = "work-queue-test"
5993 operation = "totalPending"
5994 cmdStr = " ".join( [ prefix, queueName, operation ] )
5995 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08005996 main.log.debug( self.name + ": work queue unparsed: " + output )
5997 output = output.split( "\r\n" )[ -1 ]
5998 main.log.debug( self.name + ": work queue parsed: " + output )
Jon Halle0f0b342017-04-18 11:43:47 -07005999 pattern = r'\d+'
6000 if "Invalid operation name" in output:
6001 main.log.warn( output )
6002 return None
6003 else:
6004 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006005 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006006 except ( AttributeError, TypeError ):
6007 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6008 return None
6009 except Exception:
6010 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006011 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006012
6013 def workQueueTotalCompleted( self, queueName ):
6014 """
6015 CLI command to get the Total Completed items of the specified Work Queue.
6016 This function uses the distributed primitives test app, which
6017 gives some cli access to distributed primitives for testing
6018 purposes only.
6019
6020 Required arguments:
6021 queueName - The name of the queue to add to
6022 returns:
6023 The number of complete items in the specified work queue or
6024 None on error
6025 """
6026 try:
6027 queueName = str( queueName )
6028 prefix = "work-queue-test"
6029 operation = "totalCompleted"
6030 cmdStr = " ".join( [ prefix, queueName, operation ] )
6031 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08006032 main.log.debug( self.name + ": work queue unparsed: " + output )
6033 output = output.split( "\r\n" )[ -1 ]
6034 main.log.debug( self.name + ": work queue parsed: " + output )
Jon Halle0f0b342017-04-18 11:43:47 -07006035 pattern = r'\d+'
6036 if "Invalid operation name" in output:
6037 main.log.warn( output )
6038 return None
6039 else:
6040 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006041 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006042 except ( AttributeError, TypeError ):
6043 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6044 return None
6045 except Exception:
6046 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006047 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006048
6049 def workQueueTotalInProgress( self, queueName ):
6050 """
6051 CLI command to get the Total In Progress items of the specified Work Queue.
6052 This function uses the distributed primitives test app, which
6053 gives some cli access to distributed primitives for testing
6054 purposes only.
6055
6056 Required arguments:
6057 queueName - The name of the queue to add to
6058 returns:
6059 The number of In Progress items in the specified work queue or
6060 None on error
6061 """
6062 try:
6063 queueName = str( queueName )
6064 prefix = "work-queue-test"
6065 operation = "totalInProgress"
6066 cmdStr = " ".join( [ prefix, queueName, operation ] )
6067 output = self.distPrimitivesSend( cmdStr )
Jon Hall22e94ce2019-01-15 14:52:17 -08006068 main.log.debug( self.name + ": work queue unparsed: " + output )
6069 output = output.split( "\r\n" )[ -1 ]
6070 main.log.debug( self.name + ": work queue parsed: " + output )
Jon Halle0f0b342017-04-18 11:43:47 -07006071 pattern = r'\d+'
6072 if "Invalid operation name" in output:
6073 main.log.warn( output )
6074 return None
6075 else:
6076 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006077 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006078 except ( AttributeError, TypeError ):
6079 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6080 return None
6081 except Exception:
6082 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006083 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00006084
6085 def events( self, args='-a' ):
6086 """
6087 Description: Returns events -a command output
6088 Optional:
6089 add other arguments
6090 """
6091 try:
6092 cmdStr = "events"
6093 if args:
6094 cmdStr += " " + args
6095 handle = self.sendline( cmdStr )
6096 assert handle is not None, "Error in sendline"
6097 assert "Command not found:" not in handle, handle
6098 return handle
6099 except AssertionError:
6100 main.log.exception( "" )
6101 return None
6102 except TypeError:
6103 main.log.exception( self.name + ": Object not as expected" )
6104 return None
6105 except pexpect.EOF:
6106 main.log.error( self.name + ": EOF exception found" )
6107 main.log.error( self.name + ": " + self.handle.before )
6108 main.cleanAndExit()
6109 except Exception:
6110 main.log.exception( self.name + ": Uncaught exception!" )
6111 main.cleanAndExit()
6112
6113 def getMaster( self, deviceID ):
6114 """
6115 Description: Obtains current master using "roles" command for a specific deviceID
6116 """
6117 try:
6118 return str( self.getRole( deviceID )[ 'master' ] )
6119 except AssertionError:
6120 main.log.exception( "" )
6121 return None
6122 except TypeError:
6123 main.log.exception( self.name + ": Object not as expected" )
6124 return None
6125 except pexpect.EOF:
6126 main.log.error( self.name + ": EOF exception found" )
6127 main.log.error( self.name + ": " + self.handle.before )
6128 main.cleanAndExit()
6129 except Exception:
6130 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07006131 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08006132
6133 def issu( self ):
6134 """
6135 Short summary of In-Service Software Upgrade status
6136
6137 Returns the output of the cli command or None on Error
6138 """
6139 try:
6140 cmdStr = "issu"
6141 handle = self.sendline( cmdStr )
6142 assert handle is not None, "Error in sendline"
6143 assert "Command not found:" not in handle, handle
6144 assert "Unsupported command:" not in handle, handle
6145 return handle
6146 except AssertionError:
6147 main.log.exception( "" )
6148 return None
6149 except TypeError:
6150 main.log.exception( self.name + ": Object not as expected" )
6151 return None
6152 except pexpect.EOF:
6153 main.log.error( self.name + ": EOF exception found" )
6154 main.log.error( self.name + ": " + self.handle.before )
6155 main.cleanAndExit()
6156 except Exception:
6157 main.log.exception( self.name + ": Uncaught exception!" )
6158 main.cleanAndExit()
6159
6160 def issuInit( self ):
6161 """
6162 Initiates an In-Service Software Upgrade
6163
6164 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6165 """
6166 try:
6167 cmdStr = "issu init"
6168 handle = self.sendline( cmdStr )
6169 assert handle is not None, "Error in sendline"
6170 assert "Command not found:" not in handle, handle
6171 assert "Unsupported command:" not in handle, handle
6172 if "Initialized" in handle:
6173 return main.TRUE
6174 else:
6175 return main.FALSE
6176 except AssertionError:
6177 main.log.exception( "" )
6178 return main.ERROR
6179 except TypeError:
6180 main.log.exception( self.name + ": Object not as expected" )
6181 return main.ERROR
6182 except pexpect.EOF:
6183 main.log.error( self.name + ": EOF exception found" )
6184 main.log.error( self.name + ": " + self.handle.before )
6185 main.cleanAndExit()
6186 except Exception:
6187 main.log.exception( self.name + ": Uncaught exception!" )
6188 main.cleanAndExit()
6189
6190 def issuUpgrade( self ):
6191 """
6192 Transitions stores to upgraded nodes
6193
6194 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6195 """
6196 try:
6197 cmdStr = "issu upgrade"
6198 handle = self.sendline( cmdStr )
6199 assert handle is not None, "Error in sendline"
6200 assert "Command not found:" not in handle, handle
6201 assert "Unsupported command:" not in handle, handle
6202 if "Upgraded" in handle:
6203 return main.TRUE
6204 else:
6205 return main.FALSE
6206 except AssertionError:
6207 main.log.exception( "" )
6208 return main.ERROR
6209 except TypeError:
6210 main.log.exception( self.name + ": Object not as expected" )
6211 return main.ERROR
6212 except pexpect.EOF:
6213 main.log.error( self.name + ": EOF exception found" )
6214 main.log.error( self.name + ": " + self.handle.before )
6215 main.cleanAndExit()
6216 except Exception:
6217 main.log.exception( self.name + ": Uncaught exception!" )
6218 main.cleanAndExit()
6219
6220 def issuCommit( self ):
6221 """
6222 Finalizes an In-Service Software Upgrade
6223
6224 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6225 """
6226 try:
6227 cmdStr = "issu commit"
6228 handle = self.sendline( cmdStr )
6229 assert handle is not None, "Error in sendline"
6230 assert "Command not found:" not in handle, handle
6231 assert "Unsupported command:" not in handle, handle
6232 # TODO: Check the version returned by this command
6233 if "Committed version" in handle:
6234 return main.TRUE
6235 else:
6236 return main.FALSE
6237 except AssertionError:
6238 main.log.exception( "" )
6239 return main.ERROR
6240 except TypeError:
6241 main.log.exception( self.name + ": Object not as expected" )
6242 return main.ERROR
6243 except pexpect.EOF:
6244 main.log.error( self.name + ": EOF exception found" )
6245 main.log.error( self.name + ": " + self.handle.before )
6246 main.cleanAndExit()
6247 except Exception:
6248 main.log.exception( self.name + ": Uncaught exception!" )
6249 main.cleanAndExit()
6250
6251 def issuRollback( self ):
6252 """
6253 Rolls back an In-Service Software Upgrade
6254
6255 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6256 """
6257 try:
6258 cmdStr = "issu rollback"
6259 handle = self.sendline( cmdStr )
6260 assert handle is not None, "Error in sendline"
6261 assert "Command not found:" not in handle, handle
6262 assert "Unsupported command:" not in handle, handle
6263 # TODO: Check the version returned by this command
6264 if "Rolled back to version" in handle:
6265 return main.TRUE
6266 else:
6267 return main.FALSE
6268 except AssertionError:
6269 main.log.exception( "" )
6270 return main.ERROR
6271 except TypeError:
6272 main.log.exception( self.name + ": Object not as expected" )
6273 return main.ERROR
6274 except pexpect.EOF:
6275 main.log.error( self.name + ": EOF exception found" )
6276 main.log.error( self.name + ": " + self.handle.before )
6277 main.cleanAndExit()
6278 except Exception:
6279 main.log.exception( self.name + ": Uncaught exception!" )
6280 main.cleanAndExit()
6281
6282 def issuReset( self ):
6283 """
6284 Resets the In-Service Software Upgrade status after a rollback
6285
6286 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6287 """
6288 try:
6289 cmdStr = "issu reset"
6290 handle = self.sendline( cmdStr )
6291 assert handle is not None, "Error in sendline"
6292 assert "Command not found:" not in handle, handle
6293 assert "Unsupported command:" not in handle, handle
6294 # TODO: Check the version returned by this command
6295 if "Reset version" in handle:
6296 return main.TRUE
6297 else:
6298 return main.FALSE
6299 except AssertionError:
6300 main.log.exception( "" )
6301 return main.ERROR
6302 except TypeError:
6303 main.log.exception( self.name + ": Object not as expected" )
6304 return main.ERROR
6305 except pexpect.EOF:
6306 main.log.error( self.name + ": EOF exception found" )
6307 main.log.error( self.name + ": " + self.handle.before )
6308 main.cleanAndExit()
6309 except Exception:
6310 main.log.exception( self.name + ": Uncaught exception!" )
6311 main.cleanAndExit()
6312
6313 def issuStatus( self ):
6314 """
6315 Status of an In-Service Software Upgrade
6316
6317 Returns the output of the cli command or None on Error
6318 """
6319 try:
6320 cmdStr = "issu status"
6321 handle = self.sendline( cmdStr )
6322 assert handle is not None, "Error in sendline"
6323 assert "Command not found:" not in handle, handle
6324 assert "Unsupported command:" not in handle, handle
6325 return handle
6326 except AssertionError:
6327 main.log.exception( "" )
6328 return None
6329 except TypeError:
6330 main.log.exception( self.name + ": Object not as expected" )
6331 return None
6332 except pexpect.EOF:
6333 main.log.error( self.name + ": EOF exception found" )
6334 main.log.error( self.name + ": " + self.handle.before )
6335 main.cleanAndExit()
6336 except Exception:
6337 main.log.exception( self.name + ": Uncaught exception!" )
6338 main.cleanAndExit()
6339
6340 def issuVersion( self ):
6341 """
6342 Get the version of an In-Service Software Upgrade
6343
6344 Returns the output of the cli command or None on Error
6345 """
6346 try:
6347 cmdStr = "issu version"
6348 handle = self.sendline( cmdStr )
6349 assert handle is not None, "Error in sendline"
6350 assert "Command not found:" not in handle, handle
6351 assert "Unsupported command:" not in handle, handle
6352 return handle
6353 except AssertionError:
6354 main.log.exception( "" )
6355 return None
6356 except TypeError:
6357 main.log.exception( self.name + ": Object not as expected" )
6358 return None
6359 except pexpect.EOF:
6360 main.log.error( self.name + ": EOF exception found" )
6361 main.log.error( self.name + ": " + self.handle.before )
6362 main.cleanAndExit()
6363 except Exception:
6364 main.log.exception( self.name + ": Uncaught exception!" )
6365 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006366
6367 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6368 """
6369 Create a multicast route by calling 'mcast-join' command
6370 sIP: source IP of the multicast route
6371 groupIP: group IP of the multicast route
6372 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6373 dPorts: a list of destination ports of the multicast route
6374 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6375 """
6376 try:
6377 cmdStr = "mcast-join"
6378 cmdStr += " " + str( sIP )
6379 cmdStr += " " + str( groupIP )
6380 cmdStr += " " + str( sPort )
6381 assert isinstance( dPorts, list )
6382 for dPort in dPorts:
6383 cmdStr += " " + str( dPort )
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 assert "Error executing command" not in handle, handle
6389 if "Added the mcast route" in handle:
6390 return main.TRUE
6391 else:
6392 return main.FALSE
6393 except AssertionError:
6394 main.log.exception( "" )
6395 return None
6396 except TypeError:
6397 main.log.exception( self.name + ": Object not as expected" )
6398 return None
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 mcastDelete( self, sIP, groupIP, dPorts ):
6408 """
6409 Delete a multicast route by calling 'mcast-delete' command
6410 sIP: source IP of the multicast route
6411 groupIP: group IP of the multicast route
6412 dPorts: a list of destination ports of the multicast route
6413 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6414 """
6415 try:
6416 cmdStr = "mcast-delete"
6417 cmdStr += " " + str( sIP )
6418 cmdStr += " " + str( groupIP )
6419 assert isinstance( dPorts, list )
6420 for dPort in dPorts:
6421 cmdStr += " " + str( dPort )
6422 handle = self.sendline( cmdStr )
6423 assert handle is not None, "Error in sendline"
6424 assert "Command not found:" not in handle, handle
6425 assert "Unsupported command:" not in handle, handle
6426 assert "Error executing command" not in handle, handle
6427 if "Updated the mcast route" in handle:
6428 return main.TRUE
6429 else:
6430 return main.FALSE
6431 except AssertionError:
6432 main.log.exception( "" )
6433 return None
6434 except TypeError:
6435 main.log.exception( self.name + ": Object not as expected" )
6436 return None
6437 except pexpect.EOF:
6438 main.log.error( self.name + ": EOF exception found" )
6439 main.log.error( self.name + ": " + self.handle.before )
6440 main.cleanAndExit()
6441 except Exception:
6442 main.log.exception( self.name + ": Uncaught exception!" )
6443 main.cleanAndExit()
6444
6445 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6446 """
6447 Create a multicast route by calling 'mcast-host-join' command
6448 sAddr: we can provide * for ASM or a specific address for SSM
6449 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006450 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006451 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6452 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6453 """
6454 try:
6455 cmdStr = "mcast-host-join"
6456 cmdStr += " -sAddr " + str( sAddr )
6457 cmdStr += " -gAddr " + str( gAddr )
6458 assert isinstance( srcs, list )
6459 for src in srcs:
6460 cmdStr += " -srcs " + str( src )
6461 assert isinstance( sinks, list )
6462 for sink in sinks:
6463 cmdStr += " -sinks " + str( sink )
6464 handle = self.sendline( cmdStr )
6465 assert handle is not None, "Error in sendline"
6466 assert "Command not found:" not in handle, handle
6467 assert "Unsupported command:" not in handle, handle
6468 assert "Error executing command" not in handle, handle
6469 if "Added the mcast route" in handle:
6470 return main.TRUE
6471 else:
6472 return main.FALSE
6473 except AssertionError:
6474 main.log.exception( "" )
6475 return None
6476 except TypeError:
6477 main.log.exception( self.name + ": Object not as expected" )
6478 return None
6479 except pexpect.EOF:
6480 main.log.error( self.name + ": EOF exception found" )
6481 main.log.error( self.name + ": " + self.handle.before )
6482 main.cleanAndExit()
6483 except Exception:
6484 main.log.exception( self.name + ": Uncaught exception!" )
6485 main.cleanAndExit()
6486
6487 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6488 """
6489 Delete multicast sink(s) by calling 'mcast-host-delete' command
6490 sAddr: we can provide * for ASM or a specific address for SSM
6491 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006492 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006493 will delete the route if not specified
6494 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6495 """
6496 try:
6497 cmdStr = "mcast-host-delete"
6498 cmdStr += " -sAddr " + str( sAddr )
6499 cmdStr += " -gAddr " + str( gAddr )
6500 if host:
6501 cmdStr += " -h " + str( host )
6502 handle = self.sendline( cmdStr )
6503 assert handle is not None, "Error in sendline"
6504 assert "Command not found:" not in handle, handle
6505 assert "Unsupported command:" not in handle, handle
6506 assert "Error executing command" not in handle, handle
6507 if "Updated the mcast route" in handle:
6508 return main.TRUE
6509 elif "Deleted the mcast route" in handle:
6510 return main.TRUE
6511 else:
6512 return main.FALSE
6513 except AssertionError:
6514 main.log.exception( "" )
6515 return None
6516 except TypeError:
6517 main.log.exception( self.name + ": Object not as expected" )
6518 return None
6519 except pexpect.EOF:
6520 main.log.error( self.name + ": EOF exception found" )
6521 main.log.error( self.name + ": " + self.handle.before )
6522 main.cleanAndExit()
6523 except Exception:
6524 main.log.exception( self.name + ": Uncaught exception!" )
6525 main.cleanAndExit()
6526
You Wang547893e2018-05-08 13:34:59 -07006527 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6528 """
6529 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6530 sAddr: we can provide * for ASM or a specific address for SSM
6531 gAddr: specifies multicast group address
6532 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6533 will delete the route if not specified
6534 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6535 """
6536 try:
6537 cmdStr = "mcast-sink-delete"
6538 cmdStr += " -sAddr " + str( sAddr )
6539 cmdStr += " -gAddr " + str( gAddr )
6540 if sink:
6541 cmdStr += " -s " + str( sink )
6542 handle = self.sendline( cmdStr )
6543 assert handle is not None, "Error in sendline"
6544 assert "Command not found:" not in handle, handle
6545 assert "Unsupported command:" not in handle, handle
6546 assert "Error executing command" not in handle, handle
6547 if "Updated the mcast route" in handle:
6548 return main.TRUE
6549 elif "Deleted the mcast route" in handle:
6550 return main.TRUE
6551 else:
6552 return main.FALSE
6553 except AssertionError:
6554 main.log.exception( "" )
6555 return None
6556 except TypeError:
6557 main.log.exception( self.name + ": Object not as expected" )
6558 return None
6559 except pexpect.EOF:
6560 main.log.error( self.name + ": EOF exception found" )
6561 main.log.error( self.name + ": " + self.handle.before )
6562 main.cleanAndExit()
6563 except Exception:
6564 main.log.exception( self.name + ": Uncaught exception!" )
6565 main.cleanAndExit()
6566
You Wange24d6272018-03-27 21:18:50 -07006567 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6568 """
6569 Delete multicast src(s) by calling 'mcast-source-delete' command
6570 sAddr: we can provide * for ASM or a specific address for SSM
6571 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006572 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 -07006573 will delete the route if not specified
6574 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6575 """
6576 try:
6577 cmdStr = "mcast-source-delete"
6578 cmdStr += " -sAddr " + str( sAddr )
6579 cmdStr += " -gAddr " + str( gAddr )
6580 if srcs:
6581 assert isinstance( srcs, list )
6582 for src in srcs:
6583 cmdStr += " -src " + str( src )
6584 handle = self.sendline( cmdStr )
6585 assert handle is not None, "Error in sendline"
6586 assert "Command not found:" not in handle, handle
6587 assert "Unsupported command:" not in handle, handle
6588 assert "Error executing command" not in handle, handle
6589 if "Updated the mcast route" in handle:
6590 return main.TRUE
6591 elif "Deleted the mcast route" in handle:
6592 return main.TRUE
6593 else:
6594 return main.FALSE
6595 except AssertionError:
6596 main.log.exception( "" )
6597 return None
6598 except TypeError:
6599 main.log.exception( self.name + ": Object not as expected" )
6600 return None
6601 except pexpect.EOF:
6602 main.log.error( self.name + ": EOF exception found" )
6603 main.log.error( self.name + ": " + self.handle.before )
6604 main.cleanAndExit()
6605 except Exception:
6606 main.log.exception( self.name + ": Uncaught exception!" )
6607 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006608
6609 def netcfg( self, jsonFormat=True, args="" ):
6610 """
6611 Run netcfg cli command with given args
6612 """
6613 try:
6614 cmdStr = "netcfg"
6615 if jsonFormat:
6616 cmdStr = cmdStr + " -j"
6617 if args:
6618 cmdStr = cmdStr + " " + str( args )
6619 handle = self.sendline( cmdStr )
6620 assert handle is not None, "Error in sendline"
6621 assert "Command not found:" not in handle, handle
6622 assert "Unsupported command:" not in handle, handle
6623 assert "Error executing command" not in handle, handle
6624 return handle
6625 except AssertionError:
6626 main.log.exception( "" )
6627 return None
6628 except TypeError:
6629 main.log.exception( self.name + ": Object not as expected" )
6630 return None
6631 except pexpect.EOF:
6632 main.log.error( self.name + ": EOF exception found" )
6633 main.log.error( self.name + ": " + self.handle.before )
6634 main.cleanAndExit()
6635 except Exception:
6636 main.log.exception( self.name + ": Uncaught exception!" )
6637 main.cleanAndExit()
6638
You Wang0fa76e72018-05-18 11:33:25 -07006639 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True, simple=False ):
You Wang5da39c82018-04-26 22:55:08 -07006640 """
You Wang54b1d672018-06-11 16:44:13 -07006641 Compose and return a list of t3-troubleshoot cli commands for given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006642 Options:
6643 sAddr: IP address of the source host
6644 dAddr: IP address of the destination host
You Wang0fa76e72018-05-18 11:33:25 -07006645 ipv6: True if hosts are IPv6
6646 verbose: return verbose t3 output if True
6647 simple: compose command for t3-troubleshoot-simple if True
You Wang5da39c82018-04-26 22:55:08 -07006648 """
6649 try:
6650 # Collect information of both hosts from onos
6651 hosts = self.hosts()
6652 hosts = json.loads( hosts )
6653 sHost = None
6654 dHost = None
6655 for host in hosts:
6656 if sAddr in host[ "ipAddresses" ]:
6657 sHost = host
6658 elif dAddr in host[ "ipAddresses" ]:
6659 dHost = host
6660 if sHost and dHost:
6661 break
6662 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang54b1d672018-06-11 16:44:13 -07006663 cmdList = []
You Wang5d9527b2018-05-29 17:08:54 -07006664 if simple:
6665 assert dHost, "Not able to find host with IP {}".format( dAddr )
You Wang54b1d672018-06-11 16:44:13 -07006666 cmdStr = "t3-troubleshoot-simple"
6667 if verbose:
6668 cmdStr += " -vv"
6669 if ipv6:
6670 cmdStr += " -et ipv6"
You Wang0fa76e72018-05-18 11:33:25 -07006671 cmdStr += " {}/{} {}/{}".format( sHost[ "mac" ], sHost[ "vlan" ], dHost[ "mac" ], dHost[ "vlan" ] )
You Wang54b1d672018-06-11 16:44:13 -07006672 cmdList.append( cmdStr )
You Wang0fa76e72018-05-18 11:33:25 -07006673 else:
You Wang54b1d672018-06-11 16:44:13 -07006674 for location in sHost[ "locations" ]:
6675 cmdStr = "t3-troubleshoot"
6676 if verbose:
6677 cmdStr += " -vv"
6678 if ipv6:
6679 cmdStr += " -et ipv6"
6680 cmdStr += " -s " + str( sAddr )
6681 cmdStr += " -sp " + str( location[ "elementId" ] ) + "/" + str( location[ "port" ] )
6682 cmdStr += " -sm " + str( sHost[ "mac" ] )
6683 if sHost[ "vlan" ] != "None":
6684 cmdStr += " -vid " + sHost[ "vlan" ]
6685 cmdStr += " -d " + str( dAddr )
6686 netcfg = self.netcfg( args="devices {}".format( location[ "elementId" ] ) )
6687 netcfg = json.loads( netcfg )
6688 assert netcfg, "Failed to get netcfg"
6689 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6690 cmdList.append( cmdStr )
6691 return cmdList
You Wang5da39c82018-04-26 22:55:08 -07006692 except AssertionError:
6693 main.log.exception( "" )
6694 return None
6695 except ( KeyError, TypeError ):
6696 main.log.exception( self.name + ": Object not as expected" )
6697 return None
6698 except Exception:
6699 main.log.exception( self.name + ": Uncaught exception!" )
6700 main.cleanAndExit()
6701
6702 def t3( self, sAddr, dAddr, ipv6=False ):
6703 """
You Wang54b1d672018-06-11 16:44:13 -07006704 Run t3-troubleshoot cli commands for all posible routes given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006705 Options:
6706 sAddr: IP address of the source host
6707 dAddr: IP address of the destination host
6708 """
6709 try:
You Wang54b1d672018-06-11 16:44:13 -07006710 cmdList = self.composeT3Command( sAddr, dAddr, ipv6 )
6711 assert cmdList is not None, "composeT3Command returned None"
6712 t3Output = ""
6713 for cmdStr in cmdList:
6714 handle = self.sendline( cmdStr )
6715 assert handle is not None, "Error in sendline"
6716 assert "Command not found:" not in handle, handle
6717 assert "Unsupported command:" not in handle, handle
6718 assert "Error executing command" not in handle, handle
6719 assert "Tracing packet" in handle
6720 t3Output += handle
6721 return t3Output
You Wang5da39c82018-04-26 22:55:08 -07006722 except AssertionError:
6723 main.log.exception( "" )
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()
Jon Hall3c0114c2020-08-11 15:07:42 -07006732
6733 def prepareForCLI( self, debug=True, maxRetries=120 ):
6734 """
6735 Prepare docker container to connect to onos cli
6736 """
6737 try:
6738 # Wait for log files to be created
6739 ready = 0
6740 retries = 0
6741 while not ready and retries < maxRetries:
6742 retries += 1
6743 self.handle.sendline( "ls -al /root/onos/apache-karaf-*/data/log" )
6744 ready = self.handle.expect( [ "No such file or directory", self.dockerPrompt ] )
6745 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
6746 if not ready:
6747 self.handle.expect( self.dockerPrompt )
6748 time.sleep( 1 )
Jon Hall3c0114c2020-08-11 15:07:42 -07006749
6750 cmdList = []
6751 cmdList.append( "apt-get update" )
6752 cmdList.append( "apt-get install -y openssh-server" )
6753 # Some built in scripts are hardcoded
6754 cmdList.append( "ln -s /root/onos /opt/onos" )
6755 cmdList.append( "ln -s /root/onos/apache-karaf-*/data/log /opt/onos/log" )
6756 cmdList.append( "ls -al /opt/onos" )
6757 output = ""
6758 for cmdStr in cmdList:
6759 self.handle.sendline( cmdStr )
6760 self.handle.expect( self.dockerPrompt )
6761 self.handle.sendline( "" )
6762 self.handle.expect( self.dockerPrompt )
6763 handle = self.handle.before
6764 assert "command not found" not in handle, handle
6765 assert "No such file or directory" not in handle, handle
6766 output += handle
6767 if debug:
6768 main.log.debug( "%s: %s" % ( self.name, output ) )
6769 return output
6770 except AssertionError:
6771 main.log.exception( "" )
6772 return None
6773 except pexpect.EOF:
6774 main.log.error( self.name + ": EOF exception found" )
6775 main.log.error( self.name + ": " + self.handle.before )
6776 main.cleanAndExit()
6777 except Exception:
6778 main.log.exception( self.name + ": Uncaught exception!" )
6779 main.cleanAndExit()
6780
6781 def onosSecureSSH( self, userName="onos", userPWD="rocks" ):
6782 """
6783 Enables secure access to ONOS console
6784 by removing default users & keys.
6785
6786 bin/onos-user-password onos rocks
6787
6788 Returns: main.TRUE on success and main.FALSE on failure
6789 """
6790
6791 try:
6792 self.handle.sendline( "" )
6793 self.handle.expect( self.dockerPrompt )
6794
6795 self.handle.sendline( "[ ! -f ~/.ssh/id_rsa.pub ] && ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' -q" )
6796 self.handle.expect( self.dockerPrompt )
6797 main.log.debug( "%s: %s%s" % ( self.name, self.handle.before, self.handle.after ) )
6798
6799 self.handle.sendline( "bin/onos-user-key $(id -un) $(cut -d\\\\ -f2 ~/.ssh/id_rsa.pub)" )
6800 self.handle.expect( pexpect.TIMEOUT, timeout=10 )
6801 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
6802
6803 self.handle.sendline( "bin/onos-user-password %s %s" % ( userName, userPWD ) )
6804 i = self.handle.expect( [ "usage",
6805 self.dockerPrompt,
6806 pexpect.TIMEOUT ] )
6807 if i == 0:
6808 # malformed command
6809 main.log.warn( self.name + ": Could not parse onos-user-password command" )
6810 self.handle.expect( self.dockerPrompt )
6811 return main.FALSE
6812 elif i == 1:
6813 # Process started
6814 main.log.info( self.name + ": SSH password added for user " + userName )
6815 return main.TRUE
6816 elif i == 2:
6817 # timeout
6818 main.log.error( self.name + ": Failed to secure onos ssh " )
6819 main.log.debug( "%s: %s" % ( self.name, self.handle.before ) )
6820 except pexpect.EOF:
6821 main.log.error( self.name + ": EOF exception found" )
6822 main.log.error( self.name + ": " + self.handle.before )
6823 main.cleanAndExit()
6824 except Exception:
6825 main.log.exception( self.name + ": Uncaught exception!" )
6826 main.cleanAndExit()