blob: cc5ab5048f22ad6005e3d23b50757bec7adbd169 [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
17
kelvin8ec71442015-01-15 16:57:00 -080018"""
andrewonlab95ce8322014-10-13 14:12:04 -040019import pexpect
20import re
Jon Hall30b82fa2015-03-04 17:15:43 -080021import json
22import types
Jon Hallbd16b922015-03-26 17:53:15 -070023import time
kelvin-onlaba4074292015-07-09 15:19:49 -070024import os
andrewonlab95ce8322014-10-13 14:12:04 -040025from drivers.common.clidriver import CLI
You Wangdb8cd0a2016-05-26 15:19:45 -070026from core.graph import Graph
andrewonlab95ce8322014-10-13 14:12:04 -040027
andrewonlab95ce8322014-10-13 14:12:04 -040028
kelvin8ec71442015-01-15 16:57:00 -080029class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040030
kelvin8ec71442015-01-15 16:57:00 -080031 def __init__( self ):
32 """
33 Initialize client
34 """
Jon Hallefbd9792015-03-05 16:11:36 -080035 self.name = None
36 self.home = None
37 self.handle = None
You Wangdb8cd0a2016-05-26 15:19:45 -070038 self.graph = Graph()
kelvin8ec71442015-01-15 16:57:00 -080039 super( CLI, self ).__init__()
40
41 def connect( self, **connectargs ):
42 """
andrewonlab95ce8322014-10-13 14:12:04 -040043 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080044 """
andrewonlab95ce8322014-10-13 14:12:04 -040045 try:
46 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080047 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070048 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040049 for key in self.options:
50 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080051 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040052 break
kelvin-onlabfb521662015-02-27 09:52:40 -080053 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070054 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040055
kelvin-onlaba4074292015-07-09 15:19:49 -070056 for key in self.options:
57 if key == 'onosIp':
58 self.onosIp = self.options[ 'onosIp' ]
59 break
60
kelvin8ec71442015-01-15 16:57:00 -080061 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070062
63 try:
Jon Hallc6793552016-01-19 14:18:37 -080064 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070065 self.ip_address = os.getenv( str( self.ip_address ) )
66 else:
67 main.log.info( self.name +
68 ": Trying to connect to " +
69 self.ip_address )
70
71 except KeyError:
72 main.log.info( "Invalid host name," +
73 " connecting to local host instead" )
74 self.ip_address = 'localhost'
75 except Exception as inst:
76 main.log.error( "Uncaught exception: " + str( inst ) )
77
kelvin8ec71442015-01-15 16:57:00 -080078 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080079 user_name=self.user_name,
80 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080081 port=self.port,
82 pwd=self.pwd,
83 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040084
kelvin8ec71442015-01-15 16:57:00 -080085 self.handle.sendline( "cd " + self.home )
86 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040087 if self.handle:
88 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080089 else:
90 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040091 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080092 except TypeError:
93 main.log.exception( self.name + ": Object not as expected" )
94 return None
andrewonlab95ce8322014-10-13 14:12:04 -040095 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080096 main.log.error( self.name + ": EOF exception found" )
97 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040098 main.cleanup()
99 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800100 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800101 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400102 main.cleanup()
103 main.exit()
104
kelvin8ec71442015-01-15 16:57:00 -0800105 def disconnect( self ):
106 """
andrewonlab95ce8322014-10-13 14:12:04 -0400107 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800108 """
Jon Halld61331b2015-02-17 16:35:47 -0800109 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400110 try:
Jon Hall61282e32015-03-19 11:34:11 -0700111 if self.handle:
112 i = self.logout()
113 if i == main.TRUE:
114 self.handle.sendline( "" )
115 self.handle.expect( "\$" )
116 self.handle.sendline( "exit" )
117 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800118 except TypeError:
119 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800120 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400121 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800122 main.log.error( self.name + ": EOF exception found" )
123 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700124 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700125 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700126 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800127 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800128 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400129 response = main.FALSE
130 return response
131
kelvin8ec71442015-01-15 16:57:00 -0800132 def logout( self ):
133 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500134 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700135 Returns main.TRUE if exited CLI and
136 main.FALSE on timeout (not guranteed you are disconnected)
137 None on TypeError
138 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800139 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500140 try:
Jon Hall61282e32015-03-19 11:34:11 -0700141 if self.handle:
142 self.handle.sendline( "" )
143 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
144 timeout=10 )
145 if i == 0: # In ONOS CLI
146 self.handle.sendline( "logout" )
Jon Hallbfe00002016-04-05 10:23:54 -0700147 j = self.handle.expect( [ "\$",
148 "Command not found:",
149 pexpect.TIMEOUT ] )
150 if j == 0: # Successfully logged out
151 return main.TRUE
152 elif j == 1 or j == 2:
153 # ONOS didn't fully load, and logout command isn't working
154 # or the command timed out
155 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700156 try:
157 self.handle.expect( "\$" )
158 except pexpect.TIMEOUT:
159 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700160 return main.TRUE
161 else: # some other output
162 main.log.warn( "Unknown repsonse to logout command: '{}'",
163 repr( self.handle.before ) )
164 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700165 elif i == 1: # not in CLI
166 return main.TRUE
167 elif i == 3: # Timeout
168 return main.FALSE
169 else:
andrewonlab9627f432014-11-14 12:45:10 -0500170 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800171 except TypeError:
172 main.log.exception( self.name + ": Object not as expected" )
173 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500174 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800175 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700176 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500177 main.cleanup()
178 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700179 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700180 main.log.error( self.name +
181 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800182 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800183 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500184 main.cleanup()
185 main.exit()
186
kelvin-onlabd3b64892015-01-20 13:26:24 -0800187 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800188 """
andrewonlab95ce8322014-10-13 14:12:04 -0400189 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800190
andrewonlab95ce8322014-10-13 14:12:04 -0400191 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800192 """
andrewonlab95ce8322014-10-13 14:12:04 -0400193 try:
194 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800195 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400196 main.cleanup()
197 main.exit()
198 else:
kelvin8ec71442015-01-15 16:57:00 -0800199 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800200 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800201 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400202 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800203 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800204 handleBefore = self.handle.before
205 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800206 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800207 self.handle.sendline("")
208 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800209 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400210
kelvin-onlabd3b64892015-01-20 13:26:24 -0800211 main.log.info( "Cell call returned: " + handleBefore +
212 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400213
214 return main.TRUE
215
Jon Halld4d4b372015-01-28 16:02:41 -0800216 except TypeError:
217 main.log.exception( self.name + ": Object not as expected" )
218 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400219 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800220 main.log.error( self.name + ": eof exception found" )
221 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400222 main.cleanup()
223 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800224 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800225 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400226 main.cleanup()
227 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800228
pingping-lin57a56ce2015-05-20 16:43:48 -0700229 def startOnosCli( self, ONOSIp, karafTimeout="",
Jon Hallc6793552016-01-19 14:18:37 -0800230 commandlineTimeout=10, onosStartTimeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -0800231 """
Jon Hallefbd9792015-03-05 16:11:36 -0800232 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800233 by user would be used to set the current karaf shell idle timeout.
234 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800235 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800236 Below is an example to start a session with 60 seconds idle timeout
237 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800238
Hari Krishna25d42f72015-01-05 15:08:28 -0800239 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800240 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800241
kelvin-onlabd3b64892015-01-20 13:26:24 -0800242 Note: karafTimeout is left as str so that this could be read
243 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800244 """
You Wangf69ab392016-01-26 16:34:38 -0800245 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400246 try:
kelvin8ec71442015-01-15 16:57:00 -0800247 self.handle.sendline( "" )
248 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700249 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500250
251 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800252 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500253 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400254
kelvin8ec71442015-01-15 16:57:00 -0800255 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800256 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800257 i = self.handle.expect( [
258 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700259 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400260
261 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800262 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800263 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800264 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800265 "config:property-set -p org.apache.karaf.shell\
266 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800267 karafTimeout )
268 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800269 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800270 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400271 return main.TRUE
272 else:
kelvin8ec71442015-01-15 16:57:00 -0800273 # If failed, send ctrl+c to process and try again
274 main.log.info( "Starting CLI failed. Retrying..." )
275 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800276 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800277 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
278 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400279 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800280 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800281 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800282 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800283 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800284 "config:property-set -p org.apache.karaf.shell\
285 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800286 karafTimeout )
287 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800288 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800289 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400290 return main.TRUE
291 else:
kelvin8ec71442015-01-15 16:57:00 -0800292 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800293 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400294 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400295
Jon Halld4d4b372015-01-28 16:02:41 -0800296 except TypeError:
297 main.log.exception( self.name + ": Object not as expected" )
298 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400299 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800300 main.log.error( self.name + ": EOF exception found" )
301 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400302 main.cleanup()
303 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800304 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800305 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400306 main.cleanup()
307 main.exit()
308
suibin zhang116647a2016-05-06 16:30:09 -0700309 def startCellCli( self, karafTimeout="",
310 commandlineTimeout=10, onosStartTimeout=60 ):
311 """
312 Start CLI on onos ecll handle.
313
314 karafTimeout is an optional argument. karafTimeout value passed
315 by user would be used to set the current karaf shell idle timeout.
316 Note that when ever this property is modified the shell will exit and
317 the subsequent login would reflect new idle timeout.
318 Below is an example to start a session with 60 seconds idle timeout
319 ( input value is in milliseconds ):
320
321 tValue = "60000"
322
323 Note: karafTimeout is left as str so that this could be read
324 and passed to startOnosCli from PARAMS file as str.
325 """
326
327 try:
328 self.handle.sendline( "" )
329 x = self.handle.expect( [
330 "\$", "onos>" ], commandlineTimeout)
331
332 if x == 1:
333 main.log.info( "ONOS cli is already running" )
334 return main.TRUE
335
336 # Wait for onos start ( -w ) and enter onos cli
337 self.handle.sendline( "/opt/onos/bin/onos" )
338 i = self.handle.expect( [
339 "onos>",
340 pexpect.TIMEOUT ], onosStartTimeout )
341
342 if i == 0:
343 main.log.info( self.name + " CLI Started successfully" )
344 if karafTimeout:
345 self.handle.sendline(
346 "config:property-set -p org.apache.karaf.shell\
347 sshIdleTimeout " +
348 karafTimeout )
349 self.handle.expect( "\$" )
350 self.handle.sendline( "/opt/onos/bin/onos" )
351 self.handle.expect( "onos>" )
352 return main.TRUE
353 else:
354 # If failed, send ctrl+c to process and try again
355 main.log.info( "Starting CLI failed. Retrying..." )
356 self.handle.send( "\x03" )
357 self.handle.sendline( "/opt/onos/bin/onos" )
358 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
359 timeout=30 )
360 if i == 0:
361 main.log.info( self.name + " CLI Started " +
362 "successfully after retry attempt" )
363 if karafTimeout:
364 self.handle.sendline(
365 "config:property-set -p org.apache.karaf.shell\
366 sshIdleTimeout " +
367 karafTimeout )
368 self.handle.expect( "\$" )
369 self.handle.sendline( "/opt/onos/bin/onos" )
370 self.handle.expect( "onos>" )
371 return main.TRUE
372 else:
373 main.log.error( "Connection to CLI " +
374 self.name + " timeout" )
375 return main.FALSE
376
377 except TypeError:
378 main.log.exception( self.name + ": Object not as expected" )
379 return None
380 except pexpect.EOF:
381 main.log.error( self.name + ": EOF exception found" )
382 main.log.error( self.name + ": " + self.handle.before )
383 main.cleanup()
384 main.exit()
385 except Exception:
386 main.log.exception( self.name + ": Uncaught exception!" )
387 main.cleanup()
388 main.exit()
389
YPZhangebf9eb52016-05-12 15:20:24 -0700390 def log( self, cmdStr, level="",noExit=False):
kelvin-onlab9f541032015-02-04 16:19:53 -0800391 """
392 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800393 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800394 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700395 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800396 Available level: DEBUG, TRACE, INFO, WARN, ERROR
397 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800398 """
399 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800400 lvlStr = ""
401 if level:
402 lvlStr = "--level=" + level
403
kelvin-onlab338f5512015-02-06 10:53:16 -0800404 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700405 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800406 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800407
kelvin-onlab9f541032015-02-04 16:19:53 -0800408 response = self.handle.before
409 if re.search( "Error", response ):
410 return main.FALSE
411 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700412 except pexpect.TIMEOUT:
413 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700414 if noExit:
415 main.cleanup()
416 return None
417 else:
418 main.cleanup()
419 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800420 except pexpect.EOF:
421 main.log.error( self.name + ": EOF exception found" )
422 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700423 if noExit:
424 main.cleanup()
425 return None
426 else:
427 main.cleanup()
428 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800429 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800430 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700431 if noExit:
432 main.cleanup()
433 return None
434 else:
435 main.cleanup()
436 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400437
YPZhangebf9eb52016-05-12 15:20:24 -0700438 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800439 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800440 Send a completely user specified string to
441 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400442 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800443
YPZhangebf9eb52016-05-12 15:20:24 -0700444 if noExit is True, TestON will not exit, but clean up
445
andrewonlaba18f6bf2014-10-13 19:31:54 -0400446 Warning: There are no sanity checking to commands
447 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800448
kelvin8ec71442015-01-15 16:57:00 -0800449 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400450 try:
Jon Halla495f562016-05-16 18:03:26 -0700451 # Try to reconnect if disconnected from cli
452 self.handle.sendline( "" )
453 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
454 if i == 1:
455 main.log.error( self.name + ": onos cli session closed. ")
456 if self.onosIp:
457 main.log.warn( "Trying to reconnect " + self.onosIp )
458 reconnectResult = self.startOnosCli( self.onosIp )
459 if reconnectResult:
460 main.log.info( self.name + ": onos cli session reconnected." )
461 else:
462 main.log.error( self.name + ": reconnection failed." )
463 main.cleanup()
464 main.exit()
465 else:
466 main.cleanup()
467 main.exit()
468 if i == 2:
469 self.handle.sendline( "" )
470 self.handle.expect( "onos>" )
471
Jon Hall14a03b52016-05-11 12:07:30 -0700472 if debug:
473 # NOTE: This adds and average of .4 seconds per call
474 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
YPZhangebf9eb52016-05-12 15:20:24 -0700475 self.log( logStr,noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800476 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800477 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800478 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800479 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800480 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
481 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700482 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700483 main.log.debug( self.name + ": Raw output" )
484 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700485
486 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800487 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800488 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700489 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700490 main.log.debug( self.name + ": ansiEscape output" )
491 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700492
kelvin-onlabfb521662015-02-27 09:52:40 -0800493 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800494 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700495 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700496 main.log.debug( self.name + ": Removed extra returns " +
497 "from output" )
498 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700499
500 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800501 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700502 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700503 main.log.debug( self.name + ": parsed and stripped output" )
504 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700505
Jon Hall63604932015-02-26 17:09:50 -0800506 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700507 output = response.split( cmdStr.strip(), 1 )
508 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700509 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700510 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700511 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800512 output = output[1].strip()
513 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800514 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800515 return output
GlennRCed771242016-01-13 17:02:47 -0800516 except pexpect.TIMEOUT:
517 main.log.error( self.name + ":ONOS timeout" )
518 if debug:
519 main.log.debug( self.handle.before )
520 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700521 except IndexError:
522 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700523 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700524 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800525 except TypeError:
526 main.log.exception( self.name + ": Object not as expected" )
527 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400528 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800529 main.log.error( self.name + ": EOF exception found" )
530 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700531 if noExit:
532 main.cleanup()
533 return None
534 else:
535 main.cleanup()
536 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800537 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800538 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700539 if noExit:
540 main.cleanup()
541 return None
542 else:
543 main.cleanup()
544 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400545
kelvin8ec71442015-01-15 16:57:00 -0800546 # IMPORTANT NOTE:
547 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800548 # the cli command changing 'a:b' with 'aB'.
549 # Ex ) onos:topology > onosTopology
550 # onos:links > onosLinks
551 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800552
kelvin-onlabd3b64892015-01-20 13:26:24 -0800553 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800554 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400555 Adds a new cluster node by ID and address information.
556 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800557 * nodeId
558 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400559 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800560 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800561 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400562 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800563 cmdStr = "add-node " + str( nodeId ) + " " +\
564 str( ONOSIp ) + " " + str( tcpPort )
565 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700566 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800567 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800568 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800569 main.log.error( "Error in adding node" )
570 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800571 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400572 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800573 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400574 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800575 except AssertionError:
576 main.log.exception( "" )
577 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800578 except TypeError:
579 main.log.exception( self.name + ": Object not as expected" )
580 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400581 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800582 main.log.error( self.name + ": EOF exception found" )
583 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400584 main.cleanup()
585 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800586 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800587 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400588 main.cleanup()
589 main.exit()
590
kelvin-onlabd3b64892015-01-20 13:26:24 -0800591 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800592 """
andrewonlab86dc3082014-10-13 18:18:38 -0400593 Removes a cluster by ID
594 Issues command: 'remove-node [<node-id>]'
595 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800596 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800597 """
andrewonlab86dc3082014-10-13 18:18:38 -0400598 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400599
kelvin-onlabd3b64892015-01-20 13:26:24 -0800600 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700601 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700602 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800603 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700604 if re.search( "Error", handle ):
605 main.log.error( "Error in removing node" )
606 main.log.error( handle )
607 return main.FALSE
608 else:
609 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800610 except AssertionError:
611 main.log.exception( "" )
612 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800613 except TypeError:
614 main.log.exception( self.name + ": Object not as expected" )
615 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400616 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800617 main.log.error( self.name + ": EOF exception found" )
618 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400619 main.cleanup()
620 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800621 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800622 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400623 main.cleanup()
624 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400625
Jon Hall61282e32015-03-19 11:34:11 -0700626 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800627 """
andrewonlab7c211572014-10-15 16:45:20 -0400628 List the nodes currently visible
629 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700630 Optional argument:
631 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800632 """
andrewonlab7c211572014-10-15 16:45:20 -0400633 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700634 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700635 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700636 cmdStr += " -j"
637 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700638 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800639 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700640 return output
Jon Hallc6793552016-01-19 14:18:37 -0800641 except AssertionError:
642 main.log.exception( "" )
643 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800644 except TypeError:
645 main.log.exception( self.name + ": Object not as expected" )
646 return None
andrewonlab7c211572014-10-15 16:45:20 -0400647 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800648 main.log.error( self.name + ": EOF exception found" )
649 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400650 main.cleanup()
651 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800652 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800653 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400654 main.cleanup()
655 main.exit()
656
kelvin8ec71442015-01-15 16:57:00 -0800657 def topology( self ):
658 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700659 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700660 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700661 Return:
662 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800663 """
andrewonlab95ce8322014-10-13 14:12:04 -0400664 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700665 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800666 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800667 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700668 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400669 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800670 except AssertionError:
671 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800672 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800673 except TypeError:
674 main.log.exception( self.name + ": Object not as expected" )
675 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400676 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800677 main.log.error( self.name + ": EOF exception found" )
678 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400679 main.cleanup()
680 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800681 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800682 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400683 main.cleanup()
684 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800685
jenkins7ead5a82015-03-13 10:28:21 -0700686 def deviceRemove( self, deviceId ):
687 """
688 Removes particular device from storage
689
690 TODO: refactor this function
691 """
692 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700693 cmdStr = "device-remove " + str( deviceId )
694 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800695 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700696 if re.search( "Error", handle ):
697 main.log.error( "Error in removing device" )
698 main.log.error( handle )
699 return main.FALSE
700 else:
701 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800702 except AssertionError:
703 main.log.exception( "" )
704 return None
jenkins7ead5a82015-03-13 10:28:21 -0700705 except TypeError:
706 main.log.exception( self.name + ": Object not as expected" )
707 return None
708 except pexpect.EOF:
709 main.log.error( self.name + ": EOF exception found" )
710 main.log.error( self.name + ": " + self.handle.before )
711 main.cleanup()
712 main.exit()
713 except Exception:
714 main.log.exception( self.name + ": Uncaught exception!" )
715 main.cleanup()
716 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700717
kelvin-onlabd3b64892015-01-20 13:26:24 -0800718 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800719 """
Jon Hall7b02d952014-10-17 20:14:54 -0400720 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400721 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800722 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800723 """
andrewonlab86dc3082014-10-13 18:18:38 -0400724 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700725 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800726 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700727 cmdStr += " -j"
728 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800729 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700730 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800731 except AssertionError:
732 main.log.exception( "" )
733 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800734 except TypeError:
735 main.log.exception( self.name + ": Object not as expected" )
736 return None
andrewonlab7c211572014-10-15 16:45:20 -0400737 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800738 main.log.error( self.name + ": EOF exception found" )
739 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400740 main.cleanup()
741 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800742 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800743 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400744 main.cleanup()
745 main.exit()
746
kelvin-onlabd3b64892015-01-20 13:26:24 -0800747 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800748 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800749 This balances the devices across all controllers
750 by issuing command: 'onos> onos:balance-masters'
751 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800752 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800753 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800754 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700755 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800756 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700757 if re.search( "Error", handle ):
758 main.log.error( "Error in balancing masters" )
759 main.log.error( handle )
760 return main.FALSE
761 else:
762 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800763 except AssertionError:
764 main.log.exception( "" )
765 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800766 except TypeError:
767 main.log.exception( self.name + ": Object not as expected" )
768 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800769 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800770 main.log.error( self.name + ": EOF exception found" )
771 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800772 main.cleanup()
773 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800774 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800775 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800776 main.cleanup()
777 main.exit()
778
Jon Hallc6793552016-01-19 14:18:37 -0800779 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700780 """
781 Returns the output of the masters command.
782 Optional argument:
783 * jsonFormat - boolean indicating if you want output in json
784 """
785 try:
786 cmdStr = "onos:masters"
787 if jsonFormat:
788 cmdStr += " -j"
789 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700790 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800791 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700792 return output
Jon Hallc6793552016-01-19 14:18:37 -0800793 except AssertionError:
794 main.log.exception( "" )
795 return None
acsmars24950022015-07-30 18:00:43 -0700796 except TypeError:
797 main.log.exception( self.name + ": Object not as expected" )
798 return None
799 except pexpect.EOF:
800 main.log.error( self.name + ": EOF exception found" )
801 main.log.error( self.name + ": " + self.handle.before )
802 main.cleanup()
803 main.exit()
804 except Exception:
805 main.log.exception( self.name + ": Uncaught exception!" )
806 main.cleanup()
807 main.exit()
808
Jon Hallc6793552016-01-19 14:18:37 -0800809 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700810 """
811 Uses the master command to check that the devices' leadership
812 is evenly divided
813
814 Dependencies: checkMasters() and summary()
815
Jon Hall6509dbf2016-06-21 17:01:17 -0700816 Returns main.TRUE if the devices are balanced
817 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700818 Exits on Exception
819 Returns None on TypeError
820 """
821 try:
Jon Hallc6793552016-01-19 14:18:37 -0800822 summaryOutput = self.summary()
823 totalDevices = json.loads( summaryOutput )[ "devices" ]
824 except ( TypeError, ValueError ):
825 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
826 return None
827 try:
acsmars24950022015-07-30 18:00:43 -0700828 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800829 mastersOutput = self.checkMasters()
830 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700831 first = masters[ 0 ][ "size" ]
832 for master in masters:
833 totalOwnedDevices += master[ "size" ]
834 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
835 main.log.error( "Mastership not balanced" )
836 main.log.info( "\n" + self.checkMasters( False ) )
837 return main.FALSE
838 main.log.info( "Mastership balanced between " \
839 + str( len(masters) ) + " masters" )
840 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800841 except ( TypeError, ValueError ):
842 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700843 return None
844 except pexpect.EOF:
845 main.log.error( self.name + ": EOF exception found" )
846 main.log.error( self.name + ": " + self.handle.before )
847 main.cleanup()
848 main.exit()
849 except Exception:
850 main.log.exception( self.name + ": Uncaught exception!" )
851 main.cleanup()
852 main.exit()
853
YPZhangfebf7302016-05-24 16:45:56 -0700854 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800855 """
Jon Halle8217482014-10-17 13:49:14 -0400856 Lists all core links
857 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800858 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800859 """
Jon Halle8217482014-10-17 13:49:14 -0400860 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700861 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800862 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700863 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700864 handle = self.sendline( cmdStr, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -0800865 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700866 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800867 except AssertionError:
868 main.log.exception( "" )
869 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800870 except TypeError:
871 main.log.exception( self.name + ": Object not as expected" )
872 return None
Jon Halle8217482014-10-17 13:49:14 -0400873 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800874 main.log.error( self.name + ": EOF exception found" )
875 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400876 main.cleanup()
877 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800878 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800879 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400880 main.cleanup()
881 main.exit()
882
kelvin-onlabd3b64892015-01-20 13:26:24 -0800883 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800884 """
Jon Halle8217482014-10-17 13:49:14 -0400885 Lists all ports
886 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800887 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800888 """
Jon Halle8217482014-10-17 13:49:14 -0400889 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700890 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800891 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700892 cmdStr += " -j"
893 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800894 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700895 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800896 except AssertionError:
897 main.log.exception( "" )
898 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800899 except TypeError:
900 main.log.exception( self.name + ": Object not as expected" )
901 return None
Jon Halle8217482014-10-17 13:49:14 -0400902 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800903 main.log.error( self.name + ": EOF exception found" )
904 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400905 main.cleanup()
906 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800907 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800908 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400909 main.cleanup()
910 main.exit()
911
kelvin-onlabd3b64892015-01-20 13:26:24 -0800912 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800913 """
Jon Hall983a1702014-10-28 18:44:22 -0400914 Lists all devices and the controllers with roles assigned to them
915 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800916 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800917 """
andrewonlab7c211572014-10-15 16:45:20 -0400918 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700919 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800920 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700921 cmdStr += " -j"
922 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800923 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700924 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800925 except AssertionError:
926 main.log.exception( "" )
927 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800928 except TypeError:
929 main.log.exception( self.name + ": Object not as expected" )
930 return None
Jon Hall983a1702014-10-28 18:44:22 -0400931 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800932 main.log.error( self.name + ": EOF exception found" )
933 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400934 main.cleanup()
935 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800936 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800937 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400938 main.cleanup()
939 main.exit()
940
kelvin-onlabd3b64892015-01-20 13:26:24 -0800941 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800942 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800943 Given the a string containing the json representation of the "roles"
944 cli command and a partial or whole device id, returns a json object
945 containing the roles output for the first device whose id contains
946 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400947
948 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800949 A dict of the role assignments for the given device or
950 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800951 """
Jon Hall983a1702014-10-28 18:44:22 -0400952 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800953 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400954 return None
955 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800956 rawRoles = self.roles()
957 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800958 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800959 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800960 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800961 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400962 return device
963 return None
Jon Hallc6793552016-01-19 14:18:37 -0800964 except ( TypeError, ValueError ):
965 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800966 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400967 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800968 main.log.error( self.name + ": EOF exception found" )
969 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400970 main.cleanup()
971 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800972 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800973 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400974 main.cleanup()
975 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800976
kelvin-onlabd3b64892015-01-20 13:26:24 -0800977 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800978 """
Jon Hall94fd0472014-12-08 11:52:42 -0800979 Iterates through each device and checks if there is a master assigned
980 Returns: main.TRUE if each device has a master
981 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800982 """
Jon Hall94fd0472014-12-08 11:52:42 -0800983 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800984 rawRoles = self.roles()
985 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800986 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800987 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800988 # print device
989 if device[ 'master' ] == "none":
990 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800991 return main.FALSE
992 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800993 except ( TypeError, ValueError ):
994 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800995 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800996 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800997 main.log.error( self.name + ": EOF exception found" )
998 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800999 main.cleanup()
1000 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001001 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001002 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001003 main.cleanup()
1004 main.exit()
1005
kelvin-onlabd3b64892015-01-20 13:26:24 -08001006 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001007 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001008 Returns string of paths, and the cost.
1009 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001010 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001011 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001012 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1013 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001014 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001015 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001016 main.log.error( "Error in getting paths" )
1017 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001018 else:
kelvin8ec71442015-01-15 16:57:00 -08001019 path = handle.split( ";" )[ 0 ]
1020 cost = handle.split( ";" )[ 1 ]
1021 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001022 except AssertionError:
1023 main.log.exception( "" )
1024 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001025 except TypeError:
1026 main.log.exception( self.name + ": Object not as expected" )
1027 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001028 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001029 main.log.error( self.name + ": EOF exception found" )
1030 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001031 main.cleanup()
1032 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001033 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001034 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001035 main.cleanup()
1036 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001037
kelvin-onlabd3b64892015-01-20 13:26:24 -08001038 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001039 """
Jon Hallffb386d2014-11-21 13:43:38 -08001040 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001041 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001042 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001043 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001044 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001045 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001046 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001047 cmdStr += " -j"
1048 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001049 if handle:
1050 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001051 # TODO: Maybe make this less hardcoded
1052 # ConsistentMap Exceptions
1053 assert "org.onosproject.store.service" not in handle
1054 # Node not leader
1055 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001056 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001057 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001058 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001059 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001060 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001061 except TypeError:
1062 main.log.exception( self.name + ": Object not as expected" )
1063 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001064 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001065 main.log.error( self.name + ": EOF exception found" )
1066 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001067 main.cleanup()
1068 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001069 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001070 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001071 main.cleanup()
1072 main.exit()
1073
kelvin-onlabd3b64892015-01-20 13:26:24 -08001074 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001075 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001076 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001077
Jon Hallefbd9792015-03-05 16:11:36 -08001078 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001079 partial mac address
1080
Jon Hall42db6dc2014-10-24 19:03:48 -04001081 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001082 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001083 try:
kelvin8ec71442015-01-15 16:57:00 -08001084 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001085 return None
1086 else:
1087 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001088 rawHosts = self.hosts()
1089 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001090 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001091 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001092 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001093 if not host:
1094 pass
1095 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001096 return host
1097 return None
Jon Hallc6793552016-01-19 14:18:37 -08001098 except ( TypeError, ValueError ):
1099 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001100 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001101 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001102 main.log.error( self.name + ": EOF exception found" )
1103 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001104 main.cleanup()
1105 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001106 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001107 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001108 main.cleanup()
1109 main.exit()
1110
kelvin-onlabd3b64892015-01-20 13:26:24 -08001111 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001112 """
1113 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001114 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001115
andrewonlab3f0a4af2014-10-17 12:25:14 -04001116 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001117 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001118 IMPORTANT:
1119 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001120 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001121 Furthermore, it assumes that value of VLAN is '-1'
1122 Description:
kelvin8ec71442015-01-15 16:57:00 -08001123 Converts mininet hosts ( h1, h2, h3... ) into
1124 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1125 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001126 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001127 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001128
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001130 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001131 hostHex = hex( int( host ) ).zfill( 12 )
1132 hostHex = str( hostHex ).replace( 'x', '0' )
1133 i = iter( str( hostHex ) )
1134 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1135 hostHex = hostHex + "/-1"
1136 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001137
kelvin-onlabd3b64892015-01-20 13:26:24 -08001138 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001139
Jon Halld4d4b372015-01-28 16:02:41 -08001140 except TypeError:
1141 main.log.exception( self.name + ": Object not as expected" )
1142 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001143 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001144 main.log.error( self.name + ": EOF exception found" )
1145 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001146 main.cleanup()
1147 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001148 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001149 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001150 main.cleanup()
1151 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001152
Jeremy Songsterff553672016-05-12 17:06:23 -07001153 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="" ):
kelvin8ec71442015-01-15 16:57:00 -08001154 """
andrewonlabe6745342014-10-17 14:29:13 -04001155 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001156 * hostIdOne: ONOS host id for host1
1157 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001158 Optional:
1159 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001160 * setVlan: specify a VLAN id treatment
andrewonlabe6745342014-10-17 14:29:13 -04001161 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001162 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001163 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001164 Returns:
1165 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001166 """
andrewonlabe6745342014-10-17 14:29:13 -04001167 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001168 cmdStr = "add-host-intent "
1169 if vlanId:
1170 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001171 if setVlan:
1172 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001173 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001174 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001175 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001176 if re.search( "Error", handle ):
1177 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001178 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001179 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001180 else:
1181 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001182 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1183 match = re.search('id=0x([\da-f]+),', handle)
1184 if match:
1185 return match.group()[3:-1]
1186 else:
1187 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001188 main.log.debug( "Response from ONOS was: " +
1189 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001190 return None
Jon Hallc6793552016-01-19 14:18:37 -08001191 except AssertionError:
1192 main.log.exception( "" )
1193 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001194 except TypeError:
1195 main.log.exception( self.name + ": Object not as expected" )
1196 return None
andrewonlabe6745342014-10-17 14:29:13 -04001197 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001198 main.log.error( self.name + ": EOF exception found" )
1199 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001200 main.cleanup()
1201 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001202 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001203 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001204 main.cleanup()
1205 main.exit()
1206
kelvin-onlabd3b64892015-01-20 13:26:24 -08001207 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001208 """
andrewonlab7b31d232014-10-24 13:31:47 -04001209 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001210 * ingressDevice: device id of ingress device
1211 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001212 Optional:
1213 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001214 Description:
1215 Adds an optical intent by specifying an ingress and egress device
1216 Returns:
1217 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001218 """
andrewonlab7b31d232014-10-24 13:31:47 -04001219 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001220 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1221 " " + str( egressDevice )
1222 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001223 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001224 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001225 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001226 main.log.error( "Error in adding Optical intent" )
1227 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001228 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001229 main.log.info( "Optical intent installed between " +
1230 str( ingressDevice ) + " and " +
1231 str( egressDevice ) )
1232 match = re.search('id=0x([\da-f]+),', handle)
1233 if match:
1234 return match.group()[3:-1]
1235 else:
1236 main.log.error( "Error, intent ID not found" )
1237 return None
Jon Hallc6793552016-01-19 14:18:37 -08001238 except AssertionError:
1239 main.log.exception( "" )
1240 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001241 except TypeError:
1242 main.log.exception( self.name + ": Object not as expected" )
1243 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001244 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001245 main.log.error( self.name + ": EOF exception found" )
1246 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001247 main.cleanup()
1248 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001249 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001250 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001251 main.cleanup()
1252 main.exit()
1253
kelvin-onlabd3b64892015-01-20 13:26:24 -08001254 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001255 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001256 ingressDevice,
1257 egressDevice,
1258 portIngress="",
1259 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001260 ethType="",
1261 ethSrc="",
1262 ethDst="",
1263 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001264 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001265 ipProto="",
1266 ipSrc="",
1267 ipDst="",
1268 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001269 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001270 vlanId="",
1271 setVlan="" ):
kelvin8ec71442015-01-15 16:57:00 -08001272 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001273 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001274 * ingressDevice: device id of ingress device
1275 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001276 Optional:
1277 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001278 * ethSrc: specify ethSrc ( i.e. src mac addr )
1279 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001280 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001281 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001282 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001283 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001284 * ipSrc: specify ip source address
1285 * ipDst: specify ip destination address
1286 * tcpSrc: specify tcp source port
1287 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001288 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001289 * setVlan: specify a VLAN id treatment
andrewonlab4dbb4d82014-10-17 18:22:31 -04001290 Description:
kelvin8ec71442015-01-15 16:57:00 -08001291 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001292 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001293 Returns:
1294 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001295
Jon Halle3f39ff2015-01-13 11:50:53 -08001296 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001297 options developers provide for point-to-point
1298 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001299 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001300 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001301 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001302
Jeremy Songsterff553672016-05-12 17:06:23 -07001303 if ethType:
1304 cmd += " --ethType " + str( ethType )
1305 if ethSrc:
1306 cmd += " --ethSrc " + str( ethSrc )
1307 if ethDst:
1308 cmd += " --ethDst " + str( ethDst )
1309 if bandwidth:
1310 cmd += " --bandwidth " + str( bandwidth )
1311 if lambdaAlloc:
1312 cmd += " --lambda "
1313 if ipProto:
1314 cmd += " --ipProto " + str( ipProto )
1315 if ipSrc:
1316 cmd += " --ipSrc " + str( ipSrc )
1317 if ipDst:
1318 cmd += " --ipDst " + str( ipDst )
1319 if tcpSrc:
1320 cmd += " --tcpSrc " + str( tcpSrc )
1321 if tcpDst:
1322 cmd += " --tcpDst " + str( tcpDst )
1323 if vlanId:
1324 cmd += " -v " + str( vlanId )
1325 if setVlan:
1326 cmd += " --setVlan " + str( setVlan )
andrewonlab289e4b72014-10-21 21:24:18 -04001327
kelvin8ec71442015-01-15 16:57:00 -08001328 # Check whether the user appended the port
1329 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001330 if "/" in ingressDevice:
1331 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001332 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001333 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001334 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001335 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001336 # Would it make sense to throw an exception and exit
1337 # the test?
1338 return None
andrewonlab36af3822014-11-18 17:48:18 -05001339
kelvin8ec71442015-01-15 16:57:00 -08001340 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001341 str( ingressDevice ) + "/" +\
1342 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001343
kelvin-onlabd3b64892015-01-20 13:26:24 -08001344 if "/" in egressDevice:
1345 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001346 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001347 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001348 main.log.error( "You must specify the egress port" )
1349 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001350
kelvin8ec71442015-01-15 16:57:00 -08001351 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001352 str( egressDevice ) + "/" +\
1353 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001354
kelvin-onlab898a6c62015-01-16 14:13:53 -08001355 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001356 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001357 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001358 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001359 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001360 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001361 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001362 # TODO: print out all the options in this message?
1363 main.log.info( "Point-to-point intent installed between " +
1364 str( ingressDevice ) + " and " +
1365 str( egressDevice ) )
1366 match = re.search('id=0x([\da-f]+),', handle)
1367 if match:
1368 return match.group()[3:-1]
1369 else:
1370 main.log.error( "Error, intent ID not found" )
1371 return None
Jon Hallc6793552016-01-19 14:18:37 -08001372 except AssertionError:
1373 main.log.exception( "" )
1374 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001375 except TypeError:
1376 main.log.exception( self.name + ": Object not as expected" )
1377 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001378 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001379 main.log.error( self.name + ": EOF exception found" )
1380 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001381 main.cleanup()
1382 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001383 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001384 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001385 main.cleanup()
1386 main.exit()
1387
kelvin-onlabd3b64892015-01-20 13:26:24 -08001388 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001389 self,
shahshreyac2f97072015-03-19 17:04:29 -07001390 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001391 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001392 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001393 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001394 ethType="",
1395 ethSrc="",
1396 ethDst="",
1397 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001398 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001399 ipProto="",
1400 ipSrc="",
1401 ipDst="",
1402 tcpSrc="",
1403 tcpDst="",
1404 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001405 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001406 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001407 setVlan="",
1408 partial=False ):
kelvin8ec71442015-01-15 16:57:00 -08001409 """
shahshreyad0c80432014-12-04 16:56:05 -08001410 Note:
shahshreya70622b12015-03-19 17:19:00 -07001411 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001412 is same. That is, all ingress devices include port numbers
1413 with a "/" or all ingress devices could specify device
1414 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001415 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001416 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001417 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001418 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001419 Optional:
1420 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001421 * ethSrc: specify ethSrc ( i.e. src mac addr )
1422 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001423 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001424 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001425 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001426 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001427 * ipSrc: specify ip source address
1428 * ipDst: specify ip destination address
1429 * tcpSrc: specify tcp source port
1430 * tcpDst: specify tcp destination port
1431 * setEthSrc: action to Rewrite Source MAC Address
1432 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001433 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001434 * setVlan: specify VLAN Id treatment
shahshreyad0c80432014-12-04 16:56:05 -08001435 Description:
kelvin8ec71442015-01-15 16:57:00 -08001436 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001437 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001438 Returns:
1439 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001440
Jon Halle3f39ff2015-01-13 11:50:53 -08001441 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001442 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001443 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001444 """
shahshreyad0c80432014-12-04 16:56:05 -08001445 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001446 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001447
Jeremy Songsterff553672016-05-12 17:06:23 -07001448 if ethType:
1449 cmd += " --ethType " + str( ethType )
1450 if ethSrc:
1451 cmd += " --ethSrc " + str( ethSrc )
1452 if ethDst:
1453 cmd += " --ethDst " + str( ethDst )
1454 if bandwidth:
1455 cmd += " --bandwidth " + str( bandwidth )
1456 if lambdaAlloc:
1457 cmd += " --lambda "
1458 if ipProto:
1459 cmd += " --ipProto " + str( ipProto )
1460 if ipSrc:
1461 cmd += " --ipSrc " + str( ipSrc )
1462 if ipDst:
1463 cmd += " --ipDst " + str( ipDst )
1464 if tcpSrc:
1465 cmd += " --tcpSrc " + str( tcpSrc )
1466 if tcpDst:
1467 cmd += " --tcpDst " + str( tcpDst )
1468 if setEthSrc:
1469 cmd += " --setEthSrc " + str( setEthSrc )
1470 if setEthDst:
1471 cmd += " --setEthDst " + str( setEthDst )
1472 if vlanId:
1473 cmd += " -v " + str( vlanId )
1474 if setVlan:
1475 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001476 if partial:
1477 cmd += " --partial"
shahshreyad0c80432014-12-04 16:56:05 -08001478
kelvin8ec71442015-01-15 16:57:00 -08001479 # Check whether the user appended the port
1480 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001481
1482 if portIngressList is None:
1483 for ingressDevice in ingressDeviceList:
1484 if "/" in ingressDevice:
1485 cmd += " " + str( ingressDevice )
1486 else:
1487 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001488 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001489 # TODO: perhaps more meaningful return
1490 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001491 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001492 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001493 for ingressDevice, portIngress in zip( ingressDeviceList,
1494 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001495 cmd += " " + \
1496 str( ingressDevice ) + "/" +\
1497 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001498 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001499 main.log.error( "Device list and port list does not " +
1500 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001501 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001502 if "/" in egressDevice:
1503 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001504 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001505 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001506 main.log.error( "You must specify " +
1507 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001508 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001509
kelvin8ec71442015-01-15 16:57:00 -08001510 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001511 str( egressDevice ) + "/" +\
1512 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001513 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001514 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001515 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001516 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001517 main.log.error( "Error in adding multipoint-to-singlepoint " +
1518 "intent" )
1519 return None
shahshreyad0c80432014-12-04 16:56:05 -08001520 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001521 match = re.search('id=0x([\da-f]+),', handle)
1522 if match:
1523 return match.group()[3:-1]
1524 else:
1525 main.log.error( "Error, intent ID not found" )
1526 return None
Jon Hallc6793552016-01-19 14:18:37 -08001527 except AssertionError:
1528 main.log.exception( "" )
1529 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001530 except TypeError:
1531 main.log.exception( self.name + ": Object not as expected" )
1532 return None
1533 except pexpect.EOF:
1534 main.log.error( self.name + ": EOF exception found" )
1535 main.log.error( self.name + ": " + self.handle.before )
1536 main.cleanup()
1537 main.exit()
1538 except Exception:
1539 main.log.exception( self.name + ": Uncaught exception!" )
1540 main.cleanup()
1541 main.exit()
1542
1543 def addSinglepointToMultipointIntent(
1544 self,
1545 ingressDevice,
1546 egressDeviceList,
1547 portIngress="",
1548 portEgressList=None,
1549 ethType="",
1550 ethSrc="",
1551 ethDst="",
1552 bandwidth="",
1553 lambdaAlloc=False,
1554 ipProto="",
1555 ipSrc="",
1556 ipDst="",
1557 tcpSrc="",
1558 tcpDst="",
1559 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001560 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001561 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001562 setVlan="",
1563 partial=False ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001564 """
1565 Note:
1566 This function assumes the format of all egress devices
1567 is same. That is, all egress devices include port numbers
1568 with a "/" or all egress devices could specify device
1569 ids and port numbers seperately.
1570 Required:
1571 * EgressDeviceList: List of device ids of egress device
1572 ( Atleast 2 eress devices required in the list )
1573 * ingressDevice: device id of ingress device
1574 Optional:
1575 * ethType: specify ethType
1576 * ethSrc: specify ethSrc ( i.e. src mac addr )
1577 * ethDst: specify ethDst ( i.e. dst mac addr )
1578 * bandwidth: specify bandwidth capacity of link
1579 * lambdaAlloc: if True, intent will allocate lambda
1580 for the specified intent
1581 * ipProto: specify ip protocol
1582 * ipSrc: specify ip source address
1583 * ipDst: specify ip destination address
1584 * tcpSrc: specify tcp source port
1585 * tcpDst: specify tcp destination port
1586 * setEthSrc: action to Rewrite Source MAC Address
1587 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001588 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001589 * setVlan: specify VLAN ID treatment
kelvin-onlabb9408212015-04-01 13:34:04 -07001590 Description:
1591 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1592 specifying device id's and optional fields
1593 Returns:
1594 A string of the intent id or None on error
1595
1596 NOTE: This function may change depending on the
1597 options developers provide for singlepoint-to-multipoint
1598 intent via cli
1599 """
1600 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001601 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001602
Jeremy Songsterff553672016-05-12 17:06:23 -07001603 if ethType:
1604 cmd += " --ethType " + str( ethType )
1605 if ethSrc:
1606 cmd += " --ethSrc " + str( ethSrc )
1607 if ethDst:
1608 cmd += " --ethDst " + str( ethDst )
1609 if bandwidth:
1610 cmd += " --bandwidth " + str( bandwidth )
1611 if lambdaAlloc:
1612 cmd += " --lambda "
1613 if ipProto:
1614 cmd += " --ipProto " + str( ipProto )
1615 if ipSrc:
1616 cmd += " --ipSrc " + str( ipSrc )
1617 if ipDst:
1618 cmd += " --ipDst " + str( ipDst )
1619 if tcpSrc:
1620 cmd += " --tcpSrc " + str( tcpSrc )
1621 if tcpDst:
1622 cmd += " --tcpDst " + str( tcpDst )
1623 if setEthSrc:
1624 cmd += " --setEthSrc " + str( setEthSrc )
1625 if setEthDst:
1626 cmd += " --setEthDst " + str( setEthDst )
1627 if vlanId:
1628 cmd += " -v " + str( vlanId )
1629 if setVlan:
1630 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001631 if partial:
1632 cmd += " --partial"
kelvin-onlabb9408212015-04-01 13:34:04 -07001633
1634 # Check whether the user appended the port
1635 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001636
kelvin-onlabb9408212015-04-01 13:34:04 -07001637 if "/" in ingressDevice:
1638 cmd += " " + str( ingressDevice )
1639 else:
1640 if not portIngress:
1641 main.log.error( "You must specify " +
1642 "the Ingress port" )
1643 return main.FALSE
1644
1645 cmd += " " +\
1646 str( ingressDevice ) + "/" +\
1647 str( portIngress )
1648
1649 if portEgressList is None:
1650 for egressDevice in egressDeviceList:
1651 if "/" in egressDevice:
1652 cmd += " " + str( egressDevice )
1653 else:
1654 main.log.error( "You must specify " +
1655 "the egress port" )
1656 # TODO: perhaps more meaningful return
1657 return main.FALSE
1658 else:
1659 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001660 for egressDevice, portEgress in zip( egressDeviceList,
1661 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001662 cmd += " " + \
1663 str( egressDevice ) + "/" +\
1664 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001665 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001666 main.log.error( "Device list and port list does not " +
1667 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001668 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001669 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001670 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001671 # If error, return error message
1672 if re.search( "Error", handle ):
1673 main.log.error( "Error in adding singlepoint-to-multipoint " +
1674 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001675 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001676 else:
1677 match = re.search('id=0x([\da-f]+),', handle)
1678 if match:
1679 return match.group()[3:-1]
1680 else:
1681 main.log.error( "Error, intent ID not found" )
1682 return None
Jon Hallc6793552016-01-19 14:18:37 -08001683 except AssertionError:
1684 main.log.exception( "" )
1685 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001686 except TypeError:
1687 main.log.exception( self.name + ": Object not as expected" )
1688 return None
shahshreyad0c80432014-12-04 16:56:05 -08001689 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001690 main.log.error( self.name + ": EOF exception found" )
1691 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001692 main.cleanup()
1693 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001694 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001695 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001696 main.cleanup()
1697 main.exit()
1698
Hari Krishna9e232602015-04-13 17:29:08 -07001699 def addMplsIntent(
1700 self,
1701 ingressDevice,
1702 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001703 ingressPort="",
1704 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001705 ethType="",
1706 ethSrc="",
1707 ethDst="",
1708 bandwidth="",
1709 lambdaAlloc=False,
1710 ipProto="",
1711 ipSrc="",
1712 ipDst="",
1713 tcpSrc="",
1714 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001715 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001716 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001717 priority=""):
1718 """
1719 Required:
1720 * ingressDevice: device id of ingress device
1721 * egressDevice: device id of egress device
1722 Optional:
1723 * ethType: specify ethType
1724 * ethSrc: specify ethSrc ( i.e. src mac addr )
1725 * ethDst: specify ethDst ( i.e. dst mac addr )
1726 * bandwidth: specify bandwidth capacity of link
1727 * lambdaAlloc: if True, intent will allocate lambda
1728 for the specified intent
1729 * ipProto: specify ip protocol
1730 * ipSrc: specify ip source address
1731 * ipDst: specify ip destination address
1732 * tcpSrc: specify tcp source port
1733 * tcpDst: specify tcp destination port
1734 * ingressLabel: Ingress MPLS label
1735 * egressLabel: Egress MPLS label
1736 Description:
1737 Adds MPLS intent by
1738 specifying device id's and optional fields
1739 Returns:
1740 A string of the intent id or None on error
1741
1742 NOTE: This function may change depending on the
1743 options developers provide for MPLS
1744 intent via cli
1745 """
1746 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001747 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001748
Jeremy Songsterff553672016-05-12 17:06:23 -07001749 if ethType:
1750 cmd += " --ethType " + str( ethType )
1751 if ethSrc:
1752 cmd += " --ethSrc " + str( ethSrc )
1753 if ethDst:
1754 cmd += " --ethDst " + str( ethDst )
1755 if bandwidth:
1756 cmd += " --bandwidth " + str( bandwidth )
1757 if lambdaAlloc:
1758 cmd += " --lambda "
1759 if ipProto:
1760 cmd += " --ipProto " + str( ipProto )
1761 if ipSrc:
1762 cmd += " --ipSrc " + str( ipSrc )
1763 if ipDst:
1764 cmd += " --ipDst " + str( ipDst )
1765 if tcpSrc:
1766 cmd += " --tcpSrc " + str( tcpSrc )
1767 if tcpDst:
1768 cmd += " --tcpDst " + str( tcpDst )
1769 if ingressLabel:
1770 cmd += " --ingressLabel " + str( ingressLabel )
1771 if egressLabel:
1772 cmd += " --egressLabel " + str( egressLabel )
1773 if priority:
1774 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001775
1776 # Check whether the user appended the port
1777 # or provided it as an input
1778 if "/" in ingressDevice:
1779 cmd += " " + str( ingressDevice )
1780 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001781 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001782 main.log.error( "You must specify the ingress port" )
1783 return None
1784
1785 cmd += " " + \
1786 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001787 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001788
1789 if "/" in egressDevice:
1790 cmd += " " + str( egressDevice )
1791 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001792 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001793 main.log.error( "You must specify the egress port" )
1794 return None
1795
1796 cmd += " " +\
1797 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001798 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001799
1800 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001801 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001802 # If error, return error message
1803 if re.search( "Error", handle ):
1804 main.log.error( "Error in adding mpls intent" )
1805 return None
1806 else:
1807 # TODO: print out all the options in this message?
1808 main.log.info( "MPLS intent installed between " +
1809 str( ingressDevice ) + " and " +
1810 str( egressDevice ) )
1811 match = re.search('id=0x([\da-f]+),', handle)
1812 if match:
1813 return match.group()[3:-1]
1814 else:
1815 main.log.error( "Error, intent ID not found" )
1816 return None
Jon Hallc6793552016-01-19 14:18:37 -08001817 except AssertionError:
1818 main.log.exception( "" )
1819 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001820 except TypeError:
1821 main.log.exception( self.name + ": Object not as expected" )
1822 return None
1823 except pexpect.EOF:
1824 main.log.error( self.name + ": EOF exception found" )
1825 main.log.error( self.name + ": " + self.handle.before )
1826 main.cleanup()
1827 main.exit()
1828 except Exception:
1829 main.log.exception( self.name + ": Uncaught exception!" )
1830 main.cleanup()
1831 main.exit()
1832
Jon Hallefbd9792015-03-05 16:11:36 -08001833 def removeIntent( self, intentId, app='org.onosproject.cli',
1834 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001835 """
shahshreya1c818fc2015-02-26 13:44:08 -08001836 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001837 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001838 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001839 -p or --purge: Purge the intent from the store after removal
1840
Jon Halle3f39ff2015-01-13 11:50:53 -08001841 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001842 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001843 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001844 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001845 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001846 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001847 if purge:
1848 cmdStr += " -p"
1849 if sync:
1850 cmdStr += " -s"
1851
1852 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001853 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001854 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001855 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001856 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001857 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001858 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001859 # TODO: Should this be main.TRUE
1860 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001861 except AssertionError:
1862 main.log.exception( "" )
1863 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001864 except TypeError:
1865 main.log.exception( self.name + ": Object not as expected" )
1866 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001867 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001868 main.log.error( self.name + ": EOF exception found" )
1869 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001870 main.cleanup()
1871 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001872 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001873 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001874 main.cleanup()
1875 main.exit()
1876
YPZhangfebf7302016-05-24 16:45:56 -07001877 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001878 """
1879 Description:
1880 Remove all the intents
1881 Optional args:-
1882 -s or --sync: Waits for the removal before returning
1883 -p or --purge: Purge the intent from the store after removal
1884 Returns:
1885 Returns main.TRUE if all intents are removed, otherwise returns
1886 main.FALSE; Returns None for exception
1887 """
1888 try:
1889 cmdStr = "remove-intent"
1890 if purge:
1891 cmdStr += " -p"
1892 if sync:
1893 cmdStr += " -s"
1894
1895 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001896 handle = self.sendline( cmdStr, timeout=timeout )
Jeremy42df2e72016-02-23 16:37:46 -08001897 assert "Command not found:" not in handle, handle
1898 if re.search( "Error", handle ):
1899 main.log.error( "Error in removing intent" )
1900 return main.FALSE
1901 else:
1902 return main.TRUE
1903 except AssertionError:
1904 main.log.exception( "" )
1905 return None
1906 except TypeError:
1907 main.log.exception( self.name + ": Object not as expected" )
1908 return None
1909 except pexpect.EOF:
1910 main.log.error( self.name + ": EOF exception found" )
1911 main.log.error( self.name + ": " + self.handle.before )
1912 main.cleanup()
1913 main.exit()
1914 except Exception:
1915 main.log.exception( self.name + ": Uncaught exception!" )
1916 main.cleanup()
1917 main.exit()
1918
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001919 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001920 """
1921 Purges all WITHDRAWN Intents
1922 """
1923 try:
1924 cmdStr = "purge-intents"
1925 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001926 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001927 if re.search( "Error", handle ):
1928 main.log.error( "Error in purging intents" )
1929 return main.FALSE
1930 else:
1931 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001932 except AssertionError:
1933 main.log.exception( "" )
1934 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001935 except TypeError:
1936 main.log.exception( self.name + ": Object not as expected" )
1937 return None
1938 except pexpect.EOF:
1939 main.log.error( self.name + ": EOF exception found" )
1940 main.log.error( self.name + ": " + self.handle.before )
1941 main.cleanup()
1942 main.exit()
1943 except Exception:
1944 main.log.exception( self.name + ": Uncaught exception!" )
1945 main.cleanup()
1946 main.exit()
1947
kelvin-onlabd3b64892015-01-20 13:26:24 -08001948 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001949 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001950 NOTE: This method should be used after installing application:
1951 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001952 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001953 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001954 Description:
1955 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001956 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001957 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001958 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001959 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001960 cmdStr += " -j"
1961 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001962 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001963 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001964 except AssertionError:
1965 main.log.exception( "" )
1966 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001967 except TypeError:
1968 main.log.exception( self.name + ": Object not as expected" )
1969 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001970 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001971 main.log.error( self.name + ": EOF exception found" )
1972 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001973 main.cleanup()
1974 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001975 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001976 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001977 main.cleanup()
1978 main.exit()
1979
pingping-lin54b03372015-08-13 14:43:10 -07001980 def ipv4RouteNumber( self ):
1981 """
1982 NOTE: This method should be used after installing application:
1983 onos-app-sdnip
1984 Description:
1985 Obtain the total IPv4 routes number in the system
1986 """
1987 try:
1988 cmdStr = "routes -s -j"
1989 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001990 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001991 jsonResult = json.loads( handle )
1992 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001993 except AssertionError:
1994 main.log.exception( "" )
1995 return None
1996 except ( TypeError, ValueError ):
1997 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001998 return None
1999 except pexpect.EOF:
2000 main.log.error( self.name + ": EOF exception found" )
2001 main.log.error( self.name + ": " + self.handle.before )
2002 main.cleanup()
2003 main.exit()
2004 except Exception:
2005 main.log.exception( self.name + ": Uncaught exception!" )
2006 main.cleanup()
2007 main.exit()
2008
pingping-lin8244a3b2015-09-16 13:36:56 -07002009 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002010 """
andrewonlabe6745342014-10-17 14:29:13 -04002011 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002012 Obtain intents from the ONOS cli.
2013 Optional:
2014 * jsonFormat: Enable output formatting in json, default to True
2015 * summary: Whether only output the intent summary, defaults to False
2016 * type: Only output a certain type of intent. This options is valid
2017 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002018 """
andrewonlabe6745342014-10-17 14:29:13 -04002019 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002020 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002021 if summary:
2022 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002023 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002024 cmdStr += " -j"
2025 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002026 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002027 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002028 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002029 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002030 else:
Jon Hallff566d52016-01-15 14:45:36 -08002031 intentType = ""
2032 # IF we want the summary of a specific intent type
2033 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002034 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002035 if intentType in jsonResult.keys():
2036 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002037 else:
Jon Hallff566d52016-01-15 14:45:36 -08002038 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002039 return handle
2040 else:
2041 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002042 except AssertionError:
2043 main.log.exception( "" )
2044 return None
2045 except ( TypeError, ValueError ):
2046 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002047 return None
2048 except pexpect.EOF:
2049 main.log.error( self.name + ": EOF exception found" )
2050 main.log.error( self.name + ": " + self.handle.before )
2051 main.cleanup()
2052 main.exit()
2053 except Exception:
2054 main.log.exception( self.name + ": Uncaught exception!" )
2055 main.cleanup()
2056 main.exit()
2057
kelvin-onlab54400a92015-02-26 18:05:51 -08002058 def getIntentState(self, intentsId, intentsJson=None):
2059 """
You Wangfdcbfc42016-05-16 12:16:53 -07002060 Description:
2061 Gets intent state. Accepts a single intent ID (string type) or a
2062 list of intent IDs.
2063 Parameters:
2064 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002065 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002066 Returns:
2067 Returns the state (string type) of the ID if a single intent ID is
2068 accepted.
2069 Returns a list of dictionaries if a list of intent IDs is accepted,
2070 and each dictionary maps 'id' to the Intent ID and 'state' to
2071 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002072 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002073 try:
2074 state = "State is Undefined"
2075 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002076 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002077 else:
Jon Hallc6793552016-01-19 14:18:37 -08002078 rawJson = intentsJson
2079 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002080 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002081 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002082 if intentsId == intent[ 'id' ]:
2083 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002084 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002085 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2086 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002087 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002088 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002089 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002090 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002091 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002092 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002093 if intentsId[ i ] == intents[ 'id' ]:
2094 stateDict[ 'state' ] = intents[ 'state' ]
2095 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002096 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002097 break
Jon Hallefbd9792015-03-05 16:11:36 -08002098 if len( intentsId ) != len( dictList ):
2099 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002100 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002101 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002102 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002103 return None
Jon Hallc6793552016-01-19 14:18:37 -08002104 except ( TypeError, ValueError ):
2105 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002106 return None
2107 except pexpect.EOF:
2108 main.log.error( self.name + ": EOF exception found" )
2109 main.log.error( self.name + ": " + self.handle.before )
2110 main.cleanup()
2111 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002112 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002113 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002114 main.cleanup()
2115 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002116
kelvin-onlabf512e942015-06-08 19:42:59 -07002117 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002118 """
2119 Description:
2120 Check intents state
2121 Required:
2122 intentsId - List of intents ID to be checked
2123 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002124 expectedState - Check the expected state(s) of each intents
2125 state in the list.
2126 *NOTE: You can pass in a list of expected state,
2127 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002128 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002129 Returns main.TRUE only if all intent are the same as expected states
2130 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002131 """
2132 try:
2133 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002134 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002135 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002136 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002137 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002138 "getting intents state" )
2139 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002140
2141 if isinstance( expectedState, types.StringType ):
2142 for intents in intentsDict:
2143 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002144 main.log.debug( self.name + " : Intent ID - " +
2145 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002146 " actual state = " +
2147 intents.get( 'state' )
2148 + " does not equal expected state = "
2149 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002150 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002151
2152 elif isinstance( expectedState, types.ListType ):
2153 for intents in intentsDict:
2154 if not any( state == intents.get( 'state' ) for state in
2155 expectedState ):
2156 main.log.debug( self.name + " : Intent ID - " +
2157 intents.get( 'id' ) +
2158 " actual state = " +
2159 intents.get( 'state' ) +
2160 " does not equal expected states = "
2161 + str( expectedState ) )
2162 returnValue = main.FALSE
2163
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002164 if returnValue == main.TRUE:
2165 main.log.info( self.name + ": All " +
2166 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002167 " intents are in " + str( expectedState ) +
2168 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002169 return returnValue
2170 except TypeError:
2171 main.log.exception( self.name + ": Object not as expected" )
2172 return None
2173 except pexpect.EOF:
2174 main.log.error( self.name + ": EOF exception found" )
2175 main.log.error( self.name + ": " + self.handle.before )
2176 main.cleanup()
2177 main.exit()
2178 except Exception:
2179 main.log.exception( self.name + ": Uncaught exception!" )
2180 main.cleanup()
2181 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002182
You Wang66518af2016-05-16 15:32:59 -07002183 def compareIntent( self, intentDict ):
2184 """
2185 Description:
2186 Compare the intent ids and states provided in the argument with all intents in ONOS
2187 Return:
2188 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2189 Arguments:
2190 intentDict: a dictionary which maps intent ids to intent states
2191 """
2192 try:
2193 intentsRaw = self.intents()
2194 intentsJson = json.loads( intentsRaw )
2195 intentDictONOS = {}
2196 for intent in intentsJson:
2197 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
2198 if len( intentDict ) != len( intentDictONOS ):
2199 main.log.info( self.name + ": expected intent count does not match that in ONOS, " +
2200 str( len( intentDict ) ) + " expected and " +
2201 str( len( intentDictONOS ) ) + " actual" )
2202 return main.FALSE
2203 returnValue = main.TRUE
2204 for intentID in intentDict.keys():
2205 if not intentID in intentDictONOS.keys():
2206 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2207 returnValue = main.FALSE
2208 elif intentDict[ intentID ] != intentDictONOS[ intentID ]:
2209 main.log.debug( self.name + ": intent ID - " + intentID +
2210 " expected state is " + intentDict[ intentID ] +
2211 " but actual state is " + intentDictONOS[ intentID ] )
2212 returnValue = main.FALSE
2213 if returnValue == main.TRUE:
2214 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2215 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002216 except KeyError:
2217 main.log.exception( self.name + ": KeyError exception found" )
2218 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002219 except ( TypeError, ValueError ):
2220 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002221 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002222 except pexpect.EOF:
2223 main.log.error( self.name + ": EOF exception found" )
2224 main.log.error( self.name + ": " + self.handle.before )
2225 main.cleanup()
2226 main.exit()
2227 except Exception:
2228 main.log.exception( self.name + ": Uncaught exception!" )
2229 main.cleanup()
2230 main.exit()
2231
GlennRCed771242016-01-13 17:02:47 -08002232 def checkIntentSummary( self, timeout=60 ):
2233 """
2234 Description:
2235 Check the number of installed intents.
2236 Optional:
2237 timeout - the timeout for pexcept
2238 Return:
2239 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2240 , otherwise, returns main.FALSE.
2241 """
2242
2243 try:
2244 cmd = "intents -s -j"
2245
2246 # Check response if something wrong
2247 response = self.sendline( cmd, timeout=timeout )
2248 if response == None:
YPZhang0584d432016-06-21 15:20:13 -07002249 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002250 response = json.loads( response )
2251
2252 # get total and installed number, see if they are match
2253 allState = response.get( 'all' )
2254 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002255 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002256 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002257 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002258 return main.FALSE
2259
Jon Hallc6793552016-01-19 14:18:37 -08002260 except ( TypeError, ValueError ):
2261 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002262 return None
2263 except pexpect.EOF:
2264 main.log.error( self.name + ": EOF exception found" )
2265 main.log.error( self.name + ": " + self.handle.before )
2266 main.cleanup()
2267 main.exit()
2268 except Exception:
2269 main.log.exception( self.name + ": Uncaught exception!" )
2270 main.cleanup()
2271 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002272 except pexpect.TIMEOUT:
2273 main.log.error( self.name + ": ONOS timeout" )
2274 return None
GlennRCed771242016-01-13 17:02:47 -08002275
YPZhangebf9eb52016-05-12 15:20:24 -07002276 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -08002277 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002278 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002279 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002280 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002281 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002282 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002283 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002284 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002285 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002286 cmdStr += " -j "
2287 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002288 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002289 assert "Command not found:" not in handle, handle
2290 if re.search( "Error:", handle ):
2291 main.log.error( self.name + ": flows() response: " +
2292 str( handle ) )
2293 return handle
2294 except AssertionError:
2295 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002296 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002297 except TypeError:
2298 main.log.exception( self.name + ": Object not as expected" )
2299 return None
Jon Hallc6793552016-01-19 14:18:37 -08002300 except pexpect.TIMEOUT:
2301 main.log.error( self.name + ": ONOS timeout" )
2302 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002303 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002304 main.log.error( self.name + ": EOF exception found" )
2305 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002306 main.cleanup()
2307 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002308 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002309 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002310 main.cleanup()
2311 main.exit()
2312
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002313 def checkFlowCount(self, min=0, timeout=60 ):
2314 count = int(self.getTotalFlowsNum( timeout=timeout ))
2315 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002316
YPZhangebf9eb52016-05-12 15:20:24 -07002317 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002318 """
2319 Description:
GlennRCed771242016-01-13 17:02:47 -08002320 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002321 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2322 if the count of those states is 0, which means all current flows
2323 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002324 Optional:
GlennRCed771242016-01-13 17:02:47 -08002325 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002326 Return:
2327 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002328 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002329 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002330 """
2331 try:
GlennRCed771242016-01-13 17:02:47 -08002332 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2333 checkedStates = []
2334 statesCount = [0, 0, 0, 0]
2335 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002336 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002337 if rawFlows:
2338 # if we didn't get flows or flows function return None, we should return
2339 # main.Flase
2340 checkedStates.append( json.loads( rawFlows ) )
2341 else:
2342 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002343 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002344 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002345 try:
2346 statesCount[i] += int( c.get( "flowCount" ) )
2347 except TypeError:
2348 main.log.exception( "Json object not as expected" )
2349 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002350
GlennRCed771242016-01-13 17:02:47 -08002351 # We want to count PENDING_ADD if isPENDING is true
2352 if isPENDING:
2353 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2354 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002355 else:
GlennRCed771242016-01-13 17:02:47 -08002356 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2357 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002358 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002359 except ( TypeError, ValueError ):
2360 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002361 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002362
YPZhang240842b2016-05-17 12:00:50 -07002363 except AssertionError:
2364 main.log.exception( "" )
2365 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002366 except pexpect.EOF:
2367 main.log.error( self.name + ": EOF exception found" )
2368 main.log.error( self.name + ": " + self.handle.before )
2369 main.cleanup()
2370 main.exit()
2371 except Exception:
2372 main.log.exception( self.name + ": Uncaught exception!" )
2373 main.cleanup()
2374 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002375 except pexpect.TIMEOUT:
2376 main.log.error( self.name + ": ONOS timeout" )
2377 return None
2378
kelvin-onlab4df89f22015-04-13 18:10:23 -07002379
GlennRCed771242016-01-13 17:02:47 -08002380 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002381 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002382 """
andrewonlab87852b02014-11-19 18:44:19 -05002383 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002384 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002385 a specific point-to-point intent definition
2386 Required:
GlennRCed771242016-01-13 17:02:47 -08002387 * ingress: specify source dpid
2388 * egress: specify destination dpid
2389 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002390 Optional:
GlennRCed771242016-01-13 17:02:47 -08002391 * offset: the keyOffset is where the next batch of intents
2392 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002393 * noExit: If set to True, TestON will not exit if any error when issus command
2394 * getResponse: If set to True, function will return ONOS response.
2395
GlennRCed771242016-01-13 17:02:47 -08002396 Returns: If failed to push test intents, it will returen None,
2397 if successful, return true.
2398 Timeout expection will return None,
2399 TypeError will return false
2400 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002401 """
andrewonlab87852b02014-11-19 18:44:19 -05002402 try:
GlennRCed771242016-01-13 17:02:47 -08002403 if background:
2404 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002405 else:
GlennRCed771242016-01-13 17:02:47 -08002406 back = ""
2407 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002408 ingress,
2409 egress,
2410 batchSize,
2411 offset,
2412 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002413 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002414 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002415 main.log.info( response )
2416 if response == None:
2417 return None
2418
YPZhangb34b7e12016-06-14 14:28:19 -07002419 if getResponse:
2420 return response
2421
GlennRCed771242016-01-13 17:02:47 -08002422 # TODO: We should handle if there is failure in installation
2423 return main.TRUE
2424
Jon Hallc6793552016-01-19 14:18:37 -08002425 except AssertionError:
2426 main.log.exception( "" )
2427 return None
GlennRCed771242016-01-13 17:02:47 -08002428 except pexpect.TIMEOUT:
2429 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002430 return None
andrewonlab87852b02014-11-19 18:44:19 -05002431 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002432 main.log.error( self.name + ": EOF exception found" )
2433 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002434 main.cleanup()
2435 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002436 except TypeError:
2437 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002438 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002439 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002440 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002441 main.cleanup()
2442 main.exit()
2443
YPZhangebf9eb52016-05-12 15:20:24 -07002444 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002445 """
2446 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002447 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002448 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002449 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002450 """
YPZhange3109a72016-02-02 11:25:37 -08002451
YPZhangb5d3f832016-01-23 22:54:26 -08002452 try:
YPZhange3109a72016-02-02 11:25:37 -08002453 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002454 cmd = "flows -s|grep ADDED|wc -l"
YPZhangebf9eb52016-05-12 15:20:24 -07002455 totalFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhange3109a72016-02-02 11:25:37 -08002456
2457 if totalFlows == None:
2458 # if timeout, we will get total number of all flows, and subtract other states
2459 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2460 checkedStates = []
2461 totalFlows = 0
2462 statesCount = [0, 0, 0, 0]
2463
2464 # get total flows from summary
YPZhangebf9eb52016-05-12 15:20:24 -07002465 response = json.loads( self.sendline( "summary -j", timeout=timeout, noExit=noExit ) )
YPZhange3109a72016-02-02 11:25:37 -08002466 totalFlows = int( response.get("flows") )
2467
2468 for s in states:
2469 rawFlows = self.flows( state=s, timeout = timeout )
2470 if rawFlows == None:
2471 # if timeout, return the total flows number from summary command
2472 return totalFlows
2473 checkedStates.append( json.loads( rawFlows ) )
2474
2475 # Calculate ADDED flows number, equal total subtracts others
2476 for i in range( len( states ) ):
2477 for c in checkedStates[i]:
2478 try:
2479 statesCount[i] += int( c.get( "flowCount" ) )
2480 except TypeError:
2481 main.log.exception( "Json object not as expected" )
2482 totalFlows = totalFlows - int( statesCount[i] )
2483 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2484
2485 return totalFlows
2486
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002487 return int(totalFlows)
YPZhange3109a72016-02-02 11:25:37 -08002488
You Wangd3cb2ce2016-05-16 14:01:24 -07002489 except ( TypeError, ValueError ):
2490 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002491 return None
2492 except pexpect.EOF:
2493 main.log.error( self.name + ": EOF exception found" )
2494 main.log.error( self.name + ": " + self.handle.before )
2495 main.cleanup()
2496 main.exit()
2497 except Exception:
2498 main.log.exception( self.name + ": Uncaught exception!" )
2499 main.cleanup()
2500 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002501 except pexpect.TIMEOUT:
2502 main.log.error( self.name + ": ONOS timeout" )
2503 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002504
YPZhangebf9eb52016-05-12 15:20:24 -07002505 def getTotalIntentsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002506 """
2507 Description:
2508 Get the total number of intents, include every states.
2509 Return:
2510 The number of intents
2511 """
2512 try:
2513 cmd = "summary -j"
YPZhangebf9eb52016-05-12 15:20:24 -07002514 response = self.sendline( cmd, timeout=timeout )
YPZhangb5d3f832016-01-23 22:54:26 -08002515 if response == None:
2516 return -1
2517 response = json.loads( response )
2518 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002519 except ( TypeError, ValueError ):
2520 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002521 return None
2522 except pexpect.EOF:
2523 main.log.error( self.name + ": EOF exception found" )
2524 main.log.error( self.name + ": " + self.handle.before )
2525 main.cleanup()
2526 main.exit()
2527 except Exception:
2528 main.log.exception( self.name + ": Uncaught exception!" )
2529 main.cleanup()
2530 main.exit()
2531
kelvin-onlabd3b64892015-01-20 13:26:24 -08002532 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002533 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002534 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002535 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002536 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002537 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002538 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002539 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002540 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002541 cmdStr += " -j"
2542 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002543 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002544 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002545 except AssertionError:
2546 main.log.exception( "" )
2547 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002548 except TypeError:
2549 main.log.exception( self.name + ": Object not as expected" )
2550 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002551 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002552 main.log.error( self.name + ": EOF exception found" )
2553 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002554 main.cleanup()
2555 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002556 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002557 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002558 main.cleanup()
2559 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002560
kelvin-onlabd3b64892015-01-20 13:26:24 -08002561 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002562 """
2563 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002564 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002565 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002566 """
andrewonlab867212a2014-10-22 20:13:38 -04002567 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002568 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002569 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002570 cmdStr += " -j"
2571 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002572 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002573 if handle:
2574 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002575 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002576 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002577 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002578 else:
2579 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002580 except AssertionError:
2581 main.log.exception( "" )
2582 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002583 except TypeError:
2584 main.log.exception( self.name + ": Object not as expected" )
2585 return None
andrewonlab867212a2014-10-22 20:13:38 -04002586 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002587 main.log.error( self.name + ": EOF exception found" )
2588 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002589 main.cleanup()
2590 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002591 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002592 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002593 main.cleanup()
2594 main.exit()
2595
kelvin8ec71442015-01-15 16:57:00 -08002596 # Wrapper functions ****************
2597 # Wrapper functions use existing driver
2598 # functions and extends their use case.
2599 # For example, we may use the output of
2600 # a normal driver function, and parse it
2601 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002602
kelvin-onlabd3b64892015-01-20 13:26:24 -08002603 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002604 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002605 Description:
2606 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002607 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002608 try:
kelvin8ec71442015-01-15 16:57:00 -08002609 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002610 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002611 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002612
kelvin8ec71442015-01-15 16:57:00 -08002613 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002614 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2615 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002616 match = re.search('id=0x([\da-f]+),', intents)
2617 if match:
2618 tmpId = match.group()[3:-1]
2619 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002620 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002621
Jon Halld4d4b372015-01-28 16:02:41 -08002622 except TypeError:
2623 main.log.exception( self.name + ": Object not as expected" )
2624 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002625 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002626 main.log.error( self.name + ": EOF exception found" )
2627 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002628 main.cleanup()
2629 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002630 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002631 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002632 main.cleanup()
2633 main.exit()
2634
Jon Hall30b82fa2015-03-04 17:15:43 -08002635 def FlowAddedCount( self, deviceId ):
2636 """
2637 Determine the number of flow rules for the given device id that are
2638 in the added state
2639 """
2640 try:
2641 cmdStr = "flows any " + str( deviceId ) + " | " +\
2642 "grep 'state=ADDED' | wc -l"
2643 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002644 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002645 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002646 except AssertionError:
2647 main.log.exception( "" )
2648 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002649 except pexpect.EOF:
2650 main.log.error( self.name + ": EOF exception found" )
2651 main.log.error( self.name + ": " + self.handle.before )
2652 main.cleanup()
2653 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002654 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002655 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002656 main.cleanup()
2657 main.exit()
2658
kelvin-onlabd3b64892015-01-20 13:26:24 -08002659 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002660 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002661 Use 'devices' function to obtain list of all devices
2662 and parse the result to obtain a list of all device
2663 id's. Returns this list. Returns empty list if no
2664 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002665 List is ordered sequentially
2666
andrewonlab3e15ead2014-10-15 14:21:34 -04002667 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002668 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002669 the ids. By obtaining the list of device ids on the fly,
2670 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002671 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002672 try:
kelvin8ec71442015-01-15 16:57:00 -08002673 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002674 devicesStr = self.devices( jsonFormat=False )
2675 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002676
kelvin-onlabd3b64892015-01-20 13:26:24 -08002677 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002678 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002679 return idList
kelvin8ec71442015-01-15 16:57:00 -08002680
2681 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002682 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002683 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002684 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002685 # Split list further into arguments before and after string
2686 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002687 # append to idList
2688 for arg in tempList:
2689 idList.append( arg.split( "id=" )[ 1 ] )
2690 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002691
Jon Halld4d4b372015-01-28 16:02:41 -08002692 except TypeError:
2693 main.log.exception( self.name + ": Object not as expected" )
2694 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002695 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002696 main.log.error( self.name + ": EOF exception found" )
2697 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002698 main.cleanup()
2699 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002700 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002701 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002702 main.cleanup()
2703 main.exit()
2704
kelvin-onlabd3b64892015-01-20 13:26:24 -08002705 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002706 """
andrewonlab7c211572014-10-15 16:45:20 -04002707 Uses 'nodes' function to obtain list of all nodes
2708 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002709 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002710 Returns:
2711 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002712 """
andrewonlab7c211572014-10-15 16:45:20 -04002713 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002714 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002715 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002716 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002717 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002718 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002719 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002720 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002721 nodesJson = json.loads( nodesStr )
2722 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002723 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002724 except ( TypeError, ValueError ):
2725 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002726 return None
andrewonlab7c211572014-10-15 16:45:20 -04002727 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002728 main.log.error( self.name + ": EOF exception found" )
2729 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002730 main.cleanup()
2731 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002732 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002733 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002734 main.cleanup()
2735 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002736
kelvin-onlabd3b64892015-01-20 13:26:24 -08002737 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002738 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002739 Return the first device from the devices api whose 'id' contains 'dpid'
2740 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002741 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002742 try:
kelvin8ec71442015-01-15 16:57:00 -08002743 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002744 return None
2745 else:
kelvin8ec71442015-01-15 16:57:00 -08002746 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002747 rawDevices = self.devices()
2748 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002749 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002750 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002751 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2752 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002753 return device
2754 return None
Jon Hallc6793552016-01-19 14:18:37 -08002755 except ( TypeError, ValueError ):
2756 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002757 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002758 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002759 main.log.error( self.name + ": EOF exception found" )
2760 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002761 main.cleanup()
2762 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002763 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002764 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002765 main.cleanup()
2766 main.exit()
2767
You Wang24139872016-05-03 11:48:47 -07002768 def getTopology( self, topologyOutput ):
2769 """
2770 Definition:
2771 Loads a json topology output
2772 Return:
2773 topology = current ONOS topology
2774 """
2775 import json
2776 try:
2777 # either onos:topology or 'topology' will work in CLI
2778 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002779 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002780 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002781 except ( TypeError, ValueError ):
2782 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2783 return None
You Wang24139872016-05-03 11:48:47 -07002784 except pexpect.EOF:
2785 main.log.error( self.name + ": EOF exception found" )
2786 main.log.error( self.name + ": " + self.handle.before )
2787 main.cleanup()
2788 main.exit()
2789 except Exception:
2790 main.log.exception( self.name + ": Uncaught exception!" )
2791 main.cleanup()
2792 main.exit()
2793
Flavio Castro82ee2f62016-06-07 15:04:12 -07002794 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002795 """
Jon Hallefbd9792015-03-05 16:11:36 -08002796 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002797 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002798 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002799
Flavio Castro82ee2f62016-06-07 15:04:12 -07002800 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002801 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002802 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002803 logLevel = level to log to.
2804 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002805
Jon Hallefbd9792015-03-05 16:11:36 -08002806 Returns: main.TRUE if the number of switches and links are correct,
2807 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002808 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002809 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002810 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002811 try:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002812 topology = self.getTopology( self.topology() )
2813 summary = json.loads( self.summary() )
Jon Hall97cf84a2016-06-20 13:35:58 -07002814
Flavio Castro82ee2f62016-06-07 15:04:12 -07002815 if topology == {} or topology == None or summary == {} or summary == None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002816 return main.ERROR
2817 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002818 # Is the number of switches is what we expected
2819 devices = topology.get( 'devices', False )
2820 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002821 nodes = summary.get( 'nodes', False )
2822 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002823 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002824 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002825 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002826 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002827 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2828 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002829 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002830 output = output + "The number of links and switches match "\
2831 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002832 result = main.TRUE
2833 else:
You Wang24139872016-05-03 11:48:47 -07002834 output = output + \
2835 "The number of links and switches does not match " + \
2836 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002837 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002838 output = output + "\n ONOS sees %i devices" % int( devices )
2839 output = output + " (%i expected) " % int( numoswitch )
2840 output = output + "and %i links " % int( links )
2841 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002842 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002843 output = output + "and %i controllers " % int( nodes )
2844 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002845 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002846 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002847 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002848 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002849 else:
You Wang24139872016-05-03 11:48:47 -07002850 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002851 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002852 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002853 main.log.error( self.name + ": EOF exception found" )
2854 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002855 main.cleanup()
2856 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002857 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002858 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002859 main.cleanup()
2860 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002861
kelvin-onlabd3b64892015-01-20 13:26:24 -08002862 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002863 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002864 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002865 deviceId must be the id of a device as seen in the onos devices command
2866 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002867 role must be either master, standby, or none
2868
Jon Halle3f39ff2015-01-13 11:50:53 -08002869 Returns:
2870 main.TRUE or main.FALSE based on argument verification and
2871 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002872 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002873 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002874 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002875 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002876 cmdStr = "device-role " +\
2877 str( deviceId ) + " " +\
2878 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002879 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002880 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002881 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002882 if re.search( "Error", handle ):
2883 # end color output to escape any colours
2884 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002885 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002886 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002887 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002888 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002889 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002890 main.log.error( "Invalid 'role' given to device_role(). " +
2891 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002892 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002893 except AssertionError:
2894 main.log.exception( "" )
2895 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002896 except TypeError:
2897 main.log.exception( self.name + ": Object not as expected" )
2898 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002899 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002900 main.log.error( self.name + ": EOF exception found" )
2901 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002902 main.cleanup()
2903 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002904 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002905 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002906 main.cleanup()
2907 main.exit()
2908
kelvin-onlabd3b64892015-01-20 13:26:24 -08002909 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002910 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002911 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002912 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002913 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002914 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002915 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002916 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002917 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002918 cmdStr += " -j"
2919 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002920 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002921 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002922 except AssertionError:
2923 main.log.exception( "" )
2924 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002925 except TypeError:
2926 main.log.exception( self.name + ": Object not as expected" )
2927 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002928 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002929 main.log.error( self.name + ": EOF exception found" )
2930 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002931 main.cleanup()
2932 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002933 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002934 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002935 main.cleanup()
2936 main.exit()
2937
kelvin-onlabd3b64892015-01-20 13:26:24 -08002938 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002939 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002940 CLI command to get the current leader for the Election test application
2941 NOTE: Requires installation of the onos-app-election feature
2942 Returns: Node IP of the leader if one exists
2943 None if none exists
2944 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002945 """
Jon Hall94fd0472014-12-08 11:52:42 -08002946 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002947 cmdStr = "election-test-leader"
2948 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002949 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002950 # Leader
2951 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002952 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002953 nodeSearch = re.search( leaderPattern, response )
2954 if nodeSearch:
2955 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002956 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002957 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002958 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002959 # no leader
2960 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002961 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002962 nullSearch = re.search( nullPattern, response )
2963 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002964 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002965 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002966 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002967 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07002968 main.log.error( "Error in electionTestLeader on " + self.name +
2969 ": " + "unexpected response" )
2970 main.log.error( repr( response ) )
2971 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002972 except AssertionError:
2973 main.log.exception( "" )
2974 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002975 except TypeError:
2976 main.log.exception( self.name + ": Object not as expected" )
2977 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002978 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002979 main.log.error( self.name + ": EOF exception found" )
2980 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002981 main.cleanup()
2982 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002983 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002984 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002985 main.cleanup()
2986 main.exit()
2987
kelvin-onlabd3b64892015-01-20 13:26:24 -08002988 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002989 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002990 CLI command to run for leadership of the Election test application.
2991 NOTE: Requires installation of the onos-app-election feature
2992 Returns: Main.TRUE on success
2993 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002994 """
Jon Hall94fd0472014-12-08 11:52:42 -08002995 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002996 cmdStr = "election-test-run"
2997 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002998 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002999 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003000 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003001 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003002 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003003 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003004 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003005 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003006 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003007 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003008 main.log.error( "Error in electionTestRun on " + self.name +
3009 ": " + "unexpected response" )
3010 main.log.error( repr( response ) )
3011 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003012 except AssertionError:
3013 main.log.exception( "" )
3014 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003015 except TypeError:
3016 main.log.exception( self.name + ": Object not as expected" )
3017 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003018 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003019 main.log.error( self.name + ": EOF exception found" )
3020 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003021 main.cleanup()
3022 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003023 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003024 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003025 main.cleanup()
3026 main.exit()
3027
kelvin-onlabd3b64892015-01-20 13:26:24 -08003028 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003029 """
Jon Hall94fd0472014-12-08 11:52:42 -08003030 * CLI command to withdraw the local node from leadership election for
3031 * the Election test application.
3032 #NOTE: Requires installation of the onos-app-election feature
3033 Returns: Main.TRUE on success
3034 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003035 """
Jon Hall94fd0472014-12-08 11:52:42 -08003036 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003037 cmdStr = "election-test-withdraw"
3038 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003039 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003040 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003041 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003042 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003043 if re.search( successPattern, response ):
3044 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003045 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003046 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003047 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003048 main.log.error( "Error in electionTestWithdraw on " +
3049 self.name + ": " + "unexpected response" )
3050 main.log.error( repr( response ) )
3051 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003052 except AssertionError:
3053 main.log.exception( "" )
3054 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003055 except TypeError:
3056 main.log.exception( self.name + ": Object not as expected" )
3057 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003058 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003059 main.log.error( self.name + ": EOF exception found" )
3060 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003061 main.cleanup()
3062 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003063 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003064 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003065 main.cleanup()
3066 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003067
kelvin8ec71442015-01-15 16:57:00 -08003068 def getDevicePortsEnabledCount( self, dpid ):
3069 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003070 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003071 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003072 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003073 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003074 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3075 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003076 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003077 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003078 if re.search( "No such device", output ):
3079 main.log.error( "Error in getting ports" )
3080 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003081 return output
Jon Hallc6793552016-01-19 14:18:37 -08003082 except AssertionError:
3083 main.log.exception( "" )
3084 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003085 except TypeError:
3086 main.log.exception( self.name + ": Object not as expected" )
3087 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003088 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003089 main.log.error( self.name + ": EOF exception found" )
3090 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003091 main.cleanup()
3092 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003093 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003094 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003095 main.cleanup()
3096 main.exit()
3097
kelvin8ec71442015-01-15 16:57:00 -08003098 def getDeviceLinksActiveCount( self, dpid ):
3099 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003100 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003101 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003102 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003103 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003104 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3105 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003106 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003107 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003108 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003109 main.log.error( "Error in getting ports " )
3110 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003111 return output
Jon Hallc6793552016-01-19 14:18:37 -08003112 except AssertionError:
3113 main.log.exception( "" )
3114 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003115 except TypeError:
3116 main.log.exception( self.name + ": Object not as expected" )
3117 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003118 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003119 main.log.error( self.name + ": EOF exception found" )
3120 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003121 main.cleanup()
3122 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003123 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003124 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003125 main.cleanup()
3126 main.exit()
3127
kelvin8ec71442015-01-15 16:57:00 -08003128 def getAllIntentIds( self ):
3129 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003130 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003131 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003132 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003133 cmdStr = "onos:intents | grep id="
3134 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003135 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003136 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003137 if re.search( "Error", output ):
3138 main.log.error( "Error in getting ports" )
3139 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003140 return output
Jon Hallc6793552016-01-19 14:18:37 -08003141 except AssertionError:
3142 main.log.exception( "" )
3143 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003144 except TypeError:
3145 main.log.exception( self.name + ": Object not as expected" )
3146 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003147 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003148 main.log.error( self.name + ": EOF exception found" )
3149 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003150 main.cleanup()
3151 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003152 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003153 main.log.exception( self.name + ": Uncaught exception!" )
3154 main.cleanup()
3155 main.exit()
3156
Jon Hall73509952015-02-24 16:42:56 -08003157 def intentSummary( self ):
3158 """
Jon Hallefbd9792015-03-05 16:11:36 -08003159 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003160 """
3161 try:
3162 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003163 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003164 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003165 states.append( intent.get( 'state', None ) )
3166 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003167 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003168 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003169 except ( TypeError, ValueError ):
3170 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003171 return None
3172 except pexpect.EOF:
3173 main.log.error( self.name + ": EOF exception found" )
3174 main.log.error( self.name + ": " + self.handle.before )
3175 main.cleanup()
3176 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003177 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003178 main.log.exception( self.name + ": Uncaught exception!" )
3179 main.cleanup()
3180 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003181
Jon Hall61282e32015-03-19 11:34:11 -07003182 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003183 """
3184 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003185 Optional argument:
3186 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003187 """
Jon Hall63604932015-02-26 17:09:50 -08003188 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003189 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003190 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003191 cmdStr += " -j"
3192 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003193 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003194 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003195 return output
Jon Hallc6793552016-01-19 14:18:37 -08003196 except AssertionError:
3197 main.log.exception( "" )
3198 return None
Jon Hall63604932015-02-26 17:09:50 -08003199 except TypeError:
3200 main.log.exception( self.name + ": Object not as expected" )
3201 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003202 except pexpect.EOF:
3203 main.log.error( self.name + ": EOF exception found" )
3204 main.log.error( self.name + ": " + self.handle.before )
3205 main.cleanup()
3206 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003207 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003208 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003209 main.cleanup()
3210 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003211
acsmarsa4a4d1e2015-07-10 16:01:24 -07003212 def leaderCandidates( self, jsonFormat=True ):
3213 """
3214 Returns the output of the leaders -c command.
3215 Optional argument:
3216 * jsonFormat - boolean indicating if you want output in json
3217 """
3218 try:
3219 cmdStr = "onos:leaders -c"
3220 if jsonFormat:
3221 cmdStr += " -j"
3222 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003223 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003224 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003225 return output
Jon Hallc6793552016-01-19 14:18:37 -08003226 except AssertionError:
3227 main.log.exception( "" )
3228 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003229 except TypeError:
3230 main.log.exception( self.name + ": Object not as expected" )
3231 return None
3232 except pexpect.EOF:
3233 main.log.error( self.name + ": EOF exception found" )
3234 main.log.error( self.name + ": " + self.handle.before )
3235 main.cleanup()
3236 main.exit()
3237 except Exception:
3238 main.log.exception( self.name + ": Uncaught exception!" )
3239 main.cleanup()
3240 main.exit()
3241
Jon Hallc6793552016-01-19 14:18:37 -08003242 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003243 """
3244 Returns a list in format [leader,candidate1,candidate2,...] for a given
3245 topic parameter and an empty list if the topic doesn't exist
3246 If no leader is elected leader in the returned list will be "none"
3247 Returns None if there is a type error processing the json object
3248 """
3249 try:
Jon Hall6e709752016-02-01 13:38:46 -08003250 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003251 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003252 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003253 assert "Command not found:" not in rawOutput, rawOutput
3254 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003255 results = []
3256 for dict in output:
3257 if dict["topic"] == topic:
3258 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003259 candidates = re.split( ", ", dict["candidates"][1:-1] )
3260 results.append( leader )
3261 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003262 return results
Jon Hallc6793552016-01-19 14:18:37 -08003263 except AssertionError:
3264 main.log.exception( "" )
3265 return None
3266 except ( TypeError, ValueError ):
3267 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003268 return None
3269 except pexpect.EOF:
3270 main.log.error( self.name + ": EOF exception found" )
3271 main.log.error( self.name + ": " + self.handle.before )
3272 main.cleanup()
3273 main.exit()
3274 except Exception:
3275 main.log.exception( self.name + ": Uncaught exception!" )
3276 main.cleanup()
3277 main.exit()
3278
Jon Hall61282e32015-03-19 11:34:11 -07003279 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003280 """
3281 Returns the output of the intent Pending map.
3282 """
Jon Hall63604932015-02-26 17:09:50 -08003283 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003284 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003285 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003286 cmdStr += " -j"
3287 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003288 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003289 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003290 return output
Jon Hallc6793552016-01-19 14:18:37 -08003291 except AssertionError:
3292 main.log.exception( "" )
3293 return None
Jon Hall63604932015-02-26 17:09:50 -08003294 except TypeError:
3295 main.log.exception( self.name + ": Object not as expected" )
3296 return None
3297 except pexpect.EOF:
3298 main.log.error( self.name + ": EOF exception found" )
3299 main.log.error( self.name + ": " + self.handle.before )
3300 main.cleanup()
3301 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003302 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003303 main.log.exception( self.name + ": Uncaught exception!" )
3304 main.cleanup()
3305 main.exit()
3306
Jon Hall61282e32015-03-19 11:34:11 -07003307 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003308 """
3309 Returns the output of the raft partitions command for ONOS.
3310 """
Jon Hall61282e32015-03-19 11:34:11 -07003311 # Sample JSON
3312 # {
3313 # "leader": "tcp://10.128.30.11:7238",
3314 # "members": [
3315 # "tcp://10.128.30.11:7238",
3316 # "tcp://10.128.30.17:7238",
3317 # "tcp://10.128.30.13:7238",
3318 # ],
3319 # "name": "p1",
3320 # "term": 3
3321 # },
Jon Hall63604932015-02-26 17:09:50 -08003322 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003323 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003324 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003325 cmdStr += " -j"
3326 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003327 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003328 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003329 return output
Jon Hallc6793552016-01-19 14:18:37 -08003330 except AssertionError:
3331 main.log.exception( "" )
3332 return None
Jon Hall63604932015-02-26 17:09:50 -08003333 except TypeError:
3334 main.log.exception( self.name + ": Object not as expected" )
3335 return None
3336 except pexpect.EOF:
3337 main.log.error( self.name + ": EOF exception found" )
3338 main.log.error( self.name + ": " + self.handle.before )
3339 main.cleanup()
3340 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003341 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003342 main.log.exception( self.name + ": Uncaught exception!" )
3343 main.cleanup()
3344 main.exit()
3345
Jon Hallbe379602015-03-24 13:39:32 -07003346 def apps( self, jsonFormat=True ):
3347 """
3348 Returns the output of the apps command for ONOS. This command lists
3349 information about installed ONOS applications
3350 """
3351 # Sample JSON object
3352 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3353 # "description":"ONOS OpenFlow protocol southbound providers",
3354 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3355 # "features":"[onos-openflow]","state":"ACTIVE"}]
3356 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003357 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003358 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003359 cmdStr += " -j"
3360 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003361 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003362 assert "Command not found:" not in output, output
3363 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003364 return output
Jon Hallbe379602015-03-24 13:39:32 -07003365 # FIXME: look at specific exceptions/Errors
3366 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003367 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003368 return None
3369 except TypeError:
3370 main.log.exception( self.name + ": Object not as expected" )
3371 return None
3372 except pexpect.EOF:
3373 main.log.error( self.name + ": EOF exception found" )
3374 main.log.error( self.name + ": " + self.handle.before )
3375 main.cleanup()
3376 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003377 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003378 main.log.exception( self.name + ": Uncaught exception!" )
3379 main.cleanup()
3380 main.exit()
3381
Jon Hall146f1522015-03-24 15:33:24 -07003382 def appStatus( self, appName ):
3383 """
3384 Uses the onos:apps cli command to return the status of an application.
3385 Returns:
3386 "ACTIVE" - If app is installed and activated
3387 "INSTALLED" - If app is installed and deactivated
3388 "UNINSTALLED" - If app is not installed
3389 None - on error
3390 """
Jon Hall146f1522015-03-24 15:33:24 -07003391 try:
3392 if not isinstance( appName, types.StringType ):
3393 main.log.error( self.name + ".appStatus(): appName must be" +
3394 " a string" )
3395 return None
3396 output = self.apps( jsonFormat=True )
3397 appsJson = json.loads( output )
3398 state = None
3399 for app in appsJson:
3400 if appName == app.get('name'):
3401 state = app.get('state')
3402 break
3403 if state == "ACTIVE" or state == "INSTALLED":
3404 return state
3405 elif state is None:
3406 return "UNINSTALLED"
3407 elif state:
3408 main.log.error( "Unexpected state from 'onos:apps': " +
3409 str( state ) )
3410 return state
Jon Hallc6793552016-01-19 14:18:37 -08003411 except ( TypeError, ValueError ):
3412 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003413 return None
3414 except pexpect.EOF:
3415 main.log.error( self.name + ": EOF exception found" )
3416 main.log.error( self.name + ": " + self.handle.before )
3417 main.cleanup()
3418 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003419 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003420 main.log.exception( self.name + ": Uncaught exception!" )
3421 main.cleanup()
3422 main.exit()
3423
Jon Hallbe379602015-03-24 13:39:32 -07003424 def app( self, appName, option ):
3425 """
3426 Interacts with the app command for ONOS. This command manages
3427 application inventory.
3428 """
Jon Hallbe379602015-03-24 13:39:32 -07003429 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003430 # Validate argument types
3431 valid = True
3432 if not isinstance( appName, types.StringType ):
3433 main.log.error( self.name + ".app(): appName must be a " +
3434 "string" )
3435 valid = False
3436 if not isinstance( option, types.StringType ):
3437 main.log.error( self.name + ".app(): option must be a string" )
3438 valid = False
3439 if not valid:
3440 return main.FALSE
3441 # Validate Option
3442 option = option.lower()
3443 # NOTE: Install may become a valid option
3444 if option == "activate":
3445 pass
3446 elif option == "deactivate":
3447 pass
3448 elif option == "uninstall":
3449 pass
3450 else:
3451 # Invalid option
3452 main.log.error( "The ONOS app command argument only takes " +
3453 "the values: (activate|deactivate|uninstall)" +
3454 "; was given '" + option + "'")
3455 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003456 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003457 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003458 if "Error executing command" in output:
3459 main.log.error( "Error in processing onos:app command: " +
3460 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003461 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003462 elif "No such application" in output:
3463 main.log.error( "The application '" + appName +
3464 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003465 return main.FALSE
3466 elif "Command not found:" in output:
3467 main.log.error( "Error in processing onos:app command: " +
3468 str( output ) )
3469 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003470 elif "Unsupported command:" in output:
3471 main.log.error( "Incorrect command given to 'app': " +
3472 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003473 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003474 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003475 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003476 return main.TRUE
3477 except TypeError:
3478 main.log.exception( self.name + ": Object not as expected" )
3479 return main.ERROR
3480 except pexpect.EOF:
3481 main.log.error( self.name + ": EOF exception found" )
3482 main.log.error( self.name + ": " + self.handle.before )
3483 main.cleanup()
3484 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003485 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003486 main.log.exception( self.name + ": Uncaught exception!" )
3487 main.cleanup()
3488 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003489
Jon Hallbd16b922015-03-26 17:53:15 -07003490 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003491 """
3492 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003493 appName is the hierarchical app name, not the feature name
3494 If check is True, method will check the status of the app after the
3495 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003496 Returns main.TRUE if the command was successfully sent
3497 main.FALSE if the cli responded with an error or given
3498 incorrect input
3499 """
3500 try:
3501 if not isinstance( appName, types.StringType ):
3502 main.log.error( self.name + ".activateApp(): appName must be" +
3503 " a string" )
3504 return main.FALSE
3505 status = self.appStatus( appName )
3506 if status == "INSTALLED":
3507 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003508 if check and response == main.TRUE:
3509 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003510 status = self.appStatus( appName )
3511 if status == "ACTIVE":
3512 return main.TRUE
3513 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003514 main.log.debug( "The state of application " +
3515 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003516 time.sleep( 1 )
3517 return main.FALSE
3518 else: # not 'check' or command didn't succeed
3519 return response
Jon Hall146f1522015-03-24 15:33:24 -07003520 elif status == "ACTIVE":
3521 return main.TRUE
3522 elif status == "UNINSTALLED":
3523 main.log.error( self.name + ": Tried to activate the " +
3524 "application '" + appName + "' which is not " +
3525 "installed." )
3526 else:
3527 main.log.error( "Unexpected return value from appStatus: " +
3528 str( status ) )
3529 return main.ERROR
3530 except TypeError:
3531 main.log.exception( self.name + ": Object not as expected" )
3532 return main.ERROR
3533 except pexpect.EOF:
3534 main.log.error( self.name + ": EOF exception found" )
3535 main.log.error( self.name + ": " + self.handle.before )
3536 main.cleanup()
3537 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003538 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003539 main.log.exception( self.name + ": Uncaught exception!" )
3540 main.cleanup()
3541 main.exit()
3542
Jon Hallbd16b922015-03-26 17:53:15 -07003543 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003544 """
3545 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003546 appName is the hierarchical app name, not the feature name
3547 If check is True, method will check the status of the app after the
3548 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003549 Returns main.TRUE if the command was successfully sent
3550 main.FALSE if the cli responded with an error or given
3551 incorrect input
3552 """
3553 try:
3554 if not isinstance( appName, types.StringType ):
3555 main.log.error( self.name + ".deactivateApp(): appName must " +
3556 "be a string" )
3557 return main.FALSE
3558 status = self.appStatus( appName )
3559 if status == "INSTALLED":
3560 return main.TRUE
3561 elif status == "ACTIVE":
3562 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003563 if check and response == main.TRUE:
3564 for i in range(10): # try 10 times then give up
3565 status = self.appStatus( appName )
3566 if status == "INSTALLED":
3567 return main.TRUE
3568 else:
3569 time.sleep( 1 )
3570 return main.FALSE
3571 else: # not check or command didn't succeed
3572 return response
Jon Hall146f1522015-03-24 15:33:24 -07003573 elif status == "UNINSTALLED":
3574 main.log.warn( self.name + ": Tried to deactivate the " +
3575 "application '" + appName + "' which is not " +
3576 "installed." )
3577 return main.TRUE
3578 else:
3579 main.log.error( "Unexpected return value from appStatus: " +
3580 str( status ) )
3581 return main.ERROR
3582 except TypeError:
3583 main.log.exception( self.name + ": Object not as expected" )
3584 return main.ERROR
3585 except pexpect.EOF:
3586 main.log.error( self.name + ": EOF exception found" )
3587 main.log.error( self.name + ": " + self.handle.before )
3588 main.cleanup()
3589 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003590 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003591 main.log.exception( self.name + ": Uncaught exception!" )
3592 main.cleanup()
3593 main.exit()
3594
Jon Hallbd16b922015-03-26 17:53:15 -07003595 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003596 """
3597 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003598 appName is the hierarchical app name, not the feature name
3599 If check is True, method will check the status of the app after the
3600 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003601 Returns main.TRUE if the command was successfully sent
3602 main.FALSE if the cli responded with an error or given
3603 incorrect input
3604 """
3605 # TODO: check with Thomas about the state machine for apps
3606 try:
3607 if not isinstance( appName, types.StringType ):
3608 main.log.error( self.name + ".uninstallApp(): appName must " +
3609 "be a string" )
3610 return main.FALSE
3611 status = self.appStatus( appName )
3612 if status == "INSTALLED":
3613 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003614 if check and response == main.TRUE:
3615 for i in range(10): # try 10 times then give up
3616 status = self.appStatus( appName )
3617 if status == "UNINSTALLED":
3618 return main.TRUE
3619 else:
3620 time.sleep( 1 )
3621 return main.FALSE
3622 else: # not check or command didn't succeed
3623 return response
Jon Hall146f1522015-03-24 15:33:24 -07003624 elif status == "ACTIVE":
3625 main.log.warn( self.name + ": Tried to uninstall the " +
3626 "application '" + appName + "' which is " +
3627 "currently active." )
3628 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003629 if check and response == main.TRUE:
3630 for i in range(10): # try 10 times then give up
3631 status = self.appStatus( appName )
3632 if status == "UNINSTALLED":
3633 return main.TRUE
3634 else:
3635 time.sleep( 1 )
3636 return main.FALSE
3637 else: # not check or command didn't succeed
3638 return response
Jon Hall146f1522015-03-24 15:33:24 -07003639 elif status == "UNINSTALLED":
3640 return main.TRUE
3641 else:
3642 main.log.error( "Unexpected return value from appStatus: " +
3643 str( status ) )
3644 return main.ERROR
3645 except TypeError:
3646 main.log.exception( self.name + ": Object not as expected" )
3647 return main.ERROR
3648 except pexpect.EOF:
3649 main.log.error( self.name + ": EOF exception found" )
3650 main.log.error( self.name + ": " + self.handle.before )
3651 main.cleanup()
3652 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003653 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003654 main.log.exception( self.name + ": Uncaught exception!" )
3655 main.cleanup()
3656 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003657
3658 def appIDs( self, jsonFormat=True ):
3659 """
3660 Show the mappings between app id and app names given by the 'app-ids'
3661 cli command
3662 """
3663 try:
3664 cmdStr = "app-ids"
3665 if jsonFormat:
3666 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003667 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003668 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003669 assert "Command not found:" not in output, output
3670 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003671 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003672 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003673 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003674 return None
3675 except TypeError:
3676 main.log.exception( self.name + ": Object not as expected" )
3677 return None
3678 except pexpect.EOF:
3679 main.log.error( self.name + ": EOF exception found" )
3680 main.log.error( self.name + ": " + self.handle.before )
3681 main.cleanup()
3682 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003683 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003684 main.log.exception( self.name + ": Uncaught exception!" )
3685 main.cleanup()
3686 main.exit()
3687
3688 def appToIDCheck( self ):
3689 """
3690 This method will check that each application's ID listed in 'apps' is
3691 the same as the ID listed in 'app-ids'. The check will also check that
3692 there are no duplicate IDs issued. Note that an app ID should be
3693 a globaly unique numerical identifier for app/app-like features. Once
3694 an ID is registered, the ID is never freed up so that if an app is
3695 reinstalled it will have the same ID.
3696
3697 Returns: main.TRUE if the check passes and
3698 main.FALSE if the check fails or
3699 main.ERROR if there is some error in processing the test
3700 """
3701 try:
Jon Hall390696c2015-05-05 17:13:41 -07003702 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003703 rawJson = self.appIDs( jsonFormat=True )
3704 if rawJson:
3705 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003706 else:
Jon Hallc6793552016-01-19 14:18:37 -08003707 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003708 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003709 rawJson = self.apps( jsonFormat=True )
3710 if rawJson:
3711 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003712 else:
Jon Hallc6793552016-01-19 14:18:37 -08003713 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003714 bail = True
3715 if bail:
3716 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003717 result = main.TRUE
3718 for app in apps:
3719 appID = app.get( 'id' )
3720 if appID is None:
3721 main.log.error( "Error parsing app: " + str( app ) )
3722 result = main.FALSE
3723 appName = app.get( 'name' )
3724 if appName is None:
3725 main.log.error( "Error parsing app: " + str( app ) )
3726 result = main.FALSE
3727 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003728 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003729 # main.log.debug( "Comparing " + str( app ) + " to " +
3730 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003731 if not current: # if ids doesn't have this id
3732 result = main.FALSE
3733 main.log.error( "'app-ids' does not have the ID for " +
3734 str( appName ) + " that apps does." )
3735 elif len( current ) > 1:
3736 # there is more than one app with this ID
3737 result = main.FALSE
3738 # We will log this later in the method
3739 elif not current[0][ 'name' ] == appName:
3740 currentName = current[0][ 'name' ]
3741 result = main.FALSE
3742 main.log.error( "'app-ids' has " + str( currentName ) +
3743 " registered under id:" + str( appID ) +
3744 " but 'apps' has " + str( appName ) )
3745 else:
3746 pass # id and name match!
3747 # now make sure that app-ids has no duplicates
3748 idsList = []
3749 namesList = []
3750 for item in ids:
3751 idsList.append( item[ 'id' ] )
3752 namesList.append( item[ 'name' ] )
3753 if len( idsList ) != len( set( idsList ) ) or\
3754 len( namesList ) != len( set( namesList ) ):
3755 main.log.error( "'app-ids' has some duplicate entries: \n"
3756 + json.dumps( ids,
3757 sort_keys=True,
3758 indent=4,
3759 separators=( ',', ': ' ) ) )
3760 result = main.FALSE
3761 return result
Jon Hallc6793552016-01-19 14:18:37 -08003762 except ( TypeError, ValueError ):
3763 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003764 return main.ERROR
3765 except pexpect.EOF:
3766 main.log.error( self.name + ": EOF exception found" )
3767 main.log.error( self.name + ": " + self.handle.before )
3768 main.cleanup()
3769 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003770 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003771 main.log.exception( self.name + ": Uncaught exception!" )
3772 main.cleanup()
3773 main.exit()
3774
Jon Hallfb760a02015-04-13 15:35:03 -07003775 def getCfg( self, component=None, propName=None, short=False,
3776 jsonFormat=True ):
3777 """
3778 Get configuration settings from onos cli
3779 Optional arguments:
3780 component - Optionally only list configurations for a specific
3781 component. If None, all components with configurations
3782 are displayed. Case Sensitive string.
3783 propName - If component is specified, propName option will show
3784 only this specific configuration from that component.
3785 Case Sensitive string.
3786 jsonFormat - Returns output as json. Note that this will override
3787 the short option
3788 short - Short, less verbose, version of configurations.
3789 This is overridden by the json option
3790 returns:
3791 Output from cli as a string or None on error
3792 """
3793 try:
3794 baseStr = "cfg"
3795 cmdStr = " get"
3796 componentStr = ""
3797 if component:
3798 componentStr += " " + component
3799 if propName:
3800 componentStr += " " + propName
3801 if jsonFormat:
3802 baseStr += " -j"
3803 elif short:
3804 baseStr += " -s"
3805 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003806 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003807 assert "Command not found:" not in output, output
3808 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003809 return output
3810 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003811 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003812 return None
3813 except TypeError:
3814 main.log.exception( self.name + ": Object not as expected" )
3815 return None
3816 except pexpect.EOF:
3817 main.log.error( self.name + ": EOF exception found" )
3818 main.log.error( self.name + ": " + self.handle.before )
3819 main.cleanup()
3820 main.exit()
3821 except Exception:
3822 main.log.exception( self.name + ": Uncaught exception!" )
3823 main.cleanup()
3824 main.exit()
3825
3826 def setCfg( self, component, propName, value=None, check=True ):
3827 """
3828 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003829 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003830 component - The case sensitive name of the component whose
3831 property is to be set
3832 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003833 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003834 value - The value to set the property to. If None, will unset the
3835 property and revert it to it's default value(if applicable)
3836 check - Boolean, Check whether the option was successfully set this
3837 only applies when a value is given.
3838 returns:
3839 main.TRUE on success or main.FALSE on failure. If check is False,
3840 will return main.TRUE unless there is an error
3841 """
3842 try:
3843 baseStr = "cfg"
3844 cmdStr = " set " + str( component ) + " " + str( propName )
3845 if value is not None:
3846 cmdStr += " " + str( value )
3847 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003848 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003849 assert "Command not found:" not in output, output
3850 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003851 if value and check:
3852 results = self.getCfg( component=str( component ),
3853 propName=str( propName ),
3854 jsonFormat=True )
3855 # Check if current value is what we just set
3856 try:
3857 jsonOutput = json.loads( results )
3858 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003859 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003860 main.log.exception( "Error parsing cfg output" )
3861 main.log.error( "output:" + repr( results ) )
3862 return main.FALSE
3863 if current == str( value ):
3864 return main.TRUE
3865 return main.FALSE
3866 return main.TRUE
3867 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003868 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003869 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003870 except ( TypeError, ValueError ):
3871 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003872 return main.FALSE
3873 except pexpect.EOF:
3874 main.log.error( self.name + ": EOF exception found" )
3875 main.log.error( self.name + ": " + self.handle.before )
3876 main.cleanup()
3877 main.exit()
3878 except Exception:
3879 main.log.exception( self.name + ": Uncaught exception!" )
3880 main.cleanup()
3881 main.exit()
3882
Jon Hall390696c2015-05-05 17:13:41 -07003883 def setTestAdd( self, setName, values ):
3884 """
3885 CLI command to add elements to a distributed set.
3886 Arguments:
3887 setName - The name of the set to add to.
3888 values - The value(s) to add to the set, space seperated.
3889 Example usages:
3890 setTestAdd( "set1", "a b c" )
3891 setTestAdd( "set2", "1" )
3892 returns:
3893 main.TRUE on success OR
3894 main.FALSE if elements were already in the set OR
3895 main.ERROR on error
3896 """
3897 try:
3898 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3899 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003900 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003901 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003902 try:
3903 # TODO: Maybe make this less hardcoded
3904 # ConsistentMap Exceptions
3905 assert "org.onosproject.store.service" not in output
3906 # Node not leader
3907 assert "java.lang.IllegalStateException" not in output
3908 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003909 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003910 "command: " + str( output ) )
3911 retryTime = 30 # Conservative time, given by Madan
3912 main.log.info( "Waiting " + str( retryTime ) +
3913 "seconds before retrying." )
3914 time.sleep( retryTime ) # Due to change in mastership
3915 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003916 assert output is not None, "Error in sendline"
Jon Hall390696c2015-05-05 17:13:41 -07003917 assert "Error executing command" not in output
3918 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3919 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3920 main.log.info( self.name + ": " + output )
3921 if re.search( positiveMatch, output):
3922 return main.TRUE
3923 elif re.search( negativeMatch, output):
3924 return main.FALSE
3925 else:
3926 main.log.error( self.name + ": setTestAdd did not" +
3927 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003928 main.log.debug( self.name + " actual: " + repr( output ) )
3929 return main.ERROR
3930 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003931 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003932 return main.ERROR
3933 except TypeError:
3934 main.log.exception( self.name + ": Object not as expected" )
3935 return main.ERROR
3936 except pexpect.EOF:
3937 main.log.error( self.name + ": EOF exception found" )
3938 main.log.error( self.name + ": " + self.handle.before )
3939 main.cleanup()
3940 main.exit()
3941 except Exception:
3942 main.log.exception( self.name + ": Uncaught exception!" )
3943 main.cleanup()
3944 main.exit()
3945
3946 def setTestRemove( self, setName, values, clear=False, retain=False ):
3947 """
3948 CLI command to remove elements from a distributed set.
3949 Required arguments:
3950 setName - The name of the set to remove from.
3951 values - The value(s) to remove from the set, space seperated.
3952 Optional arguments:
3953 clear - Clear all elements from the set
3954 retain - Retain only the given values. (intersection of the
3955 original set and the given set)
3956 returns:
3957 main.TRUE on success OR
3958 main.FALSE if the set was not changed OR
3959 main.ERROR on error
3960 """
3961 try:
3962 cmdStr = "set-test-remove "
3963 if clear:
3964 cmdStr += "-c " + str( setName )
3965 elif retain:
3966 cmdStr += "-r " + str( setName ) + " " + str( values )
3967 else:
3968 cmdStr += str( setName ) + " " + str( values )
3969 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003970 try:
Jon Halla495f562016-05-16 18:03:26 -07003971 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07003972 # TODO: Maybe make this less hardcoded
3973 # ConsistentMap Exceptions
3974 assert "org.onosproject.store.service" not in output
3975 # Node not leader
3976 assert "java.lang.IllegalStateException" not in output
3977 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003978 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003979 "command: " + str( output ) )
3980 retryTime = 30 # Conservative time, given by Madan
3981 main.log.info( "Waiting " + str( retryTime ) +
3982 "seconds before retrying." )
3983 time.sleep( retryTime ) # Due to change in mastership
3984 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003985 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003986 assert "Command not found:" not in output, output
3987 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003988 main.log.info( self.name + ": " + output )
3989 if clear:
3990 pattern = "Set " + str( setName ) + " cleared"
3991 if re.search( pattern, output ):
3992 return main.TRUE
3993 elif retain:
3994 positivePattern = str( setName ) + " was pruned to contain " +\
3995 "only elements of set \[(.*)\]"
3996 negativePattern = str( setName ) + " was not changed by " +\
3997 "retaining only elements of the set " +\
3998 "\[(.*)\]"
3999 if re.search( positivePattern, output ):
4000 return main.TRUE
4001 elif re.search( negativePattern, output ):
4002 return main.FALSE
4003 else:
4004 positivePattern = "\[(.*)\] was removed from the set " +\
4005 str( setName )
4006 if ( len( values.split() ) == 1 ):
4007 negativePattern = "\[(.*)\] was not in set " +\
4008 str( setName )
4009 else:
4010 negativePattern = "No element of \[(.*)\] was in set " +\
4011 str( setName )
4012 if re.search( positivePattern, output ):
4013 return main.TRUE
4014 elif re.search( negativePattern, output ):
4015 return main.FALSE
4016 main.log.error( self.name + ": setTestRemove did not" +
4017 " match expected output" )
4018 main.log.debug( self.name + " expected: " + pattern )
4019 main.log.debug( self.name + " actual: " + repr( output ) )
4020 return main.ERROR
4021 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004022 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07004023 return main.ERROR
4024 except TypeError:
4025 main.log.exception( self.name + ": Object not as expected" )
4026 return main.ERROR
4027 except pexpect.EOF:
4028 main.log.error( self.name + ": EOF exception found" )
4029 main.log.error( self.name + ": " + self.handle.before )
4030 main.cleanup()
4031 main.exit()
4032 except Exception:
4033 main.log.exception( self.name + ": Uncaught exception!" )
4034 main.cleanup()
4035 main.exit()
4036
4037 def setTestGet( self, setName, values="" ):
4038 """
4039 CLI command to get the elements in a distributed set.
4040 Required arguments:
4041 setName - The name of the set to remove from.
4042 Optional arguments:
4043 values - The value(s) to check if in the set, space seperated.
4044 returns:
4045 main.ERROR on error OR
4046 A list of elements in the set if no optional arguments are
4047 supplied OR
4048 A tuple containing the list then:
4049 main.FALSE if the given values are not in the set OR
4050 main.TRUE if the given values are in the set OR
4051 """
4052 try:
4053 values = str( values ).strip()
4054 setName = str( setName ).strip()
4055 length = len( values.split() )
4056 containsCheck = None
4057 # Patterns to match
4058 setPattern = "\[(.*)\]"
4059 pattern = "Items in set " + setName + ":\n" + setPattern
4060 containsTrue = "Set " + setName + " contains the value " + values
4061 containsFalse = "Set " + setName + " did not contain the value " +\
4062 values
4063 containsAllTrue = "Set " + setName + " contains the the subset " +\
4064 setPattern
4065 containsAllFalse = "Set " + setName + " did not contain the the" +\
4066 " subset " + setPattern
4067
4068 cmdStr = "set-test-get "
4069 cmdStr += setName + " " + values
4070 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004071 try:
Jon Halla495f562016-05-16 18:03:26 -07004072 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004073 # TODO: Maybe make this less hardcoded
4074 # ConsistentMap Exceptions
4075 assert "org.onosproject.store.service" not in output
4076 # Node not leader
4077 assert "java.lang.IllegalStateException" not in output
4078 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004079 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004080 "command: " + str( output ) )
4081 retryTime = 30 # Conservative time, given by Madan
4082 main.log.info( "Waiting " + str( retryTime ) +
4083 "seconds before retrying." )
4084 time.sleep( retryTime ) # Due to change in mastership
4085 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004086 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004087 assert "Command not found:" not in output, output
4088 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004089 main.log.info( self.name + ": " + output )
4090
4091 if length == 0:
4092 match = re.search( pattern, output )
4093 else: # if given values
4094 if length == 1: # Contains output
4095 patternTrue = pattern + "\n" + containsTrue
4096 patternFalse = pattern + "\n" + containsFalse
4097 else: # ContainsAll output
4098 patternTrue = pattern + "\n" + containsAllTrue
4099 patternFalse = pattern + "\n" + containsAllFalse
4100 matchTrue = re.search( patternTrue, output )
4101 matchFalse = re.search( patternFalse, output )
4102 if matchTrue:
4103 containsCheck = main.TRUE
4104 match = matchTrue
4105 elif matchFalse:
4106 containsCheck = main.FALSE
4107 match = matchFalse
4108 else:
4109 main.log.error( self.name + " setTestGet did not match " +\
4110 "expected output" )
4111 main.log.debug( self.name + " expected: " + pattern )
4112 main.log.debug( self.name + " actual: " + repr( output ) )
4113 match = None
4114 if match:
4115 setMatch = match.group( 1 )
4116 if setMatch == '':
4117 setList = []
4118 else:
4119 setList = setMatch.split( ", " )
4120 if length > 0:
4121 return ( setList, containsCheck )
4122 else:
4123 return setList
4124 else: # no match
4125 main.log.error( self.name + ": setTestGet did not" +
4126 " match expected output" )
4127 main.log.debug( self.name + " expected: " + pattern )
4128 main.log.debug( self.name + " actual: " + repr( output ) )
4129 return main.ERROR
4130 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004131 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004132 return main.ERROR
4133 except TypeError:
4134 main.log.exception( self.name + ": Object not as expected" )
4135 return main.ERROR
4136 except pexpect.EOF:
4137 main.log.error( self.name + ": EOF exception found" )
4138 main.log.error( self.name + ": " + self.handle.before )
4139 main.cleanup()
4140 main.exit()
4141 except Exception:
4142 main.log.exception( self.name + ": Uncaught exception!" )
4143 main.cleanup()
4144 main.exit()
4145
4146 def setTestSize( self, setName ):
4147 """
4148 CLI command to get the elements in a distributed set.
4149 Required arguments:
4150 setName - The name of the set to remove from.
4151 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004152 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004153 None on error
4154 """
4155 try:
4156 # TODO: Should this check against the number of elements returned
4157 # and then return true/false based on that?
4158 setName = str( setName ).strip()
4159 # Patterns to match
4160 setPattern = "\[(.*)\]"
4161 pattern = "There are (\d+) items in set " + setName + ":\n" +\
4162 setPattern
4163 cmdStr = "set-test-get -s "
4164 cmdStr += setName
4165 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004166 try:
Jon Halla495f562016-05-16 18:03:26 -07004167 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004168 # TODO: Maybe make this less hardcoded
4169 # ConsistentMap Exceptions
4170 assert "org.onosproject.store.service" not in output
4171 # Node not leader
4172 assert "java.lang.IllegalStateException" not in output
4173 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004174 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004175 "command: " + str( output ) )
4176 retryTime = 30 # Conservative time, given by Madan
4177 main.log.info( "Waiting " + str( retryTime ) +
4178 "seconds before retrying." )
4179 time.sleep( retryTime ) # Due to change in mastership
4180 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004181 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004182 assert "Command not found:" not in output, output
4183 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004184 main.log.info( self.name + ": " + output )
4185 match = re.search( pattern, output )
4186 if match:
4187 setSize = int( match.group( 1 ) )
4188 setMatch = match.group( 2 )
4189 if len( setMatch.split() ) == setSize:
4190 main.log.info( "The size returned by " + self.name +
4191 " matches the number of elements in " +
4192 "the returned set" )
4193 else:
4194 main.log.error( "The size returned by " + self.name +
4195 " does not match the number of " +
4196 "elements in the returned set." )
4197 return setSize
4198 else: # no match
4199 main.log.error( self.name + ": setTestGet did not" +
4200 " match expected output" )
4201 main.log.debug( self.name + " expected: " + pattern )
4202 main.log.debug( self.name + " actual: " + repr( output ) )
4203 return None
4204 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004205 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004206 return None
Jon Hall390696c2015-05-05 17:13:41 -07004207 except TypeError:
4208 main.log.exception( self.name + ": Object not as expected" )
4209 return None
4210 except pexpect.EOF:
4211 main.log.error( self.name + ": EOF exception found" )
4212 main.log.error( self.name + ": " + self.handle.before )
4213 main.cleanup()
4214 main.exit()
4215 except Exception:
4216 main.log.exception( self.name + ": Uncaught exception!" )
4217 main.cleanup()
4218 main.exit()
4219
Jon Hall80daded2015-05-27 16:07:00 -07004220 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004221 """
4222 Command to list the various counters in the system.
4223 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004224 if jsonFormat, a string of the json object returned by the cli
4225 command
4226 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004227 None on error
4228 """
Jon Hall390696c2015-05-05 17:13:41 -07004229 try:
4230 counters = {}
4231 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004232 if jsonFormat:
4233 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004234 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004235 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004236 assert "Command not found:" not in output, output
4237 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004238 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004239 return output
Jon Hall390696c2015-05-05 17:13:41 -07004240 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004241 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004242 return None
Jon Hall390696c2015-05-05 17:13:41 -07004243 except TypeError:
4244 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004245 return None
Jon Hall390696c2015-05-05 17:13:41 -07004246 except pexpect.EOF:
4247 main.log.error( self.name + ": EOF exception found" )
4248 main.log.error( self.name + ": " + self.handle.before )
4249 main.cleanup()
4250 main.exit()
4251 except Exception:
4252 main.log.exception( self.name + ": Uncaught exception!" )
4253 main.cleanup()
4254 main.exit()
4255
Jon Hall935db192016-04-19 00:22:04 -07004256 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004257 """
Jon Halle1a3b752015-07-22 13:02:46 -07004258 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004259 Required arguments:
4260 counter - The name of the counter to increment.
4261 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004262 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004263 returns:
4264 integer value of the counter or
4265 None on Error
4266 """
4267 try:
4268 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004269 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004270 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004271 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004272 if delta != 1:
4273 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004274 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004275 try:
Jon Halla495f562016-05-16 18:03:26 -07004276 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004277 # TODO: Maybe make this less hardcoded
4278 # ConsistentMap Exceptions
4279 assert "org.onosproject.store.service" not in output
4280 # Node not leader
4281 assert "java.lang.IllegalStateException" not in output
4282 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004283 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004284 "command: " + str( output ) )
4285 retryTime = 30 # Conservative time, given by Madan
4286 main.log.info( "Waiting " + str( retryTime ) +
4287 "seconds before retrying." )
4288 time.sleep( retryTime ) # Due to change in mastership
4289 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004290 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004291 assert "Command not found:" not in output, output
4292 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004293 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004294 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004295 match = re.search( pattern, output )
4296 if match:
4297 return int( match.group( 1 ) )
4298 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004299 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004300 " match expected output." )
4301 main.log.debug( self.name + " expected: " + pattern )
4302 main.log.debug( self.name + " actual: " + repr( output ) )
4303 return None
4304 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004305 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004306 return None
4307 except TypeError:
4308 main.log.exception( self.name + ": Object not as expected" )
4309 return None
4310 except pexpect.EOF:
4311 main.log.error( self.name + ": EOF exception found" )
4312 main.log.error( self.name + ": " + self.handle.before )
4313 main.cleanup()
4314 main.exit()
4315 except Exception:
4316 main.log.exception( self.name + ": Uncaught exception!" )
4317 main.cleanup()
4318 main.exit()
4319
Jon Hall935db192016-04-19 00:22:04 -07004320 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004321 """
4322 CLI command to get a distributed counter then add a delta to it.
4323 Required arguments:
4324 counter - The name of the counter to increment.
4325 Optional arguments:
4326 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004327 returns:
4328 integer value of the counter or
4329 None on Error
4330 """
4331 try:
4332 counter = str( counter )
4333 delta = int( delta )
4334 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004335 cmdStr += counter
4336 if delta != 1:
4337 cmdStr += " " + str( delta )
4338 output = self.sendline( cmdStr )
4339 try:
Jon Halla495f562016-05-16 18:03:26 -07004340 assert output is not None, "Error in sendline"
Jon Halle1a3b752015-07-22 13:02:46 -07004341 # TODO: Maybe make this less hardcoded
4342 # ConsistentMap Exceptions
4343 assert "org.onosproject.store.service" not in output
4344 # Node not leader
4345 assert "java.lang.IllegalStateException" not in output
4346 except AssertionError:
4347 main.log.error( "Error in processing '" + cmdStr + "' " +
4348 "command: " + str( output ) )
4349 retryTime = 30 # Conservative time, given by Madan
4350 main.log.info( "Waiting " + str( retryTime ) +
4351 "seconds before retrying." )
4352 time.sleep( retryTime ) # Due to change in mastership
4353 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004354 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004355 assert "Command not found:" not in output, output
4356 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004357 main.log.info( self.name + ": " + output )
4358 pattern = counter + " was updated to (-?\d+)"
4359 match = re.search( pattern, output )
4360 if match:
4361 return int( match.group( 1 ) )
4362 else:
4363 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4364 " match expected output." )
4365 main.log.debug( self.name + " expected: " + pattern )
4366 main.log.debug( self.name + " actual: " + repr( output ) )
4367 return None
4368 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004369 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004370 return None
4371 except TypeError:
4372 main.log.exception( self.name + ": Object not as expected" )
4373 return None
4374 except pexpect.EOF:
4375 main.log.error( self.name + ": EOF exception found" )
4376 main.log.error( self.name + ": " + self.handle.before )
4377 main.cleanup()
4378 main.exit()
4379 except Exception:
4380 main.log.exception( self.name + ": Uncaught exception!" )
4381 main.cleanup()
4382 main.exit()
4383
YPZhangfebf7302016-05-24 16:45:56 -07004384 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004385 """
4386 Description: Execute summary command in onos
4387 Returns: json object ( summary -j ), returns main.FALSE if there is
4388 no output
4389
4390 """
4391 try:
4392 cmdStr = "summary"
4393 if jsonFormat:
4394 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004395 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004396 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004397 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004398 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004399 if not handle:
4400 main.log.error( self.name + ": There is no output in " +
4401 "summary command" )
4402 return main.FALSE
4403 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004404 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004405 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004406 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004407 except TypeError:
4408 main.log.exception( self.name + ": Object not as expected" )
4409 return None
4410 except pexpect.EOF:
4411 main.log.error( self.name + ": EOF exception found" )
4412 main.log.error( self.name + ": " + self.handle.before )
4413 main.cleanup()
4414 main.exit()
4415 except Exception:
4416 main.log.exception( self.name + ": Uncaught exception!" )
4417 main.cleanup()
4418 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004419
Jon Hall935db192016-04-19 00:22:04 -07004420 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004421 """
4422 CLI command to get the value of a key in a consistent map using
4423 transactions. This a test function and can only get keys from the
4424 test map hard coded into the cli command
4425 Required arguments:
4426 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004427 returns:
4428 The string value of the key or
4429 None on Error
4430 """
4431 try:
4432 keyName = str( keyName )
4433 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004434 cmdStr += keyName
4435 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004436 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004437 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004438 try:
4439 # TODO: Maybe make this less hardcoded
4440 # ConsistentMap Exceptions
4441 assert "org.onosproject.store.service" not in output
4442 # Node not leader
4443 assert "java.lang.IllegalStateException" not in output
4444 except AssertionError:
4445 main.log.error( "Error in processing '" + cmdStr + "' " +
4446 "command: " + str( output ) )
4447 return None
4448 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4449 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004450 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004451 return None
4452 else:
4453 match = re.search( pattern, output )
4454 if match:
4455 return match.groupdict()[ 'value' ]
4456 else:
4457 main.log.error( self.name + ": transactionlMapGet did not" +
4458 " match expected output." )
4459 main.log.debug( self.name + " expected: " + pattern )
4460 main.log.debug( self.name + " actual: " + repr( output ) )
4461 return None
Jon Hallc6793552016-01-19 14:18:37 -08004462 except AssertionError:
4463 main.log.exception( "" )
4464 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004465 except TypeError:
4466 main.log.exception( self.name + ": Object not as expected" )
4467 return None
4468 except pexpect.EOF:
4469 main.log.error( self.name + ": EOF exception found" )
4470 main.log.error( self.name + ": " + self.handle.before )
4471 main.cleanup()
4472 main.exit()
4473 except Exception:
4474 main.log.exception( self.name + ": Uncaught exception!" )
4475 main.cleanup()
4476 main.exit()
4477
Jon Hall935db192016-04-19 00:22:04 -07004478 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004479 """
4480 CLI command to put a value into 'numKeys' number of keys in a
4481 consistent map using transactions. This a test function and can only
4482 put into keys named 'Key#' of the test map hard coded into the cli command
4483 Required arguments:
4484 numKeys - Number of keys to add the value to
4485 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004486 returns:
4487 A dictionary whose keys are the name of the keys put into the map
4488 and the values of the keys are dictionaries whose key-values are
4489 'value': value put into map and optionaly
4490 'oldValue': Previous value in the key or
4491 None on Error
4492
4493 Example output
4494 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4495 'Key2': {'value': 'Testing'} }
4496 """
4497 try:
4498 numKeys = str( numKeys )
4499 value = str( value )
4500 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004501 cmdStr += numKeys + " " + value
4502 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004503 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004504 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004505 try:
4506 # TODO: Maybe make this less hardcoded
4507 # ConsistentMap Exceptions
4508 assert "org.onosproject.store.service" not in output
4509 # Node not leader
4510 assert "java.lang.IllegalStateException" not in output
4511 except AssertionError:
4512 main.log.error( "Error in processing '" + cmdStr + "' " +
4513 "command: " + str( output ) )
4514 return None
4515 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4516 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4517 results = {}
4518 for line in output.splitlines():
4519 new = re.search( newPattern, line )
4520 updated = re.search( updatedPattern, line )
4521 if new:
4522 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4523 elif updated:
4524 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004525 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004526 else:
4527 main.log.error( self.name + ": transactionlMapGet did not" +
4528 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004529 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4530 newPattern,
4531 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004532 main.log.debug( self.name + " actual: " + repr( output ) )
4533 return results
Jon Hallc6793552016-01-19 14:18:37 -08004534 except AssertionError:
4535 main.log.exception( "" )
4536 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004537 except TypeError:
4538 main.log.exception( self.name + ": Object not as expected" )
4539 return None
4540 except pexpect.EOF:
4541 main.log.error( self.name + ": EOF exception found" )
4542 main.log.error( self.name + ": " + self.handle.before )
4543 main.cleanup()
4544 main.exit()
4545 except Exception:
4546 main.log.exception( self.name + ": Uncaught exception!" )
4547 main.cleanup()
4548 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004549
acsmarsdaea66c2015-09-03 11:44:06 -07004550 def maps( self, jsonFormat=True ):
4551 """
4552 Description: Returns result of onos:maps
4553 Optional:
4554 * jsonFormat: enable json formatting of output
4555 """
4556 try:
4557 cmdStr = "maps"
4558 if jsonFormat:
4559 cmdStr += " -j"
4560 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004561 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004562 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004563 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004564 except AssertionError:
4565 main.log.exception( "" )
4566 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004567 except TypeError:
4568 main.log.exception( self.name + ": Object not as expected" )
4569 return None
4570 except pexpect.EOF:
4571 main.log.error( self.name + ": EOF exception found" )
4572 main.log.error( self.name + ": " + self.handle.before )
4573 main.cleanup()
4574 main.exit()
4575 except Exception:
4576 main.log.exception( self.name + ": Uncaught exception!" )
4577 main.cleanup()
4578 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004579
4580 def getSwController( self, uri, jsonFormat=True ):
4581 """
4582 Descrition: Gets the controller information from the device
4583 """
4584 try:
4585 cmd = "device-controllers "
4586 if jsonFormat:
4587 cmd += "-j "
4588 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004589 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004590 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004591 return response
Jon Hallc6793552016-01-19 14:18:37 -08004592 except AssertionError:
4593 main.log.exception( "" )
4594 return None
GlennRC050596c2015-11-18 17:06:41 -08004595 except TypeError:
4596 main.log.exception( self.name + ": Object not as expected" )
4597 return None
4598 except pexpect.EOF:
4599 main.log.error( self.name + ": EOF exception found" )
4600 main.log.error( self.name + ": " + self.handle.before )
4601 main.cleanup()
4602 main.exit()
4603 except Exception:
4604 main.log.exception( self.name + ": Uncaught exception!" )
4605 main.cleanup()
4606 main.exit()
4607
4608 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4609 """
4610 Descrition: sets the controller(s) for the specified device
4611
4612 Parameters:
4613 Required: uri - String: The uri of the device(switch).
4614 ip - String or List: The ip address of the controller.
4615 This parameter can be formed in a couple of different ways.
4616 VALID:
4617 10.0.0.1 - just the ip address
4618 tcp:10.0.0.1 - the protocol and the ip address
4619 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4620 so that you can add controllers with different
4621 protocols and ports
4622 INVALID:
4623 10.0.0.1:6653 - this is not supported by ONOS
4624
4625 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4626 port - The port number.
4627 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4628
4629 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4630 """
4631 try:
4632 cmd = "device-setcontrollers"
4633
4634 if jsonFormat:
4635 cmd += " -j"
4636 cmd += " " + uri
4637 if isinstance( ip, str ):
4638 ip = [ip]
4639 for item in ip:
4640 if ":" in item:
4641 sitem = item.split( ":" )
4642 if len(sitem) == 3:
4643 cmd += " " + item
4644 elif "." in sitem[1]:
4645 cmd += " {}:{}".format(item, port)
4646 else:
4647 main.log.error( "Malformed entry: " + item )
4648 raise TypeError
4649 else:
4650 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004651 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004652 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004653 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004654 if "Error" in response:
4655 main.log.error( response )
4656 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004657 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004658 except AssertionError:
4659 main.log.exception( "" )
4660 return None
GlennRC050596c2015-11-18 17:06:41 -08004661 except TypeError:
4662 main.log.exception( self.name + ": Object not as expected" )
4663 return main.FALSE
4664 except pexpect.EOF:
4665 main.log.error( self.name + ": EOF exception found" )
4666 main.log.error( self.name + ": " + self.handle.before )
4667 main.cleanup()
4668 main.exit()
4669 except Exception:
4670 main.log.exception( self.name + ": Uncaught exception!" )
4671 main.cleanup()
4672 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004673
4674 def removeDevice( self, device ):
4675 '''
4676 Description:
4677 Remove a device from ONOS by passing the uri of the device(s).
4678 Parameters:
4679 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4680 Returns:
4681 Returns main.FALSE if an exception is thrown or an error is present
4682 in the response. Otherwise, returns main.TRUE.
4683 NOTE:
4684 If a host cannot be removed, then this function will return main.FALSE
4685 '''
4686 try:
4687 if type( device ) is str:
4688 device = list( device )
4689
4690 for d in device:
4691 time.sleep( 1 )
4692 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004693 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004694 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004695 if "Error" in response:
4696 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4697 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004698 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004699 except AssertionError:
4700 main.log.exception( "" )
4701 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004702 except TypeError:
4703 main.log.exception( self.name + ": Object not as expected" )
4704 return main.FALSE
4705 except pexpect.EOF:
4706 main.log.error( self.name + ": EOF exception found" )
4707 main.log.error( self.name + ": " + self.handle.before )
4708 main.cleanup()
4709 main.exit()
4710 except Exception:
4711 main.log.exception( self.name + ": Uncaught exception!" )
4712 main.cleanup()
4713 main.exit()
4714
4715 def removeHost( self, host ):
4716 '''
4717 Description:
4718 Remove a host from ONOS by passing the id of the host(s)
4719 Parameters:
4720 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4721 Returns:
4722 Returns main.FALSE if an exception is thrown or an error is present
4723 in the response. Otherwise, returns main.TRUE.
4724 NOTE:
4725 If a host cannot be removed, then this function will return main.FALSE
4726 '''
4727 try:
4728 if type( host ) is str:
4729 host = list( host )
4730
4731 for h in host:
4732 time.sleep( 1 )
4733 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004734 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004735 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004736 if "Error" in response:
4737 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4738 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004739 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004740 except AssertionError:
4741 main.log.exception( "" )
4742 return None
GlennRC20fc6522015-12-23 23:26:57 -08004743 except TypeError:
4744 main.log.exception( self.name + ": Object not as expected" )
4745 return main.FALSE
4746 except pexpect.EOF:
4747 main.log.error( self.name + ": EOF exception found" )
4748 main.log.error( self.name + ": " + self.handle.before )
4749 main.cleanup()
4750 main.exit()
4751 except Exception:
4752 main.log.exception( self.name + ": Uncaught exception!" )
4753 main.cleanup()
4754 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004755
YPZhangfebf7302016-05-24 16:45:56 -07004756 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004757 '''
4758 Description:
4759 Bring link down or up in the null-provider.
4760 params:
4761 begin - (string) One end of a device or switch.
4762 end - (string) the other end of the device or switch
4763 returns:
4764 main.TRUE if no exceptions were thrown and no Errors are
4765 present in the resoponse. Otherwise, returns main.FALSE
4766 '''
4767 try:
Jon Hallc6793552016-01-19 14:18:37 -08004768 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004769 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004770 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004771 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004772 if "Error" in response or "Failure" in response:
4773 main.log.error( response )
4774 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004775 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004776 except AssertionError:
4777 main.log.exception( "" )
4778 return None
GlennRCed771242016-01-13 17:02:47 -08004779 except TypeError:
4780 main.log.exception( self.name + ": Object not as expected" )
4781 return main.FALSE
4782 except pexpect.EOF:
4783 main.log.error( self.name + ": EOF exception found" )
4784 main.log.error( self.name + ": " + self.handle.before )
4785 main.cleanup()
4786 main.exit()
4787 except Exception:
4788 main.log.exception( self.name + ": Uncaught exception!" )
4789 main.cleanup()
4790 main.exit()
4791
Flavio Castro82ee2f62016-06-07 15:04:12 -07004792 def portstate(self, dpid='of:0000000000000102', port='2', state='enable'):
4793 '''
4794 Description:
4795 Changes the state of port in an OF switch by means of the
4796 PORTSTATUS OF messages.
4797 params:
4798 dpid - (string) Datapath ID of the device
4799 port - (string) target port in the device
4800 state - (string) target state (enable or disabled)
4801 returns:
4802 main.TRUE if no exceptions were thrown and no Errors are
4803 present in the resoponse. Otherwise, returns main.FALSE
4804 '''
4805 try:
4806 cmd = "portstate {} {} {}".format( dpid, port, state )
4807 response = self.sendline( cmd, showResponse=True )
4808 assert response is not None, "Error in sendline"
4809 assert "Command not found:" not in response, response
4810 if "Error" in response or "Failure" in response:
4811 main.log.error( response )
4812 return main.FALSE
4813 return main.TRUE
4814 except AssertionError:
4815 main.log.exception( "" )
4816 return None
4817 except TypeError:
4818 main.log.exception( self.name + ": Object not as expected" )
4819 return main.FALSE
4820 except pexpect.EOF:
4821 main.log.error( self.name + ": EOF exception found" )
4822 main.log.error( self.name + ": " + self.handle.before )
4823 main.cleanup()
4824 main.exit()
4825 except Exception:
4826 main.log.exception( self.name + ": Uncaught exception!" )
4827 main.cleanup()
4828 main.exit()
4829
4830 def logSet( self, level="INFO", app="org.onosproject" ):
4831 """
4832 Set the logging level to lvl for a specific app
4833 returns main.TRUE on success
4834 returns main.FALSE if Error occurred
4835 if noExit is True, TestON will not exit, but clean up
4836 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4837 Level defaults to INFO
4838 """
4839 try:
4840 self.handle.sendline( "log:set %s %s" %( level, app ) )
4841 self.handle.expect( "onos>" )
4842
4843 response = self.handle.before
4844 if re.search( "Error", response ):
4845 return main.FALSE
4846 return main.TRUE
4847 except pexpect.TIMEOUT:
4848 main.log.exception( self.name + ": TIMEOUT exception found" )
4849 main.cleanup()
4850 main.exit()
4851 except pexpect.EOF:
4852 main.log.error( self.name + ": EOF exception found" )
4853 main.log.error( self.name + ": " + self.handle.before )
4854 main.cleanup()
4855 main.exit()
4856 except Exception:
4857 main.log.exception( self.name + ": Uncaught exception!" )
4858 main.cleanup()
4859 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004860
4861 def getGraphDict( self, timeout=60, includeHost=False ):
4862 """
4863 Return a dictionary which describes the latest network topology data as a
4864 graph.
4865 An example of the dictionary:
4866 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4867 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4868 Each vertex should at least have an 'edges' attribute which describes the
4869 adjacency information. The value of 'edges' attribute is also represented by
4870 a dictionary, which maps each edge (identified by the neighbor vertex) to a
4871 list of attributes.
4872 An example of the edges dictionary:
4873 'edges': { vertex2: { 'port': ..., 'weight': ... },
4874 vertex3: { 'port': ..., 'weight': ... } }
4875 If includeHost == True, all hosts (and host-switch links) will be included
4876 in topology data.
4877 """
4878 graphDict = {}
4879 try:
4880 links = self.links()
4881 links = json.loads( links )
4882 devices = self.devices()
4883 devices = json.loads( devices )
4884 idToDevice = {}
4885 for device in devices:
4886 idToDevice[ device[ 'id' ] ] = device
4887 if includeHost:
4888 hosts = self.hosts()
4889 # FIXME: support 'includeHost' argument
4890 for link in links:
4891 nodeA = link[ 'src' ][ 'device' ]
4892 nodeB = link[ 'dst' ][ 'device' ]
4893 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
4894 if not nodeA in graphDict.keys():
4895 graphDict[ nodeA ] = { 'edges':{},
4896 'dpid':idToDevice[ nodeA ][ 'id' ][3:],
4897 'type':idToDevice[ nodeA ][ 'type' ],
4898 'available':idToDevice[ nodeA ][ 'available' ],
4899 'role':idToDevice[ nodeA ][ 'role' ],
4900 'mfr':idToDevice[ nodeA ][ 'mfr' ],
4901 'hw':idToDevice[ nodeA ][ 'hw' ],
4902 'sw':idToDevice[ nodeA ][ 'sw' ],
4903 'serial':idToDevice[ nodeA ][ 'serial' ],
4904 'chassisId':idToDevice[ nodeA ][ 'chassisId' ],
4905 'annotations':idToDevice[ nodeA ][ 'annotations' ]}
4906 else:
4907 # Assert nodeB is not connected to any current links of nodeA
4908 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
4909 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port':link[ 'src' ][ 'port' ],
4910 'type':link[ 'type' ],
4911 'state':link[ 'state' ] }
4912 return graphDict
4913 except ( TypeError, ValueError ):
4914 main.log.exception( self.name + ": Object not as expected" )
4915 return None
4916 except KeyError:
4917 main.log.exception( self.name + ": KeyError exception found" )
4918 return None
4919 except AssertionError:
4920 main.log.exception( self.name + ": AssertionError exception found" )
4921 return None
4922 except pexpect.EOF:
4923 main.log.error( self.name + ": EOF exception found" )
4924 main.log.error( self.name + ": " + self.handle.before )
4925 return None
4926 except Exception:
4927 main.log.exception( self.name + ": Uncaught exception!" )
4928 return None
YPZhangcbc2a062016-07-11 10:55:44 -07004929
4930 def getIntentPerfSummary( self ):
4931 '''
4932 Send command to check intent-perf summary
4933 Returns: dictionary for intent-perf summary
4934 if something wrong, function will return None
4935 '''
4936 cmd = "intent-perf -s"
4937 respDic = {}
4938 resp = self.sendline( cmd )
4939 try:
4940 # Generate the dictionary to return
4941 for l in resp.split( "\n" ):
4942 # Delete any white space in line
4943 temp = re.sub( r'\s+', '', l )
4944 temp = temp.split( ":" )
4945 respDic[ temp[0] ] = temp[ 1 ]
4946
4947 except (TypeError, ValueError):
4948 main.log.exception( self.name + ": Object not as expected" )
4949 return None
4950 except KeyError:
4951 main.log.exception( self.name + ": KeyError exception found" )
4952 return None
4953 except AssertionError:
4954 main.log.exception( self.name + ": AssertionError exception found" )
4955 return None
4956 except pexpect.EOF:
4957 main.log.error( self.name + ": EOF exception found" )
4958 main.log.error( self.name + ": " + self.handle.before )
4959 return None
4960 except Exception:
4961 main.log.exception( self.name + ": Uncaught exception!" )
4962 return None
4963 return respDic
4964
4965