blob: 703e15f8a6ab01c088374fe6fc30975077701559 [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 sys
andrewonlab95ce8322014-10-13 14:12:04 -040020import pexpect
21import re
Jon Hall30b82fa2015-03-04 17:15:43 -080022import json
23import types
Jon Hallbd16b922015-03-26 17:53:15 -070024import time
kelvin8ec71442015-01-15 16:57:00 -080025sys.path.append( "../" )
andrewonlab95ce8322014-10-13 14:12:04 -040026from drivers.common.clidriver import CLI
27
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
kelvin8ec71442015-01-15 16:57:00 -080038 super( CLI, self ).__init__()
39
40 def connect( self, **connectargs ):
41 """
andrewonlab95ce8322014-10-13 14:12:04 -040042 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080043 """
andrewonlab95ce8322014-10-13 14:12:04 -040044 try:
45 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080046 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070047 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040048 for key in self.options:
49 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080050 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040051 break
kelvin-onlabfb521662015-02-27 09:52:40 -080052 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070053 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040054
kelvin8ec71442015-01-15 16:57:00 -080055 self.name = self.options[ 'name' ]
56 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080057 user_name=self.user_name,
58 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080059 port=self.port,
60 pwd=self.pwd,
61 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040062
kelvin8ec71442015-01-15 16:57:00 -080063 self.handle.sendline( "cd " + self.home )
64 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040065 if self.handle:
66 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080067 else:
68 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040069 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080070 except TypeError:
71 main.log.exception( self.name + ": Object not as expected" )
72 return None
andrewonlab95ce8322014-10-13 14:12:04 -040073 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080074 main.log.error( self.name + ": EOF exception found" )
75 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040076 main.cleanup()
77 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080078 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -080079 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -040080 main.cleanup()
81 main.exit()
82
kelvin8ec71442015-01-15 16:57:00 -080083 def disconnect( self ):
84 """
andrewonlab95ce8322014-10-13 14:12:04 -040085 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -080086 """
Jon Halld61331b2015-02-17 16:35:47 -080087 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -040088 try:
Jon Hall61282e32015-03-19 11:34:11 -070089 if self.handle:
90 i = self.logout()
91 if i == main.TRUE:
92 self.handle.sendline( "" )
93 self.handle.expect( "\$" )
94 self.handle.sendline( "exit" )
95 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -080096 except TypeError:
97 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -080098 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -040099 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800100 main.log.error( self.name + ": EOF exception found" )
101 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700102 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700103 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700104 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800105 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800106 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400107 response = main.FALSE
108 return response
109
kelvin8ec71442015-01-15 16:57:00 -0800110 def logout( self ):
111 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500112 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700113 Returns main.TRUE if exited CLI and
114 main.FALSE on timeout (not guranteed you are disconnected)
115 None on TypeError
116 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800117 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500118 try:
Jon Hall61282e32015-03-19 11:34:11 -0700119 if self.handle:
120 self.handle.sendline( "" )
121 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
122 timeout=10 )
123 if i == 0: # In ONOS CLI
124 self.handle.sendline( "logout" )
125 self.handle.expect( "\$" )
126 return main.TRUE
127 elif i == 1: # not in CLI
128 return main.TRUE
129 elif i == 3: # Timeout
130 return main.FALSE
131 else:
andrewonlab9627f432014-11-14 12:45:10 -0500132 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800133 except TypeError:
134 main.log.exception( self.name + ": Object not as expected" )
135 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500136 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800137 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700138 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500139 main.cleanup()
140 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700141 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700142 main.log.error( self.name +
143 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800144 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800145 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500146 main.cleanup()
147 main.exit()
148
kelvin-onlabd3b64892015-01-20 13:26:24 -0800149 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800150 """
andrewonlab95ce8322014-10-13 14:12:04 -0400151 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800152
andrewonlab95ce8322014-10-13 14:12:04 -0400153 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800154 """
andrewonlab95ce8322014-10-13 14:12:04 -0400155 try:
156 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800157 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400158 main.cleanup()
159 main.exit()
160 else:
kelvin8ec71442015-01-15 16:57:00 -0800161 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800162 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800163 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400164 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800165 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800166 handleBefore = self.handle.before
167 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800168 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800169 self.handle.sendline("")
170 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800171 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400172
kelvin-onlabd3b64892015-01-20 13:26:24 -0800173 main.log.info( "Cell call returned: " + handleBefore +
174 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400175
176 return main.TRUE
177
Jon Halld4d4b372015-01-28 16:02:41 -0800178 except TypeError:
179 main.log.exception( self.name + ": Object not as expected" )
180 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400181 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800182 main.log.error( self.name + ": eof exception found" )
183 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400184 main.cleanup()
185 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800186 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800187 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400188 main.cleanup()
189 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800190
kelvin-onlabd3b64892015-01-20 13:26:24 -0800191 def startOnosCli( self, ONOSIp, karafTimeout="" ):
kelvin8ec71442015-01-15 16:57:00 -0800192 """
Jon Hallefbd9792015-03-05 16:11:36 -0800193 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800194 by user would be used to set the current karaf shell idle timeout.
195 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800196 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800197 Below is an example to start a session with 60 seconds idle timeout
198 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800199
Hari Krishna25d42f72015-01-05 15:08:28 -0800200 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800201 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800202
kelvin-onlabd3b64892015-01-20 13:26:24 -0800203 Note: karafTimeout is left as str so that this could be read
204 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800205 """
andrewonlab95ce8322014-10-13 14:12:04 -0400206 try:
kelvin8ec71442015-01-15 16:57:00 -0800207 self.handle.sendline( "" )
208 x = self.handle.expect( [
209 "\$", "onos>" ], timeout=10 )
andrewonlab48829f62014-11-17 13:49:01 -0500210
211 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800212 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500213 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400214
kelvin8ec71442015-01-15 16:57:00 -0800215 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800216 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800217 i = self.handle.expect( [
218 "onos>",
kelvin-onlab898a6c62015-01-16 14:13:53 -0800219 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400220
221 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800222 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800223 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800224 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800225 "config:property-set -p org.apache.karaf.shell\
226 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800227 karafTimeout )
228 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800229 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800230 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400231 return main.TRUE
232 else:
kelvin8ec71442015-01-15 16:57:00 -0800233 # If failed, send ctrl+c to process and try again
234 main.log.info( "Starting CLI failed. Retrying..." )
235 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800236 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800237 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
238 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400239 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800240 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800241 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800242 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800243 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800244 "config:property-set -p org.apache.karaf.shell\
245 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800246 karafTimeout )
247 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800248 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800249 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400250 return main.TRUE
251 else:
kelvin8ec71442015-01-15 16:57:00 -0800252 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800253 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400254 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400255
Jon Halld4d4b372015-01-28 16:02:41 -0800256 except TypeError:
257 main.log.exception( self.name + ": Object not as expected" )
258 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400259 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800260 main.log.error( self.name + ": EOF exception found" )
261 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400262 main.cleanup()
263 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800264 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800265 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400266 main.cleanup()
267 main.exit()
268
Jon Hallefbd9792015-03-05 16:11:36 -0800269 def log( self, cmdStr, level="" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800270 """
271 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800272 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800273 returns main.FALSE if Error occurred
kelvin-onlab338f5512015-02-06 10:53:16 -0800274 Available level: DEBUG, TRACE, INFO, WARN, ERROR
275 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800276 """
277 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800278 lvlStr = ""
279 if level:
280 lvlStr = "--level=" + level
281
kelvin-onlab9f541032015-02-04 16:19:53 -0800282 self.handle.sendline( "" )
283 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800284 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
kelvin-onlab9f541032015-02-04 16:19:53 -0800285 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800286
kelvin-onlab9f541032015-02-04 16:19:53 -0800287 response = self.handle.before
288 if re.search( "Error", response ):
289 return main.FALSE
290 return main.TRUE
291
292 except pexpect.EOF:
293 main.log.error( self.name + ": EOF exception found" )
294 main.log.error( self.name + ": " + self.handle.before )
295 main.cleanup()
296 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800297 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800298 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400299 main.cleanup()
300 main.exit()
301
Jon Hallc6358dd2015-04-10 12:44:28 -0700302 def sendline( self, cmdStr, debug=False ):
kelvin8ec71442015-01-15 16:57:00 -0800303 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800304 Send a completely user specified string to
305 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400306 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800307
andrewonlaba18f6bf2014-10-13 19:31:54 -0400308 Warning: There are no sanity checking to commands
309 sent using this method.
kelvin8ec71442015-01-15 16:57:00 -0800310 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400311 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800312 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
313 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800314 self.handle.sendline( cmdStr )
Jon Hall63604932015-02-26 17:09:50 -0800315 i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
316 response = self.handle.before
317 if i == 2:
318 self.handle.sendline()
Jon Hallc6358dd2015-04-10 12:44:28 -0700319 self.handle.expect( ["\$", pexpect.TIMEOUT] )
Jon Hall63604932015-02-26 17:09:50 -0800320 response += self.handle.before
321 print response
322 try:
323 print self.handle.after
Jon Hall77ba41c2015-04-06 10:25:40 -0700324 except TypeError:
Jon Hall63604932015-02-26 17:09:50 -0800325 pass
326 # TODO: do something with i
kelvin-onlabd3b64892015-01-20 13:26:24 -0800327 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
kelvin-onlab898a6c62015-01-16 14:13:53 -0800328 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700329 if debug:
330 main.log.debug( "Raw output" )
331 main.log.debug( repr( response ) )
332
333 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800334 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800335 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700336 if debug:
337 main.log.debug( "ansiEscape output" )
338 main.log.debug( repr( response ) )
339
kelvin-onlabfb521662015-02-27 09:52:40 -0800340 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800341 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700342 if debug:
343 main.log.debug( "Removed extra returns from output" )
344 main.log.debug( repr( response ) )
345
346 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800347 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700348 if debug:
349 main.log.debug( "parsed and stripped output" )
350 main.log.debug( repr( response ) )
351
Jon Hall63604932015-02-26 17:09:50 -0800352 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700353 output = response.split( cmdStr.strip(), 1 )
354 if debug:
355 main.log.debug( "split output" )
356 for r in output:
357 main.log.debug( repr( r ) )
358 return output[1].strip()
359 except IndexError:
360 main.log.exception( self.name + ": Object not as expected" )
361 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800362 except TypeError:
363 main.log.exception( self.name + ": Object not as expected" )
364 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400365 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800366 main.log.error( self.name + ": EOF exception found" )
367 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400368 main.cleanup()
369 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800370 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800371 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400372 main.cleanup()
373 main.exit()
374
kelvin8ec71442015-01-15 16:57:00 -0800375 # IMPORTANT NOTE:
376 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800377 # the cli command changing 'a:b' with 'aB'.
378 # Ex ) onos:topology > onosTopology
379 # onos:links > onosLinks
380 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800381
kelvin-onlabd3b64892015-01-20 13:26:24 -0800382 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800383 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400384 Adds a new cluster node by ID and address information.
385 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800386 * nodeId
387 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400388 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800389 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800390 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400391 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800392 cmdStr = "add-node " + str( nodeId ) + " " +\
393 str( ONOSIp ) + " " + str( tcpPort )
394 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800395 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800396 main.log.error( "Error in adding node" )
397 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800398 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400399 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800400 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400401 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800402 except TypeError:
403 main.log.exception( self.name + ": Object not as expected" )
404 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400405 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800406 main.log.error( self.name + ": EOF exception found" )
407 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400408 main.cleanup()
409 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800410 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800411 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400412 main.cleanup()
413 main.exit()
414
kelvin-onlabd3b64892015-01-20 13:26:24 -0800415 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800416 """
andrewonlab86dc3082014-10-13 18:18:38 -0400417 Removes a cluster by ID
418 Issues command: 'remove-node [<node-id>]'
419 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800420 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800421 """
andrewonlab86dc3082014-10-13 18:18:38 -0400422 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400423
kelvin-onlabd3b64892015-01-20 13:26:24 -0800424 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700425 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700426 if re.search( "Error", handle ):
427 main.log.error( "Error in removing node" )
428 main.log.error( handle )
429 return main.FALSE
430 else:
431 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800432 except TypeError:
433 main.log.exception( self.name + ": Object not as expected" )
434 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400435 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800436 main.log.error( self.name + ": EOF exception found" )
437 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400438 main.cleanup()
439 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800440 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800441 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400442 main.cleanup()
443 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400444
Jon Hall61282e32015-03-19 11:34:11 -0700445 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800446 """
andrewonlab7c211572014-10-15 16:45:20 -0400447 List the nodes currently visible
448 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700449 Optional argument:
450 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800451 """
andrewonlab7c211572014-10-15 16:45:20 -0400452 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700453 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700454 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700455 cmdStr += " -j"
456 output = self.sendline( cmdStr )
457 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800458 except TypeError:
459 main.log.exception( self.name + ": Object not as expected" )
460 return None
andrewonlab7c211572014-10-15 16:45:20 -0400461 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800462 main.log.error( self.name + ": EOF exception found" )
463 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400464 main.cleanup()
465 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800466 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800467 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400468 main.cleanup()
469 main.exit()
470
kelvin8ec71442015-01-15 16:57:00 -0800471 def topology( self ):
472 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700473 Definition:
474 Returns the ouput of topology command.
475 Return:
476 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800477 """
andrewonlab95ce8322014-10-13 14:12:04 -0400478 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700479 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800480 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700481 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400482 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800483 except TypeError:
484 main.log.exception( self.name + ": Object not as expected" )
485 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400486 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800487 main.log.error( self.name + ": EOF exception found" )
488 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400489 main.cleanup()
490 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800491 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800492 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400493 main.cleanup()
494 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800495
kelvin-onlabd3b64892015-01-20 13:26:24 -0800496 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800497 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700498 Installs a specified feature by issuing command:
499 'feature:install <feature_str>'
500 NOTE: This is now deprecated, you should use the activateApp method
501 instead
kelvin8ec71442015-01-15 16:57:00 -0800502 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400503 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800504 cmdStr = "feature:install " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700505 handle = self.sendline( cmdStr )
506 if re.search( "Error", handle ):
507 main.log.error( "Error in installing feature" )
508 main.log.error( handle )
509 return main.FALSE
510 else:
511 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800512 except TypeError:
513 main.log.exception( self.name + ": Object not as expected" )
514 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400515 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800516 main.log.error( self.name + ": EOF exception found" )
517 main.log.error( self.name + ": " + self.handle.before )
518 main.log.report( "Failed to install feature" )
519 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400520 main.cleanup()
521 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800522 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800523 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800524 main.log.report( "Failed to install feature" )
525 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400526 main.cleanup()
527 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800528
kelvin-onlabd3b64892015-01-20 13:26:24 -0800529 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800530 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700531 Uninstalls a specified feature by issuing command:
532 'feature:uninstall <feature_str>'
533 NOTE: This is now deprecated, you should use the deactivateApp method
534 instead
kelvin8ec71442015-01-15 16:57:00 -0800535 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400536 try:
Jon Hall30b82fa2015-03-04 17:15:43 -0800537 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
538 handle = self.sendline( cmdStr )
539 if handle != '':
540 cmdStr = "feature:uninstall " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700541 output = self.sendline( cmdStr )
Jon Hall30b82fa2015-03-04 17:15:43 -0800542 # TODO: Check for possible error responses from karaf
543 else:
Jon Hallefbd9792015-03-05 16:11:36 -0800544 main.log.info( "Feature needs to be installed before " +
545 "uninstalling it" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700546 return main.TRUE
547 if re.search( "Error", output ):
548 main.log.error( "Error in uninstalling feature" )
549 main.log.error( output )
550 return main.FALSE
551 else:
552 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800553 except TypeError:
554 main.log.exception( self.name + ": Object not as expected" )
555 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400556 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800557 main.log.error( self.name + ": EOF exception found" )
558 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400559 main.cleanup()
560 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800561 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800562 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400563 main.cleanup()
564 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800565
jenkins7ead5a82015-03-13 10:28:21 -0700566 def deviceRemove( self, deviceId ):
567 """
568 Removes particular device from storage
569
570 TODO: refactor this function
571 """
572 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700573 cmdStr = "device-remove " + str( deviceId )
574 handle = self.sendline( cmdStr )
575 if re.search( "Error", handle ):
576 main.log.error( "Error in removing device" )
577 main.log.error( handle )
578 return main.FALSE
579 else:
580 return main.TRUE
jenkins7ead5a82015-03-13 10:28:21 -0700581 except TypeError:
582 main.log.exception( self.name + ": Object not as expected" )
583 return None
584 except pexpect.EOF:
585 main.log.error( self.name + ": EOF exception found" )
586 main.log.error( self.name + ": " + self.handle.before )
587 main.cleanup()
588 main.exit()
589 except Exception:
590 main.log.exception( self.name + ": Uncaught exception!" )
591 main.cleanup()
592 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700593
kelvin-onlabd3b64892015-01-20 13:26:24 -0800594 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800595 """
Jon Hall7b02d952014-10-17 20:14:54 -0400596 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400597 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800598 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800599 """
andrewonlab86dc3082014-10-13 18:18:38 -0400600 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700601 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800602 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700603 cmdStr += " -j"
604 handle = self.sendline( cmdStr )
605 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800606 except TypeError:
607 main.log.exception( self.name + ": Object not as expected" )
608 return None
andrewonlab7c211572014-10-15 16:45:20 -0400609 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800610 main.log.error( self.name + ": EOF exception found" )
611 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400612 main.cleanup()
613 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800614 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800615 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400616 main.cleanup()
617 main.exit()
618
kelvin-onlabd3b64892015-01-20 13:26:24 -0800619 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800620 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800621 This balances the devices across all controllers
622 by issuing command: 'onos> onos:balance-masters'
623 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800624 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800625 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800626 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700627 handle = self.sendline( cmdStr )
628 if re.search( "Error", handle ):
629 main.log.error( "Error in balancing masters" )
630 main.log.error( handle )
631 return main.FALSE
632 else:
633 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800634 except TypeError:
635 main.log.exception( self.name + ": Object not as expected" )
636 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800637 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800638 main.log.error( self.name + ": EOF exception found" )
639 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800640 main.cleanup()
641 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800642 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800643 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800644 main.cleanup()
645 main.exit()
646
kelvin-onlabd3b64892015-01-20 13:26:24 -0800647 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800648 """
Jon Halle8217482014-10-17 13:49:14 -0400649 Lists all core links
650 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800651 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800652 """
Jon Halle8217482014-10-17 13:49:14 -0400653 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700654 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800655 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700656 cmdStr += " -j"
657 handle = self.sendline( cmdStr )
658 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800659 except TypeError:
660 main.log.exception( self.name + ": Object not as expected" )
661 return None
Jon Halle8217482014-10-17 13:49:14 -0400662 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800663 main.log.error( self.name + ": EOF exception found" )
664 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400665 main.cleanup()
666 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800667 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800668 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400669 main.cleanup()
670 main.exit()
671
kelvin-onlabd3b64892015-01-20 13:26:24 -0800672 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800673 """
Jon Halle8217482014-10-17 13:49:14 -0400674 Lists all ports
675 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800676 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800677 """
Jon Halle8217482014-10-17 13:49:14 -0400678 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700679 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800680 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700681 cmdStr += " -j"
682 handle = self.sendline( cmdStr )
683 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800684 except TypeError:
685 main.log.exception( self.name + ": Object not as expected" )
686 return None
Jon Halle8217482014-10-17 13:49:14 -0400687 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800688 main.log.error( self.name + ": EOF exception found" )
689 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400690 main.cleanup()
691 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800692 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800693 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400694 main.cleanup()
695 main.exit()
696
kelvin-onlabd3b64892015-01-20 13:26:24 -0800697 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800698 """
Jon Hall983a1702014-10-28 18:44:22 -0400699 Lists all devices and the controllers with roles assigned to them
700 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800701 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800702 """
andrewonlab7c211572014-10-15 16:45:20 -0400703 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700704 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800705 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700706 cmdStr += " -j"
707 handle = self.sendline( cmdStr )
708 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800709 except TypeError:
710 main.log.exception( self.name + ": Object not as expected" )
711 return None
Jon Hall983a1702014-10-28 18:44:22 -0400712 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800713 main.log.error( self.name + ": EOF exception found" )
714 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400715 main.cleanup()
716 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800717 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800718 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400719 main.cleanup()
720 main.exit()
721
kelvin-onlabd3b64892015-01-20 13:26:24 -0800722 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800723 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800724 Given the a string containing the json representation of the "roles"
725 cli command and a partial or whole device id, returns a json object
726 containing the roles output for the first device whose id contains
727 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400728
729 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800730 A dict of the role assignments for the given device or
731 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800732 """
Jon Hall983a1702014-10-28 18:44:22 -0400733 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800734 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400735 return None
736 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800737 rawRoles = self.roles()
738 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800739 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800740 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800741 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800742 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400743 return device
744 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800745 except TypeError:
746 main.log.exception( self.name + ": Object not as expected" )
747 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400748 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800749 main.log.error( self.name + ": EOF exception found" )
750 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400751 main.cleanup()
752 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800753 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800754 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400755 main.cleanup()
756 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800757
kelvin-onlabd3b64892015-01-20 13:26:24 -0800758 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800759 """
Jon Hall94fd0472014-12-08 11:52:42 -0800760 Iterates through each device and checks if there is a master assigned
761 Returns: main.TRUE if each device has a master
762 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800763 """
Jon Hall94fd0472014-12-08 11:52:42 -0800764 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800765 rawRoles = self.roles()
766 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800767 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800768 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800769 # print device
770 if device[ 'master' ] == "none":
771 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800772 return main.FALSE
773 return main.TRUE
774
Jon Halld4d4b372015-01-28 16:02:41 -0800775 except TypeError:
776 main.log.exception( self.name + ": Object not as expected" )
777 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800778 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800779 main.log.error( self.name + ": EOF exception found" )
780 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800781 main.cleanup()
782 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800783 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800784 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800785 main.cleanup()
786 main.exit()
787
kelvin-onlabd3b64892015-01-20 13:26:24 -0800788 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800789 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400790 Returns string of paths, and the cost.
791 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800792 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400793 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800794 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
795 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800796 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800797 main.log.error( "Error in getting paths" )
798 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400799 else:
kelvin8ec71442015-01-15 16:57:00 -0800800 path = handle.split( ";" )[ 0 ]
801 cost = handle.split( ";" )[ 1 ]
802 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800803 except TypeError:
804 main.log.exception( self.name + ": Object not as expected" )
805 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400806 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800807 main.log.error( self.name + ": EOF exception found" )
808 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400809 main.cleanup()
810 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800811 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800812 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400813 main.cleanup()
814 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800815
kelvin-onlabd3b64892015-01-20 13:26:24 -0800816 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800817 """
Jon Hallffb386d2014-11-21 13:43:38 -0800818 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400819 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800820 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800821 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400822 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700823 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800824 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700825 cmdStr += " -j"
826 handle = self.sendline( cmdStr )
827 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800828 except TypeError:
829 main.log.exception( self.name + ": Object not as expected" )
830 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400831 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800832 main.log.error( self.name + ": EOF exception found" )
833 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400834 main.cleanup()
835 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800836 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800837 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400838 main.cleanup()
839 main.exit()
840
kelvin-onlabd3b64892015-01-20 13:26:24 -0800841 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800842 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400843 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800844
Jon Hallefbd9792015-03-05 16:11:36 -0800845 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800846 partial mac address
847
Jon Hall42db6dc2014-10-24 19:03:48 -0400848 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800849 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400850 try:
kelvin8ec71442015-01-15 16:57:00 -0800851 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400852 return None
853 else:
854 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800855 rawHosts = self.hosts()
856 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800857 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800858 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800859 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800860 if not host:
861 pass
862 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400863 return host
864 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800865 except TypeError:
866 main.log.exception( self.name + ": Object not as expected" )
867 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400868 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800869 main.log.error( self.name + ": EOF exception found" )
870 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400871 main.cleanup()
872 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800873 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800874 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400875 main.cleanup()
876 main.exit()
877
kelvin-onlabd3b64892015-01-20 13:26:24 -0800878 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800879 """
880 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400881 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800882
andrewonlab3f0a4af2014-10-17 12:25:14 -0400883 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800884 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400885 IMPORTANT:
886 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800887 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400888 Furthermore, it assumes that value of VLAN is '-1'
889 Description:
kelvin8ec71442015-01-15 16:57:00 -0800890 Converts mininet hosts ( h1, h2, h3... ) into
891 ONOS format ( 00:00:00:00:00:01/-1 , ... )
892 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400893 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800894 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400895
kelvin-onlabd3b64892015-01-20 13:26:24 -0800896 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800897 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800898 hostHex = hex( int( host ) ).zfill( 12 )
899 hostHex = str( hostHex ).replace( 'x', '0' )
900 i = iter( str( hostHex ) )
901 hostHex = ":".join( a + b for a, b in zip( i, i ) )
902 hostHex = hostHex + "/-1"
903 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400904
kelvin-onlabd3b64892015-01-20 13:26:24 -0800905 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400906
Jon Halld4d4b372015-01-28 16:02:41 -0800907 except TypeError:
908 main.log.exception( self.name + ": Object not as expected" )
909 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400910 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800911 main.log.error( self.name + ": EOF exception found" )
912 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400913 main.cleanup()
914 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800915 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800916 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400917 main.cleanup()
918 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400919
kelvin-onlabd3b64892015-01-20 13:26:24 -0800920 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800921 """
andrewonlabe6745342014-10-17 14:29:13 -0400922 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800923 * hostIdOne: ONOS host id for host1
924 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400925 Description:
Jon Hallefbd9792015-03-05 16:11:36 -0800926 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500927 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -0800928 Returns:
929 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -0800930 """
andrewonlabe6745342014-10-17 14:29:13 -0400931 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800932 cmdStr = "add-host-intent " + str( hostIdOne ) +\
933 " " + str( hostIdTwo )
934 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800935 if re.search( "Error", handle ):
936 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -0700937 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800938 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -0800939 else:
940 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -0800941 str( hostIdOne ) + " and " + str( hostIdTwo ) )
942 match = re.search('id=0x([\da-f]+),', handle)
943 if match:
944 return match.group()[3:-1]
945 else:
946 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -0700947 main.log.debug( "Response from ONOS was: " +
948 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800949 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800950 except TypeError:
951 main.log.exception( self.name + ": Object not as expected" )
952 return None
andrewonlabe6745342014-10-17 14:29:13 -0400953 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800954 main.log.error( self.name + ": EOF exception found" )
955 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -0400956 main.cleanup()
957 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800958 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800959 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -0400960 main.cleanup()
961 main.exit()
962
kelvin-onlabd3b64892015-01-20 13:26:24 -0800963 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -0800964 """
andrewonlab7b31d232014-10-24 13:31:47 -0400965 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800966 * ingressDevice: device id of ingress device
967 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -0400968 Optional:
969 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -0800970 Description:
971 Adds an optical intent by specifying an ingress and egress device
972 Returns:
973 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -0800974 """
andrewonlab7b31d232014-10-24 13:31:47 -0400975 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800976 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
977 " " + str( egressDevice )
978 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800979 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -0800980 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -0800981 main.log.error( "Error in adding Optical intent" )
982 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400983 else:
kelvin-onlabfb521662015-02-27 09:52:40 -0800984 main.log.info( "Optical intent installed between " +
985 str( ingressDevice ) + " and " +
986 str( egressDevice ) )
987 match = re.search('id=0x([\da-f]+),', handle)
988 if match:
989 return match.group()[3:-1]
990 else:
991 main.log.error( "Error, intent ID not found" )
992 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800993 except TypeError:
994 main.log.exception( self.name + ": Object not as expected" )
995 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400996 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 )
andrewonlab7b31d232014-10-24 13:31:47 -0400999 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!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001003 main.cleanup()
1004 main.exit()
1005
kelvin-onlabd3b64892015-01-20 13:26:24 -08001006 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001007 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001008 ingressDevice,
1009 egressDevice,
1010 portIngress="",
1011 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001012 ethType="",
1013 ethSrc="",
1014 ethDst="",
1015 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001016 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001017 ipProto="",
1018 ipSrc="",
1019 ipDst="",
1020 tcpSrc="",
1021 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001022 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001023 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001024 * ingressDevice: device id of ingress device
1025 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001026 Optional:
1027 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001028 * ethSrc: specify ethSrc ( i.e. src mac addr )
1029 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001030 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001031 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001032 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001033 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001034 * ipSrc: specify ip source address
1035 * ipDst: specify ip destination address
1036 * tcpSrc: specify tcp source port
1037 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001038 Description:
kelvin8ec71442015-01-15 16:57:00 -08001039 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001040 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001041 Returns:
1042 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001043
Jon Halle3f39ff2015-01-13 11:50:53 -08001044 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001045 options developers provide for point-to-point
1046 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001047 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001048 try:
kelvin8ec71442015-01-15 16:57:00 -08001049 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001050 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001051 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001052 and not ipProto and not ipSrc and not ipDst \
1053 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001054 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001055
andrewonlab289e4b72014-10-21 21:24:18 -04001056 else:
andrewonlab36af3822014-11-18 17:48:18 -05001057 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001058
andrewonlab0c0a6772014-10-22 12:31:18 -04001059 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001060 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001061 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001062 cmd += " --ethSrc " + str( ethSrc )
1063 if ethDst:
1064 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001065 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001066 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001067 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001068 cmd += " --lambda "
1069 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001070 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001071 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001072 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001073 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001074 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001075 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001076 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001077 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001078 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001079
kelvin8ec71442015-01-15 16:57:00 -08001080 # Check whether the user appended the port
1081 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001082 if "/" in ingressDevice:
1083 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001084 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001086 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001087 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001088 # Would it make sense to throw an exception and exit
1089 # the test?
1090 return None
andrewonlab36af3822014-11-18 17:48:18 -05001091
kelvin8ec71442015-01-15 16:57:00 -08001092 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001093 str( ingressDevice ) + "/" +\
1094 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001095
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 if "/" in egressDevice:
1097 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001098 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001099 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001100 main.log.error( "You must specify the egress port" )
1101 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001102
kelvin8ec71442015-01-15 16:57:00 -08001103 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001104 str( egressDevice ) + "/" +\
1105 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001106
kelvin-onlab898a6c62015-01-16 14:13:53 -08001107 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001108 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001109 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001110 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001111 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001112 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001113 # TODO: print out all the options in this message?
1114 main.log.info( "Point-to-point intent installed between " +
1115 str( ingressDevice ) + " and " +
1116 str( egressDevice ) )
1117 match = re.search('id=0x([\da-f]+),', handle)
1118 if match:
1119 return match.group()[3:-1]
1120 else:
1121 main.log.error( "Error, intent ID not found" )
1122 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001123 except TypeError:
1124 main.log.exception( self.name + ": Object not as expected" )
1125 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001126 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001127 main.log.error( self.name + ": EOF exception found" )
1128 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001129 main.cleanup()
1130 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001131 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001132 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001133 main.cleanup()
1134 main.exit()
1135
kelvin-onlabd3b64892015-01-20 13:26:24 -08001136 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001137 self,
shahshreyac2f97072015-03-19 17:04:29 -07001138 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001139 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001140 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001141 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001142 ethType="",
1143 ethSrc="",
1144 ethDst="",
1145 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001146 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001147 ipProto="",
1148 ipSrc="",
1149 ipDst="",
1150 tcpSrc="",
1151 tcpDst="",
1152 setEthSrc="",
1153 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001154 """
shahshreyad0c80432014-12-04 16:56:05 -08001155 Note:
shahshreya70622b12015-03-19 17:19:00 -07001156 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001157 is same. That is, all ingress devices include port numbers
1158 with a "/" or all ingress devices could specify device
1159 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001160 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001161 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001162 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001163 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001164 Optional:
1165 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001166 * ethSrc: specify ethSrc ( i.e. src mac addr )
1167 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001168 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001169 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001170 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001171 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001172 * ipSrc: specify ip source address
1173 * ipDst: specify ip destination address
1174 * tcpSrc: specify tcp source port
1175 * tcpDst: specify tcp destination port
1176 * setEthSrc: action to Rewrite Source MAC Address
1177 * setEthDst: action to Rewrite Destination MAC Address
1178 Description:
kelvin8ec71442015-01-15 16:57:00 -08001179 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001180 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001181 Returns:
1182 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001183
Jon Halle3f39ff2015-01-13 11:50:53 -08001184 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001185 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001186 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001187 """
shahshreyad0c80432014-12-04 16:56:05 -08001188 try:
kelvin8ec71442015-01-15 16:57:00 -08001189 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001190 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001191 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001192 and not ipProto and not ipSrc and not ipDst\
1193 and not tcpSrc and not tcpDst and not setEthSrc\
1194 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001195 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001196
1197 else:
1198 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001199
shahshreyad0c80432014-12-04 16:56:05 -08001200 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001201 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001202 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001203 cmd += " --ethSrc " + str( ethSrc )
1204 if ethDst:
1205 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001206 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001207 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001208 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001209 cmd += " --lambda "
1210 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001211 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001212 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001213 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001214 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001215 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001216 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001217 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001218 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001219 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001220 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001221 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001222 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001223 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001224
kelvin8ec71442015-01-15 16:57:00 -08001225 # Check whether the user appended the port
1226 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001227
1228 if portIngressList is None:
1229 for ingressDevice in ingressDeviceList:
1230 if "/" in ingressDevice:
1231 cmd += " " + str( ingressDevice )
1232 else:
1233 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001234 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001235 # TODO: perhaps more meaningful return
1236 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001237 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001238 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001239 for ingressDevice, portIngress in zip( ingressDeviceList,
1240 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001241 cmd += " " + \
1242 str( ingressDevice ) + "/" +\
1243 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001244 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001245 main.log.error( "Device list and port list does not " +
1246 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001247 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001248 if "/" in egressDevice:
1249 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001250 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001251 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001252 main.log.error( "You must specify " +
1253 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001254 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001255
kelvin8ec71442015-01-15 16:57:00 -08001256 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001257 str( egressDevice ) + "/" +\
1258 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001259 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001260 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001261 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001262 main.log.error( "Error in adding multipoint-to-singlepoint " +
1263 "intent" )
1264 return None
shahshreyad0c80432014-12-04 16:56:05 -08001265 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001266 match = re.search('id=0x([\da-f]+),', handle)
1267 if match:
1268 return match.group()[3:-1]
1269 else:
1270 main.log.error( "Error, intent ID not found" )
1271 return None
1272 except TypeError:
1273 main.log.exception( self.name + ": Object not as expected" )
1274 return None
1275 except pexpect.EOF:
1276 main.log.error( self.name + ": EOF exception found" )
1277 main.log.error( self.name + ": " + self.handle.before )
1278 main.cleanup()
1279 main.exit()
1280 except Exception:
1281 main.log.exception( self.name + ": Uncaught exception!" )
1282 main.cleanup()
1283 main.exit()
1284
1285 def addSinglepointToMultipointIntent(
1286 self,
1287 ingressDevice,
1288 egressDeviceList,
1289 portIngress="",
1290 portEgressList=None,
1291 ethType="",
1292 ethSrc="",
1293 ethDst="",
1294 bandwidth="",
1295 lambdaAlloc=False,
1296 ipProto="",
1297 ipSrc="",
1298 ipDst="",
1299 tcpSrc="",
1300 tcpDst="",
1301 setEthSrc="",
1302 setEthDst="" ):
1303 """
1304 Note:
1305 This function assumes the format of all egress devices
1306 is same. That is, all egress devices include port numbers
1307 with a "/" or all egress devices could specify device
1308 ids and port numbers seperately.
1309 Required:
1310 * EgressDeviceList: List of device ids of egress device
1311 ( Atleast 2 eress devices required in the list )
1312 * ingressDevice: device id of ingress device
1313 Optional:
1314 * ethType: specify ethType
1315 * ethSrc: specify ethSrc ( i.e. src mac addr )
1316 * ethDst: specify ethDst ( i.e. dst mac addr )
1317 * bandwidth: specify bandwidth capacity of link
1318 * lambdaAlloc: if True, intent will allocate lambda
1319 for the specified intent
1320 * ipProto: specify ip protocol
1321 * ipSrc: specify ip source address
1322 * ipDst: specify ip destination address
1323 * tcpSrc: specify tcp source port
1324 * tcpDst: specify tcp destination port
1325 * setEthSrc: action to Rewrite Source MAC Address
1326 * setEthDst: action to Rewrite Destination MAC Address
1327 Description:
1328 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1329 specifying device id's and optional fields
1330 Returns:
1331 A string of the intent id or None on error
1332
1333 NOTE: This function may change depending on the
1334 options developers provide for singlepoint-to-multipoint
1335 intent via cli
1336 """
1337 try:
1338 # If there are no optional arguments
1339 if not ethType and not ethSrc and not ethDst\
1340 and not bandwidth and not lambdaAlloc\
1341 and not ipProto and not ipSrc and not ipDst\
1342 and not tcpSrc and not tcpDst and not setEthSrc\
1343 and not setEthDst:
1344 cmd = "add-single-to-multi-intent"
1345
1346 else:
1347 cmd = "add-single-to-multi-intent"
1348
1349 if ethType:
1350 cmd += " --ethType " + str( ethType )
1351 if ethSrc:
1352 cmd += " --ethSrc " + str( ethSrc )
1353 if ethDst:
1354 cmd += " --ethDst " + str( ethDst )
1355 if bandwidth:
1356 cmd += " --bandwidth " + str( bandwidth )
1357 if lambdaAlloc:
1358 cmd += " --lambda "
1359 if ipProto:
1360 cmd += " --ipProto " + str( ipProto )
1361 if ipSrc:
1362 cmd += " --ipSrc " + str( ipSrc )
1363 if ipDst:
1364 cmd += " --ipDst " + str( ipDst )
1365 if tcpSrc:
1366 cmd += " --tcpSrc " + str( tcpSrc )
1367 if tcpDst:
1368 cmd += " --tcpDst " + str( tcpDst )
1369 if setEthSrc:
1370 cmd += " --setEthSrc " + str( setEthSrc )
1371 if setEthDst:
1372 cmd += " --setEthDst " + str( setEthDst )
1373
1374 # Check whether the user appended the port
1375 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001376
kelvin-onlabb9408212015-04-01 13:34:04 -07001377 if "/" in ingressDevice:
1378 cmd += " " + str( ingressDevice )
1379 else:
1380 if not portIngress:
1381 main.log.error( "You must specify " +
1382 "the Ingress port" )
1383 return main.FALSE
1384
1385 cmd += " " +\
1386 str( ingressDevice ) + "/" +\
1387 str( portIngress )
1388
1389 if portEgressList is None:
1390 for egressDevice in egressDeviceList:
1391 if "/" in egressDevice:
1392 cmd += " " + str( egressDevice )
1393 else:
1394 main.log.error( "You must specify " +
1395 "the egress port" )
1396 # TODO: perhaps more meaningful return
1397 return main.FALSE
1398 else:
1399 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001400 for egressDevice, portEgress in zip( egressDeviceList,
1401 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001402 cmd += " " + \
1403 str( egressDevice ) + "/" +\
1404 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001405 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001406 main.log.error( "Device list and port list does not " +
1407 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001408 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001409 handle = self.sendline( cmd )
1410 # If error, return error message
1411 if re.search( "Error", handle ):
1412 main.log.error( "Error in adding singlepoint-to-multipoint " +
1413 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001414 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001415 else:
1416 match = re.search('id=0x([\da-f]+),', handle)
1417 if match:
1418 return match.group()[3:-1]
1419 else:
1420 main.log.error( "Error, intent ID not found" )
1421 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001422 except TypeError:
1423 main.log.exception( self.name + ": Object not as expected" )
1424 return None
shahshreyad0c80432014-12-04 16:56:05 -08001425 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001426 main.log.error( self.name + ": EOF exception found" )
1427 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001428 main.cleanup()
1429 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001430 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001431 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001432 main.cleanup()
1433 main.exit()
1434
Hari Krishna9e232602015-04-13 17:29:08 -07001435 def addMplsIntent(
1436 self,
1437 ingressDevice,
1438 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001439 ingressPort="",
1440 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001441 ethType="",
1442 ethSrc="",
1443 ethDst="",
1444 bandwidth="",
1445 lambdaAlloc=False,
1446 ipProto="",
1447 ipSrc="",
1448 ipDst="",
1449 tcpSrc="",
1450 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001451 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001452 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001453 priority=""):
1454 """
1455 Required:
1456 * ingressDevice: device id of ingress device
1457 * egressDevice: device id of egress device
1458 Optional:
1459 * ethType: specify ethType
1460 * ethSrc: specify ethSrc ( i.e. src mac addr )
1461 * ethDst: specify ethDst ( i.e. dst mac addr )
1462 * bandwidth: specify bandwidth capacity of link
1463 * lambdaAlloc: if True, intent will allocate lambda
1464 for the specified intent
1465 * ipProto: specify ip protocol
1466 * ipSrc: specify ip source address
1467 * ipDst: specify ip destination address
1468 * tcpSrc: specify tcp source port
1469 * tcpDst: specify tcp destination port
1470 * ingressLabel: Ingress MPLS label
1471 * egressLabel: Egress MPLS label
1472 Description:
1473 Adds MPLS intent by
1474 specifying device id's and optional fields
1475 Returns:
1476 A string of the intent id or None on error
1477
1478 NOTE: This function may change depending on the
1479 options developers provide for MPLS
1480 intent via cli
1481 """
1482 try:
1483 # If there are no optional arguments
1484 if not ethType and not ethSrc and not ethDst\
1485 and not bandwidth and not lambdaAlloc \
1486 and not ipProto and not ipSrc and not ipDst \
1487 and not tcpSrc and not tcpDst and not ingressLabel \
1488 and not egressLabel:
1489 cmd = "add-mpls-intent"
1490
1491 else:
1492 cmd = "add-mpls-intent"
1493
1494 if ethType:
1495 cmd += " --ethType " + str( ethType )
1496 if ethSrc:
1497 cmd += " --ethSrc " + str( ethSrc )
1498 if ethDst:
1499 cmd += " --ethDst " + str( ethDst )
1500 if bandwidth:
1501 cmd += " --bandwidth " + str( bandwidth )
1502 if lambdaAlloc:
1503 cmd += " --lambda "
1504 if ipProto:
1505 cmd += " --ipProto " + str( ipProto )
1506 if ipSrc:
1507 cmd += " --ipSrc " + str( ipSrc )
1508 if ipDst:
1509 cmd += " --ipDst " + str( ipDst )
1510 if tcpSrc:
1511 cmd += " --tcpSrc " + str( tcpSrc )
1512 if tcpDst:
1513 cmd += " --tcpDst " + str( tcpDst )
1514 if ingressLabel:
1515 cmd += " --ingressLabel " + str( ingressLabel )
1516 if egressLabel:
1517 cmd += " --egressLabel " + str( egressLabel )
1518 if priority:
1519 cmd += " --priority " + str( priority )
1520
1521 # Check whether the user appended the port
1522 # or provided it as an input
1523 if "/" in ingressDevice:
1524 cmd += " " + str( ingressDevice )
1525 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001526 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001527 main.log.error( "You must specify the ingress port" )
1528 return None
1529
1530 cmd += " " + \
1531 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001532 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001533
1534 if "/" in egressDevice:
1535 cmd += " " + str( egressDevice )
1536 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001537 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001538 main.log.error( "You must specify the egress port" )
1539 return None
1540
1541 cmd += " " +\
1542 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001543 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001544
1545 handle = self.sendline( cmd )
1546 # If error, return error message
1547 if re.search( "Error", handle ):
1548 main.log.error( "Error in adding mpls intent" )
1549 return None
1550 else:
1551 # TODO: print out all the options in this message?
1552 main.log.info( "MPLS intent installed between " +
1553 str( ingressDevice ) + " and " +
1554 str( egressDevice ) )
1555 match = re.search('id=0x([\da-f]+),', handle)
1556 if match:
1557 return match.group()[3:-1]
1558 else:
1559 main.log.error( "Error, intent ID not found" )
1560 return None
1561 except TypeError:
1562 main.log.exception( self.name + ": Object not as expected" )
1563 return None
1564 except pexpect.EOF:
1565 main.log.error( self.name + ": EOF exception found" )
1566 main.log.error( self.name + ": " + self.handle.before )
1567 main.cleanup()
1568 main.exit()
1569 except Exception:
1570 main.log.exception( self.name + ": Uncaught exception!" )
1571 main.cleanup()
1572 main.exit()
1573
Jon Hallefbd9792015-03-05 16:11:36 -08001574 def removeIntent( self, intentId, app='org.onosproject.cli',
1575 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001576 """
shahshreya1c818fc2015-02-26 13:44:08 -08001577 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001578 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001579 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001580 -p or --purge: Purge the intent from the store after removal
1581
Jon Halle3f39ff2015-01-13 11:50:53 -08001582 Returns:
1583 main.False on error and
1584 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001585 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001586 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001587 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001588 if purge:
1589 cmdStr += " -p"
1590 if sync:
1591 cmdStr += " -s"
1592
1593 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001594 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001595 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001596 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001597 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001598 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001599 # TODO: Should this be main.TRUE
1600 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001601 except TypeError:
1602 main.log.exception( self.name + ": Object not as expected" )
1603 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001604 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001605 main.log.error( self.name + ": EOF exception found" )
1606 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001607 main.cleanup()
1608 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001609 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001610 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001611 main.cleanup()
1612 main.exit()
1613
kelvin-onlabd3b64892015-01-20 13:26:24 -08001614 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001615 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001616 NOTE: This method should be used after installing application:
1617 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001618 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001619 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001620 Description:
1621 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001622 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001623 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001624 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001625 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001626 cmdStr += " -j"
1627 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001628 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001629 except TypeError:
1630 main.log.exception( self.name + ": Object not as expected" )
1631 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001632 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001633 main.log.error( self.name + ": EOF exception found" )
1634 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001635 main.cleanup()
1636 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001637 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001638 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001639 main.cleanup()
1640 main.exit()
1641
kelvin-onlabd3b64892015-01-20 13:26:24 -08001642 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001643 """
andrewonlab377693f2014-10-21 16:00:30 -04001644 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001645 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001646 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001647 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001648 """
andrewonlabe6745342014-10-17 14:29:13 -04001649 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001650 cmdStr = "intents"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001651 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001652 cmdStr += " -j"
1653 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001654 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001655 except TypeError:
1656 main.log.exception( self.name + ": Object not as expected" )
1657 return None
andrewonlabe6745342014-10-17 14:29:13 -04001658 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001659 main.log.error( self.name + ": EOF exception found" )
1660 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001661 main.cleanup()
1662 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001663 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001664 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001665 main.cleanup()
1666 main.exit()
1667
kelvin-onlab54400a92015-02-26 18:05:51 -08001668 def getIntentState(self, intentsId, intentsJson=None):
1669 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001670 Check intent state.
1671 Accepts a single intent ID (string type) or a list of intent IDs.
1672 Returns the state(string type) of the id if a single intent ID is
1673 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001674 Returns a dictionary with intent IDs as the key and its
1675 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001676 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001677 intentId: intent ID (string type)
1678 intentsJson: parsed json object from the onos:intents api
1679 Returns:
1680 state = An intent's state- INSTALL,WITHDRAWN etc.
1681 stateDict = Dictionary of intent's state. intent ID as the keys and
1682 state as the values.
1683 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001684 try:
1685 state = "State is Undefined"
1686 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001687 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001688 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001689 intentsJsonTemp = json.loads( intentsJson )
1690 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001691 for intent in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001692 if intentsId == intent[ 'id' ]:
1693 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001694 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001695 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1696 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001697 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001698 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001699 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001700 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001701 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001702 for intents in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001703 if intentsId[ i ] == intents[ 'id' ]:
1704 stateDict[ 'state' ] = intents[ 'state' ]
1705 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001706 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001707 break
Jon Hallefbd9792015-03-05 16:11:36 -08001708 if len( intentsId ) != len( dictList ):
1709 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001710 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001711 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001712 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001713 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001714 except TypeError:
1715 main.log.exception( self.name + ": Object not as expected" )
1716 return None
1717 except pexpect.EOF:
1718 main.log.error( self.name + ": EOF exception found" )
1719 main.log.error( self.name + ": " + self.handle.before )
1720 main.cleanup()
1721 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001722 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001723 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001724 main.cleanup()
1725 main.exit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001726
1727 def checkIntentState( self, intentsId, expectedState = 'INSTALLED' ):
1728 """
1729 Description:
1730 Check intents state
1731 Required:
1732 intentsId - List of intents ID to be checked
1733 Optional:
1734 expectedState - Check this expected state of each intents state
1735 in the list. Defaults to INSTALLED
1736 Return:
1737 Returns main.TRUE only if all intent are the same as expectedState,
1738 , otherwise,returns main.FALSE.
1739 """
1740 try:
1741 # Generating a dictionary: intent id as a key and state as value
1742 intentsDict = self.getIntentState( intentsId )
1743 print "len of intentsDict ", str( len( intentsDict ) )
1744 if len( intentsId ) != len( intentsDict ):
1745 main.log.info( self.name + "There is something wrong " +
1746 "getting intents state" )
1747 return main.FALSE
1748 returnValue = main.TRUE
1749 for intents in intentsDict:
1750 if intents.get( 'state' ) != expectedState:
1751 main.log.info( self.name + " : " + intents.get( 'id' ) +
1752 " actual state = " + intents.get( 'state' )
1753 + " does not equal expected state = "
1754 + expectedState )
1755 returnValue = main.FALSE
1756 if returnValue == main.TRUE:
1757 main.log.info( self.name + ": All " +
1758 str( len( intentsDict ) ) +
1759 " intents are in " + expectedState + " state")
1760 return returnValue
1761 except TypeError:
1762 main.log.exception( self.name + ": Object not as expected" )
1763 return None
1764 except pexpect.EOF:
1765 main.log.error( self.name + ": EOF exception found" )
1766 main.log.error( self.name + ": " + self.handle.before )
1767 main.cleanup()
1768 main.exit()
1769 except Exception:
1770 main.log.exception( self.name + ": Uncaught exception!" )
1771 main.cleanup()
1772 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001773
kelvin-onlabd3b64892015-01-20 13:26:24 -08001774 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001775 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001776 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001777 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001778 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001779 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001780 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001781 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001782 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001783 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001784 cmdStr += " -j"
1785 handle = self.sendline( cmdStr )
Jon Hall61282e32015-03-19 11:34:11 -07001786 if re.search( "Error:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001787 main.log.error( self.name + ".flows() response: " +
1788 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001789 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001790 except TypeError:
1791 main.log.exception( self.name + ": Object not as expected" )
1792 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001793 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001794 main.log.error( self.name + ": EOF exception found" )
1795 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001796 main.cleanup()
1797 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001798 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001799 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001800 main.cleanup()
1801 main.exit()
1802
kelvin-onlab4df89f22015-04-13 18:10:23 -07001803 def checkFlowsState( self ):
1804 """
1805 Description:
1806 Check the if all the current flows are in ADDED state or
1807 PENDING_ADD state
1808 Return:
1809 returnValue - Returns main.TRUE only if all flows are in
1810 ADDED state or PENDING_ADD, return main.FALSE
1811 otherwise.
1812 """
1813 try:
1814 tempFlows = json.loads( self.flows() )
1815 returnValue = main.TRUE
1816 for device in tempFlows:
1817 for flow in device.get( 'flows' ):
1818 if flow.get( 'state' ) != 'ADDED' and flow.get( 'state' ) != \
1819 'PENDING_ADD':
1820 main.log.info( self.name + ": flow Id: " +
1821 flow.get( 'flowId' ) +
1822 " | state:" + flow.get( 'state' ) )
1823 returnValue = main.FALSE
1824 return returnValue
1825 except TypeError:
1826 main.log.exception( self.name + ": Object not as expected" )
1827 return None
1828 except pexpect.EOF:
1829 main.log.error( self.name + ": EOF exception found" )
1830 main.log.error( self.name + ": " + self.handle.before )
1831 main.cleanup()
1832 main.exit()
1833 except Exception:
1834 main.log.exception( self.name + ": Uncaught exception!" )
1835 main.cleanup()
1836 main.exit()
1837
kelvin-onlabd3b64892015-01-20 13:26:24 -08001838 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08001839 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001840 """
andrewonlab87852b02014-11-19 18:44:19 -05001841 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001842 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001843 a specific point-to-point intent definition
1844 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001845 * dpidSrc: specify source dpid
1846 * dpidDst: specify destination dpid
1847 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001848 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001849 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001850 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001851 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001852 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001853 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001854 """
andrewonlab87852b02014-11-19 18:44:19 -05001855 try:
kelvin8ec71442015-01-15 16:57:00 -08001856 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001857 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1858 str( numIntents )
1859 if numMult:
1860 cmd += " " + str( numMult )
1861 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001862 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001863 if appId:
1864 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001865 handle = self.sendline( cmd )
andrewonlab87852b02014-11-19 18:44:19 -05001866 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001867 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001868 main.log.info( handle )
1869 # Split result by newline
1870 newline = handle.split( "\r\r\n" )
1871 # Ignore the first object of list, which is empty
1872 newline = newline[ 1: ]
1873 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001874 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001875 result = result.split( ": " )
1876 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001877 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1878 main.log.info( latResult )
1879 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001880 else:
1881 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001882 except TypeError:
1883 main.log.exception( self.name + ": Object not as expected" )
1884 return None
andrewonlab87852b02014-11-19 18:44:19 -05001885 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001886 main.log.error( self.name + ": EOF exception found" )
1887 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001888 main.cleanup()
1889 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001890 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001891 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001892 main.cleanup()
1893 main.exit()
1894
kelvin-onlabd3b64892015-01-20 13:26:24 -08001895 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001896 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001897 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001898 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001899 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001900 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001901 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001902 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001903 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001904 cmdStr += " -j"
1905 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001906 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001907 except TypeError:
1908 main.log.exception( self.name + ": Object not as expected" )
1909 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001910 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001911 main.log.error( self.name + ": EOF exception found" )
1912 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001913 main.cleanup()
1914 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001915 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001916 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001917 main.cleanup()
1918 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001919
kelvin-onlabd3b64892015-01-20 13:26:24 -08001920 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001921 """
1922 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001923 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001924 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001925 """
andrewonlab867212a2014-10-22 20:13:38 -04001926 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001927 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001928 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001929 cmdStr += " -j"
1930 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07001931 if handle:
1932 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001933 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07001934 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07001935 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07001936 else:
1937 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001938 except TypeError:
1939 main.log.exception( self.name + ": Object not as expected" )
1940 return None
andrewonlab867212a2014-10-22 20:13:38 -04001941 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001942 main.log.error( self.name + ": EOF exception found" )
1943 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001944 main.cleanup()
1945 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001946 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001947 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001948 main.cleanup()
1949 main.exit()
1950
kelvin8ec71442015-01-15 16:57:00 -08001951 # Wrapper functions ****************
1952 # Wrapper functions use existing driver
1953 # functions and extends their use case.
1954 # For example, we may use the output of
1955 # a normal driver function, and parse it
1956 # using a wrapper function
andrewonlab7e4d2d32014-10-15 13:23:21 -04001957
kelvin-onlabd3b64892015-01-20 13:26:24 -08001958 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001959 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001960 Description:
1961 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001962 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001963 try:
kelvin8ec71442015-01-15 16:57:00 -08001964 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08001965 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08001966 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001967
kelvin8ec71442015-01-15 16:57:00 -08001968 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001969 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1970 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08001971 match = re.search('id=0x([\da-f]+),', intents)
1972 if match:
1973 tmpId = match.group()[3:-1]
1974 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001975 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001976
Jon Halld4d4b372015-01-28 16:02:41 -08001977 except TypeError:
1978 main.log.exception( self.name + ": Object not as expected" )
1979 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001980 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001981 main.log.error( self.name + ": EOF exception found" )
1982 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001983 main.cleanup()
1984 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001985 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001986 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001987 main.cleanup()
1988 main.exit()
1989
Jon Hall30b82fa2015-03-04 17:15:43 -08001990 def FlowAddedCount( self, deviceId ):
1991 """
1992 Determine the number of flow rules for the given device id that are
1993 in the added state
1994 """
1995 try:
1996 cmdStr = "flows any " + str( deviceId ) + " | " +\
1997 "grep 'state=ADDED' | wc -l"
1998 handle = self.sendline( cmdStr )
1999 return handle
2000 except pexpect.EOF:
2001 main.log.error( self.name + ": EOF exception found" )
2002 main.log.error( self.name + ": " + self.handle.before )
2003 main.cleanup()
2004 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002005 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002006 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002007 main.cleanup()
2008 main.exit()
2009
kelvin-onlabd3b64892015-01-20 13:26:24 -08002010 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002011 """
andrewonlab95ce8322014-10-13 14:12:04 -04002012 Use 'devices' function to obtain list of all devices
2013 and parse the result to obtain a list of all device
2014 id's. Returns this list. Returns empty list if no
2015 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002016 List is ordered sequentially
2017
andrewonlab95ce8322014-10-13 14:12:04 -04002018 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002019 device id, and wish to execute other commands using
andrewonlab95ce8322014-10-13 14:12:04 -04002020 the ids. By obtaining the list of device ids on the fly,
2021 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002022 """
andrewonlab95ce8322014-10-13 14:12:04 -04002023 try:
kelvin8ec71442015-01-15 16:57:00 -08002024 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002025 devicesStr = self.devices( jsonFormat=False )
2026 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002027
kelvin-onlabd3b64892015-01-20 13:26:24 -08002028 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002029 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002030 return idList
kelvin8ec71442015-01-15 16:57:00 -08002031
2032 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002033 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002034 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002035 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002036 # Split list further into arguments before and after string
2037 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002038 # append to idList
2039 for arg in tempList:
2040 idList.append( arg.split( "id=" )[ 1 ] )
2041 return idList
andrewonlab95ce8322014-10-13 14:12:04 -04002042
Jon Halld4d4b372015-01-28 16:02:41 -08002043 except TypeError:
2044 main.log.exception( self.name + ": Object not as expected" )
2045 return None
andrewonlab95ce8322014-10-13 14:12:04 -04002046 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002047 main.log.error( self.name + ": EOF exception found" )
2048 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -04002049 main.cleanup()
2050 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002051 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002052 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002053 main.cleanup()
2054 main.exit()
2055
kelvin-onlabd3b64892015-01-20 13:26:24 -08002056 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002057 """
andrewonlab7c211572014-10-15 16:45:20 -04002058 Uses 'nodes' function to obtain list of all nodes
2059 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002060 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002061 Returns:
2062 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002063 """
andrewonlab7c211572014-10-15 16:45:20 -04002064 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002065 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002066 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002067 # Sample nodesStr output
2068 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002069 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002070 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002071 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002072 nodesJson = json.loads( nodesStr )
2073 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002074 return idList
kelvin8ec71442015-01-15 16:57:00 -08002075
Jon Halld4d4b372015-01-28 16:02:41 -08002076 except TypeError:
2077 main.log.exception( self.name + ": Object not as expected" )
2078 return None
andrewonlab7c211572014-10-15 16:45:20 -04002079 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002080 main.log.error( self.name + ": EOF exception found" )
2081 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002082 main.cleanup()
2083 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002084 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002085 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002086 main.cleanup()
2087 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -04002088
kelvin-onlabd3b64892015-01-20 13:26:24 -08002089 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002090 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002091 Return the first device from the devices api whose 'id' contains 'dpid'
2092 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002093 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002094 try:
kelvin8ec71442015-01-15 16:57:00 -08002095 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002096 return None
2097 else:
kelvin8ec71442015-01-15 16:57:00 -08002098 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002099 rawDevices = self.devices()
2100 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002101 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002102 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002103 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2104 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002105 return device
2106 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002107 except TypeError:
2108 main.log.exception( self.name + ": Object not as expected" )
2109 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002110 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002111 main.log.error( self.name + ": EOF exception found" )
2112 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002113 main.cleanup()
2114 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002115 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002116 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002117 main.cleanup()
2118 main.exit()
2119
kelvin-onlabd3b64892015-01-20 13:26:24 -08002120 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002121 """
Jon Hallefbd9792015-03-05 16:11:36 -08002122 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002123 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002124 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002125
Jon Hall42db6dc2014-10-24 19:03:48 -04002126 Params: ip = ip used for the onos cli
2127 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002128 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002129 logLevel = level to log to. Currently accepts
2130 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002131
2132
kelvin-onlabd3b64892015-01-20 13:26:24 -08002133 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002134
Jon Hallefbd9792015-03-05 16:11:36 -08002135 Returns: main.TRUE if the number of switches and links are correct,
2136 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002137 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002138 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002139 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002140 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002141 if topology == {}:
2142 return main.ERROR
2143 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002144 # Is the number of switches is what we expected
2145 devices = topology.get( 'devices', False )
2146 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002147 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002148 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002149 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002150 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002151 linkCheck = ( int( links ) == int( numolink ) )
2152 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002153 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002154 output += "The number of links and switches match " +\
2155 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002156 result = main.TRUE
2157 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002158 output += "The number of links and switches does not match " +\
2159 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002160 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002161 output = output + "\n ONOS sees %i devices (%i expected) \
2162 and %i links (%i expected)" % (
2163 int( devices ), int( numoswitch ), int( links ),
2164 int( numolink ) )
2165 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002166 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002167 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002168 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002169 else:
kelvin8ec71442015-01-15 16:57:00 -08002170 main.log.info( output )
2171 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002172 except TypeError:
2173 main.log.exception( self.name + ": Object not as expected" )
2174 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002175 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002176 main.log.error( self.name + ": EOF exception found" )
2177 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002178 main.cleanup()
2179 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002180 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002181 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002182 main.cleanup()
2183 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002184
kelvin-onlabd3b64892015-01-20 13:26:24 -08002185 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002186 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002187 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002188 deviceId must be the id of a device as seen in the onos devices command
2189 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002190 role must be either master, standby, or none
2191
Jon Halle3f39ff2015-01-13 11:50:53 -08002192 Returns:
2193 main.TRUE or main.FALSE based on argument verification and
2194 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002195 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002196 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002197 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002198 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002199 cmdStr = "device-role " +\
2200 str( deviceId ) + " " +\
2201 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002202 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002203 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002204 if re.search( "Error", handle ):
2205 # end color output to escape any colours
2206 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002207 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002208 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002209 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002210 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002211 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002212 main.log.error( "Invalid 'role' given to device_role(). " +
2213 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002214 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002215 except TypeError:
2216 main.log.exception( self.name + ": Object not as expected" )
2217 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002218 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002219 main.log.error( self.name + ": EOF exception found" )
2220 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002221 main.cleanup()
2222 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002223 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002224 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002225 main.cleanup()
2226 main.exit()
2227
kelvin-onlabd3b64892015-01-20 13:26:24 -08002228 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002229 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002230 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002231 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002232 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002233 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002234 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002235 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002236 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002237 cmdStr += " -j"
2238 handle = self.sendline( cmdStr )
2239 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002240 except TypeError:
2241 main.log.exception( self.name + ": Object not as expected" )
2242 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002243 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002244 main.log.error( self.name + ": EOF exception found" )
2245 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002246 main.cleanup()
2247 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002248 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002249 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002250 main.cleanup()
2251 main.exit()
2252
kelvin-onlabd3b64892015-01-20 13:26:24 -08002253 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002254 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002255 CLI command to get the current leader for the Election test application
2256 NOTE: Requires installation of the onos-app-election feature
2257 Returns: Node IP of the leader if one exists
2258 None if none exists
2259 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002260 """
Jon Hall94fd0472014-12-08 11:52:42 -08002261 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002262 cmdStr = "election-test-leader"
2263 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002264 # Leader
2265 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002266 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002267 nodeSearch = re.search( leaderPattern, response )
2268 if nodeSearch:
2269 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002270 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002271 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002272 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002273 # no leader
2274 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002275 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002276 nullSearch = re.search( nullPattern, response )
2277 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002278 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002279 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002280 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002281 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002282 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002283 if re.search( errorPattern, response ):
2284 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002285 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002286 return main.FALSE
2287 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002288 main.log.error( "Error in election_test_leader: " +
2289 "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002290 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002291 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002292 except TypeError:
2293 main.log.exception( self.name + ": Object not as expected" )
2294 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002295 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002296 main.log.error( self.name + ": EOF exception found" )
2297 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002298 main.cleanup()
2299 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002300 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002301 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002302 main.cleanup()
2303 main.exit()
2304
kelvin-onlabd3b64892015-01-20 13:26:24 -08002305 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002306 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002307 CLI command to run for leadership of the Election test application.
2308 NOTE: Requires installation of the onos-app-election feature
2309 Returns: Main.TRUE on success
2310 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002311 """
Jon Hall94fd0472014-12-08 11:52:42 -08002312 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002313 cmdStr = "election-test-run"
2314 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002315 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002316 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002317 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002318 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002319 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002320 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002321 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002322 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002323 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002324 errorPattern = "Command\snot\sfound"
2325 if re.search( errorPattern, response ):
2326 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002327 return main.FALSE
2328 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002329 main.log.error( "Error in election_test_run: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002330 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002331 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002332 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002333 except TypeError:
2334 main.log.exception( self.name + ": Object not as expected" )
2335 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002336 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002337 main.log.error( self.name + ": EOF exception found" )
2338 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002339 main.cleanup()
2340 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002341 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002342 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002343 main.cleanup()
2344 main.exit()
2345
kelvin-onlabd3b64892015-01-20 13:26:24 -08002346 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002347 """
Jon Hall94fd0472014-12-08 11:52:42 -08002348 * CLI command to withdraw the local node from leadership election for
2349 * the Election test application.
2350 #NOTE: Requires installation of the onos-app-election feature
2351 Returns: Main.TRUE on success
2352 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002353 """
Jon Hall94fd0472014-12-08 11:52:42 -08002354 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002355 cmdStr = "election-test-withdraw"
2356 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002357 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002358 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002359 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002360 if re.search( successPattern, response ):
2361 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002362 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002363 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002364 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002365 errorPattern = "Command\snot\sfound"
2366 if re.search( errorPattern, response ):
2367 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002368 return main.FALSE
2369 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002370 main.log.error( "Error in election_test_withdraw: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002371 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002372 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002373 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002374 except TypeError:
2375 main.log.exception( self.name + ": Object not as expected" )
2376 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002377 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002378 main.log.error( self.name + ": EOF exception found" )
2379 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002380 main.cleanup()
2381 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002382 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002383 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002384 main.cleanup()
2385 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002386
kelvin8ec71442015-01-15 16:57:00 -08002387 def getDevicePortsEnabledCount( self, dpid ):
2388 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002389 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002390 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002391 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002392 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002393 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2394 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002395 if re.search( "No such device", output ):
2396 main.log.error( "Error in getting ports" )
2397 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002398 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002399 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002400 except TypeError:
2401 main.log.exception( self.name + ": Object not as expected" )
2402 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002403 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002404 main.log.error( self.name + ": EOF exception found" )
2405 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002406 main.cleanup()
2407 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002408 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002409 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002410 main.cleanup()
2411 main.exit()
2412
kelvin8ec71442015-01-15 16:57:00 -08002413 def getDeviceLinksActiveCount( self, dpid ):
2414 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002415 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002416 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002417 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002418 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002419 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2420 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002421 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002422 main.log.error( "Error in getting ports " )
2423 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002424 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002425 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002426 except TypeError:
2427 main.log.exception( self.name + ": Object not as expected" )
2428 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002429 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002430 main.log.error( self.name + ": EOF exception found" )
2431 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002432 main.cleanup()
2433 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002434 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002435 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002436 main.cleanup()
2437 main.exit()
2438
kelvin8ec71442015-01-15 16:57:00 -08002439 def getAllIntentIds( self ):
2440 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002441 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002442 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002443 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002444 cmdStr = "onos:intents | grep id="
2445 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002446 if re.search( "Error", output ):
2447 main.log.error( "Error in getting ports" )
2448 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002449 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002450 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002451 except TypeError:
2452 main.log.exception( self.name + ": Object not as expected" )
2453 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002454 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002455 main.log.error( self.name + ": EOF exception found" )
2456 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002457 main.cleanup()
2458 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002459 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002460 main.log.exception( self.name + ": Uncaught exception!" )
2461 main.cleanup()
2462 main.exit()
2463
Jon Hall73509952015-02-24 16:42:56 -08002464 def intentSummary( self ):
2465 """
Jon Hallefbd9792015-03-05 16:11:36 -08002466 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002467 """
2468 try:
2469 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002470 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002471 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002472 states.append( intent.get( 'state', None ) )
2473 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002474 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002475 return dict( out )
2476 except TypeError:
2477 main.log.exception( self.name + ": Object not as expected" )
2478 return None
2479 except pexpect.EOF:
2480 main.log.error( self.name + ": EOF exception found" )
2481 main.log.error( self.name + ": " + self.handle.before )
2482 main.cleanup()
2483 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002484 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002485 main.log.exception( self.name + ": Uncaught exception!" )
2486 main.cleanup()
2487 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002488
Jon Hall61282e32015-03-19 11:34:11 -07002489 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002490 """
2491 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002492 Optional argument:
2493 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002494 """
2495 # FIXME: add json output
Jon Hall61282e32015-03-19 11:34:11 -07002496 # Sample JSON
2497 # {
2498 # "electedTime": "13m ago",
2499 # "epoch": 4,
2500 # "leader": "10.128.30.17",
2501 # "topic": "intent-partition-3"
2502 # },
Jon Hall63604932015-02-26 17:09:50 -08002503 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002504 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002505 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002506 cmdStr += " -j"
2507 output = self.sendline( cmdStr )
2508 return output
Jon Hall63604932015-02-26 17:09:50 -08002509 except TypeError:
2510 main.log.exception( self.name + ": Object not as expected" )
2511 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002512 except pexpect.EOF:
2513 main.log.error( self.name + ": EOF exception found" )
2514 main.log.error( self.name + ": " + self.handle.before )
2515 main.cleanup()
2516 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002517 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002518 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002519 main.cleanup()
2520 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002521
Jon Hall61282e32015-03-19 11:34:11 -07002522 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002523 """
2524 Returns the output of the intent Pending map.
2525 """
Jon Hall63604932015-02-26 17:09:50 -08002526 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002527 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002528 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002529 cmdStr += " -j"
2530 output = self.sendline( cmdStr )
2531 return output
Jon Hall63604932015-02-26 17:09:50 -08002532 except TypeError:
2533 main.log.exception( self.name + ": Object not as expected" )
2534 return None
2535 except pexpect.EOF:
2536 main.log.error( self.name + ": EOF exception found" )
2537 main.log.error( self.name + ": " + self.handle.before )
2538 main.cleanup()
2539 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002540 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002541 main.log.exception( self.name + ": Uncaught exception!" )
2542 main.cleanup()
2543 main.exit()
2544
Jon Hall61282e32015-03-19 11:34:11 -07002545 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002546 """
2547 Returns the output of the raft partitions command for ONOS.
2548 """
Jon Hall61282e32015-03-19 11:34:11 -07002549 # Sample JSON
2550 # {
2551 # "leader": "tcp://10.128.30.11:7238",
2552 # "members": [
2553 # "tcp://10.128.30.11:7238",
2554 # "tcp://10.128.30.17:7238",
2555 # "tcp://10.128.30.13:7238",
2556 # ],
2557 # "name": "p1",
2558 # "term": 3
2559 # },
Jon Hall63604932015-02-26 17:09:50 -08002560 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002561 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07002562 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002563 cmdStr += " -j"
2564 output = self.sendline( cmdStr )
2565 return output
Jon Hall63604932015-02-26 17:09:50 -08002566 except TypeError:
2567 main.log.exception( self.name + ": Object not as expected" )
2568 return None
2569 except pexpect.EOF:
2570 main.log.error( self.name + ": EOF exception found" )
2571 main.log.error( self.name + ": " + self.handle.before )
2572 main.cleanup()
2573 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002574 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002575 main.log.exception( self.name + ": Uncaught exception!" )
2576 main.cleanup()
2577 main.exit()
2578
Jon Hallbe379602015-03-24 13:39:32 -07002579 def apps( self, jsonFormat=True ):
2580 """
2581 Returns the output of the apps command for ONOS. This command lists
2582 information about installed ONOS applications
2583 """
2584 # Sample JSON object
2585 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2586 # "description":"ONOS OpenFlow protocol southbound providers",
2587 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2588 # "features":"[onos-openflow]","state":"ACTIVE"}]
2589 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002590 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07002591 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002592 cmdStr += " -j"
2593 output = self.sendline( cmdStr )
2594 assert "Error executing command" not in output
2595 return output
Jon Hallbe379602015-03-24 13:39:32 -07002596 # FIXME: look at specific exceptions/Errors
2597 except AssertionError:
2598 main.log.error( "Error in processing onos:app command: " +
2599 str( output ) )
2600 return None
2601 except TypeError:
2602 main.log.exception( self.name + ": Object not as expected" )
2603 return None
2604 except pexpect.EOF:
2605 main.log.error( self.name + ": EOF exception found" )
2606 main.log.error( self.name + ": " + self.handle.before )
2607 main.cleanup()
2608 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002609 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002610 main.log.exception( self.name + ": Uncaught exception!" )
2611 main.cleanup()
2612 main.exit()
2613
Jon Hall146f1522015-03-24 15:33:24 -07002614 def appStatus( self, appName ):
2615 """
2616 Uses the onos:apps cli command to return the status of an application.
2617 Returns:
2618 "ACTIVE" - If app is installed and activated
2619 "INSTALLED" - If app is installed and deactivated
2620 "UNINSTALLED" - If app is not installed
2621 None - on error
2622 """
Jon Hall146f1522015-03-24 15:33:24 -07002623 try:
2624 if not isinstance( appName, types.StringType ):
2625 main.log.error( self.name + ".appStatus(): appName must be" +
2626 " a string" )
2627 return None
2628 output = self.apps( jsonFormat=True )
2629 appsJson = json.loads( output )
2630 state = None
2631 for app in appsJson:
2632 if appName == app.get('name'):
2633 state = app.get('state')
2634 break
2635 if state == "ACTIVE" or state == "INSTALLED":
2636 return state
2637 elif state is None:
2638 return "UNINSTALLED"
2639 elif state:
2640 main.log.error( "Unexpected state from 'onos:apps': " +
2641 str( state ) )
2642 return state
2643 except TypeError:
2644 main.log.exception( self.name + ": Object not as expected" )
2645 return None
2646 except pexpect.EOF:
2647 main.log.error( self.name + ": EOF exception found" )
2648 main.log.error( self.name + ": " + self.handle.before )
2649 main.cleanup()
2650 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002651 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002652 main.log.exception( self.name + ": Uncaught exception!" )
2653 main.cleanup()
2654 main.exit()
2655
Jon Hallbe379602015-03-24 13:39:32 -07002656 def app( self, appName, option ):
2657 """
2658 Interacts with the app command for ONOS. This command manages
2659 application inventory.
2660 """
Jon Hallbe379602015-03-24 13:39:32 -07002661 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002662 # Validate argument types
2663 valid = True
2664 if not isinstance( appName, types.StringType ):
2665 main.log.error( self.name + ".app(): appName must be a " +
2666 "string" )
2667 valid = False
2668 if not isinstance( option, types.StringType ):
2669 main.log.error( self.name + ".app(): option must be a string" )
2670 valid = False
2671 if not valid:
2672 return main.FALSE
2673 # Validate Option
2674 option = option.lower()
2675 # NOTE: Install may become a valid option
2676 if option == "activate":
2677 pass
2678 elif option == "deactivate":
2679 pass
2680 elif option == "uninstall":
2681 pass
2682 else:
2683 # Invalid option
2684 main.log.error( "The ONOS app command argument only takes " +
2685 "the values: (activate|deactivate|uninstall)" +
2686 "; was given '" + option + "'")
2687 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002688 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002689 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002690 if "Error executing command" in output:
2691 main.log.error( "Error in processing onos:app command: " +
2692 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002693 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002694 elif "No such application" in output:
2695 main.log.error( "The application '" + appName +
2696 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07002697 return main.FALSE
2698 elif "Command not found:" in output:
2699 main.log.error( "Error in processing onos:app command: " +
2700 str( output ) )
2701 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002702 elif "Unsupported command:" in output:
2703 main.log.error( "Incorrect command given to 'app': " +
2704 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002705 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07002706 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07002707 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002708 return main.TRUE
2709 except TypeError:
2710 main.log.exception( self.name + ": Object not as expected" )
2711 return main.ERROR
2712 except pexpect.EOF:
2713 main.log.error( self.name + ": EOF exception found" )
2714 main.log.error( self.name + ": " + self.handle.before )
2715 main.cleanup()
2716 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002717 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002718 main.log.exception( self.name + ": Uncaught exception!" )
2719 main.cleanup()
2720 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07002721
Jon Hallbd16b922015-03-26 17:53:15 -07002722 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002723 """
2724 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002725 appName is the hierarchical app name, not the feature name
2726 If check is True, method will check the status of the app after the
2727 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002728 Returns main.TRUE if the command was successfully sent
2729 main.FALSE if the cli responded with an error or given
2730 incorrect input
2731 """
2732 try:
2733 if not isinstance( appName, types.StringType ):
2734 main.log.error( self.name + ".activateApp(): appName must be" +
2735 " a string" )
2736 return main.FALSE
2737 status = self.appStatus( appName )
2738 if status == "INSTALLED":
2739 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002740 if check and response == main.TRUE:
2741 for i in range(10): # try 10 times then give up
2742 # TODO: Check with Thomas about this delay
2743 status = self.appStatus( appName )
2744 if status == "ACTIVE":
2745 return main.TRUE
2746 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07002747 main.log.debug( "The state of application " +
2748 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07002749 time.sleep( 1 )
2750 return main.FALSE
2751 else: # not 'check' or command didn't succeed
2752 return response
Jon Hall146f1522015-03-24 15:33:24 -07002753 elif status == "ACTIVE":
2754 return main.TRUE
2755 elif status == "UNINSTALLED":
2756 main.log.error( self.name + ": Tried to activate the " +
2757 "application '" + appName + "' which is not " +
2758 "installed." )
2759 else:
2760 main.log.error( "Unexpected return value from appStatus: " +
2761 str( status ) )
2762 return main.ERROR
2763 except TypeError:
2764 main.log.exception( self.name + ": Object not as expected" )
2765 return main.ERROR
2766 except pexpect.EOF:
2767 main.log.error( self.name + ": EOF exception found" )
2768 main.log.error( self.name + ": " + self.handle.before )
2769 main.cleanup()
2770 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002771 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002772 main.log.exception( self.name + ": Uncaught exception!" )
2773 main.cleanup()
2774 main.exit()
2775
Jon Hallbd16b922015-03-26 17:53:15 -07002776 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002777 """
2778 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002779 appName is the hierarchical app name, not the feature name
2780 If check is True, method will check the status of the app after the
2781 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002782 Returns main.TRUE if the command was successfully sent
2783 main.FALSE if the cli responded with an error or given
2784 incorrect input
2785 """
2786 try:
2787 if not isinstance( appName, types.StringType ):
2788 main.log.error( self.name + ".deactivateApp(): appName must " +
2789 "be a string" )
2790 return main.FALSE
2791 status = self.appStatus( appName )
2792 if status == "INSTALLED":
2793 return main.TRUE
2794 elif status == "ACTIVE":
2795 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002796 if check and response == main.TRUE:
2797 for i in range(10): # try 10 times then give up
2798 status = self.appStatus( appName )
2799 if status == "INSTALLED":
2800 return main.TRUE
2801 else:
2802 time.sleep( 1 )
2803 return main.FALSE
2804 else: # not check or command didn't succeed
2805 return response
Jon Hall146f1522015-03-24 15:33:24 -07002806 elif status == "UNINSTALLED":
2807 main.log.warn( self.name + ": Tried to deactivate the " +
2808 "application '" + appName + "' which is not " +
2809 "installed." )
2810 return main.TRUE
2811 else:
2812 main.log.error( "Unexpected return value from appStatus: " +
2813 str( status ) )
2814 return main.ERROR
2815 except TypeError:
2816 main.log.exception( self.name + ": Object not as expected" )
2817 return main.ERROR
2818 except pexpect.EOF:
2819 main.log.error( self.name + ": EOF exception found" )
2820 main.log.error( self.name + ": " + self.handle.before )
2821 main.cleanup()
2822 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002823 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002824 main.log.exception( self.name + ": Uncaught exception!" )
2825 main.cleanup()
2826 main.exit()
2827
Jon Hallbd16b922015-03-26 17:53:15 -07002828 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002829 """
2830 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002831 appName is the hierarchical app name, not the feature name
2832 If check is True, method will check the status of the app after the
2833 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002834 Returns main.TRUE if the command was successfully sent
2835 main.FALSE if the cli responded with an error or given
2836 incorrect input
2837 """
2838 # TODO: check with Thomas about the state machine for apps
2839 try:
2840 if not isinstance( appName, types.StringType ):
2841 main.log.error( self.name + ".uninstallApp(): appName must " +
2842 "be a string" )
2843 return main.FALSE
2844 status = self.appStatus( appName )
2845 if status == "INSTALLED":
2846 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002847 if check and response == main.TRUE:
2848 for i in range(10): # try 10 times then give up
2849 status = self.appStatus( appName )
2850 if status == "UNINSTALLED":
2851 return main.TRUE
2852 else:
2853 time.sleep( 1 )
2854 return main.FALSE
2855 else: # not check or command didn't succeed
2856 return response
Jon Hall146f1522015-03-24 15:33:24 -07002857 elif status == "ACTIVE":
2858 main.log.warn( self.name + ": Tried to uninstall the " +
2859 "application '" + appName + "' which is " +
2860 "currently active." )
2861 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002862 if check and response == main.TRUE:
2863 for i in range(10): # try 10 times then give up
2864 status = self.appStatus( appName )
2865 if status == "UNINSTALLED":
2866 return main.TRUE
2867 else:
2868 time.sleep( 1 )
2869 return main.FALSE
2870 else: # not check or command didn't succeed
2871 return response
Jon Hall146f1522015-03-24 15:33:24 -07002872 elif status == "UNINSTALLED":
2873 return main.TRUE
2874 else:
2875 main.log.error( "Unexpected return value from appStatus: " +
2876 str( status ) )
2877 return main.ERROR
2878 except TypeError:
2879 main.log.exception( self.name + ": Object not as expected" )
2880 return main.ERROR
2881 except pexpect.EOF:
2882 main.log.error( self.name + ": EOF exception found" )
2883 main.log.error( self.name + ": " + self.handle.before )
2884 main.cleanup()
2885 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002886 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002887 main.log.exception( self.name + ": Uncaught exception!" )
2888 main.cleanup()
2889 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07002890
2891 def appIDs( self, jsonFormat=True ):
2892 """
2893 Show the mappings between app id and app names given by the 'app-ids'
2894 cli command
2895 """
2896 try:
2897 cmdStr = "app-ids"
2898 if jsonFormat:
2899 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07002900 output = self.sendline( cmdStr )
2901 assert "Error executing command" not in output
2902 return output
Jon Hallbd16b922015-03-26 17:53:15 -07002903 except AssertionError:
2904 main.log.error( "Error in processing onos:app-ids command: " +
2905 str( output ) )
2906 return None
2907 except TypeError:
2908 main.log.exception( self.name + ": Object not as expected" )
2909 return None
2910 except pexpect.EOF:
2911 main.log.error( self.name + ": EOF exception found" )
2912 main.log.error( self.name + ": " + self.handle.before )
2913 main.cleanup()
2914 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002915 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07002916 main.log.exception( self.name + ": Uncaught exception!" )
2917 main.cleanup()
2918 main.exit()
2919
2920 def appToIDCheck( self ):
2921 """
2922 This method will check that each application's ID listed in 'apps' is
2923 the same as the ID listed in 'app-ids'. The check will also check that
2924 there are no duplicate IDs issued. Note that an app ID should be
2925 a globaly unique numerical identifier for app/app-like features. Once
2926 an ID is registered, the ID is never freed up so that if an app is
2927 reinstalled it will have the same ID.
2928
2929 Returns: main.TRUE if the check passes and
2930 main.FALSE if the check fails or
2931 main.ERROR if there is some error in processing the test
2932 """
2933 try:
2934 ids = json.loads( self.appIDs( jsonFormat=True ) )
2935 apps = json.loads( self.apps( jsonFormat=True ) )
2936 result = main.TRUE
2937 for app in apps:
2938 appID = app.get( 'id' )
2939 if appID is None:
2940 main.log.error( "Error parsing app: " + str( app ) )
2941 result = main.FALSE
2942 appName = app.get( 'name' )
2943 if appName is None:
2944 main.log.error( "Error parsing app: " + str( app ) )
2945 result = main.FALSE
2946 # get the entry in ids that has the same appID
2947 current = filter(lambda item: item[ 'id' ] == appID, ids)
Jon Hall050e1bd2015-03-30 13:33:02 -07002948 # main.log.debug( "Comparing " + str( app ) + " to " +
2949 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07002950 if not current: # if ids doesn't have this id
2951 result = main.FALSE
2952 main.log.error( "'app-ids' does not have the ID for " +
2953 str( appName ) + " that apps does." )
2954 elif len( current ) > 1:
2955 # there is more than one app with this ID
2956 result = main.FALSE
2957 # We will log this later in the method
2958 elif not current[0][ 'name' ] == appName:
2959 currentName = current[0][ 'name' ]
2960 result = main.FALSE
2961 main.log.error( "'app-ids' has " + str( currentName ) +
2962 " registered under id:" + str( appID ) +
2963 " but 'apps' has " + str( appName ) )
2964 else:
2965 pass # id and name match!
2966 # now make sure that app-ids has no duplicates
2967 idsList = []
2968 namesList = []
2969 for item in ids:
2970 idsList.append( item[ 'id' ] )
2971 namesList.append( item[ 'name' ] )
2972 if len( idsList ) != len( set( idsList ) ) or\
2973 len( namesList ) != len( set( namesList ) ):
2974 main.log.error( "'app-ids' has some duplicate entries: \n"
2975 + json.dumps( ids,
2976 sort_keys=True,
2977 indent=4,
2978 separators=( ',', ': ' ) ) )
2979 result = main.FALSE
2980 return result
2981 except ( ValueError, TypeError ):
2982 main.log.exception( self.name + ": Object not as expected" )
2983 return main.ERROR
2984 except pexpect.EOF:
2985 main.log.error( self.name + ": EOF exception found" )
2986 main.log.error( self.name + ": " + self.handle.before )
2987 main.cleanup()
2988 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002989 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07002990 main.log.exception( self.name + ": Uncaught exception!" )
2991 main.cleanup()
2992 main.exit()
2993
Jon Hallfb760a02015-04-13 15:35:03 -07002994 def getCfg( self, component=None, propName=None, short=False,
2995 jsonFormat=True ):
2996 """
2997 Get configuration settings from onos cli
2998 Optional arguments:
2999 component - Optionally only list configurations for a specific
3000 component. If None, all components with configurations
3001 are displayed. Case Sensitive string.
3002 propName - If component is specified, propName option will show
3003 only this specific configuration from that component.
3004 Case Sensitive string.
3005 jsonFormat - Returns output as json. Note that this will override
3006 the short option
3007 short - Short, less verbose, version of configurations.
3008 This is overridden by the json option
3009 returns:
3010 Output from cli as a string or None on error
3011 """
3012 try:
3013 baseStr = "cfg"
3014 cmdStr = " get"
3015 componentStr = ""
3016 if component:
3017 componentStr += " " + component
3018 if propName:
3019 componentStr += " " + propName
3020 if jsonFormat:
3021 baseStr += " -j"
3022 elif short:
3023 baseStr += " -s"
3024 output = self.sendline( baseStr + cmdStr + componentStr )
3025 assert "Error executing command" not in output
3026 return output
3027 except AssertionError:
3028 main.log.error( "Error in processing 'cfg get' command: " +
3029 str( output ) )
3030 return None
3031 except TypeError:
3032 main.log.exception( self.name + ": Object not as expected" )
3033 return None
3034 except pexpect.EOF:
3035 main.log.error( self.name + ": EOF exception found" )
3036 main.log.error( self.name + ": " + self.handle.before )
3037 main.cleanup()
3038 main.exit()
3039 except Exception:
3040 main.log.exception( self.name + ": Uncaught exception!" )
3041 main.cleanup()
3042 main.exit()
3043
3044 def setCfg( self, component, propName, value=None, check=True ):
3045 """
3046 Set/Unset configuration settings from ONOS cli
3047 Optional arguments:
3048 component - The case sensitive name of the component whose
3049 property is to be set
3050 propName - The case sensitive name of the property to be set/unset
3051 value - The value to set the property to. If None, will unset the
3052 property and revert it to it's default value(if applicable)
3053 check - Boolean, Check whether the option was successfully set this
3054 only applies when a value is given.
3055 returns:
3056 main.TRUE on success or main.FALSE on failure. If check is False,
3057 will return main.TRUE unless there is an error
3058 """
3059 try:
3060 baseStr = "cfg"
3061 cmdStr = " set " + str( component ) + " " + str( propName )
3062 if value is not None:
3063 cmdStr += " " + str( value )
3064 output = self.sendline( baseStr + cmdStr )
3065 assert "Error executing command" not in output
3066 if value and check:
3067 results = self.getCfg( component=str( component ),
3068 propName=str( propName ),
3069 jsonFormat=True )
3070 # Check if current value is what we just set
3071 try:
3072 jsonOutput = json.loads( results )
3073 current = jsonOutput[ 'value' ]
3074 except ( ValueError, TypeError ):
3075 main.log.exception( "Error parsing cfg output" )
3076 main.log.error( "output:" + repr( results ) )
3077 return main.FALSE
3078 if current == str( value ):
3079 return main.TRUE
3080 return main.FALSE
3081 return main.TRUE
3082 except AssertionError:
3083 main.log.error( "Error in processing 'cfg set' command: " +
3084 str( output ) )
3085 return main.FALSE
3086 except TypeError:
3087 main.log.exception( self.name + ": Object not as expected" )
3088 return main.FALSE
3089 except pexpect.EOF:
3090 main.log.error( self.name + ": EOF exception found" )
3091 main.log.error( self.name + ": " + self.handle.before )
3092 main.cleanup()
3093 main.exit()
3094 except Exception:
3095 main.log.exception( self.name + ": Uncaught exception!" )
3096 main.cleanup()
3097 main.exit()
3098