blob: 2d75c39eed8d6d01396024c0c9aaa427f6cae5bd [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
andrewonlab95ce8322014-10-13 14:12:04 -040032
andrewonlab95ce8322014-10-13 14:12:04 -040033
kelvin8ec71442015-01-15 16:57:00 -080034class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040035
kelvin8ec71442015-01-15 16:57:00 -080036 def __init__( self ):
37 """
38 Initialize client
39 """
Jon Hallefbd9792015-03-05 16:11:36 -080040 self.name = None
41 self.home = None
42 self.handle = None
You Wangdb8cd0a2016-05-26 15:19:45 -070043 self.graph = Graph()
kelvin8ec71442015-01-15 16:57:00 -080044 super( CLI, self ).__init__()
45
46 def connect( self, **connectargs ):
47 """
andrewonlab95ce8322014-10-13 14:12:04 -040048 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080049 """
andrewonlab95ce8322014-10-13 14:12:04 -040050 try:
51 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080052 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070053 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040054 for key in self.options:
55 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080056 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040057 break
kelvin-onlabfb521662015-02-27 09:52:40 -080058 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070059 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040060
kelvin-onlaba4074292015-07-09 15:19:49 -070061 for key in self.options:
62 if key == 'onosIp':
63 self.onosIp = self.options[ 'onosIp' ]
64 break
65
kelvin8ec71442015-01-15 16:57:00 -080066 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070067
68 try:
Jon Hallc6793552016-01-19 14:18:37 -080069 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070070 self.ip_address = os.getenv( str( self.ip_address ) )
71 else:
72 main.log.info( self.name +
73 ": Trying to connect to " +
74 self.ip_address )
75
76 except KeyError:
77 main.log.info( "Invalid host name," +
78 " connecting to local host instead" )
79 self.ip_address = 'localhost'
80 except Exception as inst:
81 main.log.error( "Uncaught exception: " + str( inst ) )
82
kelvin8ec71442015-01-15 16:57:00 -080083 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080084 user_name=self.user_name,
85 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080086 port=self.port,
87 pwd=self.pwd,
88 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040089
kelvin8ec71442015-01-15 16:57:00 -080090 self.handle.sendline( "cd " + self.home )
91 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040092 if self.handle:
93 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080094 else:
95 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040096 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080097 except TypeError:
98 main.log.exception( self.name + ": Object not as expected" )
99 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400100 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800101 main.log.error( self.name + ": EOF exception found" )
102 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400103 main.cleanup()
104 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800105 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800106 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400107 main.cleanup()
108 main.exit()
109
kelvin8ec71442015-01-15 16:57:00 -0800110 def disconnect( self ):
111 """
andrewonlab95ce8322014-10-13 14:12:04 -0400112 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800113 """
Jon Halld61331b2015-02-17 16:35:47 -0800114 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400115 try:
Jon Hall61282e32015-03-19 11:34:11 -0700116 if self.handle:
117 i = self.logout()
118 if i == main.TRUE:
119 self.handle.sendline( "" )
120 self.handle.expect( "\$" )
121 self.handle.sendline( "exit" )
122 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800123 except TypeError:
124 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800125 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400126 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800127 main.log.error( self.name + ": EOF exception found" )
128 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700129 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700130 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700131 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800132 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800133 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400134 response = main.FALSE
135 return response
136
kelvin8ec71442015-01-15 16:57:00 -0800137 def logout( self ):
138 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500139 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700140 Returns main.TRUE if exited CLI and
141 main.FALSE on timeout (not guranteed you are disconnected)
142 None on TypeError
143 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800144 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500145 try:
Jon Hall61282e32015-03-19 11:34:11 -0700146 if self.handle:
147 self.handle.sendline( "" )
148 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
149 timeout=10 )
150 if i == 0: # In ONOS CLI
151 self.handle.sendline( "logout" )
Jon Hallbfe00002016-04-05 10:23:54 -0700152 j = self.handle.expect( [ "\$",
153 "Command not found:",
154 pexpect.TIMEOUT ] )
155 if j == 0: # Successfully logged out
156 return main.TRUE
157 elif j == 1 or j == 2:
158 # ONOS didn't fully load, and logout command isn't working
159 # or the command timed out
160 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700161 try:
162 self.handle.expect( "\$" )
163 except pexpect.TIMEOUT:
164 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700165 return main.TRUE
166 else: # some other output
167 main.log.warn( "Unknown repsonse to logout command: '{}'",
168 repr( self.handle.before ) )
169 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700170 elif i == 1: # not in CLI
171 return main.TRUE
172 elif i == 3: # Timeout
173 return main.FALSE
174 else:
andrewonlab9627f432014-11-14 12:45:10 -0500175 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800176 except TypeError:
177 main.log.exception( self.name + ": Object not as expected" )
178 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500179 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800180 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700181 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500182 main.cleanup()
183 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700184 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700185 main.log.error( self.name +
186 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800187 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800188 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500189 main.cleanup()
190 main.exit()
191
kelvin-onlabd3b64892015-01-20 13:26:24 -0800192 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800193 """
andrewonlab95ce8322014-10-13 14:12:04 -0400194 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800195
andrewonlab95ce8322014-10-13 14:12:04 -0400196 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800197 """
andrewonlab95ce8322014-10-13 14:12:04 -0400198 try:
199 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800200 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400201 main.cleanup()
202 main.exit()
203 else:
kelvin8ec71442015-01-15 16:57:00 -0800204 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800205 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800206 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400207 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800208 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800209 handleBefore = self.handle.before
210 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800211 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800212 self.handle.sendline("")
213 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800214 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400215
kelvin-onlabd3b64892015-01-20 13:26:24 -0800216 main.log.info( "Cell call returned: " + handleBefore +
217 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400218
219 return main.TRUE
220
Jon Halld4d4b372015-01-28 16:02:41 -0800221 except TypeError:
222 main.log.exception( self.name + ": Object not as expected" )
223 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400224 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800225 main.log.error( self.name + ": eof exception found" )
226 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400227 main.cleanup()
228 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800229 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800230 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400231 main.cleanup()
232 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800233
pingping-lin57a56ce2015-05-20 16:43:48 -0700234 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800235 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800236 """
Jon Hallefbd9792015-03-05 16:11:36 -0800237 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 by user would be used to set the current karaf shell idle timeout.
239 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800240 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800241 Below is an example to start a session with 60 seconds idle timeout
242 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800243
Hari Krishna25d42f72015-01-05 15:08:28 -0800244 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800245 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800246
kelvin-onlabd3b64892015-01-20 13:26:24 -0800247 Note: karafTimeout is left as str so that this could be read
248 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800249 """
You Wangf69ab392016-01-26 16:34:38 -0800250 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400251 try:
Jon Hall67253832016-12-05 09:47:13 -0800252 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800253 self.handle.sendline( "" )
254 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700255 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500256 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800257 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500258 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400259
Jon Hall67253832016-12-05 09:47:13 -0800260 # Not in CLI so login
Chiyu Chengef109502016-11-21 15:51:38 -0800261 if waitForStart:
262 # Wait for onos start ( -w ) and enter onos cli
263 startCliCommand = "onos -w "
264 else:
265 startCliCommand = "onos "
266 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800267 i = self.handle.expect( [
268 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700269 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400270
271 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800272 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800273 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800274 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800275 "config:property-set -p org.apache.karaf.shell\
276 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800277 karafTimeout )
278 self.handle.expect( "\$" )
Chiyu Chengef109502016-11-21 15:51:38 -0800279 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800280 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400281 return main.TRUE
282 else:
kelvin8ec71442015-01-15 16:57:00 -0800283 # If failed, send ctrl+c to process and try again
284 main.log.info( "Starting CLI failed. Retrying..." )
285 self.handle.send( "\x03" )
Chiyu Chengef109502016-11-21 15:51:38 -0800286 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800287 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
288 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400289 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800290 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800291 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800292 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800293 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800294 "config:property-set -p org.apache.karaf.shell\
295 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800296 karafTimeout )
297 self.handle.expect( "\$" )
Chiyu Chengef109502016-11-21 15:51:38 -0800298 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800299 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400300 return main.TRUE
301 else:
kelvin8ec71442015-01-15 16:57:00 -0800302 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800303 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400304 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400305
Jon Halld4d4b372015-01-28 16:02:41 -0800306 except TypeError:
307 main.log.exception( self.name + ": Object not as expected" )
308 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400309 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800310 main.log.error( self.name + ": EOF exception found" )
311 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400312 main.cleanup()
313 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800314 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800315 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400316 main.cleanup()
317 main.exit()
318
suibin zhang116647a2016-05-06 16:30:09 -0700319 def startCellCli( self, karafTimeout="",
320 commandlineTimeout=10, onosStartTimeout=60 ):
321 """
322 Start CLI on onos ecll handle.
323
324 karafTimeout is an optional argument. karafTimeout value passed
325 by user would be used to set the current karaf shell idle timeout.
326 Note that when ever this property is modified the shell will exit and
327 the subsequent login would reflect new idle timeout.
328 Below is an example to start a session with 60 seconds idle timeout
329 ( input value is in milliseconds ):
330
331 tValue = "60000"
332
333 Note: karafTimeout is left as str so that this could be read
334 and passed to startOnosCli from PARAMS file as str.
335 """
336
337 try:
338 self.handle.sendline( "" )
339 x = self.handle.expect( [
340 "\$", "onos>" ], commandlineTimeout)
341
342 if x == 1:
343 main.log.info( "ONOS cli is already running" )
344 return main.TRUE
345
346 # Wait for onos start ( -w ) and enter onos cli
347 self.handle.sendline( "/opt/onos/bin/onos" )
348 i = self.handle.expect( [
349 "onos>",
350 pexpect.TIMEOUT ], onosStartTimeout )
351
352 if i == 0:
353 main.log.info( self.name + " CLI Started successfully" )
354 if karafTimeout:
355 self.handle.sendline(
356 "config:property-set -p org.apache.karaf.shell\
357 sshIdleTimeout " +
358 karafTimeout )
359 self.handle.expect( "\$" )
360 self.handle.sendline( "/opt/onos/bin/onos" )
361 self.handle.expect( "onos>" )
362 return main.TRUE
363 else:
364 # If failed, send ctrl+c to process and try again
365 main.log.info( "Starting CLI failed. Retrying..." )
366 self.handle.send( "\x03" )
367 self.handle.sendline( "/opt/onos/bin/onos" )
368 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
369 timeout=30 )
370 if i == 0:
371 main.log.info( self.name + " CLI Started " +
372 "successfully after retry attempt" )
373 if karafTimeout:
374 self.handle.sendline(
375 "config:property-set -p org.apache.karaf.shell\
376 sshIdleTimeout " +
377 karafTimeout )
378 self.handle.expect( "\$" )
379 self.handle.sendline( "/opt/onos/bin/onos" )
380 self.handle.expect( "onos>" )
381 return main.TRUE
382 else:
383 main.log.error( "Connection to CLI " +
384 self.name + " timeout" )
385 return main.FALSE
386
387 except TypeError:
388 main.log.exception( self.name + ": Object not as expected" )
389 return None
390 except pexpect.EOF:
391 main.log.error( self.name + ": EOF exception found" )
392 main.log.error( self.name + ": " + self.handle.before )
393 main.cleanup()
394 main.exit()
395 except Exception:
396 main.log.exception( self.name + ": Uncaught exception!" )
397 main.cleanup()
398 main.exit()
399
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800400 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800401 """
402 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800403 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800404 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700405 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800406 Available level: DEBUG, TRACE, INFO, WARN, ERROR
407 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800408 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800409 """
410 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800411 lvlStr = ""
412 if level:
413 lvlStr = "--level=" + level
414
kelvin-onlab338f5512015-02-06 10:53:16 -0800415 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700416 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800417 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800418
kelvin-onlab9f541032015-02-04 16:19:53 -0800419 response = self.handle.before
420 if re.search( "Error", response ):
421 return main.FALSE
422 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700423 except pexpect.TIMEOUT:
424 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700425 if noExit:
426 main.cleanup()
427 return None
428 else:
429 main.cleanup()
430 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800431 except pexpect.EOF:
432 main.log.error( self.name + ": EOF exception found" )
433 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700434 if noExit:
435 main.cleanup()
436 return None
437 else:
438 main.cleanup()
439 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800440 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800441 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700442 if noExit:
443 main.cleanup()
444 return None
445 else:
446 main.cleanup()
447 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400448
YPZhangebf9eb52016-05-12 15:20:24 -0700449 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800450 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800451 Send a completely user specified string to
452 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400453 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800454
YPZhang14a4aa92016-07-15 13:37:15 -0700455 if noExit is True, TestON will not exit, and return None
YPZhangebf9eb52016-05-12 15:20:24 -0700456
andrewonlaba18f6bf2014-10-13 19:31:54 -0400457 Warning: There are no sanity checking to commands
458 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800459
kelvin8ec71442015-01-15 16:57:00 -0800460 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400461 try:
Jon Halla495f562016-05-16 18:03:26 -0700462 # Try to reconnect if disconnected from cli
463 self.handle.sendline( "" )
464 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
465 if i == 1:
466 main.log.error( self.name + ": onos cli session closed. ")
467 if self.onosIp:
468 main.log.warn( "Trying to reconnect " + self.onosIp )
469 reconnectResult = self.startOnosCli( self.onosIp )
470 if reconnectResult:
471 main.log.info( self.name + ": onos cli session reconnected." )
472 else:
473 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700474 if noExit:
475 return None
476 else:
477 main.cleanup()
478 main.exit()
Jon Halla495f562016-05-16 18:03:26 -0700479 else:
480 main.cleanup()
481 main.exit()
482 if i == 2:
483 self.handle.sendline( "" )
484 self.handle.expect( "onos>" )
485
Jon Hall14a03b52016-05-11 12:07:30 -0700486 if debug:
487 # NOTE: This adds and average of .4 seconds per call
488 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
YPZhangebf9eb52016-05-12 15:20:24 -0700489 self.log( logStr,noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800490 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800491 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800492 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800493 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800494 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
495 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700496 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700497 main.log.debug( self.name + ": Raw output" )
498 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700499
500 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800501 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800502 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700503 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700504 main.log.debug( self.name + ": ansiEscape output" )
505 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700506
kelvin-onlabfb521662015-02-27 09:52:40 -0800507 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800508 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700509 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700510 main.log.debug( self.name + ": Removed extra returns " +
511 "from output" )
512 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700513
514 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800515 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700516 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700517 main.log.debug( self.name + ": parsed and stripped output" )
518 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700519
Jon Hall63604932015-02-26 17:09:50 -0800520 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700521 output = response.split( cmdStr.strip(), 1 )
522 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700523 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700524 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700525 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800526 output = output[1].strip()
527 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800528 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800529 return output
GlennRCed771242016-01-13 17:02:47 -0800530 except pexpect.TIMEOUT:
531 main.log.error( self.name + ":ONOS timeout" )
532 if debug:
533 main.log.debug( self.handle.before )
534 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700535 except IndexError:
536 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700537 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700538 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800539 except TypeError:
540 main.log.exception( self.name + ": Object not as expected" )
541 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400542 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800543 main.log.error( self.name + ": EOF exception found" )
544 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700545 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700546 return None
547 else:
548 main.cleanup()
549 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800550 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800551 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700552 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700553 return None
554 else:
555 main.cleanup()
556 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400557
kelvin8ec71442015-01-15 16:57:00 -0800558 # IMPORTANT NOTE:
559 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800560 # the cli command changing 'a:b' with 'aB'.
561 # Ex ) onos:topology > onosTopology
562 # onos:links > onosLinks
563 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800564
kelvin-onlabd3b64892015-01-20 13:26:24 -0800565 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800566 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400567 Adds a new cluster node by ID and address information.
568 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800569 * nodeId
570 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400571 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800572 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800573 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400574 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800575 cmdStr = "add-node " + str( nodeId ) + " " +\
576 str( ONOSIp ) + " " + str( tcpPort )
577 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700578 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800579 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800580 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800581 main.log.error( "Error in adding node" )
582 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800583 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400584 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800585 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400586 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800587 except AssertionError:
588 main.log.exception( "" )
589 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800590 except TypeError:
591 main.log.exception( self.name + ": Object not as expected" )
592 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400593 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800594 main.log.error( self.name + ": EOF exception found" )
595 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400596 main.cleanup()
597 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800598 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800599 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400600 main.cleanup()
601 main.exit()
602
kelvin-onlabd3b64892015-01-20 13:26:24 -0800603 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800604 """
andrewonlab86dc3082014-10-13 18:18:38 -0400605 Removes a cluster by ID
606 Issues command: 'remove-node [<node-id>]'
607 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800608 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800609 """
andrewonlab86dc3082014-10-13 18:18:38 -0400610 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400611
kelvin-onlabd3b64892015-01-20 13:26:24 -0800612 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700613 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700614 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800615 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700616 if re.search( "Error", handle ):
617 main.log.error( "Error in removing node" )
618 main.log.error( handle )
619 return main.FALSE
620 else:
621 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800622 except AssertionError:
623 main.log.exception( "" )
624 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800625 except TypeError:
626 main.log.exception( self.name + ": Object not as expected" )
627 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400628 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800629 main.log.error( self.name + ": EOF exception found" )
630 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400631 main.cleanup()
632 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800633 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800634 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400635 main.cleanup()
636 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400637
Jon Hall61282e32015-03-19 11:34:11 -0700638 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800639 """
andrewonlab7c211572014-10-15 16:45:20 -0400640 List the nodes currently visible
641 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700642 Optional argument:
643 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800644 """
andrewonlab7c211572014-10-15 16:45:20 -0400645 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700646 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700647 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700648 cmdStr += " -j"
649 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700650 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800651 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700652 return output
Jon Hallc6793552016-01-19 14:18:37 -0800653 except AssertionError:
654 main.log.exception( "" )
655 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800656 except TypeError:
657 main.log.exception( self.name + ": Object not as expected" )
658 return None
andrewonlab7c211572014-10-15 16:45:20 -0400659 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800660 main.log.error( self.name + ": EOF exception found" )
661 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400662 main.cleanup()
663 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800664 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800665 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400666 main.cleanup()
667 main.exit()
668
kelvin8ec71442015-01-15 16:57:00 -0800669 def topology( self ):
670 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700671 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700672 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700673 Return:
674 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800675 """
andrewonlab95ce8322014-10-13 14:12:04 -0400676 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700677 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800678 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800679 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700680 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400681 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800682 except AssertionError:
683 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800684 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800685 except TypeError:
686 main.log.exception( self.name + ": Object not as expected" )
687 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400688 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800689 main.log.error( self.name + ": EOF exception found" )
690 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400691 main.cleanup()
692 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800693 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800694 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400695 main.cleanup()
696 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800697
jenkins7ead5a82015-03-13 10:28:21 -0700698 def deviceRemove( self, deviceId ):
699 """
700 Removes particular device from storage
701
702 TODO: refactor this function
703 """
704 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700705 cmdStr = "device-remove " + str( deviceId )
706 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800707 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700708 if re.search( "Error", handle ):
709 main.log.error( "Error in removing device" )
710 main.log.error( handle )
711 return main.FALSE
712 else:
713 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800714 except AssertionError:
715 main.log.exception( "" )
716 return None
jenkins7ead5a82015-03-13 10:28:21 -0700717 except TypeError:
718 main.log.exception( self.name + ": Object not as expected" )
719 return None
720 except pexpect.EOF:
721 main.log.error( self.name + ": EOF exception found" )
722 main.log.error( self.name + ": " + self.handle.before )
723 main.cleanup()
724 main.exit()
725 except Exception:
726 main.log.exception( self.name + ": Uncaught exception!" )
727 main.cleanup()
728 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700729
kelvin-onlabd3b64892015-01-20 13:26:24 -0800730 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800731 """
Jon Hall7b02d952014-10-17 20:14:54 -0400732 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400733 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800734 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800735 """
andrewonlab86dc3082014-10-13 18:18:38 -0400736 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700737 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800738 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700739 cmdStr += " -j"
740 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800741 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700742 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800743 except AssertionError:
744 main.log.exception( "" )
745 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800746 except TypeError:
747 main.log.exception( self.name + ": Object not as expected" )
748 return None
andrewonlab7c211572014-10-15 16:45:20 -0400749 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800750 main.log.error( self.name + ": EOF exception found" )
751 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400752 main.cleanup()
753 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800754 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800755 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400756 main.cleanup()
757 main.exit()
758
kelvin-onlabd3b64892015-01-20 13:26:24 -0800759 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800760 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800761 This balances the devices across all controllers
762 by issuing command: 'onos> onos:balance-masters'
763 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800764 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800765 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800766 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700767 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800768 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700769 if re.search( "Error", handle ):
770 main.log.error( "Error in balancing masters" )
771 main.log.error( handle )
772 return main.FALSE
773 else:
774 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800775 except AssertionError:
776 main.log.exception( "" )
777 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800778 except TypeError:
779 main.log.exception( self.name + ": Object not as expected" )
780 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800781 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800782 main.log.error( self.name + ": EOF exception found" )
783 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800784 main.cleanup()
785 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800786 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800787 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800788 main.cleanup()
789 main.exit()
790
Jon Hallc6793552016-01-19 14:18:37 -0800791 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700792 """
793 Returns the output of the masters command.
794 Optional argument:
795 * jsonFormat - boolean indicating if you want output in json
796 """
797 try:
798 cmdStr = "onos:masters"
799 if jsonFormat:
800 cmdStr += " -j"
801 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700802 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800803 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700804 return output
Jon Hallc6793552016-01-19 14:18:37 -0800805 except AssertionError:
806 main.log.exception( "" )
807 return None
acsmars24950022015-07-30 18:00:43 -0700808 except TypeError:
809 main.log.exception( self.name + ": Object not as expected" )
810 return None
811 except pexpect.EOF:
812 main.log.error( self.name + ": EOF exception found" )
813 main.log.error( self.name + ": " + self.handle.before )
814 main.cleanup()
815 main.exit()
816 except Exception:
817 main.log.exception( self.name + ": Uncaught exception!" )
818 main.cleanup()
819 main.exit()
820
Jon Hallc6793552016-01-19 14:18:37 -0800821 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700822 """
823 Uses the master command to check that the devices' leadership
824 is evenly divided
825
826 Dependencies: checkMasters() and summary()
827
Jon Hall6509dbf2016-06-21 17:01:17 -0700828 Returns main.TRUE if the devices are balanced
829 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700830 Exits on Exception
831 Returns None on TypeError
832 """
833 try:
Jon Hallc6793552016-01-19 14:18:37 -0800834 summaryOutput = self.summary()
835 totalDevices = json.loads( summaryOutput )[ "devices" ]
836 except ( TypeError, ValueError ):
837 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
838 return None
839 try:
acsmars24950022015-07-30 18:00:43 -0700840 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800841 mastersOutput = self.checkMasters()
842 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700843 first = masters[ 0 ][ "size" ]
844 for master in masters:
845 totalOwnedDevices += master[ "size" ]
846 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
847 main.log.error( "Mastership not balanced" )
848 main.log.info( "\n" + self.checkMasters( False ) )
849 return main.FALSE
850 main.log.info( "Mastership balanced between " \
851 + str( len(masters) ) + " masters" )
852 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800853 except ( TypeError, ValueError ):
854 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700855 return None
856 except pexpect.EOF:
857 main.log.error( self.name + ": EOF exception found" )
858 main.log.error( self.name + ": " + self.handle.before )
859 main.cleanup()
860 main.exit()
861 except Exception:
862 main.log.exception( self.name + ": Uncaught exception!" )
863 main.cleanup()
864 main.exit()
865
YPZhangfebf7302016-05-24 16:45:56 -0700866 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800867 """
Jon Halle8217482014-10-17 13:49:14 -0400868 Lists all core links
869 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800870 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800871 """
Jon Halle8217482014-10-17 13:49:14 -0400872 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700873 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800874 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700875 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700876 handle = self.sendline( cmdStr, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -0800877 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700878 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800879 except AssertionError:
880 main.log.exception( "" )
881 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800882 except TypeError:
883 main.log.exception( self.name + ": Object not as expected" )
884 return None
Jon Halle8217482014-10-17 13:49:14 -0400885 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800886 main.log.error( self.name + ": EOF exception found" )
887 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400888 main.cleanup()
889 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800890 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800891 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400892 main.cleanup()
893 main.exit()
894
kelvin-onlabd3b64892015-01-20 13:26:24 -0800895 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800896 """
Jon Halle8217482014-10-17 13:49:14 -0400897 Lists all ports
898 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800899 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800900 """
Jon Halle8217482014-10-17 13:49:14 -0400901 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700902 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800903 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700904 cmdStr += " -j"
905 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800906 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700907 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800908 except AssertionError:
909 main.log.exception( "" )
910 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800911 except TypeError:
912 main.log.exception( self.name + ": Object not as expected" )
913 return None
Jon Halle8217482014-10-17 13:49:14 -0400914 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800915 main.log.error( self.name + ": EOF exception found" )
916 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400917 main.cleanup()
918 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800919 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800920 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400921 main.cleanup()
922 main.exit()
923
kelvin-onlabd3b64892015-01-20 13:26:24 -0800924 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800925 """
Jon Hall983a1702014-10-28 18:44:22 -0400926 Lists all devices and the controllers with roles assigned to them
927 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800928 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800929 """
andrewonlab7c211572014-10-15 16:45:20 -0400930 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700931 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800932 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700933 cmdStr += " -j"
934 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800935 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700936 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800937 except AssertionError:
938 main.log.exception( "" )
939 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800940 except TypeError:
941 main.log.exception( self.name + ": Object not as expected" )
942 return None
Jon Hall983a1702014-10-28 18:44:22 -0400943 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800944 main.log.error( self.name + ": EOF exception found" )
945 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400946 main.cleanup()
947 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800948 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800949 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400950 main.cleanup()
951 main.exit()
952
kelvin-onlabd3b64892015-01-20 13:26:24 -0800953 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800954 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800955 Given the a string containing the json representation of the "roles"
956 cli command and a partial or whole device id, returns a json object
957 containing the roles output for the first device whose id contains
958 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400959
960 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800961 A dict of the role assignments for the given device or
962 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800963 """
Jon Hall983a1702014-10-28 18:44:22 -0400964 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400966 return None
967 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800968 rawRoles = self.roles()
969 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800970 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800972 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800973 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400974 return device
975 return None
Jon Hallc6793552016-01-19 14:18:37 -0800976 except ( TypeError, ValueError ):
977 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800978 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400979 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800980 main.log.error( self.name + ": EOF exception found" )
981 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400982 main.cleanup()
983 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800984 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800985 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400986 main.cleanup()
987 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800988
kelvin-onlabd3b64892015-01-20 13:26:24 -0800989 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800990 """
Jon Hall94fd0472014-12-08 11:52:42 -0800991 Iterates through each device and checks if there is a master assigned
992 Returns: main.TRUE if each device has a master
993 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800994 """
Jon Hall94fd0472014-12-08 11:52:42 -0800995 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800996 rawRoles = self.roles()
997 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800998 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800999 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001000 # print device
1001 if device[ 'master' ] == "none":
1002 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001003 return main.FALSE
1004 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001005 except ( TypeError, ValueError ):
1006 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001007 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001008 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001009 main.log.error( self.name + ": EOF exception found" )
1010 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001011 main.cleanup()
1012 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001013 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001014 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001015 main.cleanup()
1016 main.exit()
1017
kelvin-onlabd3b64892015-01-20 13:26:24 -08001018 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001019 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001020 Returns string of paths, and the cost.
1021 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001022 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001023 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001024 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1025 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001026 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001027 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001028 main.log.error( "Error in getting paths" )
1029 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001030 else:
kelvin8ec71442015-01-15 16:57:00 -08001031 path = handle.split( ";" )[ 0 ]
1032 cost = handle.split( ";" )[ 1 ]
1033 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001034 except AssertionError:
1035 main.log.exception( "" )
1036 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001037 except TypeError:
1038 main.log.exception( self.name + ": Object not as expected" )
1039 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001040 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001041 main.log.error( self.name + ": EOF exception found" )
1042 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001043 main.cleanup()
1044 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001045 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001046 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001047 main.cleanup()
1048 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001049
kelvin-onlabd3b64892015-01-20 13:26:24 -08001050 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001051 """
Jon Hallffb386d2014-11-21 13:43:38 -08001052 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001053 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001054 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001055 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001056 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001057 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001058 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001059 cmdStr += " -j"
1060 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001061 if handle:
1062 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001063 # TODO: Maybe make this less hardcoded
1064 # ConsistentMap Exceptions
1065 assert "org.onosproject.store.service" not in handle
1066 # Node not leader
1067 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001068 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001069 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001070 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001071 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001072 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001073 except TypeError:
1074 main.log.exception( self.name + ": Object not as expected" )
1075 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001076 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001077 main.log.error( self.name + ": EOF exception found" )
1078 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001079 main.cleanup()
1080 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001081 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001082 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001083 main.cleanup()
1084 main.exit()
1085
kelvin-onlabd3b64892015-01-20 13:26:24 -08001086 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001087 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001088 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001089
Jon Hallefbd9792015-03-05 16:11:36 -08001090 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001091 partial mac address
1092
Jon Hall42db6dc2014-10-24 19:03:48 -04001093 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001094 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001095 try:
kelvin8ec71442015-01-15 16:57:00 -08001096 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001097 return None
1098 else:
1099 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001100 rawHosts = self.hosts()
1101 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001102 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001103 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001104 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001105 if not host:
1106 pass
1107 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001108 return host
1109 return None
Jon Hallc6793552016-01-19 14:18:37 -08001110 except ( TypeError, ValueError ):
1111 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001112 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001113 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001114 main.log.error( self.name + ": EOF exception found" )
1115 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001116 main.cleanup()
1117 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001118 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001119 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001120 main.cleanup()
1121 main.exit()
1122
kelvin-onlabd3b64892015-01-20 13:26:24 -08001123 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001124 """
1125 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001126 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001127
andrewonlab3f0a4af2014-10-17 12:25:14 -04001128 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001130 IMPORTANT:
1131 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001132 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001133 Furthermore, it assumes that value of VLAN is '-1'
1134 Description:
kelvin8ec71442015-01-15 16:57:00 -08001135 Converts mininet hosts ( h1, h2, h3... ) into
1136 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1137 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001138 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001139 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001140
kelvin-onlabd3b64892015-01-20 13:26:24 -08001141 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001142 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001143 hostHex = hex( int( host ) ).zfill( 12 )
1144 hostHex = str( hostHex ).replace( 'x', '0' )
1145 i = iter( str( hostHex ) )
1146 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1147 hostHex = hostHex + "/-1"
1148 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001149
kelvin-onlabd3b64892015-01-20 13:26:24 -08001150 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001151
Jon Halld4d4b372015-01-28 16:02:41 -08001152 except TypeError:
1153 main.log.exception( self.name + ": Object not as expected" )
1154 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001155 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001156 main.log.error( self.name + ": EOF exception found" )
1157 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001158 main.cleanup()
1159 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001160 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001161 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001162 main.cleanup()
1163 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001164
Jeremy Songsterc032f162016-08-04 17:14:49 -07001165 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001166 """
andrewonlabe6745342014-10-17 14:29:13 -04001167 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001168 * hostIdOne: ONOS host id for host1
1169 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001170 Optional:
1171 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001172 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001173 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001174 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001175 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001176 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001177 Returns:
1178 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001179 """
andrewonlabe6745342014-10-17 14:29:13 -04001180 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001181 cmdStr = "add-host-intent "
1182 if vlanId:
1183 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001184 if setVlan:
1185 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001186 if encap:
1187 cmdStr += "--encapsulation " + str( encap ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001188 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001189 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001190 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001191 if re.search( "Error", handle ):
1192 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001193 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001194 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001195 else:
1196 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001197 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1198 match = re.search('id=0x([\da-f]+),', handle)
1199 if match:
1200 return match.group()[3:-1]
1201 else:
1202 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001203 main.log.debug( "Response from ONOS was: " +
1204 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001205 return None
Jon Hallc6793552016-01-19 14:18:37 -08001206 except AssertionError:
1207 main.log.exception( "" )
1208 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001209 except TypeError:
1210 main.log.exception( self.name + ": Object not as expected" )
1211 return None
andrewonlabe6745342014-10-17 14:29:13 -04001212 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001213 main.log.error( self.name + ": EOF exception found" )
1214 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001215 main.cleanup()
1216 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001217 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001218 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001219 main.cleanup()
1220 main.exit()
1221
kelvin-onlabd3b64892015-01-20 13:26:24 -08001222 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001223 """
andrewonlab7b31d232014-10-24 13:31:47 -04001224 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001225 * ingressDevice: device id of ingress device
1226 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001227 Optional:
1228 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001229 Description:
1230 Adds an optical intent by specifying an ingress and egress device
1231 Returns:
1232 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001233 """
andrewonlab7b31d232014-10-24 13:31:47 -04001234 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001235 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1236 " " + str( egressDevice )
1237 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001238 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001239 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001240 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001241 main.log.error( "Error in adding Optical intent" )
1242 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001243 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001244 main.log.info( "Optical intent installed between " +
1245 str( ingressDevice ) + " and " +
1246 str( egressDevice ) )
1247 match = re.search('id=0x([\da-f]+),', handle)
1248 if match:
1249 return match.group()[3:-1]
1250 else:
1251 main.log.error( "Error, intent ID not found" )
1252 return None
Jon Hallc6793552016-01-19 14:18:37 -08001253 except AssertionError:
1254 main.log.exception( "" )
1255 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001256 except TypeError:
1257 main.log.exception( self.name + ": Object not as expected" )
1258 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001259 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001260 main.log.error( self.name + ": EOF exception found" )
1261 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001262 main.cleanup()
1263 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001264 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001265 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001266 main.cleanup()
1267 main.exit()
1268
kelvin-onlabd3b64892015-01-20 13:26:24 -08001269 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001270 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001271 ingressDevice,
1272 egressDevice,
1273 portIngress="",
1274 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001275 ethType="",
1276 ethSrc="",
1277 ethDst="",
1278 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001279 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001280 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001281 ipProto="",
1282 ipSrc="",
1283 ipDst="",
1284 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001285 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001286 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001287 setVlan="",
1288 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001289 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001290 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001291 * ingressDevice: device id of ingress device
1292 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001293 Optional:
1294 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001295 * ethSrc: specify ethSrc ( i.e. src mac addr )
1296 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001297 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001298 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001299 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001300 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001301 * ipSrc: specify ip source address
1302 * ipDst: specify ip destination address
1303 * tcpSrc: specify tcp source port
1304 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001305 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001306 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001307 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001308 Description:
kelvin8ec71442015-01-15 16:57:00 -08001309 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001310 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001311 Returns:
1312 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001313
Jon Halle3f39ff2015-01-13 11:50:53 -08001314 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001315 options developers provide for point-to-point
1316 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001317 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001318 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001319 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001320
Jeremy Songsterff553672016-05-12 17:06:23 -07001321 if ethType:
1322 cmd += " --ethType " + str( ethType )
1323 if ethSrc:
1324 cmd += " --ethSrc " + str( ethSrc )
1325 if ethDst:
1326 cmd += " --ethDst " + str( ethDst )
1327 if bandwidth:
1328 cmd += " --bandwidth " + str( bandwidth )
1329 if lambdaAlloc:
1330 cmd += " --lambda "
1331 if ipProto:
1332 cmd += " --ipProto " + str( ipProto )
1333 if ipSrc:
1334 cmd += " --ipSrc " + str( ipSrc )
1335 if ipDst:
1336 cmd += " --ipDst " + str( ipDst )
1337 if tcpSrc:
1338 cmd += " --tcpSrc " + str( tcpSrc )
1339 if tcpDst:
1340 cmd += " --tcpDst " + str( tcpDst )
1341 if vlanId:
1342 cmd += " -v " + str( vlanId )
1343 if setVlan:
1344 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001345 if encap:
1346 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001347 if protected:
1348 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001349
kelvin8ec71442015-01-15 16:57:00 -08001350 # Check whether the user appended the port
1351 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001352 if "/" in ingressDevice:
1353 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001354 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001355 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001356 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001357 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001358 # Would it make sense to throw an exception and exit
1359 # the test?
1360 return None
andrewonlab36af3822014-11-18 17:48:18 -05001361
kelvin8ec71442015-01-15 16:57:00 -08001362 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001363 str( ingressDevice ) + "/" +\
1364 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001365
kelvin-onlabd3b64892015-01-20 13:26:24 -08001366 if "/" in egressDevice:
1367 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001368 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001369 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001370 main.log.error( "You must specify the egress port" )
1371 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001372
kelvin8ec71442015-01-15 16:57:00 -08001373 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001374 str( egressDevice ) + "/" +\
1375 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001376
kelvin-onlab898a6c62015-01-16 14:13:53 -08001377 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001378 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001379 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001380 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001381 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001382 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001383 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001384 # TODO: print out all the options in this message?
1385 main.log.info( "Point-to-point intent installed between " +
1386 str( ingressDevice ) + " and " +
1387 str( egressDevice ) )
1388 match = re.search('id=0x([\da-f]+),', handle)
1389 if match:
1390 return match.group()[3:-1]
1391 else:
1392 main.log.error( "Error, intent ID not found" )
1393 return None
Jon Hallc6793552016-01-19 14:18:37 -08001394 except AssertionError:
1395 main.log.exception( "" )
1396 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001397 except TypeError:
1398 main.log.exception( self.name + ": Object not as expected" )
1399 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001400 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001401 main.log.error( self.name + ": EOF exception found" )
1402 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001403 main.cleanup()
1404 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001405 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001406 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001407 main.cleanup()
1408 main.exit()
1409
kelvin-onlabd3b64892015-01-20 13:26:24 -08001410 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001411 self,
shahshreyac2f97072015-03-19 17:04:29 -07001412 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001413 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001414 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001415 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001416 ethType="",
1417 ethSrc="",
1418 ethDst="",
1419 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001420 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001421 ipProto="",
1422 ipSrc="",
1423 ipDst="",
1424 tcpSrc="",
1425 tcpDst="",
1426 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001427 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001428 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001429 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001430 partial=False,
1431 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001432 """
shahshreyad0c80432014-12-04 16:56:05 -08001433 Note:
shahshreya70622b12015-03-19 17:19:00 -07001434 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001435 is same. That is, all ingress devices include port numbers
1436 with a "/" or all ingress devices could specify device
1437 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001438 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001439 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001440 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001441 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001442 Optional:
1443 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001444 * ethSrc: specify ethSrc ( i.e. src mac addr )
1445 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001446 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001447 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001448 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001449 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001450 * ipSrc: specify ip source address
1451 * ipDst: specify ip destination address
1452 * tcpSrc: specify tcp source port
1453 * tcpDst: specify tcp destination port
1454 * setEthSrc: action to Rewrite Source MAC Address
1455 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001456 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001457 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001458 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001459 Description:
kelvin8ec71442015-01-15 16:57:00 -08001460 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001461 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001462 Returns:
1463 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001464
Jon Halle3f39ff2015-01-13 11:50:53 -08001465 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001466 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001467 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001468 """
shahshreyad0c80432014-12-04 16:56:05 -08001469 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001470 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001471
Jeremy Songsterff553672016-05-12 17:06:23 -07001472 if ethType:
1473 cmd += " --ethType " + str( ethType )
1474 if ethSrc:
1475 cmd += " --ethSrc " + str( ethSrc )
1476 if ethDst:
1477 cmd += " --ethDst " + str( ethDst )
1478 if bandwidth:
1479 cmd += " --bandwidth " + str( bandwidth )
1480 if lambdaAlloc:
1481 cmd += " --lambda "
1482 if ipProto:
1483 cmd += " --ipProto " + str( ipProto )
1484 if ipSrc:
1485 cmd += " --ipSrc " + str( ipSrc )
1486 if ipDst:
1487 cmd += " --ipDst " + str( ipDst )
1488 if tcpSrc:
1489 cmd += " --tcpSrc " + str( tcpSrc )
1490 if tcpDst:
1491 cmd += " --tcpDst " + str( tcpDst )
1492 if setEthSrc:
1493 cmd += " --setEthSrc " + str( setEthSrc )
1494 if setEthDst:
1495 cmd += " --setEthDst " + str( setEthDst )
1496 if vlanId:
1497 cmd += " -v " + str( vlanId )
1498 if setVlan:
1499 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001500 if partial:
1501 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001502 if encap:
1503 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001504
kelvin8ec71442015-01-15 16:57:00 -08001505 # Check whether the user appended the port
1506 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001507
1508 if portIngressList is None:
1509 for ingressDevice in ingressDeviceList:
1510 if "/" in ingressDevice:
1511 cmd += " " + str( ingressDevice )
1512 else:
1513 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001514 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001515 # TODO: perhaps more meaningful return
1516 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001517 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001518 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001519 for ingressDevice, portIngress in zip( ingressDeviceList,
1520 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001521 cmd += " " + \
1522 str( ingressDevice ) + "/" +\
1523 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001524 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001525 main.log.error( "Device list and port list does not " +
1526 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001527 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001528 if "/" in egressDevice:
1529 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001530 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001531 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001532 main.log.error( "You must specify " +
1533 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001534 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001535
kelvin8ec71442015-01-15 16:57:00 -08001536 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001537 str( egressDevice ) + "/" +\
1538 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001539 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001540 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001541 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001542 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001543 main.log.error( "Error in adding multipoint-to-singlepoint " +
1544 "intent" )
1545 return None
shahshreyad0c80432014-12-04 16:56:05 -08001546 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001547 match = re.search('id=0x([\da-f]+),', handle)
1548 if match:
1549 return match.group()[3:-1]
1550 else:
1551 main.log.error( "Error, intent ID not found" )
1552 return None
Jon Hallc6793552016-01-19 14:18:37 -08001553 except AssertionError:
1554 main.log.exception( "" )
1555 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001556 except TypeError:
1557 main.log.exception( self.name + ": Object not as expected" )
1558 return None
1559 except pexpect.EOF:
1560 main.log.error( self.name + ": EOF exception found" )
1561 main.log.error( self.name + ": " + self.handle.before )
1562 main.cleanup()
1563 main.exit()
1564 except Exception:
1565 main.log.exception( self.name + ": Uncaught exception!" )
1566 main.cleanup()
1567 main.exit()
1568
1569 def addSinglepointToMultipointIntent(
1570 self,
1571 ingressDevice,
1572 egressDeviceList,
1573 portIngress="",
1574 portEgressList=None,
1575 ethType="",
1576 ethSrc="",
1577 ethDst="",
1578 bandwidth="",
1579 lambdaAlloc=False,
1580 ipProto="",
1581 ipSrc="",
1582 ipDst="",
1583 tcpSrc="",
1584 tcpDst="",
1585 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001586 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001587 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001588 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001589 partial=False,
1590 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001591 """
1592 Note:
1593 This function assumes the format of all egress devices
1594 is same. That is, all egress devices include port numbers
1595 with a "/" or all egress devices could specify device
1596 ids and port numbers seperately.
1597 Required:
1598 * EgressDeviceList: List of device ids of egress device
1599 ( Atleast 2 eress devices required in the list )
1600 * ingressDevice: device id of ingress device
1601 Optional:
1602 * ethType: specify ethType
1603 * ethSrc: specify ethSrc ( i.e. src mac addr )
1604 * ethDst: specify ethDst ( i.e. dst mac addr )
1605 * bandwidth: specify bandwidth capacity of link
1606 * lambdaAlloc: if True, intent will allocate lambda
1607 for the specified intent
1608 * ipProto: specify ip protocol
1609 * ipSrc: specify ip source address
1610 * ipDst: specify ip destination address
1611 * tcpSrc: specify tcp source port
1612 * tcpDst: specify tcp destination port
1613 * setEthSrc: action to Rewrite Source MAC Address
1614 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001615 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001616 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001617 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001618 Description:
1619 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1620 specifying device id's and optional fields
1621 Returns:
1622 A string of the intent id or None on error
1623
1624 NOTE: This function may change depending on the
1625 options developers provide for singlepoint-to-multipoint
1626 intent via cli
1627 """
1628 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001629 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001630
Jeremy Songsterff553672016-05-12 17:06:23 -07001631 if ethType:
1632 cmd += " --ethType " + str( ethType )
1633 if ethSrc:
1634 cmd += " --ethSrc " + str( ethSrc )
1635 if ethDst:
1636 cmd += " --ethDst " + str( ethDst )
1637 if bandwidth:
1638 cmd += " --bandwidth " + str( bandwidth )
1639 if lambdaAlloc:
1640 cmd += " --lambda "
1641 if ipProto:
1642 cmd += " --ipProto " + str( ipProto )
1643 if ipSrc:
1644 cmd += " --ipSrc " + str( ipSrc )
1645 if ipDst:
1646 cmd += " --ipDst " + str( ipDst )
1647 if tcpSrc:
1648 cmd += " --tcpSrc " + str( tcpSrc )
1649 if tcpDst:
1650 cmd += " --tcpDst " + str( tcpDst )
1651 if setEthSrc:
1652 cmd += " --setEthSrc " + str( setEthSrc )
1653 if setEthDst:
1654 cmd += " --setEthDst " + str( setEthDst )
1655 if vlanId:
1656 cmd += " -v " + str( vlanId )
1657 if setVlan:
1658 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001659 if partial:
1660 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001661 if encap:
1662 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001663
1664 # Check whether the user appended the port
1665 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001666
kelvin-onlabb9408212015-04-01 13:34:04 -07001667 if "/" in ingressDevice:
1668 cmd += " " + str( ingressDevice )
1669 else:
1670 if not portIngress:
1671 main.log.error( "You must specify " +
1672 "the Ingress port" )
1673 return main.FALSE
1674
1675 cmd += " " +\
1676 str( ingressDevice ) + "/" +\
1677 str( portIngress )
1678
1679 if portEgressList is None:
1680 for egressDevice in egressDeviceList:
1681 if "/" in egressDevice:
1682 cmd += " " + str( egressDevice )
1683 else:
1684 main.log.error( "You must specify " +
1685 "the egress port" )
1686 # TODO: perhaps more meaningful return
1687 return main.FALSE
1688 else:
1689 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001690 for egressDevice, portEgress in zip( egressDeviceList,
1691 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001692 cmd += " " + \
1693 str( egressDevice ) + "/" +\
1694 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001695 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001696 main.log.error( "Device list and port list does not " +
1697 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001698 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001699 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001700 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001701 # If error, return error message
1702 if re.search( "Error", handle ):
1703 main.log.error( "Error in adding singlepoint-to-multipoint " +
1704 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001705 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001706 else:
1707 match = re.search('id=0x([\da-f]+),', handle)
1708 if match:
1709 return match.group()[3:-1]
1710 else:
1711 main.log.error( "Error, intent ID not found" )
1712 return None
Jon Hallc6793552016-01-19 14:18:37 -08001713 except AssertionError:
1714 main.log.exception( "" )
1715 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001716 except TypeError:
1717 main.log.exception( self.name + ": Object not as expected" )
1718 return None
shahshreyad0c80432014-12-04 16:56:05 -08001719 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001720 main.log.error( self.name + ": EOF exception found" )
1721 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001722 main.cleanup()
1723 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001724 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001725 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001726 main.cleanup()
1727 main.exit()
1728
Hari Krishna9e232602015-04-13 17:29:08 -07001729 def addMplsIntent(
1730 self,
1731 ingressDevice,
1732 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001733 ingressPort="",
1734 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001735 ethType="",
1736 ethSrc="",
1737 ethDst="",
1738 bandwidth="",
1739 lambdaAlloc=False,
1740 ipProto="",
1741 ipSrc="",
1742 ipDst="",
1743 tcpSrc="",
1744 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001745 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001746 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001747 priority=""):
1748 """
1749 Required:
1750 * ingressDevice: device id of ingress device
1751 * egressDevice: device id of egress device
1752 Optional:
1753 * ethType: specify ethType
1754 * ethSrc: specify ethSrc ( i.e. src mac addr )
1755 * ethDst: specify ethDst ( i.e. dst mac addr )
1756 * bandwidth: specify bandwidth capacity of link
1757 * lambdaAlloc: if True, intent will allocate lambda
1758 for the specified intent
1759 * ipProto: specify ip protocol
1760 * ipSrc: specify ip source address
1761 * ipDst: specify ip destination address
1762 * tcpSrc: specify tcp source port
1763 * tcpDst: specify tcp destination port
1764 * ingressLabel: Ingress MPLS label
1765 * egressLabel: Egress MPLS label
1766 Description:
1767 Adds MPLS intent by
1768 specifying device id's and optional fields
1769 Returns:
1770 A string of the intent id or None on error
1771
1772 NOTE: This function may change depending on the
1773 options developers provide for MPLS
1774 intent via cli
1775 """
1776 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001777 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001778
Jeremy Songsterff553672016-05-12 17:06:23 -07001779 if ethType:
1780 cmd += " --ethType " + str( ethType )
1781 if ethSrc:
1782 cmd += " --ethSrc " + str( ethSrc )
1783 if ethDst:
1784 cmd += " --ethDst " + str( ethDst )
1785 if bandwidth:
1786 cmd += " --bandwidth " + str( bandwidth )
1787 if lambdaAlloc:
1788 cmd += " --lambda "
1789 if ipProto:
1790 cmd += " --ipProto " + str( ipProto )
1791 if ipSrc:
1792 cmd += " --ipSrc " + str( ipSrc )
1793 if ipDst:
1794 cmd += " --ipDst " + str( ipDst )
1795 if tcpSrc:
1796 cmd += " --tcpSrc " + str( tcpSrc )
1797 if tcpDst:
1798 cmd += " --tcpDst " + str( tcpDst )
1799 if ingressLabel:
1800 cmd += " --ingressLabel " + str( ingressLabel )
1801 if egressLabel:
1802 cmd += " --egressLabel " + str( egressLabel )
1803 if priority:
1804 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001805
1806 # Check whether the user appended the port
1807 # or provided it as an input
1808 if "/" in ingressDevice:
1809 cmd += " " + str( ingressDevice )
1810 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001811 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001812 main.log.error( "You must specify the ingress port" )
1813 return None
1814
1815 cmd += " " + \
1816 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001817 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001818
1819 if "/" in egressDevice:
1820 cmd += " " + str( egressDevice )
1821 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001822 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001823 main.log.error( "You must specify the egress port" )
1824 return None
1825
1826 cmd += " " +\
1827 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001828 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001829
1830 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001831 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001832 # If error, return error message
1833 if re.search( "Error", handle ):
1834 main.log.error( "Error in adding mpls intent" )
1835 return None
1836 else:
1837 # TODO: print out all the options in this message?
1838 main.log.info( "MPLS intent installed between " +
1839 str( ingressDevice ) + " and " +
1840 str( egressDevice ) )
1841 match = re.search('id=0x([\da-f]+),', handle)
1842 if match:
1843 return match.group()[3:-1]
1844 else:
1845 main.log.error( "Error, intent ID not found" )
1846 return None
Jon Hallc6793552016-01-19 14:18:37 -08001847 except AssertionError:
1848 main.log.exception( "" )
1849 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001850 except TypeError:
1851 main.log.exception( self.name + ": Object not as expected" )
1852 return None
1853 except pexpect.EOF:
1854 main.log.error( self.name + ": EOF exception found" )
1855 main.log.error( self.name + ": " + self.handle.before )
1856 main.cleanup()
1857 main.exit()
1858 except Exception:
1859 main.log.exception( self.name + ": Uncaught exception!" )
1860 main.cleanup()
1861 main.exit()
1862
Jon Hallefbd9792015-03-05 16:11:36 -08001863 def removeIntent( self, intentId, app='org.onosproject.cli',
1864 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001865 """
shahshreya1c818fc2015-02-26 13:44:08 -08001866 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001867 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001868 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001869 -p or --purge: Purge the intent from the store after removal
1870
Jon Halle3f39ff2015-01-13 11:50:53 -08001871 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001872 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001873 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001874 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001875 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001876 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001877 if purge:
1878 cmdStr += " -p"
1879 if sync:
1880 cmdStr += " -s"
1881
1882 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001883 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001884 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001885 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001886 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001887 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001888 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001889 # TODO: Should this be main.TRUE
1890 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001891 except AssertionError:
1892 main.log.exception( "" )
1893 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001894 except TypeError:
1895 main.log.exception( self.name + ": Object not as expected" )
1896 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001897 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001898 main.log.error( self.name + ": EOF exception found" )
1899 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001900 main.cleanup()
1901 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001902 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001903 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001904 main.cleanup()
1905 main.exit()
1906
YPZhangfebf7302016-05-24 16:45:56 -07001907 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001908 """
1909 Description:
1910 Remove all the intents
1911 Optional args:-
1912 -s or --sync: Waits for the removal before returning
1913 -p or --purge: Purge the intent from the store after removal
1914 Returns:
1915 Returns main.TRUE if all intents are removed, otherwise returns
1916 main.FALSE; Returns None for exception
1917 """
1918 try:
1919 cmdStr = "remove-intent"
1920 if purge:
1921 cmdStr += " -p"
1922 if sync:
1923 cmdStr += " -s"
1924
1925 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001926 handle = self.sendline( cmdStr, timeout=timeout )
Jeremy42df2e72016-02-23 16:37:46 -08001927 assert "Command not found:" not in handle, handle
1928 if re.search( "Error", handle ):
1929 main.log.error( "Error in removing intent" )
1930 return main.FALSE
1931 else:
1932 return main.TRUE
1933 except AssertionError:
1934 main.log.exception( "" )
1935 return None
1936 except TypeError:
1937 main.log.exception( self.name + ": Object not as expected" )
1938 return None
1939 except pexpect.EOF:
1940 main.log.error( self.name + ": EOF exception found" )
1941 main.log.error( self.name + ": " + self.handle.before )
1942 main.cleanup()
1943 main.exit()
1944 except Exception:
1945 main.log.exception( self.name + ": Uncaught exception!" )
1946 main.cleanup()
1947 main.exit()
1948
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001949 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001950 """
1951 Purges all WITHDRAWN Intents
1952 """
1953 try:
1954 cmdStr = "purge-intents"
1955 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001956 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001957 if re.search( "Error", handle ):
1958 main.log.error( "Error in purging intents" )
1959 return main.FALSE
1960 else:
1961 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001962 except AssertionError:
1963 main.log.exception( "" )
1964 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001965 except TypeError:
1966 main.log.exception( self.name + ": Object not as expected" )
1967 return None
1968 except pexpect.EOF:
1969 main.log.error( self.name + ": EOF exception found" )
1970 main.log.error( self.name + ": " + self.handle.before )
1971 main.cleanup()
1972 main.exit()
1973 except Exception:
1974 main.log.exception( self.name + ": Uncaught exception!" )
1975 main.cleanup()
1976 main.exit()
1977
kelvin-onlabd3b64892015-01-20 13:26:24 -08001978 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001979 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001980 NOTE: This method should be used after installing application:
1981 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001982 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001983 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001984 Description:
1985 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001986 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001987 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001988 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001989 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001990 cmdStr += " -j"
1991 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001992 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001993 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001994 except AssertionError:
1995 main.log.exception( "" )
1996 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001997 except TypeError:
1998 main.log.exception( self.name + ": Object not as expected" )
1999 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002000 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002001 main.log.error( self.name + ": EOF exception found" )
2002 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08002003 main.cleanup()
2004 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002005 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002006 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08002007 main.cleanup()
2008 main.exit()
2009
pingping-lin54b03372015-08-13 14:43:10 -07002010 def ipv4RouteNumber( self ):
2011 """
2012 NOTE: This method should be used after installing application:
2013 onos-app-sdnip
2014 Description:
2015 Obtain the total IPv4 routes number in the system
2016 """
2017 try:
2018 cmdStr = "routes -s -j"
2019 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002020 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002021 jsonResult = json.loads( handle )
2022 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08002023 except AssertionError:
2024 main.log.exception( "" )
2025 return None
2026 except ( TypeError, ValueError ):
2027 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002028 return None
2029 except pexpect.EOF:
2030 main.log.error( self.name + ": EOF exception found" )
2031 main.log.error( self.name + ": " + self.handle.before )
2032 main.cleanup()
2033 main.exit()
2034 except Exception:
2035 main.log.exception( self.name + ": Uncaught exception!" )
2036 main.cleanup()
2037 main.exit()
2038
pingping-lin8244a3b2015-09-16 13:36:56 -07002039 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002040 """
andrewonlabe6745342014-10-17 14:29:13 -04002041 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002042 Obtain intents from the ONOS cli.
2043 Optional:
2044 * jsonFormat: Enable output formatting in json, default to True
2045 * summary: Whether only output the intent summary, defaults to False
2046 * type: Only output a certain type of intent. This options is valid
2047 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002048 """
andrewonlabe6745342014-10-17 14:29:13 -04002049 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002050 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002051 if summary:
2052 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002053 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002054 cmdStr += " -j"
2055 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002056 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002057 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002058 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002059 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002060 else:
Jon Hallff566d52016-01-15 14:45:36 -08002061 intentType = ""
2062 # IF we want the summary of a specific intent type
2063 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002064 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002065 if intentType in jsonResult.keys():
2066 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002067 else:
Jon Hallff566d52016-01-15 14:45:36 -08002068 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002069 return handle
2070 else:
2071 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002072 except AssertionError:
2073 main.log.exception( "" )
2074 return None
2075 except ( TypeError, ValueError ):
2076 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002077 return None
2078 except pexpect.EOF:
2079 main.log.error( self.name + ": EOF exception found" )
2080 main.log.error( self.name + ": " + self.handle.before )
2081 main.cleanup()
2082 main.exit()
2083 except Exception:
2084 main.log.exception( self.name + ": Uncaught exception!" )
2085 main.cleanup()
2086 main.exit()
2087
kelvin-onlab54400a92015-02-26 18:05:51 -08002088 def getIntentState(self, intentsId, intentsJson=None):
2089 """
You Wangfdcbfc42016-05-16 12:16:53 -07002090 Description:
2091 Gets intent state. Accepts a single intent ID (string type) or a
2092 list of intent IDs.
2093 Parameters:
2094 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002095 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002096 Returns:
2097 Returns the state (string type) of the ID if a single intent ID is
2098 accepted.
2099 Returns a list of dictionaries if a list of intent IDs is accepted,
2100 and each dictionary maps 'id' to the Intent ID and 'state' to
2101 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002102 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002103 try:
2104 state = "State is Undefined"
2105 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002106 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002107 else:
Jon Hallc6793552016-01-19 14:18:37 -08002108 rawJson = intentsJson
2109 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002110 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002111 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002112 if intentsId == intent[ 'id' ]:
2113 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002114 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002115 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2116 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002117 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002118 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002119 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002120 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002121 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002122 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002123 if intentsId[ i ] == intents[ 'id' ]:
2124 stateDict[ 'state' ] = intents[ 'state' ]
2125 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002126 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002127 break
Jon Hallefbd9792015-03-05 16:11:36 -08002128 if len( intentsId ) != len( dictList ):
2129 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002130 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002131 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002132 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002133 return None
Jon Hallc6793552016-01-19 14:18:37 -08002134 except ( TypeError, ValueError ):
2135 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002136 return None
2137 except pexpect.EOF:
2138 main.log.error( self.name + ": EOF exception found" )
2139 main.log.error( self.name + ": " + self.handle.before )
2140 main.cleanup()
2141 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002142 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002143 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002144 main.cleanup()
2145 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002146
kelvin-onlabf512e942015-06-08 19:42:59 -07002147 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002148 """
2149 Description:
2150 Check intents state
2151 Required:
2152 intentsId - List of intents ID to be checked
2153 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002154 expectedState - Check the expected state(s) of each intents
2155 state in the list.
2156 *NOTE: You can pass in a list of expected state,
2157 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002158 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002159 Returns main.TRUE only if all intent are the same as expected states
2160 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002161 """
2162 try:
2163 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002164 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002165 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002166 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002167 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002168 "getting intents state" )
2169 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002170
2171 if isinstance( expectedState, types.StringType ):
2172 for intents in intentsDict:
2173 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002174 main.log.debug( self.name + " : Intent ID - " +
2175 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002176 " actual state = " +
2177 intents.get( 'state' )
2178 + " does not equal expected state = "
2179 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002180 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002181
2182 elif isinstance( expectedState, types.ListType ):
2183 for intents in intentsDict:
2184 if not any( state == intents.get( 'state' ) for state in
2185 expectedState ):
2186 main.log.debug( self.name + " : Intent ID - " +
2187 intents.get( 'id' ) +
2188 " actual state = " +
2189 intents.get( 'state' ) +
2190 " does not equal expected states = "
2191 + str( expectedState ) )
2192 returnValue = main.FALSE
2193
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002194 if returnValue == main.TRUE:
2195 main.log.info( self.name + ": All " +
2196 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002197 " intents are in " + str( expectedState ) +
2198 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002199 return returnValue
2200 except TypeError:
2201 main.log.exception( self.name + ": Object not as expected" )
2202 return None
2203 except pexpect.EOF:
2204 main.log.error( self.name + ": EOF exception found" )
2205 main.log.error( self.name + ": " + self.handle.before )
2206 main.cleanup()
2207 main.exit()
2208 except Exception:
2209 main.log.exception( self.name + ": Uncaught exception!" )
2210 main.cleanup()
2211 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002212
You Wang66518af2016-05-16 15:32:59 -07002213 def compareIntent( self, intentDict ):
2214 """
2215 Description:
2216 Compare the intent ids and states provided in the argument with all intents in ONOS
2217 Return:
2218 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2219 Arguments:
2220 intentDict: a dictionary which maps intent ids to intent states
2221 """
2222 try:
2223 intentsRaw = self.intents()
2224 intentsJson = json.loads( intentsRaw )
2225 intentDictONOS = {}
2226 for intent in intentsJson:
2227 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002228 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002229 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002230 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002231 str( len( intentDict ) ) + " expected and " +
2232 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002233 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002234 for intentID in intentDict.keys():
2235 if not intentID in intentDictONOS.keys():
2236 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2237 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002238 else:
2239 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2240 main.log.debug( self.name + ": intent ID - " + intentID +
2241 " expected state is " + intentDict[ intentID ] +
2242 " but actual state is " + intentDictONOS[ intentID ] )
2243 returnValue = main.FALSE
2244 intentDictONOS.pop( intentID )
2245 if len( intentDictONOS ) > 0:
2246 returnValue = main.FALSE
2247 for intentID in intentDictONOS.keys():
2248 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002249 if returnValue == main.TRUE:
2250 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2251 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002252 except KeyError:
2253 main.log.exception( self.name + ": KeyError exception found" )
2254 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002255 except ( TypeError, ValueError ):
2256 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002257 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002258 except pexpect.EOF:
2259 main.log.error( self.name + ": EOF exception found" )
2260 main.log.error( self.name + ": " + self.handle.before )
2261 main.cleanup()
2262 main.exit()
2263 except Exception:
2264 main.log.exception( self.name + ": Uncaught exception!" )
2265 main.cleanup()
2266 main.exit()
2267
YPZhang14a4aa92016-07-15 13:37:15 -07002268 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002269 """
2270 Description:
2271 Check the number of installed intents.
2272 Optional:
2273 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002274 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002275 Return:
2276 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2277 , otherwise, returns main.FALSE.
2278 """
2279
2280 try:
2281 cmd = "intents -s -j"
2282
2283 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002284 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
GlennRCed771242016-01-13 17:02:47 -08002285 if response == None:
YPZhang0584d432016-06-21 15:20:13 -07002286 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002287 response = json.loads( response )
2288
2289 # get total and installed number, see if they are match
2290 allState = response.get( 'all' )
2291 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002292 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002293 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002294 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002295 return main.FALSE
2296
Jon Hallc6793552016-01-19 14:18:37 -08002297 except ( TypeError, ValueError ):
2298 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002299 return None
2300 except pexpect.EOF:
2301 main.log.error( self.name + ": EOF exception found" )
2302 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002303 if noExit:
2304 return main.FALSE
2305 else:
2306 main.cleanup()
2307 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002308 except Exception:
2309 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002310 if noExit:
2311 return main.FALSE
2312 else:
2313 main.cleanup()
2314 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002315 except pexpect.TIMEOUT:
2316 main.log.error( self.name + ": ONOS timeout" )
2317 return None
GlennRCed771242016-01-13 17:02:47 -08002318
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002319 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002320 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002321 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002322 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002323 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002324 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002325 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002326 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002327 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002328 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002329 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002330 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002331 if noCore:
2332 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002333 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002334 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002335 assert "Command not found:" not in handle, handle
2336 if re.search( "Error:", handle ):
2337 main.log.error( self.name + ": flows() response: " +
2338 str( handle ) )
2339 return handle
2340 except AssertionError:
2341 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002342 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002343 except TypeError:
2344 main.log.exception( self.name + ": Object not as expected" )
2345 return None
Jon Hallc6793552016-01-19 14:18:37 -08002346 except pexpect.TIMEOUT:
2347 main.log.error( self.name + ": ONOS timeout" )
2348 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002349 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002350 main.log.error( self.name + ": EOF exception found" )
2351 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002352 main.cleanup()
2353 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002354 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002355 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002356 main.cleanup()
2357 main.exit()
2358
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002359 def checkFlowCount(self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002360 count = self.getTotalFlowsNum( timeout=timeout )
2361 count = int (count) if count else 0
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002362 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002363
YPZhangebf9eb52016-05-12 15:20:24 -07002364 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002365 """
2366 Description:
GlennRCed771242016-01-13 17:02:47 -08002367 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002368 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2369 if the count of those states is 0, which means all current flows
2370 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002371 Optional:
GlennRCed771242016-01-13 17:02:47 -08002372 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002373 Return:
2374 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002375 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002376 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002377 """
2378 try:
GlennRCed771242016-01-13 17:02:47 -08002379 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2380 checkedStates = []
2381 statesCount = [0, 0, 0, 0]
2382 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002383 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002384 if rawFlows:
2385 # if we didn't get flows or flows function return None, we should return
2386 # main.Flase
2387 checkedStates.append( json.loads( rawFlows ) )
2388 else:
2389 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002390 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002391 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002392 try:
2393 statesCount[i] += int( c.get( "flowCount" ) )
2394 except TypeError:
2395 main.log.exception( "Json object not as expected" )
2396 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002397
GlennRCed771242016-01-13 17:02:47 -08002398 # We want to count PENDING_ADD if isPENDING is true
2399 if isPENDING:
2400 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2401 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002402 else:
GlennRCed771242016-01-13 17:02:47 -08002403 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2404 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002405 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002406 except ( TypeError, ValueError ):
2407 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002408 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002409
YPZhang240842b2016-05-17 12:00:50 -07002410 except AssertionError:
2411 main.log.exception( "" )
2412 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002413 except pexpect.EOF:
2414 main.log.error( self.name + ": EOF exception found" )
2415 main.log.error( self.name + ": " + self.handle.before )
2416 main.cleanup()
2417 main.exit()
2418 except Exception:
2419 main.log.exception( self.name + ": Uncaught exception!" )
2420 main.cleanup()
2421 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002422 except pexpect.TIMEOUT:
2423 main.log.error( self.name + ": ONOS timeout" )
2424 return None
2425
kelvin-onlab4df89f22015-04-13 18:10:23 -07002426
GlennRCed771242016-01-13 17:02:47 -08002427 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002428 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002429 """
andrewonlab87852b02014-11-19 18:44:19 -05002430 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002431 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002432 a specific point-to-point intent definition
2433 Required:
GlennRCed771242016-01-13 17:02:47 -08002434 * ingress: specify source dpid
2435 * egress: specify destination dpid
2436 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002437 Optional:
GlennRCed771242016-01-13 17:02:47 -08002438 * offset: the keyOffset is where the next batch of intents
2439 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002440 * noExit: If set to True, TestON will not exit if any error when issus command
2441 * getResponse: If set to True, function will return ONOS response.
2442
GlennRCed771242016-01-13 17:02:47 -08002443 Returns: If failed to push test intents, it will returen None,
2444 if successful, return true.
2445 Timeout expection will return None,
2446 TypeError will return false
2447 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002448 """
andrewonlab87852b02014-11-19 18:44:19 -05002449 try:
GlennRCed771242016-01-13 17:02:47 -08002450 if background:
2451 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002452 else:
GlennRCed771242016-01-13 17:02:47 -08002453 back = ""
2454 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002455 ingress,
2456 egress,
2457 batchSize,
2458 offset,
2459 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002460 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002461 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002462 main.log.info( response )
2463 if response == None:
2464 return None
2465
YPZhangb34b7e12016-06-14 14:28:19 -07002466 if getResponse:
2467 return response
2468
GlennRCed771242016-01-13 17:02:47 -08002469 # TODO: We should handle if there is failure in installation
2470 return main.TRUE
2471
Jon Hallc6793552016-01-19 14:18:37 -08002472 except AssertionError:
2473 main.log.exception( "" )
2474 return None
GlennRCed771242016-01-13 17:02:47 -08002475 except pexpect.TIMEOUT:
2476 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002477 return None
andrewonlab87852b02014-11-19 18:44:19 -05002478 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002479 main.log.error( self.name + ": EOF exception found" )
2480 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002481 main.cleanup()
2482 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002483 except TypeError:
2484 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002485 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002486 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002487 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002488 main.cleanup()
2489 main.exit()
2490
YPZhangebf9eb52016-05-12 15:20:24 -07002491 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002492 """
2493 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002494 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002495 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002496 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002497 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002498 """
YPZhange3109a72016-02-02 11:25:37 -08002499
YPZhangb5d3f832016-01-23 22:54:26 -08002500 try:
YPZhange3109a72016-02-02 11:25:37 -08002501 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002502 cmd = "flows -c added"
2503 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2504 if rawFlows:
2505 rawFlows = rawFlows.split("\n")
YPZhange3109a72016-02-02 11:25:37 -08002506 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002507 for l in rawFlows:
2508 totalFlows += int(l.split("Count=")[1])
2509 else:
2510 main.log.error("Response not as expected!")
2511 return None
2512 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002513
You Wangd3cb2ce2016-05-16 14:01:24 -07002514 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002515 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002516 return None
2517 except pexpect.EOF:
2518 main.log.error( self.name + ": EOF exception found" )
2519 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002520 if not noExit:
2521 main.cleanup()
2522 main.exit()
2523 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002524 except Exception:
2525 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002526 if not noExit:
2527 main.cleanup()
2528 main.exit()
2529 return None
YPZhangebf9eb52016-05-12 15:20:24 -07002530 except pexpect.TIMEOUT:
2531 main.log.error( self.name + ": ONOS timeout" )
2532 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002533
YPZhang14a4aa92016-07-15 13:37:15 -07002534 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002535 """
2536 Description:
2537 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002538 Optional:
2539 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002540 Return:
2541 The number of intents
2542 """
2543 try:
2544 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002545 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhangb5d3f832016-01-23 22:54:26 -08002546 if response == None:
2547 return -1
2548 response = json.loads( response )
2549 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002550 except ( TypeError, ValueError ):
2551 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002552 return None
2553 except pexpect.EOF:
2554 main.log.error( self.name + ": EOF exception found" )
2555 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002556 if noExit:
2557 return -1
2558 else:
2559 main.cleanup()
2560 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002561 except Exception:
2562 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002563 if noExit:
2564 return -1
2565 else:
2566 main.cleanup()
2567 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002568
kelvin-onlabd3b64892015-01-20 13:26:24 -08002569 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002570 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002571 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002572 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002573 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002574 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002575 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002576 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002577 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002578 cmdStr += " -j"
2579 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002580 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002581 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002582 except AssertionError:
2583 main.log.exception( "" )
2584 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002585 except TypeError:
2586 main.log.exception( self.name + ": Object not as expected" )
2587 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002588 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002589 main.log.error( self.name + ": EOF exception found" )
2590 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002591 main.cleanup()
2592 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002593 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002594 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002595 main.cleanup()
2596 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002597
kelvin-onlabd3b64892015-01-20 13:26:24 -08002598 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002599 """
2600 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002601 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002602 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002603 """
andrewonlab867212a2014-10-22 20:13:38 -04002604 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002605 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002606 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002607 cmdStr += " -j"
2608 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002609 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002610 if handle:
2611 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002612 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002613 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002614 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002615 else:
2616 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002617 except AssertionError:
2618 main.log.exception( "" )
2619 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002620 except TypeError:
2621 main.log.exception( self.name + ": Object not as expected" )
2622 return None
andrewonlab867212a2014-10-22 20:13:38 -04002623 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002624 main.log.error( self.name + ": EOF exception found" )
2625 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002626 main.cleanup()
2627 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002628 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002629 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002630 main.cleanup()
2631 main.exit()
2632
kelvin8ec71442015-01-15 16:57:00 -08002633 # Wrapper functions ****************
2634 # Wrapper functions use existing driver
2635 # functions and extends their use case.
2636 # For example, we may use the output of
2637 # a normal driver function, and parse it
2638 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002639
kelvin-onlabd3b64892015-01-20 13:26:24 -08002640 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002641 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002642 Description:
2643 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002644 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002645 try:
kelvin8ec71442015-01-15 16:57:00 -08002646 # Obtain output of intents function
Jon Hall6021e062017-01-30 11:10:06 -08002647 intentsStr = self.intents(jsonFormat=True)
2648 # Convert to a dictionary
2649 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002650 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002651 for intent in intents:
2652 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002653 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002654 except TypeError:
2655 main.log.exception( self.name + ": Object not as expected" )
2656 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002657 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002658 main.log.error( self.name + ": EOF exception found" )
2659 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002660 main.cleanup()
2661 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002662 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002663 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002664 main.cleanup()
2665 main.exit()
2666
You Wang3c276252016-09-21 15:21:36 -07002667 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002668 """
2669 Determine the number of flow rules for the given device id that are
2670 in the added state
You Wang3c276252016-09-21 15:21:36 -07002671 Params:
2672 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002673 """
2674 try:
You Wang3c276252016-09-21 15:21:36 -07002675 if core:
2676 cmdStr = "flows any " + str( deviceId ) + " | " +\
2677 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2678 else:
2679 cmdStr = "flows any " + str( deviceId ) + " | " +\
2680 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002681 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002682 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002683 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002684 except AssertionError:
2685 main.log.exception( "" )
2686 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002687 except pexpect.EOF:
2688 main.log.error( self.name + ": EOF exception found" )
2689 main.log.error( self.name + ": " + self.handle.before )
2690 main.cleanup()
2691 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002692 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002693 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002694 main.cleanup()
2695 main.exit()
2696
kelvin-onlabd3b64892015-01-20 13:26:24 -08002697 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002698 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002699 Use 'devices' function to obtain list of all devices
2700 and parse the result to obtain a list of all device
2701 id's. Returns this list. Returns empty list if no
2702 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002703 List is ordered sequentially
2704
andrewonlab3e15ead2014-10-15 14:21:34 -04002705 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002706 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002707 the ids. By obtaining the list of device ids on the fly,
2708 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002709 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002710 try:
kelvin8ec71442015-01-15 16:57:00 -08002711 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002712 devicesStr = self.devices( jsonFormat=False )
2713 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002714
kelvin-onlabd3b64892015-01-20 13:26:24 -08002715 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002716 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002717 return idList
kelvin8ec71442015-01-15 16:57:00 -08002718
2719 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002720 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002721 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002722 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002723 # Split list further into arguments before and after string
2724 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002725 # append to idList
2726 for arg in tempList:
2727 idList.append( arg.split( "id=" )[ 1 ] )
2728 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002729
Jon Halld4d4b372015-01-28 16:02:41 -08002730 except TypeError:
2731 main.log.exception( self.name + ": Object not as expected" )
2732 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002733 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002734 main.log.error( self.name + ": EOF exception found" )
2735 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002736 main.cleanup()
2737 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002738 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002739 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002740 main.cleanup()
2741 main.exit()
2742
kelvin-onlabd3b64892015-01-20 13:26:24 -08002743 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002744 """
andrewonlab7c211572014-10-15 16:45:20 -04002745 Uses 'nodes' function to obtain list of all nodes
2746 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002747 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002748 Returns:
2749 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002750 """
andrewonlab7c211572014-10-15 16:45:20 -04002751 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002752 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002753 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002754 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002755 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002756 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002757 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002758 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002759 nodesJson = json.loads( nodesStr )
2760 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002761 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002762 except ( TypeError, ValueError ):
2763 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002764 return None
andrewonlab7c211572014-10-15 16:45:20 -04002765 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002766 main.log.error( self.name + ": EOF exception found" )
2767 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002768 main.cleanup()
2769 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002770 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002771 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002772 main.cleanup()
2773 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002774
kelvin-onlabd3b64892015-01-20 13:26:24 -08002775 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002776 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002777 Return the first device from the devices api whose 'id' contains 'dpid'
2778 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002779 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002780 try:
kelvin8ec71442015-01-15 16:57:00 -08002781 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002782 return None
2783 else:
kelvin8ec71442015-01-15 16:57:00 -08002784 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002785 rawDevices = self.devices()
2786 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002787 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002788 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002789 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2790 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002791 return device
2792 return None
Jon Hallc6793552016-01-19 14:18:37 -08002793 except ( TypeError, ValueError ):
2794 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002795 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002796 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002797 main.log.error( self.name + ": EOF exception found" )
2798 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002799 main.cleanup()
2800 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002801 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002802 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002803 main.cleanup()
2804 main.exit()
2805
You Wang24139872016-05-03 11:48:47 -07002806 def getTopology( self, topologyOutput ):
2807 """
2808 Definition:
2809 Loads a json topology output
2810 Return:
2811 topology = current ONOS topology
2812 """
2813 import json
2814 try:
2815 # either onos:topology or 'topology' will work in CLI
2816 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002817 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002818 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002819 except ( TypeError, ValueError ):
2820 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2821 return None
You Wang24139872016-05-03 11:48:47 -07002822 except pexpect.EOF:
2823 main.log.error( self.name + ": EOF exception found" )
2824 main.log.error( self.name + ": " + self.handle.before )
2825 main.cleanup()
2826 main.exit()
2827 except Exception:
2828 main.log.exception( self.name + ": Uncaught exception!" )
2829 main.cleanup()
2830 main.exit()
2831
Flavio Castro82ee2f62016-06-07 15:04:12 -07002832 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002833 """
Jon Hallefbd9792015-03-05 16:11:36 -08002834 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002835 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002836 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002837
Flavio Castro82ee2f62016-06-07 15:04:12 -07002838 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002839 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002840 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002841 logLevel = level to log to.
2842 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002843
Jon Hallefbd9792015-03-05 16:11:36 -08002844 Returns: main.TRUE if the number of switches and links are correct,
2845 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002846 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002847 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002848 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002849 try:
You Wang13310252016-07-31 10:56:14 -07002850 summary = self.summary()
2851 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002852 except ( TypeError, ValueError ):
2853 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2854 return main.ERROR
2855 try:
2856 topology = self.getTopology( self.topology() )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002857 if topology == {} or topology == None or summary == {} or summary == None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002858 return main.ERROR
2859 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002860 # Is the number of switches is what we expected
2861 devices = topology.get( 'devices', False )
2862 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002863 nodes = summary.get( 'nodes', False )
2864 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002865 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002866 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002867 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002868 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002869 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2870 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002871 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002872 output = output + "The number of links and switches match "\
2873 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002874 result = main.TRUE
2875 else:
You Wang24139872016-05-03 11:48:47 -07002876 output = output + \
2877 "The number of links and switches does not match " + \
2878 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002879 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002880 output = output + "\n ONOS sees %i devices" % int( devices )
2881 output = output + " (%i expected) " % int( numoswitch )
2882 output = output + "and %i links " % int( links )
2883 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002884 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002885 output = output + "and %i controllers " % int( nodes )
2886 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002887 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002888 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002889 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002890 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002891 else:
You Wang24139872016-05-03 11:48:47 -07002892 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002893 return result
Jon Hall42db6dc2014-10-24 19:03:48 -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 )
Jon Hall42db6dc2014-10-24 19:03:48 -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!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002901 main.cleanup()
2902 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002903
kelvin-onlabd3b64892015-01-20 13:26:24 -08002904 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002905 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002906 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002907 deviceId must be the id of a device as seen in the onos devices command
2908 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002909 role must be either master, standby, or none
2910
Jon Halle3f39ff2015-01-13 11:50:53 -08002911 Returns:
2912 main.TRUE or main.FALSE based on argument verification and
2913 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002914 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002915 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002916 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002917 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002918 cmdStr = "device-role " +\
2919 str( deviceId ) + " " +\
2920 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002921 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002922 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002923 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002924 if re.search( "Error", handle ):
2925 # end color output to escape any colours
2926 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002927 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002928 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002929 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002930 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002931 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002932 main.log.error( "Invalid 'role' given to device_role(). " +
2933 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002934 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002935 except AssertionError:
2936 main.log.exception( "" )
2937 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002938 except TypeError:
2939 main.log.exception( self.name + ": Object not as expected" )
2940 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002941 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002942 main.log.error( self.name + ": EOF exception found" )
2943 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002944 main.cleanup()
2945 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002946 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002947 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002948 main.cleanup()
2949 main.exit()
2950
kelvin-onlabd3b64892015-01-20 13:26:24 -08002951 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002952 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002953 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002954 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002955 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002956 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002957 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002958 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002959 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002960 cmdStr += " -j"
2961 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002962 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002963 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002964 except AssertionError:
2965 main.log.exception( "" )
2966 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002967 except TypeError:
2968 main.log.exception( self.name + ": Object not as expected" )
2969 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002970 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002971 main.log.error( self.name + ": EOF exception found" )
2972 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002973 main.cleanup()
2974 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002975 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002976 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002977 main.cleanup()
2978 main.exit()
2979
kelvin-onlabd3b64892015-01-20 13:26:24 -08002980 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002981 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002982 CLI command to get the current leader for the Election test application
2983 NOTE: Requires installation of the onos-app-election feature
2984 Returns: Node IP of the leader if one exists
2985 None if none exists
2986 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002987 """
Jon Hall94fd0472014-12-08 11:52:42 -08002988 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002989 cmdStr = "election-test-leader"
2990 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002991 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002992 # Leader
2993 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002994 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002995 nodeSearch = re.search( leaderPattern, response )
2996 if nodeSearch:
2997 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002998 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002999 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003000 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003001 # no leader
3002 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003003 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003004 nullSearch = re.search( nullPattern, response )
3005 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003006 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003007 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003008 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003009 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003010 main.log.error( "Error in electionTestLeader on " + self.name +
3011 ": " + "unexpected response" )
3012 main.log.error( repr( response ) )
3013 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003014 except AssertionError:
3015 main.log.exception( "" )
3016 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003017 except TypeError:
3018 main.log.exception( self.name + ": Object not as expected" )
3019 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003020 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003021 main.log.error( self.name + ": EOF exception found" )
3022 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003023 main.cleanup()
3024 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003025 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003026 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003027 main.cleanup()
3028 main.exit()
3029
kelvin-onlabd3b64892015-01-20 13:26:24 -08003030 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003031 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003032 CLI command to run for leadership of the Election test application.
3033 NOTE: Requires installation of the onos-app-election feature
3034 Returns: Main.TRUE on success
3035 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003036 """
Jon Hall94fd0472014-12-08 11:52:42 -08003037 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003038 cmdStr = "election-test-run"
3039 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003040 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003041 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003042 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003043 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003044 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003045 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003046 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003047 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003048 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003049 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003050 main.log.error( "Error in electionTestRun on " + self.name +
3051 ": " + "unexpected response" )
3052 main.log.error( repr( response ) )
3053 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003054 except AssertionError:
3055 main.log.exception( "" )
3056 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003057 except TypeError:
3058 main.log.exception( self.name + ": Object not as expected" )
3059 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003060 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003061 main.log.error( self.name + ": EOF exception found" )
3062 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003063 main.cleanup()
3064 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003065 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003066 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003067 main.cleanup()
3068 main.exit()
3069
kelvin-onlabd3b64892015-01-20 13:26:24 -08003070 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003071 """
Jon Hall94fd0472014-12-08 11:52:42 -08003072 * CLI command to withdraw the local node from leadership election for
3073 * the Election test application.
3074 #NOTE: Requires installation of the onos-app-election feature
3075 Returns: Main.TRUE on success
3076 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003077 """
Jon Hall94fd0472014-12-08 11:52:42 -08003078 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003079 cmdStr = "election-test-withdraw"
3080 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003081 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003082 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003083 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003084 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003085 if re.search( successPattern, response ):
3086 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003087 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003088 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003089 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003090 main.log.error( "Error in electionTestWithdraw on " +
3091 self.name + ": " + "unexpected response" )
3092 main.log.error( repr( response ) )
3093 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003094 except AssertionError:
3095 main.log.exception( "" )
3096 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003097 except TypeError:
3098 main.log.exception( self.name + ": Object not as expected" )
3099 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003100 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003101 main.log.error( self.name + ": EOF exception found" )
3102 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003103 main.cleanup()
3104 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003105 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003106 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003107 main.cleanup()
3108 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003109
kelvin8ec71442015-01-15 16:57:00 -08003110 def getDevicePortsEnabledCount( self, dpid ):
3111 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003112 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003113 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003114 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003115 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003116 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3117 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003118 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003119 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003120 if re.search( "No such device", output ):
3121 main.log.error( "Error in getting ports" )
3122 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003123 return output
Jon Hallc6793552016-01-19 14:18:37 -08003124 except AssertionError:
3125 main.log.exception( "" )
3126 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003127 except TypeError:
3128 main.log.exception( self.name + ": Object not as expected" )
3129 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003130 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003131 main.log.error( self.name + ": EOF exception found" )
3132 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003133 main.cleanup()
3134 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003135 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003136 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003137 main.cleanup()
3138 main.exit()
3139
kelvin8ec71442015-01-15 16:57:00 -08003140 def getDeviceLinksActiveCount( self, dpid ):
3141 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003142 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003143 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003144 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003145 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003146 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3147 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003148 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003149 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003150 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003151 main.log.error( "Error in getting ports " )
3152 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003153 return output
Jon Hallc6793552016-01-19 14:18:37 -08003154 except AssertionError:
3155 main.log.exception( "" )
3156 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003157 except TypeError:
3158 main.log.exception( self.name + ": Object not as expected" )
3159 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003160 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003161 main.log.error( self.name + ": EOF exception found" )
3162 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003163 main.cleanup()
3164 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003165 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003166 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003167 main.cleanup()
3168 main.exit()
3169
kelvin8ec71442015-01-15 16:57:00 -08003170 def getAllIntentIds( self ):
3171 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003172 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003173 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003174 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003175 cmdStr = "onos:intents | grep id="
3176 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003177 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003178 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003179 if re.search( "Error", output ):
3180 main.log.error( "Error in getting ports" )
3181 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003182 return output
Jon Hallc6793552016-01-19 14:18:37 -08003183 except AssertionError:
3184 main.log.exception( "" )
3185 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003186 except TypeError:
3187 main.log.exception( self.name + ": Object not as expected" )
3188 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003189 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003190 main.log.error( self.name + ": EOF exception found" )
3191 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003192 main.cleanup()
3193 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003194 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003195 main.log.exception( self.name + ": Uncaught exception!" )
3196 main.cleanup()
3197 main.exit()
3198
Jon Hall73509952015-02-24 16:42:56 -08003199 def intentSummary( self ):
3200 """
Jon Hallefbd9792015-03-05 16:11:36 -08003201 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003202 """
3203 try:
3204 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003205 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003206 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003207 states.append( intent.get( 'state', None ) )
3208 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003209 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003210 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003211 except ( TypeError, ValueError ):
3212 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003213 return None
3214 except pexpect.EOF:
3215 main.log.error( self.name + ": EOF exception found" )
3216 main.log.error( self.name + ": " + self.handle.before )
3217 main.cleanup()
3218 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003219 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003220 main.log.exception( self.name + ": Uncaught exception!" )
3221 main.cleanup()
3222 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003223
Jon Hall61282e32015-03-19 11:34:11 -07003224 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003225 """
3226 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003227 Optional argument:
3228 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003229 """
Jon Hall63604932015-02-26 17:09:50 -08003230 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003231 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003232 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003233 cmdStr += " -j"
3234 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003235 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003236 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003237 return output
Jon Hallc6793552016-01-19 14:18:37 -08003238 except AssertionError:
3239 main.log.exception( "" )
3240 return None
Jon Hall63604932015-02-26 17:09:50 -08003241 except TypeError:
3242 main.log.exception( self.name + ": Object not as expected" )
3243 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003244 except pexpect.EOF:
3245 main.log.error( self.name + ": EOF exception found" )
3246 main.log.error( self.name + ": " + self.handle.before )
3247 main.cleanup()
3248 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003249 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003250 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003251 main.cleanup()
3252 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003253
acsmarsa4a4d1e2015-07-10 16:01:24 -07003254 def leaderCandidates( self, jsonFormat=True ):
3255 """
3256 Returns the output of the leaders -c command.
3257 Optional argument:
3258 * jsonFormat - boolean indicating if you want output in json
3259 """
3260 try:
3261 cmdStr = "onos:leaders -c"
3262 if jsonFormat:
3263 cmdStr += " -j"
3264 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003265 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003266 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003267 return output
Jon Hallc6793552016-01-19 14:18:37 -08003268 except AssertionError:
3269 main.log.exception( "" )
3270 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003271 except TypeError:
3272 main.log.exception( self.name + ": Object not as expected" )
3273 return None
3274 except pexpect.EOF:
3275 main.log.error( self.name + ": EOF exception found" )
3276 main.log.error( self.name + ": " + self.handle.before )
3277 main.cleanup()
3278 main.exit()
3279 except Exception:
3280 main.log.exception( self.name + ": Uncaught exception!" )
3281 main.cleanup()
3282 main.exit()
3283
Jon Hallc6793552016-01-19 14:18:37 -08003284 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003285 """
3286 Returns a list in format [leader,candidate1,candidate2,...] for a given
3287 topic parameter and an empty list if the topic doesn't exist
3288 If no leader is elected leader in the returned list will be "none"
3289 Returns None if there is a type error processing the json object
3290 """
3291 try:
Jon Hall6e709752016-02-01 13:38:46 -08003292 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003293 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003294 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003295 assert "Command not found:" not in rawOutput, rawOutput
3296 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003297 results = []
3298 for dict in output:
3299 if dict["topic"] == topic:
3300 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003301 candidates = re.split( ", ", dict["candidates"][1:-1] )
3302 results.append( leader )
3303 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003304 return results
Jon Hallc6793552016-01-19 14:18:37 -08003305 except AssertionError:
3306 main.log.exception( "" )
3307 return None
3308 except ( TypeError, ValueError ):
3309 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003310 return None
3311 except pexpect.EOF:
3312 main.log.error( self.name + ": EOF exception found" )
3313 main.log.error( self.name + ": " + self.handle.before )
3314 main.cleanup()
3315 main.exit()
3316 except Exception:
3317 main.log.exception( self.name + ": Uncaught exception!" )
3318 main.cleanup()
3319 main.exit()
3320
Jon Hall61282e32015-03-19 11:34:11 -07003321 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003322 """
3323 Returns the output of the intent Pending map.
3324 """
Jon Hall63604932015-02-26 17:09:50 -08003325 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003326 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003327 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003328 cmdStr += " -j"
3329 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003330 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003331 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003332 return output
Jon Hallc6793552016-01-19 14:18:37 -08003333 except AssertionError:
3334 main.log.exception( "" )
3335 return None
Jon Hall63604932015-02-26 17:09:50 -08003336 except TypeError:
3337 main.log.exception( self.name + ": Object not as expected" )
3338 return None
3339 except pexpect.EOF:
3340 main.log.error( self.name + ": EOF exception found" )
3341 main.log.error( self.name + ": " + self.handle.before )
3342 main.cleanup()
3343 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003344 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003345 main.log.exception( self.name + ": Uncaught exception!" )
3346 main.cleanup()
3347 main.exit()
3348
Jon Hall2c8959e2016-12-16 12:17:34 -08003349 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003350 """
3351 Returns the output of the raft partitions command for ONOS.
3352 """
Jon Hall61282e32015-03-19 11:34:11 -07003353 # Sample JSON
3354 # {
3355 # "leader": "tcp://10.128.30.11:7238",
3356 # "members": [
3357 # "tcp://10.128.30.11:7238",
3358 # "tcp://10.128.30.17:7238",
3359 # "tcp://10.128.30.13:7238",
3360 # ],
3361 # "name": "p1",
3362 # "term": 3
3363 # },
Jon Hall63604932015-02-26 17:09:50 -08003364 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003365 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003366 if candidates:
3367 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003368 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003369 cmdStr += " -j"
3370 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003371 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003372 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003373 return output
Jon Hallc6793552016-01-19 14:18:37 -08003374 except AssertionError:
3375 main.log.exception( "" )
3376 return None
Jon Hall63604932015-02-26 17:09:50 -08003377 except TypeError:
3378 main.log.exception( self.name + ": Object not as expected" )
3379 return None
3380 except pexpect.EOF:
3381 main.log.error( self.name + ": EOF exception found" )
3382 main.log.error( self.name + ": " + self.handle.before )
3383 main.cleanup()
3384 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003385 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003386 main.log.exception( self.name + ": Uncaught exception!" )
3387 main.cleanup()
3388 main.exit()
3389
Jon Halle9f909e2016-09-23 10:43:12 -07003390 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003391 """
3392 Returns the output of the apps command for ONOS. This command lists
3393 information about installed ONOS applications
3394 """
3395 # Sample JSON object
3396 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3397 # "description":"ONOS OpenFlow protocol southbound providers",
3398 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3399 # "features":"[onos-openflow]","state":"ACTIVE"}]
3400 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003401 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003402 if summary:
3403 cmdStr += " -s"
3404 if active:
3405 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003406 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003407 cmdStr += " -j"
3408 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003409 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003410 assert "Command not found:" not in output, output
3411 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003412 return output
Jon Hallbe379602015-03-24 13:39:32 -07003413 # FIXME: look at specific exceptions/Errors
3414 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003415 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003416 return None
3417 except TypeError:
3418 main.log.exception( self.name + ": Object not as expected" )
3419 return None
3420 except pexpect.EOF:
3421 main.log.error( self.name + ": EOF exception found" )
3422 main.log.error( self.name + ": " + self.handle.before )
3423 main.cleanup()
3424 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003425 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003426 main.log.exception( self.name + ": Uncaught exception!" )
3427 main.cleanup()
3428 main.exit()
3429
Jon Hall146f1522015-03-24 15:33:24 -07003430 def appStatus( self, appName ):
3431 """
3432 Uses the onos:apps cli command to return the status of an application.
3433 Returns:
3434 "ACTIVE" - If app is installed and activated
3435 "INSTALLED" - If app is installed and deactivated
3436 "UNINSTALLED" - If app is not installed
3437 None - on error
3438 """
Jon Hall146f1522015-03-24 15:33:24 -07003439 try:
3440 if not isinstance( appName, types.StringType ):
3441 main.log.error( self.name + ".appStatus(): appName must be" +
3442 " a string" )
3443 return None
3444 output = self.apps( jsonFormat=True )
3445 appsJson = json.loads( output )
3446 state = None
3447 for app in appsJson:
3448 if appName == app.get('name'):
3449 state = app.get('state')
3450 break
3451 if state == "ACTIVE" or state == "INSTALLED":
3452 return state
3453 elif state is None:
3454 return "UNINSTALLED"
3455 elif state:
3456 main.log.error( "Unexpected state from 'onos:apps': " +
3457 str( state ) )
3458 return state
Jon Hallc6793552016-01-19 14:18:37 -08003459 except ( TypeError, ValueError ):
3460 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003461 return None
3462 except pexpect.EOF:
3463 main.log.error( self.name + ": EOF exception found" )
3464 main.log.error( self.name + ": " + self.handle.before )
3465 main.cleanup()
3466 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003467 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003468 main.log.exception( self.name + ": Uncaught exception!" )
3469 main.cleanup()
3470 main.exit()
3471
Jon Hallbe379602015-03-24 13:39:32 -07003472 def app( self, appName, option ):
3473 """
3474 Interacts with the app command for ONOS. This command manages
3475 application inventory.
3476 """
Jon Hallbe379602015-03-24 13:39:32 -07003477 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003478 # Validate argument types
3479 valid = True
3480 if not isinstance( appName, types.StringType ):
3481 main.log.error( self.name + ".app(): appName must be a " +
3482 "string" )
3483 valid = False
3484 if not isinstance( option, types.StringType ):
3485 main.log.error( self.name + ".app(): option must be a string" )
3486 valid = False
3487 if not valid:
3488 return main.FALSE
3489 # Validate Option
3490 option = option.lower()
3491 # NOTE: Install may become a valid option
3492 if option == "activate":
3493 pass
3494 elif option == "deactivate":
3495 pass
3496 elif option == "uninstall":
3497 pass
3498 else:
3499 # Invalid option
3500 main.log.error( "The ONOS app command argument only takes " +
3501 "the values: (activate|deactivate|uninstall)" +
3502 "; was given '" + option + "'")
3503 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003504 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003505 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003506 if "Error executing command" in output:
3507 main.log.error( "Error in processing onos:app command: " +
3508 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003509 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003510 elif "No such application" in output:
3511 main.log.error( "The application '" + appName +
3512 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003513 return main.FALSE
3514 elif "Command not found:" in output:
3515 main.log.error( "Error in processing onos:app command: " +
3516 str( output ) )
3517 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003518 elif "Unsupported command:" in output:
3519 main.log.error( "Incorrect command given to 'app': " +
3520 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003521 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003522 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003523 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003524 return main.TRUE
3525 except TypeError:
3526 main.log.exception( self.name + ": Object not as expected" )
3527 return main.ERROR
3528 except pexpect.EOF:
3529 main.log.error( self.name + ": EOF exception found" )
3530 main.log.error( self.name + ": " + self.handle.before )
3531 main.cleanup()
3532 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003533 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003534 main.log.exception( self.name + ": Uncaught exception!" )
3535 main.cleanup()
3536 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003537
Jon Hallbd16b922015-03-26 17:53:15 -07003538 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003539 """
3540 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003541 appName is the hierarchical app name, not the feature name
3542 If check is True, method will check the status of the app after the
3543 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003544 Returns main.TRUE if the command was successfully sent
3545 main.FALSE if the cli responded with an error or given
3546 incorrect input
3547 """
3548 try:
3549 if not isinstance( appName, types.StringType ):
3550 main.log.error( self.name + ".activateApp(): appName must be" +
3551 " a string" )
3552 return main.FALSE
3553 status = self.appStatus( appName )
3554 if status == "INSTALLED":
3555 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003556 if check and response == main.TRUE:
3557 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003558 status = self.appStatus( appName )
3559 if status == "ACTIVE":
3560 return main.TRUE
3561 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003562 main.log.debug( "The state of application " +
3563 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003564 time.sleep( 1 )
3565 return main.FALSE
3566 else: # not 'check' or command didn't succeed
3567 return response
Jon Hall146f1522015-03-24 15:33:24 -07003568 elif status == "ACTIVE":
3569 return main.TRUE
3570 elif status == "UNINSTALLED":
3571 main.log.error( self.name + ": Tried to activate the " +
3572 "application '" + appName + "' which is not " +
3573 "installed." )
3574 else:
3575 main.log.error( "Unexpected return value from appStatus: " +
3576 str( status ) )
3577 return main.ERROR
3578 except TypeError:
3579 main.log.exception( self.name + ": Object not as expected" )
3580 return main.ERROR
3581 except pexpect.EOF:
3582 main.log.error( self.name + ": EOF exception found" )
3583 main.log.error( self.name + ": " + self.handle.before )
3584 main.cleanup()
3585 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003586 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003587 main.log.exception( self.name + ": Uncaught exception!" )
3588 main.cleanup()
3589 main.exit()
3590
Jon Hallbd16b922015-03-26 17:53:15 -07003591 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003592 """
3593 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003594 appName is the hierarchical app name, not the feature name
3595 If check is True, method will check the status of the app after the
3596 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003597 Returns main.TRUE if the command was successfully sent
3598 main.FALSE if the cli responded with an error or given
3599 incorrect input
3600 """
3601 try:
3602 if not isinstance( appName, types.StringType ):
3603 main.log.error( self.name + ".deactivateApp(): appName must " +
3604 "be a string" )
3605 return main.FALSE
3606 status = self.appStatus( appName )
3607 if status == "INSTALLED":
3608 return main.TRUE
3609 elif status == "ACTIVE":
3610 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003611 if check and response == main.TRUE:
3612 for i in range(10): # try 10 times then give up
3613 status = self.appStatus( appName )
3614 if status == "INSTALLED":
3615 return main.TRUE
3616 else:
3617 time.sleep( 1 )
3618 return main.FALSE
3619 else: # not check or command didn't succeed
3620 return response
Jon Hall146f1522015-03-24 15:33:24 -07003621 elif status == "UNINSTALLED":
3622 main.log.warn( self.name + ": Tried to deactivate the " +
3623 "application '" + appName + "' which is not " +
3624 "installed." )
3625 return main.TRUE
3626 else:
3627 main.log.error( "Unexpected return value from appStatus: " +
3628 str( status ) )
3629 return main.ERROR
3630 except TypeError:
3631 main.log.exception( self.name + ": Object not as expected" )
3632 return main.ERROR
3633 except pexpect.EOF:
3634 main.log.error( self.name + ": EOF exception found" )
3635 main.log.error( self.name + ": " + self.handle.before )
3636 main.cleanup()
3637 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003638 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003639 main.log.exception( self.name + ": Uncaught exception!" )
3640 main.cleanup()
3641 main.exit()
3642
Jon Hallbd16b922015-03-26 17:53:15 -07003643 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003644 """
3645 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003646 appName is the hierarchical app name, not the feature name
3647 If check is True, method will check the status of the app after the
3648 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003649 Returns main.TRUE if the command was successfully sent
3650 main.FALSE if the cli responded with an error or given
3651 incorrect input
3652 """
3653 # TODO: check with Thomas about the state machine for apps
3654 try:
3655 if not isinstance( appName, types.StringType ):
3656 main.log.error( self.name + ".uninstallApp(): appName must " +
3657 "be a string" )
3658 return main.FALSE
3659 status = self.appStatus( appName )
3660 if status == "INSTALLED":
3661 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003662 if check and response == main.TRUE:
3663 for i in range(10): # try 10 times then give up
3664 status = self.appStatus( appName )
3665 if status == "UNINSTALLED":
3666 return main.TRUE
3667 else:
3668 time.sleep( 1 )
3669 return main.FALSE
3670 else: # not check or command didn't succeed
3671 return response
Jon Hall146f1522015-03-24 15:33:24 -07003672 elif status == "ACTIVE":
3673 main.log.warn( self.name + ": Tried to uninstall the " +
3674 "application '" + appName + "' which is " +
3675 "currently active." )
3676 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003677 if check and response == main.TRUE:
3678 for i in range(10): # try 10 times then give up
3679 status = self.appStatus( appName )
3680 if status == "UNINSTALLED":
3681 return main.TRUE
3682 else:
3683 time.sleep( 1 )
3684 return main.FALSE
3685 else: # not check or command didn't succeed
3686 return response
Jon Hall146f1522015-03-24 15:33:24 -07003687 elif status == "UNINSTALLED":
3688 return main.TRUE
3689 else:
3690 main.log.error( "Unexpected return value from appStatus: " +
3691 str( status ) )
3692 return main.ERROR
3693 except TypeError:
3694 main.log.exception( self.name + ": Object not as expected" )
3695 return main.ERROR
3696 except pexpect.EOF:
3697 main.log.error( self.name + ": EOF exception found" )
3698 main.log.error( self.name + ": " + self.handle.before )
3699 main.cleanup()
3700 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003701 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003702 main.log.exception( self.name + ": Uncaught exception!" )
3703 main.cleanup()
3704 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003705
3706 def appIDs( self, jsonFormat=True ):
3707 """
3708 Show the mappings between app id and app names given by the 'app-ids'
3709 cli command
3710 """
3711 try:
3712 cmdStr = "app-ids"
3713 if jsonFormat:
3714 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003715 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003716 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003717 assert "Command not found:" not in output, output
3718 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003719 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003720 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003721 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003722 return None
3723 except TypeError:
3724 main.log.exception( self.name + ": Object not as expected" )
3725 return None
3726 except pexpect.EOF:
3727 main.log.error( self.name + ": EOF exception found" )
3728 main.log.error( self.name + ": " + self.handle.before )
3729 main.cleanup()
3730 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003731 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003732 main.log.exception( self.name + ": Uncaught exception!" )
3733 main.cleanup()
3734 main.exit()
3735
3736 def appToIDCheck( self ):
3737 """
3738 This method will check that each application's ID listed in 'apps' is
3739 the same as the ID listed in 'app-ids'. The check will also check that
3740 there are no duplicate IDs issued. Note that an app ID should be
3741 a globaly unique numerical identifier for app/app-like features. Once
3742 an ID is registered, the ID is never freed up so that if an app is
3743 reinstalled it will have the same ID.
3744
3745 Returns: main.TRUE if the check passes and
3746 main.FALSE if the check fails or
3747 main.ERROR if there is some error in processing the test
3748 """
3749 try:
Jon Hall390696c2015-05-05 17:13:41 -07003750 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003751 rawJson = self.appIDs( jsonFormat=True )
3752 if rawJson:
3753 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003754 else:
Jon Hallc6793552016-01-19 14:18:37 -08003755 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003756 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003757 rawJson = self.apps( jsonFormat=True )
3758 if rawJson:
3759 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003760 else:
Jon Hallc6793552016-01-19 14:18:37 -08003761 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003762 bail = True
3763 if bail:
3764 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003765 result = main.TRUE
3766 for app in apps:
3767 appID = app.get( 'id' )
3768 if appID is None:
3769 main.log.error( "Error parsing app: " + str( app ) )
3770 result = main.FALSE
3771 appName = app.get( 'name' )
3772 if appName is None:
3773 main.log.error( "Error parsing app: " + str( app ) )
3774 result = main.FALSE
3775 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003776 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003777 # main.log.debug( "Comparing " + str( app ) + " to " +
3778 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003779 if not current: # if ids doesn't have this id
3780 result = main.FALSE
3781 main.log.error( "'app-ids' does not have the ID for " +
3782 str( appName ) + " that apps does." )
3783 elif len( current ) > 1:
3784 # there is more than one app with this ID
3785 result = main.FALSE
3786 # We will log this later in the method
3787 elif not current[0][ 'name' ] == appName:
3788 currentName = current[0][ 'name' ]
3789 result = main.FALSE
3790 main.log.error( "'app-ids' has " + str( currentName ) +
3791 " registered under id:" + str( appID ) +
3792 " but 'apps' has " + str( appName ) )
3793 else:
3794 pass # id and name match!
3795 # now make sure that app-ids has no duplicates
3796 idsList = []
3797 namesList = []
3798 for item in ids:
3799 idsList.append( item[ 'id' ] )
3800 namesList.append( item[ 'name' ] )
3801 if len( idsList ) != len( set( idsList ) ) or\
3802 len( namesList ) != len( set( namesList ) ):
3803 main.log.error( "'app-ids' has some duplicate entries: \n"
3804 + json.dumps( ids,
3805 sort_keys=True,
3806 indent=4,
3807 separators=( ',', ': ' ) ) )
3808 result = main.FALSE
3809 return result
Jon Hallc6793552016-01-19 14:18:37 -08003810 except ( TypeError, ValueError ):
3811 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003812 return main.ERROR
3813 except pexpect.EOF:
3814 main.log.error( self.name + ": EOF exception found" )
3815 main.log.error( self.name + ": " + self.handle.before )
3816 main.cleanup()
3817 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003818 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003819 main.log.exception( self.name + ": Uncaught exception!" )
3820 main.cleanup()
3821 main.exit()
3822
Jon Hallfb760a02015-04-13 15:35:03 -07003823 def getCfg( self, component=None, propName=None, short=False,
3824 jsonFormat=True ):
3825 """
3826 Get configuration settings from onos cli
3827 Optional arguments:
3828 component - Optionally only list configurations for a specific
3829 component. If None, all components with configurations
3830 are displayed. Case Sensitive string.
3831 propName - If component is specified, propName option will show
3832 only this specific configuration from that component.
3833 Case Sensitive string.
3834 jsonFormat - Returns output as json. Note that this will override
3835 the short option
3836 short - Short, less verbose, version of configurations.
3837 This is overridden by the json option
3838 returns:
3839 Output from cli as a string or None on error
3840 """
3841 try:
3842 baseStr = "cfg"
3843 cmdStr = " get"
3844 componentStr = ""
3845 if component:
3846 componentStr += " " + component
3847 if propName:
3848 componentStr += " " + propName
3849 if jsonFormat:
3850 baseStr += " -j"
3851 elif short:
3852 baseStr += " -s"
3853 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003854 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003855 assert "Command not found:" not in output, output
3856 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003857 return output
3858 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003859 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003860 return None
3861 except TypeError:
3862 main.log.exception( self.name + ": Object not as expected" )
3863 return None
3864 except pexpect.EOF:
3865 main.log.error( self.name + ": EOF exception found" )
3866 main.log.error( self.name + ": " + self.handle.before )
3867 main.cleanup()
3868 main.exit()
3869 except Exception:
3870 main.log.exception( self.name + ": Uncaught exception!" )
3871 main.cleanup()
3872 main.exit()
3873
3874 def setCfg( self, component, propName, value=None, check=True ):
3875 """
3876 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003877 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003878 component - The case sensitive name of the component whose
3879 property is to be set
3880 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003881 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003882 value - The value to set the property to. If None, will unset the
3883 property and revert it to it's default value(if applicable)
3884 check - Boolean, Check whether the option was successfully set this
3885 only applies when a value is given.
3886 returns:
3887 main.TRUE on success or main.FALSE on failure. If check is False,
3888 will return main.TRUE unless there is an error
3889 """
3890 try:
3891 baseStr = "cfg"
3892 cmdStr = " set " + str( component ) + " " + str( propName )
3893 if value is not None:
3894 cmdStr += " " + str( value )
3895 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003896 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003897 assert "Command not found:" not in output, output
3898 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003899 if value and check:
3900 results = self.getCfg( component=str( component ),
3901 propName=str( propName ),
3902 jsonFormat=True )
3903 # Check if current value is what we just set
3904 try:
3905 jsonOutput = json.loads( results )
3906 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003907 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003908 main.log.exception( "Error parsing cfg output" )
3909 main.log.error( "output:" + repr( results ) )
3910 return main.FALSE
3911 if current == str( value ):
3912 return main.TRUE
3913 return main.FALSE
3914 return main.TRUE
3915 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003916 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003917 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003918 except ( TypeError, ValueError ):
3919 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003920 return main.FALSE
3921 except pexpect.EOF:
3922 main.log.error( self.name + ": EOF exception found" )
3923 main.log.error( self.name + ": " + self.handle.before )
3924 main.cleanup()
3925 main.exit()
3926 except Exception:
3927 main.log.exception( self.name + ": Uncaught exception!" )
3928 main.cleanup()
3929 main.exit()
3930
Jon Hall390696c2015-05-05 17:13:41 -07003931 def setTestAdd( self, setName, values ):
3932 """
3933 CLI command to add elements to a distributed set.
3934 Arguments:
3935 setName - The name of the set to add to.
3936 values - The value(s) to add to the set, space seperated.
3937 Example usages:
3938 setTestAdd( "set1", "a b c" )
3939 setTestAdd( "set2", "1" )
3940 returns:
3941 main.TRUE on success OR
3942 main.FALSE if elements were already in the set OR
3943 main.ERROR on error
3944 """
3945 try:
3946 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3947 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003948 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003949 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003950 try:
3951 # TODO: Maybe make this less hardcoded
3952 # ConsistentMap Exceptions
3953 assert "org.onosproject.store.service" not in output
3954 # Node not leader
3955 assert "java.lang.IllegalStateException" not in output
3956 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003957 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003958 "command: " + str( output ) )
3959 retryTime = 30 # Conservative time, given by Madan
3960 main.log.info( "Waiting " + str( retryTime ) +
3961 "seconds before retrying." )
3962 time.sleep( retryTime ) # Due to change in mastership
3963 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003964 assert output is not None, "Error in sendline"
Jon Hall390696c2015-05-05 17:13:41 -07003965 assert "Error executing command" not in output
3966 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3967 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3968 main.log.info( self.name + ": " + output )
3969 if re.search( positiveMatch, output):
3970 return main.TRUE
3971 elif re.search( negativeMatch, output):
3972 return main.FALSE
3973 else:
3974 main.log.error( self.name + ": setTestAdd did not" +
3975 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003976 main.log.debug( self.name + " actual: " + repr( output ) )
3977 return main.ERROR
3978 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003979 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003980 return main.ERROR
3981 except TypeError:
3982 main.log.exception( self.name + ": Object not as expected" )
3983 return main.ERROR
3984 except pexpect.EOF:
3985 main.log.error( self.name + ": EOF exception found" )
3986 main.log.error( self.name + ": " + self.handle.before )
3987 main.cleanup()
3988 main.exit()
3989 except Exception:
3990 main.log.exception( self.name + ": Uncaught exception!" )
3991 main.cleanup()
3992 main.exit()
3993
3994 def setTestRemove( self, setName, values, clear=False, retain=False ):
3995 """
3996 CLI command to remove elements from a distributed set.
3997 Required arguments:
3998 setName - The name of the set to remove from.
3999 values - The value(s) to remove from the set, space seperated.
4000 Optional arguments:
4001 clear - Clear all elements from the set
4002 retain - Retain only the given values. (intersection of the
4003 original set and the given set)
4004 returns:
4005 main.TRUE on success OR
4006 main.FALSE if the set was not changed OR
4007 main.ERROR on error
4008 """
4009 try:
4010 cmdStr = "set-test-remove "
4011 if clear:
4012 cmdStr += "-c " + str( setName )
4013 elif retain:
4014 cmdStr += "-r " + str( setName ) + " " + str( values )
4015 else:
4016 cmdStr += str( setName ) + " " + str( values )
4017 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004018 try:
Jon Halla495f562016-05-16 18:03:26 -07004019 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004020 # TODO: Maybe make this less hardcoded
4021 # ConsistentMap Exceptions
4022 assert "org.onosproject.store.service" not in output
4023 # Node not leader
4024 assert "java.lang.IllegalStateException" not in output
4025 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004026 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004027 "command: " + str( output ) )
4028 retryTime = 30 # Conservative time, given by Madan
4029 main.log.info( "Waiting " + str( retryTime ) +
4030 "seconds before retrying." )
4031 time.sleep( retryTime ) # Due to change in mastership
4032 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004033 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004034 assert "Command not found:" not in output, output
4035 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004036 main.log.info( self.name + ": " + output )
4037 if clear:
4038 pattern = "Set " + str( setName ) + " cleared"
4039 if re.search( pattern, output ):
4040 return main.TRUE
4041 elif retain:
4042 positivePattern = str( setName ) + " was pruned to contain " +\
4043 "only elements of set \[(.*)\]"
4044 negativePattern = str( setName ) + " was not changed by " +\
4045 "retaining only elements of the set " +\
4046 "\[(.*)\]"
4047 if re.search( positivePattern, output ):
4048 return main.TRUE
4049 elif re.search( negativePattern, output ):
4050 return main.FALSE
4051 else:
4052 positivePattern = "\[(.*)\] was removed from the set " +\
4053 str( setName )
4054 if ( len( values.split() ) == 1 ):
4055 negativePattern = "\[(.*)\] was not in set " +\
4056 str( setName )
4057 else:
4058 negativePattern = "No element of \[(.*)\] was in set " +\
4059 str( setName )
4060 if re.search( positivePattern, output ):
4061 return main.TRUE
4062 elif re.search( negativePattern, output ):
4063 return main.FALSE
4064 main.log.error( self.name + ": setTestRemove did not" +
4065 " match expected output" )
4066 main.log.debug( self.name + " expected: " + pattern )
4067 main.log.debug( self.name + " actual: " + repr( output ) )
4068 return main.ERROR
4069 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004070 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07004071 return main.ERROR
4072 except TypeError:
4073 main.log.exception( self.name + ": Object not as expected" )
4074 return main.ERROR
4075 except pexpect.EOF:
4076 main.log.error( self.name + ": EOF exception found" )
4077 main.log.error( self.name + ": " + self.handle.before )
4078 main.cleanup()
4079 main.exit()
4080 except Exception:
4081 main.log.exception( self.name + ": Uncaught exception!" )
4082 main.cleanup()
4083 main.exit()
4084
4085 def setTestGet( self, setName, values="" ):
4086 """
4087 CLI command to get the elements in a distributed set.
4088 Required arguments:
4089 setName - The name of the set to remove from.
4090 Optional arguments:
4091 values - The value(s) to check if in the set, space seperated.
4092 returns:
4093 main.ERROR on error OR
4094 A list of elements in the set if no optional arguments are
4095 supplied OR
4096 A tuple containing the list then:
4097 main.FALSE if the given values are not in the set OR
4098 main.TRUE if the given values are in the set OR
4099 """
4100 try:
4101 values = str( values ).strip()
4102 setName = str( setName ).strip()
4103 length = len( values.split() )
4104 containsCheck = None
4105 # Patterns to match
4106 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004107 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004108 containsTrue = "Set " + setName + " contains the value " + values
4109 containsFalse = "Set " + setName + " did not contain the value " +\
4110 values
4111 containsAllTrue = "Set " + setName + " contains the the subset " +\
4112 setPattern
4113 containsAllFalse = "Set " + setName + " did not contain the the" +\
4114 " subset " + setPattern
4115
4116 cmdStr = "set-test-get "
4117 cmdStr += setName + " " + values
4118 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004119 try:
Jon Halla495f562016-05-16 18:03:26 -07004120 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004121 # TODO: Maybe make this less hardcoded
4122 # ConsistentMap Exceptions
4123 assert "org.onosproject.store.service" not in output
4124 # Node not leader
4125 assert "java.lang.IllegalStateException" not in output
4126 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004127 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004128 "command: " + str( output ) )
4129 retryTime = 30 # Conservative time, given by Madan
4130 main.log.info( "Waiting " + str( retryTime ) +
4131 "seconds before retrying." )
4132 time.sleep( retryTime ) # Due to change in mastership
4133 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004134 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004135 assert "Command not found:" not in output, output
4136 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004137 main.log.info( self.name + ": " + output )
4138
4139 if length == 0:
4140 match = re.search( pattern, output )
4141 else: # if given values
4142 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004143 patternTrue = pattern + "\r\n" + containsTrue
4144 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004145 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004146 patternTrue = pattern + "\r\n" + containsAllTrue
4147 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004148 matchTrue = re.search( patternTrue, output )
4149 matchFalse = re.search( patternFalse, output )
4150 if matchTrue:
4151 containsCheck = main.TRUE
4152 match = matchTrue
4153 elif matchFalse:
4154 containsCheck = main.FALSE
4155 match = matchFalse
4156 else:
4157 main.log.error( self.name + " setTestGet did not match " +\
4158 "expected output" )
4159 main.log.debug( self.name + " expected: " + pattern )
4160 main.log.debug( self.name + " actual: " + repr( output ) )
4161 match = None
4162 if match:
4163 setMatch = match.group( 1 )
4164 if setMatch == '':
4165 setList = []
4166 else:
4167 setList = setMatch.split( ", " )
4168 if length > 0:
4169 return ( setList, containsCheck )
4170 else:
4171 return setList
4172 else: # no match
4173 main.log.error( self.name + ": setTestGet did not" +
4174 " match expected output" )
4175 main.log.debug( self.name + " expected: " + pattern )
4176 main.log.debug( self.name + " actual: " + repr( output ) )
4177 return main.ERROR
4178 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004179 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004180 return main.ERROR
4181 except TypeError:
4182 main.log.exception( self.name + ": Object not as expected" )
4183 return main.ERROR
4184 except pexpect.EOF:
4185 main.log.error( self.name + ": EOF exception found" )
4186 main.log.error( self.name + ": " + self.handle.before )
4187 main.cleanup()
4188 main.exit()
4189 except Exception:
4190 main.log.exception( self.name + ": Uncaught exception!" )
4191 main.cleanup()
4192 main.exit()
4193
4194 def setTestSize( self, setName ):
4195 """
4196 CLI command to get the elements in a distributed set.
4197 Required arguments:
4198 setName - The name of the set to remove from.
4199 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004200 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004201 None on error
4202 """
4203 try:
4204 # TODO: Should this check against the number of elements returned
4205 # and then return true/false based on that?
4206 setName = str( setName ).strip()
4207 # Patterns to match
4208 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004209 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004210 setPattern
4211 cmdStr = "set-test-get -s "
4212 cmdStr += setName
4213 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004214 try:
Jon Halla495f562016-05-16 18:03:26 -07004215 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004216 # TODO: Maybe make this less hardcoded
4217 # ConsistentMap Exceptions
4218 assert "org.onosproject.store.service" not in output
4219 # Node not leader
4220 assert "java.lang.IllegalStateException" not in output
4221 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004222 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004223 "command: " + str( output ) )
4224 retryTime = 30 # Conservative time, given by Madan
4225 main.log.info( "Waiting " + str( retryTime ) +
4226 "seconds before retrying." )
4227 time.sleep( retryTime ) # Due to change in mastership
4228 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004229 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004230 assert "Command not found:" not in output, output
4231 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004232 main.log.info( self.name + ": " + output )
4233 match = re.search( pattern, output )
4234 if match:
4235 setSize = int( match.group( 1 ) )
4236 setMatch = match.group( 2 )
4237 if len( setMatch.split() ) == setSize:
4238 main.log.info( "The size returned by " + self.name +
4239 " matches the number of elements in " +
4240 "the returned set" )
4241 else:
4242 main.log.error( "The size returned by " + self.name +
4243 " does not match the number of " +
4244 "elements in the returned set." )
4245 return setSize
4246 else: # no match
4247 main.log.error( self.name + ": setTestGet did not" +
4248 " match expected output" )
4249 main.log.debug( self.name + " expected: " + pattern )
4250 main.log.debug( self.name + " actual: " + repr( output ) )
4251 return None
4252 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004253 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004254 return None
Jon Hall390696c2015-05-05 17:13:41 -07004255 except TypeError:
4256 main.log.exception( self.name + ": Object not as expected" )
4257 return None
4258 except pexpect.EOF:
4259 main.log.error( self.name + ": EOF exception found" )
4260 main.log.error( self.name + ": " + self.handle.before )
4261 main.cleanup()
4262 main.exit()
4263 except Exception:
4264 main.log.exception( self.name + ": Uncaught exception!" )
4265 main.cleanup()
4266 main.exit()
4267
Jon Hall80daded2015-05-27 16:07:00 -07004268 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004269 """
4270 Command to list the various counters in the system.
4271 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004272 if jsonFormat, a string of the json object returned by the cli
4273 command
4274 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004275 None on error
4276 """
Jon Hall390696c2015-05-05 17:13:41 -07004277 try:
4278 counters = {}
4279 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004280 if jsonFormat:
4281 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004282 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004283 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004284 assert "Command not found:" not in output, output
4285 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004286 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004287 return output
Jon Hall390696c2015-05-05 17:13:41 -07004288 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004289 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004290 return None
Jon Hall390696c2015-05-05 17:13:41 -07004291 except TypeError:
4292 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004293 return None
Jon Hall390696c2015-05-05 17:13:41 -07004294 except pexpect.EOF:
4295 main.log.error( self.name + ": EOF exception found" )
4296 main.log.error( self.name + ": " + self.handle.before )
4297 main.cleanup()
4298 main.exit()
4299 except Exception:
4300 main.log.exception( self.name + ": Uncaught exception!" )
4301 main.cleanup()
4302 main.exit()
4303
Jon Hall935db192016-04-19 00:22:04 -07004304 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004305 """
Jon Halle1a3b752015-07-22 13:02:46 -07004306 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004307 Required arguments:
4308 counter - The name of the counter to increment.
4309 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004310 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004311 returns:
4312 integer value of the counter or
4313 None on Error
4314 """
4315 try:
4316 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004317 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004318 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004319 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004320 if delta != 1:
4321 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004322 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004323 try:
Jon Halla495f562016-05-16 18:03:26 -07004324 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004325 # TODO: Maybe make this less hardcoded
4326 # ConsistentMap Exceptions
4327 assert "org.onosproject.store.service" not in output
4328 # Node not leader
4329 assert "java.lang.IllegalStateException" not in output
4330 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004331 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004332 "command: " + str( output ) )
4333 retryTime = 30 # Conservative time, given by Madan
4334 main.log.info( "Waiting " + str( retryTime ) +
4335 "seconds before retrying." )
4336 time.sleep( retryTime ) # Due to change in mastership
4337 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004338 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004339 assert "Command not found:" not in output, output
4340 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004341 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004342 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004343 match = re.search( pattern, output )
4344 if match:
4345 return int( match.group( 1 ) )
4346 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004347 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004348 " match expected output." )
4349 main.log.debug( self.name + " expected: " + pattern )
4350 main.log.debug( self.name + " actual: " + repr( output ) )
4351 return None
4352 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004353 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004354 return None
4355 except TypeError:
4356 main.log.exception( self.name + ": Object not as expected" )
4357 return None
4358 except pexpect.EOF:
4359 main.log.error( self.name + ": EOF exception found" )
4360 main.log.error( self.name + ": " + self.handle.before )
4361 main.cleanup()
4362 main.exit()
4363 except Exception:
4364 main.log.exception( self.name + ": Uncaught exception!" )
4365 main.cleanup()
4366 main.exit()
4367
Jon Hall935db192016-04-19 00:22:04 -07004368 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004369 """
4370 CLI command to get a distributed counter then add a delta to it.
4371 Required arguments:
4372 counter - The name of the counter to increment.
4373 Optional arguments:
4374 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004375 returns:
4376 integer value of the counter or
4377 None on Error
4378 """
4379 try:
4380 counter = str( counter )
4381 delta = int( delta )
4382 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004383 cmdStr += counter
4384 if delta != 1:
4385 cmdStr += " " + str( delta )
4386 output = self.sendline( cmdStr )
4387 try:
Jon Halla495f562016-05-16 18:03:26 -07004388 assert output is not None, "Error in sendline"
Jon Halle1a3b752015-07-22 13:02:46 -07004389 # TODO: Maybe make this less hardcoded
4390 # ConsistentMap Exceptions
4391 assert "org.onosproject.store.service" not in output
4392 # Node not leader
4393 assert "java.lang.IllegalStateException" not in output
4394 except AssertionError:
4395 main.log.error( "Error in processing '" + cmdStr + "' " +
4396 "command: " + str( output ) )
4397 retryTime = 30 # Conservative time, given by Madan
4398 main.log.info( "Waiting " + str( retryTime ) +
4399 "seconds before retrying." )
4400 time.sleep( retryTime ) # Due to change in mastership
4401 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004402 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004403 assert "Command not found:" not in output, output
4404 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004405 main.log.info( self.name + ": " + output )
4406 pattern = counter + " was updated to (-?\d+)"
4407 match = re.search( pattern, output )
4408 if match:
4409 return int( match.group( 1 ) )
4410 else:
4411 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4412 " match expected output." )
4413 main.log.debug( self.name + " expected: " + pattern )
4414 main.log.debug( self.name + " actual: " + repr( output ) )
4415 return None
4416 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004417 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004418 return None
4419 except TypeError:
4420 main.log.exception( self.name + ": Object not as expected" )
4421 return None
4422 except pexpect.EOF:
4423 main.log.error( self.name + ": EOF exception found" )
4424 main.log.error( self.name + ": " + self.handle.before )
4425 main.cleanup()
4426 main.exit()
4427 except Exception:
4428 main.log.exception( self.name + ": Uncaught exception!" )
4429 main.cleanup()
4430 main.exit()
4431
YPZhangfebf7302016-05-24 16:45:56 -07004432 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004433 """
4434 Description: Execute summary command in onos
4435 Returns: json object ( summary -j ), returns main.FALSE if there is
4436 no output
4437
4438 """
4439 try:
4440 cmdStr = "summary"
4441 if jsonFormat:
4442 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004443 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004444 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004445 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004446 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004447 if not handle:
4448 main.log.error( self.name + ": There is no output in " +
4449 "summary command" )
4450 return main.FALSE
4451 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004452 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004453 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004454 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004455 except TypeError:
4456 main.log.exception( self.name + ": Object not as expected" )
4457 return None
4458 except pexpect.EOF:
4459 main.log.error( self.name + ": EOF exception found" )
4460 main.log.error( self.name + ": " + self.handle.before )
4461 main.cleanup()
4462 main.exit()
4463 except Exception:
4464 main.log.exception( self.name + ": Uncaught exception!" )
4465 main.cleanup()
4466 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004467
Jon Hall935db192016-04-19 00:22:04 -07004468 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004469 """
4470 CLI command to get the value of a key in a consistent map using
4471 transactions. This a test function and can only get keys from the
4472 test map hard coded into the cli command
4473 Required arguments:
4474 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004475 returns:
4476 The string value of the key or
4477 None on Error
4478 """
4479 try:
4480 keyName = str( keyName )
4481 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004482 cmdStr += keyName
4483 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004484 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004485 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004486 try:
4487 # TODO: Maybe make this less hardcoded
4488 # ConsistentMap Exceptions
4489 assert "org.onosproject.store.service" not in output
4490 # Node not leader
4491 assert "java.lang.IllegalStateException" not in output
4492 except AssertionError:
4493 main.log.error( "Error in processing '" + cmdStr + "' " +
4494 "command: " + str( output ) )
4495 return None
4496 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4497 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004498 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004499 return None
4500 else:
4501 match = re.search( pattern, output )
4502 if match:
4503 return match.groupdict()[ 'value' ]
4504 else:
4505 main.log.error( self.name + ": transactionlMapGet did not" +
4506 " match expected output." )
4507 main.log.debug( self.name + " expected: " + pattern )
4508 main.log.debug( self.name + " actual: " + repr( output ) )
4509 return None
Jon Hallc6793552016-01-19 14:18:37 -08004510 except AssertionError:
4511 main.log.exception( "" )
4512 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004513 except TypeError:
4514 main.log.exception( self.name + ": Object not as expected" )
4515 return None
4516 except pexpect.EOF:
4517 main.log.error( self.name + ": EOF exception found" )
4518 main.log.error( self.name + ": " + self.handle.before )
4519 main.cleanup()
4520 main.exit()
4521 except Exception:
4522 main.log.exception( self.name + ": Uncaught exception!" )
4523 main.cleanup()
4524 main.exit()
4525
Jon Hall935db192016-04-19 00:22:04 -07004526 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004527 """
4528 CLI command to put a value into 'numKeys' number of keys in a
4529 consistent map using transactions. This a test function and can only
4530 put into keys named 'Key#' of the test map hard coded into the cli command
4531 Required arguments:
4532 numKeys - Number of keys to add the value to
4533 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004534 returns:
4535 A dictionary whose keys are the name of the keys put into the map
4536 and the values of the keys are dictionaries whose key-values are
4537 'value': value put into map and optionaly
4538 'oldValue': Previous value in the key or
4539 None on Error
4540
4541 Example output
4542 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4543 'Key2': {'value': 'Testing'} }
4544 """
4545 try:
4546 numKeys = str( numKeys )
4547 value = str( value )
4548 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004549 cmdStr += numKeys + " " + value
4550 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004551 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004552 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004553 try:
4554 # TODO: Maybe make this less hardcoded
4555 # ConsistentMap Exceptions
4556 assert "org.onosproject.store.service" not in output
4557 # Node not leader
4558 assert "java.lang.IllegalStateException" not in output
4559 except AssertionError:
4560 main.log.error( "Error in processing '" + cmdStr + "' " +
4561 "command: " + str( output ) )
4562 return None
4563 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4564 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4565 results = {}
4566 for line in output.splitlines():
4567 new = re.search( newPattern, line )
4568 updated = re.search( updatedPattern, line )
4569 if new:
4570 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4571 elif updated:
4572 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004573 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004574 else:
4575 main.log.error( self.name + ": transactionlMapGet did not" +
4576 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004577 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4578 newPattern,
4579 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004580 main.log.debug( self.name + " actual: " + repr( output ) )
4581 return results
Jon Hallc6793552016-01-19 14:18:37 -08004582 except AssertionError:
4583 main.log.exception( "" )
4584 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004585 except TypeError:
4586 main.log.exception( self.name + ": Object not as expected" )
4587 return None
4588 except pexpect.EOF:
4589 main.log.error( self.name + ": EOF exception found" )
4590 main.log.error( self.name + ": " + self.handle.before )
4591 main.cleanup()
4592 main.exit()
4593 except Exception:
4594 main.log.exception( self.name + ": Uncaught exception!" )
4595 main.cleanup()
4596 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004597
acsmarsdaea66c2015-09-03 11:44:06 -07004598 def maps( self, jsonFormat=True ):
4599 """
4600 Description: Returns result of onos:maps
4601 Optional:
4602 * jsonFormat: enable json formatting of output
4603 """
4604 try:
4605 cmdStr = "maps"
4606 if jsonFormat:
4607 cmdStr += " -j"
4608 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004609 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004610 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004611 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004612 except AssertionError:
4613 main.log.exception( "" )
4614 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004615 except TypeError:
4616 main.log.exception( self.name + ": Object not as expected" )
4617 return None
4618 except pexpect.EOF:
4619 main.log.error( self.name + ": EOF exception found" )
4620 main.log.error( self.name + ": " + self.handle.before )
4621 main.cleanup()
4622 main.exit()
4623 except Exception:
4624 main.log.exception( self.name + ": Uncaught exception!" )
4625 main.cleanup()
4626 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004627
4628 def getSwController( self, uri, jsonFormat=True ):
4629 """
4630 Descrition: Gets the controller information from the device
4631 """
4632 try:
4633 cmd = "device-controllers "
4634 if jsonFormat:
4635 cmd += "-j "
4636 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004637 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004638 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004639 return response
Jon Hallc6793552016-01-19 14:18:37 -08004640 except AssertionError:
4641 main.log.exception( "" )
4642 return None
GlennRC050596c2015-11-18 17:06:41 -08004643 except TypeError:
4644 main.log.exception( self.name + ": Object not as expected" )
4645 return None
4646 except pexpect.EOF:
4647 main.log.error( self.name + ": EOF exception found" )
4648 main.log.error( self.name + ": " + self.handle.before )
4649 main.cleanup()
4650 main.exit()
4651 except Exception:
4652 main.log.exception( self.name + ": Uncaught exception!" )
4653 main.cleanup()
4654 main.exit()
4655
4656 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4657 """
4658 Descrition: sets the controller(s) for the specified device
4659
4660 Parameters:
4661 Required: uri - String: The uri of the device(switch).
4662 ip - String or List: The ip address of the controller.
4663 This parameter can be formed in a couple of different ways.
4664 VALID:
4665 10.0.0.1 - just the ip address
4666 tcp:10.0.0.1 - the protocol and the ip address
4667 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4668 so that you can add controllers with different
4669 protocols and ports
4670 INVALID:
4671 10.0.0.1:6653 - this is not supported by ONOS
4672
4673 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4674 port - The port number.
4675 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4676
4677 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4678 """
4679 try:
4680 cmd = "device-setcontrollers"
4681
4682 if jsonFormat:
4683 cmd += " -j"
4684 cmd += " " + uri
4685 if isinstance( ip, str ):
4686 ip = [ip]
4687 for item in ip:
4688 if ":" in item:
4689 sitem = item.split( ":" )
4690 if len(sitem) == 3:
4691 cmd += " " + item
4692 elif "." in sitem[1]:
4693 cmd += " {}:{}".format(item, port)
4694 else:
4695 main.log.error( "Malformed entry: " + item )
4696 raise TypeError
4697 else:
4698 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004699 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004700 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004701 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004702 if "Error" in response:
4703 main.log.error( response )
4704 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004705 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004706 except AssertionError:
4707 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004708 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004709 except TypeError:
4710 main.log.exception( self.name + ": Object not as expected" )
4711 return main.FALSE
4712 except pexpect.EOF:
4713 main.log.error( self.name + ": EOF exception found" )
4714 main.log.error( self.name + ": " + self.handle.before )
4715 main.cleanup()
4716 main.exit()
4717 except Exception:
4718 main.log.exception( self.name + ": Uncaught exception!" )
4719 main.cleanup()
4720 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004721
4722 def removeDevice( self, device ):
4723 '''
4724 Description:
4725 Remove a device from ONOS by passing the uri of the device(s).
4726 Parameters:
4727 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4728 Returns:
4729 Returns main.FALSE if an exception is thrown or an error is present
4730 in the response. Otherwise, returns main.TRUE.
4731 NOTE:
4732 If a host cannot be removed, then this function will return main.FALSE
4733 '''
4734 try:
4735 if type( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004736 deviceStr = device
4737 device = []
4738 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004739
4740 for d in device:
4741 time.sleep( 1 )
4742 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004743 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004744 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004745 if "Error" in response:
4746 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4747 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004748 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004749 except AssertionError:
4750 main.log.exception( "" )
4751 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004752 except TypeError:
4753 main.log.exception( self.name + ": Object not as expected" )
4754 return main.FALSE
4755 except pexpect.EOF:
4756 main.log.error( self.name + ": EOF exception found" )
4757 main.log.error( self.name + ": " + self.handle.before )
4758 main.cleanup()
4759 main.exit()
4760 except Exception:
4761 main.log.exception( self.name + ": Uncaught exception!" )
4762 main.cleanup()
4763 main.exit()
4764
4765 def removeHost( self, host ):
4766 '''
4767 Description:
4768 Remove a host from ONOS by passing the id of the host(s)
4769 Parameters:
4770 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4771 Returns:
4772 Returns main.FALSE if an exception is thrown or an error is present
4773 in the response. Otherwise, returns main.TRUE.
4774 NOTE:
4775 If a host cannot be removed, then this function will return main.FALSE
4776 '''
4777 try:
4778 if type( host ) is str:
4779 host = list( host )
4780
4781 for h in host:
4782 time.sleep( 1 )
4783 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004784 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004785 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004786 if "Error" in response:
4787 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4788 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004789 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004790 except AssertionError:
4791 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004792 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004793 except TypeError:
4794 main.log.exception( self.name + ": Object not as expected" )
4795 return main.FALSE
4796 except pexpect.EOF:
4797 main.log.error( self.name + ": EOF exception found" )
4798 main.log.error( self.name + ": " + self.handle.before )
4799 main.cleanup()
4800 main.exit()
4801 except Exception:
4802 main.log.exception( self.name + ": Uncaught exception!" )
4803 main.cleanup()
4804 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004805
YPZhangfebf7302016-05-24 16:45:56 -07004806 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004807 '''
4808 Description:
4809 Bring link down or up in the null-provider.
4810 params:
4811 begin - (string) One end of a device or switch.
4812 end - (string) the other end of the device or switch
4813 returns:
4814 main.TRUE if no exceptions were thrown and no Errors are
4815 present in the resoponse. Otherwise, returns main.FALSE
4816 '''
4817 try:
Jon Hallc6793552016-01-19 14:18:37 -08004818 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004819 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004820 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004821 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004822 if "Error" in response or "Failure" in response:
4823 main.log.error( response )
4824 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004825 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004826 except AssertionError:
4827 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004828 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004829 except TypeError:
4830 main.log.exception( self.name + ": Object not as expected" )
4831 return main.FALSE
4832 except pexpect.EOF:
4833 main.log.error( self.name + ": EOF exception found" )
4834 main.log.error( self.name + ": " + self.handle.before )
4835 main.cleanup()
4836 main.exit()
4837 except Exception:
4838 main.log.exception( self.name + ": Uncaught exception!" )
4839 main.cleanup()
4840 main.exit()
4841
Jon Hall2c8959e2016-12-16 12:17:34 -08004842 def portstate( self, dpid, port, state ):
Flavio Castro82ee2f62016-06-07 15:04:12 -07004843 '''
4844 Description:
4845 Changes the state of port in an OF switch by means of the
4846 PORTSTATUS OF messages.
4847 params:
Jon Hall2c8959e2016-12-16 12:17:34 -08004848 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
4849 port - (string) target port in the device. Ex: '2'
4850 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07004851 returns:
4852 main.TRUE if no exceptions were thrown and no Errors are
4853 present in the resoponse. Otherwise, returns main.FALSE
4854 '''
4855 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08004856 state = state.lower()
4857 assert state == 'enable' or state == 'disable', "Unknown state"
Flavio Castro82ee2f62016-06-07 15:04:12 -07004858 cmd = "portstate {} {} {}".format( dpid, port, state )
4859 response = self.sendline( cmd, showResponse=True )
4860 assert response is not None, "Error in sendline"
4861 assert "Command not found:" not in response, response
4862 if "Error" in response or "Failure" in response:
4863 main.log.error( response )
4864 return main.FALSE
4865 return main.TRUE
4866 except AssertionError:
4867 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004868 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07004869 except TypeError:
4870 main.log.exception( self.name + ": Object not as expected" )
4871 return main.FALSE
4872 except pexpect.EOF:
4873 main.log.error( self.name + ": EOF exception found" )
4874 main.log.error( self.name + ": " + self.handle.before )
4875 main.cleanup()
4876 main.exit()
4877 except Exception:
4878 main.log.exception( self.name + ": Uncaught exception!" )
4879 main.cleanup()
4880 main.exit()
4881
4882 def logSet( self, level="INFO", app="org.onosproject" ):
4883 """
4884 Set the logging level to lvl for a specific app
4885 returns main.TRUE on success
4886 returns main.FALSE if Error occurred
4887 if noExit is True, TestON will not exit, but clean up
4888 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4889 Level defaults to INFO
4890 """
4891 try:
4892 self.handle.sendline( "log:set %s %s" %( level, app ) )
4893 self.handle.expect( "onos>" )
4894
4895 response = self.handle.before
4896 if re.search( "Error", response ):
4897 return main.FALSE
4898 return main.TRUE
4899 except pexpect.TIMEOUT:
4900 main.log.exception( self.name + ": TIMEOUT exception found" )
4901 main.cleanup()
4902 main.exit()
4903 except pexpect.EOF:
4904 main.log.error( self.name + ": EOF exception found" )
4905 main.log.error( self.name + ": " + self.handle.before )
4906 main.cleanup()
4907 main.exit()
4908 except Exception:
4909 main.log.exception( self.name + ": Uncaught exception!" )
4910 main.cleanup()
4911 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004912
4913 def getGraphDict( self, timeout=60, includeHost=False ):
4914 """
4915 Return a dictionary which describes the latest network topology data as a
4916 graph.
4917 An example of the dictionary:
4918 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4919 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4920 Each vertex should at least have an 'edges' attribute which describes the
4921 adjacency information. The value of 'edges' attribute is also represented by
4922 a dictionary, which maps each edge (identified by the neighbor vertex) to a
4923 list of attributes.
4924 An example of the edges dictionary:
4925 'edges': { vertex2: { 'port': ..., 'weight': ... },
4926 vertex3: { 'port': ..., 'weight': ... } }
4927 If includeHost == True, all hosts (and host-switch links) will be included
4928 in topology data.
4929 """
4930 graphDict = {}
4931 try:
4932 links = self.links()
4933 links = json.loads( links )
4934 devices = self.devices()
4935 devices = json.loads( devices )
4936 idToDevice = {}
4937 for device in devices:
4938 idToDevice[ device[ 'id' ] ] = device
4939 if includeHost:
4940 hosts = self.hosts()
4941 # FIXME: support 'includeHost' argument
4942 for link in links:
4943 nodeA = link[ 'src' ][ 'device' ]
4944 nodeB = link[ 'dst' ][ 'device' ]
4945 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
4946 if not nodeA in graphDict.keys():
4947 graphDict[ nodeA ] = { 'edges':{},
4948 'dpid':idToDevice[ nodeA ][ 'id' ][3:],
4949 'type':idToDevice[ nodeA ][ 'type' ],
4950 'available':idToDevice[ nodeA ][ 'available' ],
4951 'role':idToDevice[ nodeA ][ 'role' ],
4952 'mfr':idToDevice[ nodeA ][ 'mfr' ],
4953 'hw':idToDevice[ nodeA ][ 'hw' ],
4954 'sw':idToDevice[ nodeA ][ 'sw' ],
4955 'serial':idToDevice[ nodeA ][ 'serial' ],
4956 'chassisId':idToDevice[ nodeA ][ 'chassisId' ],
4957 'annotations':idToDevice[ nodeA ][ 'annotations' ]}
4958 else:
4959 # Assert nodeB is not connected to any current links of nodeA
4960 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
4961 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port':link[ 'src' ][ 'port' ],
4962 'type':link[ 'type' ],
4963 'state':link[ 'state' ] }
4964 return graphDict
4965 except ( TypeError, ValueError ):
4966 main.log.exception( self.name + ": Object not as expected" )
4967 return None
4968 except KeyError:
4969 main.log.exception( self.name + ": KeyError exception found" )
4970 return None
4971 except AssertionError:
4972 main.log.exception( self.name + ": AssertionError exception found" )
4973 return None
4974 except pexpect.EOF:
4975 main.log.error( self.name + ": EOF exception found" )
4976 main.log.error( self.name + ": " + self.handle.before )
4977 return None
4978 except Exception:
4979 main.log.exception( self.name + ": Uncaught exception!" )
4980 return None
YPZhangcbc2a062016-07-11 10:55:44 -07004981
4982 def getIntentPerfSummary( self ):
4983 '''
4984 Send command to check intent-perf summary
4985 Returns: dictionary for intent-perf summary
4986 if something wrong, function will return None
4987 '''
4988 cmd = "intent-perf -s"
4989 respDic = {}
4990 resp = self.sendline( cmd )
4991 try:
4992 # Generate the dictionary to return
4993 for l in resp.split( "\n" ):
4994 # Delete any white space in line
4995 temp = re.sub( r'\s+', '', l )
4996 temp = temp.split( ":" )
4997 respDic[ temp[0] ] = temp[ 1 ]
4998
4999 except (TypeError, ValueError):
5000 main.log.exception( self.name + ": Object not as expected" )
5001 return None
5002 except KeyError:
5003 main.log.exception( self.name + ": KeyError exception found" )
5004 return None
5005 except AssertionError:
5006 main.log.exception( self.name + ": AssertionError exception found" )
5007 return None
5008 except pexpect.EOF:
5009 main.log.error( self.name + ": EOF exception found" )
5010 main.log.error( self.name + ": " + self.handle.before )
5011 return None
5012 except Exception:
5013 main.log.exception( self.name + ": Uncaught exception!" )
5014 return None
5015 return respDic
5016
Chiyu Chengec63bde2016-11-17 18:11:36 -08005017 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005018 """
5019 Searches the latest ONOS log file for the given search term and
5020 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005021
chengchiyu08303a02016-09-08 17:40:26 -07005022 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005023 searchTerm:
5024 The string to grep from the ONOS log.
5025 startLine:
5026 The term that decides which line is the start to search the searchTerm in
5027 the karaf log. For now, startTerm only works in 'first' mode.
5028 logNum:
5029 In some extreme cases, one karaf log is not big enough to contain all the
5030 information.Because of this, search mutiply logs is necessary to capture
5031 the right result. logNum is the number of karaf logs that we need to search
5032 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005033 mode:
5034 all: return all the strings that contain the search term
5035 last: return the last string that contains the search term
5036 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005037 num: return the number of times that the searchTerm appears in the log
5038 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005039 """
5040 try:
5041 assert type( searchTerm ) is str
Chiyu Chengec63bde2016-11-17 18:11:36 -08005042 #Build the log paths string
5043 logPath = '/opt/onos/log/karaf.log.'
5044 logPaths = '/opt/onos/log/karaf.log'
5045 for i in range( 1, logNum ):
5046 logPaths = logPath + str( i ) + " " + logPaths
5047 cmd = "cat " + logPaths
5048 if mode == 'all':
5049 cmd = cmd + " | grep \'" + searchTerm + "\'"
chengchiyu08303a02016-09-08 17:40:26 -07005050 if mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005051 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
chengchiyu08303a02016-09-08 17:40:26 -07005052 if mode == 'first':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005053 if startLine != '':
5054 # 100000000 is just a extreme large number to make sure this function can grep all the lines after startLine
5055 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\' | grep \'" + searchTerm + "\'" + "| head -n 1"
5056 else:
5057 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005058 if mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005059 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005060 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005061 return num
Chiyu Chengec63bde2016-11-17 18:11:36 -08005062 if mode == 'total':
5063 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
5064 return int(totalLines)
chengchiyu08303a02016-09-08 17:40:26 -07005065 before = self.sendline( cmd )
5066 before = before.splitlines()
5067 # make sure the returned list only contains the search term
5068 returnLines = [line for line in before if searchTerm in line]
5069 return returnLines
5070 except AssertionError:
5071 main.log.error( self.name + " searchTerm is not string type" )
5072 return None
5073 except pexpect.EOF:
5074 main.log.error( self.name + ": EOF exception found" )
5075 main.log.error( self.name + ": " + self.handle.before )
5076 main.cleanup()
5077 main.exit()
5078 except pexpect.TIMEOUT:
5079 main.log.error( self.name + ": TIMEOUT exception found" )
5080 main.log.error( self.name + ": " + self.handle.before )
5081 main.cleanup()
5082 main.exit()
5083 except Exception:
5084 main.log.exception( self.name + ": Uncaught exception!" )
5085 main.cleanup()
5086 main.exit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005087
5088 def vplsShow( self, jsonFormat=True ):
5089 """
5090 Description: Returns result of onos:vpls show, which should list the
5091 configured VPLS networks and the assigned interfaces.
5092 Optional:
5093 * jsonFormat: enable json formatting of output
5094 Returns:
5095 The output of the command or None on error.
5096 """
5097 try:
5098 cmdStr = "vpls show"
5099 if jsonFormat:
5100 raise NotImplementedError
5101 cmdStr += " -j"
5102 handle = self.sendline( cmdStr )
5103 assert handle is not None, "Error in sendline"
5104 assert "Command not found:" not in handle, handle
5105 return handle
5106 except AssertionError:
5107 main.log.exception( "" )
5108 return None
5109 except TypeError:
5110 main.log.exception( self.name + ": Object not as expected" )
5111 return None
5112 except pexpect.EOF:
5113 main.log.error( self.name + ": EOF exception found" )
5114 main.log.error( self.name + ": " + self.handle.before )
5115 main.cleanup()
5116 main.exit()
5117 except NotImplementedError:
5118 main.log.exception( self.name + ": Json output not supported")
5119 return None
5120 except Exception:
5121 main.log.exception( self.name + ": Uncaught exception!" )
5122 main.cleanup()
5123 main.exit()
5124
5125 def parseVplsShow( self ):
5126 """
5127 Parse the cli output of 'vpls show' into json output. This is required
5128 as there is currently no json output available.
5129 """
5130 try:
5131 output = []
5132 raw = self.vplsShow( jsonFormat=False )
5133 namePat = "VPLS name: (?P<name>\w+)"
5134 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5135 encapPat = "Encapsulation: (?P<encap>\w+)"
5136 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5137 mIter = re.finditer( pattern, raw )
5138 for match in mIter:
5139 item = {}
5140 item[ 'name' ] = match.group( 'name' )
5141 ifaces = match.group( 'interfaces' ).split( ', ')
5142 if ifaces == [ "" ]:
5143 ifaces = []
5144 item[ 'interfaces' ] = ifaces
5145 encap = match.group( 'encap' )
5146 if encap != 'NONE':
5147 item[ 'encapsulation' ] = encap.lower()
5148 output.append( item )
5149 return output
5150 except Exception:
5151 main.log.exception( self.name + ": Uncaught exception!" )
5152 main.cleanup()
5153 main.exit()
5154
5155 def vplsList( self, jsonFormat=True ):
5156 """
5157 Description: Returns result of onos:vpls list, which should list the
5158 configured VPLS networks.
5159 Optional:
5160 * jsonFormat: enable json formatting of output
5161 """
5162 try:
5163 cmdStr = "vpls list"
5164 if jsonFormat:
5165 raise NotImplementedError
5166 cmdStr += " -j"
5167 handle = self.sendline( cmdStr )
5168 assert handle is not None, "Error in sendline"
5169 assert "Command not found:" not in handle, handle
5170 return handle
5171 except AssertionError:
5172 main.log.exception( "" )
5173 return None
5174 except TypeError:
5175 main.log.exception( self.name + ": Object not as expected" )
5176 return None
5177 except pexpect.EOF:
5178 main.log.error( self.name + ": EOF exception found" )
5179 main.log.error( self.name + ": " + self.handle.before )
5180 main.cleanup()
5181 main.exit()
5182 except NotImplementedError:
5183 main.log.exception( self.name + ": Json output not supported")
5184 return None
5185 except Exception:
5186 main.log.exception( self.name + ": Uncaught exception!" )
5187 main.cleanup()
5188 main.exit()
5189
5190 def vplsCreate( self, network ):
5191 """
5192 CLI command to create a new VPLS network.
5193 Required arguments:
5194 network - String name of the network to create.
5195 returns:
5196 main.TRUE on success and main.FALSE on failure
5197 """
5198 try:
5199 network = str( network )
5200 cmdStr = "vpls create "
5201 cmdStr += network
5202 output = self.sendline( cmdStr )
5203 assert output is not None, "Error in sendline"
5204 assert "Command not found:" not in output, output
5205 assert "Error executing command" not in output, output
5206 assert "VPLS already exists:" not in output, output
5207 return main.TRUE
5208 except AssertionError:
5209 main.log.exception( "" )
5210 return main.FALSE
5211 except TypeError:
5212 main.log.exception( self.name + ": Object not as expected" )
5213 return main.FALSE
5214 except pexpect.EOF:
5215 main.log.error( self.name + ": EOF exception found" )
5216 main.log.error( self.name + ": " + self.handle.before )
5217 main.cleanup()
5218 main.exit()
5219 except Exception:
5220 main.log.exception( self.name + ": Uncaught exception!" )
5221 main.cleanup()
5222 main.exit()
5223
5224 def vplsDelete( self, network ):
5225 """
5226 CLI command to delete a VPLS network.
5227 Required arguments:
5228 network - Name of the network to delete.
5229 returns:
5230 main.TRUE on success and main.FALSE on failure
5231 """
5232 try:
5233 network = str( network )
5234 cmdStr = "vpls delete "
5235 cmdStr += network
5236 output = self.sendline( cmdStr )
5237 assert output is not None, "Error in sendline"
5238 assert "Command not found:" not in output, output
5239 assert "Error executing command" not in output, output
5240 assert " not found" not in output, output
5241 return main.TRUE
5242 except AssertionError:
5243 main.log.exception( "" )
5244 return main.FALSE
5245 except TypeError:
5246 main.log.exception( self.name + ": Object not as expected" )
5247 return main.FALSE
5248 except pexpect.EOF:
5249 main.log.error( self.name + ": EOF exception found" )
5250 main.log.error( self.name + ": " + self.handle.before )
5251 main.cleanup()
5252 main.exit()
5253 except Exception:
5254 main.log.exception( self.name + ": Uncaught exception!" )
5255 main.cleanup()
5256 main.exit()
5257
5258 def vplsAddIface( self, network, iface ):
5259 """
5260 CLI command to add an interface to a VPLS network.
5261 Required arguments:
5262 network - Name of the network to add the interface to.
5263 iface - The ONOS name for an interface.
5264 returns:
5265 main.TRUE on success and main.FALSE on failure
5266 """
5267 try:
5268 network = str( network )
5269 iface = str( iface )
5270 cmdStr = "vpls add-if "
5271 cmdStr += network + " " + iface
5272 output = self.sendline( cmdStr )
5273 assert output is not None, "Error in sendline"
5274 assert "Command not found:" not in output, output
5275 assert "Error executing command" not in output, output
5276 assert "already associated to network" not in output, output
5277 assert "Interface cannot be added." not in output, output
5278 return main.TRUE
5279 except AssertionError:
5280 main.log.exception( "" )
5281 return main.FALSE
5282 except TypeError:
5283 main.log.exception( self.name + ": Object not as expected" )
5284 return main.FALSE
5285 except pexpect.EOF:
5286 main.log.error( self.name + ": EOF exception found" )
5287 main.log.error( self.name + ": " + self.handle.before )
5288 main.cleanup()
5289 main.exit()
5290 except Exception:
5291 main.log.exception( self.name + ": Uncaught exception!" )
5292 main.cleanup()
5293 main.exit()
5294
5295 def vplsRemIface( self, network, iface ):
5296 """
5297 CLI command to remove an interface from a VPLS network.
5298 Required arguments:
5299 network - Name of the network to remove the interface from.
5300 iface - Name of the interface to remove.
5301 returns:
5302 main.TRUE on success and main.FALSE on failure
5303 """
5304 try:
5305 iface = str( iface )
5306 cmdStr = "vpls rem-if "
5307 cmdStr += network + " " + iface
5308 output = self.sendline( cmdStr )
5309 assert output is not None, "Error in sendline"
5310 assert "Command not found:" not in output, output
5311 assert "Error executing command" not in output, output
5312 assert "is not configured" not in output, output
5313 return main.TRUE
5314 except AssertionError:
5315 main.log.exception( "" )
5316 return main.FALSE
5317 except TypeError:
5318 main.log.exception( self.name + ": Object not as expected" )
5319 return main.FALSE
5320 except pexpect.EOF:
5321 main.log.error( self.name + ": EOF exception found" )
5322 main.log.error( self.name + ": " + self.handle.before )
5323 main.cleanup()
5324 main.exit()
5325 except Exception:
5326 main.log.exception( self.name + ": Uncaught exception!" )
5327 main.cleanup()
5328 main.exit()
5329
5330 def vplsClean( self ):
5331 """
5332 Description: Clears the VPLS app configuration.
5333 Returns: main.TRUE on success and main.FALSE on failure
5334 """
5335 try:
5336 cmdStr = "vpls clean"
5337 handle = self.sendline( cmdStr )
5338 assert handle is not None, "Error in sendline"
5339 assert "Command not found:" not in handle, handle
5340 return handle
5341 except AssertionError:
5342 main.log.exception( "" )
5343 return main.FALSE
5344 except TypeError:
5345 main.log.exception( self.name + ": Object not as expected" )
5346 return main.FALSE
5347 except pexpect.EOF:
5348 main.log.error( self.name + ": EOF exception found" )
5349 main.log.error( self.name + ": " + self.handle.before )
5350 main.cleanup()
5351 main.exit()
5352 except Exception:
5353 main.log.exception( self.name + ": Uncaught exception!" )
5354 main.cleanup()
5355 main.exit()
5356
5357 def vplsSetEncap( self, network, encapType ):
5358 """
5359 CLI command to add an interface to a VPLS network.
5360 Required arguments:
5361 network - Name of the network to create.
5362 encapType - Type of encapsulation.
5363 returns:
5364 main.TRUE on success and main.FALSE on failure
5365 """
5366 try:
5367 network = str( network )
5368 encapType = str( encapType ).upper()
5369 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5370 cmdStr = "vpls set-encap "
5371 cmdStr += network + " " + encapType
5372 output = self.sendline( cmdStr )
5373 assert output is not None, "Error in sendline"
5374 assert "Command not found:" not in output, output
5375 assert "Error executing command" not in output, output
5376 assert "already associated to network" not in output, output
5377 assert "Encapsulation type " not in output, output
5378 return main.TRUE
5379 except AssertionError:
5380 main.log.exception( "" )
5381 return main.FALSE
5382 except TypeError:
5383 main.log.exception( self.name + ": Object not as expected" )
5384 return main.FALSE
5385 except pexpect.EOF:
5386 main.log.error( self.name + ": EOF exception found" )
5387 main.log.error( self.name + ": " + self.handle.before )
5388 main.cleanup()
5389 main.exit()
5390 except Exception:
5391 main.log.exception( self.name + ": Uncaught exception!" )
5392 main.cleanup()
5393 main.exit()
5394
5395 def interfaces( self, jsonFormat=True ):
5396 """
5397 Description: Returns result of interfaces command.
5398 Optional:
5399 * jsonFormat: enable json formatting of output
5400 Returns:
5401 The output of the command or None on error.
5402 """
5403 try:
5404 cmdStr = "interfaces"
5405 if jsonFormat:
5406 #raise NotImplementedError
5407 cmdStr += " -j"
5408 handle = self.sendline( cmdStr )
5409 assert handle is not None, "Error in sendline"
5410 assert "Command not found:" not in handle, handle
5411 return handle
5412 except AssertionError:
5413 main.log.exception( "" )
5414 return None
5415 except TypeError:
5416 main.log.exception( self.name + ": Object not as expected" )
5417 return None
5418 except pexpect.EOF:
5419 main.log.error( self.name + ": EOF exception found" )
5420 main.log.error( self.name + ": " + self.handle.before )
5421 main.cleanup()
5422 main.exit()
5423 except NotImplementedError:
5424 main.log.exception( self.name + ": Json output not supported")
5425 return None
5426 except Exception:
5427 main.log.exception( self.name + ": Uncaught exception!" )
5428 main.cleanup()
5429 main.exit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005430
5431 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
5432 '''
5433 Get the timestamp of searchTerm from karaf log.
5434
5435 Arguments:
5436 splitTerm_before and splitTerm_after:
5437
5438 The terms that split the string that contains the timeStamp of
5439 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5440 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5441 and the splitTerm_after is "x"
5442
5443 others:
5444
5445 plz look at the "logsearch" Function in onosclidriver.py
5446
5447
5448 '''
5449 if logNum < 0:
5450 main.log.error("Get wrong log number ")
5451 return main.ERROR
5452 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
5453 if len(lines) == 0:
5454 main.log.warn( "Captured timestamp string is empty" )
5455 return main.ERROR
5456 lines = lines[ 0 ]
5457 try:
5458 assert type(lines) is str
5459 # get the target value
5460 line = lines.split( splitTerm_before )
5461 key = line[ 1 ].split( splitTerm_after )
5462 return int( key[ 0 ] )
5463 except IndexError:
5464 main.log.warn( "Index Error!" )
5465 return main.ERROR
5466 except AssertionError:
5467 main.log.warn( "Search Term Not Found " )
5468 return main.ERROR