blob: 9636aa4d872ad586dd870b9c64c45f4c8067acca [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
5Copyright 2014 Open Networking Foundation (ONF)
6
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
14 (at your option) any later version.
15
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"""
24
25"""
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
kelvin8ec71442015-01-15 16:57:00 -080037"""
andrewonlab95ce8322014-10-13 14:12:04 -040038import pexpect
39import re
Jon Hall30b82fa2015-03-04 17:15:43 -080040import json
41import types
Jon Hallbd16b922015-03-26 17:53:15 -070042import time
kelvin-onlaba4074292015-07-09 15:19:49 -070043import os
andrewonlab95ce8322014-10-13 14:12:04 -040044from drivers.common.clidriver import CLI
You Wangdb8cd0a2016-05-26 15:19:45 -070045from core.graph import Graph
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -070046from cStringIO import StringIO
47from itertools import izip
andrewonlab95ce8322014-10-13 14:12:04 -040048
kelvin8ec71442015-01-15 16:57:00 -080049class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040050
kelvin8ec71442015-01-15 16:57:00 -080051 def __init__( self ):
52 """
53 Initialize client
54 """
Jon Hallefbd9792015-03-05 16:11:36 -080055 self.name = None
56 self.home = None
57 self.handle = None
Devin Limdc78e202017-06-09 18:30:07 -070058 self.karafUser = None
59 self.karafPass = None
You Wangdb8cd0a2016-05-26 15:19:45 -070060 self.graph = Graph()
Devin Limdc78e202017-06-09 18:30:07 -070061 super( OnosCliDriver, self ).__init__()
kelvin8ec71442015-01-15 16:57:00 -080062
Devin Limdc78e202017-06-09 18:30:07 -070063 def checkOptions(self, var, defaultVar):
64 if var is None or var == "":
65 return defaultVar
66 return var
kelvin8ec71442015-01-15 16:57:00 -080067 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 ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070074 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040075 for key in self.options:
76 if key == "home":
Devin Limdc78e202017-06-09 18:30:07 -070077 self.home = self.options[ key ]
78 elif key == "karaf_username":
79 self.karafUser = self.options[ key ]
80 elif key == "karaf_password":
81 self.karafPass = self.options[ key ]
82
83 self.home = self.checkOptions(self.home, "~/onos")
84 self.karafUser = self.checkOptions(self.karafUser, self.user_name)
85 self.karafPass = self.checkOptions(self.karafPass, self.pwd )
andrewonlab95ce8322014-10-13 14:12:04 -040086
kelvin-onlaba4074292015-07-09 15:19:49 -070087 for key in self.options:
88 if key == 'onosIp':
89 self.onosIp = self.options[ 'onosIp' ]
90 break
91
kelvin8ec71442015-01-15 16:57:00 -080092 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070093
94 try:
Jon Hallc6793552016-01-19 14:18:37 -080095 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070096 self.ip_address = os.getenv( str( self.ip_address ) )
97 else:
98 main.log.info( self.name +
99 ": Trying to connect to " +
100 self.ip_address )
101
102 except KeyError:
103 main.log.info( "Invalid host name," +
104 " connecting to local host instead" )
105 self.ip_address = 'localhost'
106 except Exception as inst:
107 main.log.error( "Uncaught exception: " + str( inst ) )
108
kelvin8ec71442015-01-15 16:57:00 -0800109 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -0800110 user_name=self.user_name,
111 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -0800112 port=self.port,
113 pwd=self.pwd,
114 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -0400115
kelvin8ec71442015-01-15 16:57:00 -0800116 self.handle.sendline( "cd " + self.home )
Devin Limdc78e202017-06-09 18:30:07 -0700117 self.handle.expect( self.prompt )
andrewonlab95ce8322014-10-13 14:12:04 -0400118 if self.handle:
119 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800120 else:
121 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -0400122 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800123 except TypeError:
124 main.log.exception( self.name + ": Object not as expected" )
125 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400126 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800127 main.log.error( self.name + ": EOF exception found" )
128 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700129 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800130 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800131 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700132 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400133
kelvin8ec71442015-01-15 16:57:00 -0800134 def disconnect( self ):
135 """
andrewonlab95ce8322014-10-13 14:12:04 -0400136 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800137 """
Jon Halld61331b2015-02-17 16:35:47 -0800138 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400139 try:
Jon Hall61282e32015-03-19 11:34:11 -0700140 if self.handle:
141 i = self.logout()
142 if i == main.TRUE:
143 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700144 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700145 self.handle.sendline( "exit" )
146 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800147 except TypeError:
148 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800149 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400150 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800151 main.log.error( self.name + ": EOF exception found" )
152 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700153 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700154 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700155 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800156 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800157 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400158 response = main.FALSE
159 return response
160
kelvin8ec71442015-01-15 16:57:00 -0800161 def logout( self ):
162 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500163 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700164 Returns main.TRUE if exited CLI and
165 main.FALSE on timeout (not guranteed you are disconnected)
166 None on TypeError
167 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800168 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500169 try:
Jon Hall61282e32015-03-19 11:34:11 -0700170 if self.handle:
171 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700172 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ],
Jon Hall61282e32015-03-19 11:34:11 -0700173 timeout=10 )
174 if i == 0: # In ONOS CLI
175 self.handle.sendline( "logout" )
Devin Limdc78e202017-06-09 18:30:07 -0700176 j = self.handle.expect( [ self.prompt,
Jon Hallbfe00002016-04-05 10:23:54 -0700177 "Command not found:",
178 pexpect.TIMEOUT ] )
179 if j == 0: # Successfully logged out
180 return main.TRUE
181 elif j == 1 or j == 2:
182 # ONOS didn't fully load, and logout command isn't working
183 # or the command timed out
184 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700185 try:
Devin Limdc78e202017-06-09 18:30:07 -0700186 self.handle.expect( self.prompt )
Jon Hall64ab3bd2016-05-13 11:29:44 -0700187 except pexpect.TIMEOUT:
188 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700189 return main.TRUE
Jon Halle0f0b342017-04-18 11:43:47 -0700190 else: # some other output
Jon Hallbfe00002016-04-05 10:23:54 -0700191 main.log.warn( "Unknown repsonse to logout command: '{}'",
192 repr( self.handle.before ) )
193 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700194 elif i == 1: # not in CLI
195 return main.TRUE
196 elif i == 3: # Timeout
197 return main.FALSE
198 else:
andrewonlab9627f432014-11-14 12:45:10 -0500199 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800200 except TypeError:
201 main.log.exception( self.name + ": Object not as expected" )
202 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500203 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800204 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700205 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700206 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700207 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700208 main.log.error( self.name +
209 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800210 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800211 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700212 main.cleanAndExit()
andrewonlab38d2b4a2014-11-13 16:28:47 -0500213
kelvin-onlabd3b64892015-01-20 13:26:24 -0800214 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800215 """
andrewonlab95ce8322014-10-13 14:12:04 -0400216 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800217
andrewonlab95ce8322014-10-13 14:12:04 -0400218 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800219 """
andrewonlab95ce8322014-10-13 14:12:04 -0400220 try:
221 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800222 main.log.error( "Must define cellname" )
Devin Lim44075962017-08-11 10:56:37 -0700223 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400224 else:
kelvin8ec71442015-01-15 16:57:00 -0800225 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800226 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800227 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400228 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800229 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800230 handleBefore = self.handle.before
231 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800232 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800233 self.handle.sendline("")
Devin Limdc78e202017-06-09 18:30:07 -0700234 self.handle.expect(self.prompt)
andrew@onlab.usc400b112015-01-21 15:33:19 -0800235 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400236
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 main.log.info( "Cell call returned: " + handleBefore +
238 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400239
240 return main.TRUE
241
Jon Halld4d4b372015-01-28 16:02:41 -0800242 except TypeError:
243 main.log.exception( self.name + ": Object not as expected" )
244 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400245 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800246 main.log.error( self.name + ": eof exception found" )
247 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700248 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800249 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800250 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700251 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -0800252
pingping-lin57a56ce2015-05-20 16:43:48 -0700253 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800254 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800255 """
Jon Hallefbd9792015-03-05 16:11:36 -0800256 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800257 by user would be used to set the current karaf shell idle timeout.
258 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800259 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800260 Below is an example to start a session with 60 seconds idle timeout
261 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800262
Hari Krishna25d42f72015-01-05 15:08:28 -0800263 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800264 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800265
kelvin-onlabd3b64892015-01-20 13:26:24 -0800266 Note: karafTimeout is left as str so that this could be read
267 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800268 """
You Wangf69ab392016-01-26 16:34:38 -0800269 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400270 try:
Jon Hall67253832016-12-05 09:47:13 -0800271 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800272 self.handle.sendline( "" )
273 x = self.handle.expect( [
Devin Limdc78e202017-06-09 18:30:07 -0700274 self.prompt, "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500275 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800276 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500277 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400278
Jon Hall67253832016-12-05 09:47:13 -0800279 # Not in CLI so login
Chiyu Chengef109502016-11-21 15:51:38 -0800280 if waitForStart:
281 # Wait for onos start ( -w ) and enter onos cli
282 startCliCommand = "onos -w "
283 else:
284 startCliCommand = "onos "
285 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800286 i = self.handle.expect( [
287 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700288 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400289
290 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800291 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800292 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800293 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800294 "config:property-set -p org.apache.karaf.shell\
295 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800296 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700297 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800298 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800299 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400300 return main.TRUE
301 else:
kelvin8ec71442015-01-15 16:57:00 -0800302 # If failed, send ctrl+c to process and try again
303 main.log.info( "Starting CLI failed. Retrying..." )
304 self.handle.send( "\x03" )
Chiyu Chengef109502016-11-21 15:51:38 -0800305 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800306 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
307 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400308 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800309 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800310 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800311 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800312 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800313 "config:property-set -p org.apache.karaf.shell\
314 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800315 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700316 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800317 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800318 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400319 return main.TRUE
320 else:
kelvin8ec71442015-01-15 16:57:00 -0800321 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800322 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400323 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400324
Jon Halld4d4b372015-01-28 16:02:41 -0800325 except TypeError:
326 main.log.exception( self.name + ": Object not as expected" )
327 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400328 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800329 main.log.error( self.name + ": EOF exception found" )
330 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700331 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800332 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800333 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700334 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400335
suibin zhang116647a2016-05-06 16:30:09 -0700336 def startCellCli( self, karafTimeout="",
337 commandlineTimeout=10, onosStartTimeout=60 ):
338 """
339 Start CLI on onos ecll handle.
340
341 karafTimeout is an optional argument. karafTimeout value passed
342 by user would be used to set the current karaf shell idle timeout.
343 Note that when ever this property is modified the shell will exit and
344 the subsequent login would reflect new idle timeout.
345 Below is an example to start a session with 60 seconds idle timeout
346 ( input value is in milliseconds ):
347
348 tValue = "60000"
349
350 Note: karafTimeout is left as str so that this could be read
351 and passed to startOnosCli from PARAMS file as str.
352 """
353
354 try:
355 self.handle.sendline( "" )
356 x = self.handle.expect( [
Devin Limdc78e202017-06-09 18:30:07 -0700357 self.prompt, "onos>" ], commandlineTimeout)
suibin zhang116647a2016-05-06 16:30:09 -0700358
359 if x == 1:
360 main.log.info( "ONOS cli is already running" )
361 return main.TRUE
362
363 # Wait for onos start ( -w ) and enter onos cli
364 self.handle.sendline( "/opt/onos/bin/onos" )
365 i = self.handle.expect( [
366 "onos>",
367 pexpect.TIMEOUT ], onosStartTimeout )
368
369 if i == 0:
370 main.log.info( self.name + " CLI Started successfully" )
371 if karafTimeout:
372 self.handle.sendline(
373 "config:property-set -p org.apache.karaf.shell\
374 sshIdleTimeout " +
375 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700376 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700377 self.handle.sendline( "/opt/onos/bin/onos" )
378 self.handle.expect( "onos>" )
379 return main.TRUE
380 else:
381 # If failed, send ctrl+c to process and try again
382 main.log.info( "Starting CLI failed. Retrying..." )
383 self.handle.send( "\x03" )
384 self.handle.sendline( "/opt/onos/bin/onos" )
385 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
386 timeout=30 )
387 if i == 0:
388 main.log.info( self.name + " CLI Started " +
389 "successfully after retry attempt" )
390 if karafTimeout:
391 self.handle.sendline(
392 "config:property-set -p org.apache.karaf.shell\
393 sshIdleTimeout " +
394 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700395 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700396 self.handle.sendline( "/opt/onos/bin/onos" )
397 self.handle.expect( "onos>" )
398 return main.TRUE
399 else:
400 main.log.error( "Connection to CLI " +
401 self.name + " timeout" )
402 return main.FALSE
403
404 except TypeError:
405 main.log.exception( self.name + ": Object not as expected" )
406 return None
407 except pexpect.EOF:
408 main.log.error( self.name + ": EOF exception found" )
409 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700410 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700411 except Exception:
412 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700413 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700414
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800415 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800416 """
417 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800418 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800419 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700420 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800421 Available level: DEBUG, TRACE, INFO, WARN, ERROR
422 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800423 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800424 """
425 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800426 lvlStr = ""
427 if level:
428 lvlStr = "--level=" + level
429
kelvin-onlab338f5512015-02-06 10:53:16 -0800430 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700431 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800432 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800433
kelvin-onlab9f541032015-02-04 16:19:53 -0800434 response = self.handle.before
435 if re.search( "Error", response ):
436 return main.FALSE
437 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700438 except pexpect.TIMEOUT:
439 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700440 if noExit:
441 main.cleanup()
442 return None
443 else:
Devin Lim44075962017-08-11 10:56:37 -0700444 main.cleanAndExit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800445 except pexpect.EOF:
446 main.log.error( self.name + ": EOF exception found" )
447 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700448 if noExit:
449 main.cleanup()
450 return None
451 else:
Devin Lim44075962017-08-11 10:56:37 -0700452 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800453 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800454 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700455 if noExit:
456 main.cleanup()
457 return None
458 else:
Devin Lim44075962017-08-11 10:56:37 -0700459 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400460
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700461 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, dollarSign=False ):
kelvin8ec71442015-01-15 16:57:00 -0800462 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800463 Send a completely user specified string to
464 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400465 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800466
YPZhang14a4aa92016-07-15 13:37:15 -0700467 if noExit is True, TestON will not exit, and return None
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700468 if dollarSign is True, TestON will not expect for '$' as a new CLI or onos> prompt
469 since '$' can be in the output.
YPZhangebf9eb52016-05-12 15:20:24 -0700470
andrewonlaba18f6bf2014-10-13 19:31:54 -0400471 Warning: There are no sanity checking to commands
472 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800473
kelvin8ec71442015-01-15 16:57:00 -0800474 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400475 try:
Jon Halla495f562016-05-16 18:03:26 -0700476 # Try to reconnect if disconnected from cli
477 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700478 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ] )
Jon Halla495f562016-05-16 18:03:26 -0700479 if i == 1:
480 main.log.error( self.name + ": onos cli session closed. ")
481 if self.onosIp:
482 main.log.warn( "Trying to reconnect " + self.onosIp )
483 reconnectResult = self.startOnosCli( self.onosIp )
484 if reconnectResult:
485 main.log.info( self.name + ": onos cli session reconnected." )
486 else:
487 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700488 if noExit:
489 return None
490 else:
Devin Lim44075962017-08-11 10:56:37 -0700491 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700492 else:
Devin Lim44075962017-08-11 10:56:37 -0700493 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700494 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700495 main.log.warn( "Timeout when testing cli responsiveness" )
496 main.log.debug( self.handle.before )
497 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Halla495f562016-05-16 18:03:26 -0700498 self.handle.expect( "onos>" )
499
Jon Hall14a03b52016-05-11 12:07:30 -0700500 if debug:
501 # NOTE: This adds and average of .4 seconds per call
502 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700503 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800504 self.handle.sendline( cmdStr )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700505 if dollarSign:
506 i = self.handle.expect( ["onos>"], timeout )
507 else:
Devin Limdc78e202017-06-09 18:30:07 -0700508 i = self.handle.expect( ["onos>", self.prompt], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800509 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800510 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800511 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
512 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700513 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700514 main.log.debug( self.name + ": Raw output" )
515 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700516
517 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800518 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800519 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700520 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700521 main.log.debug( self.name + ": ansiEscape output" )
522 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700523
kelvin-onlabfb521662015-02-27 09:52:40 -0800524 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800525 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700526 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700527 main.log.debug( self.name + ": Removed extra returns " +
528 "from output" )
529 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700530
531 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800532 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700533 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700534 main.log.debug( self.name + ": parsed and stripped output" )
535 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700536
Jon Hall63604932015-02-26 17:09:50 -0800537 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700538 output = response.split( cmdStr.strip(), 1 )
539 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700540 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700541 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700542 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800543 output = output[1].strip()
544 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800545 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800546 return output
GlennRCed771242016-01-13 17:02:47 -0800547 except pexpect.TIMEOUT:
548 main.log.error( self.name + ":ONOS timeout" )
549 if debug:
550 main.log.debug( self.handle.before )
551 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700552 except IndexError:
553 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700554 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700555 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800556 except TypeError:
557 main.log.exception( self.name + ": Object not as expected" )
558 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400559 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800560 main.log.error( self.name + ": EOF exception found" )
561 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700562 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700563 return None
564 else:
Devin Lim44075962017-08-11 10:56:37 -0700565 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800566 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800567 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700568 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700569 return None
570 else:
Devin Lim44075962017-08-11 10:56:37 -0700571 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400572
kelvin8ec71442015-01-15 16:57:00 -0800573 # IMPORTANT NOTE:
574 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800575 # the cli command changing 'a:b' with 'aB'.
576 # Ex ) onos:topology > onosTopology
577 # onos:links > onosLinks
578 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800579
kelvin-onlabd3b64892015-01-20 13:26:24 -0800580 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800581 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400582 Adds a new cluster node by ID and address information.
583 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800584 * nodeId
585 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400586 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800587 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800588 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400589 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800590 cmdStr = "add-node " + str( nodeId ) + " " +\
591 str( ONOSIp ) + " " + str( tcpPort )
592 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700593 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800594 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800595 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800596 main.log.error( "Error in adding node" )
597 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800598 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400599 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800600 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400601 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800602 except AssertionError:
603 main.log.exception( "" )
604 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800605 except TypeError:
606 main.log.exception( self.name + ": Object not as expected" )
607 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400608 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800609 main.log.error( self.name + ": EOF exception found" )
610 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700611 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800612 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800613 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700614 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400615
kelvin-onlabd3b64892015-01-20 13:26:24 -0800616 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800617 """
andrewonlab86dc3082014-10-13 18:18:38 -0400618 Removes a cluster by ID
619 Issues command: 'remove-node [<node-id>]'
620 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800621 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800622 """
andrewonlab86dc3082014-10-13 18:18:38 -0400623 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400624
kelvin-onlabd3b64892015-01-20 13:26:24 -0800625 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700626 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700627 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800628 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700629 if re.search( "Error", handle ):
630 main.log.error( "Error in removing node" )
631 main.log.error( handle )
632 return main.FALSE
633 else:
634 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800635 except AssertionError:
636 main.log.exception( "" )
637 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800638 except TypeError:
639 main.log.exception( self.name + ": Object not as expected" )
640 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400641 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800642 main.log.error( self.name + ": EOF exception found" )
643 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700644 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800645 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800646 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700647 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400648
Jon Hall61282e32015-03-19 11:34:11 -0700649 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800650 """
andrewonlab7c211572014-10-15 16:45:20 -0400651 List the nodes currently visible
652 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700653 Optional argument:
654 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800655 """
andrewonlab7c211572014-10-15 16:45:20 -0400656 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700657 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700658 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700659 cmdStr += " -j"
660 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700661 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800662 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700663 return output
Jon Hallc6793552016-01-19 14:18:37 -0800664 except AssertionError:
665 main.log.exception( "" )
666 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800667 except TypeError:
668 main.log.exception( self.name + ": Object not as expected" )
669 return None
andrewonlab7c211572014-10-15 16:45:20 -0400670 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800671 main.log.error( self.name + ": EOF exception found" )
672 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700673 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800674 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800675 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700676 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400677
kelvin8ec71442015-01-15 16:57:00 -0800678 def topology( self ):
679 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700680 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700681 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700682 Return:
683 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800684 """
andrewonlab95ce8322014-10-13 14:12:04 -0400685 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700686 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800687 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800688 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800689 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700690 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400691 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800692 except AssertionError:
693 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800694 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800695 except TypeError:
696 main.log.exception( self.name + ": Object not as expected" )
697 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400698 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800699 main.log.error( self.name + ": EOF exception found" )
700 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700701 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800702 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800703 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700704 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800705
jenkins7ead5a82015-03-13 10:28:21 -0700706 def deviceRemove( self, deviceId ):
707 """
708 Removes particular device from storage
709
710 TODO: refactor this function
711 """
712 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700713 cmdStr = "device-remove " + str( deviceId )
714 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800715 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800716 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700717 if re.search( "Error", handle ):
718 main.log.error( "Error in removing device" )
719 main.log.error( handle )
720 return main.FALSE
721 else:
722 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800723 except AssertionError:
724 main.log.exception( "" )
725 return None
jenkins7ead5a82015-03-13 10:28:21 -0700726 except TypeError:
727 main.log.exception( self.name + ": Object not as expected" )
728 return None
729 except pexpect.EOF:
730 main.log.error( self.name + ": EOF exception found" )
731 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700732 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700733 except Exception:
734 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700735 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700736
kelvin-onlabd3b64892015-01-20 13:26:24 -0800737 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800738 """
Jon Hall7b02d952014-10-17 20:14:54 -0400739 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400740 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800741 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800742 """
andrewonlab86dc3082014-10-13 18:18:38 -0400743 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700744 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800745 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700746 cmdStr += " -j"
747 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800748 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800749 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700750 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800751 except AssertionError:
752 main.log.exception( "" )
753 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800754 except TypeError:
755 main.log.exception( self.name + ": Object not as expected" )
756 return None
andrewonlab7c211572014-10-15 16:45:20 -0400757 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800758 main.log.error( self.name + ": EOF exception found" )
759 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700760 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800761 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800762 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700763 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400764
kelvin-onlabd3b64892015-01-20 13:26:24 -0800765 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800766 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800767 This balances the devices across all controllers
768 by issuing command: 'onos> onos:balance-masters'
769 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800770 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800771 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800772 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700773 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800774 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800775 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700776 if re.search( "Error", handle ):
777 main.log.error( "Error in balancing masters" )
778 main.log.error( handle )
779 return main.FALSE
780 else:
781 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800782 except AssertionError:
783 main.log.exception( "" )
784 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800785 except TypeError:
786 main.log.exception( self.name + ": Object not as expected" )
787 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800788 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800789 main.log.error( self.name + ": EOF exception found" )
790 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700791 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800792 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800793 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700794 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800795
Jon Hallc6793552016-01-19 14:18:37 -0800796 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700797 """
798 Returns the output of the masters command.
799 Optional argument:
800 * jsonFormat - boolean indicating if you want output in json
801 """
802 try:
803 cmdStr = "onos:masters"
804 if jsonFormat:
805 cmdStr += " -j"
806 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700807 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800808 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700809 return output
Jon Hallc6793552016-01-19 14:18:37 -0800810 except AssertionError:
811 main.log.exception( "" )
812 return None
acsmars24950022015-07-30 18:00:43 -0700813 except TypeError:
814 main.log.exception( self.name + ": Object not as expected" )
815 return None
816 except pexpect.EOF:
817 main.log.error( self.name + ": EOF exception found" )
818 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700819 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700820 except Exception:
821 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700822 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700823
Jon Hallc6793552016-01-19 14:18:37 -0800824 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700825 """
826 Uses the master command to check that the devices' leadership
827 is evenly divided
828
829 Dependencies: checkMasters() and summary()
830
Jon Hall6509dbf2016-06-21 17:01:17 -0700831 Returns main.TRUE if the devices are balanced
832 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700833 Exits on Exception
834 Returns None on TypeError
835 """
836 try:
Jon Hallc6793552016-01-19 14:18:37 -0800837 summaryOutput = self.summary()
838 totalDevices = json.loads( summaryOutput )[ "devices" ]
839 except ( TypeError, ValueError ):
840 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
841 return None
842 try:
acsmars24950022015-07-30 18:00:43 -0700843 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800844 mastersOutput = self.checkMasters()
845 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700846 first = masters[ 0 ][ "size" ]
847 for master in masters:
848 totalOwnedDevices += master[ "size" ]
849 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
850 main.log.error( "Mastership not balanced" )
851 main.log.info( "\n" + self.checkMasters( False ) )
852 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700853 main.log.info( "Mastership balanced between " +
854 str( len(masters) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700855 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800856 except ( TypeError, ValueError ):
857 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700858 return None
859 except pexpect.EOF:
860 main.log.error( self.name + ": EOF exception found" )
861 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700862 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700863 except Exception:
864 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700865 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700866
YPZhangfebf7302016-05-24 16:45:56 -0700867 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800868 """
Jon Halle8217482014-10-17 13:49:14 -0400869 Lists all core links
870 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800871 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800872 """
Jon Halle8217482014-10-17 13:49:14 -0400873 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700874 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800875 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700876 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700877 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800878 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800879 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700880 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800881 except AssertionError:
882 main.log.exception( "" )
883 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800884 except TypeError:
885 main.log.exception( self.name + ": Object not as expected" )
886 return None
Jon Halle8217482014-10-17 13:49:14 -0400887 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800888 main.log.error( self.name + ": EOF exception found" )
889 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700890 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800891 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800892 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700893 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400894
kelvin-onlabd3b64892015-01-20 13:26:24 -0800895 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800896 """
Jon Halle8217482014-10-17 13:49:14 -0400897 Lists all ports
898 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800899 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800900 """
Jon Halle8217482014-10-17 13:49:14 -0400901 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700902 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800903 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700904 cmdStr += " -j"
905 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800906 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800907 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700908 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800909 except AssertionError:
910 main.log.exception( "" )
911 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800912 except TypeError:
913 main.log.exception( self.name + ": Object not as expected" )
914 return None
Jon Halle8217482014-10-17 13:49:14 -0400915 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800916 main.log.error( self.name + ": EOF exception found" )
917 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700918 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800919 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800920 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700921 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400922
kelvin-onlabd3b64892015-01-20 13:26:24 -0800923 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800924 """
Jon Hall983a1702014-10-28 18:44:22 -0400925 Lists all devices and the controllers with roles assigned to them
926 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800927 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800928 """
andrewonlab7c211572014-10-15 16:45:20 -0400929 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700930 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800931 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700932 cmdStr += " -j"
933 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800934 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800935 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700936 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800937 except AssertionError:
938 main.log.exception( "" )
939 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800940 except TypeError:
941 main.log.exception( self.name + ": Object not as expected" )
942 return None
Jon Hall983a1702014-10-28 18:44:22 -0400943 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800944 main.log.error( self.name + ": EOF exception found" )
945 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700946 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800947 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800948 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700949 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -0400950
kelvin-onlabd3b64892015-01-20 13:26:24 -0800951 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800952 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800953 Given the a string containing the json representation of the "roles"
954 cli command and a partial or whole device id, returns a json object
955 containing the roles output for the first device whose id contains
956 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400957
958 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800959 A dict of the role assignments for the given device or
960 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800961 """
Jon Hall983a1702014-10-28 18:44:22 -0400962 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800963 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400964 return None
965 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800966 rawRoles = self.roles()
967 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800968 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800969 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800970 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400972 return device
973 return None
Jon Hallc6793552016-01-19 14:18:37 -0800974 except ( TypeError, ValueError ):
975 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800976 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400977 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800978 main.log.error( self.name + ": EOF exception found" )
979 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700980 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800981 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800982 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700983 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -0800984
kelvin-onlabd3b64892015-01-20 13:26:24 -0800985 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800986 """
Jon Hall94fd0472014-12-08 11:52:42 -0800987 Iterates through each device and checks if there is a master assigned
988 Returns: main.TRUE if each device has a master
989 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800990 """
Jon Hall94fd0472014-12-08 11:52:42 -0800991 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800992 rawRoles = self.roles()
993 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800994 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800995 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800996 # print device
997 if device[ 'master' ] == "none":
998 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800999 return main.FALSE
1000 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001001 except ( TypeError, ValueError ):
1002 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001003 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001004 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001005 main.log.error( self.name + ": EOF exception found" )
1006 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001007 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001008 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001009 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001010 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001011
kelvin-onlabd3b64892015-01-20 13:26:24 -08001012 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001013 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001014 Returns string of paths, and the cost.
1015 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001016 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001017 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001018 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1019 handle = self.sendline( cmdStr )
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 Halle3f39ff2015-01-13 11:50:53 -08001022 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001023 main.log.error( "Error in getting paths" )
1024 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001025 else:
kelvin8ec71442015-01-15 16:57:00 -08001026 path = handle.split( ";" )[ 0 ]
1027 cost = handle.split( ";" )[ 1 ]
1028 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001029 except AssertionError:
1030 main.log.exception( "" )
1031 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001032 except TypeError:
1033 main.log.exception( self.name + ": Object not as expected" )
1034 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001035 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001036 main.log.error( self.name + ": EOF exception found" )
1037 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001038 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001039 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001040 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001041 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001042
kelvin-onlabd3b64892015-01-20 13:26:24 -08001043 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001044 """
Jon Hallffb386d2014-11-21 13:43:38 -08001045 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001046 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001047 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001048 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001049 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001050 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001051 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001052 cmdStr += " -j"
1053 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001054 if handle:
1055 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001056 # TODO: Maybe make this less hardcoded
1057 # ConsistentMap Exceptions
1058 assert "org.onosproject.store.service" not in handle
1059 # Node not leader
1060 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001061 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001062 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001063 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001064 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001065 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001066 except TypeError:
1067 main.log.exception( self.name + ": Object not as expected" )
1068 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001069 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001070 main.log.error( self.name + ": EOF exception found" )
1071 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001072 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001073 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001074 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001075 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001076
kelvin-onlabd3b64892015-01-20 13:26:24 -08001077 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001078 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001079 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001080
Jon Hallefbd9792015-03-05 16:11:36 -08001081 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001082 partial mac address
1083
Jon Hall42db6dc2014-10-24 19:03:48 -04001084 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001085 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001086 try:
kelvin8ec71442015-01-15 16:57:00 -08001087 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001088 return None
1089 else:
1090 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001091 rawHosts = self.hosts()
1092 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001093 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001094 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001095 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001096 if not host:
1097 pass
1098 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001099 return host
1100 return None
Jon Hallc6793552016-01-19 14:18:37 -08001101 except ( TypeError, ValueError ):
1102 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001103 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001104 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001105 main.log.error( self.name + ": EOF exception found" )
1106 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001107 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001108 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001109 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001110 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001111
kelvin-onlabd3b64892015-01-20 13:26:24 -08001112 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001113 """
1114 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001115 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001116
andrewonlab3f0a4af2014-10-17 12:25:14 -04001117 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001118 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001119 IMPORTANT:
1120 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001121 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001122 Furthermore, it assumes that value of VLAN is '-1'
1123 Description:
kelvin8ec71442015-01-15 16:57:00 -08001124 Converts mininet hosts ( h1, h2, h3... ) into
1125 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1126 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001127 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001128 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001129
kelvin-onlabd3b64892015-01-20 13:26:24 -08001130 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001131 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001132 hostHex = hex( int( host ) ).zfill( 12 )
1133 hostHex = str( hostHex ).replace( 'x', '0' )
1134 i = iter( str( hostHex ) )
1135 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1136 hostHex = hostHex + "/-1"
1137 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001138
kelvin-onlabd3b64892015-01-20 13:26:24 -08001139 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001140
Jon Halld4d4b372015-01-28 16:02:41 -08001141 except TypeError:
1142 main.log.exception( self.name + ": Object not as expected" )
1143 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001144 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001145 main.log.error( self.name + ": EOF exception found" )
1146 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001147 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001148 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001149 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001150 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001151
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001152 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001153 """
andrewonlabe6745342014-10-17 14:29:13 -04001154 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001155 * hostIdOne: ONOS host id for host1
1156 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001157 Optional:
1158 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001159 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001160 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001161 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001162 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001163 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001164 Returns:
1165 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001166 """
andrewonlabe6745342014-10-17 14:29:13 -04001167 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001168 cmdStr = "add-host-intent "
1169 if vlanId:
1170 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001171 if setVlan:
1172 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001173 if encap:
1174 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001175 if bandwidth:
1176 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001177 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001178 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001179 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001180 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001181 if re.search( "Error", handle ):
1182 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001183 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001184 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001185 else:
1186 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001187 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1188 match = re.search('id=0x([\da-f]+),', handle)
1189 if match:
1190 return match.group()[3:-1]
1191 else:
1192 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001193 main.log.debug( "Response from ONOS was: " +
1194 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001195 return None
Jon Hallc6793552016-01-19 14:18:37 -08001196 except AssertionError:
1197 main.log.exception( "" )
1198 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001199 except TypeError:
1200 main.log.exception( self.name + ": Object not as expected" )
1201 return None
andrewonlabe6745342014-10-17 14:29:13 -04001202 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001203 main.log.error( self.name + ": EOF exception found" )
1204 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001205 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001206 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001207 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001208 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001209
kelvin-onlabd3b64892015-01-20 13:26:24 -08001210 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001211 """
andrewonlab7b31d232014-10-24 13:31:47 -04001212 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001213 * ingressDevice: device id of ingress device
1214 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001215 Optional:
1216 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001217 Description:
1218 Adds an optical intent by specifying an ingress and egress device
1219 Returns:
1220 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001221 """
andrewonlab7b31d232014-10-24 13:31:47 -04001222 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001223 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1224 " " + str( egressDevice )
1225 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001226 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001227 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001228 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001229 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001230 main.log.error( "Error in adding Optical intent" )
1231 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001232 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001233 main.log.info( "Optical intent installed between " +
1234 str( ingressDevice ) + " and " +
1235 str( egressDevice ) )
1236 match = re.search('id=0x([\da-f]+),', handle)
1237 if match:
1238 return match.group()[3:-1]
1239 else:
1240 main.log.error( "Error, intent ID not found" )
1241 return None
Jon Hallc6793552016-01-19 14:18:37 -08001242 except AssertionError:
1243 main.log.exception( "" )
1244 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001245 except TypeError:
1246 main.log.exception( self.name + ": Object not as expected" )
1247 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001248 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001249 main.log.error( self.name + ": EOF exception found" )
1250 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001251 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001252 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001253 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001254 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001255
kelvin-onlabd3b64892015-01-20 13:26:24 -08001256 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001257 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001258 ingressDevice,
1259 egressDevice,
1260 portIngress="",
1261 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001262 ethType="",
1263 ethSrc="",
1264 ethDst="",
1265 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001266 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001267 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001268 ipProto="",
1269 ipSrc="",
1270 ipDst="",
1271 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001272 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001273 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001274 setVlan="",
1275 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001276 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001277 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001278 * ingressDevice: device id of ingress device
1279 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001280 Optional:
1281 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001282 * ethSrc: specify ethSrc ( i.e. src mac addr )
1283 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001284 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001285 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001286 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001287 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001288 * ipSrc: specify ip source address
1289 * ipDst: specify ip destination address
1290 * tcpSrc: specify tcp source port
1291 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001292 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001293 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001294 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001295 Description:
kelvin8ec71442015-01-15 16:57:00 -08001296 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001297 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001298 Returns:
1299 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001300
Jon Halle3f39ff2015-01-13 11:50:53 -08001301 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001302 options developers provide for point-to-point
1303 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001304 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001305 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001306 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001307
Jeremy Songsterff553672016-05-12 17:06:23 -07001308 if ethType:
1309 cmd += " --ethType " + str( ethType )
1310 if ethSrc:
1311 cmd += " --ethSrc " + str( ethSrc )
1312 if ethDst:
1313 cmd += " --ethDst " + str( ethDst )
1314 if bandwidth:
1315 cmd += " --bandwidth " + str( bandwidth )
1316 if lambdaAlloc:
1317 cmd += " --lambda "
1318 if ipProto:
1319 cmd += " --ipProto " + str( ipProto )
1320 if ipSrc:
1321 cmd += " --ipSrc " + str( ipSrc )
1322 if ipDst:
1323 cmd += " --ipDst " + str( ipDst )
1324 if tcpSrc:
1325 cmd += " --tcpSrc " + str( tcpSrc )
1326 if tcpDst:
1327 cmd += " --tcpDst " + str( tcpDst )
1328 if vlanId:
1329 cmd += " -v " + str( vlanId )
1330 if setVlan:
1331 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001332 if encap:
1333 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001334 if protected:
1335 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001336
kelvin8ec71442015-01-15 16:57:00 -08001337 # Check whether the user appended the port
1338 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001339 if "/" in ingressDevice:
1340 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001341 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001342 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001343 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001344 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001345 # Would it make sense to throw an exception and exit
1346 # the test?
1347 return None
andrewonlab36af3822014-11-18 17:48:18 -05001348
kelvin8ec71442015-01-15 16:57:00 -08001349 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001350 str( ingressDevice ) + "/" +\
1351 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001352
kelvin-onlabd3b64892015-01-20 13:26:24 -08001353 if "/" in egressDevice:
1354 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001355 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001356 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001357 main.log.error( "You must specify the egress port" )
1358 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001359
kelvin8ec71442015-01-15 16:57:00 -08001360 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001361 str( egressDevice ) + "/" +\
1362 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001363
kelvin-onlab898a6c62015-01-16 14:13:53 -08001364 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001365 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001366 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001367 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001368 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001369 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001370 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001371 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001372 # TODO: print out all the options in this message?
1373 main.log.info( "Point-to-point intent installed between " +
1374 str( ingressDevice ) + " and " +
1375 str( egressDevice ) )
1376 match = re.search('id=0x([\da-f]+),', handle)
1377 if match:
1378 return match.group()[3:-1]
1379 else:
1380 main.log.error( "Error, intent ID not found" )
1381 return None
Jon Hallc6793552016-01-19 14:18:37 -08001382 except AssertionError:
1383 main.log.exception( "" )
1384 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001385 except TypeError:
1386 main.log.exception( self.name + ": Object not as expected" )
1387 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001388 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001389 main.log.error( self.name + ": EOF exception found" )
1390 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001391 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001392 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001393 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001394 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001395
kelvin-onlabd3b64892015-01-20 13:26:24 -08001396 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001397 self,
shahshreyac2f97072015-03-19 17:04:29 -07001398 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001399 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001400 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001401 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001402 ethType="",
1403 ethSrc="",
1404 ethDst="",
1405 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001406 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001407 ipProto="",
1408 ipSrc="",
1409 ipDst="",
1410 tcpSrc="",
1411 tcpDst="",
1412 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001413 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001414 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001415 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001416 partial=False,
1417 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001418 """
shahshreyad0c80432014-12-04 16:56:05 -08001419 Note:
shahshreya70622b12015-03-19 17:19:00 -07001420 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001421 is same. That is, all ingress devices include port numbers
1422 with a "/" or all ingress devices could specify device
1423 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001424 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001425 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001426 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001427 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001428 Optional:
1429 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001430 * ethSrc: specify ethSrc ( i.e. src mac addr )
1431 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001432 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001433 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001434 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001435 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001436 * ipSrc: specify ip source address
1437 * ipDst: specify ip destination address
1438 * tcpSrc: specify tcp source port
1439 * tcpDst: specify tcp destination port
1440 * setEthSrc: action to Rewrite Source MAC Address
1441 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001442 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001443 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001444 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001445 Description:
kelvin8ec71442015-01-15 16:57:00 -08001446 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001447 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001448 Returns:
1449 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001450
Jon Halle3f39ff2015-01-13 11:50:53 -08001451 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001452 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001453 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001454 """
shahshreyad0c80432014-12-04 16:56:05 -08001455 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001456 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001457
Jeremy Songsterff553672016-05-12 17:06:23 -07001458 if ethType:
1459 cmd += " --ethType " + str( ethType )
1460 if ethSrc:
1461 cmd += " --ethSrc " + str( ethSrc )
1462 if ethDst:
1463 cmd += " --ethDst " + str( ethDst )
1464 if bandwidth:
1465 cmd += " --bandwidth " + str( bandwidth )
1466 if lambdaAlloc:
1467 cmd += " --lambda "
1468 if ipProto:
1469 cmd += " --ipProto " + str( ipProto )
1470 if ipSrc:
1471 cmd += " --ipSrc " + str( ipSrc )
1472 if ipDst:
1473 cmd += " --ipDst " + str( ipDst )
1474 if tcpSrc:
1475 cmd += " --tcpSrc " + str( tcpSrc )
1476 if tcpDst:
1477 cmd += " --tcpDst " + str( tcpDst )
1478 if setEthSrc:
1479 cmd += " --setEthSrc " + str( setEthSrc )
1480 if setEthDst:
1481 cmd += " --setEthDst " + str( setEthDst )
1482 if vlanId:
1483 cmd += " -v " + str( vlanId )
1484 if setVlan:
1485 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001486 if partial:
1487 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001488 if encap:
1489 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001490
kelvin8ec71442015-01-15 16:57:00 -08001491 # Check whether the user appended the port
1492 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001493
1494 if portIngressList is None:
1495 for ingressDevice in ingressDeviceList:
1496 if "/" in ingressDevice:
1497 cmd += " " + str( ingressDevice )
1498 else:
1499 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001500 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001501 # TODO: perhaps more meaningful return
1502 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001503 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001504 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001505 for ingressDevice, portIngress in zip( ingressDeviceList,
1506 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001507 cmd += " " + \
1508 str( ingressDevice ) + "/" +\
1509 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001510 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001511 main.log.error( "Device list and port list does not " +
1512 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001513 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001514 if "/" in egressDevice:
1515 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001516 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001517 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001518 main.log.error( "You must specify " +
1519 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001520 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001521
kelvin8ec71442015-01-15 16:57:00 -08001522 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001523 str( egressDevice ) + "/" +\
1524 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001525 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001526 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001527 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001528 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001529 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001530 main.log.error( "Error in adding multipoint-to-singlepoint " +
1531 "intent" )
1532 return None
shahshreyad0c80432014-12-04 16:56:05 -08001533 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001534 match = re.search('id=0x([\da-f]+),', handle)
1535 if match:
1536 return match.group()[3:-1]
1537 else:
1538 main.log.error( "Error, intent ID not found" )
1539 return None
Jon Hallc6793552016-01-19 14:18:37 -08001540 except AssertionError:
1541 main.log.exception( "" )
1542 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001543 except TypeError:
1544 main.log.exception( self.name + ": Object not as expected" )
1545 return None
1546 except pexpect.EOF:
1547 main.log.error( self.name + ": EOF exception found" )
1548 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001549 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001550 except Exception:
1551 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001552 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001553
1554 def addSinglepointToMultipointIntent(
1555 self,
1556 ingressDevice,
1557 egressDeviceList,
1558 portIngress="",
1559 portEgressList=None,
1560 ethType="",
1561 ethSrc="",
1562 ethDst="",
1563 bandwidth="",
1564 lambdaAlloc=False,
1565 ipProto="",
1566 ipSrc="",
1567 ipDst="",
1568 tcpSrc="",
1569 tcpDst="",
1570 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001571 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001572 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001573 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001574 partial=False,
1575 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001576 """
1577 Note:
1578 This function assumes the format of all egress devices
1579 is same. That is, all egress devices include port numbers
1580 with a "/" or all egress devices could specify device
1581 ids and port numbers seperately.
1582 Required:
1583 * EgressDeviceList: List of device ids of egress device
1584 ( Atleast 2 eress devices required in the list )
1585 * ingressDevice: device id of ingress device
1586 Optional:
1587 * ethType: specify ethType
1588 * ethSrc: specify ethSrc ( i.e. src mac addr )
1589 * ethDst: specify ethDst ( i.e. dst mac addr )
1590 * bandwidth: specify bandwidth capacity of link
1591 * lambdaAlloc: if True, intent will allocate lambda
1592 for the specified intent
1593 * ipProto: specify ip protocol
1594 * ipSrc: specify ip source address
1595 * ipDst: specify ip destination address
1596 * tcpSrc: specify tcp source port
1597 * tcpDst: specify tcp destination port
1598 * setEthSrc: action to Rewrite Source MAC Address
1599 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001600 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001601 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001602 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001603 Description:
1604 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1605 specifying device id's and optional fields
1606 Returns:
1607 A string of the intent id or None on error
1608
1609 NOTE: This function may change depending on the
1610 options developers provide for singlepoint-to-multipoint
1611 intent via cli
1612 """
1613 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001614 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001615
Jeremy Songsterff553672016-05-12 17:06:23 -07001616 if ethType:
1617 cmd += " --ethType " + str( ethType )
1618 if ethSrc:
1619 cmd += " --ethSrc " + str( ethSrc )
1620 if ethDst:
1621 cmd += " --ethDst " + str( ethDst )
1622 if bandwidth:
1623 cmd += " --bandwidth " + str( bandwidth )
1624 if lambdaAlloc:
1625 cmd += " --lambda "
1626 if ipProto:
1627 cmd += " --ipProto " + str( ipProto )
1628 if ipSrc:
1629 cmd += " --ipSrc " + str( ipSrc )
1630 if ipDst:
1631 cmd += " --ipDst " + str( ipDst )
1632 if tcpSrc:
1633 cmd += " --tcpSrc " + str( tcpSrc )
1634 if tcpDst:
1635 cmd += " --tcpDst " + str( tcpDst )
1636 if setEthSrc:
1637 cmd += " --setEthSrc " + str( setEthSrc )
1638 if setEthDst:
1639 cmd += " --setEthDst " + str( setEthDst )
1640 if vlanId:
1641 cmd += " -v " + str( vlanId )
1642 if setVlan:
1643 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001644 if partial:
1645 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001646 if encap:
1647 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001648
1649 # Check whether the user appended the port
1650 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001651
kelvin-onlabb9408212015-04-01 13:34:04 -07001652 if "/" in ingressDevice:
1653 cmd += " " + str( ingressDevice )
1654 else:
1655 if not portIngress:
1656 main.log.error( "You must specify " +
1657 "the Ingress port" )
1658 return main.FALSE
1659
1660 cmd += " " +\
1661 str( ingressDevice ) + "/" +\
1662 str( portIngress )
1663
1664 if portEgressList is None:
1665 for egressDevice in egressDeviceList:
1666 if "/" in egressDevice:
1667 cmd += " " + str( egressDevice )
1668 else:
1669 main.log.error( "You must specify " +
1670 "the egress port" )
1671 # TODO: perhaps more meaningful return
1672 return main.FALSE
1673 else:
1674 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001675 for egressDevice, portEgress in zip( egressDeviceList,
1676 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001677 cmd += " " + \
1678 str( egressDevice ) + "/" +\
1679 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001680 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001681 main.log.error( "Device list and port list does not " +
1682 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001683 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001684 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001685 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001686 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001687 # If error, return error message
1688 if re.search( "Error", handle ):
1689 main.log.error( "Error in adding singlepoint-to-multipoint " +
1690 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001691 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001692 else:
1693 match = re.search('id=0x([\da-f]+),', handle)
1694 if match:
1695 return match.group()[3:-1]
1696 else:
1697 main.log.error( "Error, intent ID not found" )
1698 return None
Jon Hallc6793552016-01-19 14:18:37 -08001699 except AssertionError:
1700 main.log.exception( "" )
1701 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001702 except TypeError:
1703 main.log.exception( self.name + ": Object not as expected" )
1704 return None
shahshreyad0c80432014-12-04 16:56:05 -08001705 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001706 main.log.error( self.name + ": EOF exception found" )
1707 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001708 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001709 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001710 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001711 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001712
Hari Krishna9e232602015-04-13 17:29:08 -07001713 def addMplsIntent(
1714 self,
1715 ingressDevice,
1716 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001717 ingressPort="",
1718 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001719 ethType="",
1720 ethSrc="",
1721 ethDst="",
1722 bandwidth="",
1723 lambdaAlloc=False,
1724 ipProto="",
1725 ipSrc="",
1726 ipDst="",
1727 tcpSrc="",
1728 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001729 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001730 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001731 priority=""):
1732 """
1733 Required:
1734 * ingressDevice: device id of ingress device
1735 * egressDevice: device id of egress device
1736 Optional:
1737 * ethType: specify ethType
1738 * ethSrc: specify ethSrc ( i.e. src mac addr )
1739 * ethDst: specify ethDst ( i.e. dst mac addr )
1740 * bandwidth: specify bandwidth capacity of link
1741 * lambdaAlloc: if True, intent will allocate lambda
1742 for the specified intent
1743 * ipProto: specify ip protocol
1744 * ipSrc: specify ip source address
1745 * ipDst: specify ip destination address
1746 * tcpSrc: specify tcp source port
1747 * tcpDst: specify tcp destination port
1748 * ingressLabel: Ingress MPLS label
1749 * egressLabel: Egress MPLS label
1750 Description:
1751 Adds MPLS intent by
1752 specifying device id's and optional fields
1753 Returns:
1754 A string of the intent id or None on error
1755
1756 NOTE: This function may change depending on the
1757 options developers provide for MPLS
1758 intent via cli
1759 """
1760 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001761 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001762
Jeremy Songsterff553672016-05-12 17:06:23 -07001763 if ethType:
1764 cmd += " --ethType " + str( ethType )
1765 if ethSrc:
1766 cmd += " --ethSrc " + str( ethSrc )
1767 if ethDst:
1768 cmd += " --ethDst " + str( ethDst )
1769 if bandwidth:
1770 cmd += " --bandwidth " + str( bandwidth )
1771 if lambdaAlloc:
1772 cmd += " --lambda "
1773 if ipProto:
1774 cmd += " --ipProto " + str( ipProto )
1775 if ipSrc:
1776 cmd += " --ipSrc " + str( ipSrc )
1777 if ipDst:
1778 cmd += " --ipDst " + str( ipDst )
1779 if tcpSrc:
1780 cmd += " --tcpSrc " + str( tcpSrc )
1781 if tcpDst:
1782 cmd += " --tcpDst " + str( tcpDst )
1783 if ingressLabel:
1784 cmd += " --ingressLabel " + str( ingressLabel )
1785 if egressLabel:
1786 cmd += " --egressLabel " + str( egressLabel )
1787 if priority:
1788 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001789
1790 # Check whether the user appended the port
1791 # or provided it as an input
1792 if "/" in ingressDevice:
1793 cmd += " " + str( ingressDevice )
1794 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001795 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001796 main.log.error( "You must specify the ingress port" )
1797 return None
1798
1799 cmd += " " + \
1800 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001801 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001802
1803 if "/" in egressDevice:
1804 cmd += " " + str( egressDevice )
1805 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001806 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001807 main.log.error( "You must specify the egress port" )
1808 return None
1809
1810 cmd += " " +\
1811 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001812 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001813
1814 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001815 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001816 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001817 # If error, return error message
1818 if re.search( "Error", handle ):
1819 main.log.error( "Error in adding mpls intent" )
1820 return None
1821 else:
1822 # TODO: print out all the options in this message?
1823 main.log.info( "MPLS intent installed between " +
1824 str( ingressDevice ) + " and " +
1825 str( egressDevice ) )
1826 match = re.search('id=0x([\da-f]+),', handle)
1827 if match:
1828 return match.group()[3:-1]
1829 else:
1830 main.log.error( "Error, intent ID not found" )
1831 return None
Jon Hallc6793552016-01-19 14:18:37 -08001832 except AssertionError:
1833 main.log.exception( "" )
1834 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001835 except TypeError:
1836 main.log.exception( self.name + ": Object not as expected" )
1837 return None
1838 except pexpect.EOF:
1839 main.log.error( self.name + ": EOF exception found" )
1840 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001841 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001842 except Exception:
1843 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001844 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001845
Jon Hallefbd9792015-03-05 16:11:36 -08001846 def removeIntent( self, intentId, app='org.onosproject.cli',
1847 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001848 """
shahshreya1c818fc2015-02-26 13:44:08 -08001849 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001850 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001851 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001852 -p or --purge: Purge the intent from the store after removal
1853
Jon Halle3f39ff2015-01-13 11:50:53 -08001854 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001855 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001856 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001857 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001858 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001859 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001860 if purge:
1861 cmdStr += " -p"
1862 if sync:
1863 cmdStr += " -s"
1864
1865 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001866 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001867 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001868 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001869 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001870 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001871 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001872 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001873 # TODO: Should this be main.TRUE
1874 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001875 except AssertionError:
1876 main.log.exception( "" )
1877 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001878 except TypeError:
1879 main.log.exception( self.name + ": Object not as expected" )
1880 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001881 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001882 main.log.error( self.name + ": EOF exception found" )
1883 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001884 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001885 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001886 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001887 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04001888
YPZhangfebf7302016-05-24 16:45:56 -07001889 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001890 """
1891 Description:
1892 Remove all the intents
1893 Optional args:-
1894 -s or --sync: Waits for the removal before returning
1895 -p or --purge: Purge the intent from the store after removal
1896 Returns:
1897 Returns main.TRUE if all intents are removed, otherwise returns
1898 main.FALSE; Returns None for exception
1899 """
1900 try:
1901 cmdStr = "remove-intent"
1902 if purge:
1903 cmdStr += " -p"
1904 if sync:
1905 cmdStr += " -s"
1906
1907 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001908 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001909 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08001910 assert "Command not found:" not in handle, handle
1911 if re.search( "Error", handle ):
1912 main.log.error( "Error in removing intent" )
1913 return main.FALSE
1914 else:
1915 return main.TRUE
1916 except AssertionError:
1917 main.log.exception( "" )
1918 return None
1919 except TypeError:
1920 main.log.exception( self.name + ": Object not as expected" )
1921 return None
1922 except pexpect.EOF:
1923 main.log.error( self.name + ": EOF exception found" )
1924 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001925 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08001926 except Exception:
1927 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001928 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08001929
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001930 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001931 """
1932 Purges all WITHDRAWN Intents
1933 """
1934 try:
1935 cmdStr = "purge-intents"
1936 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001937 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001938 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001939 if re.search( "Error", handle ):
1940 main.log.error( "Error in purging intents" )
1941 return main.FALSE
1942 else:
1943 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001944 except AssertionError:
1945 main.log.exception( "" )
1946 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001947 except TypeError:
1948 main.log.exception( self.name + ": Object not as expected" )
1949 return None
1950 except pexpect.EOF:
1951 main.log.error( self.name + ": EOF exception found" )
1952 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001953 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07001954 except Exception:
1955 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001956 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07001957
kelvin-onlabd3b64892015-01-20 13:26:24 -08001958 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001959 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001960 NOTE: This method should be used after installing application:
1961 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001962 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001963 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001964 Description:
1965 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001966 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001967 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001968 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001969 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001970 cmdStr += " -j"
1971 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001972 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001973 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001974 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001975 except AssertionError:
1976 main.log.exception( "" )
1977 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001978 except TypeError:
1979 main.log.exception( self.name + ": Object not as expected" )
1980 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001981 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001982 main.log.error( self.name + ": EOF exception found" )
1983 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001984 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001985 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001986 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001987 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08001988
pingping-lin54b03372015-08-13 14:43:10 -07001989 def ipv4RouteNumber( self ):
1990 """
1991 NOTE: This method should be used after installing application:
1992 onos-app-sdnip
1993 Description:
1994 Obtain the total IPv4 routes number in the system
1995 """
1996 try:
Pratik Parab57963572017-05-09 11:37:54 -07001997 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07001998 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001999 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002000 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002001 jsonResult = json.loads( handle )
Pratik Parab57963572017-05-09 11:37:54 -07002002 return len(jsonResult['routes4'])
Jon Hallc6793552016-01-19 14:18:37 -08002003 except AssertionError:
2004 main.log.exception( "" )
2005 return None
2006 except ( TypeError, ValueError ):
2007 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002008 return None
2009 except pexpect.EOF:
2010 main.log.error( self.name + ": EOF exception found" )
2011 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002012 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002013 except Exception:
2014 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002015 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002016
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002017 #=============Function to check Bandwidth allocation========
2018 def allocations( self, jsonFormat = True, dollarSign = True ):
2019 """
2020 Description:
2021 Obtain Bandwidth Allocation Information from ONOS cli.
2022 """
2023 try:
2024 cmdStr = "allocations"
2025 if jsonFormat:
2026 cmdStr += " -j"
2027 handle = self.sendline( cmdStr, timeout=300, dollarSign=True )
2028 assert handle is not None, "Error in sendline"
2029 assert "Command not found:" not in handle, handle
2030 return handle
2031 except AssertionError:
2032 main.log.exception( "" )
2033 return None
2034 except ( TypeError, ValueError ):
2035 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2036 return None
2037 except pexpect.EOF:
2038 main.log.error( self.name + ": EOF exception found" )
2039 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002040 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002041 except Exception:
2042 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002043 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002044
pingping-lin8244a3b2015-09-16 13:36:56 -07002045 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002046 """
andrewonlabe6745342014-10-17 14:29:13 -04002047 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002048 Obtain intents from the ONOS cli.
2049 Optional:
2050 * jsonFormat: Enable output formatting in json, default to True
2051 * summary: Whether only output the intent summary, defaults to False
2052 * type: Only output a certain type of intent. This options is valid
2053 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002054 """
andrewonlabe6745342014-10-17 14:29:13 -04002055 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002056 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002057 if summary:
2058 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002059 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002060 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002061 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002062 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002063 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002064 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002065 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002066 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002067 else:
Jon Hallff566d52016-01-15 14:45:36 -08002068 intentType = ""
2069 # IF we want the summary of a specific intent type
2070 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002071 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002072 if intentType in jsonResult.keys():
2073 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002074 else:
Jon Hallff566d52016-01-15 14:45:36 -08002075 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002076 return handle
2077 else:
2078 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002079 except AssertionError:
2080 main.log.exception( "" )
2081 return None
2082 except ( TypeError, ValueError ):
2083 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002084 return None
2085 except pexpect.EOF:
2086 main.log.error( self.name + ": EOF exception found" )
2087 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002088 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002089 except Exception:
2090 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002091 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002092
kelvin-onlab54400a92015-02-26 18:05:51 -08002093 def getIntentState(self, intentsId, intentsJson=None):
2094 """
You Wangfdcbfc42016-05-16 12:16:53 -07002095 Description:
2096 Gets intent state. Accepts a single intent ID (string type) or a
2097 list of intent IDs.
2098 Parameters:
2099 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002100 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002101 Returns:
2102 Returns the state (string type) of the ID if a single intent ID is
2103 accepted.
2104 Returns a list of dictionaries if a list of intent IDs is accepted,
2105 and each dictionary maps 'id' to the Intent ID and 'state' to
2106 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002107 """
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002108
kelvin-onlab54400a92015-02-26 18:05:51 -08002109 try:
2110 state = "State is Undefined"
2111 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002112 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002113 else:
Jon Hallc6793552016-01-19 14:18:37 -08002114 rawJson = intentsJson
2115 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002116 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002117 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002118 if intentsId == intent[ 'id' ]:
2119 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002120 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002121 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002122 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002123 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002124 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002125 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002126 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002127 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002128 for intent in parsedIntentsJson:
2129 if intentsId[ i ] == intent[ 'id' ]:
2130 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002131 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002132 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002133 break
Jon Hallefbd9792015-03-05 16:11:36 -08002134 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002135 main.log.warn( "Could not find all intents in ONOS output" )
2136 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002137 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002138 else:
Jon Hall53158082017-05-18 11:17:00 -07002139 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002140 return None
Jon Hallc6793552016-01-19 14:18:37 -08002141 except ( TypeError, ValueError ):
2142 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002143 return None
2144 except pexpect.EOF:
2145 main.log.error( self.name + ": EOF exception found" )
2146 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002147 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002148 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002149 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002150 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002151
Jon Hallf539eb92017-05-22 17:18:42 -07002152 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002153 """
2154 Description:
2155 Check intents state
2156 Required:
2157 intentsId - List of intents ID to be checked
2158 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002159 expectedState - Check the expected state(s) of each intents
2160 state in the list.
2161 *NOTE: You can pass in a list of expected state,
2162 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002163 Return:
Jon Hall53158082017-05-18 11:17:00 -07002164 Returns main.TRUE only if all intent are the same as expected states,
2165 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002166 """
2167 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002168 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002169 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002170
2171 #intentsDict = self.getIntentState( intentsId )
2172 intentsDict = []
2173 for intent in json.loads( self.intents() ):
2174 if isinstance ( intentsId, types.StringType) \
2175 and intent.get('id') == intentsId:
2176 intentsDict.append(intent)
2177 elif isinstance ( intentsId, types.ListType ) \
2178 and any( intent.get( 'id' ) == ids for ids in intentsId ):
2179 intentsDict.append(intent)
2180
2181 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002182 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002183 "getting intents state" )
2184 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002185
2186 if isinstance( expectedState, types.StringType ):
2187 for intents in intentsDict:
2188 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002189 main.log.debug( self.name + " : Intent ID - " +
2190 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002191 " actual state = " +
2192 intents.get( 'state' )
2193 + " does not equal expected state = "
2194 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002195 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002196 elif isinstance( expectedState, types.ListType ):
2197 for intents in intentsDict:
2198 if not any( state == intents.get( 'state' ) for state in
2199 expectedState ):
2200 main.log.debug( self.name + " : Intent ID - " +
2201 intents.get( 'id' ) +
2202 " actual state = " +
2203 intents.get( 'state' ) +
2204 " does not equal expected states = "
2205 + str( expectedState ) )
2206 returnValue = main.FALSE
2207
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002208 if returnValue == main.TRUE:
2209 main.log.info( self.name + ": All " +
2210 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002211 " intents are in " + str( expectedState ) +
2212 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002213 return returnValue
2214 except TypeError:
2215 main.log.exception( self.name + ": Object not as expected" )
2216 return None
2217 except pexpect.EOF:
2218 main.log.error( self.name + ": EOF exception found" )
2219 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002220 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002221 except Exception:
2222 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002223 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002224
Jon Hallf539eb92017-05-22 17:18:42 -07002225 def compareBandwidthAllocations( self, expectedAllocations ):
2226 """
2227 Description:
2228 Compare the allocated bandwidth with the given allocations
2229 Required:
2230 expectedAllocations - The expected ONOS output of the allocations command
2231 Return:
2232 Returns main.TRUE only if all intent are the same as expected states,
2233 otherwise returns main.FALSE.
2234 """
2235 # FIXME: Convert these string comparisons to object comparisons
2236 try:
2237 returnValue = main.TRUE
2238 bandwidthFailed = False
2239 rawAlloc = self.allocations()
2240 expectedFormat = StringIO( expectedAllocations )
2241 ONOSOutput = StringIO( rawAlloc )
2242 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2243 str( expectedFormat ) ) )
2244
2245 for actual, expected in izip( ONOSOutput, expectedFormat ):
2246 actual = actual.rstrip()
2247 expected = expected.rstrip()
2248 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2249 if actual != expected and 'allocated' in actual and 'allocated' in expected:
2250 marker1 = actual.find('allocated')
2251 m1 = actual[:marker1]
2252 marker2 = expected.find('allocated')
2253 m2 = expected[:marker2]
2254 if m1 != m2:
2255 bandwidthFailed = True
2256 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2257 bandwidthFailed = True
2258 expectedFormat.close()
2259 ONOSOutput.close()
2260
2261 if bandwidthFailed:
2262 main.log.error("Bandwidth not allocated correctly using Intents!!")
2263 returnValue = main.FALSE
2264 return returnValue
2265 except TypeError:
2266 main.log.exception( self.name + ": Object not as expected" )
2267 return None
2268 except pexpect.EOF:
2269 main.log.error( self.name + ": EOF exception found" )
2270 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002271 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002272 except Exception:
2273 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002274 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002275
You Wang66518af2016-05-16 15:32:59 -07002276 def compareIntent( self, intentDict ):
2277 """
2278 Description:
2279 Compare the intent ids and states provided in the argument with all intents in ONOS
2280 Return:
2281 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2282 Arguments:
2283 intentDict: a dictionary which maps intent ids to intent states
2284 """
2285 try:
2286 intentsRaw = self.intents()
2287 intentsJson = json.loads( intentsRaw )
2288 intentDictONOS = {}
2289 for intent in intentsJson:
2290 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002291 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002292 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002293 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002294 str( len( intentDict ) ) + " expected and " +
2295 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002296 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002297 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002298 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002299 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2300 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002301 else:
2302 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2303 main.log.debug( self.name + ": intent ID - " + intentID +
2304 " expected state is " + intentDict[ intentID ] +
2305 " but actual state is " + intentDictONOS[ intentID ] )
2306 returnValue = main.FALSE
2307 intentDictONOS.pop( intentID )
2308 if len( intentDictONOS ) > 0:
2309 returnValue = main.FALSE
2310 for intentID in intentDictONOS.keys():
2311 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002312 if returnValue == main.TRUE:
2313 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2314 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002315 except KeyError:
2316 main.log.exception( self.name + ": KeyError exception found" )
2317 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002318 except ( TypeError, ValueError ):
2319 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002320 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002321 except pexpect.EOF:
2322 main.log.error( self.name + ": EOF exception found" )
2323 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002324 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002325 except Exception:
2326 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002327 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002328
YPZhang14a4aa92016-07-15 13:37:15 -07002329 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002330 """
2331 Description:
2332 Check the number of installed intents.
2333 Optional:
2334 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002335 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002336 Return:
2337 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2338 , otherwise, returns main.FALSE.
2339 """
2340
2341 try:
2342 cmd = "intents -s -j"
2343
2344 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002345 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002346 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002347 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002348 response = json.loads( response )
2349
2350 # get total and installed number, see if they are match
2351 allState = response.get( 'all' )
2352 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002353 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002354 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002355 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002356 return main.FALSE
2357
Jon Hallc6793552016-01-19 14:18:37 -08002358 except ( TypeError, ValueError ):
2359 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002360 return None
2361 except pexpect.EOF:
2362 main.log.error( self.name + ": EOF exception found" )
2363 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002364 if noExit:
2365 return main.FALSE
2366 else:
Devin Lim44075962017-08-11 10:56:37 -07002367 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002368 except pexpect.TIMEOUT:
2369 main.log.error( self.name + ": ONOS timeout" )
2370 return None
GlennRCed771242016-01-13 17:02:47 -08002371 except Exception:
2372 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002373 if noExit:
2374 return main.FALSE
2375 else:
Devin Lim44075962017-08-11 10:56:37 -07002376 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002377
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002378 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002379 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002380 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002381 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002382 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002383 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002384 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002385 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002386 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002387 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002388 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002389 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002390 if noCore:
2391 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002392 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002393 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002394 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002395 assert "Command not found:" not in handle, handle
2396 if re.search( "Error:", handle ):
2397 main.log.error( self.name + ": flows() response: " +
2398 str( handle ) )
2399 return handle
2400 except AssertionError:
2401 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002402 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002403 except TypeError:
2404 main.log.exception( self.name + ": Object not as expected" )
2405 return None
Jon Hallc6793552016-01-19 14:18:37 -08002406 except pexpect.TIMEOUT:
2407 main.log.error( self.name + ": ONOS timeout" )
2408 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002409 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002410 main.log.error( self.name + ": EOF exception found" )
2411 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002412 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002413 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002414 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002415 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002416
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002417 def checkFlowCount(self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002418 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002419 count = int( count ) if count else 0
2420 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002421
Jon Halle0f0b342017-04-18 11:43:47 -07002422 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002423 """
2424 Description:
GlennRCed771242016-01-13 17:02:47 -08002425 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002426 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2427 if the count of those states is 0, which means all current flows
2428 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002429 Optional:
GlennRCed771242016-01-13 17:02:47 -08002430 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002431 Return:
2432 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002433 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002434 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002435 """
2436 try:
GlennRCed771242016-01-13 17:02:47 -08002437 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2438 checkedStates = []
2439 statesCount = [0, 0, 0, 0]
2440 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002441 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002442 if rawFlows:
2443 # if we didn't get flows or flows function return None, we should return
2444 # main.Flase
2445 checkedStates.append( json.loads( rawFlows ) )
2446 else:
2447 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002448 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002449 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002450 try:
2451 statesCount[i] += int( c.get( "flowCount" ) )
2452 except TypeError:
2453 main.log.exception( "Json object not as expected" )
2454 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002455
GlennRCed771242016-01-13 17:02:47 -08002456 # We want to count PENDING_ADD if isPENDING is true
2457 if isPENDING:
2458 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2459 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002460 else:
GlennRCed771242016-01-13 17:02:47 -08002461 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2462 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002463 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002464 except ( TypeError, ValueError ):
2465 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002466 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002467
YPZhang240842b2016-05-17 12:00:50 -07002468 except AssertionError:
2469 main.log.exception( "" )
2470 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002471 except pexpect.TIMEOUT:
2472 main.log.error( self.name + ": ONOS timeout" )
2473 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002474 except pexpect.EOF:
2475 main.log.error( self.name + ": EOF exception found" )
2476 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002477 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002478 except Exception:
2479 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002480 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002481
GlennRCed771242016-01-13 17:02:47 -08002482 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002483 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002484 """
andrewonlab87852b02014-11-19 18:44:19 -05002485 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002486 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002487 a specific point-to-point intent definition
2488 Required:
GlennRCed771242016-01-13 17:02:47 -08002489 * ingress: specify source dpid
2490 * egress: specify destination dpid
2491 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002492 Optional:
GlennRCed771242016-01-13 17:02:47 -08002493 * offset: the keyOffset is where the next batch of intents
2494 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002495 * noExit: If set to True, TestON will not exit if any error when issus command
2496 * getResponse: If set to True, function will return ONOS response.
2497
GlennRCed771242016-01-13 17:02:47 -08002498 Returns: If failed to push test intents, it will returen None,
2499 if successful, return true.
2500 Timeout expection will return None,
2501 TypeError will return false
2502 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002503 """
andrewonlab87852b02014-11-19 18:44:19 -05002504 try:
GlennRCed771242016-01-13 17:02:47 -08002505 if background:
2506 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002507 else:
GlennRCed771242016-01-13 17:02:47 -08002508 back = ""
2509 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002510 ingress,
2511 egress,
2512 batchSize,
2513 offset,
2514 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002515 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002516 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002517 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002518 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002519 if getResponse:
2520 return response
2521
GlennRCed771242016-01-13 17:02:47 -08002522 # TODO: We should handle if there is failure in installation
2523 return main.TRUE
2524
Jon Hallc6793552016-01-19 14:18:37 -08002525 except AssertionError:
2526 main.log.exception( "" )
2527 return None
GlennRCed771242016-01-13 17:02:47 -08002528 except pexpect.TIMEOUT:
2529 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002530 return None
andrewonlab87852b02014-11-19 18:44:19 -05002531 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002532 main.log.error( self.name + ": EOF exception found" )
2533 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002534 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002535 except TypeError:
2536 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002537 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002538 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002539 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002540 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002541
YPZhangebf9eb52016-05-12 15:20:24 -07002542 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002543 """
2544 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002545 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002546 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002547 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002548 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002549 """
YPZhange3109a72016-02-02 11:25:37 -08002550
YPZhangb5d3f832016-01-23 22:54:26 -08002551 try:
YPZhange3109a72016-02-02 11:25:37 -08002552 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002553 cmd = "flows -c added"
2554 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2555 if rawFlows:
2556 rawFlows = rawFlows.split("\n")
YPZhange3109a72016-02-02 11:25:37 -08002557 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002558 for l in rawFlows:
2559 totalFlows += int(l.split("Count=")[1])
2560 else:
2561 main.log.error("Response not as expected!")
2562 return None
2563 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002564
You Wangd3cb2ce2016-05-16 14:01:24 -07002565 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002566 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002567 return None
2568 except pexpect.EOF:
2569 main.log.error( self.name + ": EOF exception found" )
2570 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002571 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002572 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002573 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002574 except pexpect.TIMEOUT:
2575 main.log.error( self.name + ": ONOS timeout" )
2576 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002577 except Exception:
2578 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002579 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002580 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002581 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002582
YPZhang14a4aa92016-07-15 13:37:15 -07002583 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002584 """
2585 Description:
2586 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002587 Optional:
2588 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002589 Return:
2590 The number of intents
2591 """
2592 try:
2593 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002594 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002595 if response is None:
2596 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002597 response = json.loads( response )
2598 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002599 except ( TypeError, ValueError ):
2600 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002601 return None
2602 except pexpect.EOF:
2603 main.log.error( self.name + ": EOF exception found" )
2604 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002605 if noExit:
2606 return -1
2607 else:
Devin Lim44075962017-08-11 10:56:37 -07002608 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002609 except Exception:
2610 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002611 if noExit:
2612 return -1
2613 else:
Devin Lim44075962017-08-11 10:56:37 -07002614 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002615
kelvin-onlabd3b64892015-01-20 13:26:24 -08002616 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002617 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002618 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002619 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002620 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002621 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002622 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002623 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002624 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002625 cmdStr += " -j"
2626 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002627 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002628 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002629 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002630 except AssertionError:
2631 main.log.exception( "" )
2632 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002633 except TypeError:
2634 main.log.exception( self.name + ": Object not as expected" )
2635 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002636 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002637 main.log.error( self.name + ": EOF exception found" )
2638 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002639 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002640 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002641 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002642 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002643
kelvin-onlabd3b64892015-01-20 13:26:24 -08002644 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002645 """
2646 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002647 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002648 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002649 """
andrewonlab867212a2014-10-22 20:13:38 -04002650 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002651 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002652 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002653 cmdStr += " -j"
2654 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002655 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002656 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002657 if handle:
2658 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002659 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002660 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002661 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002662 else:
2663 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002664 except AssertionError:
2665 main.log.exception( "" )
2666 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002667 except TypeError:
2668 main.log.exception( self.name + ": Object not as expected" )
2669 return None
andrewonlab867212a2014-10-22 20:13:38 -04002670 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002671 main.log.error( self.name + ": EOF exception found" )
2672 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002673 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002674 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002675 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002676 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002677
kelvin8ec71442015-01-15 16:57:00 -08002678 # Wrapper functions ****************
2679 # Wrapper functions use existing driver
2680 # functions and extends their use case.
2681 # For example, we may use the output of
2682 # a normal driver function, and parse it
2683 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002684
kelvin-onlabd3b64892015-01-20 13:26:24 -08002685 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002686 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002687 Description:
2688 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002689 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002690 try:
kelvin8ec71442015-01-15 16:57:00 -08002691 # Obtain output of intents function
Jon Hall6021e062017-01-30 11:10:06 -08002692 intentsStr = self.intents(jsonFormat=True)
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002693 if intentsStr is None:
2694 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002695 # Convert to a dictionary
2696 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002697 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002698 for intent in intents:
2699 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002700 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002701 except TypeError:
2702 main.log.exception( self.name + ": Object not as expected" )
2703 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002704 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002705 main.log.error( self.name + ": EOF exception found" )
2706 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002707 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002708 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002709 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002710 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002711
You Wang3c276252016-09-21 15:21:36 -07002712 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002713 """
2714 Determine the number of flow rules for the given device id that are
2715 in the added state
You Wang3c276252016-09-21 15:21:36 -07002716 Params:
2717 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002718 """
2719 try:
You Wang3c276252016-09-21 15:21:36 -07002720 if core:
2721 cmdStr = "flows any " + str( deviceId ) + " | " +\
2722 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2723 else:
2724 cmdStr = "flows any " + str( deviceId ) + " | " +\
2725 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002726 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002727 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002728 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002729 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002730 except AssertionError:
2731 main.log.exception( "" )
2732 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002733 except pexpect.EOF:
2734 main.log.error( self.name + ": EOF exception found" )
2735 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002736 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002737 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002738 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002739 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002740
kelvin-onlabd3b64892015-01-20 13:26:24 -08002741 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002742 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002743 Use 'devices' function to obtain list of all devices
2744 and parse the result to obtain a list of all device
2745 id's. Returns this list. Returns empty list if no
2746 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002747 List is ordered sequentially
2748
andrewonlab3e15ead2014-10-15 14:21:34 -04002749 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002750 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002751 the ids. By obtaining the list of device ids on the fly,
2752 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002753 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002754 try:
kelvin8ec71442015-01-15 16:57:00 -08002755 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002756 devicesStr = self.devices( jsonFormat=False )
2757 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002758
kelvin-onlabd3b64892015-01-20 13:26:24 -08002759 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002760 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002761 return idList
kelvin8ec71442015-01-15 16:57:00 -08002762
2763 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002764 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002765 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002766 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002767 # Split list further into arguments before and after string
2768 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002769 # append to idList
2770 for arg in tempList:
2771 idList.append( arg.split( "id=" )[ 1 ] )
2772 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002773
Jon Halld4d4b372015-01-28 16:02:41 -08002774 except TypeError:
2775 main.log.exception( self.name + ": Object not as expected" )
2776 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002777 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002778 main.log.error( self.name + ": EOF exception found" )
2779 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002780 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002781 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002782 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002783 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002784
kelvin-onlabd3b64892015-01-20 13:26:24 -08002785 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002786 """
andrewonlab7c211572014-10-15 16:45:20 -04002787 Uses 'nodes' function to obtain list of all nodes
2788 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002789 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002790 Returns:
2791 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002792 """
andrewonlab7c211572014-10-15 16:45:20 -04002793 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002794 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002795 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002796 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002797 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002798 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002799 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002800 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002801 nodesJson = json.loads( nodesStr )
2802 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002803 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002804 except ( TypeError, ValueError ):
2805 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002806 return None
andrewonlab7c211572014-10-15 16:45:20 -04002807 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002808 main.log.error( self.name + ": EOF exception found" )
2809 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002810 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002811 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002812 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002813 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002814
kelvin-onlabd3b64892015-01-20 13:26:24 -08002815 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002816 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002817 Return the first device from the devices api whose 'id' contains 'dpid'
2818 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002819 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002820 try:
kelvin8ec71442015-01-15 16:57:00 -08002821 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002822 return None
2823 else:
kelvin8ec71442015-01-15 16:57:00 -08002824 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002825 rawDevices = self.devices()
2826 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002827 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002828 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002829 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2830 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002831 return device
2832 return None
Jon Hallc6793552016-01-19 14:18:37 -08002833 except ( TypeError, ValueError ):
2834 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002835 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002836 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002837 main.log.error( self.name + ": EOF exception found" )
2838 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002839 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002840 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002841 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002842 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04002843
You Wang24139872016-05-03 11:48:47 -07002844 def getTopology( self, topologyOutput ):
2845 """
2846 Definition:
2847 Loads a json topology output
2848 Return:
2849 topology = current ONOS topology
2850 """
2851 import json
2852 try:
2853 # either onos:topology or 'topology' will work in CLI
2854 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002855 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002856 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002857 except ( TypeError, ValueError ):
2858 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2859 return None
You Wang24139872016-05-03 11:48:47 -07002860 except pexpect.EOF:
2861 main.log.error( self.name + ": EOF exception found" )
2862 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002863 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07002864 except Exception:
2865 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002866 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07002867
Flavio Castro82ee2f62016-06-07 15:04:12 -07002868 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002869 """
Jon Hallefbd9792015-03-05 16:11:36 -08002870 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002871 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002872 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002873
Flavio Castro82ee2f62016-06-07 15:04:12 -07002874 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002875 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002876 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002877 logLevel = level to log to.
2878 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002879
Jon Hallefbd9792015-03-05 16:11:36 -08002880 Returns: main.TRUE if the number of switches and links are correct,
2881 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002882 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002883 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002884 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002885 try:
You Wang13310252016-07-31 10:56:14 -07002886 summary = self.summary()
2887 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002888 except ( TypeError, ValueError ):
2889 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2890 return main.ERROR
2891 try:
2892 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07002893 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002894 return main.ERROR
2895 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002896 # Is the number of switches is what we expected
2897 devices = topology.get( 'devices', False )
2898 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002899 nodes = summary.get( 'nodes', False )
2900 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002901 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002902 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002903 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002904 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002905 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2906 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002907 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002908 output = output + "The number of links and switches match "\
2909 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002910 result = main.TRUE
2911 else:
You Wang24139872016-05-03 11:48:47 -07002912 output = output + \
2913 "The number of links and switches does not match " + \
2914 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002915 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002916 output = output + "\n ONOS sees %i devices" % int( devices )
2917 output = output + " (%i expected) " % int( numoswitch )
2918 output = output + "and %i links " % int( links )
2919 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002920 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002921 output = output + "and %i controllers " % int( nodes )
2922 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002923 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002924 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002925 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002926 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002927 else:
You Wang24139872016-05-03 11:48:47 -07002928 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002929 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002930 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002931 main.log.error( self.name + ": EOF exception found" )
2932 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002933 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002934 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002935 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002936 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002937
kelvin-onlabd3b64892015-01-20 13:26:24 -08002938 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002939 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002940 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002941 deviceId must be the id of a device as seen in the onos devices command
2942 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002943 role must be either master, standby, or none
2944
Jon Halle3f39ff2015-01-13 11:50:53 -08002945 Returns:
2946 main.TRUE or main.FALSE based on argument verification and
2947 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002948 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002949 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002950 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002951 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002952 cmdStr = "device-role " +\
2953 str( deviceId ) + " " +\
2954 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002955 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002956 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002957 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002958 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002959 if re.search( "Error", handle ):
2960 # end color output to escape any colours
2961 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002962 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002963 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002964 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002965 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002966 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002967 main.log.error( "Invalid 'role' given to device_role(). " +
2968 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002969 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002970 except AssertionError:
2971 main.log.exception( "" )
2972 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002973 except TypeError:
2974 main.log.exception( self.name + ": Object not as expected" )
2975 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002976 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002977 main.log.error( self.name + ": EOF exception found" )
2978 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002979 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002980 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002981 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002982 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002983
kelvin-onlabd3b64892015-01-20 13:26:24 -08002984 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002985 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002986 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002987 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002988 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002989 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002990 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002991 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002992 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002993 cmdStr += " -j"
2994 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002995 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002996 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002997 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002998 except AssertionError:
2999 main.log.exception( "" )
3000 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003001 except TypeError:
3002 main.log.exception( self.name + ": Object not as expected" )
3003 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003004 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003005 main.log.error( self.name + ": EOF exception found" )
3006 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003007 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003008 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003009 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003010 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003011
kelvin-onlabd3b64892015-01-20 13:26:24 -08003012 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003013 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003014 CLI command to get the current leader for the Election test application
3015 NOTE: Requires installation of the onos-app-election feature
3016 Returns: Node IP of the leader if one exists
3017 None if none exists
3018 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003019 """
Jon Hall94fd0472014-12-08 11:52:42 -08003020 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003021 cmdStr = "election-test-leader"
3022 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003023 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003024 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003025 # Leader
3026 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003027 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003028 nodeSearch = re.search( leaderPattern, response )
3029 if nodeSearch:
3030 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003031 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003032 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003033 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003034 # no leader
3035 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003036 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003037 nullSearch = re.search( nullPattern, response )
3038 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003039 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003040 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003041 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003042 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003043 main.log.error( "Error in electionTestLeader on " + self.name +
3044 ": " + "unexpected response" )
3045 main.log.error( repr( response ) )
3046 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003047 except AssertionError:
3048 main.log.exception( "" )
3049 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003050 except TypeError:
3051 main.log.exception( self.name + ": Object not as expected" )
3052 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003053 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003054 main.log.error( self.name + ": EOF exception found" )
3055 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003056 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003057 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003058 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003059 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003060
kelvin-onlabd3b64892015-01-20 13:26:24 -08003061 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003062 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003063 CLI command to run for leadership of the Election test application.
3064 NOTE: Requires installation of the onos-app-election feature
3065 Returns: Main.TRUE on success
3066 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003067 """
Jon Hall94fd0472014-12-08 11:52:42 -08003068 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003069 cmdStr = "election-test-run"
3070 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003071 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003072 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003073 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003074 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003075 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003076 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003077 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003078 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003079 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003080 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003081 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003082 main.log.error( "Error in electionTestRun on " + self.name +
3083 ": " + "unexpected response" )
3084 main.log.error( repr( response ) )
3085 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003086 except AssertionError:
3087 main.log.exception( "" )
3088 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003089 except TypeError:
3090 main.log.exception( self.name + ": Object not as expected" )
3091 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003092 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003093 main.log.error( self.name + ": EOF exception found" )
3094 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003095 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003096 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003097 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003098 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003099
kelvin-onlabd3b64892015-01-20 13:26:24 -08003100 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003101 """
Jon Hall94fd0472014-12-08 11:52:42 -08003102 * CLI command to withdraw the local node from leadership election for
3103 * the Election test application.
3104 #NOTE: Requires installation of the onos-app-election feature
3105 Returns: Main.TRUE on success
3106 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003107 """
Jon Hall94fd0472014-12-08 11:52:42 -08003108 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003109 cmdStr = "election-test-withdraw"
3110 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003111 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003112 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003113 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003114 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003115 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003116 if re.search( successPattern, response ):
3117 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003118 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003119 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003120 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003121 main.log.error( "Error in electionTestWithdraw on " +
3122 self.name + ": " + "unexpected response" )
3123 main.log.error( repr( response ) )
3124 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003125 except AssertionError:
3126 main.log.exception( "" )
3127 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003128 except TypeError:
3129 main.log.exception( self.name + ": Object not as expected" )
3130 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003131 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003132 main.log.error( self.name + ": EOF exception found" )
3133 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003134 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003135 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003136 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003137 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003138
kelvin8ec71442015-01-15 16:57:00 -08003139 def getDevicePortsEnabledCount( self, dpid ):
3140 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003141 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003142 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003143 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003144 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003145 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3146 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003147 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003148 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003149 if re.search( "No such device", output ):
3150 main.log.error( "Error in getting ports" )
3151 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003152 return output
Jon Hallc6793552016-01-19 14:18:37 -08003153 except AssertionError:
3154 main.log.exception( "" )
3155 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003156 except TypeError:
3157 main.log.exception( self.name + ": Object not as expected" )
3158 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003159 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003160 main.log.error( self.name + ": EOF exception found" )
3161 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003162 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003163 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003164 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003165 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003166
kelvin8ec71442015-01-15 16:57:00 -08003167 def getDeviceLinksActiveCount( self, dpid ):
3168 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003169 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003170 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003171 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003172 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003173 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3174 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003175 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003176 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003177 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003178 main.log.error( "Error in getting ports " )
3179 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003180 return output
Jon Hallc6793552016-01-19 14:18:37 -08003181 except AssertionError:
3182 main.log.exception( "" )
3183 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003184 except TypeError:
3185 main.log.exception( self.name + ": Object not as expected" )
3186 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003187 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003188 main.log.error( self.name + ": EOF exception found" )
3189 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003190 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003191 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003192 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003193 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003194
kelvin8ec71442015-01-15 16:57:00 -08003195 def getAllIntentIds( self ):
3196 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003197 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003198 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003199 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003200 cmdStr = "onos:intents | grep id="
3201 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003202 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003203 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003204 if re.search( "Error", output ):
3205 main.log.error( "Error in getting ports" )
3206 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003207 return output
Jon Hallc6793552016-01-19 14:18:37 -08003208 except AssertionError:
3209 main.log.exception( "" )
3210 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003211 except TypeError:
3212 main.log.exception( self.name + ": Object not as expected" )
3213 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003214 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003215 main.log.error( self.name + ": EOF exception found" )
3216 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003217 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003218 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003219 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003220 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003221
Jon Hall73509952015-02-24 16:42:56 -08003222 def intentSummary( self ):
3223 """
Jon Hallefbd9792015-03-05 16:11:36 -08003224 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003225 """
3226 try:
3227 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003228 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003229 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003230 states.append( intent.get( 'state', None ) )
3231 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003232 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003233 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003234 except ( TypeError, ValueError ):
3235 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003236 return None
3237 except pexpect.EOF:
3238 main.log.error( self.name + ": EOF exception found" )
3239 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003240 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003241 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003242 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003243 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003244
Jon Hall61282e32015-03-19 11:34:11 -07003245 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003246 """
3247 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003248 Optional argument:
3249 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003250 """
Jon Hall63604932015-02-26 17:09:50 -08003251 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003252 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003253 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003254 cmdStr += " -j"
3255 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003256 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003257 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003258 return output
Jon Hallc6793552016-01-19 14:18:37 -08003259 except AssertionError:
3260 main.log.exception( "" )
3261 return None
Jon Hall63604932015-02-26 17:09:50 -08003262 except TypeError:
3263 main.log.exception( self.name + ": Object not as expected" )
3264 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003265 except pexpect.EOF:
3266 main.log.error( self.name + ": EOF exception found" )
3267 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003268 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003269 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003270 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003271 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003272
acsmarsa4a4d1e2015-07-10 16:01:24 -07003273 def leaderCandidates( self, jsonFormat=True ):
3274 """
3275 Returns the output of the leaders -c command.
3276 Optional argument:
3277 * jsonFormat - boolean indicating if you want output in json
3278 """
3279 try:
3280 cmdStr = "onos:leaders -c"
3281 if jsonFormat:
3282 cmdStr += " -j"
3283 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003284 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003285 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003286 return output
Jon Hallc6793552016-01-19 14:18:37 -08003287 except AssertionError:
3288 main.log.exception( "" )
3289 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003290 except TypeError:
3291 main.log.exception( self.name + ": Object not as expected" )
3292 return None
3293 except pexpect.EOF:
3294 main.log.error( self.name + ": EOF exception found" )
3295 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003296 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003297 except Exception:
3298 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003299 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003300
Jon Hallc6793552016-01-19 14:18:37 -08003301 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003302 """
3303 Returns a list in format [leader,candidate1,candidate2,...] for a given
3304 topic parameter and an empty list if the topic doesn't exist
3305 If no leader is elected leader in the returned list will be "none"
3306 Returns None if there is a type error processing the json object
3307 """
3308 try:
Jon Hall6e709752016-02-01 13:38:46 -08003309 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003310 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003311 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003312 assert "Command not found:" not in rawOutput, rawOutput
3313 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003314 results = []
3315 for dict in output:
3316 if dict["topic"] == topic:
3317 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003318 candidates = re.split( ", ", dict["candidates"][1:-1] )
3319 results.append( leader )
3320 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003321 return results
Jon Hallc6793552016-01-19 14:18:37 -08003322 except AssertionError:
3323 main.log.exception( "" )
3324 return None
3325 except ( TypeError, ValueError ):
3326 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003327 return None
3328 except pexpect.EOF:
3329 main.log.error( self.name + ": EOF exception found" )
3330 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003331 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003332 except Exception:
3333 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003334 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003335
Jon Hall61282e32015-03-19 11:34:11 -07003336 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003337 """
3338 Returns the output of the intent Pending map.
3339 """
Jon Hall63604932015-02-26 17:09:50 -08003340 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003341 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003342 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003343 cmdStr += " -j"
3344 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003345 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003346 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003347 return output
Jon Hallc6793552016-01-19 14:18:37 -08003348 except AssertionError:
3349 main.log.exception( "" )
3350 return None
Jon Hall63604932015-02-26 17:09:50 -08003351 except TypeError:
3352 main.log.exception( self.name + ": Object not as expected" )
3353 return None
3354 except pexpect.EOF:
3355 main.log.error( self.name + ": EOF exception found" )
3356 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003357 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003358 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003359 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003360 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003361
Jon Hall2c8959e2016-12-16 12:17:34 -08003362 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003363 """
3364 Returns the output of the raft partitions command for ONOS.
3365 """
Jon Hall61282e32015-03-19 11:34:11 -07003366 # Sample JSON
3367 # {
3368 # "leader": "tcp://10.128.30.11:7238",
3369 # "members": [
3370 # "tcp://10.128.30.11:7238",
3371 # "tcp://10.128.30.17:7238",
3372 # "tcp://10.128.30.13:7238",
3373 # ],
3374 # "name": "p1",
3375 # "term": 3
3376 # },
Jon Hall63604932015-02-26 17:09:50 -08003377 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003378 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003379 if candidates:
3380 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003381 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003382 cmdStr += " -j"
3383 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003384 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003385 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003386 return output
Jon Hallc6793552016-01-19 14:18:37 -08003387 except AssertionError:
3388 main.log.exception( "" )
3389 return None
Jon Hall63604932015-02-26 17:09:50 -08003390 except TypeError:
3391 main.log.exception( self.name + ": Object not as expected" )
3392 return None
3393 except pexpect.EOF:
3394 main.log.error( self.name + ": EOF exception found" )
3395 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003396 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003397 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003398 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003399 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003400
Jon Halle9f909e2016-09-23 10:43:12 -07003401 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003402 """
3403 Returns the output of the apps command for ONOS. This command lists
3404 information about installed ONOS applications
3405 """
3406 # Sample JSON object
3407 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3408 # "description":"ONOS OpenFlow protocol southbound providers",
3409 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3410 # "features":"[onos-openflow]","state":"ACTIVE"}]
3411 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003412 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003413 if summary:
3414 cmdStr += " -s"
3415 if active:
3416 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003417 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003418 cmdStr += " -j"
3419 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003420 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003421 assert "Command not found:" not in output, output
3422 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003423 return output
Jon Hallbe379602015-03-24 13:39:32 -07003424 # FIXME: look at specific exceptions/Errors
3425 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003426 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003427 return None
3428 except TypeError:
3429 main.log.exception( self.name + ": Object not as expected" )
3430 return None
3431 except pexpect.EOF:
3432 main.log.error( self.name + ": EOF exception found" )
3433 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003434 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003435 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003436 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003437 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003438
Jon Hall146f1522015-03-24 15:33:24 -07003439 def appStatus( self, appName ):
3440 """
3441 Uses the onos:apps cli command to return the status of an application.
3442 Returns:
3443 "ACTIVE" - If app is installed and activated
3444 "INSTALLED" - If app is installed and deactivated
3445 "UNINSTALLED" - If app is not installed
3446 None - on error
3447 """
Jon Hall146f1522015-03-24 15:33:24 -07003448 try:
3449 if not isinstance( appName, types.StringType ):
3450 main.log.error( self.name + ".appStatus(): appName must be" +
3451 " a string" )
3452 return None
3453 output = self.apps( jsonFormat=True )
3454 appsJson = json.loads( output )
3455 state = None
3456 for app in appsJson:
3457 if appName == app.get('name'):
3458 state = app.get('state')
3459 break
3460 if state == "ACTIVE" or state == "INSTALLED":
3461 return state
3462 elif state is None:
3463 return "UNINSTALLED"
3464 elif state:
3465 main.log.error( "Unexpected state from 'onos:apps': " +
3466 str( state ) )
3467 return state
Jon Hallc6793552016-01-19 14:18:37 -08003468 except ( TypeError, ValueError ):
3469 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003470 return None
3471 except pexpect.EOF:
3472 main.log.error( self.name + ": EOF exception found" )
3473 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003474 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003475 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003476 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003477 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003478
Jon Hallbe379602015-03-24 13:39:32 -07003479 def app( self, appName, option ):
3480 """
3481 Interacts with the app command for ONOS. This command manages
3482 application inventory.
3483 """
Jon Hallbe379602015-03-24 13:39:32 -07003484 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003485 # Validate argument types
3486 valid = True
3487 if not isinstance( appName, types.StringType ):
3488 main.log.error( self.name + ".app(): appName must be a " +
3489 "string" )
3490 valid = False
3491 if not isinstance( option, types.StringType ):
3492 main.log.error( self.name + ".app(): option must be a string" )
3493 valid = False
3494 if not valid:
3495 return main.FALSE
3496 # Validate Option
3497 option = option.lower()
3498 # NOTE: Install may become a valid option
3499 if option == "activate":
3500 pass
3501 elif option == "deactivate":
3502 pass
3503 elif option == "uninstall":
3504 pass
3505 else:
3506 # Invalid option
3507 main.log.error( "The ONOS app command argument only takes " +
3508 "the values: (activate|deactivate|uninstall)" +
3509 "; was given '" + option + "'")
3510 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003511 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003512 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003513 assert output is not None, "Error in sendline"
3514 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003515 if "Error executing command" in output:
3516 main.log.error( "Error in processing onos:app command: " +
3517 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003518 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003519 elif "No such application" in output:
3520 main.log.error( "The application '" + appName +
3521 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003522 return main.FALSE
3523 elif "Command not found:" in output:
3524 main.log.error( "Error in processing onos:app command: " +
3525 str( output ) )
3526 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003527 elif "Unsupported command:" in output:
3528 main.log.error( "Incorrect command given to 'app': " +
3529 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003530 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003531 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003532 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003533 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003534 except AssertionError:
3535 main.log.exception( self.name + ": AssertionError exception found" )
3536 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003537 except TypeError:
3538 main.log.exception( self.name + ": Object not as expected" )
3539 return main.ERROR
3540 except pexpect.EOF:
3541 main.log.error( self.name + ": EOF exception found" )
3542 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003543 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003544 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003545 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003546 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003547
Jon Hallbd16b922015-03-26 17:53:15 -07003548 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003549 """
3550 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003551 appName is the hierarchical app name, not the feature name
3552 If check is True, method will check the status of the app after the
3553 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003554 Returns main.TRUE if the command was successfully sent
3555 main.FALSE if the cli responded with an error or given
3556 incorrect input
3557 """
3558 try:
3559 if not isinstance( appName, types.StringType ):
3560 main.log.error( self.name + ".activateApp(): appName must be" +
3561 " a string" )
3562 return main.FALSE
3563 status = self.appStatus( appName )
3564 if status == "INSTALLED":
3565 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003566 if check and response == main.TRUE:
3567 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003568 status = self.appStatus( appName )
3569 if status == "ACTIVE":
3570 return main.TRUE
3571 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003572 main.log.debug( "The state of application " +
3573 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003574 time.sleep( 1 )
3575 return main.FALSE
3576 else: # not 'check' or command didn't succeed
3577 return response
Jon Hall146f1522015-03-24 15:33:24 -07003578 elif status == "ACTIVE":
3579 return main.TRUE
3580 elif status == "UNINSTALLED":
3581 main.log.error( self.name + ": Tried to activate the " +
3582 "application '" + appName + "' which is not " +
3583 "installed." )
3584 else:
3585 main.log.error( "Unexpected return value from appStatus: " +
3586 str( status ) )
3587 return main.ERROR
3588 except TypeError:
3589 main.log.exception( self.name + ": Object not as expected" )
3590 return main.ERROR
3591 except pexpect.EOF:
3592 main.log.error( self.name + ": EOF exception found" )
3593 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003594 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003595 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003596 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003597 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003598
Jon Hallbd16b922015-03-26 17:53:15 -07003599 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003600 """
3601 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003602 appName is the hierarchical app name, not the feature name
3603 If check is True, method will check the status of the app after the
3604 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003605 Returns main.TRUE if the command was successfully sent
3606 main.FALSE if the cli responded with an error or given
3607 incorrect input
3608 """
3609 try:
3610 if not isinstance( appName, types.StringType ):
3611 main.log.error( self.name + ".deactivateApp(): appName must " +
3612 "be a string" )
3613 return main.FALSE
3614 status = self.appStatus( appName )
3615 if status == "INSTALLED":
3616 return main.TRUE
3617 elif status == "ACTIVE":
3618 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003619 if check and response == main.TRUE:
3620 for i in range(10): # try 10 times then give up
3621 status = self.appStatus( appName )
3622 if status == "INSTALLED":
3623 return main.TRUE
3624 else:
3625 time.sleep( 1 )
3626 return main.FALSE
3627 else: # not check or command didn't succeed
3628 return response
Jon Hall146f1522015-03-24 15:33:24 -07003629 elif status == "UNINSTALLED":
3630 main.log.warn( self.name + ": Tried to deactivate the " +
3631 "application '" + appName + "' which is not " +
3632 "installed." )
3633 return main.TRUE
3634 else:
3635 main.log.error( "Unexpected return value from appStatus: " +
3636 str( status ) )
3637 return main.ERROR
3638 except TypeError:
3639 main.log.exception( self.name + ": Object not as expected" )
3640 return main.ERROR
3641 except pexpect.EOF:
3642 main.log.error( self.name + ": EOF exception found" )
3643 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003644 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003645 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003646 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003647 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003648
Jon Hallbd16b922015-03-26 17:53:15 -07003649 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003650 """
3651 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003652 appName is the hierarchical app name, not the feature name
3653 If check is True, method will check the status of the app after the
3654 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003655 Returns main.TRUE if the command was successfully sent
3656 main.FALSE if the cli responded with an error or given
3657 incorrect input
3658 """
3659 # TODO: check with Thomas about the state machine for apps
3660 try:
3661 if not isinstance( appName, types.StringType ):
3662 main.log.error( self.name + ".uninstallApp(): appName must " +
3663 "be a string" )
3664 return main.FALSE
3665 status = self.appStatus( appName )
3666 if status == "INSTALLED":
3667 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003668 if check and response == main.TRUE:
3669 for i in range(10): # try 10 times then give up
3670 status = self.appStatus( appName )
3671 if status == "UNINSTALLED":
3672 return main.TRUE
3673 else:
3674 time.sleep( 1 )
3675 return main.FALSE
3676 else: # not check or command didn't succeed
3677 return response
Jon Hall146f1522015-03-24 15:33:24 -07003678 elif status == "ACTIVE":
3679 main.log.warn( self.name + ": Tried to uninstall the " +
3680 "application '" + appName + "' which is " +
3681 "currently active." )
3682 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003683 if check and response == main.TRUE:
3684 for i in range(10): # try 10 times then give up
3685 status = self.appStatus( appName )
3686 if status == "UNINSTALLED":
3687 return main.TRUE
3688 else:
3689 time.sleep( 1 )
3690 return main.FALSE
3691 else: # not check or command didn't succeed
3692 return response
Jon Hall146f1522015-03-24 15:33:24 -07003693 elif status == "UNINSTALLED":
3694 return main.TRUE
3695 else:
3696 main.log.error( "Unexpected return value from appStatus: " +
3697 str( status ) )
3698 return main.ERROR
3699 except TypeError:
3700 main.log.exception( self.name + ": Object not as expected" )
3701 return main.ERROR
3702 except pexpect.EOF:
3703 main.log.error( self.name + ": EOF exception found" )
3704 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003705 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003706 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003707 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003708 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003709
3710 def appIDs( self, jsonFormat=True ):
3711 """
3712 Show the mappings between app id and app names given by the 'app-ids'
3713 cli command
3714 """
3715 try:
3716 cmdStr = "app-ids"
3717 if jsonFormat:
3718 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003719 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003720 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003721 assert "Command not found:" not in output, output
3722 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003723 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003724 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003725 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003726 return None
3727 except TypeError:
3728 main.log.exception( self.name + ": Object not as expected" )
3729 return None
3730 except pexpect.EOF:
3731 main.log.error( self.name + ": EOF exception found" )
3732 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003733 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003734 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003735 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003736 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003737
3738 def appToIDCheck( self ):
3739 """
3740 This method will check that each application's ID listed in 'apps' is
3741 the same as the ID listed in 'app-ids'. The check will also check that
3742 there are no duplicate IDs issued. Note that an app ID should be
3743 a globaly unique numerical identifier for app/app-like features. Once
3744 an ID is registered, the ID is never freed up so that if an app is
3745 reinstalled it will have the same ID.
3746
3747 Returns: main.TRUE if the check passes and
3748 main.FALSE if the check fails or
3749 main.ERROR if there is some error in processing the test
3750 """
3751 try:
Jon Hall390696c2015-05-05 17:13:41 -07003752 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003753 rawJson = self.appIDs( jsonFormat=True )
3754 if rawJson:
3755 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003756 else:
Jon Hallc6793552016-01-19 14:18:37 -08003757 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003758 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003759 rawJson = self.apps( jsonFormat=True )
3760 if rawJson:
3761 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003762 else:
Jon Hallc6793552016-01-19 14:18:37 -08003763 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003764 bail = True
3765 if bail:
3766 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003767 result = main.TRUE
3768 for app in apps:
3769 appID = app.get( 'id' )
3770 if appID is None:
3771 main.log.error( "Error parsing app: " + str( app ) )
3772 result = main.FALSE
3773 appName = app.get( 'name' )
3774 if appName is None:
3775 main.log.error( "Error parsing app: " + str( app ) )
3776 result = main.FALSE
3777 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003778 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003779 # main.log.debug( "Comparing " + str( app ) + " to " +
3780 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003781 if not current: # if ids doesn't have this id
3782 result = main.FALSE
3783 main.log.error( "'app-ids' does not have the ID for " +
3784 str( appName ) + " that apps does." )
3785 elif len( current ) > 1:
3786 # there is more than one app with this ID
3787 result = main.FALSE
3788 # We will log this later in the method
3789 elif not current[0][ 'name' ] == appName:
3790 currentName = current[0][ 'name' ]
3791 result = main.FALSE
3792 main.log.error( "'app-ids' has " + str( currentName ) +
3793 " registered under id:" + str( appID ) +
3794 " but 'apps' has " + str( appName ) )
3795 else:
3796 pass # id and name match!
3797 # now make sure that app-ids has no duplicates
3798 idsList = []
3799 namesList = []
3800 for item in ids:
3801 idsList.append( item[ 'id' ] )
3802 namesList.append( item[ 'name' ] )
3803 if len( idsList ) != len( set( idsList ) ) or\
3804 len( namesList ) != len( set( namesList ) ):
3805 main.log.error( "'app-ids' has some duplicate entries: \n"
3806 + json.dumps( ids,
3807 sort_keys=True,
3808 indent=4,
3809 separators=( ',', ': ' ) ) )
3810 result = main.FALSE
3811 return result
Jon Hallc6793552016-01-19 14:18:37 -08003812 except ( TypeError, ValueError ):
3813 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003814 return main.ERROR
3815 except pexpect.EOF:
3816 main.log.error( self.name + ": EOF exception found" )
3817 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003818 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003819 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003820 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003821 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003822
Jon Hallfb760a02015-04-13 15:35:03 -07003823 def getCfg( self, component=None, propName=None, short=False,
3824 jsonFormat=True ):
3825 """
3826 Get configuration settings from onos cli
3827 Optional arguments:
3828 component - Optionally only list configurations for a specific
3829 component. If None, all components with configurations
3830 are displayed. Case Sensitive string.
3831 propName - If component is specified, propName option will show
3832 only this specific configuration from that component.
3833 Case Sensitive string.
3834 jsonFormat - Returns output as json. Note that this will override
3835 the short option
3836 short - Short, less verbose, version of configurations.
3837 This is overridden by the json option
3838 returns:
3839 Output from cli as a string or None on error
3840 """
3841 try:
3842 baseStr = "cfg"
3843 cmdStr = " get"
3844 componentStr = ""
3845 if component:
3846 componentStr += " " + component
3847 if propName:
3848 componentStr += " " + propName
3849 if jsonFormat:
3850 baseStr += " -j"
3851 elif short:
3852 baseStr += " -s"
3853 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003854 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003855 assert "Command not found:" not in output, output
3856 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003857 return output
3858 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003859 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003860 return None
3861 except TypeError:
3862 main.log.exception( self.name + ": Object not as expected" )
3863 return None
3864 except pexpect.EOF:
3865 main.log.error( self.name + ": EOF exception found" )
3866 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003867 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003868 except Exception:
3869 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003870 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003871
3872 def setCfg( self, component, propName, value=None, check=True ):
3873 """
3874 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003875 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003876 component - The case sensitive name of the component whose
3877 property is to be set
3878 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003879 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003880 value - The value to set the property to. If None, will unset the
3881 property and revert it to it's default value(if applicable)
3882 check - Boolean, Check whether the option was successfully set this
3883 only applies when a value is given.
3884 returns:
3885 main.TRUE on success or main.FALSE on failure. If check is False,
3886 will return main.TRUE unless there is an error
3887 """
3888 try:
3889 baseStr = "cfg"
3890 cmdStr = " set " + str( component ) + " " + str( propName )
3891 if value is not None:
3892 cmdStr += " " + str( value )
3893 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003894 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003895 assert "Command not found:" not in output, output
3896 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003897 if value and check:
3898 results = self.getCfg( component=str( component ),
3899 propName=str( propName ),
3900 jsonFormat=True )
3901 # Check if current value is what we just set
3902 try:
3903 jsonOutput = json.loads( results )
3904 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003905 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003906 main.log.exception( "Error parsing cfg output" )
3907 main.log.error( "output:" + repr( results ) )
3908 return main.FALSE
3909 if current == str( value ):
3910 return main.TRUE
3911 return main.FALSE
3912 return main.TRUE
3913 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003914 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003915 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003916 except ( TypeError, ValueError ):
3917 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003918 return main.FALSE
3919 except pexpect.EOF:
3920 main.log.error( self.name + ": EOF exception found" )
3921 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003922 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003923 except Exception:
3924 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003925 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003926
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003927 def distPrimitivesSend( self, cmd ):
3928 """
3929 Function to handle sending cli commands for the distributed primitives test app
3930
3931 This command will catch some exceptions and retry the command on some
3932 specific store exceptions.
3933
3934 Required arguments:
3935 cmd - The command to send to the cli
3936 returns:
3937 string containing the cli output
3938 None on Error
3939 """
3940 try:
3941 output = self.sendline( cmd )
3942 try:
3943 assert output is not None, "Error in sendline"
3944 # TODO: Maybe make this less hardcoded
3945 # ConsistentMap Exceptions
3946 assert "org.onosproject.store.service" not in output
3947 # Node not leader
3948 assert "java.lang.IllegalStateException" not in output
3949 except AssertionError:
3950 main.log.error( "Error in processing '" + cmd + "' " +
3951 "command: " + str( output ) )
3952 retryTime = 30 # Conservative time, given by Madan
3953 main.log.info( "Waiting " + str( retryTime ) +
3954 "seconds before retrying." )
3955 time.sleep( retryTime ) # Due to change in mastership
3956 output = self.sendline( cmd )
3957 assert output is not None, "Error in sendline"
3958 assert "Command not found:" not in output, output
3959 assert "Error executing command" not in output, output
3960 main.log.info( self.name + ": " + output )
3961 return output
3962 except AssertionError:
3963 main.log.exception( "Error in processing '" + cmd + "' command." )
3964 return None
3965 except TypeError:
3966 main.log.exception( self.name + ": Object not as expected" )
3967 return None
3968 except pexpect.EOF:
3969 main.log.error( self.name + ": EOF exception found" )
3970 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003971 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003972 except Exception:
3973 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003974 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003975
Jon Hall390696c2015-05-05 17:13:41 -07003976 def setTestAdd( self, setName, values ):
3977 """
3978 CLI command to add elements to a distributed set.
3979 Arguments:
3980 setName - The name of the set to add to.
3981 values - The value(s) to add to the set, space seperated.
3982 Example usages:
3983 setTestAdd( "set1", "a b c" )
3984 setTestAdd( "set2", "1" )
3985 returns:
3986 main.TRUE on success OR
3987 main.FALSE if elements were already in the set OR
3988 main.ERROR on error
3989 """
3990 try:
3991 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003992 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003993 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3994 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jon Hall390696c2015-05-05 17:13:41 -07003995 if re.search( positiveMatch, output):
3996 return main.TRUE
3997 elif re.search( negativeMatch, output):
3998 return main.FALSE
3999 else:
4000 main.log.error( self.name + ": setTestAdd did not" +
4001 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004002 main.log.debug( self.name + " actual: " + repr( output ) )
4003 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004004 except TypeError:
4005 main.log.exception( self.name + ": Object not as expected" )
4006 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004007 except Exception:
4008 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004009 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004010
4011 def setTestRemove( self, setName, values, clear=False, retain=False ):
4012 """
4013 CLI command to remove elements from a distributed set.
4014 Required arguments:
4015 setName - The name of the set to remove from.
4016 values - The value(s) to remove from the set, space seperated.
4017 Optional arguments:
4018 clear - Clear all elements from the set
4019 retain - Retain only the given values. (intersection of the
4020 original set and the given set)
4021 returns:
4022 main.TRUE on success OR
4023 main.FALSE if the set was not changed OR
4024 main.ERROR on error
4025 """
4026 try:
4027 cmdStr = "set-test-remove "
4028 if clear:
4029 cmdStr += "-c " + str( setName )
4030 elif retain:
4031 cmdStr += "-r " + str( setName ) + " " + str( values )
4032 else:
4033 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004034 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004035 if clear:
4036 pattern = "Set " + str( setName ) + " cleared"
4037 if re.search( pattern, output ):
4038 return main.TRUE
4039 elif retain:
4040 positivePattern = str( setName ) + " was pruned to contain " +\
4041 "only elements of set \[(.*)\]"
4042 negativePattern = str( setName ) + " was not changed by " +\
4043 "retaining only elements of the set " +\
4044 "\[(.*)\]"
4045 if re.search( positivePattern, output ):
4046 return main.TRUE
4047 elif re.search( negativePattern, output ):
4048 return main.FALSE
4049 else:
4050 positivePattern = "\[(.*)\] was removed from the set " +\
4051 str( setName )
4052 if ( len( values.split() ) == 1 ):
4053 negativePattern = "\[(.*)\] was not in set " +\
4054 str( setName )
4055 else:
4056 negativePattern = "No element of \[(.*)\] was in set " +\
4057 str( setName )
4058 if re.search( positivePattern, output ):
4059 return main.TRUE
4060 elif re.search( negativePattern, output ):
4061 return main.FALSE
4062 main.log.error( self.name + ": setTestRemove did not" +
4063 " match expected output" )
4064 main.log.debug( self.name + " expected: " + pattern )
4065 main.log.debug( self.name + " actual: " + repr( output ) )
4066 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004067 except TypeError:
4068 main.log.exception( self.name + ": Object not as expected" )
4069 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004070 except Exception:
4071 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004072 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004073
4074 def setTestGet( self, setName, values="" ):
4075 """
4076 CLI command to get the elements in a distributed set.
4077 Required arguments:
4078 setName - The name of the set to remove from.
4079 Optional arguments:
4080 values - The value(s) to check if in the set, space seperated.
4081 returns:
4082 main.ERROR on error OR
4083 A list of elements in the set if no optional arguments are
4084 supplied OR
4085 A tuple containing the list then:
4086 main.FALSE if the given values are not in the set OR
4087 main.TRUE if the given values are in the set OR
4088 """
4089 try:
4090 values = str( values ).strip()
4091 setName = str( setName ).strip()
4092 length = len( values.split() )
4093 containsCheck = None
4094 # Patterns to match
4095 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004096 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004097 containsTrue = "Set " + setName + " contains the value " + values
4098 containsFalse = "Set " + setName + " did not contain the value " +\
4099 values
4100 containsAllTrue = "Set " + setName + " contains the the subset " +\
4101 setPattern
4102 containsAllFalse = "Set " + setName + " did not contain the the" +\
4103 " subset " + setPattern
4104
4105 cmdStr = "set-test-get "
4106 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004107 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004108 if length == 0:
4109 match = re.search( pattern, output )
4110 else: # if given values
4111 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004112 patternTrue = pattern + "\r\n" + containsTrue
4113 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004114 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004115 patternTrue = pattern + "\r\n" + containsAllTrue
4116 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004117 matchTrue = re.search( patternTrue, output )
4118 matchFalse = re.search( patternFalse, output )
4119 if matchTrue:
4120 containsCheck = main.TRUE
4121 match = matchTrue
4122 elif matchFalse:
4123 containsCheck = main.FALSE
4124 match = matchFalse
4125 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004126 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004127 "expected output" )
4128 main.log.debug( self.name + " expected: " + pattern )
4129 main.log.debug( self.name + " actual: " + repr( output ) )
4130 match = None
4131 if match:
4132 setMatch = match.group( 1 )
4133 if setMatch == '':
4134 setList = []
4135 else:
4136 setList = setMatch.split( ", " )
4137 if length > 0:
4138 return ( setList, containsCheck )
4139 else:
4140 return setList
4141 else: # no match
4142 main.log.error( self.name + ": setTestGet did not" +
4143 " match expected output" )
4144 main.log.debug( self.name + " expected: " + pattern )
4145 main.log.debug( self.name + " actual: " + repr( output ) )
4146 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004147 except TypeError:
4148 main.log.exception( self.name + ": Object not as expected" )
4149 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004150 except Exception:
4151 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004152 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004153
4154 def setTestSize( self, setName ):
4155 """
4156 CLI command to get the elements in a distributed set.
4157 Required arguments:
4158 setName - The name of the set to remove from.
4159 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004160 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004161 None on error
4162 """
4163 try:
4164 # TODO: Should this check against the number of elements returned
4165 # and then return true/false based on that?
4166 setName = str( setName ).strip()
4167 # Patterns to match
4168 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004169 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004170 setPattern
4171 cmdStr = "set-test-get -s "
4172 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004173 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004174 match = re.search( pattern, output )
4175 if match:
4176 setSize = int( match.group( 1 ) )
4177 setMatch = match.group( 2 )
4178 if len( setMatch.split() ) == setSize:
4179 main.log.info( "The size returned by " + self.name +
4180 " matches the number of elements in " +
4181 "the returned set" )
4182 else:
4183 main.log.error( "The size returned by " + self.name +
4184 " does not match the number of " +
4185 "elements in the returned set." )
4186 return setSize
4187 else: # no match
4188 main.log.error( self.name + ": setTestGet did not" +
4189 " match expected output" )
4190 main.log.debug( self.name + " expected: " + pattern )
4191 main.log.debug( self.name + " actual: " + repr( output ) )
4192 return None
Jon Hall390696c2015-05-05 17:13:41 -07004193 except TypeError:
4194 main.log.exception( self.name + ": Object not as expected" )
4195 return None
Jon Hall390696c2015-05-05 17:13:41 -07004196 except Exception:
4197 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004198 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004199
Jon Hall80daded2015-05-27 16:07:00 -07004200 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004201 """
4202 Command to list the various counters in the system.
4203 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004204 if jsonFormat, a string of the json object returned by the cli
4205 command
4206 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004207 None on error
4208 """
Jon Hall390696c2015-05-05 17:13:41 -07004209 try:
Jon Hall390696c2015-05-05 17:13:41 -07004210 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004211 if jsonFormat:
4212 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004213 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004214 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004215 assert "Command not found:" not in output, output
4216 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004217 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004218 return output
Jon Hall390696c2015-05-05 17:13:41 -07004219 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004220 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004221 return None
Jon Hall390696c2015-05-05 17:13:41 -07004222 except TypeError:
4223 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004224 return None
Jon Hall390696c2015-05-05 17:13:41 -07004225 except pexpect.EOF:
4226 main.log.error( self.name + ": EOF exception found" )
4227 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004228 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004229 except Exception:
4230 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004231 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004232
Jon Hall935db192016-04-19 00:22:04 -07004233 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004234 """
Jon Halle1a3b752015-07-22 13:02:46 -07004235 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004236 Required arguments:
4237 counter - The name of the counter to increment.
4238 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004239 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004240 returns:
4241 integer value of the counter or
4242 None on Error
4243 """
4244 try:
4245 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004246 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004247 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004248 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004249 if delta != 1:
4250 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004251 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004252 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004253 match = re.search( pattern, output )
4254 if match:
4255 return int( match.group( 1 ) )
4256 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004257 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004258 " match expected output." )
4259 main.log.debug( self.name + " expected: " + pattern )
4260 main.log.debug( self.name + " actual: " + repr( output ) )
4261 return None
Jon Hall390696c2015-05-05 17:13:41 -07004262 except TypeError:
4263 main.log.exception( self.name + ": Object not as expected" )
4264 return None
Jon Hall390696c2015-05-05 17:13:41 -07004265 except Exception:
4266 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004267 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004268
Jon Hall935db192016-04-19 00:22:04 -07004269 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004270 """
4271 CLI command to get a distributed counter then add a delta to it.
4272 Required arguments:
4273 counter - The name of the counter to increment.
4274 Optional arguments:
4275 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004276 returns:
4277 integer value of the counter or
4278 None on Error
4279 """
4280 try:
4281 counter = str( counter )
4282 delta = int( delta )
4283 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004284 cmdStr += counter
4285 if delta != 1:
4286 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004287 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004288 pattern = counter + " was updated to (-?\d+)"
4289 match = re.search( pattern, output )
4290 if match:
4291 return int( match.group( 1 ) )
4292 else:
4293 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4294 " match expected output." )
4295 main.log.debug( self.name + " expected: " + pattern )
4296 main.log.debug( self.name + " actual: " + repr( output ) )
4297 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004298 except TypeError:
4299 main.log.exception( self.name + ": Object not as expected" )
4300 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004301 except Exception:
4302 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004303 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004304
4305 def valueTestGet( self, valueName ):
4306 """
4307 CLI command to get the value of an atomic value.
4308 Required arguments:
4309 valueName - The name of the value to get.
4310 returns:
4311 string value of the value or
4312 None on Error
4313 """
4314 try:
4315 valueName = str( valueName )
4316 cmdStr = "value-test "
4317 operation = "get"
4318 cmdStr = "value-test {} {}".format( valueName,
4319 operation )
4320 output = self.distPrimitivesSend( cmdStr )
4321 pattern = "(\w+)"
4322 match = re.search( pattern, output )
4323 if match:
4324 return match.group( 1 )
4325 else:
4326 main.log.error( self.name + ": valueTestGet did not" +
4327 " match expected output." )
4328 main.log.debug( self.name + " expected: " + pattern )
4329 main.log.debug( self.name + " actual: " + repr( output ) )
4330 return None
4331 except TypeError:
4332 main.log.exception( self.name + ": Object not as expected" )
4333 return None
4334 except Exception:
4335 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004336 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004337
4338 def valueTestSet( self, valueName, newValue ):
4339 """
4340 CLI command to set the value of an atomic value.
4341 Required arguments:
4342 valueName - The name of the value to set.
4343 newValue - The value to assign to the given value.
4344 returns:
4345 main.TRUE on success or
4346 main.ERROR on Error
4347 """
4348 try:
4349 valueName = str( valueName )
4350 newValue = str( newValue )
4351 operation = "set"
4352 cmdStr = "value-test {} {} {}".format( valueName,
4353 operation,
4354 newValue )
4355 output = self.distPrimitivesSend( cmdStr )
4356 if output is not None:
4357 return main.TRUE
4358 else:
4359 return main.ERROR
4360 except TypeError:
4361 main.log.exception( self.name + ": Object not as expected" )
4362 return main.ERROR
4363 except Exception:
4364 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004365 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004366
4367 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4368 """
4369 CLI command to compareAndSet the value of an atomic value.
4370 Required arguments:
4371 valueName - The name of the value.
4372 oldValue - Compare the current value of the atomic value to this
4373 newValue - If the value equals oldValue, set the value to newValue
4374 returns:
4375 main.TRUE on success or
4376 main.FALSE on failure or
4377 main.ERROR on Error
4378 """
4379 try:
4380 valueName = str( valueName )
4381 oldValue = str( oldValue )
4382 newValue = str( newValue )
4383 operation = "compareAndSet"
4384 cmdStr = "value-test {} {} {} {}".format( valueName,
4385 operation,
4386 oldValue,
4387 newValue )
4388 output = self.distPrimitivesSend( cmdStr )
4389 pattern = "(\w+)"
4390 match = re.search( pattern, output )
4391 if match:
4392 result = match.group( 1 )
4393 if result == "true":
4394 return main.TRUE
4395 elif result == "false":
4396 return main.FALSE
4397 else:
4398 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4399 " match expected output." )
4400 main.log.debug( self.name + " expected: " + pattern )
4401 main.log.debug( self.name + " actual: " + repr( output ) )
4402 return main.ERROR
4403 except TypeError:
4404 main.log.exception( self.name + ": Object not as expected" )
4405 return main.ERROR
4406 except Exception:
4407 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004408 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004409
4410 def valueTestGetAndSet( self, valueName, newValue ):
4411 """
4412 CLI command to getAndSet the value of an atomic value.
4413 Required arguments:
4414 valueName - The name of the value to get.
4415 newValue - The value to assign to the given value
4416 returns:
4417 string value of the value or
4418 None on Error
4419 """
4420 try:
4421 valueName = str( valueName )
4422 cmdStr = "value-test "
4423 operation = "getAndSet"
4424 cmdStr += valueName + " " + operation
4425 cmdStr = "value-test {} {} {}".format( valueName,
4426 operation,
4427 newValue )
4428 output = self.distPrimitivesSend( cmdStr )
4429 pattern = "(\w+)"
4430 match = re.search( pattern, output )
4431 if match:
4432 return match.group( 1 )
4433 else:
4434 main.log.error( self.name + ": valueTestGetAndSet did not" +
4435 " match expected output." )
4436 main.log.debug( self.name + " expected: " + pattern )
4437 main.log.debug( self.name + " actual: " + repr( output ) )
4438 return None
4439 except TypeError:
4440 main.log.exception( self.name + ": Object not as expected" )
4441 return None
4442 except Exception:
4443 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004444 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004445
4446 def valueTestDestroy( self, valueName ):
4447 """
4448 CLI command to destroy an atomic value.
4449 Required arguments:
4450 valueName - The name of the value to destroy.
4451 returns:
4452 main.TRUE on success or
4453 main.ERROR on Error
4454 """
4455 try:
4456 valueName = str( valueName )
4457 cmdStr = "value-test "
4458 operation = "destroy"
4459 cmdStr += valueName + " " + operation
4460 output = self.distPrimitivesSend( cmdStr )
4461 if output is not None:
4462 return main.TRUE
4463 else:
4464 return main.ERROR
4465 except TypeError:
4466 main.log.exception( self.name + ": Object not as expected" )
4467 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004468 except Exception:
4469 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004470 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004471
YPZhangfebf7302016-05-24 16:45:56 -07004472 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004473 """
4474 Description: Execute summary command in onos
4475 Returns: json object ( summary -j ), returns main.FALSE if there is
4476 no output
4477
4478 """
4479 try:
4480 cmdStr = "summary"
4481 if jsonFormat:
4482 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004483 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004484 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004485 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004486 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004487 if not handle:
4488 main.log.error( self.name + ": There is no output in " +
4489 "summary command" )
4490 return main.FALSE
4491 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004492 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004493 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004494 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004495 except TypeError:
4496 main.log.exception( self.name + ": Object not as expected" )
4497 return None
4498 except pexpect.EOF:
4499 main.log.error( self.name + ": EOF exception found" )
4500 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004501 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004502 except Exception:
4503 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004504 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004505
Jon Hall935db192016-04-19 00:22:04 -07004506 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004507 """
4508 CLI command to get the value of a key in a consistent map using
4509 transactions. This a test function and can only get keys from the
4510 test map hard coded into the cli command
4511 Required arguments:
4512 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004513 returns:
4514 The string value of the key or
4515 None on Error
4516 """
4517 try:
4518 keyName = str( keyName )
4519 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004520 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004521 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004522 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4523 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004524 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004525 return None
4526 else:
4527 match = re.search( pattern, output )
4528 if match:
4529 return match.groupdict()[ 'value' ]
4530 else:
4531 main.log.error( self.name + ": transactionlMapGet did not" +
4532 " match expected output." )
4533 main.log.debug( self.name + " expected: " + pattern )
4534 main.log.debug( self.name + " actual: " + repr( output ) )
4535 return None
4536 except TypeError:
4537 main.log.exception( self.name + ": Object not as expected" )
4538 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004539 except Exception:
4540 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004541 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004542
Jon Hall935db192016-04-19 00:22:04 -07004543 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004544 """
4545 CLI command to put a value into 'numKeys' number of keys in a
4546 consistent map using transactions. This a test function and can only
4547 put into keys named 'Key#' of the test map hard coded into the cli command
4548 Required arguments:
4549 numKeys - Number of keys to add the value to
4550 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004551 returns:
4552 A dictionary whose keys are the name of the keys put into the map
4553 and the values of the keys are dictionaries whose key-values are
4554 'value': value put into map and optionaly
4555 'oldValue': Previous value in the key or
4556 None on Error
4557
4558 Example output
4559 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4560 'Key2': {'value': 'Testing'} }
4561 """
4562 try:
4563 numKeys = str( numKeys )
4564 value = str( value )
4565 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004566 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004567 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004568 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4569 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4570 results = {}
4571 for line in output.splitlines():
4572 new = re.search( newPattern, line )
4573 updated = re.search( updatedPattern, line )
4574 if new:
4575 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4576 elif updated:
4577 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004578 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004579 else:
4580 main.log.error( self.name + ": transactionlMapGet did not" +
4581 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004582 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4583 newPattern,
4584 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004585 main.log.debug( self.name + " actual: " + repr( output ) )
4586 return results
4587 except TypeError:
4588 main.log.exception( self.name + ": Object not as expected" )
4589 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004590 except Exception:
4591 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004592 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004593
acsmarsdaea66c2015-09-03 11:44:06 -07004594 def maps( self, jsonFormat=True ):
4595 """
4596 Description: Returns result of onos:maps
4597 Optional:
4598 * jsonFormat: enable json formatting of output
4599 """
4600 try:
4601 cmdStr = "maps"
4602 if jsonFormat:
4603 cmdStr += " -j"
4604 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004605 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004606 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004607 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004608 except AssertionError:
4609 main.log.exception( "" )
4610 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004611 except TypeError:
4612 main.log.exception( self.name + ": Object not as expected" )
4613 return None
4614 except pexpect.EOF:
4615 main.log.error( self.name + ": EOF exception found" )
4616 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004617 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004618 except Exception:
4619 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004620 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004621
4622 def getSwController( self, uri, jsonFormat=True ):
4623 """
4624 Descrition: Gets the controller information from the device
4625 """
4626 try:
4627 cmd = "device-controllers "
4628 if jsonFormat:
4629 cmd += "-j "
4630 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004631 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004632 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004633 return response
Jon Hallc6793552016-01-19 14:18:37 -08004634 except AssertionError:
4635 main.log.exception( "" )
4636 return None
GlennRC050596c2015-11-18 17:06:41 -08004637 except TypeError:
4638 main.log.exception( self.name + ": Object not as expected" )
4639 return None
4640 except pexpect.EOF:
4641 main.log.error( self.name + ": EOF exception found" )
4642 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004643 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004644 except Exception:
4645 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004646 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004647
4648 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4649 """
4650 Descrition: sets the controller(s) for the specified device
4651
4652 Parameters:
4653 Required: uri - String: The uri of the device(switch).
4654 ip - String or List: The ip address of the controller.
4655 This parameter can be formed in a couple of different ways.
4656 VALID:
4657 10.0.0.1 - just the ip address
4658 tcp:10.0.0.1 - the protocol and the ip address
4659 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4660 so that you can add controllers with different
4661 protocols and ports
4662 INVALID:
4663 10.0.0.1:6653 - this is not supported by ONOS
4664
4665 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4666 port - The port number.
4667 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4668
4669 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4670 """
4671 try:
4672 cmd = "device-setcontrollers"
4673
4674 if jsonFormat:
4675 cmd += " -j"
4676 cmd += " " + uri
4677 if isinstance( ip, str ):
4678 ip = [ip]
4679 for item in ip:
4680 if ":" in item:
4681 sitem = item.split( ":" )
4682 if len(sitem) == 3:
4683 cmd += " " + item
4684 elif "." in sitem[1]:
4685 cmd += " {}:{}".format(item, port)
4686 else:
4687 main.log.error( "Malformed entry: " + item )
4688 raise TypeError
4689 else:
4690 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004691 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004692 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004693 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004694 if "Error" in response:
4695 main.log.error( response )
4696 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004697 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004698 except AssertionError:
4699 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004700 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004701 except TypeError:
4702 main.log.exception( self.name + ": Object not as expected" )
4703 return main.FALSE
4704 except pexpect.EOF:
4705 main.log.error( self.name + ": EOF exception found" )
4706 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004707 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004708 except Exception:
4709 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004710 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004711
4712 def removeDevice( self, device ):
4713 '''
4714 Description:
4715 Remove a device from ONOS by passing the uri of the device(s).
4716 Parameters:
4717 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4718 Returns:
4719 Returns main.FALSE if an exception is thrown or an error is present
4720 in the response. Otherwise, returns main.TRUE.
4721 NOTE:
4722 If a host cannot be removed, then this function will return main.FALSE
4723 '''
4724 try:
4725 if type( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004726 deviceStr = device
4727 device = []
4728 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004729
4730 for d in device:
4731 time.sleep( 1 )
4732 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004733 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004734 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004735 if "Error" in response:
4736 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4737 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004738 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004739 except AssertionError:
4740 main.log.exception( "" )
4741 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004742 except TypeError:
4743 main.log.exception( self.name + ": Object not as expected" )
4744 return main.FALSE
4745 except pexpect.EOF:
4746 main.log.error( self.name + ": EOF exception found" )
4747 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004748 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004749 except Exception:
4750 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004751 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004752
4753 def removeHost( self, host ):
4754 '''
4755 Description:
4756 Remove a host from ONOS by passing the id of the host(s)
4757 Parameters:
4758 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4759 Returns:
4760 Returns main.FALSE if an exception is thrown or an error is present
4761 in the response. Otherwise, returns main.TRUE.
4762 NOTE:
4763 If a host cannot be removed, then this function will return main.FALSE
4764 '''
4765 try:
4766 if type( host ) is str:
4767 host = list( host )
4768
4769 for h in host:
4770 time.sleep( 1 )
4771 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004772 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004773 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004774 if "Error" in response:
4775 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4776 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004777 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004778 except AssertionError:
4779 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004780 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004781 except TypeError:
4782 main.log.exception( self.name + ": Object not as expected" )
4783 return main.FALSE
4784 except pexpect.EOF:
4785 main.log.error( self.name + ": EOF exception found" )
4786 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004787 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004788 except Exception:
4789 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004790 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004791
YPZhangfebf7302016-05-24 16:45:56 -07004792 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004793 '''
4794 Description:
4795 Bring link down or up in the null-provider.
4796 params:
4797 begin - (string) One end of a device or switch.
4798 end - (string) the other end of the device or switch
4799 returns:
4800 main.TRUE if no exceptions were thrown and no Errors are
4801 present in the resoponse. Otherwise, returns main.FALSE
4802 '''
4803 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004804 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004805 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004806 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004807 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004808 if "Error" in response or "Failure" in response:
4809 main.log.error( response )
4810 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004811 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004812 except AssertionError:
4813 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004814 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004815 except TypeError:
4816 main.log.exception( self.name + ": Object not as expected" )
4817 return main.FALSE
4818 except pexpect.EOF:
4819 main.log.error( self.name + ": EOF exception found" )
4820 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004821 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004822 except Exception:
4823 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004824 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004825
Jon Hall2c8959e2016-12-16 12:17:34 -08004826 def portstate( self, dpid, port, state ):
Flavio Castro82ee2f62016-06-07 15:04:12 -07004827 '''
4828 Description:
4829 Changes the state of port in an OF switch by means of the
4830 PORTSTATUS OF messages.
4831 params:
Jon Hall2c8959e2016-12-16 12:17:34 -08004832 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
4833 port - (string) target port in the device. Ex: '2'
4834 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07004835 returns:
4836 main.TRUE if no exceptions were thrown and no Errors are
4837 present in the resoponse. Otherwise, returns main.FALSE
4838 '''
4839 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08004840 state = state.lower()
4841 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07004842 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07004843 response = self.sendline( cmd, showResponse=True )
4844 assert response is not None, "Error in sendline"
4845 assert "Command not found:" not in response, response
4846 if "Error" in response or "Failure" in response:
4847 main.log.error( response )
4848 return main.FALSE
4849 return main.TRUE
4850 except AssertionError:
4851 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004852 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07004853 except TypeError:
4854 main.log.exception( self.name + ": Object not as expected" )
4855 return main.FALSE
4856 except pexpect.EOF:
4857 main.log.error( self.name + ": EOF exception found" )
4858 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004859 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004860 except Exception:
4861 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004862 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004863
4864 def logSet( self, level="INFO", app="org.onosproject" ):
4865 """
4866 Set the logging level to lvl for a specific app
4867 returns main.TRUE on success
4868 returns main.FALSE if Error occurred
4869 if noExit is True, TestON will not exit, but clean up
4870 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4871 Level defaults to INFO
4872 """
4873 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004874 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07004875 self.handle.expect( "onos>" )
4876
4877 response = self.handle.before
4878 if re.search( "Error", response ):
4879 return main.FALSE
4880 return main.TRUE
4881 except pexpect.TIMEOUT:
4882 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07004883 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004884 except pexpect.EOF:
4885 main.log.error( self.name + ": EOF exception found" )
4886 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004887 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004888 except Exception:
4889 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004890 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004891
4892 def getGraphDict( self, timeout=60, includeHost=False ):
4893 """
4894 Return a dictionary which describes the latest network topology data as a
4895 graph.
4896 An example of the dictionary:
4897 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4898 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4899 Each vertex should at least have an 'edges' attribute which describes the
4900 adjacency information. The value of 'edges' attribute is also represented by
4901 a dictionary, which maps each edge (identified by the neighbor vertex) to a
4902 list of attributes.
4903 An example of the edges dictionary:
4904 'edges': { vertex2: { 'port': ..., 'weight': ... },
4905 vertex3: { 'port': ..., 'weight': ... } }
4906 If includeHost == True, all hosts (and host-switch links) will be included
4907 in topology data.
4908 """
4909 graphDict = {}
4910 try:
4911 links = self.links()
4912 links = json.loads( links )
4913 devices = self.devices()
4914 devices = json.loads( devices )
4915 idToDevice = {}
4916 for device in devices:
4917 idToDevice[ device[ 'id' ] ] = device
4918 if includeHost:
4919 hosts = self.hosts()
4920 # FIXME: support 'includeHost' argument
4921 for link in links:
4922 nodeA = link[ 'src' ][ 'device' ]
4923 nodeB = link[ 'dst' ][ 'device' ]
4924 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07004925 if nodeA not in graphDict.keys():
4926 graphDict[ nodeA ] = { 'edges': {},
4927 'dpid': idToDevice[ nodeA ][ 'id' ][3:],
4928 'type': idToDevice[ nodeA ][ 'type' ],
4929 'available': idToDevice[ nodeA ][ 'available' ],
4930 'role': idToDevice[ nodeA ][ 'role' ],
4931 'mfr': idToDevice[ nodeA ][ 'mfr' ],
4932 'hw': idToDevice[ nodeA ][ 'hw' ],
4933 'sw': idToDevice[ nodeA ][ 'sw' ],
4934 'serial': idToDevice[ nodeA ][ 'serial' ],
4935 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
4936 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07004937 else:
4938 # Assert nodeB is not connected to any current links of nodeA
4939 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07004940 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
4941 'type': link[ 'type' ],
4942 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07004943 return graphDict
4944 except ( TypeError, ValueError ):
4945 main.log.exception( self.name + ": Object not as expected" )
4946 return None
4947 except KeyError:
4948 main.log.exception( self.name + ": KeyError exception found" )
4949 return None
4950 except AssertionError:
4951 main.log.exception( self.name + ": AssertionError exception found" )
4952 return None
4953 except pexpect.EOF:
4954 main.log.error( self.name + ": EOF exception found" )
4955 main.log.error( self.name + ": " + self.handle.before )
4956 return None
4957 except Exception:
4958 main.log.exception( self.name + ": Uncaught exception!" )
4959 return None
YPZhangcbc2a062016-07-11 10:55:44 -07004960
4961 def getIntentPerfSummary( self ):
4962 '''
4963 Send command to check intent-perf summary
4964 Returns: dictionary for intent-perf summary
4965 if something wrong, function will return None
4966 '''
4967 cmd = "intent-perf -s"
4968 respDic = {}
4969 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08004970 assert resp is not None, "Error in sendline"
4971 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07004972 try:
4973 # Generate the dictionary to return
4974 for l in resp.split( "\n" ):
4975 # Delete any white space in line
4976 temp = re.sub( r'\s+', '', l )
4977 temp = temp.split( ":" )
4978 respDic[ temp[0] ] = temp[ 1 ]
4979
4980 except (TypeError, ValueError):
4981 main.log.exception( self.name + ": Object not as expected" )
4982 return None
4983 except KeyError:
4984 main.log.exception( self.name + ": KeyError exception found" )
4985 return None
4986 except AssertionError:
4987 main.log.exception( self.name + ": AssertionError exception found" )
4988 return None
4989 except pexpect.EOF:
4990 main.log.error( self.name + ": EOF exception found" )
4991 main.log.error( self.name + ": " + self.handle.before )
4992 return None
4993 except Exception:
4994 main.log.exception( self.name + ": Uncaught exception!" )
4995 return None
4996 return respDic
4997
Chiyu Chengec63bde2016-11-17 18:11:36 -08004998 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07004999 """
5000 Searches the latest ONOS log file for the given search term and
5001 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005002
chengchiyu08303a02016-09-08 17:40:26 -07005003 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005004 searchTerm:
5005 The string to grep from the ONOS log.
5006 startLine:
5007 The term that decides which line is the start to search the searchTerm in
5008 the karaf log. For now, startTerm only works in 'first' mode.
5009 logNum:
5010 In some extreme cases, one karaf log is not big enough to contain all the
5011 information.Because of this, search mutiply logs is necessary to capture
5012 the right result. logNum is the number of karaf logs that we need to search
5013 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005014 mode:
5015 all: return all the strings that contain the search term
5016 last: return the last string that contains the search term
5017 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005018 num: return the number of times that the searchTerm appears in the log
5019 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005020 """
5021 try:
5022 assert type( searchTerm ) is str
Jon Halle0f0b342017-04-18 11:43:47 -07005023 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005024 logPath = '/opt/onos/log/karaf.log.'
5025 logPaths = '/opt/onos/log/karaf.log'
5026 for i in range( 1, logNum ):
5027 logPaths = logPath + str( i ) + " " + logPaths
5028 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005029 if startLine:
5030 # 100000000 is just a extreme large number to make sure this function can grep all the lines after startLine
5031 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005032 if mode == 'all':
5033 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005034 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005035 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005036 elif mode == 'first':
5037 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5038 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005039 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005040 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005041 return num
You Wang6d301d42017-04-21 10:49:33 -07005042 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005043 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
5044 return int(totalLines)
You Wang6d301d42017-04-21 10:49:33 -07005045 else:
5046 main.log.error( self.name + " unsupported mode" )
5047 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005048 before = self.sendline( cmd )
5049 before = before.splitlines()
5050 # make sure the returned list only contains the search term
5051 returnLines = [line for line in before if searchTerm in line]
5052 return returnLines
5053 except AssertionError:
5054 main.log.error( self.name + " searchTerm is not string type" )
5055 return None
5056 except pexpect.EOF:
5057 main.log.error( self.name + ": EOF exception found" )
5058 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005059 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005060 except pexpect.TIMEOUT:
5061 main.log.error( self.name + ": TIMEOUT exception found" )
5062 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005063 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005064 except Exception:
5065 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005066 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005067
5068 def vplsShow( self, jsonFormat=True ):
5069 """
5070 Description: Returns result of onos:vpls show, which should list the
5071 configured VPLS networks and the assigned interfaces.
5072 Optional:
5073 * jsonFormat: enable json formatting of output
5074 Returns:
5075 The output of the command or None on error.
5076 """
5077 try:
5078 cmdStr = "vpls show"
5079 if jsonFormat:
5080 raise NotImplementedError
5081 cmdStr += " -j"
5082 handle = self.sendline( cmdStr )
5083 assert handle is not None, "Error in sendline"
5084 assert "Command not found:" not in handle, handle
5085 return handle
5086 except AssertionError:
5087 main.log.exception( "" )
5088 return None
5089 except TypeError:
5090 main.log.exception( self.name + ": Object not as expected" )
5091 return None
5092 except pexpect.EOF:
5093 main.log.error( self.name + ": EOF exception found" )
5094 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005095 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005096 except NotImplementedError:
5097 main.log.exception( self.name + ": Json output not supported")
5098 return None
5099 except Exception:
5100 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005101 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005102
5103 def parseVplsShow( self ):
5104 """
5105 Parse the cli output of 'vpls show' into json output. This is required
5106 as there is currently no json output available.
5107 """
5108 try:
5109 output = []
5110 raw = self.vplsShow( jsonFormat=False )
5111 namePat = "VPLS name: (?P<name>\w+)"
5112 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5113 encapPat = "Encapsulation: (?P<encap>\w+)"
5114 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5115 mIter = re.finditer( pattern, raw )
5116 for match in mIter:
5117 item = {}
5118 item[ 'name' ] = match.group( 'name' )
5119 ifaces = match.group( 'interfaces' ).split( ', ')
5120 if ifaces == [ "" ]:
5121 ifaces = []
5122 item[ 'interfaces' ] = ifaces
5123 encap = match.group( 'encap' )
5124 if encap != 'NONE':
5125 item[ 'encapsulation' ] = encap.lower()
5126 output.append( item )
5127 return output
5128 except Exception:
5129 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005130 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005131
5132 def vplsList( self, jsonFormat=True ):
5133 """
5134 Description: Returns result of onos:vpls list, which should list the
5135 configured VPLS networks.
5136 Optional:
5137 * jsonFormat: enable json formatting of output
5138 """
5139 try:
5140 cmdStr = "vpls list"
5141 if jsonFormat:
5142 raise NotImplementedError
5143 cmdStr += " -j"
5144 handle = self.sendline( cmdStr )
5145 assert handle is not None, "Error in sendline"
5146 assert "Command not found:" not in handle, handle
5147 return handle
5148 except AssertionError:
5149 main.log.exception( "" )
5150 return None
5151 except TypeError:
5152 main.log.exception( self.name + ": Object not as expected" )
5153 return None
5154 except pexpect.EOF:
5155 main.log.error( self.name + ": EOF exception found" )
5156 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005157 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005158 except NotImplementedError:
5159 main.log.exception( self.name + ": Json output not supported")
5160 return None
5161 except Exception:
5162 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005163 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005164
5165 def vplsCreate( self, network ):
5166 """
5167 CLI command to create a new VPLS network.
5168 Required arguments:
5169 network - String name of the network to create.
5170 returns:
5171 main.TRUE on success and main.FALSE on failure
5172 """
5173 try:
5174 network = str( network )
5175 cmdStr = "vpls create "
5176 cmdStr += network
5177 output = self.sendline( cmdStr )
5178 assert output is not None, "Error in sendline"
5179 assert "Command not found:" not in output, output
5180 assert "Error executing command" not in output, output
5181 assert "VPLS already exists:" not in output, output
5182 return main.TRUE
5183 except AssertionError:
5184 main.log.exception( "" )
5185 return main.FALSE
5186 except TypeError:
5187 main.log.exception( self.name + ": Object not as expected" )
5188 return main.FALSE
5189 except pexpect.EOF:
5190 main.log.error( self.name + ": EOF exception found" )
5191 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005192 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005193 except Exception:
5194 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005195 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005196
5197 def vplsDelete( self, network ):
5198 """
5199 CLI command to delete a VPLS network.
5200 Required arguments:
5201 network - Name of the network to delete.
5202 returns:
5203 main.TRUE on success and main.FALSE on failure
5204 """
5205 try:
5206 network = str( network )
5207 cmdStr = "vpls delete "
5208 cmdStr += network
5209 output = self.sendline( cmdStr )
5210 assert output is not None, "Error in sendline"
5211 assert "Command not found:" not in output, output
5212 assert "Error executing command" not in output, output
5213 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005214 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005215 return main.TRUE
5216 except AssertionError:
5217 main.log.exception( "" )
5218 return main.FALSE
5219 except TypeError:
5220 main.log.exception( self.name + ": Object not as expected" )
5221 return main.FALSE
5222 except pexpect.EOF:
5223 main.log.error( self.name + ": EOF exception found" )
5224 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005225 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005226 except Exception:
5227 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005228 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005229
5230 def vplsAddIface( self, network, iface ):
5231 """
5232 CLI command to add an interface to a VPLS network.
5233 Required arguments:
5234 network - Name of the network to add the interface to.
5235 iface - The ONOS name for an interface.
5236 returns:
5237 main.TRUE on success and main.FALSE on failure
5238 """
5239 try:
5240 network = str( network )
5241 iface = str( iface )
5242 cmdStr = "vpls add-if "
5243 cmdStr += network + " " + iface
5244 output = self.sendline( cmdStr )
5245 assert output is not None, "Error in sendline"
5246 assert "Command not found:" not in output, output
5247 assert "Error executing command" not in output, output
5248 assert "already associated to network" not in output, output
5249 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005250 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005251 return main.TRUE
5252 except AssertionError:
5253 main.log.exception( "" )
5254 return main.FALSE
5255 except TypeError:
5256 main.log.exception( self.name + ": Object not as expected" )
5257 return main.FALSE
5258 except pexpect.EOF:
5259 main.log.error( self.name + ": EOF exception found" )
5260 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005261 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005262 except Exception:
5263 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005264 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005265
5266 def vplsRemIface( self, network, iface ):
5267 """
5268 CLI command to remove an interface from a VPLS network.
5269 Required arguments:
5270 network - Name of the network to remove the interface from.
5271 iface - Name of the interface to remove.
5272 returns:
5273 main.TRUE on success and main.FALSE on failure
5274 """
5275 try:
5276 iface = str( iface )
5277 cmdStr = "vpls rem-if "
5278 cmdStr += network + " " + iface
5279 output = self.sendline( cmdStr )
5280 assert output is not None, "Error in sendline"
5281 assert "Command not found:" not in output, output
5282 assert "Error executing command" not in output, output
5283 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005284 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005285 return main.TRUE
5286 except AssertionError:
5287 main.log.exception( "" )
5288 return main.FALSE
5289 except TypeError:
5290 main.log.exception( self.name + ": Object not as expected" )
5291 return main.FALSE
5292 except pexpect.EOF:
5293 main.log.error( self.name + ": EOF exception found" )
5294 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005295 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005296 except Exception:
5297 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005298 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005299
5300 def vplsClean( self ):
5301 """
5302 Description: Clears the VPLS app configuration.
5303 Returns: main.TRUE on success and main.FALSE on failure
5304 """
5305 try:
5306 cmdStr = "vpls clean"
5307 handle = self.sendline( cmdStr )
5308 assert handle is not None, "Error in sendline"
5309 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005310 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005311 return handle
5312 except AssertionError:
5313 main.log.exception( "" )
5314 return main.FALSE
5315 except TypeError:
5316 main.log.exception( self.name + ": Object not as expected" )
5317 return main.FALSE
5318 except pexpect.EOF:
5319 main.log.error( self.name + ": EOF exception found" )
5320 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005321 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005322 except Exception:
5323 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005324 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005325
5326 def vplsSetEncap( self, network, encapType ):
5327 """
5328 CLI command to add an interface to a VPLS network.
5329 Required arguments:
5330 network - Name of the network to create.
5331 encapType - Type of encapsulation.
5332 returns:
5333 main.TRUE on success and main.FALSE on failure
5334 """
5335 try:
5336 network = str( network )
5337 encapType = str( encapType ).upper()
5338 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5339 cmdStr = "vpls set-encap "
5340 cmdStr += network + " " + encapType
5341 output = self.sendline( cmdStr )
5342 assert output is not None, "Error in sendline"
5343 assert "Command not found:" not in output, output
5344 assert "Error executing command" not in output, output
5345 assert "already associated to network" not in output, output
5346 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005347 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005348 return main.TRUE
5349 except AssertionError:
5350 main.log.exception( "" )
5351 return main.FALSE
5352 except TypeError:
5353 main.log.exception( self.name + ": Object not as expected" )
5354 return main.FALSE
5355 except pexpect.EOF:
5356 main.log.error( self.name + ": EOF exception found" )
5357 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005358 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005359 except Exception:
5360 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005361 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005362
5363 def interfaces( self, jsonFormat=True ):
5364 """
5365 Description: Returns result of interfaces command.
5366 Optional:
5367 * jsonFormat: enable json formatting of output
5368 Returns:
5369 The output of the command or None on error.
5370 """
5371 try:
5372 cmdStr = "interfaces"
5373 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005374 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005375 cmdStr += " -j"
5376 handle = self.sendline( cmdStr )
5377 assert handle is not None, "Error in sendline"
5378 assert "Command not found:" not in handle, handle
5379 return handle
5380 except AssertionError:
5381 main.log.exception( "" )
5382 return None
5383 except TypeError:
5384 main.log.exception( self.name + ": Object not as expected" )
5385 return None
5386 except pexpect.EOF:
5387 main.log.error( self.name + ": EOF exception found" )
5388 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005389 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005390 except NotImplementedError:
5391 main.log.exception( self.name + ": Json output not supported")
5392 return None
5393 except Exception:
5394 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005395 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005396
5397 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
5398 '''
5399 Get the timestamp of searchTerm from karaf log.
5400
5401 Arguments:
5402 splitTerm_before and splitTerm_after:
5403
5404 The terms that split the string that contains the timeStamp of
5405 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5406 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5407 and the splitTerm_after is "x"
5408
5409 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005410 Please look at the "logsearch" Function in onosclidriver.py
Chiyu Chengec63bde2016-11-17 18:11:36 -08005411 '''
5412 if logNum < 0:
5413 main.log.error("Get wrong log number ")
5414 return main.ERROR
5415 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
5416 if len(lines) == 0:
5417 main.log.warn( "Captured timestamp string is empty" )
5418 return main.ERROR
5419 lines = lines[ 0 ]
5420 try:
5421 assert type(lines) is str
5422 # get the target value
5423 line = lines.split( splitTerm_before )
5424 key = line[ 1 ].split( splitTerm_after )
5425 return int( key[ 0 ] )
5426 except IndexError:
5427 main.log.warn( "Index Error!" )
5428 return main.ERROR
5429 except AssertionError:
5430 main.log.warn( "Search Term Not Found " )
5431 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005432
5433 def workQueueAdd( self, queueName, value ):
5434 """
5435 CLI command to add a string to the specified Work Queue.
5436 This function uses the distributed primitives test app, which
5437 gives some cli access to distributed primitives for testing
5438 purposes only.
5439
5440 Required arguments:
5441 queueName - The name of the queue to add to
5442 value - The value to add to the queue
5443 returns:
5444 main.TRUE on success, main.FALSE on failure and
5445 main.ERROR on error.
5446 """
5447 try:
5448 queueName = str( queueName )
5449 value = str( value )
5450 prefix = "work-queue-test"
5451 operation = "add"
5452 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5453 output = self.distPrimitivesSend( cmdStr )
5454 if "Invalid operation name" in output:
5455 main.log.warn( output )
5456 return main.ERROR
5457 elif "Done" in output:
5458 return main.TRUE
5459 except TypeError:
5460 main.log.exception( self.name + ": Object not as expected" )
5461 return main.ERROR
5462 except Exception:
5463 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005464 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005465
5466 def workQueueAddMultiple( self, queueName, value1, value2 ):
5467 """
5468 CLI command to add two strings to the specified Work Queue.
5469 This function uses the distributed primitives test app, which
5470 gives some cli access to distributed primitives for testing
5471 purposes only.
5472
5473 Required arguments:
5474 queueName - The name of the queue to add to
5475 value1 - The first value to add to the queue
5476 value2 - The second value to add to the queue
5477 returns:
5478 main.TRUE on success, main.FALSE on failure and
5479 main.ERROR on error.
5480 """
5481 try:
5482 queueName = str( queueName )
5483 value1 = str( value1 )
5484 value2 = str( value2 )
5485 prefix = "work-queue-test"
5486 operation = "addMultiple"
5487 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5488 output = self.distPrimitivesSend( cmdStr )
5489 if "Invalid operation name" in output:
5490 main.log.warn( output )
5491 return main.ERROR
5492 elif "Done" in output:
5493 return main.TRUE
5494 except TypeError:
5495 main.log.exception( self.name + ": Object not as expected" )
5496 return main.ERROR
5497 except Exception:
5498 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005499 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005500
5501 def workQueueTakeAndComplete( self, queueName, number=1 ):
5502 """
5503 CLI command to take a value from the specified Work Queue and compelte it.
5504 This function uses the distributed primitives test app, which
5505 gives some cli access to distributed primitives for testing
5506 purposes only.
5507
5508 Required arguments:
5509 queueName - The name of the queue to add to
5510 number - The number of items to take and complete
5511 returns:
5512 main.TRUE on success, main.FALSE on failure and
5513 main.ERROR on error.
5514 """
5515 try:
5516 queueName = str( queueName )
5517 number = str( int( number ) )
5518 prefix = "work-queue-test"
5519 operation = "takeAndComplete"
5520 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5521 output = self.distPrimitivesSend( cmdStr )
5522 if "Invalid operation name" in output:
5523 main.log.warn( output )
5524 return main.ERROR
5525 elif "Done" in output:
5526 return main.TRUE
5527 except TypeError:
5528 main.log.exception( self.name + ": Object not as expected" )
5529 return main.ERROR
5530 except Exception:
5531 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005532 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005533
5534 def workQueueDestroy( self, queueName ):
5535 """
5536 CLI command to destroy the specified Work Queue.
5537 This function uses the distributed primitives test app, which
5538 gives some cli access to distributed primitives for testing
5539 purposes only.
5540
5541 Required arguments:
5542 queueName - The name of the queue to add to
5543 returns:
5544 main.TRUE on success, main.FALSE on failure and
5545 main.ERROR on error.
5546 """
5547 try:
5548 queueName = str( queueName )
5549 prefix = "work-queue-test"
5550 operation = "destroy"
5551 cmdStr = " ".join( [ prefix, queueName, operation ] )
5552 output = self.distPrimitivesSend( cmdStr )
5553 if "Invalid operation name" in output:
5554 main.log.warn( output )
5555 return main.ERROR
5556 return main.TRUE
5557 except TypeError:
5558 main.log.exception( self.name + ": Object not as expected" )
5559 return main.ERROR
5560 except Exception:
5561 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005562 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005563
5564 def workQueueTotalPending( self, queueName ):
5565 """
5566 CLI command to get the Total Pending items of the specified Work Queue.
5567 This function uses the distributed primitives test app, which
5568 gives some cli access to distributed primitives for testing
5569 purposes only.
5570
5571 Required arguments:
5572 queueName - The name of the queue to add to
5573 returns:
5574 The number of Pending items in the specified work queue or
5575 None on error
5576 """
5577 try:
5578 queueName = str( queueName )
5579 prefix = "work-queue-test"
5580 operation = "totalPending"
5581 cmdStr = " ".join( [ prefix, queueName, operation ] )
5582 output = self.distPrimitivesSend( cmdStr )
5583 pattern = r'\d+'
5584 if "Invalid operation name" in output:
5585 main.log.warn( output )
5586 return None
5587 else:
5588 match = re.search( pattern, output )
5589 return match.group(0)
5590 except ( AttributeError, TypeError ):
5591 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5592 return None
5593 except Exception:
5594 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005595 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005596
5597 def workQueueTotalCompleted( self, queueName ):
5598 """
5599 CLI command to get the Total Completed items of the specified Work Queue.
5600 This function uses the distributed primitives test app, which
5601 gives some cli access to distributed primitives for testing
5602 purposes only.
5603
5604 Required arguments:
5605 queueName - The name of the queue to add to
5606 returns:
5607 The number of complete items in the specified work queue or
5608 None on error
5609 """
5610 try:
5611 queueName = str( queueName )
5612 prefix = "work-queue-test"
5613 operation = "totalCompleted"
5614 cmdStr = " ".join( [ prefix, queueName, operation ] )
5615 output = self.distPrimitivesSend( cmdStr )
5616 pattern = r'\d+'
5617 if "Invalid operation name" in output:
5618 main.log.warn( output )
5619 return None
5620 else:
5621 match = re.search( pattern, output )
5622 return match.group(0)
5623 except ( AttributeError, TypeError ):
5624 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5625 return None
5626 except Exception:
5627 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005628 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005629
5630 def workQueueTotalInProgress( self, queueName ):
5631 """
5632 CLI command to get the Total In Progress items of the specified Work Queue.
5633 This function uses the distributed primitives test app, which
5634 gives some cli access to distributed primitives for testing
5635 purposes only.
5636
5637 Required arguments:
5638 queueName - The name of the queue to add to
5639 returns:
5640 The number of In Progress items in the specified work queue or
5641 None on error
5642 """
5643 try:
5644 queueName = str( queueName )
5645 prefix = "work-queue-test"
5646 operation = "totalInProgress"
5647 cmdStr = " ".join( [ prefix, queueName, operation ] )
5648 output = self.distPrimitivesSend( cmdStr )
5649 pattern = r'\d+'
5650 if "Invalid operation name" in output:
5651 main.log.warn( output )
5652 return None
5653 else:
5654 match = re.search( pattern, output )
5655 return match.group(0)
5656 except ( AttributeError, TypeError ):
5657 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5658 return None
5659 except Exception:
5660 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005661 main.cleanAndExit()