blob: 9b0a50906c3703724bd926024a1db014e6008b82 [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
andrewonlab95ce8322014-10-13 14:12:04 -04004This driver enters the onos> prompt to issue commands.
5
kelvin8ec71442015-01-15 16:57:00 -08006Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -04007functions and document properly.
8
9If you are a contributor to the driver, please
10list your email here for future contact:
11
12jhall@onlab.us
13andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040014shreya@onlab.us
andrewonlab95ce8322014-10-13 14:12:04 -040015
16OCT 13 2014
Jeremy Songsterae01bba2016-07-11 15:39:17 -070017Modified 2016 by ON.Lab
18
19Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
20the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
21or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
andrewonlab95ce8322014-10-13 14:12:04 -040022
kelvin8ec71442015-01-15 16:57:00 -080023"""
andrewonlab95ce8322014-10-13 14:12:04 -040024import pexpect
25import re
Jon Hall30b82fa2015-03-04 17:15:43 -080026import json
27import types
Jon Hallbd16b922015-03-26 17:53:15 -070028import time
kelvin-onlaba4074292015-07-09 15:19:49 -070029import os
andrewonlab95ce8322014-10-13 14:12:04 -040030from drivers.common.clidriver import CLI
You Wangdb8cd0a2016-05-26 15:19:45 -070031from core.graph import Graph
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -070032from cStringIO import StringIO
33from itertools import izip
andrewonlab95ce8322014-10-13 14:12:04 -040034
kelvin8ec71442015-01-15 16:57:00 -080035class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040036
kelvin8ec71442015-01-15 16:57:00 -080037 def __init__( self ):
38 """
39 Initialize client
40 """
Jon Hallefbd9792015-03-05 16:11:36 -080041 self.name = None
42 self.home = None
43 self.handle = None
Devin Limdc78e202017-06-09 18:30:07 -070044 self.karafUser = None
45 self.karafPass = None
You Wangdb8cd0a2016-05-26 15:19:45 -070046 self.graph = Graph()
Devin Limdc78e202017-06-09 18:30:07 -070047 super( OnosCliDriver, self ).__init__()
kelvin8ec71442015-01-15 16:57:00 -080048
Devin Limdc78e202017-06-09 18:30:07 -070049 def checkOptions(self, var, defaultVar):
50 if var is None or var == "":
51 return defaultVar
52 return var
kelvin8ec71442015-01-15 16:57:00 -080053 def connect( self, **connectargs ):
54 """
andrewonlab95ce8322014-10-13 14:12:04 -040055 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080056 """
andrewonlab95ce8322014-10-13 14:12:04 -040057 try:
58 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080059 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070060 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040061 for key in self.options:
62 if key == "home":
Devin Limdc78e202017-06-09 18:30:07 -070063 self.home = self.options[ key ]
64 elif key == "karaf_username":
65 self.karafUser = self.options[ key ]
66 elif key == "karaf_password":
67 self.karafPass = self.options[ key ]
68
69 self.home = self.checkOptions(self.home, "~/onos")
70 self.karafUser = self.checkOptions(self.karafUser, self.user_name)
71 self.karafPass = self.checkOptions(self.karafPass, self.pwd )
andrewonlab95ce8322014-10-13 14:12:04 -040072
kelvin-onlaba4074292015-07-09 15:19:49 -070073 for key in self.options:
74 if key == 'onosIp':
75 self.onosIp = self.options[ 'onosIp' ]
76 break
77
kelvin8ec71442015-01-15 16:57:00 -080078 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070079
80 try:
Jon Hallc6793552016-01-19 14:18:37 -080081 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070082 self.ip_address = os.getenv( str( self.ip_address ) )
83 else:
84 main.log.info( self.name +
85 ": Trying to connect to " +
86 self.ip_address )
87
88 except KeyError:
89 main.log.info( "Invalid host name," +
90 " connecting to local host instead" )
91 self.ip_address = 'localhost'
92 except Exception as inst:
93 main.log.error( "Uncaught exception: " + str( inst ) )
94
kelvin8ec71442015-01-15 16:57:00 -080095 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080096 user_name=self.user_name,
97 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080098 port=self.port,
99 pwd=self.pwd,
100 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -0400101
kelvin8ec71442015-01-15 16:57:00 -0800102 self.handle.sendline( "cd " + self.home )
Devin Limdc78e202017-06-09 18:30:07 -0700103 self.handle.expect( self.prompt )
andrewonlab95ce8322014-10-13 14:12:04 -0400104 if self.handle:
105 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800106 else:
107 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -0400108 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800109 except TypeError:
110 main.log.exception( self.name + ": Object not as expected" )
111 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400112 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800113 main.log.error( self.name + ": EOF exception found" )
114 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400115 main.cleanup()
116 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800117 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800118 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400119 main.cleanup()
120 main.exit()
121
kelvin8ec71442015-01-15 16:57:00 -0800122 def disconnect( self ):
123 """
andrewonlab95ce8322014-10-13 14:12:04 -0400124 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800125 """
Jon Halld61331b2015-02-17 16:35:47 -0800126 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400127 try:
Jon Hall61282e32015-03-19 11:34:11 -0700128 if self.handle:
129 i = self.logout()
130 if i == main.TRUE:
131 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700132 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700133 self.handle.sendline( "exit" )
134 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800135 except TypeError:
136 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800137 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400138 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800139 main.log.error( self.name + ": EOF exception found" )
140 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700141 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700142 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700143 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800144 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800145 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400146 response = main.FALSE
147 return response
148
kelvin8ec71442015-01-15 16:57:00 -0800149 def logout( self ):
150 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500151 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700152 Returns main.TRUE if exited CLI and
153 main.FALSE on timeout (not guranteed you are disconnected)
154 None on TypeError
155 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800156 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500157 try:
Jon Hall61282e32015-03-19 11:34:11 -0700158 if self.handle:
159 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700160 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ],
Jon Hall61282e32015-03-19 11:34:11 -0700161 timeout=10 )
162 if i == 0: # In ONOS CLI
163 self.handle.sendline( "logout" )
Devin Limdc78e202017-06-09 18:30:07 -0700164 j = self.handle.expect( [ self.prompt,
Jon Hallbfe00002016-04-05 10:23:54 -0700165 "Command not found:",
166 pexpect.TIMEOUT ] )
167 if j == 0: # Successfully logged out
168 return main.TRUE
169 elif j == 1 or j == 2:
170 # ONOS didn't fully load, and logout command isn't working
171 # or the command timed out
172 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700173 try:
Devin Limdc78e202017-06-09 18:30:07 -0700174 self.handle.expect( self.prompt )
Jon Hall64ab3bd2016-05-13 11:29:44 -0700175 except pexpect.TIMEOUT:
176 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700177 return main.TRUE
Jon Halle0f0b342017-04-18 11:43:47 -0700178 else: # some other output
Jon Hallbfe00002016-04-05 10:23:54 -0700179 main.log.warn( "Unknown repsonse to logout command: '{}'",
180 repr( self.handle.before ) )
181 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700182 elif i == 1: # not in CLI
183 return main.TRUE
184 elif i == 3: # Timeout
185 return main.FALSE
186 else:
andrewonlab9627f432014-11-14 12:45:10 -0500187 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800188 except TypeError:
189 main.log.exception( self.name + ": Object not as expected" )
190 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500191 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800192 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700193 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500194 main.cleanup()
195 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700196 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700197 main.log.error( self.name +
198 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800199 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800200 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500201 main.cleanup()
202 main.exit()
203
kelvin-onlabd3b64892015-01-20 13:26:24 -0800204 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800205 """
andrewonlab95ce8322014-10-13 14:12:04 -0400206 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800207
andrewonlab95ce8322014-10-13 14:12:04 -0400208 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800209 """
andrewonlab95ce8322014-10-13 14:12:04 -0400210 try:
211 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800212 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400213 main.cleanup()
214 main.exit()
215 else:
kelvin8ec71442015-01-15 16:57:00 -0800216 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800217 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800218 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400219 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800220 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800221 handleBefore = self.handle.before
222 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800223 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800224 self.handle.sendline("")
Devin Limdc78e202017-06-09 18:30:07 -0700225 self.handle.expect(self.prompt)
andrew@onlab.usc400b112015-01-21 15:33:19 -0800226 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400227
kelvin-onlabd3b64892015-01-20 13:26:24 -0800228 main.log.info( "Cell call returned: " + handleBefore +
229 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400230
231 return main.TRUE
232
Jon Halld4d4b372015-01-28 16:02:41 -0800233 except TypeError:
234 main.log.exception( self.name + ": Object not as expected" )
235 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400236 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800237 main.log.error( self.name + ": eof exception found" )
238 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400239 main.cleanup()
240 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800241 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800242 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400243 main.cleanup()
244 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800245
pingping-lin57a56ce2015-05-20 16:43:48 -0700246 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800247 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800248 """
Jon Hallefbd9792015-03-05 16:11:36 -0800249 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800250 by user would be used to set the current karaf shell idle timeout.
251 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800252 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800253 Below is an example to start a session with 60 seconds idle timeout
254 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800255
Hari Krishna25d42f72015-01-05 15:08:28 -0800256 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800257 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800258
kelvin-onlabd3b64892015-01-20 13:26:24 -0800259 Note: karafTimeout is left as str so that this could be read
260 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800261 """
You Wangf69ab392016-01-26 16:34:38 -0800262 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400263 try:
Jon Hall67253832016-12-05 09:47:13 -0800264 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800265 self.handle.sendline( "" )
266 x = self.handle.expect( [
Devin Limdc78e202017-06-09 18:30:07 -0700267 self.prompt, "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500268 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800269 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500270 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400271
Jon Hall67253832016-12-05 09:47:13 -0800272 # Not in CLI so login
Chiyu Chengef109502016-11-21 15:51:38 -0800273 if waitForStart:
274 # Wait for onos start ( -w ) and enter onos cli
275 startCliCommand = "onos -w "
276 else:
277 startCliCommand = "onos "
278 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800279 i = self.handle.expect( [
280 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700281 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400282
283 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800284 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800285 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800286 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800287 "config:property-set -p org.apache.karaf.shell\
288 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800289 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700290 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800291 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800292 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400293 return main.TRUE
294 else:
kelvin8ec71442015-01-15 16:57:00 -0800295 # If failed, send ctrl+c to process and try again
296 main.log.info( "Starting CLI failed. Retrying..." )
297 self.handle.send( "\x03" )
Chiyu Chengef109502016-11-21 15:51:38 -0800298 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800299 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
300 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400301 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800302 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800303 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800304 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800305 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800306 "config:property-set -p org.apache.karaf.shell\
307 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800308 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700309 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800310 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800311 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400312 return main.TRUE
313 else:
kelvin8ec71442015-01-15 16:57:00 -0800314 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800315 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400316 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400317
Jon Halld4d4b372015-01-28 16:02:41 -0800318 except TypeError:
319 main.log.exception( self.name + ": Object not as expected" )
320 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400321 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800322 main.log.error( self.name + ": EOF exception found" )
323 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400324 main.cleanup()
325 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800326 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800327 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400328 main.cleanup()
329 main.exit()
330
suibin zhang116647a2016-05-06 16:30:09 -0700331 def startCellCli( self, karafTimeout="",
332 commandlineTimeout=10, onosStartTimeout=60 ):
333 """
334 Start CLI on onos ecll handle.
335
336 karafTimeout is an optional argument. karafTimeout value passed
337 by user would be used to set the current karaf shell idle timeout.
338 Note that when ever this property is modified the shell will exit and
339 the subsequent login would reflect new idle timeout.
340 Below is an example to start a session with 60 seconds idle timeout
341 ( input value is in milliseconds ):
342
343 tValue = "60000"
344
345 Note: karafTimeout is left as str so that this could be read
346 and passed to startOnosCli from PARAMS file as str.
347 """
348
349 try:
350 self.handle.sendline( "" )
351 x = self.handle.expect( [
Devin Limdc78e202017-06-09 18:30:07 -0700352 self.prompt, "onos>" ], commandlineTimeout)
suibin zhang116647a2016-05-06 16:30:09 -0700353
354 if x == 1:
355 main.log.info( "ONOS cli is already running" )
356 return main.TRUE
357
358 # Wait for onos start ( -w ) and enter onos cli
359 self.handle.sendline( "/opt/onos/bin/onos" )
360 i = self.handle.expect( [
361 "onos>",
362 pexpect.TIMEOUT ], onosStartTimeout )
363
364 if i == 0:
365 main.log.info( self.name + " CLI Started successfully" )
366 if karafTimeout:
367 self.handle.sendline(
368 "config:property-set -p org.apache.karaf.shell\
369 sshIdleTimeout " +
370 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700371 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700372 self.handle.sendline( "/opt/onos/bin/onos" )
373 self.handle.expect( "onos>" )
374 return main.TRUE
375 else:
376 # If failed, send ctrl+c to process and try again
377 main.log.info( "Starting CLI failed. Retrying..." )
378 self.handle.send( "\x03" )
379 self.handle.sendline( "/opt/onos/bin/onos" )
380 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
381 timeout=30 )
382 if i == 0:
383 main.log.info( self.name + " CLI Started " +
384 "successfully after retry attempt" )
385 if karafTimeout:
386 self.handle.sendline(
387 "config:property-set -p org.apache.karaf.shell\
388 sshIdleTimeout " +
389 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700390 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700391 self.handle.sendline( "/opt/onos/bin/onos" )
392 self.handle.expect( "onos>" )
393 return main.TRUE
394 else:
395 main.log.error( "Connection to CLI " +
396 self.name + " timeout" )
397 return main.FALSE
398
399 except TypeError:
400 main.log.exception( self.name + ": Object not as expected" )
401 return None
402 except pexpect.EOF:
403 main.log.error( self.name + ": EOF exception found" )
404 main.log.error( self.name + ": " + self.handle.before )
405 main.cleanup()
406 main.exit()
407 except Exception:
408 main.log.exception( self.name + ": Uncaught exception!" )
409 main.cleanup()
410 main.exit()
411
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800412 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800413 """
414 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800415 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800416 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700417 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800418 Available level: DEBUG, TRACE, INFO, WARN, ERROR
419 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800420 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800421 """
422 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800423 lvlStr = ""
424 if level:
425 lvlStr = "--level=" + level
426
kelvin-onlab338f5512015-02-06 10:53:16 -0800427 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700428 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800429 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800430
kelvin-onlab9f541032015-02-04 16:19:53 -0800431 response = self.handle.before
432 if re.search( "Error", response ):
433 return main.FALSE
434 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700435 except pexpect.TIMEOUT:
436 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700437 if noExit:
438 main.cleanup()
439 return None
440 else:
441 main.cleanup()
442 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800443 except pexpect.EOF:
444 main.log.error( self.name + ": EOF exception found" )
445 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700446 if noExit:
447 main.cleanup()
448 return None
449 else:
450 main.cleanup()
451 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800452 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800453 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700454 if noExit:
455 main.cleanup()
456 return None
457 else:
458 main.cleanup()
459 main.exit()
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:
491 main.cleanup()
492 main.exit()
Jon Halla495f562016-05-16 18:03:26 -0700493 else:
494 main.cleanup()
495 main.exit()
496 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700497 main.log.warn( "Timeout when testing cli responsiveness" )
498 main.log.debug( self.handle.before )
499 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Halla495f562016-05-16 18:03:26 -0700500 self.handle.expect( "onos>" )
501
Jon Hall14a03b52016-05-11 12:07:30 -0700502 if debug:
503 # NOTE: This adds and average of .4 seconds per call
504 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700505 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800506 self.handle.sendline( cmdStr )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700507 if dollarSign:
508 i = self.handle.expect( ["onos>"], timeout )
509 else:
Devin Limdc78e202017-06-09 18:30:07 -0700510 i = self.handle.expect( ["onos>", self.prompt], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800511 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800512 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800513 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
514 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700515 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700516 main.log.debug( self.name + ": Raw output" )
517 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700518
519 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800520 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800521 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700522 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700523 main.log.debug( self.name + ": ansiEscape output" )
524 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700525
kelvin-onlabfb521662015-02-27 09:52:40 -0800526 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800527 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700528 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700529 main.log.debug( self.name + ": Removed extra returns " +
530 "from output" )
531 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700532
533 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800534 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700535 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700536 main.log.debug( self.name + ": parsed and stripped output" )
537 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700538
Jon Hall63604932015-02-26 17:09:50 -0800539 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700540 output = response.split( cmdStr.strip(), 1 )
541 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700542 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700543 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700544 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800545 output = output[1].strip()
546 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800547 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800548 return output
GlennRCed771242016-01-13 17:02:47 -0800549 except pexpect.TIMEOUT:
550 main.log.error( self.name + ":ONOS timeout" )
551 if debug:
552 main.log.debug( self.handle.before )
553 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700554 except IndexError:
555 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700556 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700557 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800558 except TypeError:
559 main.log.exception( self.name + ": Object not as expected" )
560 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400561 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800562 main.log.error( self.name + ": EOF exception found" )
563 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700564 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700565 return None
566 else:
567 main.cleanup()
568 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800569 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800570 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700571 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700572 return None
573 else:
574 main.cleanup()
575 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400576
kelvin8ec71442015-01-15 16:57:00 -0800577 # IMPORTANT NOTE:
578 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800579 # the cli command changing 'a:b' with 'aB'.
580 # Ex ) onos:topology > onosTopology
581 # onos:links > onosLinks
582 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800583
kelvin-onlabd3b64892015-01-20 13:26:24 -0800584 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800585 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400586 Adds a new cluster node by ID and address information.
587 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800588 * nodeId
589 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400590 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800591 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800592 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400593 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800594 cmdStr = "add-node " + str( nodeId ) + " " +\
595 str( ONOSIp ) + " " + str( tcpPort )
596 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700597 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800598 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800599 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800600 main.log.error( "Error in adding node" )
601 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800602 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400603 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800604 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400605 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800606 except AssertionError:
607 main.log.exception( "" )
608 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800609 except TypeError:
610 main.log.exception( self.name + ": Object not as expected" )
611 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400612 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800613 main.log.error( self.name + ": EOF exception found" )
614 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400615 main.cleanup()
616 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800617 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800618 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400619 main.cleanup()
620 main.exit()
621
kelvin-onlabd3b64892015-01-20 13:26:24 -0800622 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800623 """
andrewonlab86dc3082014-10-13 18:18:38 -0400624 Removes a cluster by ID
625 Issues command: 'remove-node [<node-id>]'
626 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800627 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800628 """
andrewonlab86dc3082014-10-13 18:18:38 -0400629 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400630
kelvin-onlabd3b64892015-01-20 13:26:24 -0800631 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700632 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700633 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800634 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700635 if re.search( "Error", handle ):
636 main.log.error( "Error in removing node" )
637 main.log.error( handle )
638 return main.FALSE
639 else:
640 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800641 except AssertionError:
642 main.log.exception( "" )
643 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800644 except TypeError:
645 main.log.exception( self.name + ": Object not as expected" )
646 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400647 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800648 main.log.error( self.name + ": EOF exception found" )
649 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400650 main.cleanup()
651 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800652 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800653 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400654 main.cleanup()
655 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400656
Jon Hall61282e32015-03-19 11:34:11 -0700657 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800658 """
andrewonlab7c211572014-10-15 16:45:20 -0400659 List the nodes currently visible
660 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700661 Optional argument:
662 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800663 """
andrewonlab7c211572014-10-15 16:45:20 -0400664 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700665 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700666 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700667 cmdStr += " -j"
668 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700669 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800670 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700671 return output
Jon Hallc6793552016-01-19 14:18:37 -0800672 except AssertionError:
673 main.log.exception( "" )
674 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800675 except TypeError:
676 main.log.exception( self.name + ": Object not as expected" )
677 return None
andrewonlab7c211572014-10-15 16:45:20 -0400678 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800679 main.log.error( self.name + ": EOF exception found" )
680 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400681 main.cleanup()
682 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800683 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800684 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400685 main.cleanup()
686 main.exit()
687
kelvin8ec71442015-01-15 16:57:00 -0800688 def topology( self ):
689 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700690 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700691 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700692 Return:
693 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800694 """
andrewonlab95ce8322014-10-13 14:12:04 -0400695 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700696 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800697 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800698 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800699 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700700 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400701 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800702 except AssertionError:
703 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800704 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800705 except TypeError:
706 main.log.exception( self.name + ": Object not as expected" )
707 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400708 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800709 main.log.error( self.name + ": EOF exception found" )
710 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400711 main.cleanup()
712 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800713 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800714 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400715 main.cleanup()
716 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800717
jenkins7ead5a82015-03-13 10:28:21 -0700718 def deviceRemove( self, deviceId ):
719 """
720 Removes particular device from storage
721
722 TODO: refactor this function
723 """
724 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700725 cmdStr = "device-remove " + str( deviceId )
726 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800727 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800728 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700729 if re.search( "Error", handle ):
730 main.log.error( "Error in removing device" )
731 main.log.error( handle )
732 return main.FALSE
733 else:
734 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800735 except AssertionError:
736 main.log.exception( "" )
737 return None
jenkins7ead5a82015-03-13 10:28:21 -0700738 except TypeError:
739 main.log.exception( self.name + ": Object not as expected" )
740 return None
741 except pexpect.EOF:
742 main.log.error( self.name + ": EOF exception found" )
743 main.log.error( self.name + ": " + self.handle.before )
744 main.cleanup()
745 main.exit()
746 except Exception:
747 main.log.exception( self.name + ": Uncaught exception!" )
748 main.cleanup()
749 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700750
kelvin-onlabd3b64892015-01-20 13:26:24 -0800751 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800752 """
Jon Hall7b02d952014-10-17 20:14:54 -0400753 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400754 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800755 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800756 """
andrewonlab86dc3082014-10-13 18:18:38 -0400757 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700758 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800759 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700760 cmdStr += " -j"
761 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800762 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800763 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700764 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800765 except AssertionError:
766 main.log.exception( "" )
767 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800768 except TypeError:
769 main.log.exception( self.name + ": Object not as expected" )
770 return None
andrewonlab7c211572014-10-15 16:45:20 -0400771 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800772 main.log.error( self.name + ": EOF exception found" )
773 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400774 main.cleanup()
775 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800776 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800777 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400778 main.cleanup()
779 main.exit()
780
kelvin-onlabd3b64892015-01-20 13:26:24 -0800781 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800782 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800783 This balances the devices across all controllers
784 by issuing command: 'onos> onos:balance-masters'
785 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800786 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800787 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800788 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700789 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800790 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800791 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700792 if re.search( "Error", handle ):
793 main.log.error( "Error in balancing masters" )
794 main.log.error( handle )
795 return main.FALSE
796 else:
797 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800798 except AssertionError:
799 main.log.exception( "" )
800 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800801 except TypeError:
802 main.log.exception( self.name + ": Object not as expected" )
803 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800804 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800805 main.log.error( self.name + ": EOF exception found" )
806 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800807 main.cleanup()
808 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800809 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800810 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800811 main.cleanup()
812 main.exit()
813
Jon Hallc6793552016-01-19 14:18:37 -0800814 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700815 """
816 Returns the output of the masters command.
817 Optional argument:
818 * jsonFormat - boolean indicating if you want output in json
819 """
820 try:
821 cmdStr = "onos:masters"
822 if jsonFormat:
823 cmdStr += " -j"
824 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700825 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800826 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700827 return output
Jon Hallc6793552016-01-19 14:18:37 -0800828 except AssertionError:
829 main.log.exception( "" )
830 return None
acsmars24950022015-07-30 18:00:43 -0700831 except TypeError:
832 main.log.exception( self.name + ": Object not as expected" )
833 return None
834 except pexpect.EOF:
835 main.log.error( self.name + ": EOF exception found" )
836 main.log.error( self.name + ": " + self.handle.before )
837 main.cleanup()
838 main.exit()
839 except Exception:
840 main.log.exception( self.name + ": Uncaught exception!" )
841 main.cleanup()
842 main.exit()
843
Jon Hallc6793552016-01-19 14:18:37 -0800844 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700845 """
846 Uses the master command to check that the devices' leadership
847 is evenly divided
848
849 Dependencies: checkMasters() and summary()
850
Jon Hall6509dbf2016-06-21 17:01:17 -0700851 Returns main.TRUE if the devices are balanced
852 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700853 Exits on Exception
854 Returns None on TypeError
855 """
856 try:
Jon Hallc6793552016-01-19 14:18:37 -0800857 summaryOutput = self.summary()
858 totalDevices = json.loads( summaryOutput )[ "devices" ]
859 except ( TypeError, ValueError ):
860 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
861 return None
862 try:
acsmars24950022015-07-30 18:00:43 -0700863 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800864 mastersOutput = self.checkMasters()
865 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700866 first = masters[ 0 ][ "size" ]
867 for master in masters:
868 totalOwnedDevices += master[ "size" ]
869 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
870 main.log.error( "Mastership not balanced" )
871 main.log.info( "\n" + self.checkMasters( False ) )
872 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700873 main.log.info( "Mastership balanced between " +
874 str( len(masters) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700875 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800876 except ( TypeError, ValueError ):
877 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700878 return None
879 except pexpect.EOF:
880 main.log.error( self.name + ": EOF exception found" )
881 main.log.error( self.name + ": " + self.handle.before )
882 main.cleanup()
883 main.exit()
884 except Exception:
885 main.log.exception( self.name + ": Uncaught exception!" )
886 main.cleanup()
887 main.exit()
888
YPZhangfebf7302016-05-24 16:45:56 -0700889 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800890 """
Jon Halle8217482014-10-17 13:49:14 -0400891 Lists all core links
892 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800893 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800894 """
Jon Halle8217482014-10-17 13:49:14 -0400895 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700896 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800897 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700898 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700899 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800900 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800901 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700902 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800903 except AssertionError:
904 main.log.exception( "" )
905 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800906 except TypeError:
907 main.log.exception( self.name + ": Object not as expected" )
908 return None
Jon Halle8217482014-10-17 13:49:14 -0400909 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800910 main.log.error( self.name + ": EOF exception found" )
911 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400912 main.cleanup()
913 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800914 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800915 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400916 main.cleanup()
917 main.exit()
918
kelvin-onlabd3b64892015-01-20 13:26:24 -0800919 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800920 """
Jon Halle8217482014-10-17 13:49:14 -0400921 Lists all ports
922 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800923 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800924 """
Jon Halle8217482014-10-17 13:49:14 -0400925 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700926 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800927 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700928 cmdStr += " -j"
929 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800930 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800931 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700932 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800933 except AssertionError:
934 main.log.exception( "" )
935 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800936 except TypeError:
937 main.log.exception( self.name + ": Object not as expected" )
938 return None
Jon Halle8217482014-10-17 13:49:14 -0400939 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800940 main.log.error( self.name + ": EOF exception found" )
941 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400942 main.cleanup()
943 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800944 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800945 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400946 main.cleanup()
947 main.exit()
948
kelvin-onlabd3b64892015-01-20 13:26:24 -0800949 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800950 """
Jon Hall983a1702014-10-28 18:44:22 -0400951 Lists all devices and the controllers with roles assigned to them
952 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800953 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800954 """
andrewonlab7c211572014-10-15 16:45:20 -0400955 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700956 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800957 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700958 cmdStr += " -j"
959 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800960 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800961 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700962 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800963 except AssertionError:
964 main.log.exception( "" )
965 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800966 except TypeError:
967 main.log.exception( self.name + ": Object not as expected" )
968 return None
Jon Hall983a1702014-10-28 18:44:22 -0400969 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800970 main.log.error( self.name + ": EOF exception found" )
971 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400972 main.cleanup()
973 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800974 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800975 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400976 main.cleanup()
977 main.exit()
978
kelvin-onlabd3b64892015-01-20 13:26:24 -0800979 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800980 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800981 Given the a string containing the json representation of the "roles"
982 cli command and a partial or whole device id, returns a json object
983 containing the roles output for the first device whose id contains
984 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400985
986 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800987 A dict of the role assignments for the given device or
988 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800989 """
Jon Hall983a1702014-10-28 18:44:22 -0400990 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800991 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400992 return None
993 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800994 rawRoles = self.roles()
995 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800996 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800997 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800998 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800999 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001000 return device
1001 return None
Jon Hallc6793552016-01-19 14:18:37 -08001002 except ( TypeError, ValueError ):
1003 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001004 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001005 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001006 main.log.error( self.name + ": EOF exception found" )
1007 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -04001008 main.cleanup()
1009 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001010 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001011 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -04001012 main.cleanup()
1013 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001014
kelvin-onlabd3b64892015-01-20 13:26:24 -08001015 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001016 """
Jon Hall94fd0472014-12-08 11:52:42 -08001017 Iterates through each device and checks if there is a master assigned
1018 Returns: main.TRUE if each device has a master
1019 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001020 """
Jon Hall94fd0472014-12-08 11:52:42 -08001021 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001022 rawRoles = self.roles()
1023 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001024 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001025 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001026 # print device
1027 if device[ 'master' ] == "none":
1028 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001029 return main.FALSE
1030 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001031 except ( TypeError, ValueError ):
1032 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001033 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001034 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001035 main.log.error( self.name + ": EOF exception found" )
1036 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001037 main.cleanup()
1038 main.exit()
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!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001041 main.cleanup()
1042 main.exit()
1043
kelvin-onlabd3b64892015-01-20 13:26:24 -08001044 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001045 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001046 Returns string of paths, and the cost.
1047 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001048 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001049 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001050 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1051 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001052 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001053 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001054 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001055 main.log.error( "Error in getting paths" )
1056 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001057 else:
kelvin8ec71442015-01-15 16:57:00 -08001058 path = handle.split( ";" )[ 0 ]
1059 cost = handle.split( ";" )[ 1 ]
1060 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001061 except AssertionError:
1062 main.log.exception( "" )
1063 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001064 except TypeError:
1065 main.log.exception( self.name + ": Object not as expected" )
1066 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001067 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001068 main.log.error( self.name + ": EOF exception found" )
1069 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001070 main.cleanup()
1071 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001072 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001073 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001074 main.cleanup()
1075 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001076
kelvin-onlabd3b64892015-01-20 13:26:24 -08001077 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001078 """
Jon Hallffb386d2014-11-21 13:43:38 -08001079 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001080 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001081 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001082 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001083 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001084 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001086 cmdStr += " -j"
1087 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001088 if handle:
1089 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001090 # TODO: Maybe make this less hardcoded
1091 # ConsistentMap Exceptions
1092 assert "org.onosproject.store.service" not in handle
1093 # Node not leader
1094 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001095 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001096 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001097 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001098 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001099 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001100 except TypeError:
1101 main.log.exception( self.name + ": Object not as expected" )
1102 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001103 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001104 main.log.error( self.name + ": EOF exception found" )
1105 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001106 main.cleanup()
1107 main.exit()
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!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001110 main.cleanup()
1111 main.exit()
1112
kelvin-onlabd3b64892015-01-20 13:26:24 -08001113 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001114 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001115 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001116
Jon Hallefbd9792015-03-05 16:11:36 -08001117 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001118 partial mac address
1119
Jon Hall42db6dc2014-10-24 19:03:48 -04001120 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001121 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001122 try:
kelvin8ec71442015-01-15 16:57:00 -08001123 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001124 return None
1125 else:
1126 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001127 rawHosts = self.hosts()
1128 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001129 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001130 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001131 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001132 if not host:
1133 pass
1134 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001135 return host
1136 return None
Jon Hallc6793552016-01-19 14:18:37 -08001137 except ( TypeError, ValueError ):
1138 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001139 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001140 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001141 main.log.error( self.name + ": EOF exception found" )
1142 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001143 main.cleanup()
1144 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001145 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001146 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001147 main.cleanup()
1148 main.exit()
1149
kelvin-onlabd3b64892015-01-20 13:26:24 -08001150 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001151 """
1152 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001153 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001154
andrewonlab3f0a4af2014-10-17 12:25:14 -04001155 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001156 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001157 IMPORTANT:
1158 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001159 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001160 Furthermore, it assumes that value of VLAN is '-1'
1161 Description:
kelvin8ec71442015-01-15 16:57:00 -08001162 Converts mininet hosts ( h1, h2, h3... ) into
1163 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1164 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001165 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001166 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001167
kelvin-onlabd3b64892015-01-20 13:26:24 -08001168 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001169 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001170 hostHex = hex( int( host ) ).zfill( 12 )
1171 hostHex = str( hostHex ).replace( 'x', '0' )
1172 i = iter( str( hostHex ) )
1173 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1174 hostHex = hostHex + "/-1"
1175 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001176
kelvin-onlabd3b64892015-01-20 13:26:24 -08001177 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001178
Jon Halld4d4b372015-01-28 16:02:41 -08001179 except TypeError:
1180 main.log.exception( self.name + ": Object not as expected" )
1181 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001182 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001183 main.log.error( self.name + ": EOF exception found" )
1184 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001185 main.cleanup()
1186 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001187 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001188 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001189 main.cleanup()
1190 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001191
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001192 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001193 """
andrewonlabe6745342014-10-17 14:29:13 -04001194 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001195 * hostIdOne: ONOS host id for host1
1196 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001197 Optional:
1198 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001199 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001200 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001201 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001202 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001203 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001204 Returns:
1205 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001206 """
andrewonlabe6745342014-10-17 14:29:13 -04001207 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001208 cmdStr = "add-host-intent "
1209 if vlanId:
1210 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001211 if setVlan:
1212 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001213 if encap:
1214 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001215 if bandwidth:
1216 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001217 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001218 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001219 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001220 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001221 if re.search( "Error", handle ):
1222 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001223 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001224 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001225 else:
1226 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001227 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1228 match = re.search('id=0x([\da-f]+),', handle)
1229 if match:
1230 return match.group()[3:-1]
1231 else:
1232 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001233 main.log.debug( "Response from ONOS was: " +
1234 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001235 return None
Jon Hallc6793552016-01-19 14:18:37 -08001236 except AssertionError:
1237 main.log.exception( "" )
1238 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001239 except TypeError:
1240 main.log.exception( self.name + ": Object not as expected" )
1241 return None
andrewonlabe6745342014-10-17 14:29:13 -04001242 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001243 main.log.error( self.name + ": EOF exception found" )
1244 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001245 main.cleanup()
1246 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001247 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001248 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001249 main.cleanup()
1250 main.exit()
1251
kelvin-onlabd3b64892015-01-20 13:26:24 -08001252 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001253 """
andrewonlab7b31d232014-10-24 13:31:47 -04001254 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001255 * ingressDevice: device id of ingress device
1256 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001257 Optional:
1258 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001259 Description:
1260 Adds an optical intent by specifying an ingress and egress device
1261 Returns:
1262 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001263 """
andrewonlab7b31d232014-10-24 13:31:47 -04001264 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001265 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1266 " " + str( egressDevice )
1267 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001268 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001269 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001270 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001271 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001272 main.log.error( "Error in adding Optical intent" )
1273 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001274 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001275 main.log.info( "Optical intent installed between " +
1276 str( ingressDevice ) + " and " +
1277 str( egressDevice ) )
1278 match = re.search('id=0x([\da-f]+),', handle)
1279 if match:
1280 return match.group()[3:-1]
1281 else:
1282 main.log.error( "Error, intent ID not found" )
1283 return None
Jon Hallc6793552016-01-19 14:18:37 -08001284 except AssertionError:
1285 main.log.exception( "" )
1286 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001287 except TypeError:
1288 main.log.exception( self.name + ": Object not as expected" )
1289 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001290 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001291 main.log.error( self.name + ": EOF exception found" )
1292 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001293 main.cleanup()
1294 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001295 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001296 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001297 main.cleanup()
1298 main.exit()
1299
kelvin-onlabd3b64892015-01-20 13:26:24 -08001300 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001301 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001302 ingressDevice,
1303 egressDevice,
1304 portIngress="",
1305 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001306 ethType="",
1307 ethSrc="",
1308 ethDst="",
1309 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001310 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001311 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001312 ipProto="",
1313 ipSrc="",
1314 ipDst="",
1315 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001316 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001317 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001318 setVlan="",
1319 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001320 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001321 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001322 * ingressDevice: device id of ingress device
1323 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001324 Optional:
1325 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001326 * ethSrc: specify ethSrc ( i.e. src mac addr )
1327 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001328 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001329 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001330 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001331 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001332 * ipSrc: specify ip source address
1333 * ipDst: specify ip destination address
1334 * tcpSrc: specify tcp source port
1335 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001336 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001337 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001338 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001339 Description:
kelvin8ec71442015-01-15 16:57:00 -08001340 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001341 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001342 Returns:
1343 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001344
Jon Halle3f39ff2015-01-13 11:50:53 -08001345 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001346 options developers provide for point-to-point
1347 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001348 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001349 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001350 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001351
Jeremy Songsterff553672016-05-12 17:06:23 -07001352 if ethType:
1353 cmd += " --ethType " + str( ethType )
1354 if ethSrc:
1355 cmd += " --ethSrc " + str( ethSrc )
1356 if ethDst:
1357 cmd += " --ethDst " + str( ethDst )
1358 if bandwidth:
1359 cmd += " --bandwidth " + str( bandwidth )
1360 if lambdaAlloc:
1361 cmd += " --lambda "
1362 if ipProto:
1363 cmd += " --ipProto " + str( ipProto )
1364 if ipSrc:
1365 cmd += " --ipSrc " + str( ipSrc )
1366 if ipDst:
1367 cmd += " --ipDst " + str( ipDst )
1368 if tcpSrc:
1369 cmd += " --tcpSrc " + str( tcpSrc )
1370 if tcpDst:
1371 cmd += " --tcpDst " + str( tcpDst )
1372 if vlanId:
1373 cmd += " -v " + str( vlanId )
1374 if setVlan:
1375 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001376 if encap:
1377 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001378 if protected:
1379 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001380
kelvin8ec71442015-01-15 16:57:00 -08001381 # Check whether the user appended the port
1382 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001383 if "/" in ingressDevice:
1384 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001385 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001386 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001387 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001388 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001389 # Would it make sense to throw an exception and exit
1390 # the test?
1391 return None
andrewonlab36af3822014-11-18 17:48:18 -05001392
kelvin8ec71442015-01-15 16:57:00 -08001393 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001394 str( ingressDevice ) + "/" +\
1395 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001396
kelvin-onlabd3b64892015-01-20 13:26:24 -08001397 if "/" in egressDevice:
1398 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001399 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001400 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001401 main.log.error( "You must specify the egress port" )
1402 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001403
kelvin8ec71442015-01-15 16:57:00 -08001404 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001405 str( egressDevice ) + "/" +\
1406 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001407
kelvin-onlab898a6c62015-01-16 14:13:53 -08001408 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001409 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001410 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001411 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001412 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001413 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001414 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001415 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001416 # TODO: print out all the options in this message?
1417 main.log.info( "Point-to-point intent installed between " +
1418 str( ingressDevice ) + " and " +
1419 str( egressDevice ) )
1420 match = re.search('id=0x([\da-f]+),', handle)
1421 if match:
1422 return match.group()[3:-1]
1423 else:
1424 main.log.error( "Error, intent ID not found" )
1425 return None
Jon Hallc6793552016-01-19 14:18:37 -08001426 except AssertionError:
1427 main.log.exception( "" )
1428 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001429 except TypeError:
1430 main.log.exception( self.name + ": Object not as expected" )
1431 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001432 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001433 main.log.error( self.name + ": EOF exception found" )
1434 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001435 main.cleanup()
1436 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001437 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001438 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001439 main.cleanup()
1440 main.exit()
1441
kelvin-onlabd3b64892015-01-20 13:26:24 -08001442 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001443 self,
shahshreyac2f97072015-03-19 17:04:29 -07001444 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001445 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001446 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001447 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001448 ethType="",
1449 ethSrc="",
1450 ethDst="",
1451 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001452 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001453 ipProto="",
1454 ipSrc="",
1455 ipDst="",
1456 tcpSrc="",
1457 tcpDst="",
1458 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001459 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001460 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001461 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001462 partial=False,
1463 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001464 """
shahshreyad0c80432014-12-04 16:56:05 -08001465 Note:
shahshreya70622b12015-03-19 17:19:00 -07001466 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001467 is same. That is, all ingress devices include port numbers
1468 with a "/" or all ingress devices could specify device
1469 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001470 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001471 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001472 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001473 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001474 Optional:
1475 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001476 * ethSrc: specify ethSrc ( i.e. src mac addr )
1477 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001478 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001479 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001480 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001481 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001482 * ipSrc: specify ip source address
1483 * ipDst: specify ip destination address
1484 * tcpSrc: specify tcp source port
1485 * tcpDst: specify tcp destination port
1486 * setEthSrc: action to Rewrite Source MAC Address
1487 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001488 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001489 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001490 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001491 Description:
kelvin8ec71442015-01-15 16:57:00 -08001492 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001493 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001494 Returns:
1495 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001496
Jon Halle3f39ff2015-01-13 11:50:53 -08001497 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001498 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001499 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001500 """
shahshreyad0c80432014-12-04 16:56:05 -08001501 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001502 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001503
Jeremy Songsterff553672016-05-12 17:06:23 -07001504 if ethType:
1505 cmd += " --ethType " + str( ethType )
1506 if ethSrc:
1507 cmd += " --ethSrc " + str( ethSrc )
1508 if ethDst:
1509 cmd += " --ethDst " + str( ethDst )
1510 if bandwidth:
1511 cmd += " --bandwidth " + str( bandwidth )
1512 if lambdaAlloc:
1513 cmd += " --lambda "
1514 if ipProto:
1515 cmd += " --ipProto " + str( ipProto )
1516 if ipSrc:
1517 cmd += " --ipSrc " + str( ipSrc )
1518 if ipDst:
1519 cmd += " --ipDst " + str( ipDst )
1520 if tcpSrc:
1521 cmd += " --tcpSrc " + str( tcpSrc )
1522 if tcpDst:
1523 cmd += " --tcpDst " + str( tcpDst )
1524 if setEthSrc:
1525 cmd += " --setEthSrc " + str( setEthSrc )
1526 if setEthDst:
1527 cmd += " --setEthDst " + str( setEthDst )
1528 if vlanId:
1529 cmd += " -v " + str( vlanId )
1530 if setVlan:
1531 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001532 if partial:
1533 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001534 if encap:
1535 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001536
kelvin8ec71442015-01-15 16:57:00 -08001537 # Check whether the user appended the port
1538 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001539
1540 if portIngressList is None:
1541 for ingressDevice in ingressDeviceList:
1542 if "/" in ingressDevice:
1543 cmd += " " + str( ingressDevice )
1544 else:
1545 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001546 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001547 # TODO: perhaps more meaningful return
1548 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001549 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001550 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001551 for ingressDevice, portIngress in zip( ingressDeviceList,
1552 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001553 cmd += " " + \
1554 str( ingressDevice ) + "/" +\
1555 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001556 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001557 main.log.error( "Device list and port list does not " +
1558 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001559 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001560 if "/" in egressDevice:
1561 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001562 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001563 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001564 main.log.error( "You must specify " +
1565 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001566 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001567
kelvin8ec71442015-01-15 16:57:00 -08001568 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001569 str( egressDevice ) + "/" +\
1570 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001571 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001572 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001573 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001574 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001575 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001576 main.log.error( "Error in adding multipoint-to-singlepoint " +
1577 "intent" )
1578 return None
shahshreyad0c80432014-12-04 16:56:05 -08001579 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001580 match = re.search('id=0x([\da-f]+),', handle)
1581 if match:
1582 return match.group()[3:-1]
1583 else:
1584 main.log.error( "Error, intent ID not found" )
1585 return None
Jon Hallc6793552016-01-19 14:18:37 -08001586 except AssertionError:
1587 main.log.exception( "" )
1588 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001589 except TypeError:
1590 main.log.exception( self.name + ": Object not as expected" )
1591 return None
1592 except pexpect.EOF:
1593 main.log.error( self.name + ": EOF exception found" )
1594 main.log.error( self.name + ": " + self.handle.before )
1595 main.cleanup()
1596 main.exit()
1597 except Exception:
1598 main.log.exception( self.name + ": Uncaught exception!" )
1599 main.cleanup()
1600 main.exit()
1601
1602 def addSinglepointToMultipointIntent(
1603 self,
1604 ingressDevice,
1605 egressDeviceList,
1606 portIngress="",
1607 portEgressList=None,
1608 ethType="",
1609 ethSrc="",
1610 ethDst="",
1611 bandwidth="",
1612 lambdaAlloc=False,
1613 ipProto="",
1614 ipSrc="",
1615 ipDst="",
1616 tcpSrc="",
1617 tcpDst="",
1618 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001619 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001620 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001621 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001622 partial=False,
1623 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001624 """
1625 Note:
1626 This function assumes the format of all egress devices
1627 is same. That is, all egress devices include port numbers
1628 with a "/" or all egress devices could specify device
1629 ids and port numbers seperately.
1630 Required:
1631 * EgressDeviceList: List of device ids of egress device
1632 ( Atleast 2 eress devices required in the list )
1633 * ingressDevice: device id of ingress device
1634 Optional:
1635 * ethType: specify ethType
1636 * ethSrc: specify ethSrc ( i.e. src mac addr )
1637 * ethDst: specify ethDst ( i.e. dst mac addr )
1638 * bandwidth: specify bandwidth capacity of link
1639 * lambdaAlloc: if True, intent will allocate lambda
1640 for the specified intent
1641 * ipProto: specify ip protocol
1642 * ipSrc: specify ip source address
1643 * ipDst: specify ip destination address
1644 * tcpSrc: specify tcp source port
1645 * tcpDst: specify tcp destination port
1646 * setEthSrc: action to Rewrite Source MAC Address
1647 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001648 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001649 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001650 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001651 Description:
1652 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1653 specifying device id's and optional fields
1654 Returns:
1655 A string of the intent id or None on error
1656
1657 NOTE: This function may change depending on the
1658 options developers provide for singlepoint-to-multipoint
1659 intent via cli
1660 """
1661 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001662 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001663
Jeremy Songsterff553672016-05-12 17:06:23 -07001664 if ethType:
1665 cmd += " --ethType " + str( ethType )
1666 if ethSrc:
1667 cmd += " --ethSrc " + str( ethSrc )
1668 if ethDst:
1669 cmd += " --ethDst " + str( ethDst )
1670 if bandwidth:
1671 cmd += " --bandwidth " + str( bandwidth )
1672 if lambdaAlloc:
1673 cmd += " --lambda "
1674 if ipProto:
1675 cmd += " --ipProto " + str( ipProto )
1676 if ipSrc:
1677 cmd += " --ipSrc " + str( ipSrc )
1678 if ipDst:
1679 cmd += " --ipDst " + str( ipDst )
1680 if tcpSrc:
1681 cmd += " --tcpSrc " + str( tcpSrc )
1682 if tcpDst:
1683 cmd += " --tcpDst " + str( tcpDst )
1684 if setEthSrc:
1685 cmd += " --setEthSrc " + str( setEthSrc )
1686 if setEthDst:
1687 cmd += " --setEthDst " + str( setEthDst )
1688 if vlanId:
1689 cmd += " -v " + str( vlanId )
1690 if setVlan:
1691 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001692 if partial:
1693 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001694 if encap:
1695 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001696
1697 # Check whether the user appended the port
1698 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001699
kelvin-onlabb9408212015-04-01 13:34:04 -07001700 if "/" in ingressDevice:
1701 cmd += " " + str( ingressDevice )
1702 else:
1703 if not portIngress:
1704 main.log.error( "You must specify " +
1705 "the Ingress port" )
1706 return main.FALSE
1707
1708 cmd += " " +\
1709 str( ingressDevice ) + "/" +\
1710 str( portIngress )
1711
1712 if portEgressList is None:
1713 for egressDevice in egressDeviceList:
1714 if "/" in egressDevice:
1715 cmd += " " + str( egressDevice )
1716 else:
1717 main.log.error( "You must specify " +
1718 "the egress port" )
1719 # TODO: perhaps more meaningful return
1720 return main.FALSE
1721 else:
1722 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001723 for egressDevice, portEgress in zip( egressDeviceList,
1724 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001725 cmd += " " + \
1726 str( egressDevice ) + "/" +\
1727 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001728 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001729 main.log.error( "Device list and port list does not " +
1730 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001731 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001732 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001733 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001734 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001735 # If error, return error message
1736 if re.search( "Error", handle ):
1737 main.log.error( "Error in adding singlepoint-to-multipoint " +
1738 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001739 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001740 else:
1741 match = re.search('id=0x([\da-f]+),', handle)
1742 if match:
1743 return match.group()[3:-1]
1744 else:
1745 main.log.error( "Error, intent ID not found" )
1746 return None
Jon Hallc6793552016-01-19 14:18:37 -08001747 except AssertionError:
1748 main.log.exception( "" )
1749 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001750 except TypeError:
1751 main.log.exception( self.name + ": Object not as expected" )
1752 return None
shahshreyad0c80432014-12-04 16:56:05 -08001753 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001754 main.log.error( self.name + ": EOF exception found" )
1755 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001756 main.cleanup()
1757 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001758 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001759 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001760 main.cleanup()
1761 main.exit()
1762
Hari Krishna9e232602015-04-13 17:29:08 -07001763 def addMplsIntent(
1764 self,
1765 ingressDevice,
1766 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001767 ingressPort="",
1768 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001769 ethType="",
1770 ethSrc="",
1771 ethDst="",
1772 bandwidth="",
1773 lambdaAlloc=False,
1774 ipProto="",
1775 ipSrc="",
1776 ipDst="",
1777 tcpSrc="",
1778 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001779 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001780 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001781 priority=""):
1782 """
1783 Required:
1784 * ingressDevice: device id of ingress device
1785 * egressDevice: device id of egress device
1786 Optional:
1787 * ethType: specify ethType
1788 * ethSrc: specify ethSrc ( i.e. src mac addr )
1789 * ethDst: specify ethDst ( i.e. dst mac addr )
1790 * bandwidth: specify bandwidth capacity of link
1791 * lambdaAlloc: if True, intent will allocate lambda
1792 for the specified intent
1793 * ipProto: specify ip protocol
1794 * ipSrc: specify ip source address
1795 * ipDst: specify ip destination address
1796 * tcpSrc: specify tcp source port
1797 * tcpDst: specify tcp destination port
1798 * ingressLabel: Ingress MPLS label
1799 * egressLabel: Egress MPLS label
1800 Description:
1801 Adds MPLS intent by
1802 specifying device id's and optional fields
1803 Returns:
1804 A string of the intent id or None on error
1805
1806 NOTE: This function may change depending on the
1807 options developers provide for MPLS
1808 intent via cli
1809 """
1810 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001811 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001812
Jeremy Songsterff553672016-05-12 17:06:23 -07001813 if ethType:
1814 cmd += " --ethType " + str( ethType )
1815 if ethSrc:
1816 cmd += " --ethSrc " + str( ethSrc )
1817 if ethDst:
1818 cmd += " --ethDst " + str( ethDst )
1819 if bandwidth:
1820 cmd += " --bandwidth " + str( bandwidth )
1821 if lambdaAlloc:
1822 cmd += " --lambda "
1823 if ipProto:
1824 cmd += " --ipProto " + str( ipProto )
1825 if ipSrc:
1826 cmd += " --ipSrc " + str( ipSrc )
1827 if ipDst:
1828 cmd += " --ipDst " + str( ipDst )
1829 if tcpSrc:
1830 cmd += " --tcpSrc " + str( tcpSrc )
1831 if tcpDst:
1832 cmd += " --tcpDst " + str( tcpDst )
1833 if ingressLabel:
1834 cmd += " --ingressLabel " + str( ingressLabel )
1835 if egressLabel:
1836 cmd += " --egressLabel " + str( egressLabel )
1837 if priority:
1838 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001839
1840 # Check whether the user appended the port
1841 # or provided it as an input
1842 if "/" in ingressDevice:
1843 cmd += " " + str( ingressDevice )
1844 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001845 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001846 main.log.error( "You must specify the ingress port" )
1847 return None
1848
1849 cmd += " " + \
1850 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001851 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001852
1853 if "/" in egressDevice:
1854 cmd += " " + str( egressDevice )
1855 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001856 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001857 main.log.error( "You must specify the egress port" )
1858 return None
1859
1860 cmd += " " +\
1861 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001862 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001863
1864 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001865 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001866 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001867 # If error, return error message
1868 if re.search( "Error", handle ):
1869 main.log.error( "Error in adding mpls intent" )
1870 return None
1871 else:
1872 # TODO: print out all the options in this message?
1873 main.log.info( "MPLS intent installed between " +
1874 str( ingressDevice ) + " and " +
1875 str( egressDevice ) )
1876 match = re.search('id=0x([\da-f]+),', handle)
1877 if match:
1878 return match.group()[3:-1]
1879 else:
1880 main.log.error( "Error, intent ID not found" )
1881 return None
Jon Hallc6793552016-01-19 14:18:37 -08001882 except AssertionError:
1883 main.log.exception( "" )
1884 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001885 except TypeError:
1886 main.log.exception( self.name + ": Object not as expected" )
1887 return None
1888 except pexpect.EOF:
1889 main.log.error( self.name + ": EOF exception found" )
1890 main.log.error( self.name + ": " + self.handle.before )
1891 main.cleanup()
1892 main.exit()
1893 except Exception:
1894 main.log.exception( self.name + ": Uncaught exception!" )
1895 main.cleanup()
1896 main.exit()
1897
Jon Hallefbd9792015-03-05 16:11:36 -08001898 def removeIntent( self, intentId, app='org.onosproject.cli',
1899 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001900 """
shahshreya1c818fc2015-02-26 13:44:08 -08001901 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001902 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001903 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001904 -p or --purge: Purge the intent from the store after removal
1905
Jon Halle3f39ff2015-01-13 11:50:53 -08001906 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001907 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001908 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001909 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001910 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001911 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001912 if purge:
1913 cmdStr += " -p"
1914 if sync:
1915 cmdStr += " -s"
1916
1917 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001918 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001919 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001920 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001921 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001922 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001923 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001924 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001925 # TODO: Should this be main.TRUE
1926 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001927 except AssertionError:
1928 main.log.exception( "" )
1929 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001930 except TypeError:
1931 main.log.exception( self.name + ": Object not as expected" )
1932 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001933 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001934 main.log.error( self.name + ": EOF exception found" )
1935 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001936 main.cleanup()
1937 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001938 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001939 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001940 main.cleanup()
1941 main.exit()
1942
YPZhangfebf7302016-05-24 16:45:56 -07001943 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001944 """
1945 Description:
1946 Remove all the intents
1947 Optional args:-
1948 -s or --sync: Waits for the removal before returning
1949 -p or --purge: Purge the intent from the store after removal
1950 Returns:
1951 Returns main.TRUE if all intents are removed, otherwise returns
1952 main.FALSE; Returns None for exception
1953 """
1954 try:
1955 cmdStr = "remove-intent"
1956 if purge:
1957 cmdStr += " -p"
1958 if sync:
1959 cmdStr += " -s"
1960
1961 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001962 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001963 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08001964 assert "Command not found:" not in handle, handle
1965 if re.search( "Error", handle ):
1966 main.log.error( "Error in removing intent" )
1967 return main.FALSE
1968 else:
1969 return main.TRUE
1970 except AssertionError:
1971 main.log.exception( "" )
1972 return None
1973 except TypeError:
1974 main.log.exception( self.name + ": Object not as expected" )
1975 return None
1976 except pexpect.EOF:
1977 main.log.error( self.name + ": EOF exception found" )
1978 main.log.error( self.name + ": " + self.handle.before )
1979 main.cleanup()
1980 main.exit()
1981 except Exception:
1982 main.log.exception( self.name + ": Uncaught exception!" )
1983 main.cleanup()
1984 main.exit()
1985
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001986 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001987 """
1988 Purges all WITHDRAWN Intents
1989 """
1990 try:
1991 cmdStr = "purge-intents"
1992 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001993 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001994 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001995 if re.search( "Error", handle ):
1996 main.log.error( "Error in purging intents" )
1997 return main.FALSE
1998 else:
1999 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002000 except AssertionError:
2001 main.log.exception( "" )
2002 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002003 except TypeError:
2004 main.log.exception( self.name + ": Object not as expected" )
2005 return None
2006 except pexpect.EOF:
2007 main.log.error( self.name + ": EOF exception found" )
2008 main.log.error( self.name + ": " + self.handle.before )
2009 main.cleanup()
2010 main.exit()
2011 except Exception:
2012 main.log.exception( self.name + ": Uncaught exception!" )
2013 main.cleanup()
2014 main.exit()
2015
kelvin-onlabd3b64892015-01-20 13:26:24 -08002016 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002017 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002018 NOTE: This method should be used after installing application:
2019 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002020 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002021 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002022 Description:
2023 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002024 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002025 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002026 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002027 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002028 cmdStr += " -j"
2029 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002030 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002031 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002032 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002033 except AssertionError:
2034 main.log.exception( "" )
2035 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002036 except TypeError:
2037 main.log.exception( self.name + ": Object not as expected" )
2038 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002039 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002040 main.log.error( self.name + ": EOF exception found" )
2041 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08002042 main.cleanup()
2043 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002044 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002045 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08002046 main.cleanup()
2047 main.exit()
2048
pingping-lin54b03372015-08-13 14:43:10 -07002049 def ipv4RouteNumber( self ):
2050 """
2051 NOTE: This method should be used after installing application:
2052 onos-app-sdnip
2053 Description:
2054 Obtain the total IPv4 routes number in the system
2055 """
2056 try:
Pratik Parab57963572017-05-09 11:37:54 -07002057 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002058 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002059 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002060 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002061 jsonResult = json.loads( handle )
Pratik Parab57963572017-05-09 11:37:54 -07002062 return len(jsonResult['routes4'])
Jon Hallc6793552016-01-19 14:18:37 -08002063 except AssertionError:
2064 main.log.exception( "" )
2065 return None
2066 except ( TypeError, ValueError ):
2067 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002068 return None
2069 except pexpect.EOF:
2070 main.log.error( self.name + ": EOF exception found" )
2071 main.log.error( self.name + ": " + self.handle.before )
2072 main.cleanup()
2073 main.exit()
2074 except Exception:
2075 main.log.exception( self.name + ": Uncaught exception!" )
2076 main.cleanup()
2077 main.exit()
2078
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002079 #=============Function to check Bandwidth allocation========
2080 def allocations( self, jsonFormat = True, dollarSign = True ):
2081 """
2082 Description:
2083 Obtain Bandwidth Allocation Information from ONOS cli.
2084 """
2085 try:
2086 cmdStr = "allocations"
2087 if jsonFormat:
2088 cmdStr += " -j"
2089 handle = self.sendline( cmdStr, timeout=300, dollarSign=True )
2090 assert handle is not None, "Error in sendline"
2091 assert "Command not found:" not in handle, handle
2092 return handle
2093 except AssertionError:
2094 main.log.exception( "" )
2095 return None
2096 except ( TypeError, ValueError ):
2097 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2098 return None
2099 except pexpect.EOF:
2100 main.log.error( self.name + ": EOF exception found" )
2101 main.log.error( self.name + ": " + self.handle.before )
2102 main.cleanup()
2103 main.exit()
2104 except Exception:
2105 main.log.exception( self.name + ": Uncaught exception!" )
2106 main.cleanup()
2107 main.exit()
2108
pingping-lin8244a3b2015-09-16 13:36:56 -07002109 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002110 """
andrewonlabe6745342014-10-17 14:29:13 -04002111 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002112 Obtain intents from the ONOS cli.
2113 Optional:
2114 * jsonFormat: Enable output formatting in json, default to True
2115 * summary: Whether only output the intent summary, defaults to False
2116 * type: Only output a certain type of intent. This options is valid
2117 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002118 """
andrewonlabe6745342014-10-17 14:29:13 -04002119 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002120 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002121 if summary:
2122 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002123 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002124 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002125 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002126 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002127 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002128 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002129 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002130 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002131 else:
Jon Hallff566d52016-01-15 14:45:36 -08002132 intentType = ""
2133 # IF we want the summary of a specific intent type
2134 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002135 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002136 if intentType in jsonResult.keys():
2137 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002138 else:
Jon Hallff566d52016-01-15 14:45:36 -08002139 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002140 return handle
2141 else:
2142 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002143 except AssertionError:
2144 main.log.exception( "" )
2145 return None
2146 except ( TypeError, ValueError ):
2147 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002148 return None
2149 except pexpect.EOF:
2150 main.log.error( self.name + ": EOF exception found" )
2151 main.log.error( self.name + ": " + self.handle.before )
2152 main.cleanup()
2153 main.exit()
2154 except Exception:
2155 main.log.exception( self.name + ": Uncaught exception!" )
2156 main.cleanup()
2157 main.exit()
2158
kelvin-onlab54400a92015-02-26 18:05:51 -08002159 def getIntentState(self, intentsId, intentsJson=None):
2160 """
You Wangfdcbfc42016-05-16 12:16:53 -07002161 Description:
2162 Gets intent state. Accepts a single intent ID (string type) or a
2163 list of intent IDs.
2164 Parameters:
2165 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002166 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002167 Returns:
2168 Returns the state (string type) of the ID if a single intent ID is
2169 accepted.
2170 Returns a list of dictionaries if a list of intent IDs is accepted,
2171 and each dictionary maps 'id' to the Intent ID and 'state' to
2172 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002173 """
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002174
kelvin-onlab54400a92015-02-26 18:05:51 -08002175 try:
2176 state = "State is Undefined"
2177 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002178 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002179 else:
Jon Hallc6793552016-01-19 14:18:37 -08002180 rawJson = intentsJson
2181 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002182 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002183 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002184 if intentsId == intent[ 'id' ]:
2185 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002186 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002187 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002188 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002189 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002190 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002191 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002192 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002193 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002194 for intent in parsedIntentsJson:
2195 if intentsId[ i ] == intent[ 'id' ]:
2196 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002197 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002198 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002199 break
Jon Hallefbd9792015-03-05 16:11:36 -08002200 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002201 main.log.warn( "Could not find all intents in ONOS output" )
2202 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002203 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002204 else:
Jon Hall53158082017-05-18 11:17:00 -07002205 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002206 return None
Jon Hallc6793552016-01-19 14:18:37 -08002207 except ( TypeError, ValueError ):
2208 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002209 return None
2210 except pexpect.EOF:
2211 main.log.error( self.name + ": EOF exception found" )
2212 main.log.error( self.name + ": " + self.handle.before )
2213 main.cleanup()
2214 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002215 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002216 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002217 main.cleanup()
2218 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002219
Jon Hallf539eb92017-05-22 17:18:42 -07002220 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002221 """
2222 Description:
2223 Check intents state
2224 Required:
2225 intentsId - List of intents ID to be checked
2226 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002227 expectedState - Check the expected state(s) of each intents
2228 state in the list.
2229 *NOTE: You can pass in a list of expected state,
2230 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002231 Return:
Jon Hall53158082017-05-18 11:17:00 -07002232 Returns main.TRUE only if all intent are the same as expected states,
2233 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002234 """
2235 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002236 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002237 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002238
2239 #intentsDict = self.getIntentState( intentsId )
2240 intentsDict = []
2241 for intent in json.loads( self.intents() ):
2242 if isinstance ( intentsId, types.StringType) \
2243 and intent.get('id') == intentsId:
2244 intentsDict.append(intent)
2245 elif isinstance ( intentsId, types.ListType ) \
2246 and any( intent.get( 'id' ) == ids for ids in intentsId ):
2247 intentsDict.append(intent)
2248
2249 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002250 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002251 "getting intents state" )
2252 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002253
2254 if isinstance( expectedState, types.StringType ):
2255 for intents in intentsDict:
2256 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002257 main.log.debug( self.name + " : Intent ID - " +
2258 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002259 " actual state = " +
2260 intents.get( 'state' )
2261 + " does not equal expected state = "
2262 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002263 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002264 elif isinstance( expectedState, types.ListType ):
2265 for intents in intentsDict:
2266 if not any( state == intents.get( 'state' ) for state in
2267 expectedState ):
2268 main.log.debug( self.name + " : Intent ID - " +
2269 intents.get( 'id' ) +
2270 " actual state = " +
2271 intents.get( 'state' ) +
2272 " does not equal expected states = "
2273 + str( expectedState ) )
2274 returnValue = main.FALSE
2275
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002276 if returnValue == main.TRUE:
2277 main.log.info( self.name + ": All " +
2278 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002279 " intents are in " + str( expectedState ) +
2280 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002281 return returnValue
2282 except TypeError:
2283 main.log.exception( self.name + ": Object not as expected" )
2284 return None
2285 except pexpect.EOF:
2286 main.log.error( self.name + ": EOF exception found" )
2287 main.log.error( self.name + ": " + self.handle.before )
2288 main.cleanup()
2289 main.exit()
2290 except Exception:
2291 main.log.exception( self.name + ": Uncaught exception!" )
2292 main.cleanup()
2293 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002294
Jon Hallf539eb92017-05-22 17:18:42 -07002295 def compareBandwidthAllocations( self, expectedAllocations ):
2296 """
2297 Description:
2298 Compare the allocated bandwidth with the given allocations
2299 Required:
2300 expectedAllocations - The expected ONOS output of the allocations command
2301 Return:
2302 Returns main.TRUE only if all intent are the same as expected states,
2303 otherwise returns main.FALSE.
2304 """
2305 # FIXME: Convert these string comparisons to object comparisons
2306 try:
2307 returnValue = main.TRUE
2308 bandwidthFailed = False
2309 rawAlloc = self.allocations()
2310 expectedFormat = StringIO( expectedAllocations )
2311 ONOSOutput = StringIO( rawAlloc )
2312 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2313 str( expectedFormat ) ) )
2314
2315 for actual, expected in izip( ONOSOutput, expectedFormat ):
2316 actual = actual.rstrip()
2317 expected = expected.rstrip()
2318 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2319 if actual != expected and 'allocated' in actual and 'allocated' in expected:
2320 marker1 = actual.find('allocated')
2321 m1 = actual[:marker1]
2322 marker2 = expected.find('allocated')
2323 m2 = expected[:marker2]
2324 if m1 != m2:
2325 bandwidthFailed = True
2326 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2327 bandwidthFailed = True
2328 expectedFormat.close()
2329 ONOSOutput.close()
2330
2331 if bandwidthFailed:
2332 main.log.error("Bandwidth not allocated correctly using Intents!!")
2333 returnValue = main.FALSE
2334 return returnValue
2335 except TypeError:
2336 main.log.exception( self.name + ": Object not as expected" )
2337 return None
2338 except pexpect.EOF:
2339 main.log.error( self.name + ": EOF exception found" )
2340 main.log.error( self.name + ": " + self.handle.before )
2341 main.cleanup()
2342 main.exit()
2343 except Exception:
2344 main.log.exception( self.name + ": Uncaught exception!" )
2345 main.cleanup()
2346 main.exit()
2347
You Wang66518af2016-05-16 15:32:59 -07002348 def compareIntent( self, intentDict ):
2349 """
2350 Description:
2351 Compare the intent ids and states provided in the argument with all intents in ONOS
2352 Return:
2353 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2354 Arguments:
2355 intentDict: a dictionary which maps intent ids to intent states
2356 """
2357 try:
2358 intentsRaw = self.intents()
2359 intentsJson = json.loads( intentsRaw )
2360 intentDictONOS = {}
2361 for intent in intentsJson:
2362 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002363 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002364 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002365 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002366 str( len( intentDict ) ) + " expected and " +
2367 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002368 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002369 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002370 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002371 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2372 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002373 else:
2374 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2375 main.log.debug( self.name + ": intent ID - " + intentID +
2376 " expected state is " + intentDict[ intentID ] +
2377 " but actual state is " + intentDictONOS[ intentID ] )
2378 returnValue = main.FALSE
2379 intentDictONOS.pop( intentID )
2380 if len( intentDictONOS ) > 0:
2381 returnValue = main.FALSE
2382 for intentID in intentDictONOS.keys():
2383 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002384 if returnValue == main.TRUE:
2385 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2386 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002387 except KeyError:
2388 main.log.exception( self.name + ": KeyError exception found" )
2389 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002390 except ( TypeError, ValueError ):
2391 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002392 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002393 except pexpect.EOF:
2394 main.log.error( self.name + ": EOF exception found" )
2395 main.log.error( self.name + ": " + self.handle.before )
2396 main.cleanup()
2397 main.exit()
2398 except Exception:
2399 main.log.exception( self.name + ": Uncaught exception!" )
2400 main.cleanup()
2401 main.exit()
2402
YPZhang14a4aa92016-07-15 13:37:15 -07002403 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002404 """
2405 Description:
2406 Check the number of installed intents.
2407 Optional:
2408 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002409 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002410 Return:
2411 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2412 , otherwise, returns main.FALSE.
2413 """
2414
2415 try:
2416 cmd = "intents -s -j"
2417
2418 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002419 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002420 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002421 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002422 response = json.loads( response )
2423
2424 # get total and installed number, see if they are match
2425 allState = response.get( 'all' )
2426 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002427 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002428 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002429 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002430 return main.FALSE
2431
Jon Hallc6793552016-01-19 14:18:37 -08002432 except ( TypeError, ValueError ):
2433 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002434 return None
2435 except pexpect.EOF:
2436 main.log.error( self.name + ": EOF exception found" )
2437 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002438 if noExit:
2439 return main.FALSE
2440 else:
2441 main.cleanup()
2442 main.exit()
Jon Halle0f0b342017-04-18 11:43:47 -07002443 except pexpect.TIMEOUT:
2444 main.log.error( self.name + ": ONOS timeout" )
2445 return None
GlennRCed771242016-01-13 17:02:47 -08002446 except Exception:
2447 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002448 if noExit:
2449 return main.FALSE
2450 else:
2451 main.cleanup()
2452 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002453
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002454 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002455 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002456 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002457 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002458 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002459 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002460 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002461 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002462 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002463 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002464 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002465 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002466 if noCore:
2467 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002468 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002469 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002470 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002471 assert "Command not found:" not in handle, handle
2472 if re.search( "Error:", handle ):
2473 main.log.error( self.name + ": flows() response: " +
2474 str( handle ) )
2475 return handle
2476 except AssertionError:
2477 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002478 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002479 except TypeError:
2480 main.log.exception( self.name + ": Object not as expected" )
2481 return None
Jon Hallc6793552016-01-19 14:18:37 -08002482 except pexpect.TIMEOUT:
2483 main.log.error( self.name + ": ONOS timeout" )
2484 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002485 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002486 main.log.error( self.name + ": EOF exception found" )
2487 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002488 main.cleanup()
2489 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002490 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002491 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002492 main.cleanup()
2493 main.exit()
2494
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002495 def checkFlowCount(self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002496 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002497 count = int( count ) if count else 0
2498 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002499
Jon Halle0f0b342017-04-18 11:43:47 -07002500 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002501 """
2502 Description:
GlennRCed771242016-01-13 17:02:47 -08002503 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002504 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2505 if the count of those states is 0, which means all current flows
2506 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002507 Optional:
GlennRCed771242016-01-13 17:02:47 -08002508 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002509 Return:
2510 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002511 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002512 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002513 """
2514 try:
GlennRCed771242016-01-13 17:02:47 -08002515 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2516 checkedStates = []
2517 statesCount = [0, 0, 0, 0]
2518 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002519 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002520 if rawFlows:
2521 # if we didn't get flows or flows function return None, we should return
2522 # main.Flase
2523 checkedStates.append( json.loads( rawFlows ) )
2524 else:
2525 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002526 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002527 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002528 try:
2529 statesCount[i] += int( c.get( "flowCount" ) )
2530 except TypeError:
2531 main.log.exception( "Json object not as expected" )
2532 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002533
GlennRCed771242016-01-13 17:02:47 -08002534 # We want to count PENDING_ADD if isPENDING is true
2535 if isPENDING:
2536 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2537 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002538 else:
GlennRCed771242016-01-13 17:02:47 -08002539 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2540 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002541 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002542 except ( TypeError, ValueError ):
2543 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002544 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002545
YPZhang240842b2016-05-17 12:00:50 -07002546 except AssertionError:
2547 main.log.exception( "" )
2548 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002549 except pexpect.TIMEOUT:
2550 main.log.error( self.name + ": ONOS timeout" )
2551 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002552 except pexpect.EOF:
2553 main.log.error( self.name + ": EOF exception found" )
2554 main.log.error( self.name + ": " + self.handle.before )
2555 main.cleanup()
2556 main.exit()
2557 except Exception:
2558 main.log.exception( self.name + ": Uncaught exception!" )
2559 main.cleanup()
2560 main.exit()
2561
GlennRCed771242016-01-13 17:02:47 -08002562 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002563 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002564 """
andrewonlab87852b02014-11-19 18:44:19 -05002565 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002566 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002567 a specific point-to-point intent definition
2568 Required:
GlennRCed771242016-01-13 17:02:47 -08002569 * ingress: specify source dpid
2570 * egress: specify destination dpid
2571 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002572 Optional:
GlennRCed771242016-01-13 17:02:47 -08002573 * offset: the keyOffset is where the next batch of intents
2574 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002575 * noExit: If set to True, TestON will not exit if any error when issus command
2576 * getResponse: If set to True, function will return ONOS response.
2577
GlennRCed771242016-01-13 17:02:47 -08002578 Returns: If failed to push test intents, it will returen None,
2579 if successful, return true.
2580 Timeout expection will return None,
2581 TypeError will return false
2582 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002583 """
andrewonlab87852b02014-11-19 18:44:19 -05002584 try:
GlennRCed771242016-01-13 17:02:47 -08002585 if background:
2586 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002587 else:
GlennRCed771242016-01-13 17:02:47 -08002588 back = ""
2589 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002590 ingress,
2591 egress,
2592 batchSize,
2593 offset,
2594 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002595 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002596 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002597 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002598 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002599 if getResponse:
2600 return response
2601
GlennRCed771242016-01-13 17:02:47 -08002602 # TODO: We should handle if there is failure in installation
2603 return main.TRUE
2604
Jon Hallc6793552016-01-19 14:18:37 -08002605 except AssertionError:
2606 main.log.exception( "" )
2607 return None
GlennRCed771242016-01-13 17:02:47 -08002608 except pexpect.TIMEOUT:
2609 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002610 return None
andrewonlab87852b02014-11-19 18:44:19 -05002611 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002612 main.log.error( self.name + ": EOF exception found" )
2613 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002614 main.cleanup()
2615 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002616 except TypeError:
2617 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002618 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002619 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002620 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002621 main.cleanup()
2622 main.exit()
2623
YPZhangebf9eb52016-05-12 15:20:24 -07002624 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002625 """
2626 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002627 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002628 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002629 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002630 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002631 """
YPZhange3109a72016-02-02 11:25:37 -08002632
YPZhangb5d3f832016-01-23 22:54:26 -08002633 try:
YPZhange3109a72016-02-02 11:25:37 -08002634 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002635 cmd = "flows -c added"
2636 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2637 if rawFlows:
2638 rawFlows = rawFlows.split("\n")
YPZhange3109a72016-02-02 11:25:37 -08002639 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002640 for l in rawFlows:
2641 totalFlows += int(l.split("Count=")[1])
2642 else:
2643 main.log.error("Response not as expected!")
2644 return None
2645 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002646
You Wangd3cb2ce2016-05-16 14:01:24 -07002647 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002648 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002649 return None
2650 except pexpect.EOF:
2651 main.log.error( self.name + ": EOF exception found" )
2652 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002653 if not noExit:
2654 main.cleanup()
2655 main.exit()
2656 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002657 except pexpect.TIMEOUT:
2658 main.log.error( self.name + ": ONOS timeout" )
2659 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002660 except Exception:
2661 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002662 if not noExit:
2663 main.cleanup()
2664 main.exit()
2665 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002666
YPZhang14a4aa92016-07-15 13:37:15 -07002667 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002668 """
2669 Description:
2670 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002671 Optional:
2672 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002673 Return:
2674 The number of intents
2675 """
2676 try:
2677 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002678 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002679 if response is None:
2680 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002681 response = json.loads( response )
2682 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002683 except ( TypeError, ValueError ):
2684 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002685 return None
2686 except pexpect.EOF:
2687 main.log.error( self.name + ": EOF exception found" )
2688 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002689 if noExit:
2690 return -1
2691 else:
2692 main.cleanup()
2693 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002694 except Exception:
2695 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002696 if noExit:
2697 return -1
2698 else:
2699 main.cleanup()
2700 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002701
kelvin-onlabd3b64892015-01-20 13:26:24 -08002702 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002703 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002704 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002705 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002706 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002707 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002708 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002709 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002710 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002711 cmdStr += " -j"
2712 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002713 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002714 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002715 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002716 except AssertionError:
2717 main.log.exception( "" )
2718 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002719 except TypeError:
2720 main.log.exception( self.name + ": Object not as expected" )
2721 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002722 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002723 main.log.error( self.name + ": EOF exception found" )
2724 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002725 main.cleanup()
2726 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002727 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002728 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002729 main.cleanup()
2730 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002731
kelvin-onlabd3b64892015-01-20 13:26:24 -08002732 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002733 """
2734 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002735 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002736 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002737 """
andrewonlab867212a2014-10-22 20:13:38 -04002738 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002739 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002740 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002741 cmdStr += " -j"
2742 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002743 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002744 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002745 if handle:
2746 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002747 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002748 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002749 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002750 else:
2751 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002752 except AssertionError:
2753 main.log.exception( "" )
2754 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002755 except TypeError:
2756 main.log.exception( self.name + ": Object not as expected" )
2757 return None
andrewonlab867212a2014-10-22 20:13:38 -04002758 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002759 main.log.error( self.name + ": EOF exception found" )
2760 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002761 main.cleanup()
2762 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002763 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002764 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002765 main.cleanup()
2766 main.exit()
2767
kelvin8ec71442015-01-15 16:57:00 -08002768 # Wrapper functions ****************
2769 # Wrapper functions use existing driver
2770 # functions and extends their use case.
2771 # For example, we may use the output of
2772 # a normal driver function, and parse it
2773 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002774
kelvin-onlabd3b64892015-01-20 13:26:24 -08002775 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002776 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002777 Description:
2778 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002779 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002780 try:
kelvin8ec71442015-01-15 16:57:00 -08002781 # Obtain output of intents function
Jon Hall6021e062017-01-30 11:10:06 -08002782 intentsStr = self.intents(jsonFormat=True)
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002783 if intentsStr is None:
2784 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002785 # Convert to a dictionary
2786 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002787 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002788 for intent in intents:
2789 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002790 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002791 except TypeError:
2792 main.log.exception( self.name + ": Object not as expected" )
2793 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002794 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002795 main.log.error( self.name + ": EOF exception found" )
2796 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002797 main.cleanup()
2798 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002799 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002800 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002801 main.cleanup()
2802 main.exit()
2803
You Wang3c276252016-09-21 15:21:36 -07002804 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002805 """
2806 Determine the number of flow rules for the given device id that are
2807 in the added state
You Wang3c276252016-09-21 15:21:36 -07002808 Params:
2809 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002810 """
2811 try:
You Wang3c276252016-09-21 15:21:36 -07002812 if core:
2813 cmdStr = "flows any " + str( deviceId ) + " | " +\
2814 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2815 else:
2816 cmdStr = "flows any " + str( deviceId ) + " | " +\
2817 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002818 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002819 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002820 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002821 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002822 except AssertionError:
2823 main.log.exception( "" )
2824 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002825 except pexpect.EOF:
2826 main.log.error( self.name + ": EOF exception found" )
2827 main.log.error( self.name + ": " + self.handle.before )
2828 main.cleanup()
2829 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002830 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002831 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002832 main.cleanup()
2833 main.exit()
2834
kelvin-onlabd3b64892015-01-20 13:26:24 -08002835 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002836 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002837 Use 'devices' function to obtain list of all devices
2838 and parse the result to obtain a list of all device
2839 id's. Returns this list. Returns empty list if no
2840 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002841 List is ordered sequentially
2842
andrewonlab3e15ead2014-10-15 14:21:34 -04002843 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002844 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002845 the ids. By obtaining the list of device ids on the fly,
2846 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002847 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002848 try:
kelvin8ec71442015-01-15 16:57:00 -08002849 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002850 devicesStr = self.devices( jsonFormat=False )
2851 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002852
kelvin-onlabd3b64892015-01-20 13:26:24 -08002853 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002854 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002855 return idList
kelvin8ec71442015-01-15 16:57:00 -08002856
2857 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002858 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002859 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002860 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002861 # Split list further into arguments before and after string
2862 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002863 # append to idList
2864 for arg in tempList:
2865 idList.append( arg.split( "id=" )[ 1 ] )
2866 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002867
Jon Halld4d4b372015-01-28 16:02:41 -08002868 except TypeError:
2869 main.log.exception( self.name + ": Object not as expected" )
2870 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002871 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002872 main.log.error( self.name + ": EOF exception found" )
2873 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002874 main.cleanup()
2875 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002876 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002877 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002878 main.cleanup()
2879 main.exit()
2880
kelvin-onlabd3b64892015-01-20 13:26:24 -08002881 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002882 """
andrewonlab7c211572014-10-15 16:45:20 -04002883 Uses 'nodes' function to obtain list of all nodes
2884 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002885 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002886 Returns:
2887 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002888 """
andrewonlab7c211572014-10-15 16:45:20 -04002889 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002890 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002891 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002892 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002893 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002894 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002895 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002896 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002897 nodesJson = json.loads( nodesStr )
2898 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002899 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002900 except ( TypeError, ValueError ):
2901 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002902 return None
andrewonlab7c211572014-10-15 16:45:20 -04002903 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002904 main.log.error( self.name + ": EOF exception found" )
2905 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002906 main.cleanup()
2907 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002908 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002909 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002910 main.cleanup()
2911 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002912
kelvin-onlabd3b64892015-01-20 13:26:24 -08002913 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002914 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002915 Return the first device from the devices api whose 'id' contains 'dpid'
2916 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002917 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002918 try:
kelvin8ec71442015-01-15 16:57:00 -08002919 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002920 return None
2921 else:
kelvin8ec71442015-01-15 16:57:00 -08002922 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002923 rawDevices = self.devices()
2924 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002925 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002926 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002927 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2928 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002929 return device
2930 return None
Jon Hallc6793552016-01-19 14:18:37 -08002931 except ( TypeError, ValueError ):
2932 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002933 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002934 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002935 main.log.error( self.name + ": EOF exception found" )
2936 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002937 main.cleanup()
2938 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002939 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002940 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002941 main.cleanup()
2942 main.exit()
2943
You Wang24139872016-05-03 11:48:47 -07002944 def getTopology( self, topologyOutput ):
2945 """
2946 Definition:
2947 Loads a json topology output
2948 Return:
2949 topology = current ONOS topology
2950 """
2951 import json
2952 try:
2953 # either onos:topology or 'topology' will work in CLI
2954 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002955 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002956 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002957 except ( TypeError, ValueError ):
2958 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2959 return None
You Wang24139872016-05-03 11:48:47 -07002960 except pexpect.EOF:
2961 main.log.error( self.name + ": EOF exception found" )
2962 main.log.error( self.name + ": " + self.handle.before )
2963 main.cleanup()
2964 main.exit()
2965 except Exception:
2966 main.log.exception( self.name + ": Uncaught exception!" )
2967 main.cleanup()
2968 main.exit()
2969
Flavio Castro82ee2f62016-06-07 15:04:12 -07002970 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002971 """
Jon Hallefbd9792015-03-05 16:11:36 -08002972 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002973 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002974 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002975
Flavio Castro82ee2f62016-06-07 15:04:12 -07002976 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002977 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002978 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002979 logLevel = level to log to.
2980 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002981
Jon Hallefbd9792015-03-05 16:11:36 -08002982 Returns: main.TRUE if the number of switches and links are correct,
2983 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002984 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002985 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002986 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002987 try:
You Wang13310252016-07-31 10:56:14 -07002988 summary = self.summary()
2989 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002990 except ( TypeError, ValueError ):
2991 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2992 return main.ERROR
2993 try:
2994 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07002995 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002996 return main.ERROR
2997 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002998 # Is the number of switches is what we expected
2999 devices = topology.get( 'devices', False )
3000 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003001 nodes = summary.get( 'nodes', False )
3002 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003003 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003004 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003005 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08003006 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003007 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3008 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003009 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003010 output = output + "The number of links and switches match "\
3011 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003012 result = main.TRUE
3013 else:
You Wang24139872016-05-03 11:48:47 -07003014 output = output + \
3015 "The number of links and switches does not match " + \
3016 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003017 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003018 output = output + "\n ONOS sees %i devices" % int( devices )
3019 output = output + " (%i expected) " % int( numoswitch )
3020 output = output + "and %i links " % int( links )
3021 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003022 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003023 output = output + "and %i controllers " % int( nodes )
3024 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003025 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003026 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003027 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003028 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003029 else:
You Wang24139872016-05-03 11:48:47 -07003030 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003031 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003032 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003033 main.log.error( self.name + ": EOF exception found" )
3034 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04003035 main.cleanup()
3036 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003037 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003038 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04003039 main.cleanup()
3040 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003041
kelvin-onlabd3b64892015-01-20 13:26:24 -08003042 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003043 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003044 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003045 deviceId must be the id of a device as seen in the onos devices command
3046 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003047 role must be either master, standby, or none
3048
Jon Halle3f39ff2015-01-13 11:50:53 -08003049 Returns:
3050 main.TRUE or main.FALSE based on argument verification and
3051 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003052 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003053 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003054 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003055 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003056 cmdStr = "device-role " +\
3057 str( deviceId ) + " " +\
3058 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003059 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003060 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003061 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003062 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003063 if re.search( "Error", handle ):
3064 # end color output to escape any colours
3065 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003066 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003067 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003068 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003069 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003070 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003071 main.log.error( "Invalid 'role' given to device_role(). " +
3072 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003073 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003074 except AssertionError:
3075 main.log.exception( "" )
3076 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003077 except TypeError:
3078 main.log.exception( self.name + ": Object not as expected" )
3079 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003080 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003081 main.log.error( self.name + ": EOF exception found" )
3082 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04003083 main.cleanup()
3084 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003085 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003086 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04003087 main.cleanup()
3088 main.exit()
3089
kelvin-onlabd3b64892015-01-20 13:26:24 -08003090 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003091 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003092 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003093 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003094 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003095 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003096 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003097 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003098 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003099 cmdStr += " -j"
3100 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003101 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003102 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003103 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003104 except AssertionError:
3105 main.log.exception( "" )
3106 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003107 except TypeError:
3108 main.log.exception( self.name + ": Object not as expected" )
3109 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003110 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003111 main.log.error( self.name + ": EOF exception found" )
3112 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08003113 main.cleanup()
3114 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003115 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003116 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08003117 main.cleanup()
3118 main.exit()
3119
kelvin-onlabd3b64892015-01-20 13:26:24 -08003120 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003121 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003122 CLI command to get the current leader for the Election test application
3123 NOTE: Requires installation of the onos-app-election feature
3124 Returns: Node IP of the leader if one exists
3125 None if none exists
3126 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003127 """
Jon Hall94fd0472014-12-08 11:52:42 -08003128 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003129 cmdStr = "election-test-leader"
3130 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003131 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003132 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003133 # Leader
3134 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003135 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003136 nodeSearch = re.search( leaderPattern, response )
3137 if nodeSearch:
3138 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003139 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003140 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003141 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003142 # no leader
3143 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003144 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003145 nullSearch = re.search( nullPattern, response )
3146 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003147 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003148 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003149 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003150 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003151 main.log.error( "Error in electionTestLeader on " + self.name +
3152 ": " + "unexpected response" )
3153 main.log.error( repr( response ) )
3154 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003155 except AssertionError:
3156 main.log.exception( "" )
3157 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003158 except TypeError:
3159 main.log.exception( self.name + ": Object not as expected" )
3160 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003161 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003162 main.log.error( self.name + ": EOF exception found" )
3163 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003164 main.cleanup()
3165 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003166 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003167 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003168 main.cleanup()
3169 main.exit()
3170
kelvin-onlabd3b64892015-01-20 13:26:24 -08003171 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003172 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003173 CLI command to run for leadership of the Election test application.
3174 NOTE: Requires installation of the onos-app-election feature
3175 Returns: Main.TRUE on success
3176 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003177 """
Jon Hall94fd0472014-12-08 11:52:42 -08003178 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003179 cmdStr = "election-test-run"
3180 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003181 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003182 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003183 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003184 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003185 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003186 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003187 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003188 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003189 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003190 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003191 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003192 main.log.error( "Error in electionTestRun on " + self.name +
3193 ": " + "unexpected response" )
3194 main.log.error( repr( response ) )
3195 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003196 except AssertionError:
3197 main.log.exception( "" )
3198 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003199 except TypeError:
3200 main.log.exception( self.name + ": Object not as expected" )
3201 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003202 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003203 main.log.error( self.name + ": EOF exception found" )
3204 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003205 main.cleanup()
3206 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003207 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003208 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003209 main.cleanup()
3210 main.exit()
3211
kelvin-onlabd3b64892015-01-20 13:26:24 -08003212 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003213 """
Jon Hall94fd0472014-12-08 11:52:42 -08003214 * CLI command to withdraw the local node from leadership election for
3215 * the Election test application.
3216 #NOTE: Requires installation of the onos-app-election feature
3217 Returns: Main.TRUE on success
3218 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003219 """
Jon Hall94fd0472014-12-08 11:52:42 -08003220 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003221 cmdStr = "election-test-withdraw"
3222 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003223 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003224 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003225 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003226 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003227 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003228 if re.search( successPattern, response ):
3229 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003230 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003231 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003232 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003233 main.log.error( "Error in electionTestWithdraw on " +
3234 self.name + ": " + "unexpected response" )
3235 main.log.error( repr( response ) )
3236 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003237 except AssertionError:
3238 main.log.exception( "" )
3239 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003240 except TypeError:
3241 main.log.exception( self.name + ": Object not as expected" )
3242 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003243 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003244 main.log.error( self.name + ": EOF exception found" )
3245 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003246 main.cleanup()
3247 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003248 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003249 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003250 main.cleanup()
3251 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003252
kelvin8ec71442015-01-15 16:57:00 -08003253 def getDevicePortsEnabledCount( self, dpid ):
3254 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003255 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003256 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003257 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003258 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003259 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3260 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003261 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003262 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003263 if re.search( "No such device", output ):
3264 main.log.error( "Error in getting ports" )
3265 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003266 return output
Jon Hallc6793552016-01-19 14:18:37 -08003267 except AssertionError:
3268 main.log.exception( "" )
3269 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003270 except TypeError:
3271 main.log.exception( self.name + ": Object not as expected" )
3272 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003273 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003274 main.log.error( self.name + ": EOF exception found" )
3275 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003276 main.cleanup()
3277 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003278 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003279 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003280 main.cleanup()
3281 main.exit()
3282
kelvin8ec71442015-01-15 16:57:00 -08003283 def getDeviceLinksActiveCount( self, dpid ):
3284 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003285 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003286 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003287 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003288 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003289 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3290 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003291 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003292 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003293 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003294 main.log.error( "Error in getting ports " )
3295 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003296 return output
Jon Hallc6793552016-01-19 14:18:37 -08003297 except AssertionError:
3298 main.log.exception( "" )
3299 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003300 except TypeError:
3301 main.log.exception( self.name + ": Object not as expected" )
3302 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003303 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003304 main.log.error( self.name + ": EOF exception found" )
3305 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003306 main.cleanup()
3307 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003308 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003309 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003310 main.cleanup()
3311 main.exit()
3312
kelvin8ec71442015-01-15 16:57:00 -08003313 def getAllIntentIds( self ):
3314 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003315 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003316 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003317 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003318 cmdStr = "onos:intents | grep id="
3319 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003320 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003321 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003322 if re.search( "Error", output ):
3323 main.log.error( "Error in getting ports" )
3324 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003325 return output
Jon Hallc6793552016-01-19 14:18:37 -08003326 except AssertionError:
3327 main.log.exception( "" )
3328 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003329 except TypeError:
3330 main.log.exception( self.name + ": Object not as expected" )
3331 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003332 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003333 main.log.error( self.name + ": EOF exception found" )
3334 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003335 main.cleanup()
3336 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003337 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003338 main.log.exception( self.name + ": Uncaught exception!" )
3339 main.cleanup()
3340 main.exit()
3341
Jon Hall73509952015-02-24 16:42:56 -08003342 def intentSummary( self ):
3343 """
Jon Hallefbd9792015-03-05 16:11:36 -08003344 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003345 """
3346 try:
3347 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003348 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003349 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003350 states.append( intent.get( 'state', None ) )
3351 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003352 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003353 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003354 except ( TypeError, ValueError ):
3355 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003356 return None
3357 except pexpect.EOF:
3358 main.log.error( self.name + ": EOF exception found" )
3359 main.log.error( self.name + ": " + self.handle.before )
3360 main.cleanup()
3361 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003362 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003363 main.log.exception( self.name + ": Uncaught exception!" )
3364 main.cleanup()
3365 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003366
Jon Hall61282e32015-03-19 11:34:11 -07003367 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003368 """
3369 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003370 Optional argument:
3371 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003372 """
Jon Hall63604932015-02-26 17:09:50 -08003373 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003374 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003375 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003376 cmdStr += " -j"
3377 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003378 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003379 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003380 return output
Jon Hallc6793552016-01-19 14:18:37 -08003381 except AssertionError:
3382 main.log.exception( "" )
3383 return None
Jon Hall63604932015-02-26 17:09:50 -08003384 except TypeError:
3385 main.log.exception( self.name + ": Object not as expected" )
3386 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003387 except pexpect.EOF:
3388 main.log.error( self.name + ": EOF exception found" )
3389 main.log.error( self.name + ": " + self.handle.before )
3390 main.cleanup()
3391 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003392 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003393 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003394 main.cleanup()
3395 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003396
acsmarsa4a4d1e2015-07-10 16:01:24 -07003397 def leaderCandidates( self, jsonFormat=True ):
3398 """
3399 Returns the output of the leaders -c command.
3400 Optional argument:
3401 * jsonFormat - boolean indicating if you want output in json
3402 """
3403 try:
3404 cmdStr = "onos:leaders -c"
3405 if jsonFormat:
3406 cmdStr += " -j"
3407 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003408 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003409 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003410 return output
Jon Hallc6793552016-01-19 14:18:37 -08003411 except AssertionError:
3412 main.log.exception( "" )
3413 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003414 except TypeError:
3415 main.log.exception( self.name + ": Object not as expected" )
3416 return None
3417 except pexpect.EOF:
3418 main.log.error( self.name + ": EOF exception found" )
3419 main.log.error( self.name + ": " + self.handle.before )
3420 main.cleanup()
3421 main.exit()
3422 except Exception:
3423 main.log.exception( self.name + ": Uncaught exception!" )
3424 main.cleanup()
3425 main.exit()
3426
Jon Hallc6793552016-01-19 14:18:37 -08003427 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003428 """
3429 Returns a list in format [leader,candidate1,candidate2,...] for a given
3430 topic parameter and an empty list if the topic doesn't exist
3431 If no leader is elected leader in the returned list will be "none"
3432 Returns None if there is a type error processing the json object
3433 """
3434 try:
Jon Hall6e709752016-02-01 13:38:46 -08003435 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003436 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003437 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003438 assert "Command not found:" not in rawOutput, rawOutput
3439 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003440 results = []
3441 for dict in output:
3442 if dict["topic"] == topic:
3443 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003444 candidates = re.split( ", ", dict["candidates"][1:-1] )
3445 results.append( leader )
3446 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003447 return results
Jon Hallc6793552016-01-19 14:18:37 -08003448 except AssertionError:
3449 main.log.exception( "" )
3450 return None
3451 except ( TypeError, ValueError ):
3452 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003453 return None
3454 except pexpect.EOF:
3455 main.log.error( self.name + ": EOF exception found" )
3456 main.log.error( self.name + ": " + self.handle.before )
3457 main.cleanup()
3458 main.exit()
3459 except Exception:
3460 main.log.exception( self.name + ": Uncaught exception!" )
3461 main.cleanup()
3462 main.exit()
3463
Jon Hall61282e32015-03-19 11:34:11 -07003464 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003465 """
3466 Returns the output of the intent Pending map.
3467 """
Jon Hall63604932015-02-26 17:09:50 -08003468 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003469 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003470 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003471 cmdStr += " -j"
3472 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003473 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003474 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003475 return output
Jon Hallc6793552016-01-19 14:18:37 -08003476 except AssertionError:
3477 main.log.exception( "" )
3478 return None
Jon Hall63604932015-02-26 17:09:50 -08003479 except TypeError:
3480 main.log.exception( self.name + ": Object not as expected" )
3481 return None
3482 except pexpect.EOF:
3483 main.log.error( self.name + ": EOF exception found" )
3484 main.log.error( self.name + ": " + self.handle.before )
3485 main.cleanup()
3486 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003487 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003488 main.log.exception( self.name + ": Uncaught exception!" )
3489 main.cleanup()
3490 main.exit()
3491
Jon Hall2c8959e2016-12-16 12:17:34 -08003492 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003493 """
3494 Returns the output of the raft partitions command for ONOS.
3495 """
Jon Hall61282e32015-03-19 11:34:11 -07003496 # Sample JSON
3497 # {
3498 # "leader": "tcp://10.128.30.11:7238",
3499 # "members": [
3500 # "tcp://10.128.30.11:7238",
3501 # "tcp://10.128.30.17:7238",
3502 # "tcp://10.128.30.13:7238",
3503 # ],
3504 # "name": "p1",
3505 # "term": 3
3506 # },
Jon Hall63604932015-02-26 17:09:50 -08003507 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003508 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003509 if candidates:
3510 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003511 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003512 cmdStr += " -j"
3513 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003514 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003515 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003516 return output
Jon Hallc6793552016-01-19 14:18:37 -08003517 except AssertionError:
3518 main.log.exception( "" )
3519 return None
Jon Hall63604932015-02-26 17:09:50 -08003520 except TypeError:
3521 main.log.exception( self.name + ": Object not as expected" )
3522 return None
3523 except pexpect.EOF:
3524 main.log.error( self.name + ": EOF exception found" )
3525 main.log.error( self.name + ": " + self.handle.before )
3526 main.cleanup()
3527 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003528 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003529 main.log.exception( self.name + ": Uncaught exception!" )
3530 main.cleanup()
3531 main.exit()
3532
Jon Halle9f909e2016-09-23 10:43:12 -07003533 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003534 """
3535 Returns the output of the apps command for ONOS. This command lists
3536 information about installed ONOS applications
3537 """
3538 # Sample JSON object
3539 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3540 # "description":"ONOS OpenFlow protocol southbound providers",
3541 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3542 # "features":"[onos-openflow]","state":"ACTIVE"}]
3543 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003544 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003545 if summary:
3546 cmdStr += " -s"
3547 if active:
3548 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003549 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003550 cmdStr += " -j"
3551 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003552 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003553 assert "Command not found:" not in output, output
3554 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003555 return output
Jon Hallbe379602015-03-24 13:39:32 -07003556 # FIXME: look at specific exceptions/Errors
3557 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003558 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003559 return None
3560 except TypeError:
3561 main.log.exception( self.name + ": Object not as expected" )
3562 return None
3563 except pexpect.EOF:
3564 main.log.error( self.name + ": EOF exception found" )
3565 main.log.error( self.name + ": " + self.handle.before )
3566 main.cleanup()
3567 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003568 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003569 main.log.exception( self.name + ": Uncaught exception!" )
3570 main.cleanup()
3571 main.exit()
3572
Jon Hall146f1522015-03-24 15:33:24 -07003573 def appStatus( self, appName ):
3574 """
3575 Uses the onos:apps cli command to return the status of an application.
3576 Returns:
3577 "ACTIVE" - If app is installed and activated
3578 "INSTALLED" - If app is installed and deactivated
3579 "UNINSTALLED" - If app is not installed
3580 None - on error
3581 """
Jon Hall146f1522015-03-24 15:33:24 -07003582 try:
3583 if not isinstance( appName, types.StringType ):
3584 main.log.error( self.name + ".appStatus(): appName must be" +
3585 " a string" )
3586 return None
3587 output = self.apps( jsonFormat=True )
3588 appsJson = json.loads( output )
3589 state = None
3590 for app in appsJson:
3591 if appName == app.get('name'):
3592 state = app.get('state')
3593 break
3594 if state == "ACTIVE" or state == "INSTALLED":
3595 return state
3596 elif state is None:
3597 return "UNINSTALLED"
3598 elif state:
3599 main.log.error( "Unexpected state from 'onos:apps': " +
3600 str( state ) )
3601 return state
Jon Hallc6793552016-01-19 14:18:37 -08003602 except ( TypeError, ValueError ):
3603 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003604 return None
3605 except pexpect.EOF:
3606 main.log.error( self.name + ": EOF exception found" )
3607 main.log.error( self.name + ": " + self.handle.before )
3608 main.cleanup()
3609 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003610 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003611 main.log.exception( self.name + ": Uncaught exception!" )
3612 main.cleanup()
3613 main.exit()
3614
Jon Hallbe379602015-03-24 13:39:32 -07003615 def app( self, appName, option ):
3616 """
3617 Interacts with the app command for ONOS. This command manages
3618 application inventory.
3619 """
Jon Hallbe379602015-03-24 13:39:32 -07003620 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003621 # Validate argument types
3622 valid = True
3623 if not isinstance( appName, types.StringType ):
3624 main.log.error( self.name + ".app(): appName must be a " +
3625 "string" )
3626 valid = False
3627 if not isinstance( option, types.StringType ):
3628 main.log.error( self.name + ".app(): option must be a string" )
3629 valid = False
3630 if not valid:
3631 return main.FALSE
3632 # Validate Option
3633 option = option.lower()
3634 # NOTE: Install may become a valid option
3635 if option == "activate":
3636 pass
3637 elif option == "deactivate":
3638 pass
3639 elif option == "uninstall":
3640 pass
3641 else:
3642 # Invalid option
3643 main.log.error( "The ONOS app command argument only takes " +
3644 "the values: (activate|deactivate|uninstall)" +
3645 "; was given '" + option + "'")
3646 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003647 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003648 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003649 assert output is not None, "Error in sendline"
3650 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003651 if "Error executing command" in output:
3652 main.log.error( "Error in processing onos:app command: " +
3653 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003654 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003655 elif "No such application" in output:
3656 main.log.error( "The application '" + appName +
3657 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003658 return main.FALSE
3659 elif "Command not found:" in output:
3660 main.log.error( "Error in processing onos:app command: " +
3661 str( output ) )
3662 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003663 elif "Unsupported command:" in output:
3664 main.log.error( "Incorrect command given to 'app': " +
3665 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003666 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003667 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003668 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003669 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003670 except AssertionError:
3671 main.log.exception( self.name + ": AssertionError exception found" )
3672 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003673 except TypeError:
3674 main.log.exception( self.name + ": Object not as expected" )
3675 return main.ERROR
3676 except pexpect.EOF:
3677 main.log.error( self.name + ": EOF exception found" )
3678 main.log.error( self.name + ": " + self.handle.before )
3679 main.cleanup()
3680 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003681 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003682 main.log.exception( self.name + ": Uncaught exception!" )
3683 main.cleanup()
3684 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003685
Jon Hallbd16b922015-03-26 17:53:15 -07003686 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003687 """
3688 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003689 appName is the hierarchical app name, not the feature name
3690 If check is True, method will check the status of the app after the
3691 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003692 Returns main.TRUE if the command was successfully sent
3693 main.FALSE if the cli responded with an error or given
3694 incorrect input
3695 """
3696 try:
3697 if not isinstance( appName, types.StringType ):
3698 main.log.error( self.name + ".activateApp(): appName must be" +
3699 " a string" )
3700 return main.FALSE
3701 status = self.appStatus( appName )
3702 if status == "INSTALLED":
3703 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003704 if check and response == main.TRUE:
3705 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003706 status = self.appStatus( appName )
3707 if status == "ACTIVE":
3708 return main.TRUE
3709 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003710 main.log.debug( "The state of application " +
3711 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003712 time.sleep( 1 )
3713 return main.FALSE
3714 else: # not 'check' or command didn't succeed
3715 return response
Jon Hall146f1522015-03-24 15:33:24 -07003716 elif status == "ACTIVE":
3717 return main.TRUE
3718 elif status == "UNINSTALLED":
3719 main.log.error( self.name + ": Tried to activate the " +
3720 "application '" + appName + "' which is not " +
3721 "installed." )
3722 else:
3723 main.log.error( "Unexpected return value from appStatus: " +
3724 str( status ) )
3725 return main.ERROR
3726 except TypeError:
3727 main.log.exception( self.name + ": Object not as expected" )
3728 return main.ERROR
3729 except pexpect.EOF:
3730 main.log.error( self.name + ": EOF exception found" )
3731 main.log.error( self.name + ": " + self.handle.before )
3732 main.cleanup()
3733 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003734 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003735 main.log.exception( self.name + ": Uncaught exception!" )
3736 main.cleanup()
3737 main.exit()
3738
Jon Hallbd16b922015-03-26 17:53:15 -07003739 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003740 """
3741 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003742 appName is the hierarchical app name, not the feature name
3743 If check is True, method will check the status of the app after the
3744 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003745 Returns main.TRUE if the command was successfully sent
3746 main.FALSE if the cli responded with an error or given
3747 incorrect input
3748 """
3749 try:
3750 if not isinstance( appName, types.StringType ):
3751 main.log.error( self.name + ".deactivateApp(): appName must " +
3752 "be a string" )
3753 return main.FALSE
3754 status = self.appStatus( appName )
3755 if status == "INSTALLED":
3756 return main.TRUE
3757 elif status == "ACTIVE":
3758 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003759 if check and response == main.TRUE:
3760 for i in range(10): # try 10 times then give up
3761 status = self.appStatus( appName )
3762 if status == "INSTALLED":
3763 return main.TRUE
3764 else:
3765 time.sleep( 1 )
3766 return main.FALSE
3767 else: # not check or command didn't succeed
3768 return response
Jon Hall146f1522015-03-24 15:33:24 -07003769 elif status == "UNINSTALLED":
3770 main.log.warn( self.name + ": Tried to deactivate the " +
3771 "application '" + appName + "' which is not " +
3772 "installed." )
3773 return main.TRUE
3774 else:
3775 main.log.error( "Unexpected return value from appStatus: " +
3776 str( status ) )
3777 return main.ERROR
3778 except TypeError:
3779 main.log.exception( self.name + ": Object not as expected" )
3780 return main.ERROR
3781 except pexpect.EOF:
3782 main.log.error( self.name + ": EOF exception found" )
3783 main.log.error( self.name + ": " + self.handle.before )
3784 main.cleanup()
3785 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003786 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003787 main.log.exception( self.name + ": Uncaught exception!" )
3788 main.cleanup()
3789 main.exit()
3790
Jon Hallbd16b922015-03-26 17:53:15 -07003791 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003792 """
3793 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003794 appName is the hierarchical app name, not the feature name
3795 If check is True, method will check the status of the app after the
3796 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003797 Returns main.TRUE if the command was successfully sent
3798 main.FALSE if the cli responded with an error or given
3799 incorrect input
3800 """
3801 # TODO: check with Thomas about the state machine for apps
3802 try:
3803 if not isinstance( appName, types.StringType ):
3804 main.log.error( self.name + ".uninstallApp(): appName must " +
3805 "be a string" )
3806 return main.FALSE
3807 status = self.appStatus( appName )
3808 if status == "INSTALLED":
3809 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003810 if check and response == main.TRUE:
3811 for i in range(10): # try 10 times then give up
3812 status = self.appStatus( appName )
3813 if status == "UNINSTALLED":
3814 return main.TRUE
3815 else:
3816 time.sleep( 1 )
3817 return main.FALSE
3818 else: # not check or command didn't succeed
3819 return response
Jon Hall146f1522015-03-24 15:33:24 -07003820 elif status == "ACTIVE":
3821 main.log.warn( self.name + ": Tried to uninstall the " +
3822 "application '" + appName + "' which is " +
3823 "currently active." )
3824 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003825 if check and response == main.TRUE:
3826 for i in range(10): # try 10 times then give up
3827 status = self.appStatus( appName )
3828 if status == "UNINSTALLED":
3829 return main.TRUE
3830 else:
3831 time.sleep( 1 )
3832 return main.FALSE
3833 else: # not check or command didn't succeed
3834 return response
Jon Hall146f1522015-03-24 15:33:24 -07003835 elif status == "UNINSTALLED":
3836 return main.TRUE
3837 else:
3838 main.log.error( "Unexpected return value from appStatus: " +
3839 str( status ) )
3840 return main.ERROR
3841 except TypeError:
3842 main.log.exception( self.name + ": Object not as expected" )
3843 return main.ERROR
3844 except pexpect.EOF:
3845 main.log.error( self.name + ": EOF exception found" )
3846 main.log.error( self.name + ": " + self.handle.before )
3847 main.cleanup()
3848 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003849 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003850 main.log.exception( self.name + ": Uncaught exception!" )
3851 main.cleanup()
3852 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003853
3854 def appIDs( self, jsonFormat=True ):
3855 """
3856 Show the mappings between app id and app names given by the 'app-ids'
3857 cli command
3858 """
3859 try:
3860 cmdStr = "app-ids"
3861 if jsonFormat:
3862 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003863 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003864 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003865 assert "Command not found:" not in output, output
3866 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003867 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003868 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003869 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003870 return None
3871 except TypeError:
3872 main.log.exception( self.name + ": Object not as expected" )
3873 return None
3874 except pexpect.EOF:
3875 main.log.error( self.name + ": EOF exception found" )
3876 main.log.error( self.name + ": " + self.handle.before )
3877 main.cleanup()
3878 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003879 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003880 main.log.exception( self.name + ": Uncaught exception!" )
3881 main.cleanup()
3882 main.exit()
3883
3884 def appToIDCheck( self ):
3885 """
3886 This method will check that each application's ID listed in 'apps' is
3887 the same as the ID listed in 'app-ids'. The check will also check that
3888 there are no duplicate IDs issued. Note that an app ID should be
3889 a globaly unique numerical identifier for app/app-like features. Once
3890 an ID is registered, the ID is never freed up so that if an app is
3891 reinstalled it will have the same ID.
3892
3893 Returns: main.TRUE if the check passes and
3894 main.FALSE if the check fails or
3895 main.ERROR if there is some error in processing the test
3896 """
3897 try:
Jon Hall390696c2015-05-05 17:13:41 -07003898 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003899 rawJson = self.appIDs( jsonFormat=True )
3900 if rawJson:
3901 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003902 else:
Jon Hallc6793552016-01-19 14:18:37 -08003903 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003904 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003905 rawJson = self.apps( jsonFormat=True )
3906 if rawJson:
3907 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003908 else:
Jon Hallc6793552016-01-19 14:18:37 -08003909 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003910 bail = True
3911 if bail:
3912 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003913 result = main.TRUE
3914 for app in apps:
3915 appID = app.get( 'id' )
3916 if appID is None:
3917 main.log.error( "Error parsing app: " + str( app ) )
3918 result = main.FALSE
3919 appName = app.get( 'name' )
3920 if appName is None:
3921 main.log.error( "Error parsing app: " + str( app ) )
3922 result = main.FALSE
3923 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003924 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003925 # main.log.debug( "Comparing " + str( app ) + " to " +
3926 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003927 if not current: # if ids doesn't have this id
3928 result = main.FALSE
3929 main.log.error( "'app-ids' does not have the ID for " +
3930 str( appName ) + " that apps does." )
3931 elif len( current ) > 1:
3932 # there is more than one app with this ID
3933 result = main.FALSE
3934 # We will log this later in the method
3935 elif not current[0][ 'name' ] == appName:
3936 currentName = current[0][ 'name' ]
3937 result = main.FALSE
3938 main.log.error( "'app-ids' has " + str( currentName ) +
3939 " registered under id:" + str( appID ) +
3940 " but 'apps' has " + str( appName ) )
3941 else:
3942 pass # id and name match!
3943 # now make sure that app-ids has no duplicates
3944 idsList = []
3945 namesList = []
3946 for item in ids:
3947 idsList.append( item[ 'id' ] )
3948 namesList.append( item[ 'name' ] )
3949 if len( idsList ) != len( set( idsList ) ) or\
3950 len( namesList ) != len( set( namesList ) ):
3951 main.log.error( "'app-ids' has some duplicate entries: \n"
3952 + json.dumps( ids,
3953 sort_keys=True,
3954 indent=4,
3955 separators=( ',', ': ' ) ) )
3956 result = main.FALSE
3957 return result
Jon Hallc6793552016-01-19 14:18:37 -08003958 except ( TypeError, ValueError ):
3959 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003960 return main.ERROR
3961 except pexpect.EOF:
3962 main.log.error( self.name + ": EOF exception found" )
3963 main.log.error( self.name + ": " + self.handle.before )
3964 main.cleanup()
3965 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003966 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003967 main.log.exception( self.name + ": Uncaught exception!" )
3968 main.cleanup()
3969 main.exit()
3970
Jon Hallfb760a02015-04-13 15:35:03 -07003971 def getCfg( self, component=None, propName=None, short=False,
3972 jsonFormat=True ):
3973 """
3974 Get configuration settings from onos cli
3975 Optional arguments:
3976 component - Optionally only list configurations for a specific
3977 component. If None, all components with configurations
3978 are displayed. Case Sensitive string.
3979 propName - If component is specified, propName option will show
3980 only this specific configuration from that component.
3981 Case Sensitive string.
3982 jsonFormat - Returns output as json. Note that this will override
3983 the short option
3984 short - Short, less verbose, version of configurations.
3985 This is overridden by the json option
3986 returns:
3987 Output from cli as a string or None on error
3988 """
3989 try:
3990 baseStr = "cfg"
3991 cmdStr = " get"
3992 componentStr = ""
3993 if component:
3994 componentStr += " " + component
3995 if propName:
3996 componentStr += " " + propName
3997 if jsonFormat:
3998 baseStr += " -j"
3999 elif short:
4000 baseStr += " -s"
4001 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004002 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004003 assert "Command not found:" not in output, output
4004 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004005 return output
4006 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004007 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004008 return None
4009 except TypeError:
4010 main.log.exception( self.name + ": Object not as expected" )
4011 return None
4012 except pexpect.EOF:
4013 main.log.error( self.name + ": EOF exception found" )
4014 main.log.error( self.name + ": " + self.handle.before )
4015 main.cleanup()
4016 main.exit()
4017 except Exception:
4018 main.log.exception( self.name + ": Uncaught exception!" )
4019 main.cleanup()
4020 main.exit()
4021
4022 def setCfg( self, component, propName, value=None, check=True ):
4023 """
4024 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004025 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004026 component - The case sensitive name of the component whose
4027 property is to be set
4028 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004029 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004030 value - The value to set the property to. If None, will unset the
4031 property and revert it to it's default value(if applicable)
4032 check - Boolean, Check whether the option was successfully set this
4033 only applies when a value is given.
4034 returns:
4035 main.TRUE on success or main.FALSE on failure. If check is False,
4036 will return main.TRUE unless there is an error
4037 """
4038 try:
4039 baseStr = "cfg"
4040 cmdStr = " set " + str( component ) + " " + str( propName )
4041 if value is not None:
4042 cmdStr += " " + str( value )
4043 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004044 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004045 assert "Command not found:" not in output, output
4046 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004047 if value and check:
4048 results = self.getCfg( component=str( component ),
4049 propName=str( propName ),
4050 jsonFormat=True )
4051 # Check if current value is what we just set
4052 try:
4053 jsonOutput = json.loads( results )
4054 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004055 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004056 main.log.exception( "Error parsing cfg output" )
4057 main.log.error( "output:" + repr( results ) )
4058 return main.FALSE
4059 if current == str( value ):
4060 return main.TRUE
4061 return main.FALSE
4062 return main.TRUE
4063 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004064 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004065 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004066 except ( TypeError, ValueError ):
4067 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004068 return main.FALSE
4069 except pexpect.EOF:
4070 main.log.error( self.name + ": EOF exception found" )
4071 main.log.error( self.name + ": " + self.handle.before )
4072 main.cleanup()
4073 main.exit()
4074 except Exception:
4075 main.log.exception( self.name + ": Uncaught exception!" )
4076 main.cleanup()
4077 main.exit()
4078
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004079 def distPrimitivesSend( self, cmd ):
4080 """
4081 Function to handle sending cli commands for the distributed primitives test app
4082
4083 This command will catch some exceptions and retry the command on some
4084 specific store exceptions.
4085
4086 Required arguments:
4087 cmd - The command to send to the cli
4088 returns:
4089 string containing the cli output
4090 None on Error
4091 """
4092 try:
4093 output = self.sendline( cmd )
4094 try:
4095 assert output is not None, "Error in sendline"
4096 # TODO: Maybe make this less hardcoded
4097 # ConsistentMap Exceptions
4098 assert "org.onosproject.store.service" not in output
4099 # Node not leader
4100 assert "java.lang.IllegalStateException" not in output
4101 except AssertionError:
4102 main.log.error( "Error in processing '" + cmd + "' " +
4103 "command: " + str( output ) )
4104 retryTime = 30 # Conservative time, given by Madan
4105 main.log.info( "Waiting " + str( retryTime ) +
4106 "seconds before retrying." )
4107 time.sleep( retryTime ) # Due to change in mastership
4108 output = self.sendline( cmd )
4109 assert output is not None, "Error in sendline"
4110 assert "Command not found:" not in output, output
4111 assert "Error executing command" not in output, output
4112 main.log.info( self.name + ": " + output )
4113 return output
4114 except AssertionError:
4115 main.log.exception( "Error in processing '" + cmd + "' command." )
4116 return None
4117 except TypeError:
4118 main.log.exception( self.name + ": Object not as expected" )
4119 return None
4120 except pexpect.EOF:
4121 main.log.error( self.name + ": EOF exception found" )
4122 main.log.error( self.name + ": " + self.handle.before )
4123 main.cleanup()
4124 main.exit()
4125 except Exception:
4126 main.log.exception( self.name + ": Uncaught exception!" )
4127 main.cleanup()
4128 main.exit()
4129
Jon Hall390696c2015-05-05 17:13:41 -07004130 def setTestAdd( self, setName, values ):
4131 """
4132 CLI command to add elements to a distributed set.
4133 Arguments:
4134 setName - The name of the set to add to.
4135 values - The value(s) to add to the set, space seperated.
4136 Example usages:
4137 setTestAdd( "set1", "a b c" )
4138 setTestAdd( "set2", "1" )
4139 returns:
4140 main.TRUE on success OR
4141 main.FALSE if elements were already in the set OR
4142 main.ERROR on error
4143 """
4144 try:
4145 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004146 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004147 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4148 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jon Hall390696c2015-05-05 17:13:41 -07004149 if re.search( positiveMatch, output):
4150 return main.TRUE
4151 elif re.search( negativeMatch, output):
4152 return main.FALSE
4153 else:
4154 main.log.error( self.name + ": setTestAdd did not" +
4155 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004156 main.log.debug( self.name + " actual: " + repr( output ) )
4157 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004158 except TypeError:
4159 main.log.exception( self.name + ": Object not as expected" )
4160 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004161 except Exception:
4162 main.log.exception( self.name + ": Uncaught exception!" )
4163 main.cleanup()
4164 main.exit()
4165
4166 def setTestRemove( self, setName, values, clear=False, retain=False ):
4167 """
4168 CLI command to remove elements from a distributed set.
4169 Required arguments:
4170 setName - The name of the set to remove from.
4171 values - The value(s) to remove from the set, space seperated.
4172 Optional arguments:
4173 clear - Clear all elements from the set
4174 retain - Retain only the given values. (intersection of the
4175 original set and the given set)
4176 returns:
4177 main.TRUE on success OR
4178 main.FALSE if the set was not changed OR
4179 main.ERROR on error
4180 """
4181 try:
4182 cmdStr = "set-test-remove "
4183 if clear:
4184 cmdStr += "-c " + str( setName )
4185 elif retain:
4186 cmdStr += "-r " + str( setName ) + " " + str( values )
4187 else:
4188 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004189 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004190 if clear:
4191 pattern = "Set " + str( setName ) + " cleared"
4192 if re.search( pattern, output ):
4193 return main.TRUE
4194 elif retain:
4195 positivePattern = str( setName ) + " was pruned to contain " +\
4196 "only elements of set \[(.*)\]"
4197 negativePattern = str( setName ) + " was not changed by " +\
4198 "retaining only elements of the set " +\
4199 "\[(.*)\]"
4200 if re.search( positivePattern, output ):
4201 return main.TRUE
4202 elif re.search( negativePattern, output ):
4203 return main.FALSE
4204 else:
4205 positivePattern = "\[(.*)\] was removed from the set " +\
4206 str( setName )
4207 if ( len( values.split() ) == 1 ):
4208 negativePattern = "\[(.*)\] was not in set " +\
4209 str( setName )
4210 else:
4211 negativePattern = "No element of \[(.*)\] was in set " +\
4212 str( setName )
4213 if re.search( positivePattern, output ):
4214 return main.TRUE
4215 elif re.search( negativePattern, output ):
4216 return main.FALSE
4217 main.log.error( self.name + ": setTestRemove did not" +
4218 " match expected output" )
4219 main.log.debug( self.name + " expected: " + pattern )
4220 main.log.debug( self.name + " actual: " + repr( output ) )
4221 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004222 except TypeError:
4223 main.log.exception( self.name + ": Object not as expected" )
4224 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004225 except Exception:
4226 main.log.exception( self.name + ": Uncaught exception!" )
4227 main.cleanup()
4228 main.exit()
4229
4230 def setTestGet( self, setName, values="" ):
4231 """
4232 CLI command to get the elements in a distributed set.
4233 Required arguments:
4234 setName - The name of the set to remove from.
4235 Optional arguments:
4236 values - The value(s) to check if in the set, space seperated.
4237 returns:
4238 main.ERROR on error OR
4239 A list of elements in the set if no optional arguments are
4240 supplied OR
4241 A tuple containing the list then:
4242 main.FALSE if the given values are not in the set OR
4243 main.TRUE if the given values are in the set OR
4244 """
4245 try:
4246 values = str( values ).strip()
4247 setName = str( setName ).strip()
4248 length = len( values.split() )
4249 containsCheck = None
4250 # Patterns to match
4251 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004252 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004253 containsTrue = "Set " + setName + " contains the value " + values
4254 containsFalse = "Set " + setName + " did not contain the value " +\
4255 values
4256 containsAllTrue = "Set " + setName + " contains the the subset " +\
4257 setPattern
4258 containsAllFalse = "Set " + setName + " did not contain the the" +\
4259 " subset " + setPattern
4260
4261 cmdStr = "set-test-get "
4262 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004263 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004264 if length == 0:
4265 match = re.search( pattern, output )
4266 else: # if given values
4267 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004268 patternTrue = pattern + "\r\n" + containsTrue
4269 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004270 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004271 patternTrue = pattern + "\r\n" + containsAllTrue
4272 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004273 matchTrue = re.search( patternTrue, output )
4274 matchFalse = re.search( patternFalse, output )
4275 if matchTrue:
4276 containsCheck = main.TRUE
4277 match = matchTrue
4278 elif matchFalse:
4279 containsCheck = main.FALSE
4280 match = matchFalse
4281 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004282 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004283 "expected output" )
4284 main.log.debug( self.name + " expected: " + pattern )
4285 main.log.debug( self.name + " actual: " + repr( output ) )
4286 match = None
4287 if match:
4288 setMatch = match.group( 1 )
4289 if setMatch == '':
4290 setList = []
4291 else:
4292 setList = setMatch.split( ", " )
4293 if length > 0:
4294 return ( setList, containsCheck )
4295 else:
4296 return setList
4297 else: # no match
4298 main.log.error( self.name + ": setTestGet did not" +
4299 " match expected output" )
4300 main.log.debug( self.name + " expected: " + pattern )
4301 main.log.debug( self.name + " actual: " + repr( output ) )
4302 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004303 except TypeError:
4304 main.log.exception( self.name + ": Object not as expected" )
4305 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004306 except Exception:
4307 main.log.exception( self.name + ": Uncaught exception!" )
4308 main.cleanup()
4309 main.exit()
4310
4311 def setTestSize( self, setName ):
4312 """
4313 CLI command to get the elements in a distributed set.
4314 Required arguments:
4315 setName - The name of the set to remove from.
4316 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004317 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004318 None on error
4319 """
4320 try:
4321 # TODO: Should this check against the number of elements returned
4322 # and then return true/false based on that?
4323 setName = str( setName ).strip()
4324 # Patterns to match
4325 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004326 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004327 setPattern
4328 cmdStr = "set-test-get -s "
4329 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004330 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004331 match = re.search( pattern, output )
4332 if match:
4333 setSize = int( match.group( 1 ) )
4334 setMatch = match.group( 2 )
4335 if len( setMatch.split() ) == setSize:
4336 main.log.info( "The size returned by " + self.name +
4337 " matches the number of elements in " +
4338 "the returned set" )
4339 else:
4340 main.log.error( "The size returned by " + self.name +
4341 " does not match the number of " +
4342 "elements in the returned set." )
4343 return setSize
4344 else: # no match
4345 main.log.error( self.name + ": setTestGet did not" +
4346 " match expected output" )
4347 main.log.debug( self.name + " expected: " + pattern )
4348 main.log.debug( self.name + " actual: " + repr( output ) )
4349 return None
Jon Hall390696c2015-05-05 17:13:41 -07004350 except TypeError:
4351 main.log.exception( self.name + ": Object not as expected" )
4352 return None
Jon Hall390696c2015-05-05 17:13:41 -07004353 except Exception:
4354 main.log.exception( self.name + ": Uncaught exception!" )
4355 main.cleanup()
4356 main.exit()
4357
Jon Hall80daded2015-05-27 16:07:00 -07004358 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004359 """
4360 Command to list the various counters in the system.
4361 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004362 if jsonFormat, a string of the json object returned by the cli
4363 command
4364 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004365 None on error
4366 """
Jon Hall390696c2015-05-05 17:13:41 -07004367 try:
Jon Hall390696c2015-05-05 17:13:41 -07004368 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004369 if jsonFormat:
4370 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004371 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004372 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004373 assert "Command not found:" not in output, output
4374 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004375 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004376 return output
Jon Hall390696c2015-05-05 17:13:41 -07004377 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004378 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004379 return None
Jon Hall390696c2015-05-05 17:13:41 -07004380 except TypeError:
4381 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004382 return None
Jon Hall390696c2015-05-05 17:13:41 -07004383 except pexpect.EOF:
4384 main.log.error( self.name + ": EOF exception found" )
4385 main.log.error( self.name + ": " + self.handle.before )
4386 main.cleanup()
4387 main.exit()
4388 except Exception:
4389 main.log.exception( self.name + ": Uncaught exception!" )
4390 main.cleanup()
4391 main.exit()
4392
Jon Hall935db192016-04-19 00:22:04 -07004393 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004394 """
Jon Halle1a3b752015-07-22 13:02:46 -07004395 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004396 Required arguments:
4397 counter - The name of the counter to increment.
4398 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004399 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004400 returns:
4401 integer value of the counter or
4402 None on Error
4403 """
4404 try:
4405 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004406 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004407 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004408 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004409 if delta != 1:
4410 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004411 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004412 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004413 match = re.search( pattern, output )
4414 if match:
4415 return int( match.group( 1 ) )
4416 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004417 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004418 " match expected output." )
4419 main.log.debug( self.name + " expected: " + pattern )
4420 main.log.debug( self.name + " actual: " + repr( output ) )
4421 return None
Jon Hall390696c2015-05-05 17:13:41 -07004422 except TypeError:
4423 main.log.exception( self.name + ": Object not as expected" )
4424 return None
Jon Hall390696c2015-05-05 17:13:41 -07004425 except Exception:
4426 main.log.exception( self.name + ": Uncaught exception!" )
4427 main.cleanup()
4428 main.exit()
4429
Jon Hall935db192016-04-19 00:22:04 -07004430 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004431 """
4432 CLI command to get a distributed counter then add a delta to it.
4433 Required arguments:
4434 counter - The name of the counter to increment.
4435 Optional arguments:
4436 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004437 returns:
4438 integer value of the counter or
4439 None on Error
4440 """
4441 try:
4442 counter = str( counter )
4443 delta = int( delta )
4444 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004445 cmdStr += counter
4446 if delta != 1:
4447 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004448 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004449 pattern = counter + " was updated to (-?\d+)"
4450 match = re.search( pattern, output )
4451 if match:
4452 return int( match.group( 1 ) )
4453 else:
4454 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4455 " match expected output." )
4456 main.log.debug( self.name + " expected: " + pattern )
4457 main.log.debug( self.name + " actual: " + repr( output ) )
4458 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004459 except TypeError:
4460 main.log.exception( self.name + ": Object not as expected" )
4461 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004462 except Exception:
4463 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle1a3b752015-07-22 13:02:46 -07004464 main.cleanup()
4465 main.exit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004466
4467 def valueTestGet( self, valueName ):
4468 """
4469 CLI command to get the value of an atomic value.
4470 Required arguments:
4471 valueName - The name of the value to get.
4472 returns:
4473 string value of the value or
4474 None on Error
4475 """
4476 try:
4477 valueName = str( valueName )
4478 cmdStr = "value-test "
4479 operation = "get"
4480 cmdStr = "value-test {} {}".format( valueName,
4481 operation )
4482 output = self.distPrimitivesSend( cmdStr )
4483 pattern = "(\w+)"
4484 match = re.search( pattern, output )
4485 if match:
4486 return match.group( 1 )
4487 else:
4488 main.log.error( self.name + ": valueTestGet did not" +
4489 " match expected output." )
4490 main.log.debug( self.name + " expected: " + pattern )
4491 main.log.debug( self.name + " actual: " + repr( output ) )
4492 return None
4493 except TypeError:
4494 main.log.exception( self.name + ": Object not as expected" )
4495 return None
4496 except Exception:
4497 main.log.exception( self.name + ": Uncaught exception!" )
4498 main.cleanup()
4499 main.exit()
4500
4501 def valueTestSet( self, valueName, newValue ):
4502 """
4503 CLI command to set the value of an atomic value.
4504 Required arguments:
4505 valueName - The name of the value to set.
4506 newValue - The value to assign to the given value.
4507 returns:
4508 main.TRUE on success or
4509 main.ERROR on Error
4510 """
4511 try:
4512 valueName = str( valueName )
4513 newValue = str( newValue )
4514 operation = "set"
4515 cmdStr = "value-test {} {} {}".format( valueName,
4516 operation,
4517 newValue )
4518 output = self.distPrimitivesSend( cmdStr )
4519 if output is not None:
4520 return main.TRUE
4521 else:
4522 return main.ERROR
4523 except TypeError:
4524 main.log.exception( self.name + ": Object not as expected" )
4525 return main.ERROR
4526 except Exception:
4527 main.log.exception( self.name + ": Uncaught exception!" )
4528 main.cleanup()
4529 main.exit()
4530
4531 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4532 """
4533 CLI command to compareAndSet the value of an atomic value.
4534 Required arguments:
4535 valueName - The name of the value.
4536 oldValue - Compare the current value of the atomic value to this
4537 newValue - If the value equals oldValue, set the value to newValue
4538 returns:
4539 main.TRUE on success or
4540 main.FALSE on failure or
4541 main.ERROR on Error
4542 """
4543 try:
4544 valueName = str( valueName )
4545 oldValue = str( oldValue )
4546 newValue = str( newValue )
4547 operation = "compareAndSet"
4548 cmdStr = "value-test {} {} {} {}".format( valueName,
4549 operation,
4550 oldValue,
4551 newValue )
4552 output = self.distPrimitivesSend( cmdStr )
4553 pattern = "(\w+)"
4554 match = re.search( pattern, output )
4555 if match:
4556 result = match.group( 1 )
4557 if result == "true":
4558 return main.TRUE
4559 elif result == "false":
4560 return main.FALSE
4561 else:
4562 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4563 " match expected output." )
4564 main.log.debug( self.name + " expected: " + pattern )
4565 main.log.debug( self.name + " actual: " + repr( output ) )
4566 return main.ERROR
4567 except TypeError:
4568 main.log.exception( self.name + ": Object not as expected" )
4569 return main.ERROR
4570 except Exception:
4571 main.log.exception( self.name + ": Uncaught exception!" )
4572 main.cleanup()
4573 main.exit()
4574
4575 def valueTestGetAndSet( self, valueName, newValue ):
4576 """
4577 CLI command to getAndSet the value of an atomic value.
4578 Required arguments:
4579 valueName - The name of the value to get.
4580 newValue - The value to assign to the given value
4581 returns:
4582 string value of the value or
4583 None on Error
4584 """
4585 try:
4586 valueName = str( valueName )
4587 cmdStr = "value-test "
4588 operation = "getAndSet"
4589 cmdStr += valueName + " " + operation
4590 cmdStr = "value-test {} {} {}".format( valueName,
4591 operation,
4592 newValue )
4593 output = self.distPrimitivesSend( cmdStr )
4594 pattern = "(\w+)"
4595 match = re.search( pattern, output )
4596 if match:
4597 return match.group( 1 )
4598 else:
4599 main.log.error( self.name + ": valueTestGetAndSet did not" +
4600 " match expected output." )
4601 main.log.debug( self.name + " expected: " + pattern )
4602 main.log.debug( self.name + " actual: " + repr( output ) )
4603 return None
4604 except TypeError:
4605 main.log.exception( self.name + ": Object not as expected" )
4606 return None
4607 except Exception:
4608 main.log.exception( self.name + ": Uncaught exception!" )
4609 main.cleanup()
4610 main.exit()
4611
4612 def valueTestDestroy( self, valueName ):
4613 """
4614 CLI command to destroy an atomic value.
4615 Required arguments:
4616 valueName - The name of the value to destroy.
4617 returns:
4618 main.TRUE on success or
4619 main.ERROR on Error
4620 """
4621 try:
4622 valueName = str( valueName )
4623 cmdStr = "value-test "
4624 operation = "destroy"
4625 cmdStr += valueName + " " + operation
4626 output = self.distPrimitivesSend( cmdStr )
4627 if output is not None:
4628 return main.TRUE
4629 else:
4630 return main.ERROR
4631 except TypeError:
4632 main.log.exception( self.name + ": Object not as expected" )
4633 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004634 except Exception:
4635 main.log.exception( self.name + ": Uncaught exception!" )
4636 main.cleanup()
4637 main.exit()
4638
YPZhangfebf7302016-05-24 16:45:56 -07004639 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004640 """
4641 Description: Execute summary command in onos
4642 Returns: json object ( summary -j ), returns main.FALSE if there is
4643 no output
4644
4645 """
4646 try:
4647 cmdStr = "summary"
4648 if jsonFormat:
4649 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004650 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004651 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004652 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004653 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004654 if not handle:
4655 main.log.error( self.name + ": There is no output in " +
4656 "summary command" )
4657 return main.FALSE
4658 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004659 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004660 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004661 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004662 except TypeError:
4663 main.log.exception( self.name + ": Object not as expected" )
4664 return None
4665 except pexpect.EOF:
4666 main.log.error( self.name + ": EOF exception found" )
4667 main.log.error( self.name + ": " + self.handle.before )
4668 main.cleanup()
4669 main.exit()
4670 except Exception:
4671 main.log.exception( self.name + ": Uncaught exception!" )
4672 main.cleanup()
4673 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004674
Jon Hall935db192016-04-19 00:22:04 -07004675 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004676 """
4677 CLI command to get the value of a key in a consistent map using
4678 transactions. This a test function and can only get keys from the
4679 test map hard coded into the cli command
4680 Required arguments:
4681 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004682 returns:
4683 The string value of the key or
4684 None on Error
4685 """
4686 try:
4687 keyName = str( keyName )
4688 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004689 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004690 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004691 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4692 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004693 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004694 return None
4695 else:
4696 match = re.search( pattern, output )
4697 if match:
4698 return match.groupdict()[ 'value' ]
4699 else:
4700 main.log.error( self.name + ": transactionlMapGet did not" +
4701 " match expected output." )
4702 main.log.debug( self.name + " expected: " + pattern )
4703 main.log.debug( self.name + " actual: " + repr( output ) )
4704 return None
4705 except TypeError:
4706 main.log.exception( self.name + ": Object not as expected" )
4707 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004708 except Exception:
4709 main.log.exception( self.name + ": Uncaught exception!" )
4710 main.cleanup()
4711 main.exit()
4712
Jon Hall935db192016-04-19 00:22:04 -07004713 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004714 """
4715 CLI command to put a value into 'numKeys' number of keys in a
4716 consistent map using transactions. This a test function and can only
4717 put into keys named 'Key#' of the test map hard coded into the cli command
4718 Required arguments:
4719 numKeys - Number of keys to add the value to
4720 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004721 returns:
4722 A dictionary whose keys are the name of the keys put into the map
4723 and the values of the keys are dictionaries whose key-values are
4724 'value': value put into map and optionaly
4725 'oldValue': Previous value in the key or
4726 None on Error
4727
4728 Example output
4729 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4730 'Key2': {'value': 'Testing'} }
4731 """
4732 try:
4733 numKeys = str( numKeys )
4734 value = str( value )
4735 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004736 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004737 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004738 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4739 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4740 results = {}
4741 for line in output.splitlines():
4742 new = re.search( newPattern, line )
4743 updated = re.search( updatedPattern, line )
4744 if new:
4745 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4746 elif updated:
4747 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004748 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004749 else:
4750 main.log.error( self.name + ": transactionlMapGet did not" +
4751 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004752 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4753 newPattern,
4754 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004755 main.log.debug( self.name + " actual: " + repr( output ) )
4756 return results
4757 except TypeError:
4758 main.log.exception( self.name + ": Object not as expected" )
4759 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004760 except Exception:
4761 main.log.exception( self.name + ": Uncaught exception!" )
4762 main.cleanup()
4763 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004764
acsmarsdaea66c2015-09-03 11:44:06 -07004765 def maps( self, jsonFormat=True ):
4766 """
4767 Description: Returns result of onos:maps
4768 Optional:
4769 * jsonFormat: enable json formatting of output
4770 """
4771 try:
4772 cmdStr = "maps"
4773 if jsonFormat:
4774 cmdStr += " -j"
4775 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004776 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004777 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004778 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004779 except AssertionError:
4780 main.log.exception( "" )
4781 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004782 except TypeError:
4783 main.log.exception( self.name + ": Object not as expected" )
4784 return None
4785 except pexpect.EOF:
4786 main.log.error( self.name + ": EOF exception found" )
4787 main.log.error( self.name + ": " + self.handle.before )
4788 main.cleanup()
4789 main.exit()
4790 except Exception:
4791 main.log.exception( self.name + ": Uncaught exception!" )
4792 main.cleanup()
4793 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004794
4795 def getSwController( self, uri, jsonFormat=True ):
4796 """
4797 Descrition: Gets the controller information from the device
4798 """
4799 try:
4800 cmd = "device-controllers "
4801 if jsonFormat:
4802 cmd += "-j "
4803 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004804 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004805 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004806 return response
Jon Hallc6793552016-01-19 14:18:37 -08004807 except AssertionError:
4808 main.log.exception( "" )
4809 return None
GlennRC050596c2015-11-18 17:06:41 -08004810 except TypeError:
4811 main.log.exception( self.name + ": Object not as expected" )
4812 return None
4813 except pexpect.EOF:
4814 main.log.error( self.name + ": EOF exception found" )
4815 main.log.error( self.name + ": " + self.handle.before )
4816 main.cleanup()
4817 main.exit()
4818 except Exception:
4819 main.log.exception( self.name + ": Uncaught exception!" )
4820 main.cleanup()
4821 main.exit()
4822
4823 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4824 """
4825 Descrition: sets the controller(s) for the specified device
4826
4827 Parameters:
4828 Required: uri - String: The uri of the device(switch).
4829 ip - String or List: The ip address of the controller.
4830 This parameter can be formed in a couple of different ways.
4831 VALID:
4832 10.0.0.1 - just the ip address
4833 tcp:10.0.0.1 - the protocol and the ip address
4834 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4835 so that you can add controllers with different
4836 protocols and ports
4837 INVALID:
4838 10.0.0.1:6653 - this is not supported by ONOS
4839
4840 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4841 port - The port number.
4842 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4843
4844 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4845 """
4846 try:
4847 cmd = "device-setcontrollers"
4848
4849 if jsonFormat:
4850 cmd += " -j"
4851 cmd += " " + uri
4852 if isinstance( ip, str ):
4853 ip = [ip]
4854 for item in ip:
4855 if ":" in item:
4856 sitem = item.split( ":" )
4857 if len(sitem) == 3:
4858 cmd += " " + item
4859 elif "." in sitem[1]:
4860 cmd += " {}:{}".format(item, port)
4861 else:
4862 main.log.error( "Malformed entry: " + item )
4863 raise TypeError
4864 else:
4865 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004866 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004867 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004868 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004869 if "Error" in response:
4870 main.log.error( response )
4871 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004872 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004873 except AssertionError:
4874 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004875 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004876 except TypeError:
4877 main.log.exception( self.name + ": Object not as expected" )
4878 return main.FALSE
4879 except pexpect.EOF:
4880 main.log.error( self.name + ": EOF exception found" )
4881 main.log.error( self.name + ": " + self.handle.before )
4882 main.cleanup()
4883 main.exit()
4884 except Exception:
4885 main.log.exception( self.name + ": Uncaught exception!" )
4886 main.cleanup()
4887 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004888
4889 def removeDevice( self, device ):
4890 '''
4891 Description:
4892 Remove a device from ONOS by passing the uri of the device(s).
4893 Parameters:
4894 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4895 Returns:
4896 Returns main.FALSE if an exception is thrown or an error is present
4897 in the response. Otherwise, returns main.TRUE.
4898 NOTE:
4899 If a host cannot be removed, then this function will return main.FALSE
4900 '''
4901 try:
4902 if type( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004903 deviceStr = device
4904 device = []
4905 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004906
4907 for d in device:
4908 time.sleep( 1 )
4909 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004910 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004911 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004912 if "Error" in response:
4913 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4914 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004915 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004916 except AssertionError:
4917 main.log.exception( "" )
4918 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004919 except TypeError:
4920 main.log.exception( self.name + ": Object not as expected" )
4921 return main.FALSE
4922 except pexpect.EOF:
4923 main.log.error( self.name + ": EOF exception found" )
4924 main.log.error( self.name + ": " + self.handle.before )
4925 main.cleanup()
4926 main.exit()
4927 except Exception:
4928 main.log.exception( self.name + ": Uncaught exception!" )
4929 main.cleanup()
4930 main.exit()
4931
4932 def removeHost( self, host ):
4933 '''
4934 Description:
4935 Remove a host from ONOS by passing the id of the host(s)
4936 Parameters:
4937 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4938 Returns:
4939 Returns main.FALSE if an exception is thrown or an error is present
4940 in the response. Otherwise, returns main.TRUE.
4941 NOTE:
4942 If a host cannot be removed, then this function will return main.FALSE
4943 '''
4944 try:
4945 if type( host ) is str:
4946 host = list( host )
4947
4948 for h in host:
4949 time.sleep( 1 )
4950 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004951 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004952 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004953 if "Error" in response:
4954 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4955 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004956 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004957 except AssertionError:
4958 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004959 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004960 except TypeError:
4961 main.log.exception( self.name + ": Object not as expected" )
4962 return main.FALSE
4963 except pexpect.EOF:
4964 main.log.error( self.name + ": EOF exception found" )
4965 main.log.error( self.name + ": " + self.handle.before )
4966 main.cleanup()
4967 main.exit()
4968 except Exception:
4969 main.log.exception( self.name + ": Uncaught exception!" )
4970 main.cleanup()
4971 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004972
YPZhangfebf7302016-05-24 16:45:56 -07004973 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004974 '''
4975 Description:
4976 Bring link down or up in the null-provider.
4977 params:
4978 begin - (string) One end of a device or switch.
4979 end - (string) the other end of the device or switch
4980 returns:
4981 main.TRUE if no exceptions were thrown and no Errors are
4982 present in the resoponse. Otherwise, returns main.FALSE
4983 '''
4984 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004985 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004986 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004987 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004988 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004989 if "Error" in response or "Failure" in response:
4990 main.log.error( response )
4991 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004992 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004993 except AssertionError:
4994 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004995 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004996 except TypeError:
4997 main.log.exception( self.name + ": Object not as expected" )
4998 return main.FALSE
4999 except pexpect.EOF:
5000 main.log.error( self.name + ": EOF exception found" )
5001 main.log.error( self.name + ": " + self.handle.before )
5002 main.cleanup()
5003 main.exit()
5004 except Exception:
5005 main.log.exception( self.name + ": Uncaught exception!" )
5006 main.cleanup()
5007 main.exit()
5008
Jon Hall2c8959e2016-12-16 12:17:34 -08005009 def portstate( self, dpid, port, state ):
Flavio Castro82ee2f62016-06-07 15:04:12 -07005010 '''
5011 Description:
5012 Changes the state of port in an OF switch by means of the
5013 PORTSTATUS OF messages.
5014 params:
Jon Hall2c8959e2016-12-16 12:17:34 -08005015 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5016 port - (string) target port in the device. Ex: '2'
5017 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005018 returns:
5019 main.TRUE if no exceptions were thrown and no Errors are
5020 present in the resoponse. Otherwise, returns main.FALSE
5021 '''
5022 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005023 state = state.lower()
5024 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005025 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005026 response = self.sendline( cmd, showResponse=True )
5027 assert response is not None, "Error in sendline"
5028 assert "Command not found:" not in response, response
5029 if "Error" in response or "Failure" in response:
5030 main.log.error( response )
5031 return main.FALSE
5032 return main.TRUE
5033 except AssertionError:
5034 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005035 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005036 except TypeError:
5037 main.log.exception( self.name + ": Object not as expected" )
5038 return main.FALSE
5039 except pexpect.EOF:
5040 main.log.error( self.name + ": EOF exception found" )
5041 main.log.error( self.name + ": " + self.handle.before )
5042 main.cleanup()
5043 main.exit()
5044 except Exception:
5045 main.log.exception( self.name + ": Uncaught exception!" )
5046 main.cleanup()
5047 main.exit()
5048
5049 def logSet( self, level="INFO", app="org.onosproject" ):
5050 """
5051 Set the logging level to lvl for a specific app
5052 returns main.TRUE on success
5053 returns main.FALSE if Error occurred
5054 if noExit is True, TestON will not exit, but clean up
5055 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5056 Level defaults to INFO
5057 """
5058 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005059 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005060 self.handle.expect( "onos>" )
5061
5062 response = self.handle.before
5063 if re.search( "Error", response ):
5064 return main.FALSE
5065 return main.TRUE
5066 except pexpect.TIMEOUT:
5067 main.log.exception( self.name + ": TIMEOUT exception found" )
5068 main.cleanup()
5069 main.exit()
5070 except pexpect.EOF:
5071 main.log.error( self.name + ": EOF exception found" )
5072 main.log.error( self.name + ": " + self.handle.before )
5073 main.cleanup()
5074 main.exit()
5075 except Exception:
5076 main.log.exception( self.name + ": Uncaught exception!" )
5077 main.cleanup()
5078 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005079
5080 def getGraphDict( self, timeout=60, includeHost=False ):
5081 """
5082 Return a dictionary which describes the latest network topology data as a
5083 graph.
5084 An example of the dictionary:
5085 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5086 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5087 Each vertex should at least have an 'edges' attribute which describes the
5088 adjacency information. The value of 'edges' attribute is also represented by
5089 a dictionary, which maps each edge (identified by the neighbor vertex) to a
5090 list of attributes.
5091 An example of the edges dictionary:
5092 'edges': { vertex2: { 'port': ..., 'weight': ... },
5093 vertex3: { 'port': ..., 'weight': ... } }
5094 If includeHost == True, all hosts (and host-switch links) will be included
5095 in topology data.
5096 """
5097 graphDict = {}
5098 try:
5099 links = self.links()
5100 links = json.loads( links )
5101 devices = self.devices()
5102 devices = json.loads( devices )
5103 idToDevice = {}
5104 for device in devices:
5105 idToDevice[ device[ 'id' ] ] = device
5106 if includeHost:
5107 hosts = self.hosts()
5108 # FIXME: support 'includeHost' argument
5109 for link in links:
5110 nodeA = link[ 'src' ][ 'device' ]
5111 nodeB = link[ 'dst' ][ 'device' ]
5112 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005113 if nodeA not in graphDict.keys():
5114 graphDict[ nodeA ] = { 'edges': {},
5115 'dpid': idToDevice[ nodeA ][ 'id' ][3:],
5116 'type': idToDevice[ nodeA ][ 'type' ],
5117 'available': idToDevice[ nodeA ][ 'available' ],
5118 'role': idToDevice[ nodeA ][ 'role' ],
5119 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5120 'hw': idToDevice[ nodeA ][ 'hw' ],
5121 'sw': idToDevice[ nodeA ][ 'sw' ],
5122 'serial': idToDevice[ nodeA ][ 'serial' ],
5123 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
5124 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005125 else:
5126 # Assert nodeB is not connected to any current links of nodeA
5127 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005128 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5129 'type': link[ 'type' ],
5130 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005131 return graphDict
5132 except ( TypeError, ValueError ):
5133 main.log.exception( self.name + ": Object not as expected" )
5134 return None
5135 except KeyError:
5136 main.log.exception( self.name + ": KeyError exception found" )
5137 return None
5138 except AssertionError:
5139 main.log.exception( self.name + ": AssertionError exception found" )
5140 return None
5141 except pexpect.EOF:
5142 main.log.error( self.name + ": EOF exception found" )
5143 main.log.error( self.name + ": " + self.handle.before )
5144 return None
5145 except Exception:
5146 main.log.exception( self.name + ": Uncaught exception!" )
5147 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005148
5149 def getIntentPerfSummary( self ):
5150 '''
5151 Send command to check intent-perf summary
5152 Returns: dictionary for intent-perf summary
5153 if something wrong, function will return None
5154 '''
5155 cmd = "intent-perf -s"
5156 respDic = {}
5157 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005158 assert resp is not None, "Error in sendline"
5159 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005160 try:
5161 # Generate the dictionary to return
5162 for l in resp.split( "\n" ):
5163 # Delete any white space in line
5164 temp = re.sub( r'\s+', '', l )
5165 temp = temp.split( ":" )
5166 respDic[ temp[0] ] = temp[ 1 ]
5167
5168 except (TypeError, ValueError):
5169 main.log.exception( self.name + ": Object not as expected" )
5170 return None
5171 except KeyError:
5172 main.log.exception( self.name + ": KeyError exception found" )
5173 return None
5174 except AssertionError:
5175 main.log.exception( self.name + ": AssertionError exception found" )
5176 return None
5177 except pexpect.EOF:
5178 main.log.error( self.name + ": EOF exception found" )
5179 main.log.error( self.name + ": " + self.handle.before )
5180 return None
5181 except Exception:
5182 main.log.exception( self.name + ": Uncaught exception!" )
5183 return None
5184 return respDic
5185
Chiyu Chengec63bde2016-11-17 18:11:36 -08005186 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005187 """
5188 Searches the latest ONOS log file for the given search term and
5189 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005190
chengchiyu08303a02016-09-08 17:40:26 -07005191 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005192 searchTerm:
5193 The string to grep from the ONOS log.
5194 startLine:
5195 The term that decides which line is the start to search the searchTerm in
5196 the karaf log. For now, startTerm only works in 'first' mode.
5197 logNum:
5198 In some extreme cases, one karaf log is not big enough to contain all the
5199 information.Because of this, search mutiply logs is necessary to capture
5200 the right result. logNum is the number of karaf logs that we need to search
5201 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005202 mode:
5203 all: return all the strings that contain the search term
5204 last: return the last string that contains the search term
5205 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005206 num: return the number of times that the searchTerm appears in the log
5207 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005208 """
5209 try:
5210 assert type( searchTerm ) is str
Jon Halle0f0b342017-04-18 11:43:47 -07005211 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005212 logPath = '/opt/onos/log/karaf.log.'
5213 logPaths = '/opt/onos/log/karaf.log'
5214 for i in range( 1, logNum ):
5215 logPaths = logPath + str( i ) + " " + logPaths
5216 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005217 if startLine:
5218 # 100000000 is just a extreme large number to make sure this function can grep all the lines after startLine
5219 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005220 if mode == 'all':
5221 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005222 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005223 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005224 elif mode == 'first':
5225 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5226 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005227 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005228 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005229 return num
You Wang6d301d42017-04-21 10:49:33 -07005230 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005231 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
5232 return int(totalLines)
You Wang6d301d42017-04-21 10:49:33 -07005233 else:
5234 main.log.error( self.name + " unsupported mode" )
5235 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005236 before = self.sendline( cmd )
5237 before = before.splitlines()
5238 # make sure the returned list only contains the search term
5239 returnLines = [line for line in before if searchTerm in line]
5240 return returnLines
5241 except AssertionError:
5242 main.log.error( self.name + " searchTerm is not string type" )
5243 return None
5244 except pexpect.EOF:
5245 main.log.error( self.name + ": EOF exception found" )
5246 main.log.error( self.name + ": " + self.handle.before )
5247 main.cleanup()
5248 main.exit()
5249 except pexpect.TIMEOUT:
5250 main.log.error( self.name + ": TIMEOUT exception found" )
5251 main.log.error( self.name + ": " + self.handle.before )
5252 main.cleanup()
5253 main.exit()
5254 except Exception:
5255 main.log.exception( self.name + ": Uncaught exception!" )
5256 main.cleanup()
5257 main.exit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005258
5259 def vplsShow( self, jsonFormat=True ):
5260 """
5261 Description: Returns result of onos:vpls show, which should list the
5262 configured VPLS networks and the assigned interfaces.
5263 Optional:
5264 * jsonFormat: enable json formatting of output
5265 Returns:
5266 The output of the command or None on error.
5267 """
5268 try:
5269 cmdStr = "vpls show"
5270 if jsonFormat:
5271 raise NotImplementedError
5272 cmdStr += " -j"
5273 handle = self.sendline( cmdStr )
5274 assert handle is not None, "Error in sendline"
5275 assert "Command not found:" not in handle, handle
5276 return handle
5277 except AssertionError:
5278 main.log.exception( "" )
5279 return None
5280 except TypeError:
5281 main.log.exception( self.name + ": Object not as expected" )
5282 return None
5283 except pexpect.EOF:
5284 main.log.error( self.name + ": EOF exception found" )
5285 main.log.error( self.name + ": " + self.handle.before )
5286 main.cleanup()
5287 main.exit()
5288 except NotImplementedError:
5289 main.log.exception( self.name + ": Json output not supported")
5290 return None
5291 except Exception:
5292 main.log.exception( self.name + ": Uncaught exception!" )
5293 main.cleanup()
5294 main.exit()
5295
5296 def parseVplsShow( self ):
5297 """
5298 Parse the cli output of 'vpls show' into json output. This is required
5299 as there is currently no json output available.
5300 """
5301 try:
5302 output = []
5303 raw = self.vplsShow( jsonFormat=False )
5304 namePat = "VPLS name: (?P<name>\w+)"
5305 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5306 encapPat = "Encapsulation: (?P<encap>\w+)"
5307 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5308 mIter = re.finditer( pattern, raw )
5309 for match in mIter:
5310 item = {}
5311 item[ 'name' ] = match.group( 'name' )
5312 ifaces = match.group( 'interfaces' ).split( ', ')
5313 if ifaces == [ "" ]:
5314 ifaces = []
5315 item[ 'interfaces' ] = ifaces
5316 encap = match.group( 'encap' )
5317 if encap != 'NONE':
5318 item[ 'encapsulation' ] = encap.lower()
5319 output.append( item )
5320 return output
5321 except Exception:
5322 main.log.exception( self.name + ": Uncaught exception!" )
5323 main.cleanup()
5324 main.exit()
5325
5326 def vplsList( self, jsonFormat=True ):
5327 """
5328 Description: Returns result of onos:vpls list, which should list the
5329 configured VPLS networks.
5330 Optional:
5331 * jsonFormat: enable json formatting of output
5332 """
5333 try:
5334 cmdStr = "vpls list"
5335 if jsonFormat:
5336 raise NotImplementedError
5337 cmdStr += " -j"
5338 handle = self.sendline( cmdStr )
5339 assert handle is not None, "Error in sendline"
5340 assert "Command not found:" not in handle, handle
5341 return handle
5342 except AssertionError:
5343 main.log.exception( "" )
5344 return None
5345 except TypeError:
5346 main.log.exception( self.name + ": Object not as expected" )
5347 return None
5348 except pexpect.EOF:
5349 main.log.error( self.name + ": EOF exception found" )
5350 main.log.error( self.name + ": " + self.handle.before )
5351 main.cleanup()
5352 main.exit()
5353 except NotImplementedError:
5354 main.log.exception( self.name + ": Json output not supported")
5355 return None
5356 except Exception:
5357 main.log.exception( self.name + ": Uncaught exception!" )
5358 main.cleanup()
5359 main.exit()
5360
5361 def vplsCreate( self, network ):
5362 """
5363 CLI command to create a new VPLS network.
5364 Required arguments:
5365 network - String name of the network to create.
5366 returns:
5367 main.TRUE on success and main.FALSE on failure
5368 """
5369 try:
5370 network = str( network )
5371 cmdStr = "vpls create "
5372 cmdStr += network
5373 output = self.sendline( cmdStr )
5374 assert output is not None, "Error in sendline"
5375 assert "Command not found:" not in output, output
5376 assert "Error executing command" not in output, output
5377 assert "VPLS already exists:" not in output, output
5378 return main.TRUE
5379 except AssertionError:
5380 main.log.exception( "" )
5381 return main.FALSE
5382 except TypeError:
5383 main.log.exception( self.name + ": Object not as expected" )
5384 return main.FALSE
5385 except pexpect.EOF:
5386 main.log.error( self.name + ": EOF exception found" )
5387 main.log.error( self.name + ": " + self.handle.before )
5388 main.cleanup()
5389 main.exit()
5390 except Exception:
5391 main.log.exception( self.name + ": Uncaught exception!" )
5392 main.cleanup()
5393 main.exit()
5394
5395 def vplsDelete( self, network ):
5396 """
5397 CLI command to delete a VPLS network.
5398 Required arguments:
5399 network - Name of the network to delete.
5400 returns:
5401 main.TRUE on success and main.FALSE on failure
5402 """
5403 try:
5404 network = str( network )
5405 cmdStr = "vpls delete "
5406 cmdStr += network
5407 output = self.sendline( cmdStr )
5408 assert output is not None, "Error in sendline"
5409 assert "Command not found:" not in output, output
5410 assert "Error executing command" not in output, output
5411 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005412 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005413 return main.TRUE
5414 except AssertionError:
5415 main.log.exception( "" )
5416 return main.FALSE
5417 except TypeError:
5418 main.log.exception( self.name + ": Object not as expected" )
5419 return main.FALSE
5420 except pexpect.EOF:
5421 main.log.error( self.name + ": EOF exception found" )
5422 main.log.error( self.name + ": " + self.handle.before )
5423 main.cleanup()
5424 main.exit()
5425 except Exception:
5426 main.log.exception( self.name + ": Uncaught exception!" )
5427 main.cleanup()
5428 main.exit()
5429
5430 def vplsAddIface( self, network, iface ):
5431 """
5432 CLI command to add an interface to a VPLS network.
5433 Required arguments:
5434 network - Name of the network to add the interface to.
5435 iface - The ONOS name for an interface.
5436 returns:
5437 main.TRUE on success and main.FALSE on failure
5438 """
5439 try:
5440 network = str( network )
5441 iface = str( iface )
5442 cmdStr = "vpls add-if "
5443 cmdStr += network + " " + iface
5444 output = self.sendline( cmdStr )
5445 assert output is not None, "Error in sendline"
5446 assert "Command not found:" not in output, output
5447 assert "Error executing command" not in output, output
5448 assert "already associated to network" not in output, output
5449 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005450 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005451 return main.TRUE
5452 except AssertionError:
5453 main.log.exception( "" )
5454 return main.FALSE
5455 except TypeError:
5456 main.log.exception( self.name + ": Object not as expected" )
5457 return main.FALSE
5458 except pexpect.EOF:
5459 main.log.error( self.name + ": EOF exception found" )
5460 main.log.error( self.name + ": " + self.handle.before )
5461 main.cleanup()
5462 main.exit()
5463 except Exception:
5464 main.log.exception( self.name + ": Uncaught exception!" )
5465 main.cleanup()
5466 main.exit()
5467
5468 def vplsRemIface( self, network, iface ):
5469 """
5470 CLI command to remove an interface from a VPLS network.
5471 Required arguments:
5472 network - Name of the network to remove the interface from.
5473 iface - Name of the interface to remove.
5474 returns:
5475 main.TRUE on success and main.FALSE on failure
5476 """
5477 try:
5478 iface = str( iface )
5479 cmdStr = "vpls rem-if "
5480 cmdStr += network + " " + iface
5481 output = self.sendline( cmdStr )
5482 assert output is not None, "Error in sendline"
5483 assert "Command not found:" not in output, output
5484 assert "Error executing command" not in output, output
5485 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005486 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005487 return main.TRUE
5488 except AssertionError:
5489 main.log.exception( "" )
5490 return main.FALSE
5491 except TypeError:
5492 main.log.exception( self.name + ": Object not as expected" )
5493 return main.FALSE
5494 except pexpect.EOF:
5495 main.log.error( self.name + ": EOF exception found" )
5496 main.log.error( self.name + ": " + self.handle.before )
5497 main.cleanup()
5498 main.exit()
5499 except Exception:
5500 main.log.exception( self.name + ": Uncaught exception!" )
5501 main.cleanup()
5502 main.exit()
5503
5504 def vplsClean( self ):
5505 """
5506 Description: Clears the VPLS app configuration.
5507 Returns: main.TRUE on success and main.FALSE on failure
5508 """
5509 try:
5510 cmdStr = "vpls clean"
5511 handle = self.sendline( cmdStr )
5512 assert handle is not None, "Error in sendline"
5513 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005514 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005515 return handle
5516 except AssertionError:
5517 main.log.exception( "" )
5518 return main.FALSE
5519 except TypeError:
5520 main.log.exception( self.name + ": Object not as expected" )
5521 return main.FALSE
5522 except pexpect.EOF:
5523 main.log.error( self.name + ": EOF exception found" )
5524 main.log.error( self.name + ": " + self.handle.before )
5525 main.cleanup()
5526 main.exit()
5527 except Exception:
5528 main.log.exception( self.name + ": Uncaught exception!" )
5529 main.cleanup()
5530 main.exit()
5531
5532 def vplsSetEncap( self, network, encapType ):
5533 """
5534 CLI command to add an interface to a VPLS network.
5535 Required arguments:
5536 network - Name of the network to create.
5537 encapType - Type of encapsulation.
5538 returns:
5539 main.TRUE on success and main.FALSE on failure
5540 """
5541 try:
5542 network = str( network )
5543 encapType = str( encapType ).upper()
5544 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5545 cmdStr = "vpls set-encap "
5546 cmdStr += network + " " + encapType
5547 output = self.sendline( cmdStr )
5548 assert output is not None, "Error in sendline"
5549 assert "Command not found:" not in output, output
5550 assert "Error executing command" not in output, output
5551 assert "already associated to network" not in output, output
5552 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005553 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005554 return main.TRUE
5555 except AssertionError:
5556 main.log.exception( "" )
5557 return main.FALSE
5558 except TypeError:
5559 main.log.exception( self.name + ": Object not as expected" )
5560 return main.FALSE
5561 except pexpect.EOF:
5562 main.log.error( self.name + ": EOF exception found" )
5563 main.log.error( self.name + ": " + self.handle.before )
5564 main.cleanup()
5565 main.exit()
5566 except Exception:
5567 main.log.exception( self.name + ": Uncaught exception!" )
5568 main.cleanup()
5569 main.exit()
5570
5571 def interfaces( self, jsonFormat=True ):
5572 """
5573 Description: Returns result of interfaces command.
5574 Optional:
5575 * jsonFormat: enable json formatting of output
5576 Returns:
5577 The output of the command or None on error.
5578 """
5579 try:
5580 cmdStr = "interfaces"
5581 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005582 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005583 cmdStr += " -j"
5584 handle = self.sendline( cmdStr )
5585 assert handle is not None, "Error in sendline"
5586 assert "Command not found:" not in handle, handle
5587 return handle
5588 except AssertionError:
5589 main.log.exception( "" )
5590 return None
5591 except TypeError:
5592 main.log.exception( self.name + ": Object not as expected" )
5593 return None
5594 except pexpect.EOF:
5595 main.log.error( self.name + ": EOF exception found" )
5596 main.log.error( self.name + ": " + self.handle.before )
5597 main.cleanup()
5598 main.exit()
5599 except NotImplementedError:
5600 main.log.exception( self.name + ": Json output not supported")
5601 return None
5602 except Exception:
5603 main.log.exception( self.name + ": Uncaught exception!" )
5604 main.cleanup()
5605 main.exit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005606
5607 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
5608 '''
5609 Get the timestamp of searchTerm from karaf log.
5610
5611 Arguments:
5612 splitTerm_before and splitTerm_after:
5613
5614 The terms that split the string that contains the timeStamp of
5615 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5616 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5617 and the splitTerm_after is "x"
5618
5619 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005620 Please look at the "logsearch" Function in onosclidriver.py
Chiyu Chengec63bde2016-11-17 18:11:36 -08005621 '''
5622 if logNum < 0:
5623 main.log.error("Get wrong log number ")
5624 return main.ERROR
5625 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
5626 if len(lines) == 0:
5627 main.log.warn( "Captured timestamp string is empty" )
5628 return main.ERROR
5629 lines = lines[ 0 ]
5630 try:
5631 assert type(lines) is str
5632 # get the target value
5633 line = lines.split( splitTerm_before )
5634 key = line[ 1 ].split( splitTerm_after )
5635 return int( key[ 0 ] )
5636 except IndexError:
5637 main.log.warn( "Index Error!" )
5638 return main.ERROR
5639 except AssertionError:
5640 main.log.warn( "Search Term Not Found " )
5641 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005642
5643 def workQueueAdd( self, queueName, value ):
5644 """
5645 CLI command to add a string to the specified Work Queue.
5646 This function uses the distributed primitives test app, which
5647 gives some cli access to distributed primitives for testing
5648 purposes only.
5649
5650 Required arguments:
5651 queueName - The name of the queue to add to
5652 value - The value to add to the queue
5653 returns:
5654 main.TRUE on success, main.FALSE on failure and
5655 main.ERROR on error.
5656 """
5657 try:
5658 queueName = str( queueName )
5659 value = str( value )
5660 prefix = "work-queue-test"
5661 operation = "add"
5662 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5663 output = self.distPrimitivesSend( cmdStr )
5664 if "Invalid operation name" in output:
5665 main.log.warn( output )
5666 return main.ERROR
5667 elif "Done" in output:
5668 return main.TRUE
5669 except TypeError:
5670 main.log.exception( self.name + ": Object not as expected" )
5671 return main.ERROR
5672 except Exception:
5673 main.log.exception( self.name + ": Uncaught exception!" )
5674 main.cleanup()
5675 main.exit()
5676
5677 def workQueueAddMultiple( self, queueName, value1, value2 ):
5678 """
5679 CLI command to add two strings to the specified Work Queue.
5680 This function uses the distributed primitives test app, which
5681 gives some cli access to distributed primitives for testing
5682 purposes only.
5683
5684 Required arguments:
5685 queueName - The name of the queue to add to
5686 value1 - The first value to add to the queue
5687 value2 - The second value to add to the queue
5688 returns:
5689 main.TRUE on success, main.FALSE on failure and
5690 main.ERROR on error.
5691 """
5692 try:
5693 queueName = str( queueName )
5694 value1 = str( value1 )
5695 value2 = str( value2 )
5696 prefix = "work-queue-test"
5697 operation = "addMultiple"
5698 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5699 output = self.distPrimitivesSend( cmdStr )
5700 if "Invalid operation name" in output:
5701 main.log.warn( output )
5702 return main.ERROR
5703 elif "Done" in output:
5704 return main.TRUE
5705 except TypeError:
5706 main.log.exception( self.name + ": Object not as expected" )
5707 return main.ERROR
5708 except Exception:
5709 main.log.exception( self.name + ": Uncaught exception!" )
5710 main.cleanup()
5711 main.exit()
5712
5713 def workQueueTakeAndComplete( self, queueName, number=1 ):
5714 """
5715 CLI command to take a value from the specified Work Queue and compelte it.
5716 This function uses the distributed primitives test app, which
5717 gives some cli access to distributed primitives for testing
5718 purposes only.
5719
5720 Required arguments:
5721 queueName - The name of the queue to add to
5722 number - The number of items to take and complete
5723 returns:
5724 main.TRUE on success, main.FALSE on failure and
5725 main.ERROR on error.
5726 """
5727 try:
5728 queueName = str( queueName )
5729 number = str( int( number ) )
5730 prefix = "work-queue-test"
5731 operation = "takeAndComplete"
5732 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5733 output = self.distPrimitivesSend( cmdStr )
5734 if "Invalid operation name" in output:
5735 main.log.warn( output )
5736 return main.ERROR
5737 elif "Done" in output:
5738 return main.TRUE
5739 except TypeError:
5740 main.log.exception( self.name + ": Object not as expected" )
5741 return main.ERROR
5742 except Exception:
5743 main.log.exception( self.name + ": Uncaught exception!" )
5744 main.cleanup()
5745 main.exit()
5746
5747 def workQueueDestroy( self, queueName ):
5748 """
5749 CLI command to destroy the specified Work Queue.
5750 This function uses the distributed primitives test app, which
5751 gives some cli access to distributed primitives for testing
5752 purposes only.
5753
5754 Required arguments:
5755 queueName - The name of the queue to add to
5756 returns:
5757 main.TRUE on success, main.FALSE on failure and
5758 main.ERROR on error.
5759 """
5760 try:
5761 queueName = str( queueName )
5762 prefix = "work-queue-test"
5763 operation = "destroy"
5764 cmdStr = " ".join( [ prefix, queueName, operation ] )
5765 output = self.distPrimitivesSend( cmdStr )
5766 if "Invalid operation name" in output:
5767 main.log.warn( output )
5768 return main.ERROR
5769 return main.TRUE
5770 except TypeError:
5771 main.log.exception( self.name + ": Object not as expected" )
5772 return main.ERROR
5773 except Exception:
5774 main.log.exception( self.name + ": Uncaught exception!" )
5775 main.cleanup()
5776 main.exit()
5777
5778 def workQueueTotalPending( self, queueName ):
5779 """
5780 CLI command to get the Total Pending items of the specified Work Queue.
5781 This function uses the distributed primitives test app, which
5782 gives some cli access to distributed primitives for testing
5783 purposes only.
5784
5785 Required arguments:
5786 queueName - The name of the queue to add to
5787 returns:
5788 The number of Pending items in the specified work queue or
5789 None on error
5790 """
5791 try:
5792 queueName = str( queueName )
5793 prefix = "work-queue-test"
5794 operation = "totalPending"
5795 cmdStr = " ".join( [ prefix, queueName, operation ] )
5796 output = self.distPrimitivesSend( cmdStr )
5797 pattern = r'\d+'
5798 if "Invalid operation name" in output:
5799 main.log.warn( output )
5800 return None
5801 else:
5802 match = re.search( pattern, output )
5803 return match.group(0)
5804 except ( AttributeError, TypeError ):
5805 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5806 return None
5807 except Exception:
5808 main.log.exception( self.name + ": Uncaught exception!" )
5809 main.cleanup()
5810 main.exit()
5811
5812 def workQueueTotalCompleted( self, queueName ):
5813 """
5814 CLI command to get the Total Completed items of the specified Work Queue.
5815 This function uses the distributed primitives test app, which
5816 gives some cli access to distributed primitives for testing
5817 purposes only.
5818
5819 Required arguments:
5820 queueName - The name of the queue to add to
5821 returns:
5822 The number of complete items in the specified work queue or
5823 None on error
5824 """
5825 try:
5826 queueName = str( queueName )
5827 prefix = "work-queue-test"
5828 operation = "totalCompleted"
5829 cmdStr = " ".join( [ prefix, queueName, operation ] )
5830 output = self.distPrimitivesSend( cmdStr )
5831 pattern = r'\d+'
5832 if "Invalid operation name" in output:
5833 main.log.warn( output )
5834 return None
5835 else:
5836 match = re.search( pattern, output )
5837 return match.group(0)
5838 except ( AttributeError, TypeError ):
5839 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5840 return None
5841 except Exception:
5842 main.log.exception( self.name + ": Uncaught exception!" )
5843 main.cleanup()
5844 main.exit()
5845
5846 def workQueueTotalInProgress( self, queueName ):
5847 """
5848 CLI command to get the Total In Progress items of the specified Work Queue.
5849 This function uses the distributed primitives test app, which
5850 gives some cli access to distributed primitives for testing
5851 purposes only.
5852
5853 Required arguments:
5854 queueName - The name of the queue to add to
5855 returns:
5856 The number of In Progress items in the specified work queue or
5857 None on error
5858 """
5859 try:
5860 queueName = str( queueName )
5861 prefix = "work-queue-test"
5862 operation = "totalInProgress"
5863 cmdStr = " ".join( [ prefix, queueName, operation ] )
5864 output = self.distPrimitivesSend( cmdStr )
5865 pattern = r'\d+'
5866 if "Invalid operation name" in output:
5867 main.log.warn( output )
5868 return None
5869 else:
5870 match = re.search( pattern, output )
5871 return match.group(0)
5872 except ( AttributeError, TypeError ):
5873 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5874 return None
5875 except Exception:
5876 main.log.exception( self.name + ": Uncaught exception!" )
5877 main.cleanup()
5878 main.exit()