blob: 032460b1bbdf74d19455ad97681cdef6a8ba3b8d [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
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002238 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002239 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002240 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002241 "getting intents state" )
2242 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002243
2244 if isinstance( expectedState, types.StringType ):
2245 for intents in intentsDict:
2246 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002247 main.log.debug( self.name + " : Intent ID - " +
2248 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002249 " actual state = " +
2250 intents.get( 'state' )
2251 + " does not equal expected state = "
2252 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002253 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002254
2255 elif isinstance( expectedState, types.ListType ):
2256 for intents in intentsDict:
2257 if not any( state == intents.get( 'state' ) for state in
2258 expectedState ):
2259 main.log.debug( self.name + " : Intent ID - " +
2260 intents.get( 'id' ) +
2261 " actual state = " +
2262 intents.get( 'state' ) +
2263 " does not equal expected states = "
2264 + str( expectedState ) )
2265 returnValue = main.FALSE
2266
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002267 if returnValue == main.TRUE:
2268 main.log.info( self.name + ": All " +
2269 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002270 " intents are in " + str( expectedState ) +
2271 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002272 return returnValue
2273 except TypeError:
2274 main.log.exception( self.name + ": Object not as expected" )
2275 return None
2276 except pexpect.EOF:
2277 main.log.error( self.name + ": EOF exception found" )
2278 main.log.error( self.name + ": " + self.handle.before )
2279 main.cleanup()
2280 main.exit()
2281 except Exception:
2282 main.log.exception( self.name + ": Uncaught exception!" )
2283 main.cleanup()
2284 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002285
Jon Hallf539eb92017-05-22 17:18:42 -07002286 def compareBandwidthAllocations( self, expectedAllocations ):
2287 """
2288 Description:
2289 Compare the allocated bandwidth with the given allocations
2290 Required:
2291 expectedAllocations - The expected ONOS output of the allocations command
2292 Return:
2293 Returns main.TRUE only if all intent are the same as expected states,
2294 otherwise returns main.FALSE.
2295 """
2296 # FIXME: Convert these string comparisons to object comparisons
2297 try:
2298 returnValue = main.TRUE
2299 bandwidthFailed = False
2300 rawAlloc = self.allocations()
2301 expectedFormat = StringIO( expectedAllocations )
2302 ONOSOutput = StringIO( rawAlloc )
2303 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2304 str( expectedFormat ) ) )
2305
2306 for actual, expected in izip( ONOSOutput, expectedFormat ):
2307 actual = actual.rstrip()
2308 expected = expected.rstrip()
2309 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2310 if actual != expected and 'allocated' in actual and 'allocated' in expected:
2311 marker1 = actual.find('allocated')
2312 m1 = actual[:marker1]
2313 marker2 = expected.find('allocated')
2314 m2 = expected[:marker2]
2315 if m1 != m2:
2316 bandwidthFailed = True
2317 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2318 bandwidthFailed = True
2319 expectedFormat.close()
2320 ONOSOutput.close()
2321
2322 if bandwidthFailed:
2323 main.log.error("Bandwidth not allocated correctly using Intents!!")
2324 returnValue = main.FALSE
2325 return returnValue
2326 except TypeError:
2327 main.log.exception( self.name + ": Object not as expected" )
2328 return None
2329 except pexpect.EOF:
2330 main.log.error( self.name + ": EOF exception found" )
2331 main.log.error( self.name + ": " + self.handle.before )
2332 main.cleanup()
2333 main.exit()
2334 except Exception:
2335 main.log.exception( self.name + ": Uncaught exception!" )
2336 main.cleanup()
2337 main.exit()
2338
You Wang66518af2016-05-16 15:32:59 -07002339 def compareIntent( self, intentDict ):
2340 """
2341 Description:
2342 Compare the intent ids and states provided in the argument with all intents in ONOS
2343 Return:
2344 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2345 Arguments:
2346 intentDict: a dictionary which maps intent ids to intent states
2347 """
2348 try:
2349 intentsRaw = self.intents()
2350 intentsJson = json.loads( intentsRaw )
2351 intentDictONOS = {}
2352 for intent in intentsJson:
2353 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002354 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002355 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002356 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002357 str( len( intentDict ) ) + " expected and " +
2358 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002359 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002360 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002361 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002362 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2363 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002364 else:
2365 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2366 main.log.debug( self.name + ": intent ID - " + intentID +
2367 " expected state is " + intentDict[ intentID ] +
2368 " but actual state is " + intentDictONOS[ intentID ] )
2369 returnValue = main.FALSE
2370 intentDictONOS.pop( intentID )
2371 if len( intentDictONOS ) > 0:
2372 returnValue = main.FALSE
2373 for intentID in intentDictONOS.keys():
2374 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002375 if returnValue == main.TRUE:
2376 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2377 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002378 except KeyError:
2379 main.log.exception( self.name + ": KeyError exception found" )
2380 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002381 except ( TypeError, ValueError ):
2382 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002383 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002384 except pexpect.EOF:
2385 main.log.error( self.name + ": EOF exception found" )
2386 main.log.error( self.name + ": " + self.handle.before )
2387 main.cleanup()
2388 main.exit()
2389 except Exception:
2390 main.log.exception( self.name + ": Uncaught exception!" )
2391 main.cleanup()
2392 main.exit()
2393
YPZhang14a4aa92016-07-15 13:37:15 -07002394 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002395 """
2396 Description:
2397 Check the number of installed intents.
2398 Optional:
2399 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002400 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002401 Return:
2402 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2403 , otherwise, returns main.FALSE.
2404 """
2405
2406 try:
2407 cmd = "intents -s -j"
2408
2409 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002410 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002411 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002412 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002413 response = json.loads( response )
2414
2415 # get total and installed number, see if they are match
2416 allState = response.get( 'all' )
2417 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002418 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002419 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002420 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002421 return main.FALSE
2422
Jon Hallc6793552016-01-19 14:18:37 -08002423 except ( TypeError, ValueError ):
2424 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002425 return None
2426 except pexpect.EOF:
2427 main.log.error( self.name + ": EOF exception found" )
2428 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002429 if noExit:
2430 return main.FALSE
2431 else:
2432 main.cleanup()
2433 main.exit()
Jon Halle0f0b342017-04-18 11:43:47 -07002434 except pexpect.TIMEOUT:
2435 main.log.error( self.name + ": ONOS timeout" )
2436 return None
GlennRCed771242016-01-13 17:02:47 -08002437 except Exception:
2438 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002439 if noExit:
2440 return main.FALSE
2441 else:
2442 main.cleanup()
2443 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002444
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002445 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002446 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002447 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002448 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002449 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002450 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002451 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002452 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002453 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002454 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002455 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002456 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002457 if noCore:
2458 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002459 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002460 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002461 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002462 assert "Command not found:" not in handle, handle
2463 if re.search( "Error:", handle ):
2464 main.log.error( self.name + ": flows() response: " +
2465 str( handle ) )
2466 return handle
2467 except AssertionError:
2468 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002469 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002470 except TypeError:
2471 main.log.exception( self.name + ": Object not as expected" )
2472 return None
Jon Hallc6793552016-01-19 14:18:37 -08002473 except pexpect.TIMEOUT:
2474 main.log.error( self.name + ": ONOS timeout" )
2475 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002476 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002477 main.log.error( self.name + ": EOF exception found" )
2478 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002479 main.cleanup()
2480 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002481 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002482 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002483 main.cleanup()
2484 main.exit()
2485
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002486 def checkFlowCount(self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002487 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002488 count = int( count ) if count else 0
2489 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002490
Jon Halle0f0b342017-04-18 11:43:47 -07002491 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002492 """
2493 Description:
GlennRCed771242016-01-13 17:02:47 -08002494 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002495 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2496 if the count of those states is 0, which means all current flows
2497 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002498 Optional:
GlennRCed771242016-01-13 17:02:47 -08002499 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002500 Return:
2501 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002502 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002503 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002504 """
2505 try:
GlennRCed771242016-01-13 17:02:47 -08002506 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2507 checkedStates = []
2508 statesCount = [0, 0, 0, 0]
2509 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002510 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002511 if rawFlows:
2512 # if we didn't get flows or flows function return None, we should return
2513 # main.Flase
2514 checkedStates.append( json.loads( rawFlows ) )
2515 else:
2516 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002517 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002518 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002519 try:
2520 statesCount[i] += int( c.get( "flowCount" ) )
2521 except TypeError:
2522 main.log.exception( "Json object not as expected" )
2523 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002524
GlennRCed771242016-01-13 17:02:47 -08002525 # We want to count PENDING_ADD if isPENDING is true
2526 if isPENDING:
2527 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2528 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002529 else:
GlennRCed771242016-01-13 17:02:47 -08002530 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2531 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002532 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002533 except ( TypeError, ValueError ):
2534 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002535 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002536
YPZhang240842b2016-05-17 12:00:50 -07002537 except AssertionError:
2538 main.log.exception( "" )
2539 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002540 except pexpect.TIMEOUT:
2541 main.log.error( self.name + ": ONOS timeout" )
2542 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002543 except pexpect.EOF:
2544 main.log.error( self.name + ": EOF exception found" )
2545 main.log.error( self.name + ": " + self.handle.before )
2546 main.cleanup()
2547 main.exit()
2548 except Exception:
2549 main.log.exception( self.name + ": Uncaught exception!" )
2550 main.cleanup()
2551 main.exit()
2552
GlennRCed771242016-01-13 17:02:47 -08002553 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002554 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002555 """
andrewonlab87852b02014-11-19 18:44:19 -05002556 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002557 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002558 a specific point-to-point intent definition
2559 Required:
GlennRCed771242016-01-13 17:02:47 -08002560 * ingress: specify source dpid
2561 * egress: specify destination dpid
2562 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002563 Optional:
GlennRCed771242016-01-13 17:02:47 -08002564 * offset: the keyOffset is where the next batch of intents
2565 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002566 * noExit: If set to True, TestON will not exit if any error when issus command
2567 * getResponse: If set to True, function will return ONOS response.
2568
GlennRCed771242016-01-13 17:02:47 -08002569 Returns: If failed to push test intents, it will returen None,
2570 if successful, return true.
2571 Timeout expection will return None,
2572 TypeError will return false
2573 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002574 """
andrewonlab87852b02014-11-19 18:44:19 -05002575 try:
GlennRCed771242016-01-13 17:02:47 -08002576 if background:
2577 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002578 else:
GlennRCed771242016-01-13 17:02:47 -08002579 back = ""
2580 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002581 ingress,
2582 egress,
2583 batchSize,
2584 offset,
2585 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002586 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002587 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002588 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002589 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002590 if getResponse:
2591 return response
2592
GlennRCed771242016-01-13 17:02:47 -08002593 # TODO: We should handle if there is failure in installation
2594 return main.TRUE
2595
Jon Hallc6793552016-01-19 14:18:37 -08002596 except AssertionError:
2597 main.log.exception( "" )
2598 return None
GlennRCed771242016-01-13 17:02:47 -08002599 except pexpect.TIMEOUT:
2600 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002601 return None
andrewonlab87852b02014-11-19 18:44:19 -05002602 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002603 main.log.error( self.name + ": EOF exception found" )
2604 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002605 main.cleanup()
2606 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002607 except TypeError:
2608 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002609 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002610 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002611 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002612 main.cleanup()
2613 main.exit()
2614
YPZhangebf9eb52016-05-12 15:20:24 -07002615 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002616 """
2617 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002618 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002619 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002620 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002621 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002622 """
YPZhange3109a72016-02-02 11:25:37 -08002623
YPZhangb5d3f832016-01-23 22:54:26 -08002624 try:
YPZhange3109a72016-02-02 11:25:37 -08002625 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002626 cmd = "flows -c added"
2627 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2628 if rawFlows:
2629 rawFlows = rawFlows.split("\n")
YPZhange3109a72016-02-02 11:25:37 -08002630 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002631 for l in rawFlows:
2632 totalFlows += int(l.split("Count=")[1])
2633 else:
2634 main.log.error("Response not as expected!")
2635 return None
2636 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002637
You Wangd3cb2ce2016-05-16 14:01:24 -07002638 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002639 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002640 return None
2641 except pexpect.EOF:
2642 main.log.error( self.name + ": EOF exception found" )
2643 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002644 if not noExit:
2645 main.cleanup()
2646 main.exit()
2647 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002648 except pexpect.TIMEOUT:
2649 main.log.error( self.name + ": ONOS timeout" )
2650 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002651 except Exception:
2652 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002653 if not noExit:
2654 main.cleanup()
2655 main.exit()
2656 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002657
YPZhang14a4aa92016-07-15 13:37:15 -07002658 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002659 """
2660 Description:
2661 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002662 Optional:
2663 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002664 Return:
2665 The number of intents
2666 """
2667 try:
2668 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002669 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002670 if response is None:
2671 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002672 response = json.loads( response )
2673 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002674 except ( TypeError, ValueError ):
2675 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002676 return None
2677 except pexpect.EOF:
2678 main.log.error( self.name + ": EOF exception found" )
2679 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002680 if noExit:
2681 return -1
2682 else:
2683 main.cleanup()
2684 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002685 except Exception:
2686 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002687 if noExit:
2688 return -1
2689 else:
2690 main.cleanup()
2691 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002692
kelvin-onlabd3b64892015-01-20 13:26:24 -08002693 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002694 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002695 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002696 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002697 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002698 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002699 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002700 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002701 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002702 cmdStr += " -j"
2703 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002704 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002705 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002706 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002707 except AssertionError:
2708 main.log.exception( "" )
2709 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002710 except TypeError:
2711 main.log.exception( self.name + ": Object not as expected" )
2712 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002713 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002714 main.log.error( self.name + ": EOF exception found" )
2715 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002716 main.cleanup()
2717 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002718 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002719 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002720 main.cleanup()
2721 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002722
kelvin-onlabd3b64892015-01-20 13:26:24 -08002723 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002724 """
2725 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002726 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002727 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002728 """
andrewonlab867212a2014-10-22 20:13:38 -04002729 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002730 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002731 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002732 cmdStr += " -j"
2733 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002734 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002735 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002736 if handle:
2737 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002738 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002739 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002740 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002741 else:
2742 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002743 except AssertionError:
2744 main.log.exception( "" )
2745 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002746 except TypeError:
2747 main.log.exception( self.name + ": Object not as expected" )
2748 return None
andrewonlab867212a2014-10-22 20:13:38 -04002749 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002750 main.log.error( self.name + ": EOF exception found" )
2751 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002752 main.cleanup()
2753 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002754 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002755 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002756 main.cleanup()
2757 main.exit()
2758
kelvin8ec71442015-01-15 16:57:00 -08002759 # Wrapper functions ****************
2760 # Wrapper functions use existing driver
2761 # functions and extends their use case.
2762 # For example, we may use the output of
2763 # a normal driver function, and parse it
2764 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002765
kelvin-onlabd3b64892015-01-20 13:26:24 -08002766 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002767 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002768 Description:
2769 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002770 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002771 try:
kelvin8ec71442015-01-15 16:57:00 -08002772 # Obtain output of intents function
Jon Hall6021e062017-01-30 11:10:06 -08002773 intentsStr = self.intents(jsonFormat=True)
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002774 if intentsStr is None:
2775 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002776 # Convert to a dictionary
2777 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002778 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002779 for intent in intents:
2780 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002781 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002782 except TypeError:
2783 main.log.exception( self.name + ": Object not as expected" )
2784 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002785 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002786 main.log.error( self.name + ": EOF exception found" )
2787 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002788 main.cleanup()
2789 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002790 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002791 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002792 main.cleanup()
2793 main.exit()
2794
You Wang3c276252016-09-21 15:21:36 -07002795 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002796 """
2797 Determine the number of flow rules for the given device id that are
2798 in the added state
You Wang3c276252016-09-21 15:21:36 -07002799 Params:
2800 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002801 """
2802 try:
You Wang3c276252016-09-21 15:21:36 -07002803 if core:
2804 cmdStr = "flows any " + str( deviceId ) + " | " +\
2805 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2806 else:
2807 cmdStr = "flows any " + str( deviceId ) + " | " +\
2808 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002809 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002810 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002811 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002812 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002813 except AssertionError:
2814 main.log.exception( "" )
2815 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002816 except pexpect.EOF:
2817 main.log.error( self.name + ": EOF exception found" )
2818 main.log.error( self.name + ": " + self.handle.before )
2819 main.cleanup()
2820 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002821 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002822 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002823 main.cleanup()
2824 main.exit()
2825
kelvin-onlabd3b64892015-01-20 13:26:24 -08002826 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002827 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002828 Use 'devices' function to obtain list of all devices
2829 and parse the result to obtain a list of all device
2830 id's. Returns this list. Returns empty list if no
2831 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002832 List is ordered sequentially
2833
andrewonlab3e15ead2014-10-15 14:21:34 -04002834 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002835 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002836 the ids. By obtaining the list of device ids on the fly,
2837 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002838 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002839 try:
kelvin8ec71442015-01-15 16:57:00 -08002840 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002841 devicesStr = self.devices( jsonFormat=False )
2842 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002843
kelvin-onlabd3b64892015-01-20 13:26:24 -08002844 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002845 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002846 return idList
kelvin8ec71442015-01-15 16:57:00 -08002847
2848 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002849 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002850 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002851 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002852 # Split list further into arguments before and after string
2853 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002854 # append to idList
2855 for arg in tempList:
2856 idList.append( arg.split( "id=" )[ 1 ] )
2857 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002858
Jon Halld4d4b372015-01-28 16:02:41 -08002859 except TypeError:
2860 main.log.exception( self.name + ": Object not as expected" )
2861 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002862 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002863 main.log.error( self.name + ": EOF exception found" )
2864 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002865 main.cleanup()
2866 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002867 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002868 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002869 main.cleanup()
2870 main.exit()
2871
kelvin-onlabd3b64892015-01-20 13:26:24 -08002872 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002873 """
andrewonlab7c211572014-10-15 16:45:20 -04002874 Uses 'nodes' function to obtain list of all nodes
2875 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002876 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002877 Returns:
2878 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002879 """
andrewonlab7c211572014-10-15 16:45:20 -04002880 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002881 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002882 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002883 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002884 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002885 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002886 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002887 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002888 nodesJson = json.loads( nodesStr )
2889 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002890 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002891 except ( TypeError, ValueError ):
2892 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002893 return None
andrewonlab7c211572014-10-15 16:45:20 -04002894 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002895 main.log.error( self.name + ": EOF exception found" )
2896 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002897 main.cleanup()
2898 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002899 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002900 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002901 main.cleanup()
2902 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002903
kelvin-onlabd3b64892015-01-20 13:26:24 -08002904 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002905 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002906 Return the first device from the devices api whose 'id' contains 'dpid'
2907 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002908 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002909 try:
kelvin8ec71442015-01-15 16:57:00 -08002910 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002911 return None
2912 else:
kelvin8ec71442015-01-15 16:57:00 -08002913 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002914 rawDevices = self.devices()
2915 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002916 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002917 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002918 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2919 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002920 return device
2921 return None
Jon Hallc6793552016-01-19 14:18:37 -08002922 except ( TypeError, ValueError ):
2923 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002924 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002925 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002926 main.log.error( self.name + ": EOF exception found" )
2927 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002928 main.cleanup()
2929 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002930 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002931 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002932 main.cleanup()
2933 main.exit()
2934
You Wang24139872016-05-03 11:48:47 -07002935 def getTopology( self, topologyOutput ):
2936 """
2937 Definition:
2938 Loads a json topology output
2939 Return:
2940 topology = current ONOS topology
2941 """
2942 import json
2943 try:
2944 # either onos:topology or 'topology' will work in CLI
2945 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002946 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002947 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002948 except ( TypeError, ValueError ):
2949 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2950 return None
You Wang24139872016-05-03 11:48:47 -07002951 except pexpect.EOF:
2952 main.log.error( self.name + ": EOF exception found" )
2953 main.log.error( self.name + ": " + self.handle.before )
2954 main.cleanup()
2955 main.exit()
2956 except Exception:
2957 main.log.exception( self.name + ": Uncaught exception!" )
2958 main.cleanup()
2959 main.exit()
2960
Flavio Castro82ee2f62016-06-07 15:04:12 -07002961 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002962 """
Jon Hallefbd9792015-03-05 16:11:36 -08002963 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002964 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002965 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002966
Flavio Castro82ee2f62016-06-07 15:04:12 -07002967 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002968 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002969 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002970 logLevel = level to log to.
2971 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002972
Jon Hallefbd9792015-03-05 16:11:36 -08002973 Returns: main.TRUE if the number of switches and links are correct,
2974 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002975 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002976 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002977 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002978 try:
You Wang13310252016-07-31 10:56:14 -07002979 summary = self.summary()
2980 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002981 except ( TypeError, ValueError ):
2982 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2983 return main.ERROR
2984 try:
2985 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07002986 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002987 return main.ERROR
2988 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002989 # Is the number of switches is what we expected
2990 devices = topology.get( 'devices', False )
2991 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002992 nodes = summary.get( 'nodes', False )
2993 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002994 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002995 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002996 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002997 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002998 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2999 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003000 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003001 output = output + "The number of links and switches match "\
3002 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003003 result = main.TRUE
3004 else:
You Wang24139872016-05-03 11:48:47 -07003005 output = output + \
3006 "The number of links and switches does not match " + \
3007 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003008 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003009 output = output + "\n ONOS sees %i devices" % int( devices )
3010 output = output + " (%i expected) " % int( numoswitch )
3011 output = output + "and %i links " % int( links )
3012 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003013 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003014 output = output + "and %i controllers " % int( nodes )
3015 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003016 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003017 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003018 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003019 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003020 else:
You Wang24139872016-05-03 11:48:47 -07003021 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003022 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003023 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003024 main.log.error( self.name + ": EOF exception found" )
3025 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04003026 main.cleanup()
3027 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003028 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003029 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04003030 main.cleanup()
3031 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003032
kelvin-onlabd3b64892015-01-20 13:26:24 -08003033 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003034 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003035 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003036 deviceId must be the id of a device as seen in the onos devices command
3037 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003038 role must be either master, standby, or none
3039
Jon Halle3f39ff2015-01-13 11:50:53 -08003040 Returns:
3041 main.TRUE or main.FALSE based on argument verification and
3042 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003043 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003044 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003045 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003046 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003047 cmdStr = "device-role " +\
3048 str( deviceId ) + " " +\
3049 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003050 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003051 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003052 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003053 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003054 if re.search( "Error", handle ):
3055 # end color output to escape any colours
3056 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003057 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003058 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003059 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003060 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003061 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003062 main.log.error( "Invalid 'role' given to device_role(). " +
3063 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003064 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003065 except AssertionError:
3066 main.log.exception( "" )
3067 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003068 except TypeError:
3069 main.log.exception( self.name + ": Object not as expected" )
3070 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003071 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003072 main.log.error( self.name + ": EOF exception found" )
3073 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04003074 main.cleanup()
3075 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003076 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003077 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04003078 main.cleanup()
3079 main.exit()
3080
kelvin-onlabd3b64892015-01-20 13:26:24 -08003081 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003082 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003083 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003084 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003085 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003086 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003087 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003088 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003089 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003090 cmdStr += " -j"
3091 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003092 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003093 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003094 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003095 except AssertionError:
3096 main.log.exception( "" )
3097 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003098 except TypeError:
3099 main.log.exception( self.name + ": Object not as expected" )
3100 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003101 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003102 main.log.error( self.name + ": EOF exception found" )
3103 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08003104 main.cleanup()
3105 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003106 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003107 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08003108 main.cleanup()
3109 main.exit()
3110
kelvin-onlabd3b64892015-01-20 13:26:24 -08003111 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003112 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003113 CLI command to get the current leader for the Election test application
3114 NOTE: Requires installation of the onos-app-election feature
3115 Returns: Node IP of the leader if one exists
3116 None if none exists
3117 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003118 """
Jon Hall94fd0472014-12-08 11:52:42 -08003119 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003120 cmdStr = "election-test-leader"
3121 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003122 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003123 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003124 # Leader
3125 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003126 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003127 nodeSearch = re.search( leaderPattern, response )
3128 if nodeSearch:
3129 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003130 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003131 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003132 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003133 # no leader
3134 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003135 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003136 nullSearch = re.search( nullPattern, response )
3137 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003138 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003139 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003140 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003141 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003142 main.log.error( "Error in electionTestLeader on " + self.name +
3143 ": " + "unexpected response" )
3144 main.log.error( repr( response ) )
3145 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003146 except AssertionError:
3147 main.log.exception( "" )
3148 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003149 except TypeError:
3150 main.log.exception( self.name + ": Object not as expected" )
3151 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003152 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003153 main.log.error( self.name + ": EOF exception found" )
3154 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003155 main.cleanup()
3156 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003157 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003158 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003159 main.cleanup()
3160 main.exit()
3161
kelvin-onlabd3b64892015-01-20 13:26:24 -08003162 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003163 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003164 CLI command to run for leadership of the Election test application.
3165 NOTE: Requires installation of the onos-app-election feature
3166 Returns: Main.TRUE on success
3167 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003168 """
Jon Hall94fd0472014-12-08 11:52:42 -08003169 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003170 cmdStr = "election-test-run"
3171 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003172 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003173 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003174 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003175 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003176 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003177 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003178 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003179 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003180 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003181 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003182 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003183 main.log.error( "Error in electionTestRun on " + self.name +
3184 ": " + "unexpected response" )
3185 main.log.error( repr( response ) )
3186 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003187 except AssertionError:
3188 main.log.exception( "" )
3189 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003190 except TypeError:
3191 main.log.exception( self.name + ": Object not as expected" )
3192 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003193 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003194 main.log.error( self.name + ": EOF exception found" )
3195 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003196 main.cleanup()
3197 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003198 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003199 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003200 main.cleanup()
3201 main.exit()
3202
kelvin-onlabd3b64892015-01-20 13:26:24 -08003203 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003204 """
Jon Hall94fd0472014-12-08 11:52:42 -08003205 * CLI command to withdraw the local node from leadership election for
3206 * the Election test application.
3207 #NOTE: Requires installation of the onos-app-election feature
3208 Returns: Main.TRUE on success
3209 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003210 """
Jon Hall94fd0472014-12-08 11:52:42 -08003211 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003212 cmdStr = "election-test-withdraw"
3213 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003214 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003215 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003216 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003217 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003218 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003219 if re.search( successPattern, response ):
3220 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003221 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003222 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003223 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003224 main.log.error( "Error in electionTestWithdraw on " +
3225 self.name + ": " + "unexpected response" )
3226 main.log.error( repr( response ) )
3227 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003228 except AssertionError:
3229 main.log.exception( "" )
3230 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003231 except TypeError:
3232 main.log.exception( self.name + ": Object not as expected" )
3233 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003234 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003235 main.log.error( self.name + ": EOF exception found" )
3236 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003237 main.cleanup()
3238 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003239 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003240 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003241 main.cleanup()
3242 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003243
kelvin8ec71442015-01-15 16:57:00 -08003244 def getDevicePortsEnabledCount( self, dpid ):
3245 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003246 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003247 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003248 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003249 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003250 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3251 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003252 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003253 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003254 if re.search( "No such device", output ):
3255 main.log.error( "Error in getting ports" )
3256 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003257 return output
Jon Hallc6793552016-01-19 14:18:37 -08003258 except AssertionError:
3259 main.log.exception( "" )
3260 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003261 except TypeError:
3262 main.log.exception( self.name + ": Object not as expected" )
3263 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003264 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003265 main.log.error( self.name + ": EOF exception found" )
3266 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003267 main.cleanup()
3268 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003269 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003270 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003271 main.cleanup()
3272 main.exit()
3273
kelvin8ec71442015-01-15 16:57:00 -08003274 def getDeviceLinksActiveCount( self, dpid ):
3275 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003276 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003277 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003278 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003279 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003280 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3281 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003282 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003283 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003284 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003285 main.log.error( "Error in getting ports " )
3286 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003287 return output
Jon Hallc6793552016-01-19 14:18:37 -08003288 except AssertionError:
3289 main.log.exception( "" )
3290 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003291 except TypeError:
3292 main.log.exception( self.name + ": Object not as expected" )
3293 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003294 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003295 main.log.error( self.name + ": EOF exception found" )
3296 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003297 main.cleanup()
3298 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003299 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003300 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003301 main.cleanup()
3302 main.exit()
3303
kelvin8ec71442015-01-15 16:57:00 -08003304 def getAllIntentIds( self ):
3305 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003306 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003307 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003308 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003309 cmdStr = "onos:intents | grep id="
3310 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003311 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003312 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003313 if re.search( "Error", output ):
3314 main.log.error( "Error in getting ports" )
3315 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003316 return output
Jon Hallc6793552016-01-19 14:18:37 -08003317 except AssertionError:
3318 main.log.exception( "" )
3319 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003320 except TypeError:
3321 main.log.exception( self.name + ": Object not as expected" )
3322 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003323 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003324 main.log.error( self.name + ": EOF exception found" )
3325 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003326 main.cleanup()
3327 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003328 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003329 main.log.exception( self.name + ": Uncaught exception!" )
3330 main.cleanup()
3331 main.exit()
3332
Jon Hall73509952015-02-24 16:42:56 -08003333 def intentSummary( self ):
3334 """
Jon Hallefbd9792015-03-05 16:11:36 -08003335 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003336 """
3337 try:
3338 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003339 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003340 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003341 states.append( intent.get( 'state', None ) )
3342 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003343 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003344 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003345 except ( TypeError, ValueError ):
3346 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003347 return None
3348 except pexpect.EOF:
3349 main.log.error( self.name + ": EOF exception found" )
3350 main.log.error( self.name + ": " + self.handle.before )
3351 main.cleanup()
3352 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003353 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003354 main.log.exception( self.name + ": Uncaught exception!" )
3355 main.cleanup()
3356 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003357
Jon Hall61282e32015-03-19 11:34:11 -07003358 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003359 """
3360 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003361 Optional argument:
3362 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003363 """
Jon Hall63604932015-02-26 17:09:50 -08003364 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003365 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003366 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003367 cmdStr += " -j"
3368 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003369 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003370 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003371 return output
Jon Hallc6793552016-01-19 14:18:37 -08003372 except AssertionError:
3373 main.log.exception( "" )
3374 return None
Jon Hall63604932015-02-26 17:09:50 -08003375 except TypeError:
3376 main.log.exception( self.name + ": Object not as expected" )
3377 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003378 except pexpect.EOF:
3379 main.log.error( self.name + ": EOF exception found" )
3380 main.log.error( self.name + ": " + self.handle.before )
3381 main.cleanup()
3382 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003383 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003384 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003385 main.cleanup()
3386 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003387
acsmarsa4a4d1e2015-07-10 16:01:24 -07003388 def leaderCandidates( self, jsonFormat=True ):
3389 """
3390 Returns the output of the leaders -c command.
3391 Optional argument:
3392 * jsonFormat - boolean indicating if you want output in json
3393 """
3394 try:
3395 cmdStr = "onos:leaders -c"
3396 if jsonFormat:
3397 cmdStr += " -j"
3398 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003399 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003400 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003401 return output
Jon Hallc6793552016-01-19 14:18:37 -08003402 except AssertionError:
3403 main.log.exception( "" )
3404 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003405 except TypeError:
3406 main.log.exception( self.name + ": Object not as expected" )
3407 return None
3408 except pexpect.EOF:
3409 main.log.error( self.name + ": EOF exception found" )
3410 main.log.error( self.name + ": " + self.handle.before )
3411 main.cleanup()
3412 main.exit()
3413 except Exception:
3414 main.log.exception( self.name + ": Uncaught exception!" )
3415 main.cleanup()
3416 main.exit()
3417
Jon Hallc6793552016-01-19 14:18:37 -08003418 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003419 """
3420 Returns a list in format [leader,candidate1,candidate2,...] for a given
3421 topic parameter and an empty list if the topic doesn't exist
3422 If no leader is elected leader in the returned list will be "none"
3423 Returns None if there is a type error processing the json object
3424 """
3425 try:
Jon Hall6e709752016-02-01 13:38:46 -08003426 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003427 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003428 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003429 assert "Command not found:" not in rawOutput, rawOutput
3430 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003431 results = []
3432 for dict in output:
3433 if dict["topic"] == topic:
3434 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003435 candidates = re.split( ", ", dict["candidates"][1:-1] )
3436 results.append( leader )
3437 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003438 return results
Jon Hallc6793552016-01-19 14:18:37 -08003439 except AssertionError:
3440 main.log.exception( "" )
3441 return None
3442 except ( TypeError, ValueError ):
3443 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003444 return None
3445 except pexpect.EOF:
3446 main.log.error( self.name + ": EOF exception found" )
3447 main.log.error( self.name + ": " + self.handle.before )
3448 main.cleanup()
3449 main.exit()
3450 except Exception:
3451 main.log.exception( self.name + ": Uncaught exception!" )
3452 main.cleanup()
3453 main.exit()
3454
Jon Hall61282e32015-03-19 11:34:11 -07003455 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003456 """
3457 Returns the output of the intent Pending map.
3458 """
Jon Hall63604932015-02-26 17:09:50 -08003459 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003460 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003461 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003462 cmdStr += " -j"
3463 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003464 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003465 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003466 return output
Jon Hallc6793552016-01-19 14:18:37 -08003467 except AssertionError:
3468 main.log.exception( "" )
3469 return None
Jon Hall63604932015-02-26 17:09:50 -08003470 except TypeError:
3471 main.log.exception( self.name + ": Object not as expected" )
3472 return None
3473 except pexpect.EOF:
3474 main.log.error( self.name + ": EOF exception found" )
3475 main.log.error( self.name + ": " + self.handle.before )
3476 main.cleanup()
3477 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003478 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003479 main.log.exception( self.name + ": Uncaught exception!" )
3480 main.cleanup()
3481 main.exit()
3482
Jon Hall2c8959e2016-12-16 12:17:34 -08003483 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003484 """
3485 Returns the output of the raft partitions command for ONOS.
3486 """
Jon Hall61282e32015-03-19 11:34:11 -07003487 # Sample JSON
3488 # {
3489 # "leader": "tcp://10.128.30.11:7238",
3490 # "members": [
3491 # "tcp://10.128.30.11:7238",
3492 # "tcp://10.128.30.17:7238",
3493 # "tcp://10.128.30.13:7238",
3494 # ],
3495 # "name": "p1",
3496 # "term": 3
3497 # },
Jon Hall63604932015-02-26 17:09:50 -08003498 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003499 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003500 if candidates:
3501 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003502 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003503 cmdStr += " -j"
3504 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003505 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003506 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003507 return output
Jon Hallc6793552016-01-19 14:18:37 -08003508 except AssertionError:
3509 main.log.exception( "" )
3510 return None
Jon Hall63604932015-02-26 17:09:50 -08003511 except TypeError:
3512 main.log.exception( self.name + ": Object not as expected" )
3513 return None
3514 except pexpect.EOF:
3515 main.log.error( self.name + ": EOF exception found" )
3516 main.log.error( self.name + ": " + self.handle.before )
3517 main.cleanup()
3518 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003519 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003520 main.log.exception( self.name + ": Uncaught exception!" )
3521 main.cleanup()
3522 main.exit()
3523
Jon Halle9f909e2016-09-23 10:43:12 -07003524 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003525 """
3526 Returns the output of the apps command for ONOS. This command lists
3527 information about installed ONOS applications
3528 """
3529 # Sample JSON object
3530 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3531 # "description":"ONOS OpenFlow protocol southbound providers",
3532 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3533 # "features":"[onos-openflow]","state":"ACTIVE"}]
3534 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003535 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003536 if summary:
3537 cmdStr += " -s"
3538 if active:
3539 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003540 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003541 cmdStr += " -j"
3542 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003543 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003544 assert "Command not found:" not in output, output
3545 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003546 return output
Jon Hallbe379602015-03-24 13:39:32 -07003547 # FIXME: look at specific exceptions/Errors
3548 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003549 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003550 return None
3551 except TypeError:
3552 main.log.exception( self.name + ": Object not as expected" )
3553 return None
3554 except pexpect.EOF:
3555 main.log.error( self.name + ": EOF exception found" )
3556 main.log.error( self.name + ": " + self.handle.before )
3557 main.cleanup()
3558 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003559 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003560 main.log.exception( self.name + ": Uncaught exception!" )
3561 main.cleanup()
3562 main.exit()
3563
Jon Hall146f1522015-03-24 15:33:24 -07003564 def appStatus( self, appName ):
3565 """
3566 Uses the onos:apps cli command to return the status of an application.
3567 Returns:
3568 "ACTIVE" - If app is installed and activated
3569 "INSTALLED" - If app is installed and deactivated
3570 "UNINSTALLED" - If app is not installed
3571 None - on error
3572 """
Jon Hall146f1522015-03-24 15:33:24 -07003573 try:
3574 if not isinstance( appName, types.StringType ):
3575 main.log.error( self.name + ".appStatus(): appName must be" +
3576 " a string" )
3577 return None
3578 output = self.apps( jsonFormat=True )
3579 appsJson = json.loads( output )
3580 state = None
3581 for app in appsJson:
3582 if appName == app.get('name'):
3583 state = app.get('state')
3584 break
3585 if state == "ACTIVE" or state == "INSTALLED":
3586 return state
3587 elif state is None:
3588 return "UNINSTALLED"
3589 elif state:
3590 main.log.error( "Unexpected state from 'onos:apps': " +
3591 str( state ) )
3592 return state
Jon Hallc6793552016-01-19 14:18:37 -08003593 except ( TypeError, ValueError ):
3594 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003595 return None
3596 except pexpect.EOF:
3597 main.log.error( self.name + ": EOF exception found" )
3598 main.log.error( self.name + ": " + self.handle.before )
3599 main.cleanup()
3600 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003601 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003602 main.log.exception( self.name + ": Uncaught exception!" )
3603 main.cleanup()
3604 main.exit()
3605
Jon Hallbe379602015-03-24 13:39:32 -07003606 def app( self, appName, option ):
3607 """
3608 Interacts with the app command for ONOS. This command manages
3609 application inventory.
3610 """
Jon Hallbe379602015-03-24 13:39:32 -07003611 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003612 # Validate argument types
3613 valid = True
3614 if not isinstance( appName, types.StringType ):
3615 main.log.error( self.name + ".app(): appName must be a " +
3616 "string" )
3617 valid = False
3618 if not isinstance( option, types.StringType ):
3619 main.log.error( self.name + ".app(): option must be a string" )
3620 valid = False
3621 if not valid:
3622 return main.FALSE
3623 # Validate Option
3624 option = option.lower()
3625 # NOTE: Install may become a valid option
3626 if option == "activate":
3627 pass
3628 elif option == "deactivate":
3629 pass
3630 elif option == "uninstall":
3631 pass
3632 else:
3633 # Invalid option
3634 main.log.error( "The ONOS app command argument only takes " +
3635 "the values: (activate|deactivate|uninstall)" +
3636 "; was given '" + option + "'")
3637 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003638 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003639 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003640 assert output is not None, "Error in sendline"
3641 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003642 if "Error executing command" in output:
3643 main.log.error( "Error in processing onos:app command: " +
3644 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003645 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003646 elif "No such application" in output:
3647 main.log.error( "The application '" + appName +
3648 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003649 return main.FALSE
3650 elif "Command not found:" in output:
3651 main.log.error( "Error in processing onos:app command: " +
3652 str( output ) )
3653 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003654 elif "Unsupported command:" in output:
3655 main.log.error( "Incorrect command given to 'app': " +
3656 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003657 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003658 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003659 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003660 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003661 except AssertionError:
3662 main.log.exception( self.name + ": AssertionError exception found" )
3663 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003664 except TypeError:
3665 main.log.exception( self.name + ": Object not as expected" )
3666 return main.ERROR
3667 except pexpect.EOF:
3668 main.log.error( self.name + ": EOF exception found" )
3669 main.log.error( self.name + ": " + self.handle.before )
3670 main.cleanup()
3671 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003672 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003673 main.log.exception( self.name + ": Uncaught exception!" )
3674 main.cleanup()
3675 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003676
Jon Hallbd16b922015-03-26 17:53:15 -07003677 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003678 """
3679 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003680 appName is the hierarchical app name, not the feature name
3681 If check is True, method will check the status of the app after the
3682 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003683 Returns main.TRUE if the command was successfully sent
3684 main.FALSE if the cli responded with an error or given
3685 incorrect input
3686 """
3687 try:
3688 if not isinstance( appName, types.StringType ):
3689 main.log.error( self.name + ".activateApp(): appName must be" +
3690 " a string" )
3691 return main.FALSE
3692 status = self.appStatus( appName )
3693 if status == "INSTALLED":
3694 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003695 if check and response == main.TRUE:
3696 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003697 status = self.appStatus( appName )
3698 if status == "ACTIVE":
3699 return main.TRUE
3700 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003701 main.log.debug( "The state of application " +
3702 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003703 time.sleep( 1 )
3704 return main.FALSE
3705 else: # not 'check' or command didn't succeed
3706 return response
Jon Hall146f1522015-03-24 15:33:24 -07003707 elif status == "ACTIVE":
3708 return main.TRUE
3709 elif status == "UNINSTALLED":
3710 main.log.error( self.name + ": Tried to activate the " +
3711 "application '" + appName + "' which is not " +
3712 "installed." )
3713 else:
3714 main.log.error( "Unexpected return value from appStatus: " +
3715 str( status ) )
3716 return main.ERROR
3717 except TypeError:
3718 main.log.exception( self.name + ": Object not as expected" )
3719 return main.ERROR
3720 except pexpect.EOF:
3721 main.log.error( self.name + ": EOF exception found" )
3722 main.log.error( self.name + ": " + self.handle.before )
3723 main.cleanup()
3724 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003725 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003726 main.log.exception( self.name + ": Uncaught exception!" )
3727 main.cleanup()
3728 main.exit()
3729
Jon Hallbd16b922015-03-26 17:53:15 -07003730 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003731 """
3732 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003733 appName is the hierarchical app name, not the feature name
3734 If check is True, method will check the status of the app after the
3735 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003736 Returns main.TRUE if the command was successfully sent
3737 main.FALSE if the cli responded with an error or given
3738 incorrect input
3739 """
3740 try:
3741 if not isinstance( appName, types.StringType ):
3742 main.log.error( self.name + ".deactivateApp(): appName must " +
3743 "be a string" )
3744 return main.FALSE
3745 status = self.appStatus( appName )
3746 if status == "INSTALLED":
3747 return main.TRUE
3748 elif status == "ACTIVE":
3749 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003750 if check and response == main.TRUE:
3751 for i in range(10): # try 10 times then give up
3752 status = self.appStatus( appName )
3753 if status == "INSTALLED":
3754 return main.TRUE
3755 else:
3756 time.sleep( 1 )
3757 return main.FALSE
3758 else: # not check or command didn't succeed
3759 return response
Jon Hall146f1522015-03-24 15:33:24 -07003760 elif status == "UNINSTALLED":
3761 main.log.warn( self.name + ": Tried to deactivate the " +
3762 "application '" + appName + "' which is not " +
3763 "installed." )
3764 return main.TRUE
3765 else:
3766 main.log.error( "Unexpected return value from appStatus: " +
3767 str( status ) )
3768 return main.ERROR
3769 except TypeError:
3770 main.log.exception( self.name + ": Object not as expected" )
3771 return main.ERROR
3772 except pexpect.EOF:
3773 main.log.error( self.name + ": EOF exception found" )
3774 main.log.error( self.name + ": " + self.handle.before )
3775 main.cleanup()
3776 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003777 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003778 main.log.exception( self.name + ": Uncaught exception!" )
3779 main.cleanup()
3780 main.exit()
3781
Jon Hallbd16b922015-03-26 17:53:15 -07003782 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003783 """
3784 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003785 appName is the hierarchical app name, not the feature name
3786 If check is True, method will check the status of the app after the
3787 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003788 Returns main.TRUE if the command was successfully sent
3789 main.FALSE if the cli responded with an error or given
3790 incorrect input
3791 """
3792 # TODO: check with Thomas about the state machine for apps
3793 try:
3794 if not isinstance( appName, types.StringType ):
3795 main.log.error( self.name + ".uninstallApp(): appName must " +
3796 "be a string" )
3797 return main.FALSE
3798 status = self.appStatus( appName )
3799 if status == "INSTALLED":
3800 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003801 if check and response == main.TRUE:
3802 for i in range(10): # try 10 times then give up
3803 status = self.appStatus( appName )
3804 if status == "UNINSTALLED":
3805 return main.TRUE
3806 else:
3807 time.sleep( 1 )
3808 return main.FALSE
3809 else: # not check or command didn't succeed
3810 return response
Jon Hall146f1522015-03-24 15:33:24 -07003811 elif status == "ACTIVE":
3812 main.log.warn( self.name + ": Tried to uninstall the " +
3813 "application '" + appName + "' which is " +
3814 "currently active." )
3815 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003816 if check and response == main.TRUE:
3817 for i in range(10): # try 10 times then give up
3818 status = self.appStatus( appName )
3819 if status == "UNINSTALLED":
3820 return main.TRUE
3821 else:
3822 time.sleep( 1 )
3823 return main.FALSE
3824 else: # not check or command didn't succeed
3825 return response
Jon Hall146f1522015-03-24 15:33:24 -07003826 elif status == "UNINSTALLED":
3827 return main.TRUE
3828 else:
3829 main.log.error( "Unexpected return value from appStatus: " +
3830 str( status ) )
3831 return main.ERROR
3832 except TypeError:
3833 main.log.exception( self.name + ": Object not as expected" )
3834 return main.ERROR
3835 except pexpect.EOF:
3836 main.log.error( self.name + ": EOF exception found" )
3837 main.log.error( self.name + ": " + self.handle.before )
3838 main.cleanup()
3839 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003840 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003841 main.log.exception( self.name + ": Uncaught exception!" )
3842 main.cleanup()
3843 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003844
3845 def appIDs( self, jsonFormat=True ):
3846 """
3847 Show the mappings between app id and app names given by the 'app-ids'
3848 cli command
3849 """
3850 try:
3851 cmdStr = "app-ids"
3852 if jsonFormat:
3853 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003854 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003855 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003856 assert "Command not found:" not in output, output
3857 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003858 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003859 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003860 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003861 return None
3862 except TypeError:
3863 main.log.exception( self.name + ": Object not as expected" )
3864 return None
3865 except pexpect.EOF:
3866 main.log.error( self.name + ": EOF exception found" )
3867 main.log.error( self.name + ": " + self.handle.before )
3868 main.cleanup()
3869 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003870 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003871 main.log.exception( self.name + ": Uncaught exception!" )
3872 main.cleanup()
3873 main.exit()
3874
3875 def appToIDCheck( self ):
3876 """
3877 This method will check that each application's ID listed in 'apps' is
3878 the same as the ID listed in 'app-ids'. The check will also check that
3879 there are no duplicate IDs issued. Note that an app ID should be
3880 a globaly unique numerical identifier for app/app-like features. Once
3881 an ID is registered, the ID is never freed up so that if an app is
3882 reinstalled it will have the same ID.
3883
3884 Returns: main.TRUE if the check passes and
3885 main.FALSE if the check fails or
3886 main.ERROR if there is some error in processing the test
3887 """
3888 try:
Jon Hall390696c2015-05-05 17:13:41 -07003889 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003890 rawJson = self.appIDs( jsonFormat=True )
3891 if rawJson:
3892 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003893 else:
Jon Hallc6793552016-01-19 14:18:37 -08003894 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003895 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003896 rawJson = self.apps( jsonFormat=True )
3897 if rawJson:
3898 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003899 else:
Jon Hallc6793552016-01-19 14:18:37 -08003900 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003901 bail = True
3902 if bail:
3903 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003904 result = main.TRUE
3905 for app in apps:
3906 appID = app.get( 'id' )
3907 if appID is None:
3908 main.log.error( "Error parsing app: " + str( app ) )
3909 result = main.FALSE
3910 appName = app.get( 'name' )
3911 if appName is None:
3912 main.log.error( "Error parsing app: " + str( app ) )
3913 result = main.FALSE
3914 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003915 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003916 # main.log.debug( "Comparing " + str( app ) + " to " +
3917 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003918 if not current: # if ids doesn't have this id
3919 result = main.FALSE
3920 main.log.error( "'app-ids' does not have the ID for " +
3921 str( appName ) + " that apps does." )
3922 elif len( current ) > 1:
3923 # there is more than one app with this ID
3924 result = main.FALSE
3925 # We will log this later in the method
3926 elif not current[0][ 'name' ] == appName:
3927 currentName = current[0][ 'name' ]
3928 result = main.FALSE
3929 main.log.error( "'app-ids' has " + str( currentName ) +
3930 " registered under id:" + str( appID ) +
3931 " but 'apps' has " + str( appName ) )
3932 else:
3933 pass # id and name match!
3934 # now make sure that app-ids has no duplicates
3935 idsList = []
3936 namesList = []
3937 for item in ids:
3938 idsList.append( item[ 'id' ] )
3939 namesList.append( item[ 'name' ] )
3940 if len( idsList ) != len( set( idsList ) ) or\
3941 len( namesList ) != len( set( namesList ) ):
3942 main.log.error( "'app-ids' has some duplicate entries: \n"
3943 + json.dumps( ids,
3944 sort_keys=True,
3945 indent=4,
3946 separators=( ',', ': ' ) ) )
3947 result = main.FALSE
3948 return result
Jon Hallc6793552016-01-19 14:18:37 -08003949 except ( TypeError, ValueError ):
3950 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003951 return main.ERROR
3952 except pexpect.EOF:
3953 main.log.error( self.name + ": EOF exception found" )
3954 main.log.error( self.name + ": " + self.handle.before )
3955 main.cleanup()
3956 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003957 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003958 main.log.exception( self.name + ": Uncaught exception!" )
3959 main.cleanup()
3960 main.exit()
3961
Jon Hallfb760a02015-04-13 15:35:03 -07003962 def getCfg( self, component=None, propName=None, short=False,
3963 jsonFormat=True ):
3964 """
3965 Get configuration settings from onos cli
3966 Optional arguments:
3967 component - Optionally only list configurations for a specific
3968 component. If None, all components with configurations
3969 are displayed. Case Sensitive string.
3970 propName - If component is specified, propName option will show
3971 only this specific configuration from that component.
3972 Case Sensitive string.
3973 jsonFormat - Returns output as json. Note that this will override
3974 the short option
3975 short - Short, less verbose, version of configurations.
3976 This is overridden by the json option
3977 returns:
3978 Output from cli as a string or None on error
3979 """
3980 try:
3981 baseStr = "cfg"
3982 cmdStr = " get"
3983 componentStr = ""
3984 if component:
3985 componentStr += " " + component
3986 if propName:
3987 componentStr += " " + propName
3988 if jsonFormat:
3989 baseStr += " -j"
3990 elif short:
3991 baseStr += " -s"
3992 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003993 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003994 assert "Command not found:" not in output, output
3995 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003996 return output
3997 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003998 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003999 return None
4000 except TypeError:
4001 main.log.exception( self.name + ": Object not as expected" )
4002 return None
4003 except pexpect.EOF:
4004 main.log.error( self.name + ": EOF exception found" )
4005 main.log.error( self.name + ": " + self.handle.before )
4006 main.cleanup()
4007 main.exit()
4008 except Exception:
4009 main.log.exception( self.name + ": Uncaught exception!" )
4010 main.cleanup()
4011 main.exit()
4012
4013 def setCfg( self, component, propName, value=None, check=True ):
4014 """
4015 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004016 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004017 component - The case sensitive name of the component whose
4018 property is to be set
4019 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004020 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004021 value - The value to set the property to. If None, will unset the
4022 property and revert it to it's default value(if applicable)
4023 check - Boolean, Check whether the option was successfully set this
4024 only applies when a value is given.
4025 returns:
4026 main.TRUE on success or main.FALSE on failure. If check is False,
4027 will return main.TRUE unless there is an error
4028 """
4029 try:
4030 baseStr = "cfg"
4031 cmdStr = " set " + str( component ) + " " + str( propName )
4032 if value is not None:
4033 cmdStr += " " + str( value )
4034 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004035 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004036 assert "Command not found:" not in output, output
4037 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004038 if value and check:
4039 results = self.getCfg( component=str( component ),
4040 propName=str( propName ),
4041 jsonFormat=True )
4042 # Check if current value is what we just set
4043 try:
4044 jsonOutput = json.loads( results )
4045 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004046 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004047 main.log.exception( "Error parsing cfg output" )
4048 main.log.error( "output:" + repr( results ) )
4049 return main.FALSE
4050 if current == str( value ):
4051 return main.TRUE
4052 return main.FALSE
4053 return main.TRUE
4054 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004055 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004056 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004057 except ( TypeError, ValueError ):
4058 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004059 return main.FALSE
4060 except pexpect.EOF:
4061 main.log.error( self.name + ": EOF exception found" )
4062 main.log.error( self.name + ": " + self.handle.before )
4063 main.cleanup()
4064 main.exit()
4065 except Exception:
4066 main.log.exception( self.name + ": Uncaught exception!" )
4067 main.cleanup()
4068 main.exit()
4069
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004070 def distPrimitivesSend( self, cmd ):
4071 """
4072 Function to handle sending cli commands for the distributed primitives test app
4073
4074 This command will catch some exceptions and retry the command on some
4075 specific store exceptions.
4076
4077 Required arguments:
4078 cmd - The command to send to the cli
4079 returns:
4080 string containing the cli output
4081 None on Error
4082 """
4083 try:
4084 output = self.sendline( cmd )
4085 try:
4086 assert output is not None, "Error in sendline"
4087 # TODO: Maybe make this less hardcoded
4088 # ConsistentMap Exceptions
4089 assert "org.onosproject.store.service" not in output
4090 # Node not leader
4091 assert "java.lang.IllegalStateException" not in output
4092 except AssertionError:
4093 main.log.error( "Error in processing '" + cmd + "' " +
4094 "command: " + str( output ) )
4095 retryTime = 30 # Conservative time, given by Madan
4096 main.log.info( "Waiting " + str( retryTime ) +
4097 "seconds before retrying." )
4098 time.sleep( retryTime ) # Due to change in mastership
4099 output = self.sendline( cmd )
4100 assert output is not None, "Error in sendline"
4101 assert "Command not found:" not in output, output
4102 assert "Error executing command" not in output, output
4103 main.log.info( self.name + ": " + output )
4104 return output
4105 except AssertionError:
4106 main.log.exception( "Error in processing '" + cmd + "' command." )
4107 return None
4108 except TypeError:
4109 main.log.exception( self.name + ": Object not as expected" )
4110 return None
4111 except pexpect.EOF:
4112 main.log.error( self.name + ": EOF exception found" )
4113 main.log.error( self.name + ": " + self.handle.before )
4114 main.cleanup()
4115 main.exit()
4116 except Exception:
4117 main.log.exception( self.name + ": Uncaught exception!" )
4118 main.cleanup()
4119 main.exit()
4120
Jon Hall390696c2015-05-05 17:13:41 -07004121 def setTestAdd( self, setName, values ):
4122 """
4123 CLI command to add elements to a distributed set.
4124 Arguments:
4125 setName - The name of the set to add to.
4126 values - The value(s) to add to the set, space seperated.
4127 Example usages:
4128 setTestAdd( "set1", "a b c" )
4129 setTestAdd( "set2", "1" )
4130 returns:
4131 main.TRUE on success OR
4132 main.FALSE if elements were already in the set OR
4133 main.ERROR on error
4134 """
4135 try:
4136 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004137 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004138 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4139 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jon Hall390696c2015-05-05 17:13:41 -07004140 if re.search( positiveMatch, output):
4141 return main.TRUE
4142 elif re.search( negativeMatch, output):
4143 return main.FALSE
4144 else:
4145 main.log.error( self.name + ": setTestAdd did not" +
4146 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004147 main.log.debug( self.name + " actual: " + repr( output ) )
4148 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004149 except TypeError:
4150 main.log.exception( self.name + ": Object not as expected" )
4151 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004152 except Exception:
4153 main.log.exception( self.name + ": Uncaught exception!" )
4154 main.cleanup()
4155 main.exit()
4156
4157 def setTestRemove( self, setName, values, clear=False, retain=False ):
4158 """
4159 CLI command to remove elements from a distributed set.
4160 Required arguments:
4161 setName - The name of the set to remove from.
4162 values - The value(s) to remove from the set, space seperated.
4163 Optional arguments:
4164 clear - Clear all elements from the set
4165 retain - Retain only the given values. (intersection of the
4166 original set and the given set)
4167 returns:
4168 main.TRUE on success OR
4169 main.FALSE if the set was not changed OR
4170 main.ERROR on error
4171 """
4172 try:
4173 cmdStr = "set-test-remove "
4174 if clear:
4175 cmdStr += "-c " + str( setName )
4176 elif retain:
4177 cmdStr += "-r " + str( setName ) + " " + str( values )
4178 else:
4179 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004180 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004181 if clear:
4182 pattern = "Set " + str( setName ) + " cleared"
4183 if re.search( pattern, output ):
4184 return main.TRUE
4185 elif retain:
4186 positivePattern = str( setName ) + " was pruned to contain " +\
4187 "only elements of set \[(.*)\]"
4188 negativePattern = str( setName ) + " was not changed by " +\
4189 "retaining only elements of the set " +\
4190 "\[(.*)\]"
4191 if re.search( positivePattern, output ):
4192 return main.TRUE
4193 elif re.search( negativePattern, output ):
4194 return main.FALSE
4195 else:
4196 positivePattern = "\[(.*)\] was removed from the set " +\
4197 str( setName )
4198 if ( len( values.split() ) == 1 ):
4199 negativePattern = "\[(.*)\] was not in set " +\
4200 str( setName )
4201 else:
4202 negativePattern = "No element of \[(.*)\] was in set " +\
4203 str( setName )
4204 if re.search( positivePattern, output ):
4205 return main.TRUE
4206 elif re.search( negativePattern, output ):
4207 return main.FALSE
4208 main.log.error( self.name + ": setTestRemove did not" +
4209 " match expected output" )
4210 main.log.debug( self.name + " expected: " + pattern )
4211 main.log.debug( self.name + " actual: " + repr( output ) )
4212 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004213 except TypeError:
4214 main.log.exception( self.name + ": Object not as expected" )
4215 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004216 except Exception:
4217 main.log.exception( self.name + ": Uncaught exception!" )
4218 main.cleanup()
4219 main.exit()
4220
4221 def setTestGet( self, setName, values="" ):
4222 """
4223 CLI command to get the elements in a distributed set.
4224 Required arguments:
4225 setName - The name of the set to remove from.
4226 Optional arguments:
4227 values - The value(s) to check if in the set, space seperated.
4228 returns:
4229 main.ERROR on error OR
4230 A list of elements in the set if no optional arguments are
4231 supplied OR
4232 A tuple containing the list then:
4233 main.FALSE if the given values are not in the set OR
4234 main.TRUE if the given values are in the set OR
4235 """
4236 try:
4237 values = str( values ).strip()
4238 setName = str( setName ).strip()
4239 length = len( values.split() )
4240 containsCheck = None
4241 # Patterns to match
4242 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004243 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004244 containsTrue = "Set " + setName + " contains the value " + values
4245 containsFalse = "Set " + setName + " did not contain the value " +\
4246 values
4247 containsAllTrue = "Set " + setName + " contains the the subset " +\
4248 setPattern
4249 containsAllFalse = "Set " + setName + " did not contain the the" +\
4250 " subset " + setPattern
4251
4252 cmdStr = "set-test-get "
4253 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004254 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004255 if length == 0:
4256 match = re.search( pattern, output )
4257 else: # if given values
4258 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004259 patternTrue = pattern + "\r\n" + containsTrue
4260 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004261 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004262 patternTrue = pattern + "\r\n" + containsAllTrue
4263 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004264 matchTrue = re.search( patternTrue, output )
4265 matchFalse = re.search( patternFalse, output )
4266 if matchTrue:
4267 containsCheck = main.TRUE
4268 match = matchTrue
4269 elif matchFalse:
4270 containsCheck = main.FALSE
4271 match = matchFalse
4272 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004273 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004274 "expected output" )
4275 main.log.debug( self.name + " expected: " + pattern )
4276 main.log.debug( self.name + " actual: " + repr( output ) )
4277 match = None
4278 if match:
4279 setMatch = match.group( 1 )
4280 if setMatch == '':
4281 setList = []
4282 else:
4283 setList = setMatch.split( ", " )
4284 if length > 0:
4285 return ( setList, containsCheck )
4286 else:
4287 return setList
4288 else: # no match
4289 main.log.error( self.name + ": setTestGet did not" +
4290 " match expected output" )
4291 main.log.debug( self.name + " expected: " + pattern )
4292 main.log.debug( self.name + " actual: " + repr( output ) )
4293 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004294 except TypeError:
4295 main.log.exception( self.name + ": Object not as expected" )
4296 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004297 except Exception:
4298 main.log.exception( self.name + ": Uncaught exception!" )
4299 main.cleanup()
4300 main.exit()
4301
4302 def setTestSize( self, setName ):
4303 """
4304 CLI command to get the elements in a distributed set.
4305 Required arguments:
4306 setName - The name of the set to remove from.
4307 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004308 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004309 None on error
4310 """
4311 try:
4312 # TODO: Should this check against the number of elements returned
4313 # and then return true/false based on that?
4314 setName = str( setName ).strip()
4315 # Patterns to match
4316 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004317 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004318 setPattern
4319 cmdStr = "set-test-get -s "
4320 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004321 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004322 match = re.search( pattern, output )
4323 if match:
4324 setSize = int( match.group( 1 ) )
4325 setMatch = match.group( 2 )
4326 if len( setMatch.split() ) == setSize:
4327 main.log.info( "The size returned by " + self.name +
4328 " matches the number of elements in " +
4329 "the returned set" )
4330 else:
4331 main.log.error( "The size returned by " + self.name +
4332 " does not match the number of " +
4333 "elements in the returned set." )
4334 return setSize
4335 else: # no match
4336 main.log.error( self.name + ": setTestGet did not" +
4337 " match expected output" )
4338 main.log.debug( self.name + " expected: " + pattern )
4339 main.log.debug( self.name + " actual: " + repr( output ) )
4340 return None
Jon Hall390696c2015-05-05 17:13:41 -07004341 except TypeError:
4342 main.log.exception( self.name + ": Object not as expected" )
4343 return None
Jon Hall390696c2015-05-05 17:13:41 -07004344 except Exception:
4345 main.log.exception( self.name + ": Uncaught exception!" )
4346 main.cleanup()
4347 main.exit()
4348
Jon Hall80daded2015-05-27 16:07:00 -07004349 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004350 """
4351 Command to list the various counters in the system.
4352 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004353 if jsonFormat, a string of the json object returned by the cli
4354 command
4355 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004356 None on error
4357 """
Jon Hall390696c2015-05-05 17:13:41 -07004358 try:
Jon Hall390696c2015-05-05 17:13:41 -07004359 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004360 if jsonFormat:
4361 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004362 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004363 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004364 assert "Command not found:" not in output, output
4365 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004366 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004367 return output
Jon Hall390696c2015-05-05 17:13:41 -07004368 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004369 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004370 return None
Jon Hall390696c2015-05-05 17:13:41 -07004371 except TypeError:
4372 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004373 return None
Jon Hall390696c2015-05-05 17:13:41 -07004374 except pexpect.EOF:
4375 main.log.error( self.name + ": EOF exception found" )
4376 main.log.error( self.name + ": " + self.handle.before )
4377 main.cleanup()
4378 main.exit()
4379 except Exception:
4380 main.log.exception( self.name + ": Uncaught exception!" )
4381 main.cleanup()
4382 main.exit()
4383
Jon Hall935db192016-04-19 00:22:04 -07004384 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004385 """
Jon Halle1a3b752015-07-22 13:02:46 -07004386 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004387 Required arguments:
4388 counter - The name of the counter to increment.
4389 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004390 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004391 returns:
4392 integer value of the counter or
4393 None on Error
4394 """
4395 try:
4396 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004397 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004398 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004399 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004400 if delta != 1:
4401 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004402 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004403 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004404 match = re.search( pattern, output )
4405 if match:
4406 return int( match.group( 1 ) )
4407 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004408 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004409 " match expected output." )
4410 main.log.debug( self.name + " expected: " + pattern )
4411 main.log.debug( self.name + " actual: " + repr( output ) )
4412 return None
Jon Hall390696c2015-05-05 17:13:41 -07004413 except TypeError:
4414 main.log.exception( self.name + ": Object not as expected" )
4415 return None
Jon Hall390696c2015-05-05 17:13:41 -07004416 except Exception:
4417 main.log.exception( self.name + ": Uncaught exception!" )
4418 main.cleanup()
4419 main.exit()
4420
Jon Hall935db192016-04-19 00:22:04 -07004421 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004422 """
4423 CLI command to get a distributed counter then add a delta to it.
4424 Required arguments:
4425 counter - The name of the counter to increment.
4426 Optional arguments:
4427 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004428 returns:
4429 integer value of the counter or
4430 None on Error
4431 """
4432 try:
4433 counter = str( counter )
4434 delta = int( delta )
4435 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004436 cmdStr += counter
4437 if delta != 1:
4438 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004439 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004440 pattern = counter + " was updated to (-?\d+)"
4441 match = re.search( pattern, output )
4442 if match:
4443 return int( match.group( 1 ) )
4444 else:
4445 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4446 " match expected output." )
4447 main.log.debug( self.name + " expected: " + pattern )
4448 main.log.debug( self.name + " actual: " + repr( output ) )
4449 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004450 except TypeError:
4451 main.log.exception( self.name + ": Object not as expected" )
4452 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004453 except Exception:
4454 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle1a3b752015-07-22 13:02:46 -07004455 main.cleanup()
4456 main.exit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004457
4458 def valueTestGet( self, valueName ):
4459 """
4460 CLI command to get the value of an atomic value.
4461 Required arguments:
4462 valueName - The name of the value to get.
4463 returns:
4464 string value of the value or
4465 None on Error
4466 """
4467 try:
4468 valueName = str( valueName )
4469 cmdStr = "value-test "
4470 operation = "get"
4471 cmdStr = "value-test {} {}".format( valueName,
4472 operation )
4473 output = self.distPrimitivesSend( cmdStr )
4474 pattern = "(\w+)"
4475 match = re.search( pattern, output )
4476 if match:
4477 return match.group( 1 )
4478 else:
4479 main.log.error( self.name + ": valueTestGet did not" +
4480 " match expected output." )
4481 main.log.debug( self.name + " expected: " + pattern )
4482 main.log.debug( self.name + " actual: " + repr( output ) )
4483 return None
4484 except TypeError:
4485 main.log.exception( self.name + ": Object not as expected" )
4486 return None
4487 except Exception:
4488 main.log.exception( self.name + ": Uncaught exception!" )
4489 main.cleanup()
4490 main.exit()
4491
4492 def valueTestSet( self, valueName, newValue ):
4493 """
4494 CLI command to set the value of an atomic value.
4495 Required arguments:
4496 valueName - The name of the value to set.
4497 newValue - The value to assign to the given value.
4498 returns:
4499 main.TRUE on success or
4500 main.ERROR on Error
4501 """
4502 try:
4503 valueName = str( valueName )
4504 newValue = str( newValue )
4505 operation = "set"
4506 cmdStr = "value-test {} {} {}".format( valueName,
4507 operation,
4508 newValue )
4509 output = self.distPrimitivesSend( cmdStr )
4510 if output is not None:
4511 return main.TRUE
4512 else:
4513 return main.ERROR
4514 except TypeError:
4515 main.log.exception( self.name + ": Object not as expected" )
4516 return main.ERROR
4517 except Exception:
4518 main.log.exception( self.name + ": Uncaught exception!" )
4519 main.cleanup()
4520 main.exit()
4521
4522 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4523 """
4524 CLI command to compareAndSet the value of an atomic value.
4525 Required arguments:
4526 valueName - The name of the value.
4527 oldValue - Compare the current value of the atomic value to this
4528 newValue - If the value equals oldValue, set the value to newValue
4529 returns:
4530 main.TRUE on success or
4531 main.FALSE on failure or
4532 main.ERROR on Error
4533 """
4534 try:
4535 valueName = str( valueName )
4536 oldValue = str( oldValue )
4537 newValue = str( newValue )
4538 operation = "compareAndSet"
4539 cmdStr = "value-test {} {} {} {}".format( valueName,
4540 operation,
4541 oldValue,
4542 newValue )
4543 output = self.distPrimitivesSend( cmdStr )
4544 pattern = "(\w+)"
4545 match = re.search( pattern, output )
4546 if match:
4547 result = match.group( 1 )
4548 if result == "true":
4549 return main.TRUE
4550 elif result == "false":
4551 return main.FALSE
4552 else:
4553 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4554 " match expected output." )
4555 main.log.debug( self.name + " expected: " + pattern )
4556 main.log.debug( self.name + " actual: " + repr( output ) )
4557 return main.ERROR
4558 except TypeError:
4559 main.log.exception( self.name + ": Object not as expected" )
4560 return main.ERROR
4561 except Exception:
4562 main.log.exception( self.name + ": Uncaught exception!" )
4563 main.cleanup()
4564 main.exit()
4565
4566 def valueTestGetAndSet( self, valueName, newValue ):
4567 """
4568 CLI command to getAndSet the value of an atomic value.
4569 Required arguments:
4570 valueName - The name of the value to get.
4571 newValue - The value to assign to the given value
4572 returns:
4573 string value of the value or
4574 None on Error
4575 """
4576 try:
4577 valueName = str( valueName )
4578 cmdStr = "value-test "
4579 operation = "getAndSet"
4580 cmdStr += valueName + " " + operation
4581 cmdStr = "value-test {} {} {}".format( valueName,
4582 operation,
4583 newValue )
4584 output = self.distPrimitivesSend( cmdStr )
4585 pattern = "(\w+)"
4586 match = re.search( pattern, output )
4587 if match:
4588 return match.group( 1 )
4589 else:
4590 main.log.error( self.name + ": valueTestGetAndSet did not" +
4591 " match expected output." )
4592 main.log.debug( self.name + " expected: " + pattern )
4593 main.log.debug( self.name + " actual: " + repr( output ) )
4594 return None
4595 except TypeError:
4596 main.log.exception( self.name + ": Object not as expected" )
4597 return None
4598 except Exception:
4599 main.log.exception( self.name + ": Uncaught exception!" )
4600 main.cleanup()
4601 main.exit()
4602
4603 def valueTestDestroy( self, valueName ):
4604 """
4605 CLI command to destroy an atomic value.
4606 Required arguments:
4607 valueName - The name of the value to destroy.
4608 returns:
4609 main.TRUE on success or
4610 main.ERROR on Error
4611 """
4612 try:
4613 valueName = str( valueName )
4614 cmdStr = "value-test "
4615 operation = "destroy"
4616 cmdStr += valueName + " " + operation
4617 output = self.distPrimitivesSend( cmdStr )
4618 if output is not None:
4619 return main.TRUE
4620 else:
4621 return main.ERROR
4622 except TypeError:
4623 main.log.exception( self.name + ": Object not as expected" )
4624 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004625 except Exception:
4626 main.log.exception( self.name + ": Uncaught exception!" )
4627 main.cleanup()
4628 main.exit()
4629
YPZhangfebf7302016-05-24 16:45:56 -07004630 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004631 """
4632 Description: Execute summary command in onos
4633 Returns: json object ( summary -j ), returns main.FALSE if there is
4634 no output
4635
4636 """
4637 try:
4638 cmdStr = "summary"
4639 if jsonFormat:
4640 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004641 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004642 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004643 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004644 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004645 if not handle:
4646 main.log.error( self.name + ": There is no output in " +
4647 "summary command" )
4648 return main.FALSE
4649 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004650 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004651 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004652 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004653 except TypeError:
4654 main.log.exception( self.name + ": Object not as expected" )
4655 return None
4656 except pexpect.EOF:
4657 main.log.error( self.name + ": EOF exception found" )
4658 main.log.error( self.name + ": " + self.handle.before )
4659 main.cleanup()
4660 main.exit()
4661 except Exception:
4662 main.log.exception( self.name + ": Uncaught exception!" )
4663 main.cleanup()
4664 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004665
Jon Hall935db192016-04-19 00:22:04 -07004666 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004667 """
4668 CLI command to get the value of a key in a consistent map using
4669 transactions. This a test function and can only get keys from the
4670 test map hard coded into the cli command
4671 Required arguments:
4672 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004673 returns:
4674 The string value of the key or
4675 None on Error
4676 """
4677 try:
4678 keyName = str( keyName )
4679 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004680 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004681 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004682 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4683 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004684 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004685 return None
4686 else:
4687 match = re.search( pattern, output )
4688 if match:
4689 return match.groupdict()[ 'value' ]
4690 else:
4691 main.log.error( self.name + ": transactionlMapGet did not" +
4692 " match expected output." )
4693 main.log.debug( self.name + " expected: " + pattern )
4694 main.log.debug( self.name + " actual: " + repr( output ) )
4695 return None
4696 except TypeError:
4697 main.log.exception( self.name + ": Object not as expected" )
4698 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004699 except Exception:
4700 main.log.exception( self.name + ": Uncaught exception!" )
4701 main.cleanup()
4702 main.exit()
4703
Jon Hall935db192016-04-19 00:22:04 -07004704 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004705 """
4706 CLI command to put a value into 'numKeys' number of keys in a
4707 consistent map using transactions. This a test function and can only
4708 put into keys named 'Key#' of the test map hard coded into the cli command
4709 Required arguments:
4710 numKeys - Number of keys to add the value to
4711 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004712 returns:
4713 A dictionary whose keys are the name of the keys put into the map
4714 and the values of the keys are dictionaries whose key-values are
4715 'value': value put into map and optionaly
4716 'oldValue': Previous value in the key or
4717 None on Error
4718
4719 Example output
4720 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4721 'Key2': {'value': 'Testing'} }
4722 """
4723 try:
4724 numKeys = str( numKeys )
4725 value = str( value )
4726 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004727 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004728 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004729 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4730 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4731 results = {}
4732 for line in output.splitlines():
4733 new = re.search( newPattern, line )
4734 updated = re.search( updatedPattern, line )
4735 if new:
4736 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4737 elif updated:
4738 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004739 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004740 else:
4741 main.log.error( self.name + ": transactionlMapGet did not" +
4742 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004743 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4744 newPattern,
4745 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004746 main.log.debug( self.name + " actual: " + repr( output ) )
4747 return results
4748 except TypeError:
4749 main.log.exception( self.name + ": Object not as expected" )
4750 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004751 except Exception:
4752 main.log.exception( self.name + ": Uncaught exception!" )
4753 main.cleanup()
4754 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004755
acsmarsdaea66c2015-09-03 11:44:06 -07004756 def maps( self, jsonFormat=True ):
4757 """
4758 Description: Returns result of onos:maps
4759 Optional:
4760 * jsonFormat: enable json formatting of output
4761 """
4762 try:
4763 cmdStr = "maps"
4764 if jsonFormat:
4765 cmdStr += " -j"
4766 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004767 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004768 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004769 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004770 except AssertionError:
4771 main.log.exception( "" )
4772 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004773 except TypeError:
4774 main.log.exception( self.name + ": Object not as expected" )
4775 return None
4776 except pexpect.EOF:
4777 main.log.error( self.name + ": EOF exception found" )
4778 main.log.error( self.name + ": " + self.handle.before )
4779 main.cleanup()
4780 main.exit()
4781 except Exception:
4782 main.log.exception( self.name + ": Uncaught exception!" )
4783 main.cleanup()
4784 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004785
4786 def getSwController( self, uri, jsonFormat=True ):
4787 """
4788 Descrition: Gets the controller information from the device
4789 """
4790 try:
4791 cmd = "device-controllers "
4792 if jsonFormat:
4793 cmd += "-j "
4794 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004795 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004796 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004797 return response
Jon Hallc6793552016-01-19 14:18:37 -08004798 except AssertionError:
4799 main.log.exception( "" )
4800 return None
GlennRC050596c2015-11-18 17:06:41 -08004801 except TypeError:
4802 main.log.exception( self.name + ": Object not as expected" )
4803 return None
4804 except pexpect.EOF:
4805 main.log.error( self.name + ": EOF exception found" )
4806 main.log.error( self.name + ": " + self.handle.before )
4807 main.cleanup()
4808 main.exit()
4809 except Exception:
4810 main.log.exception( self.name + ": Uncaught exception!" )
4811 main.cleanup()
4812 main.exit()
4813
4814 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4815 """
4816 Descrition: sets the controller(s) for the specified device
4817
4818 Parameters:
4819 Required: uri - String: The uri of the device(switch).
4820 ip - String or List: The ip address of the controller.
4821 This parameter can be formed in a couple of different ways.
4822 VALID:
4823 10.0.0.1 - just the ip address
4824 tcp:10.0.0.1 - the protocol and the ip address
4825 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4826 so that you can add controllers with different
4827 protocols and ports
4828 INVALID:
4829 10.0.0.1:6653 - this is not supported by ONOS
4830
4831 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4832 port - The port number.
4833 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4834
4835 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4836 """
4837 try:
4838 cmd = "device-setcontrollers"
4839
4840 if jsonFormat:
4841 cmd += " -j"
4842 cmd += " " + uri
4843 if isinstance( ip, str ):
4844 ip = [ip]
4845 for item in ip:
4846 if ":" in item:
4847 sitem = item.split( ":" )
4848 if len(sitem) == 3:
4849 cmd += " " + item
4850 elif "." in sitem[1]:
4851 cmd += " {}:{}".format(item, port)
4852 else:
4853 main.log.error( "Malformed entry: " + item )
4854 raise TypeError
4855 else:
4856 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004857 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004858 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004859 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004860 if "Error" in response:
4861 main.log.error( response )
4862 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004863 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004864 except AssertionError:
4865 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004866 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004867 except TypeError:
4868 main.log.exception( self.name + ": Object not as expected" )
4869 return main.FALSE
4870 except pexpect.EOF:
4871 main.log.error( self.name + ": EOF exception found" )
4872 main.log.error( self.name + ": " + self.handle.before )
4873 main.cleanup()
4874 main.exit()
4875 except Exception:
4876 main.log.exception( self.name + ": Uncaught exception!" )
4877 main.cleanup()
4878 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004879
4880 def removeDevice( self, device ):
4881 '''
4882 Description:
4883 Remove a device from ONOS by passing the uri of the device(s).
4884 Parameters:
4885 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4886 Returns:
4887 Returns main.FALSE if an exception is thrown or an error is present
4888 in the response. Otherwise, returns main.TRUE.
4889 NOTE:
4890 If a host cannot be removed, then this function will return main.FALSE
4891 '''
4892 try:
4893 if type( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004894 deviceStr = device
4895 device = []
4896 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004897
4898 for d in device:
4899 time.sleep( 1 )
4900 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004901 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004902 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004903 if "Error" in response:
4904 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4905 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004906 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004907 except AssertionError:
4908 main.log.exception( "" )
4909 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004910 except TypeError:
4911 main.log.exception( self.name + ": Object not as expected" )
4912 return main.FALSE
4913 except pexpect.EOF:
4914 main.log.error( self.name + ": EOF exception found" )
4915 main.log.error( self.name + ": " + self.handle.before )
4916 main.cleanup()
4917 main.exit()
4918 except Exception:
4919 main.log.exception( self.name + ": Uncaught exception!" )
4920 main.cleanup()
4921 main.exit()
4922
4923 def removeHost( self, host ):
4924 '''
4925 Description:
4926 Remove a host from ONOS by passing the id of the host(s)
4927 Parameters:
4928 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4929 Returns:
4930 Returns main.FALSE if an exception is thrown or an error is present
4931 in the response. Otherwise, returns main.TRUE.
4932 NOTE:
4933 If a host cannot be removed, then this function will return main.FALSE
4934 '''
4935 try:
4936 if type( host ) is str:
4937 host = list( host )
4938
4939 for h in host:
4940 time.sleep( 1 )
4941 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004942 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004943 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004944 if "Error" in response:
4945 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4946 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004947 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004948 except AssertionError:
4949 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004950 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004951 except TypeError:
4952 main.log.exception( self.name + ": Object not as expected" )
4953 return main.FALSE
4954 except pexpect.EOF:
4955 main.log.error( self.name + ": EOF exception found" )
4956 main.log.error( self.name + ": " + self.handle.before )
4957 main.cleanup()
4958 main.exit()
4959 except Exception:
4960 main.log.exception( self.name + ": Uncaught exception!" )
4961 main.cleanup()
4962 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004963
YPZhangfebf7302016-05-24 16:45:56 -07004964 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004965 '''
4966 Description:
4967 Bring link down or up in the null-provider.
4968 params:
4969 begin - (string) One end of a device or switch.
4970 end - (string) the other end of the device or switch
4971 returns:
4972 main.TRUE if no exceptions were thrown and no Errors are
4973 present in the resoponse. Otherwise, returns main.FALSE
4974 '''
4975 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004976 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004977 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004978 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004979 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004980 if "Error" in response or "Failure" in response:
4981 main.log.error( response )
4982 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004983 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004984 except AssertionError:
4985 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004986 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004987 except TypeError:
4988 main.log.exception( self.name + ": Object not as expected" )
4989 return main.FALSE
4990 except pexpect.EOF:
4991 main.log.error( self.name + ": EOF exception found" )
4992 main.log.error( self.name + ": " + self.handle.before )
4993 main.cleanup()
4994 main.exit()
4995 except Exception:
4996 main.log.exception( self.name + ": Uncaught exception!" )
4997 main.cleanup()
4998 main.exit()
4999
Jon Hall2c8959e2016-12-16 12:17:34 -08005000 def portstate( self, dpid, port, state ):
Flavio Castro82ee2f62016-06-07 15:04:12 -07005001 '''
5002 Description:
5003 Changes the state of port in an OF switch by means of the
5004 PORTSTATUS OF messages.
5005 params:
Jon Hall2c8959e2016-12-16 12:17:34 -08005006 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5007 port - (string) target port in the device. Ex: '2'
5008 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005009 returns:
5010 main.TRUE if no exceptions were thrown and no Errors are
5011 present in the resoponse. Otherwise, returns main.FALSE
5012 '''
5013 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005014 state = state.lower()
5015 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005016 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005017 response = self.sendline( cmd, showResponse=True )
5018 assert response is not None, "Error in sendline"
5019 assert "Command not found:" not in response, response
5020 if "Error" in response or "Failure" in response:
5021 main.log.error( response )
5022 return main.FALSE
5023 return main.TRUE
5024 except AssertionError:
5025 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005026 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005027 except TypeError:
5028 main.log.exception( self.name + ": Object not as expected" )
5029 return main.FALSE
5030 except pexpect.EOF:
5031 main.log.error( self.name + ": EOF exception found" )
5032 main.log.error( self.name + ": " + self.handle.before )
5033 main.cleanup()
5034 main.exit()
5035 except Exception:
5036 main.log.exception( self.name + ": Uncaught exception!" )
5037 main.cleanup()
5038 main.exit()
5039
5040 def logSet( self, level="INFO", app="org.onosproject" ):
5041 """
5042 Set the logging level to lvl for a specific app
5043 returns main.TRUE on success
5044 returns main.FALSE if Error occurred
5045 if noExit is True, TestON will not exit, but clean up
5046 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5047 Level defaults to INFO
5048 """
5049 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005050 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005051 self.handle.expect( "onos>" )
5052
5053 response = self.handle.before
5054 if re.search( "Error", response ):
5055 return main.FALSE
5056 return main.TRUE
5057 except pexpect.TIMEOUT:
5058 main.log.exception( self.name + ": TIMEOUT exception found" )
5059 main.cleanup()
5060 main.exit()
5061 except pexpect.EOF:
5062 main.log.error( self.name + ": EOF exception found" )
5063 main.log.error( self.name + ": " + self.handle.before )
5064 main.cleanup()
5065 main.exit()
5066 except Exception:
5067 main.log.exception( self.name + ": Uncaught exception!" )
5068 main.cleanup()
5069 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005070
5071 def getGraphDict( self, timeout=60, includeHost=False ):
5072 """
5073 Return a dictionary which describes the latest network topology data as a
5074 graph.
5075 An example of the dictionary:
5076 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5077 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5078 Each vertex should at least have an 'edges' attribute which describes the
5079 adjacency information. The value of 'edges' attribute is also represented by
5080 a dictionary, which maps each edge (identified by the neighbor vertex) to a
5081 list of attributes.
5082 An example of the edges dictionary:
5083 'edges': { vertex2: { 'port': ..., 'weight': ... },
5084 vertex3: { 'port': ..., 'weight': ... } }
5085 If includeHost == True, all hosts (and host-switch links) will be included
5086 in topology data.
5087 """
5088 graphDict = {}
5089 try:
5090 links = self.links()
5091 links = json.loads( links )
5092 devices = self.devices()
5093 devices = json.loads( devices )
5094 idToDevice = {}
5095 for device in devices:
5096 idToDevice[ device[ 'id' ] ] = device
5097 if includeHost:
5098 hosts = self.hosts()
5099 # FIXME: support 'includeHost' argument
5100 for link in links:
5101 nodeA = link[ 'src' ][ 'device' ]
5102 nodeB = link[ 'dst' ][ 'device' ]
5103 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005104 if nodeA not in graphDict.keys():
5105 graphDict[ nodeA ] = { 'edges': {},
5106 'dpid': idToDevice[ nodeA ][ 'id' ][3:],
5107 'type': idToDevice[ nodeA ][ 'type' ],
5108 'available': idToDevice[ nodeA ][ 'available' ],
5109 'role': idToDevice[ nodeA ][ 'role' ],
5110 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5111 'hw': idToDevice[ nodeA ][ 'hw' ],
5112 'sw': idToDevice[ nodeA ][ 'sw' ],
5113 'serial': idToDevice[ nodeA ][ 'serial' ],
5114 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
5115 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005116 else:
5117 # Assert nodeB is not connected to any current links of nodeA
5118 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005119 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5120 'type': link[ 'type' ],
5121 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005122 return graphDict
5123 except ( TypeError, ValueError ):
5124 main.log.exception( self.name + ": Object not as expected" )
5125 return None
5126 except KeyError:
5127 main.log.exception( self.name + ": KeyError exception found" )
5128 return None
5129 except AssertionError:
5130 main.log.exception( self.name + ": AssertionError exception found" )
5131 return None
5132 except pexpect.EOF:
5133 main.log.error( self.name + ": EOF exception found" )
5134 main.log.error( self.name + ": " + self.handle.before )
5135 return None
5136 except Exception:
5137 main.log.exception( self.name + ": Uncaught exception!" )
5138 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005139
5140 def getIntentPerfSummary( self ):
5141 '''
5142 Send command to check intent-perf summary
5143 Returns: dictionary for intent-perf summary
5144 if something wrong, function will return None
5145 '''
5146 cmd = "intent-perf -s"
5147 respDic = {}
5148 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005149 assert resp is not None, "Error in sendline"
5150 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005151 try:
5152 # Generate the dictionary to return
5153 for l in resp.split( "\n" ):
5154 # Delete any white space in line
5155 temp = re.sub( r'\s+', '', l )
5156 temp = temp.split( ":" )
5157 respDic[ temp[0] ] = temp[ 1 ]
5158
5159 except (TypeError, ValueError):
5160 main.log.exception( self.name + ": Object not as expected" )
5161 return None
5162 except KeyError:
5163 main.log.exception( self.name + ": KeyError exception found" )
5164 return None
5165 except AssertionError:
5166 main.log.exception( self.name + ": AssertionError exception found" )
5167 return None
5168 except pexpect.EOF:
5169 main.log.error( self.name + ": EOF exception found" )
5170 main.log.error( self.name + ": " + self.handle.before )
5171 return None
5172 except Exception:
5173 main.log.exception( self.name + ": Uncaught exception!" )
5174 return None
5175 return respDic
5176
Chiyu Chengec63bde2016-11-17 18:11:36 -08005177 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005178 """
5179 Searches the latest ONOS log file for the given search term and
5180 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005181
chengchiyu08303a02016-09-08 17:40:26 -07005182 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005183 searchTerm:
5184 The string to grep from the ONOS log.
5185 startLine:
5186 The term that decides which line is the start to search the searchTerm in
5187 the karaf log. For now, startTerm only works in 'first' mode.
5188 logNum:
5189 In some extreme cases, one karaf log is not big enough to contain all the
5190 information.Because of this, search mutiply logs is necessary to capture
5191 the right result. logNum is the number of karaf logs that we need to search
5192 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005193 mode:
5194 all: return all the strings that contain the search term
5195 last: return the last string that contains the search term
5196 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005197 num: return the number of times that the searchTerm appears in the log
5198 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005199 """
5200 try:
5201 assert type( searchTerm ) is str
Jon Halle0f0b342017-04-18 11:43:47 -07005202 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005203 logPath = '/opt/onos/log/karaf.log.'
5204 logPaths = '/opt/onos/log/karaf.log'
5205 for i in range( 1, logNum ):
5206 logPaths = logPath + str( i ) + " " + logPaths
5207 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005208 if startLine:
5209 # 100000000 is just a extreme large number to make sure this function can grep all the lines after startLine
5210 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005211 if mode == 'all':
5212 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005213 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005214 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005215 elif mode == 'first':
5216 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5217 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005218 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005219 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005220 return num
You Wang6d301d42017-04-21 10:49:33 -07005221 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005222 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
5223 return int(totalLines)
You Wang6d301d42017-04-21 10:49:33 -07005224 else:
5225 main.log.error( self.name + " unsupported mode" )
5226 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005227 before = self.sendline( cmd )
5228 before = before.splitlines()
5229 # make sure the returned list only contains the search term
5230 returnLines = [line for line in before if searchTerm in line]
5231 return returnLines
5232 except AssertionError:
5233 main.log.error( self.name + " searchTerm is not string type" )
5234 return None
5235 except pexpect.EOF:
5236 main.log.error( self.name + ": EOF exception found" )
5237 main.log.error( self.name + ": " + self.handle.before )
5238 main.cleanup()
5239 main.exit()
5240 except pexpect.TIMEOUT:
5241 main.log.error( self.name + ": TIMEOUT exception found" )
5242 main.log.error( self.name + ": " + self.handle.before )
5243 main.cleanup()
5244 main.exit()
5245 except Exception:
5246 main.log.exception( self.name + ": Uncaught exception!" )
5247 main.cleanup()
5248 main.exit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005249
5250 def vplsShow( self, jsonFormat=True ):
5251 """
5252 Description: Returns result of onos:vpls show, which should list the
5253 configured VPLS networks and the assigned interfaces.
5254 Optional:
5255 * jsonFormat: enable json formatting of output
5256 Returns:
5257 The output of the command or None on error.
5258 """
5259 try:
5260 cmdStr = "vpls show"
5261 if jsonFormat:
5262 raise NotImplementedError
5263 cmdStr += " -j"
5264 handle = self.sendline( cmdStr )
5265 assert handle is not None, "Error in sendline"
5266 assert "Command not found:" not in handle, handle
5267 return handle
5268 except AssertionError:
5269 main.log.exception( "" )
5270 return None
5271 except TypeError:
5272 main.log.exception( self.name + ": Object not as expected" )
5273 return None
5274 except pexpect.EOF:
5275 main.log.error( self.name + ": EOF exception found" )
5276 main.log.error( self.name + ": " + self.handle.before )
5277 main.cleanup()
5278 main.exit()
5279 except NotImplementedError:
5280 main.log.exception( self.name + ": Json output not supported")
5281 return None
5282 except Exception:
5283 main.log.exception( self.name + ": Uncaught exception!" )
5284 main.cleanup()
5285 main.exit()
5286
5287 def parseVplsShow( self ):
5288 """
5289 Parse the cli output of 'vpls show' into json output. This is required
5290 as there is currently no json output available.
5291 """
5292 try:
5293 output = []
5294 raw = self.vplsShow( jsonFormat=False )
5295 namePat = "VPLS name: (?P<name>\w+)"
5296 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5297 encapPat = "Encapsulation: (?P<encap>\w+)"
5298 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5299 mIter = re.finditer( pattern, raw )
5300 for match in mIter:
5301 item = {}
5302 item[ 'name' ] = match.group( 'name' )
5303 ifaces = match.group( 'interfaces' ).split( ', ')
5304 if ifaces == [ "" ]:
5305 ifaces = []
5306 item[ 'interfaces' ] = ifaces
5307 encap = match.group( 'encap' )
5308 if encap != 'NONE':
5309 item[ 'encapsulation' ] = encap.lower()
5310 output.append( item )
5311 return output
5312 except Exception:
5313 main.log.exception( self.name + ": Uncaught exception!" )
5314 main.cleanup()
5315 main.exit()
5316
5317 def vplsList( self, jsonFormat=True ):
5318 """
5319 Description: Returns result of onos:vpls list, which should list the
5320 configured VPLS networks.
5321 Optional:
5322 * jsonFormat: enable json formatting of output
5323 """
5324 try:
5325 cmdStr = "vpls list"
5326 if jsonFormat:
5327 raise NotImplementedError
5328 cmdStr += " -j"
5329 handle = self.sendline( cmdStr )
5330 assert handle is not None, "Error in sendline"
5331 assert "Command not found:" not in handle, handle
5332 return handle
5333 except AssertionError:
5334 main.log.exception( "" )
5335 return None
5336 except TypeError:
5337 main.log.exception( self.name + ": Object not as expected" )
5338 return None
5339 except pexpect.EOF:
5340 main.log.error( self.name + ": EOF exception found" )
5341 main.log.error( self.name + ": " + self.handle.before )
5342 main.cleanup()
5343 main.exit()
5344 except NotImplementedError:
5345 main.log.exception( self.name + ": Json output not supported")
5346 return None
5347 except Exception:
5348 main.log.exception( self.name + ": Uncaught exception!" )
5349 main.cleanup()
5350 main.exit()
5351
5352 def vplsCreate( self, network ):
5353 """
5354 CLI command to create a new VPLS network.
5355 Required arguments:
5356 network - String name of the network to create.
5357 returns:
5358 main.TRUE on success and main.FALSE on failure
5359 """
5360 try:
5361 network = str( network )
5362 cmdStr = "vpls create "
5363 cmdStr += network
5364 output = self.sendline( cmdStr )
5365 assert output is not None, "Error in sendline"
5366 assert "Command not found:" not in output, output
5367 assert "Error executing command" not in output, output
5368 assert "VPLS already exists:" not in output, output
5369 return main.TRUE
5370 except AssertionError:
5371 main.log.exception( "" )
5372 return main.FALSE
5373 except TypeError:
5374 main.log.exception( self.name + ": Object not as expected" )
5375 return main.FALSE
5376 except pexpect.EOF:
5377 main.log.error( self.name + ": EOF exception found" )
5378 main.log.error( self.name + ": " + self.handle.before )
5379 main.cleanup()
5380 main.exit()
5381 except Exception:
5382 main.log.exception( self.name + ": Uncaught exception!" )
5383 main.cleanup()
5384 main.exit()
5385
5386 def vplsDelete( self, network ):
5387 """
5388 CLI command to delete a VPLS network.
5389 Required arguments:
5390 network - Name of the network to delete.
5391 returns:
5392 main.TRUE on success and main.FALSE on failure
5393 """
5394 try:
5395 network = str( network )
5396 cmdStr = "vpls delete "
5397 cmdStr += network
5398 output = self.sendline( cmdStr )
5399 assert output is not None, "Error in sendline"
5400 assert "Command not found:" not in output, output
5401 assert "Error executing command" not in output, output
5402 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005403 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005404 return main.TRUE
5405 except AssertionError:
5406 main.log.exception( "" )
5407 return main.FALSE
5408 except TypeError:
5409 main.log.exception( self.name + ": Object not as expected" )
5410 return main.FALSE
5411 except pexpect.EOF:
5412 main.log.error( self.name + ": EOF exception found" )
5413 main.log.error( self.name + ": " + self.handle.before )
5414 main.cleanup()
5415 main.exit()
5416 except Exception:
5417 main.log.exception( self.name + ": Uncaught exception!" )
5418 main.cleanup()
5419 main.exit()
5420
5421 def vplsAddIface( self, network, iface ):
5422 """
5423 CLI command to add an interface to a VPLS network.
5424 Required arguments:
5425 network - Name of the network to add the interface to.
5426 iface - The ONOS name for an interface.
5427 returns:
5428 main.TRUE on success and main.FALSE on failure
5429 """
5430 try:
5431 network = str( network )
5432 iface = str( iface )
5433 cmdStr = "vpls add-if "
5434 cmdStr += network + " " + iface
5435 output = self.sendline( cmdStr )
5436 assert output is not None, "Error in sendline"
5437 assert "Command not found:" not in output, output
5438 assert "Error executing command" not in output, output
5439 assert "already associated to network" not in output, output
5440 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005441 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005442 return main.TRUE
5443 except AssertionError:
5444 main.log.exception( "" )
5445 return main.FALSE
5446 except TypeError:
5447 main.log.exception( self.name + ": Object not as expected" )
5448 return main.FALSE
5449 except pexpect.EOF:
5450 main.log.error( self.name + ": EOF exception found" )
5451 main.log.error( self.name + ": " + self.handle.before )
5452 main.cleanup()
5453 main.exit()
5454 except Exception:
5455 main.log.exception( self.name + ": Uncaught exception!" )
5456 main.cleanup()
5457 main.exit()
5458
5459 def vplsRemIface( self, network, iface ):
5460 """
5461 CLI command to remove an interface from a VPLS network.
5462 Required arguments:
5463 network - Name of the network to remove the interface from.
5464 iface - Name of the interface to remove.
5465 returns:
5466 main.TRUE on success and main.FALSE on failure
5467 """
5468 try:
5469 iface = str( iface )
5470 cmdStr = "vpls rem-if "
5471 cmdStr += network + " " + iface
5472 output = self.sendline( cmdStr )
5473 assert output is not None, "Error in sendline"
5474 assert "Command not found:" not in output, output
5475 assert "Error executing command" not in output, output
5476 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005477 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005478 return main.TRUE
5479 except AssertionError:
5480 main.log.exception( "" )
5481 return main.FALSE
5482 except TypeError:
5483 main.log.exception( self.name + ": Object not as expected" )
5484 return main.FALSE
5485 except pexpect.EOF:
5486 main.log.error( self.name + ": EOF exception found" )
5487 main.log.error( self.name + ": " + self.handle.before )
5488 main.cleanup()
5489 main.exit()
5490 except Exception:
5491 main.log.exception( self.name + ": Uncaught exception!" )
5492 main.cleanup()
5493 main.exit()
5494
5495 def vplsClean( self ):
5496 """
5497 Description: Clears the VPLS app configuration.
5498 Returns: main.TRUE on success and main.FALSE on failure
5499 """
5500 try:
5501 cmdStr = "vpls clean"
5502 handle = self.sendline( cmdStr )
5503 assert handle is not None, "Error in sendline"
5504 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005505 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005506 return handle
5507 except AssertionError:
5508 main.log.exception( "" )
5509 return main.FALSE
5510 except TypeError:
5511 main.log.exception( self.name + ": Object not as expected" )
5512 return main.FALSE
5513 except pexpect.EOF:
5514 main.log.error( self.name + ": EOF exception found" )
5515 main.log.error( self.name + ": " + self.handle.before )
5516 main.cleanup()
5517 main.exit()
5518 except Exception:
5519 main.log.exception( self.name + ": Uncaught exception!" )
5520 main.cleanup()
5521 main.exit()
5522
5523 def vplsSetEncap( self, network, encapType ):
5524 """
5525 CLI command to add an interface to a VPLS network.
5526 Required arguments:
5527 network - Name of the network to create.
5528 encapType - Type of encapsulation.
5529 returns:
5530 main.TRUE on success and main.FALSE on failure
5531 """
5532 try:
5533 network = str( network )
5534 encapType = str( encapType ).upper()
5535 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5536 cmdStr = "vpls set-encap "
5537 cmdStr += network + " " + encapType
5538 output = self.sendline( cmdStr )
5539 assert output is not None, "Error in sendline"
5540 assert "Command not found:" not in output, output
5541 assert "Error executing command" not in output, output
5542 assert "already associated to network" not in output, output
5543 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005544 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005545 return main.TRUE
5546 except AssertionError:
5547 main.log.exception( "" )
5548 return main.FALSE
5549 except TypeError:
5550 main.log.exception( self.name + ": Object not as expected" )
5551 return main.FALSE
5552 except pexpect.EOF:
5553 main.log.error( self.name + ": EOF exception found" )
5554 main.log.error( self.name + ": " + self.handle.before )
5555 main.cleanup()
5556 main.exit()
5557 except Exception:
5558 main.log.exception( self.name + ": Uncaught exception!" )
5559 main.cleanup()
5560 main.exit()
5561
5562 def interfaces( self, jsonFormat=True ):
5563 """
5564 Description: Returns result of interfaces command.
5565 Optional:
5566 * jsonFormat: enable json formatting of output
5567 Returns:
5568 The output of the command or None on error.
5569 """
5570 try:
5571 cmdStr = "interfaces"
5572 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005573 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005574 cmdStr += " -j"
5575 handle = self.sendline( cmdStr )
5576 assert handle is not None, "Error in sendline"
5577 assert "Command not found:" not in handle, handle
5578 return handle
5579 except AssertionError:
5580 main.log.exception( "" )
5581 return None
5582 except TypeError:
5583 main.log.exception( self.name + ": Object not as expected" )
5584 return None
5585 except pexpect.EOF:
5586 main.log.error( self.name + ": EOF exception found" )
5587 main.log.error( self.name + ": " + self.handle.before )
5588 main.cleanup()
5589 main.exit()
5590 except NotImplementedError:
5591 main.log.exception( self.name + ": Json output not supported")
5592 return None
5593 except Exception:
5594 main.log.exception( self.name + ": Uncaught exception!" )
5595 main.cleanup()
5596 main.exit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005597
5598 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
5599 '''
5600 Get the timestamp of searchTerm from karaf log.
5601
5602 Arguments:
5603 splitTerm_before and splitTerm_after:
5604
5605 The terms that split the string that contains the timeStamp of
5606 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5607 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5608 and the splitTerm_after is "x"
5609
5610 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005611 Please look at the "logsearch" Function in onosclidriver.py
Chiyu Chengec63bde2016-11-17 18:11:36 -08005612 '''
5613 if logNum < 0:
5614 main.log.error("Get wrong log number ")
5615 return main.ERROR
5616 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
5617 if len(lines) == 0:
5618 main.log.warn( "Captured timestamp string is empty" )
5619 return main.ERROR
5620 lines = lines[ 0 ]
5621 try:
5622 assert type(lines) is str
5623 # get the target value
5624 line = lines.split( splitTerm_before )
5625 key = line[ 1 ].split( splitTerm_after )
5626 return int( key[ 0 ] )
5627 except IndexError:
5628 main.log.warn( "Index Error!" )
5629 return main.ERROR
5630 except AssertionError:
5631 main.log.warn( "Search Term Not Found " )
5632 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005633
5634 def workQueueAdd( self, queueName, value ):
5635 """
5636 CLI command to add a string to the specified Work Queue.
5637 This function uses the distributed primitives test app, which
5638 gives some cli access to distributed primitives for testing
5639 purposes only.
5640
5641 Required arguments:
5642 queueName - The name of the queue to add to
5643 value - The value to add to the queue
5644 returns:
5645 main.TRUE on success, main.FALSE on failure and
5646 main.ERROR on error.
5647 """
5648 try:
5649 queueName = str( queueName )
5650 value = str( value )
5651 prefix = "work-queue-test"
5652 operation = "add"
5653 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5654 output = self.distPrimitivesSend( cmdStr )
5655 if "Invalid operation name" in output:
5656 main.log.warn( output )
5657 return main.ERROR
5658 elif "Done" in output:
5659 return main.TRUE
5660 except TypeError:
5661 main.log.exception( self.name + ": Object not as expected" )
5662 return main.ERROR
5663 except Exception:
5664 main.log.exception( self.name + ": Uncaught exception!" )
5665 main.cleanup()
5666 main.exit()
5667
5668 def workQueueAddMultiple( self, queueName, value1, value2 ):
5669 """
5670 CLI command to add two strings to the specified Work Queue.
5671 This function uses the distributed primitives test app, which
5672 gives some cli access to distributed primitives for testing
5673 purposes only.
5674
5675 Required arguments:
5676 queueName - The name of the queue to add to
5677 value1 - The first value to add to the queue
5678 value2 - The second value to add to the queue
5679 returns:
5680 main.TRUE on success, main.FALSE on failure and
5681 main.ERROR on error.
5682 """
5683 try:
5684 queueName = str( queueName )
5685 value1 = str( value1 )
5686 value2 = str( value2 )
5687 prefix = "work-queue-test"
5688 operation = "addMultiple"
5689 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5690 output = self.distPrimitivesSend( cmdStr )
5691 if "Invalid operation name" in output:
5692 main.log.warn( output )
5693 return main.ERROR
5694 elif "Done" in output:
5695 return main.TRUE
5696 except TypeError:
5697 main.log.exception( self.name + ": Object not as expected" )
5698 return main.ERROR
5699 except Exception:
5700 main.log.exception( self.name + ": Uncaught exception!" )
5701 main.cleanup()
5702 main.exit()
5703
5704 def workQueueTakeAndComplete( self, queueName, number=1 ):
5705 """
5706 CLI command to take a value from the specified Work Queue and compelte it.
5707 This function uses the distributed primitives test app, which
5708 gives some cli access to distributed primitives for testing
5709 purposes only.
5710
5711 Required arguments:
5712 queueName - The name of the queue to add to
5713 number - The number of items to take and complete
5714 returns:
5715 main.TRUE on success, main.FALSE on failure and
5716 main.ERROR on error.
5717 """
5718 try:
5719 queueName = str( queueName )
5720 number = str( int( number ) )
5721 prefix = "work-queue-test"
5722 operation = "takeAndComplete"
5723 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5724 output = self.distPrimitivesSend( cmdStr )
5725 if "Invalid operation name" in output:
5726 main.log.warn( output )
5727 return main.ERROR
5728 elif "Done" in output:
5729 return main.TRUE
5730 except TypeError:
5731 main.log.exception( self.name + ": Object not as expected" )
5732 return main.ERROR
5733 except Exception:
5734 main.log.exception( self.name + ": Uncaught exception!" )
5735 main.cleanup()
5736 main.exit()
5737
5738 def workQueueDestroy( self, queueName ):
5739 """
5740 CLI command to destroy the specified Work Queue.
5741 This function uses the distributed primitives test app, which
5742 gives some cli access to distributed primitives for testing
5743 purposes only.
5744
5745 Required arguments:
5746 queueName - The name of the queue to add to
5747 returns:
5748 main.TRUE on success, main.FALSE on failure and
5749 main.ERROR on error.
5750 """
5751 try:
5752 queueName = str( queueName )
5753 prefix = "work-queue-test"
5754 operation = "destroy"
5755 cmdStr = " ".join( [ prefix, queueName, operation ] )
5756 output = self.distPrimitivesSend( cmdStr )
5757 if "Invalid operation name" in output:
5758 main.log.warn( output )
5759 return main.ERROR
5760 return main.TRUE
5761 except TypeError:
5762 main.log.exception( self.name + ": Object not as expected" )
5763 return main.ERROR
5764 except Exception:
5765 main.log.exception( self.name + ": Uncaught exception!" )
5766 main.cleanup()
5767 main.exit()
5768
5769 def workQueueTotalPending( self, queueName ):
5770 """
5771 CLI command to get the Total Pending items of the specified Work Queue.
5772 This function uses the distributed primitives test app, which
5773 gives some cli access to distributed primitives for testing
5774 purposes only.
5775
5776 Required arguments:
5777 queueName - The name of the queue to add to
5778 returns:
5779 The number of Pending items in the specified work queue or
5780 None on error
5781 """
5782 try:
5783 queueName = str( queueName )
5784 prefix = "work-queue-test"
5785 operation = "totalPending"
5786 cmdStr = " ".join( [ prefix, queueName, operation ] )
5787 output = self.distPrimitivesSend( cmdStr )
5788 pattern = r'\d+'
5789 if "Invalid operation name" in output:
5790 main.log.warn( output )
5791 return None
5792 else:
5793 match = re.search( pattern, output )
5794 return match.group(0)
5795 except ( AttributeError, TypeError ):
5796 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5797 return None
5798 except Exception:
5799 main.log.exception( self.name + ": Uncaught exception!" )
5800 main.cleanup()
5801 main.exit()
5802
5803 def workQueueTotalCompleted( self, queueName ):
5804 """
5805 CLI command to get the Total Completed items of the specified Work Queue.
5806 This function uses the distributed primitives test app, which
5807 gives some cli access to distributed primitives for testing
5808 purposes only.
5809
5810 Required arguments:
5811 queueName - The name of the queue to add to
5812 returns:
5813 The number of complete items in the specified work queue or
5814 None on error
5815 """
5816 try:
5817 queueName = str( queueName )
5818 prefix = "work-queue-test"
5819 operation = "totalCompleted"
5820 cmdStr = " ".join( [ prefix, queueName, operation ] )
5821 output = self.distPrimitivesSend( cmdStr )
5822 pattern = r'\d+'
5823 if "Invalid operation name" in output:
5824 main.log.warn( output )
5825 return None
5826 else:
5827 match = re.search( pattern, output )
5828 return match.group(0)
5829 except ( AttributeError, TypeError ):
5830 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5831 return None
5832 except Exception:
5833 main.log.exception( self.name + ": Uncaught exception!" )
5834 main.cleanup()
5835 main.exit()
5836
5837 def workQueueTotalInProgress( self, queueName ):
5838 """
5839 CLI command to get the Total In Progress items of the specified Work Queue.
5840 This function uses the distributed primitives test app, which
5841 gives some cli access to distributed primitives for testing
5842 purposes only.
5843
5844 Required arguments:
5845 queueName - The name of the queue to add to
5846 returns:
5847 The number of In Progress items in the specified work queue or
5848 None on error
5849 """
5850 try:
5851 queueName = str( queueName )
5852 prefix = "work-queue-test"
5853 operation = "totalInProgress"
5854 cmdStr = " ".join( [ prefix, queueName, operation ] )
5855 output = self.distPrimitivesSend( cmdStr )
5856 pattern = r'\d+'
5857 if "Invalid operation name" in output:
5858 main.log.warn( output )
5859 return None
5860 else:
5861 match = re.search( pattern, output )
5862 return match.group(0)
5863 except ( AttributeError, TypeError ):
5864 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5865 return None
5866 except Exception:
5867 main.log.exception( self.name + ": Uncaught exception!" )
5868 main.cleanup()
5869 main.exit()