blob: a99793327656808f37d49649061479ad69175f9d [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:
103 main.log.exception( "Exception in discconect of " + self.name )
104 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
kelvin-onlabd3b64892015-01-20 13:26:24 -0800302 def sendline( self, cmdStr ):
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()
319 self.handle.expect( "\$" )
320 response += self.handle.before
321 print response
322 try:
323 print self.handle.after
324 except:
325 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 Hall7bdfc122015-01-23 11:45:32 -0800329 # Remove control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800330 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800331 response = ansiEscape.sub( '', response )
kelvin-onlabfb521662015-02-27 09:52:40 -0800332 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800333 response = re.sub( r"\s\r", "", response )
334 response = response.strip()
335 # parse for just the output, remove the cmd from response
336 output = response.split( cmdStr, 1 )[1]
Jon Hall7bdfc122015-01-23 11:45:32 -0800337 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800338 except TypeError:
339 main.log.exception( self.name + ": Object not as expected" )
340 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400341 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800342 main.log.error( self.name + ": EOF exception found" )
343 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400344 main.cleanup()
345 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800346 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800347 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400348 main.cleanup()
349 main.exit()
350
kelvin8ec71442015-01-15 16:57:00 -0800351 # IMPORTANT NOTE:
352 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800353 # the cli command changing 'a:b' with 'aB'.
354 # Ex ) onos:topology > onosTopology
355 # onos:links > onosLinks
356 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800357
kelvin-onlabd3b64892015-01-20 13:26:24 -0800358 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800359 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400360 Adds a new cluster node by ID and address information.
361 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800362 * nodeId
363 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400364 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800365 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800366 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400367 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800368 cmdStr = "add-node " + str( nodeId ) + " " +\
369 str( ONOSIp ) + " " + str( tcpPort )
370 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800371 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800372 main.log.error( "Error in adding node" )
373 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800374 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400375 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800376 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400377 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800378 except TypeError:
379 main.log.exception( self.name + ": Object not as expected" )
380 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400381 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800382 main.log.error( self.name + ": EOF exception found" )
383 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400384 main.cleanup()
385 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800386 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800387 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400388 main.cleanup()
389 main.exit()
390
kelvin-onlabd3b64892015-01-20 13:26:24 -0800391 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800392 """
andrewonlab86dc3082014-10-13 18:18:38 -0400393 Removes a cluster by ID
394 Issues command: 'remove-node [<node-id>]'
395 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800396 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800397 """
andrewonlab86dc3082014-10-13 18:18:38 -0400398 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400399
kelvin-onlabd3b64892015-01-20 13:26:24 -0800400 cmdStr = "remove-node " + str( nodeId )
401 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800402 # TODO: add error checking. Does ONOS give any errors?
andrewonlab86dc3082014-10-13 18:18:38 -0400403
404 return main.TRUE
Jon Halle3f39ff2015-01-13 11:50:53 -0800405
Jon Halld4d4b372015-01-28 16:02:41 -0800406 except TypeError:
407 main.log.exception( self.name + ": Object not as expected" )
408 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400409 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800410 main.log.error( self.name + ": EOF exception found" )
411 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400412 main.cleanup()
413 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800414 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800415 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400416 main.cleanup()
417 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400418
Jon Hall61282e32015-03-19 11:34:11 -0700419 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800420 """
andrewonlab7c211572014-10-15 16:45:20 -0400421 List the nodes currently visible
422 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700423 Optional argument:
424 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800425 """
andrewonlab7c211572014-10-15 16:45:20 -0400426 try:
Jon Hall61282e32015-03-19 11:34:11 -0700427 if jsonFormat:
428 cmdStr = "nodes -j"
429 output = self.sendline( cmdStr )
430 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
431 parsedOutput = ansiEscape.sub( '', output )
432 return parsedOutput
433 else:
434 cmdStr = "nodes"
435 output = self.sendline( cmdStr )
436 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800437 except TypeError:
438 main.log.exception( self.name + ": Object not as expected" )
439 return None
andrewonlab7c211572014-10-15 16:45:20 -0400440 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800441 main.log.error( self.name + ": EOF exception found" )
442 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400443 main.cleanup()
444 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800445 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800446 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400447 main.cleanup()
448 main.exit()
449
kelvin8ec71442015-01-15 16:57:00 -0800450 def topology( self ):
451 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700452 Definition:
453 Returns the ouput of topology command.
454 Return:
455 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800456 """
andrewonlab95ce8322014-10-13 14:12:04 -0400457 try:
Jon Halle3f39ff2015-01-13 11:50:53 -0800458 # either onos:topology or 'topology' will work in CLI
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700459 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800460 handle = self.sendline( cmdStr )
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700461 main.log.info( "topology -j returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400462 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800463 except TypeError:
464 main.log.exception( self.name + ": Object not as expected" )
465 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400466 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800467 main.log.error( self.name + ": EOF exception found" )
468 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400469 main.cleanup()
470 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800471 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800472 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400473 main.cleanup()
474 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800475
kelvin-onlabd3b64892015-01-20 13:26:24 -0800476 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800477 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800478 Installs a specified feature
andrewonlabc2d05aa2014-10-13 16:51:10 -0400479 by issuing command: 'onos> feature:install <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800480 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400481 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800482 cmdStr = "feature:install " + str( featureStr )
483 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800484 # TODO: Check for possible error responses from karaf
andrewonlabc2d05aa2014-10-13 16:51:10 -0400485 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800486 except TypeError:
487 main.log.exception( self.name + ": Object not as expected" )
488 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400489 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800490 main.log.error( self.name + ": EOF exception found" )
491 main.log.error( self.name + ": " + self.handle.before )
492 main.log.report( "Failed to install feature" )
493 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400494 main.cleanup()
495 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800496 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800497 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800498 main.log.report( "Failed to install feature" )
499 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400500 main.cleanup()
501 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800502
kelvin-onlabd3b64892015-01-20 13:26:24 -0800503 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800504 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400505 Uninstalls a specified feature
506 by issuing command: 'onos> feature:uninstall <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800507 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400508 try:
Jon Hall30b82fa2015-03-04 17:15:43 -0800509 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
510 handle = self.sendline( cmdStr )
511 if handle != '':
512 cmdStr = "feature:uninstall " + str( featureStr )
513 self.sendline( cmdStr )
514 # TODO: Check for possible error responses from karaf
515 else:
Jon Hallefbd9792015-03-05 16:11:36 -0800516 main.log.info( "Feature needs to be installed before " +
517 "uninstalling it" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400518 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800519 except TypeError:
520 main.log.exception( self.name + ": Object not as expected" )
521 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400522 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800523 main.log.error( self.name + ": EOF exception found" )
524 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400525 main.cleanup()
526 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800527 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800528 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400529 main.cleanup()
530 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800531
jenkins7ead5a82015-03-13 10:28:21 -0700532 def deviceRemove( self, deviceId ):
533 """
534 Removes particular device from storage
535
536 TODO: refactor this function
537 """
538 try:
539 cmdStr = "device-remove "+str(deviceId)
Jon Hallbe379602015-03-24 13:39:32 -0700540 self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -0700541 return main.TRUE
542 except TypeError:
543 main.log.exception( self.name + ": Object not as expected" )
544 return None
545 except pexpect.EOF:
546 main.log.error( self.name + ": EOF exception found" )
547 main.log.error( self.name + ": " + self.handle.before )
548 main.cleanup()
549 main.exit()
550 except Exception:
551 main.log.exception( self.name + ": Uncaught exception!" )
552 main.cleanup()
553 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700554
kelvin-onlabd3b64892015-01-20 13:26:24 -0800555 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800556 """
Jon Hall7b02d952014-10-17 20:14:54 -0400557 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400558 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800559 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800560 """
andrewonlab86dc3082014-10-13 18:18:38 -0400561 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800562 if jsonFormat:
563 cmdStr = "devices -j"
564 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800565 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800566 handle variable here contains some ANSI escape color code
567 sequences at the end which are invisible in the print command
568 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800569 function. The repr( handle ) output when printed shows the
570 ANSI escape sequences. In json.loads( somestring ), this
571 somestring variable is actually repr( somestring ) and
Jon Halle3f39ff2015-01-13 11:50:53 -0800572 json.loads would fail with the escape sequence. So we take off
573 that escape sequence using:
574
kelvin-onlabd3b64892015-01-20 13:26:24 -0800575 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
576 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800577 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800578 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
579 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400580 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400581 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800582 cmdStr = "devices"
583 handle = self.sendline( cmdStr )
Jon Hallcd707292014-10-17 19:06:17 -0400584 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800585 except TypeError:
586 main.log.exception( self.name + ": Object not as expected" )
587 return None
andrewonlab7c211572014-10-15 16:45:20 -0400588 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800589 main.log.error( self.name + ": EOF exception found" )
590 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400591 main.cleanup()
592 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800593 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800594 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400595 main.cleanup()
596 main.exit()
597
kelvin-onlabd3b64892015-01-20 13:26:24 -0800598 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800599 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800600 This balances the devices across all controllers
601 by issuing command: 'onos> onos:balance-masters'
602 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800603 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800604 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800605 cmdStr = "onos:balance-masters"
606 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800607 # TODO: Check for error responses from ONOS
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800608 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800609 except TypeError:
610 main.log.exception( self.name + ": Object not as expected" )
611 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800612 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800613 main.log.error( self.name + ": EOF exception found" )
614 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800615 main.cleanup()
616 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800617 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800618 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800619 main.cleanup()
620 main.exit()
621
kelvin-onlabd3b64892015-01-20 13:26:24 -0800622 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800623 """
Jon Halle8217482014-10-17 13:49:14 -0400624 Lists all core links
625 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800626 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800627 """
Jon Halle8217482014-10-17 13:49:14 -0400628 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800629 if jsonFormat:
630 cmdStr = "links -j"
631 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800632 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800633 handle variable here contains some ANSI escape color code
634 sequences at the end which are invisible in the print command
635 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800636 function. The repr( handle ) output when printed shows the ANSI
637 escape sequences. In json.loads( somestring ), this somestring
638 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800639 fail with the escape sequence. So we take off that escape
640 sequence using:
641
kelvin-onlabd3b64892015-01-20 13:26:24 -0800642 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
643 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800644 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800645 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
646 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400647 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400648 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800649 cmdStr = "links"
650 handle = self.sendline( cmdStr )
Jon Halla001c392014-10-17 18:50:59 -0400651 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800652 except TypeError:
653 main.log.exception( self.name + ": Object not as expected" )
654 return None
Jon Halle8217482014-10-17 13:49:14 -0400655 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800656 main.log.error( self.name + ": EOF exception found" )
657 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400658 main.cleanup()
659 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800660 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800661 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400662 main.cleanup()
663 main.exit()
664
kelvin-onlabd3b64892015-01-20 13:26:24 -0800665 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800666 """
Jon Halle8217482014-10-17 13:49:14 -0400667 Lists all ports
668 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800669 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800670 """
Jon Halle8217482014-10-17 13:49:14 -0400671 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800672 if jsonFormat:
673 cmdStr = "ports -j"
674 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800675 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800676 handle variable here contains some ANSI escape color code
677 sequences at the end which are invisible in the print command
678 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800679 function. The repr( handle ) output when printed shows the ANSI
680 escape sequences. In json.loads( somestring ), this somestring
681 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800682 fail with the escape sequence. So we take off that escape
Jon Hallefbd9792015-03-05 16:11:36 -0800683 sequence using the following commands:
Jon Halle3f39ff2015-01-13 11:50:53 -0800684
kelvin-onlabd3b64892015-01-20 13:26:24 -0800685 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
686 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800687 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800688 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
689 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400690 return handle1
691
Jon Halle8217482014-10-17 13:49:14 -0400692 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800693 cmdStr = "ports"
694 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800695 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800696 except TypeError:
697 main.log.exception( self.name + ": Object not as expected" )
698 return None
Jon Halle8217482014-10-17 13:49:14 -0400699 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800700 main.log.error( self.name + ": EOF exception found" )
701 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400702 main.cleanup()
703 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800704 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800705 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400706 main.cleanup()
707 main.exit()
708
kelvin-onlabd3b64892015-01-20 13:26:24 -0800709 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800710 """
Jon Hall983a1702014-10-28 18:44:22 -0400711 Lists all devices and the controllers with roles assigned to them
712 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800713 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800714 """
andrewonlab7c211572014-10-15 16:45:20 -0400715 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800716 if jsonFormat:
717 cmdStr = "roles -j"
718 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800719 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800720 handle variable here contains some ANSI escape color code
721 sequences at the end which are invisible in the print command
722 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800723 function. The repr( handle ) output when printed shows the ANSI
724 escape sequences. In json.loads( somestring ), this somestring
725 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800726 fail with the escape sequence.
Jon Hallb1290e82014-11-18 16:17:48 -0500727
Jon Halle3f39ff2015-01-13 11:50:53 -0800728 So we take off that escape sequence using the following
729 commads:
730
kelvin-onlabd3b64892015-01-20 13:26:24 -0800731 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
732 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800733 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800734 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
735 handle1 = ansiEscape.sub( '', handle )
Jon Hall983a1702014-10-28 18:44:22 -0400736 return handle1
andrewonlab7c211572014-10-15 16:45:20 -0400737
andrewonlab7c211572014-10-15 16:45:20 -0400738 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800739 cmdStr = "roles"
740 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800741 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800742 except TypeError:
743 main.log.exception( self.name + ": Object not as expected" )
744 return None
Jon Hall983a1702014-10-28 18:44:22 -0400745 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800746 main.log.error( self.name + ": EOF exception found" )
747 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400748 main.cleanup()
749 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800750 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800751 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400752 main.cleanup()
753 main.exit()
754
kelvin-onlabd3b64892015-01-20 13:26:24 -0800755 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800756 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800757 Given the a string containing the json representation of the "roles"
758 cli command and a partial or whole device id, returns a json object
759 containing the roles output for the first device whose id contains
760 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400761
762 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800763 A dict of the role assignments for the given device or
764 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800765 """
Jon Hall983a1702014-10-28 18:44:22 -0400766 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800767 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400768 return None
769 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800770 rawRoles = self.roles()
771 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800772 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800773 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800774 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800775 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400776 return device
777 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800778 except TypeError:
779 main.log.exception( self.name + ": Object not as expected" )
780 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400781 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800782 main.log.error( self.name + ": EOF exception found" )
783 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400784 main.cleanup()
785 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800786 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800787 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400788 main.cleanup()
789 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800790
kelvin-onlabd3b64892015-01-20 13:26:24 -0800791 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800792 """
Jon Hall94fd0472014-12-08 11:52:42 -0800793 Iterates through each device and checks if there is a master assigned
794 Returns: main.TRUE if each device has a master
795 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800796 """
Jon Hall94fd0472014-12-08 11:52:42 -0800797 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800798 rawRoles = self.roles()
799 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800800 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800801 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800802 # print device
803 if device[ 'master' ] == "none":
804 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800805 return main.FALSE
806 return main.TRUE
807
Jon Halld4d4b372015-01-28 16:02:41 -0800808 except TypeError:
809 main.log.exception( self.name + ": Object not as expected" )
810 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800811 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800812 main.log.error( self.name + ": EOF exception found" )
813 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800814 main.cleanup()
815 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800816 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800817 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800818 main.cleanup()
819 main.exit()
820
kelvin-onlabd3b64892015-01-20 13:26:24 -0800821 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800822 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400823 Returns string of paths, and the cost.
824 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800825 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400826 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800827 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
828 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800829 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800830 main.log.error( "Error in getting paths" )
831 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400832 else:
kelvin8ec71442015-01-15 16:57:00 -0800833 path = handle.split( ";" )[ 0 ]
834 cost = handle.split( ";" )[ 1 ]
835 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800836 except TypeError:
837 main.log.exception( self.name + ": Object not as expected" )
838 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400839 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800840 main.log.error( self.name + ": EOF exception found" )
841 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400842 main.cleanup()
843 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800844 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800845 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400846 main.cleanup()
847 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800848
kelvin-onlabd3b64892015-01-20 13:26:24 -0800849 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800850 """
Jon Hallffb386d2014-11-21 13:43:38 -0800851 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400852 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800853 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800854 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400855 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800856 if jsonFormat:
857 cmdStr = "hosts -j"
858 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800859 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800860 handle variable here contains some ANSI escape color code
861 sequences at the end which are invisible in the print command
862 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800863 function. The repr( handle ) output when printed shows the ANSI
864 escape sequences. In json.loads( somestring ), this somestring
865 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800866 fail with the escape sequence. So we take off that escape
867 sequence using:
868
kelvin-onlabd3b64892015-01-20 13:26:24 -0800869 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
870 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800871 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800872 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
873 handle1 = ansiEscape.sub( '', handle )
Jon Hall42db6dc2014-10-24 19:03:48 -0400874 return handle1
875 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800876 cmdStr = "hosts"
877 handle = self.sendline( cmdStr )
Jon Hall42db6dc2014-10-24 19:03:48 -0400878 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800879 except TypeError:
880 main.log.exception( self.name + ": Object not as expected" )
881 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400882 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800883 main.log.error( self.name + ": EOF exception found" )
884 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400885 main.cleanup()
886 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800887 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800888 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400889 main.cleanup()
890 main.exit()
891
kelvin-onlabd3b64892015-01-20 13:26:24 -0800892 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800893 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400894 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800895
Jon Hallefbd9792015-03-05 16:11:36 -0800896 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800897 partial mac address
898
Jon Hall42db6dc2014-10-24 19:03:48 -0400899 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800900 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400901 try:
kelvin8ec71442015-01-15 16:57:00 -0800902 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400903 return None
904 else:
905 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800906 rawHosts = self.hosts()
907 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800908 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800909 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800910 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800911 if not host:
912 pass
913 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400914 return host
915 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800916 except TypeError:
917 main.log.exception( self.name + ": Object not as expected" )
918 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400919 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800920 main.log.error( self.name + ": EOF exception found" )
921 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400922 main.cleanup()
923 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800924 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800925 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400926 main.cleanup()
927 main.exit()
928
kelvin-onlabd3b64892015-01-20 13:26:24 -0800929 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800930 """
931 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400932 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800933
andrewonlab3f0a4af2014-10-17 12:25:14 -0400934 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800935 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400936 IMPORTANT:
937 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800938 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400939 Furthermore, it assumes that value of VLAN is '-1'
940 Description:
kelvin8ec71442015-01-15 16:57:00 -0800941 Converts mininet hosts ( h1, h2, h3... ) into
942 ONOS format ( 00:00:00:00:00:01/-1 , ... )
943 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400944 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800945 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400946
kelvin-onlabd3b64892015-01-20 13:26:24 -0800947 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800948 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800949 hostHex = hex( int( host ) ).zfill( 12 )
950 hostHex = str( hostHex ).replace( 'x', '0' )
951 i = iter( str( hostHex ) )
952 hostHex = ":".join( a + b for a, b in zip( i, i ) )
953 hostHex = hostHex + "/-1"
954 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400955
kelvin-onlabd3b64892015-01-20 13:26:24 -0800956 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400957
Jon Halld4d4b372015-01-28 16:02:41 -0800958 except TypeError:
959 main.log.exception( self.name + ": Object not as expected" )
960 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400961 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800962 main.log.error( self.name + ": EOF exception found" )
963 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400964 main.cleanup()
965 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800966 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800967 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400968 main.cleanup()
969 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400970
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800972 """
andrewonlabe6745342014-10-17 14:29:13 -0400973 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800974 * hostIdOne: ONOS host id for host1
975 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400976 Description:
Jon Hallefbd9792015-03-05 16:11:36 -0800977 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500978 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -0800979 Returns:
980 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -0800981 """
andrewonlabe6745342014-10-17 14:29:13 -0400982 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800983 cmdStr = "add-host-intent " + str( hostIdOne ) +\
984 " " + str( hostIdTwo )
985 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800986 if re.search( "Error", handle ):
987 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -0700988 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800989 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -0800990 else:
991 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -0800992 str( hostIdOne ) + " and " + str( hostIdTwo ) )
993 match = re.search('id=0x([\da-f]+),', handle)
994 if match:
995 return match.group()[3:-1]
996 else:
997 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -0700998 main.log.debug( "Response from ONOS was: " +
999 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001000 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001001 except TypeError:
1002 main.log.exception( self.name + ": Object not as expected" )
1003 return None
andrewonlabe6745342014-10-17 14:29:13 -04001004 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001005 main.log.error( self.name + ": EOF exception found" )
1006 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001007 main.cleanup()
1008 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001009 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001010 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001011 main.cleanup()
1012 main.exit()
1013
kelvin-onlabd3b64892015-01-20 13:26:24 -08001014 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001015 """
andrewonlab7b31d232014-10-24 13:31:47 -04001016 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001017 * ingressDevice: device id of ingress device
1018 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001019 Optional:
1020 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001021 Description:
1022 Adds an optical intent by specifying an ingress and egress device
1023 Returns:
1024 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001025 """
andrewonlab7b31d232014-10-24 13:31:47 -04001026 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001027 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1028 " " + str( egressDevice )
1029 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001030 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001031 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001032 main.log.error( "Error in adding Optical intent" )
1033 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001034 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001035 main.log.info( "Optical intent installed between " +
1036 str( ingressDevice ) + " and " +
1037 str( egressDevice ) )
1038 match = re.search('id=0x([\da-f]+),', handle)
1039 if match:
1040 return match.group()[3:-1]
1041 else:
1042 main.log.error( "Error, intent ID not found" )
1043 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001044 except TypeError:
1045 main.log.exception( self.name + ": Object not as expected" )
1046 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001047 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001048 main.log.error( self.name + ": EOF exception found" )
1049 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001050 main.cleanup()
1051 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001052 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001053 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001054 main.cleanup()
1055 main.exit()
1056
kelvin-onlabd3b64892015-01-20 13:26:24 -08001057 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001058 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001059 ingressDevice,
1060 egressDevice,
1061 portIngress="",
1062 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001063 ethType="",
1064 ethSrc="",
1065 ethDst="",
1066 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001067 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001068 ipProto="",
1069 ipSrc="",
1070 ipDst="",
1071 tcpSrc="",
1072 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001073 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001074 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001075 * ingressDevice: device id of ingress device
1076 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001077 Optional:
1078 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001079 * ethSrc: specify ethSrc ( i.e. src mac addr )
1080 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001081 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001082 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001083 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001084 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001085 * ipSrc: specify ip source address
1086 * ipDst: specify ip destination address
1087 * tcpSrc: specify tcp source port
1088 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001089 Description:
kelvin8ec71442015-01-15 16:57:00 -08001090 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001091 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001092 Returns:
1093 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001094
Jon Halle3f39ff2015-01-13 11:50:53 -08001095 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001096 options developers provide for point-to-point
1097 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001098 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001099 try:
kelvin8ec71442015-01-15 16:57:00 -08001100 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001101 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001102 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001103 and not ipProto and not ipSrc and not ipDst \
1104 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001105 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001106
andrewonlab289e4b72014-10-21 21:24:18 -04001107 else:
andrewonlab36af3822014-11-18 17:48:18 -05001108 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001109
andrewonlab0c0a6772014-10-22 12:31:18 -04001110 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001111 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001112 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001113 cmd += " --ethSrc " + str( ethSrc )
1114 if ethDst:
1115 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001116 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001117 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001118 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001119 cmd += " --lambda "
1120 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001121 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001122 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001123 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001124 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001125 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001126 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001127 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001128 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001129 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001130
kelvin8ec71442015-01-15 16:57:00 -08001131 # Check whether the user appended the port
1132 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001133 if "/" in ingressDevice:
1134 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001135 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001136 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001137 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001138 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001139 # Would it make sense to throw an exception and exit
1140 # the test?
1141 return None
andrewonlab36af3822014-11-18 17:48:18 -05001142
kelvin8ec71442015-01-15 16:57:00 -08001143 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001144 str( ingressDevice ) + "/" +\
1145 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001146
kelvin-onlabd3b64892015-01-20 13:26:24 -08001147 if "/" in egressDevice:
1148 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001149 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001150 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001151 main.log.error( "You must specify the egress port" )
1152 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001153
kelvin8ec71442015-01-15 16:57:00 -08001154 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001155 str( egressDevice ) + "/" +\
1156 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001157
kelvin-onlab898a6c62015-01-16 14:13:53 -08001158 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001159 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001160 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001161 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001162 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001163 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001164 # TODO: print out all the options in this message?
1165 main.log.info( "Point-to-point intent installed between " +
1166 str( ingressDevice ) + " and " +
1167 str( egressDevice ) )
1168 match = re.search('id=0x([\da-f]+),', handle)
1169 if match:
1170 return match.group()[3:-1]
1171 else:
1172 main.log.error( "Error, intent ID not found" )
1173 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001174 except TypeError:
1175 main.log.exception( self.name + ": Object not as expected" )
1176 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001177 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001178 main.log.error( self.name + ": EOF exception found" )
1179 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001180 main.cleanup()
1181 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001182 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001183 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001184 main.cleanup()
1185 main.exit()
1186
kelvin-onlabd3b64892015-01-20 13:26:24 -08001187 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001188 self,
shahshreyac2f97072015-03-19 17:04:29 -07001189 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001190 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001191 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001192 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001193 ethType="",
1194 ethSrc="",
1195 ethDst="",
1196 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001197 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001198 ipProto="",
1199 ipSrc="",
1200 ipDst="",
1201 tcpSrc="",
1202 tcpDst="",
1203 setEthSrc="",
1204 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001205 """
shahshreyad0c80432014-12-04 16:56:05 -08001206 Note:
shahshreya70622b12015-03-19 17:19:00 -07001207 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001208 is same. That is, all ingress devices include port numbers
1209 with a "/" or all ingress devices could specify device
1210 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001211 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001212 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001213 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001214 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001215 Optional:
1216 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001217 * ethSrc: specify ethSrc ( i.e. src mac addr )
1218 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001219 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001220 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001221 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001222 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001223 * ipSrc: specify ip source address
1224 * ipDst: specify ip destination address
1225 * tcpSrc: specify tcp source port
1226 * tcpDst: specify tcp destination port
1227 * setEthSrc: action to Rewrite Source MAC Address
1228 * setEthDst: action to Rewrite Destination MAC Address
1229 Description:
kelvin8ec71442015-01-15 16:57:00 -08001230 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001231 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001232 Returns:
1233 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001234
Jon Halle3f39ff2015-01-13 11:50:53 -08001235 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001236 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001237 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001238 """
shahshreyad0c80432014-12-04 16:56:05 -08001239 try:
kelvin8ec71442015-01-15 16:57:00 -08001240 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001241 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001242 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001243 and not ipProto and not ipSrc and not ipDst\
1244 and not tcpSrc and not tcpDst and not setEthSrc\
1245 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001246 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001247
1248 else:
1249 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001250
shahshreyad0c80432014-12-04 16:56:05 -08001251 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001252 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001253 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001254 cmd += " --ethSrc " + str( ethSrc )
1255 if ethDst:
1256 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001257 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001258 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001260 cmd += " --lambda "
1261 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001262 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001263 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001264 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001265 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001266 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001267 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001268 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001269 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001270 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001271 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001272 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001273 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001274 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001275
kelvin8ec71442015-01-15 16:57:00 -08001276 # Check whether the user appended the port
1277 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001278
1279 if portIngressList is None:
1280 for ingressDevice in ingressDeviceList:
1281 if "/" in ingressDevice:
1282 cmd += " " + str( ingressDevice )
1283 else:
1284 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001285 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001286 # TODO: perhaps more meaningful return
1287 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001288 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001289 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hallbe379602015-03-24 13:39:32 -07001290 for ingressDevice, portIngress in zip( ingressDeviceList, portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001291 cmd += " " + \
1292 str( ingressDevice ) + "/" +\
1293 str( portIngress ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001294
kelvin-onlabd3b64892015-01-20 13:26:24 -08001295 if "/" in egressDevice:
1296 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001297 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001298 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001299 main.log.error( "You must specify " +
1300 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001301 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001302
kelvin8ec71442015-01-15 16:57:00 -08001303 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001304 str( egressDevice ) + "/" +\
1305 str( portEgress )
shahshreyac2f97072015-03-19 17:04:29 -07001306
kelvin8ec71442015-01-15 16:57:00 -08001307 print "cmd= ", cmd
kelvin-onlab898a6c62015-01-16 14:13:53 -08001308 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001309 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001310 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001311 main.log.error( "Error in adding multipoint-to-singlepoint " +
1312 "intent" )
1313 return None
shahshreyad0c80432014-12-04 16:56:05 -08001314 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001315 # TODO: print out all the options in this message?
1316 main.log.info( "Multipoint-to-singlepoint intent installed" +
shahshreyac2f97072015-03-19 17:04:29 -07001317 " failed " )
1318 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001319 except TypeError:
1320 main.log.exception( self.name + ": Object not as expected" )
1321 return None
shahshreyad0c80432014-12-04 16:56:05 -08001322 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001323 main.log.error( self.name + ": EOF exception found" )
1324 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001325 main.cleanup()
1326 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001327 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001328 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001329 main.cleanup()
1330 main.exit()
1331
Jon Hallefbd9792015-03-05 16:11:36 -08001332 def removeIntent( self, intentId, app='org.onosproject.cli',
1333 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001334 """
shahshreya1c818fc2015-02-26 13:44:08 -08001335 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001336 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001337 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001338 -p or --purge: Purge the intent from the store after removal
1339
Jon Halle3f39ff2015-01-13 11:50:53 -08001340 Returns:
1341 main.False on error and
1342 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001343 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001344 try:
shahshreya1c818fc2015-02-26 13:44:08 -08001345 cmdStr = "remove-intent "
1346 if purge:
1347 cmdStr += " -p"
1348 if sync:
1349 cmdStr += " -s"
1350
1351 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001352 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001353 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001354 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001355 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001356 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001357 # TODO: Should this be main.TRUE
1358 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001359 except TypeError:
1360 main.log.exception( self.name + ": Object not as expected" )
1361 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001362 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001363 main.log.error( self.name + ": EOF exception found" )
1364 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001365 main.cleanup()
1366 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001367 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001368 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001369 main.cleanup()
1370 main.exit()
1371
kelvin-onlabd3b64892015-01-20 13:26:24 -08001372 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001373 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001374 NOTE: This method should be used after installing application:
1375 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001376 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001377 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001378 Description:
1379 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001380 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001381 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001382 if jsonFormat:
1383 cmdStr = "routes -j"
1384 handleTmp = self.sendline( cmdStr )
1385 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1386 handle = ansiEscape.sub( '', handleTmp )
pingping-lin8b306ac2014-11-17 18:13:51 -08001387 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001388 cmdStr = "routes"
1389 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001390 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001391 except TypeError:
1392 main.log.exception( self.name + ": Object not as expected" )
1393 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001394 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001395 main.log.error( self.name + ": EOF exception found" )
1396 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001397 main.cleanup()
1398 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001399 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001400 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001401 main.cleanup()
1402 main.exit()
1403
kelvin-onlabd3b64892015-01-20 13:26:24 -08001404 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001405 """
andrewonlab377693f2014-10-21 16:00:30 -04001406 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001407 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001408 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001409 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001410 """
andrewonlabe6745342014-10-17 14:29:13 -04001411 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001412 if jsonFormat:
1413 cmdStr = "intents -j"
1414 handle = self.sendline( cmdStr )
1415 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1416 handle = ansiEscape.sub( '', handle )
kelvin8ec71442015-01-15 16:57:00 -08001417 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001418 cmdStr = "intents"
1419 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001420 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001421 except TypeError:
1422 main.log.exception( self.name + ": Object not as expected" )
1423 return None
andrewonlabe6745342014-10-17 14:29:13 -04001424 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001425 main.log.error( self.name + ": EOF exception found" )
1426 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001427 main.cleanup()
1428 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001429 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001430 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001431 main.cleanup()
1432 main.exit()
1433
kelvin-onlab54400a92015-02-26 18:05:51 -08001434 def getIntentState(self, intentsId, intentsJson=None):
1435 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001436 Check intent state.
1437 Accepts a single intent ID (string type) or a list of intent IDs.
1438 Returns the state(string type) of the id if a single intent ID is
1439 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001440 Returns a dictionary with intent IDs as the key and its
1441 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001442 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001443 intentId: intent ID (string type)
1444 intentsJson: parsed json object from the onos:intents api
1445 Returns:
1446 state = An intent's state- INSTALL,WITHDRAWN etc.
1447 stateDict = Dictionary of intent's state. intent ID as the keys and
1448 state as the values.
1449 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001450 try:
1451 state = "State is Undefined"
1452 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001453 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001454 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001455 intentsJsonTemp = json.loads( intentsJson )
1456 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001457 for intent in intentsJsonTemp:
1458 if intentsId == intent['id']:
1459 state = intent['state']
1460 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001461 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1462 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001463 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001464 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001465 dictList = []
kelvin-onlab54400a92015-02-26 18:05:51 -08001466 for ID in intentsId:
kelvin-onlab07dbd012015-03-04 16:29:39 -08001467 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001468 for intents in intentsJsonTemp:
1469 if ID == intents['id']:
kelvin-onlab07dbd012015-03-04 16:29:39 -08001470 stateDict['state'] = intents['state']
1471 stateDict['id'] = ID
Jon Hallefbd9792015-03-05 16:11:36 -08001472 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001473 break
Jon Hallefbd9792015-03-05 16:11:36 -08001474 if len( intentsId ) != len( dictList ):
1475 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001476 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001477 else:
1478 main.log.info("Invalid intents ID entry")
1479 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001480 except TypeError:
1481 main.log.exception( self.name + ": Object not as expected" )
1482 return None
1483 except pexpect.EOF:
1484 main.log.error( self.name + ": EOF exception found" )
1485 main.log.error( self.name + ": " + self.handle.before )
1486 main.cleanup()
1487 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001488 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001489 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001490 main.cleanup()
1491 main.exit()
1492
kelvin-onlabd3b64892015-01-20 13:26:24 -08001493 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001494 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001495 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001496 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001497 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001498 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001499 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001500 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001501 if jsonFormat:
1502 cmdStr = "flows -j"
1503 handle = self.sendline( cmdStr )
1504 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1505 handle = ansiEscape.sub( '', handle )
Shreya Shah0f01c812014-10-26 20:15:28 -04001506 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001507 cmdStr = "flows"
1508 handle = self.sendline( cmdStr )
Jon Hall61282e32015-03-19 11:34:11 -07001509 if re.search( "Error:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001510 main.log.error( self.name + ".flows() response: " +
1511 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001512 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001513 except TypeError:
1514 main.log.exception( self.name + ": Object not as expected" )
1515 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001516 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001517 main.log.error( self.name + ": EOF exception found" )
1518 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001519 main.cleanup()
1520 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001521 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001522 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001523 main.cleanup()
1524 main.exit()
1525
kelvin-onlabd3b64892015-01-20 13:26:24 -08001526 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08001527 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001528 """
andrewonlab87852b02014-11-19 18:44:19 -05001529 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001530 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001531 a specific point-to-point intent definition
1532 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001533 * dpidSrc: specify source dpid
1534 * dpidDst: specify destination dpid
1535 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001536 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001537 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001538 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001539 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001540 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001541 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001542 """
andrewonlab87852b02014-11-19 18:44:19 -05001543 try:
kelvin8ec71442015-01-15 16:57:00 -08001544 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001545 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1546 str( numIntents )
1547 if numMult:
1548 cmd += " " + str( numMult )
1549 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001550 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001551 if appId:
1552 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001553 handle = self.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001554 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1555 handle = ansiEscape.sub( '', handle )
andrewonlab87852b02014-11-19 18:44:19 -05001556 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001557 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001558 main.log.info( handle )
1559 # Split result by newline
1560 newline = handle.split( "\r\r\n" )
1561 # Ignore the first object of list, which is empty
1562 newline = newline[ 1: ]
1563 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001564 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001565 result = result.split( ": " )
1566 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001567 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1568 main.log.info( latResult )
1569 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001570 else:
1571 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001572 except TypeError:
1573 main.log.exception( self.name + ": Object not as expected" )
1574 return None
andrewonlab87852b02014-11-19 18:44:19 -05001575 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001576 main.log.error( self.name + ": EOF exception found" )
1577 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001578 main.cleanup()
1579 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001580 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001581 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001582 main.cleanup()
1583 main.exit()
1584
kelvin-onlabd3b64892015-01-20 13:26:24 -08001585 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001586 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001587 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001588 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001589 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001590 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001591 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001592 if jsonFormat:
1593 cmdStr = "intents-events-metrics -j"
1594 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001595 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001596 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1597 handle = ansiEscape.sub( '', handle )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001598 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001599 cmdStr = "intents-events-metrics"
1600 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001601 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001602 except TypeError:
1603 main.log.exception( self.name + ": Object not as expected" )
1604 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001605 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001606 main.log.error( self.name + ": EOF exception found" )
1607 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001608 main.cleanup()
1609 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001610 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001611 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001612 main.cleanup()
1613 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001614
kelvin-onlabd3b64892015-01-20 13:26:24 -08001615 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001616 """
1617 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001618 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001619 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001620 """
andrewonlab867212a2014-10-22 20:13:38 -04001621 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001622 if jsonFormat:
1623 cmdStr = "topology-events-metrics -j"
1624 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001625 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001626 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1627 handle = ansiEscape.sub( '', handle )
andrewonlab867212a2014-10-22 20:13:38 -04001628 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001629 cmdStr = "topology-events-metrics"
1630 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07001631 if handle:
1632 return handle
1633 else:
Jon Hallbe379602015-03-24 13:39:32 -07001634 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07001635 return '{}'
Jon Halld4d4b372015-01-28 16:02:41 -08001636 except TypeError:
1637 main.log.exception( self.name + ": Object not as expected" )
1638 return None
andrewonlab867212a2014-10-22 20:13:38 -04001639 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001640 main.log.error( self.name + ": EOF exception found" )
1641 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001642 main.cleanup()
1643 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001644 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001645 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001646 main.cleanup()
1647 main.exit()
1648
kelvin8ec71442015-01-15 16:57:00 -08001649 # Wrapper functions ****************
1650 # Wrapper functions use existing driver
1651 # functions and extends their use case.
1652 # For example, we may use the output of
1653 # a normal driver function, and parse it
1654 # using a wrapper function
andrewonlab7e4d2d32014-10-15 13:23:21 -04001655
kelvin-onlabd3b64892015-01-20 13:26:24 -08001656 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001657 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001658 Description:
1659 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001660 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001661 try:
kelvin8ec71442015-01-15 16:57:00 -08001662 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08001663 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08001664 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001665
kelvin8ec71442015-01-15 16:57:00 -08001666 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001667 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1668 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08001669 match = re.search('id=0x([\da-f]+),', intents)
1670 if match:
1671 tmpId = match.group()[3:-1]
1672 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001673 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001674
Jon Halld4d4b372015-01-28 16:02:41 -08001675 except TypeError:
1676 main.log.exception( self.name + ": Object not as expected" )
1677 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001678 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001679 main.log.error( self.name + ": EOF exception found" )
1680 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001681 main.cleanup()
1682 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001683 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001684 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001685 main.cleanup()
1686 main.exit()
1687
Jon Hall30b82fa2015-03-04 17:15:43 -08001688 def FlowAddedCount( self, deviceId ):
1689 """
1690 Determine the number of flow rules for the given device id that are
1691 in the added state
1692 """
1693 try:
1694 cmdStr = "flows any " + str( deviceId ) + " | " +\
1695 "grep 'state=ADDED' | wc -l"
1696 handle = self.sendline( cmdStr )
1697 return handle
1698 except pexpect.EOF:
1699 main.log.error( self.name + ": EOF exception found" )
1700 main.log.error( self.name + ": " + self.handle.before )
1701 main.cleanup()
1702 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001703 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08001704 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001705 main.cleanup()
1706 main.exit()
1707
kelvin-onlabd3b64892015-01-20 13:26:24 -08001708 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001709 """
andrewonlab95ce8322014-10-13 14:12:04 -04001710 Use 'devices' function to obtain list of all devices
1711 and parse the result to obtain a list of all device
1712 id's. Returns this list. Returns empty list if no
1713 devices exist
kelvin8ec71442015-01-15 16:57:00 -08001714 List is ordered sequentially
1715
andrewonlab95ce8322014-10-13 14:12:04 -04001716 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08001717 device id, and wish to execute other commands using
andrewonlab95ce8322014-10-13 14:12:04 -04001718 the ids. By obtaining the list of device ids on the fly,
1719 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08001720 """
andrewonlab95ce8322014-10-13 14:12:04 -04001721 try:
kelvin8ec71442015-01-15 16:57:00 -08001722 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08001723 devicesStr = self.devices( jsonFormat=False )
1724 idList = []
kelvin8ec71442015-01-15 16:57:00 -08001725
kelvin-onlabd3b64892015-01-20 13:26:24 -08001726 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08001727 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001728 return idList
kelvin8ec71442015-01-15 16:57:00 -08001729
1730 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001731 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08001732 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08001733 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08001734 # Split list further into arguments before and after string
1735 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08001736 # append to idList
1737 for arg in tempList:
1738 idList.append( arg.split( "id=" )[ 1 ] )
1739 return idList
andrewonlab95ce8322014-10-13 14:12:04 -04001740
Jon Halld4d4b372015-01-28 16:02:41 -08001741 except TypeError:
1742 main.log.exception( self.name + ": Object not as expected" )
1743 return None
andrewonlab95ce8322014-10-13 14:12:04 -04001744 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001745 main.log.error( self.name + ": EOF exception found" )
1746 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -04001747 main.cleanup()
1748 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001749 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001750 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04001751 main.cleanup()
1752 main.exit()
1753
kelvin-onlabd3b64892015-01-20 13:26:24 -08001754 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001755 """
andrewonlab7c211572014-10-15 16:45:20 -04001756 Uses 'nodes' function to obtain list of all nodes
1757 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08001758 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04001759 Returns:
1760 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08001761 """
andrewonlab7c211572014-10-15 16:45:20 -04001762 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07001763 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001764 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07001765 # Sample nodesStr output
1766 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08001767 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08001768 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001769 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07001770 nodesJson = json.loads( nodesStr )
1771 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001772 return idList
kelvin8ec71442015-01-15 16:57:00 -08001773
Jon Halld4d4b372015-01-28 16:02:41 -08001774 except TypeError:
1775 main.log.exception( self.name + ": Object not as expected" )
1776 return None
andrewonlab7c211572014-10-15 16:45:20 -04001777 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001778 main.log.error( self.name + ": EOF exception found" )
1779 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04001780 main.cleanup()
1781 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001782 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001783 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04001784 main.cleanup()
1785 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -04001786
kelvin-onlabd3b64892015-01-20 13:26:24 -08001787 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08001788 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001789 Return the first device from the devices api whose 'id' contains 'dpid'
1790 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001791 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001792 try:
kelvin8ec71442015-01-15 16:57:00 -08001793 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04001794 return None
1795 else:
kelvin8ec71442015-01-15 16:57:00 -08001796 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001797 rawDevices = self.devices()
1798 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08001799 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001800 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08001801 # print "%s in %s?" % ( dpid, device[ 'id' ] )
1802 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04001803 return device
1804 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001805 except TypeError:
1806 main.log.exception( self.name + ": Object not as expected" )
1807 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04001808 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001809 main.log.error( self.name + ": EOF exception found" )
1810 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04001811 main.cleanup()
1812 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001813 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001814 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04001815 main.cleanup()
1816 main.exit()
1817
kelvin-onlabd3b64892015-01-20 13:26:24 -08001818 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001819 """
Jon Hallefbd9792015-03-05 16:11:36 -08001820 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001821 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001822 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08001823
Jon Hall42db6dc2014-10-24 19:03:48 -04001824 Params: ip = ip used for the onos cli
1825 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001826 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001827 logLevel = level to log to. Currently accepts
1828 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04001829
1830
kelvin-onlabd3b64892015-01-20 13:26:24 -08001831 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04001832
Jon Hallefbd9792015-03-05 16:11:36 -08001833 Returns: main.TRUE if the number of switches and links are correct,
1834 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04001835 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001836 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001837 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001838 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04001839 if topology == {}:
1840 return main.ERROR
1841 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001842 # Is the number of switches is what we expected
1843 devices = topology.get( 'devices', False )
1844 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08001845 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04001846 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001847 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001848 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001849 linkCheck = ( int( links ) == int( numolink ) )
1850 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08001851 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08001852 output += "The number of links and switches match " +\
1853 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001854 result = main.TRUE
1855 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001856 output += "The number of links and switches does not match " +\
1857 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001858 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001859 output = output + "\n ONOS sees %i devices (%i expected) \
1860 and %i links (%i expected)" % (
1861 int( devices ), int( numoswitch ), int( links ),
1862 int( numolink ) )
1863 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001864 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001865 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001866 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04001867 else:
kelvin8ec71442015-01-15 16:57:00 -08001868 main.log.info( output )
1869 return result
Jon Halld4d4b372015-01-28 16:02:41 -08001870 except TypeError:
1871 main.log.exception( self.name + ": Object not as expected" )
1872 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001873 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001874 main.log.error( self.name + ": EOF exception found" )
1875 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001876 main.cleanup()
1877 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001878 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001879 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001880 main.cleanup()
1881 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001882
kelvin-onlabd3b64892015-01-20 13:26:24 -08001883 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08001884 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001885 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001886 deviceId must be the id of a device as seen in the onos devices command
1887 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04001888 role must be either master, standby, or none
1889
Jon Halle3f39ff2015-01-13 11:50:53 -08001890 Returns:
1891 main.TRUE or main.FALSE based on argument verification and
1892 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001893 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001894 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001895 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04001896 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08001897 cmdStr = "device-role " +\
1898 str( deviceId ) + " " +\
1899 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001900 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001901 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001902 if re.search( "Error", handle ):
1903 # end color output to escape any colours
1904 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08001905 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001906 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08001907 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08001908 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04001909 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001910 main.log.error( "Invalid 'role' given to device_role(). " +
1911 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04001912 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001913 except TypeError:
1914 main.log.exception( self.name + ": Object not as expected" )
1915 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04001916 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001917 main.log.error( self.name + ": EOF exception found" )
1918 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04001919 main.cleanup()
1920 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001921 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001922 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04001923 main.cleanup()
1924 main.exit()
1925
kelvin-onlabd3b64892015-01-20 13:26:24 -08001926 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001927 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001928 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08001929 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001930 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001931 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001932 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001933 if jsonFormat:
1934 cmdStr = "clusters -j"
1935 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001936 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001937 handle variable here contains some ANSI escape color code
1938 sequences at the end which are invisible in the print command
Jon Halle3f39ff2015-01-13 11:50:53 -08001939 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -08001940 function. The repr( handle ) output when printed shows the ANSI
1941 escape sequences. In json.loads( somestring ), this somestring
kelvin-onlabd3b64892015-01-20 13:26:24 -08001942 variable is actually repr( somestring ) and json.loads would
1943 fail with the escape sequence. So we take off that escape
1944 sequence using:
Jon Halle3f39ff2015-01-13 11:50:53 -08001945
kelvin-onlabd3b64892015-01-20 13:26:24 -08001946 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1947 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001948 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001949 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1950 handle1 = ansiEscape.sub( '', handle )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001951 return handle1
1952 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001953 cmdStr = "clusters"
1954 handle = self.sendline( cmdStr )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001955 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001956 except TypeError:
1957 main.log.exception( self.name + ": Object not as expected" )
1958 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08001959 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001960 main.log.error( self.name + ": EOF exception found" )
1961 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001962 main.cleanup()
1963 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001964 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001965 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001966 main.cleanup()
1967 main.exit()
1968
kelvin-onlabd3b64892015-01-20 13:26:24 -08001969 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001970 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001971 CLI command to get the current leader for the Election test application
1972 NOTE: Requires installation of the onos-app-election feature
1973 Returns: Node IP of the leader if one exists
1974 None if none exists
1975 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001976 """
Jon Hall94fd0472014-12-08 11:52:42 -08001977 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001978 cmdStr = "election-test-leader"
1979 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001980 # Leader
1981 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001982 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08001983 nodeSearch = re.search( leaderPattern, response )
1984 if nodeSearch:
1985 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08001986 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001987 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08001988 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08001989 # no leader
1990 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001991 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001992 nullSearch = re.search( nullPattern, response )
1993 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08001994 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001995 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08001996 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08001997 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001998 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08001999 if re.search( errorPattern, response ):
2000 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002001 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002002 return main.FALSE
2003 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002004 main.log.error( "Error in election_test_leader: " +
2005 "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002006 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002007 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002008 except TypeError:
2009 main.log.exception( self.name + ": Object not as expected" )
2010 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002011 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002012 main.log.error( self.name + ": EOF exception found" )
2013 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002014 main.cleanup()
2015 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002016 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002017 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002018 main.cleanup()
2019 main.exit()
2020
kelvin-onlabd3b64892015-01-20 13:26:24 -08002021 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002022 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002023 CLI command to run for leadership of the Election test application.
2024 NOTE: Requires installation of the onos-app-election feature
2025 Returns: Main.TRUE on success
2026 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002027 """
Jon Hall94fd0472014-12-08 11:52:42 -08002028 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002029 cmdStr = "election-test-run"
2030 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002031 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002032 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002033 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002034 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002035 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002036 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002037 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002038 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002039 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002040 errorPattern = "Command\snot\sfound"
2041 if re.search( errorPattern, response ):
2042 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002043 return main.FALSE
2044 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002045 main.log.error( "Error in election_test_run: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002046 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002047 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002048 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002049 except TypeError:
2050 main.log.exception( self.name + ": Object not as expected" )
2051 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002052 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002053 main.log.error( self.name + ": EOF exception found" )
2054 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002055 main.cleanup()
2056 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002057 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002058 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002059 main.cleanup()
2060 main.exit()
2061
kelvin-onlabd3b64892015-01-20 13:26:24 -08002062 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002063 """
Jon Hall94fd0472014-12-08 11:52:42 -08002064 * CLI command to withdraw the local node from leadership election for
2065 * the Election test application.
2066 #NOTE: Requires installation of the onos-app-election feature
2067 Returns: Main.TRUE on success
2068 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002069 """
Jon Hall94fd0472014-12-08 11:52:42 -08002070 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002071 cmdStr = "election-test-withdraw"
2072 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002073 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002074 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002075 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002076 if re.search( successPattern, response ):
2077 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002078 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002079 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002080 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002081 errorPattern = "Command\snot\sfound"
2082 if re.search( errorPattern, response ):
2083 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002084 return main.FALSE
2085 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002086 main.log.error( "Error in election_test_withdraw: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002087 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002088 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002089 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002090 except TypeError:
2091 main.log.exception( self.name + ": Object not as expected" )
2092 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002093 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002094 main.log.error( self.name + ": EOF exception found" )
2095 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002096 main.cleanup()
2097 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002098 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002099 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002100 main.cleanup()
2101 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002102
kelvin8ec71442015-01-15 16:57:00 -08002103 def getDevicePortsEnabledCount( self, dpid ):
2104 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002105 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002106 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002107 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002108 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002109 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2110 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002111 if re.search( "No such device", output ):
2112 main.log.error( "Error in getting ports" )
2113 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002114 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002115 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002116 except TypeError:
2117 main.log.exception( self.name + ": Object not as expected" )
2118 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002119 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002120 main.log.error( self.name + ": EOF exception found" )
2121 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002122 main.cleanup()
2123 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002124 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002125 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002126 main.cleanup()
2127 main.exit()
2128
kelvin8ec71442015-01-15 16:57:00 -08002129 def getDeviceLinksActiveCount( self, dpid ):
2130 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002131 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002132 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002133 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002134 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002135 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2136 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002137 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002138 main.log.error( "Error in getting ports " )
2139 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002140 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002141 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002142 except TypeError:
2143 main.log.exception( self.name + ": Object not as expected" )
2144 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002145 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002146 main.log.error( self.name + ": EOF exception found" )
2147 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002148 main.cleanup()
2149 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002150 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002151 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002152 main.cleanup()
2153 main.exit()
2154
kelvin8ec71442015-01-15 16:57:00 -08002155 def getAllIntentIds( self ):
2156 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002157 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002158 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002159 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002160 cmdStr = "onos:intents | grep id="
2161 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002162 if re.search( "Error", output ):
2163 main.log.error( "Error in getting ports" )
2164 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002165 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002166 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002167 except TypeError:
2168 main.log.exception( self.name + ": Object not as expected" )
2169 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002170 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002171 main.log.error( self.name + ": EOF exception found" )
2172 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002173 main.cleanup()
2174 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002175 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002176 main.log.exception( self.name + ": Uncaught exception!" )
2177 main.cleanup()
2178 main.exit()
2179
Jon Hall73509952015-02-24 16:42:56 -08002180 def intentSummary( self ):
2181 """
Jon Hallefbd9792015-03-05 16:11:36 -08002182 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002183 """
2184 try:
2185 intents = self.intents( )
2186 intentStates = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002187 for intent in json.loads( intents ):
Jon Hall73509952015-02-24 16:42:56 -08002188 intentStates.append( intent.get( 'state', None ) )
Jon Hall63604932015-02-26 17:09:50 -08002189 out = [ (i, intentStates.count( i ) ) for i in set( intentStates ) ]
2190 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002191 return dict( out )
2192 except TypeError:
2193 main.log.exception( self.name + ": Object not as expected" )
2194 return None
2195 except pexpect.EOF:
2196 main.log.error( self.name + ": EOF exception found" )
2197 main.log.error( self.name + ": " + self.handle.before )
2198 main.cleanup()
2199 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002200 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002201 main.log.exception( self.name + ": Uncaught exception!" )
2202 main.cleanup()
2203 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002204
Jon Hall61282e32015-03-19 11:34:11 -07002205 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002206 """
2207 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002208 Optional argument:
2209 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002210 """
2211 # FIXME: add json output
Jon Hall61282e32015-03-19 11:34:11 -07002212 # Sample JSON
2213 # {
2214 # "electedTime": "13m ago",
2215 # "epoch": 4,
2216 # "leader": "10.128.30.17",
2217 # "topic": "intent-partition-3"
2218 # },
Jon Hall63604932015-02-26 17:09:50 -08002219 try:
Jon Hall61282e32015-03-19 11:34:11 -07002220 if jsonFormat:
2221 cmdStr = "onos:leaders -j"
2222 output = self.sendline( cmdStr )
2223 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2224 cleanedOutput = ansiEscape.sub( '', output )
2225 return cleanedOutput
2226 else:
2227 cmdStr = "onos:leaders"
2228 output = self.sendline( cmdStr )
2229 return output
Jon Hall63604932015-02-26 17:09:50 -08002230 except TypeError:
2231 main.log.exception( self.name + ": Object not as expected" )
2232 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002233 except pexpect.EOF:
2234 main.log.error( self.name + ": EOF exception found" )
2235 main.log.error( self.name + ": " + self.handle.before )
2236 main.cleanup()
2237 main.exit()
2238 except:
Jon Hall63604932015-02-26 17:09:50 -08002239 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002240 main.cleanup()
2241 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002242
Jon Hall61282e32015-03-19 11:34:11 -07002243 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002244 """
2245 Returns the output of the intent Pending map.
2246 """
Jon Hall63604932015-02-26 17:09:50 -08002247 try:
Jon Hall61282e32015-03-19 11:34:11 -07002248 if jsonFormat:
2249 cmdStr = "onos:intents -p -j"
2250 output = self.sendline( cmdStr )
2251 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2252 cleanedOutput = ansiEscape.sub( '', output )
2253 return cleanedOutput
2254 else:
2255 cmdStr = "onos:intents -p"
2256 output = self.sendline( cmdStr )
2257 return output
Jon Hall63604932015-02-26 17:09:50 -08002258 except TypeError:
2259 main.log.exception( self.name + ": Object not as expected" )
2260 return None
2261 except pexpect.EOF:
2262 main.log.error( self.name + ": EOF exception found" )
2263 main.log.error( self.name + ": " + self.handle.before )
2264 main.cleanup()
2265 main.exit()
2266 except:
2267 main.log.exception( self.name + ": Uncaught exception!" )
2268 main.cleanup()
2269 main.exit()
2270
Jon Hall61282e32015-03-19 11:34:11 -07002271 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002272 """
2273 Returns the output of the raft partitions command for ONOS.
2274 """
Jon Hall61282e32015-03-19 11:34:11 -07002275 # Sample JSON
2276 # {
2277 # "leader": "tcp://10.128.30.11:7238",
2278 # "members": [
2279 # "tcp://10.128.30.11:7238",
2280 # "tcp://10.128.30.17:7238",
2281 # "tcp://10.128.30.13:7238",
2282 # ],
2283 # "name": "p1",
2284 # "term": 3
2285 # },
Jon Hall63604932015-02-26 17:09:50 -08002286 try:
Jon Hall61282e32015-03-19 11:34:11 -07002287 if jsonFormat:
2288 cmdStr = "onos:partitions -j"
2289 output = self.sendline( cmdStr )
2290 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2291 cleanedOutput = ansiEscape.sub( '', output )
2292 return cleanedOutput
2293 else:
2294 cmdStr = "onos:partitions"
2295 output = self.sendline( cmdStr )
2296 return output
Jon Hall63604932015-02-26 17:09:50 -08002297 except TypeError:
2298 main.log.exception( self.name + ": Object not as expected" )
2299 return None
2300 except pexpect.EOF:
2301 main.log.error( self.name + ": EOF exception found" )
2302 main.log.error( self.name + ": " + self.handle.before )
2303 main.cleanup()
2304 main.exit()
2305 except:
2306 main.log.exception( self.name + ": Uncaught exception!" )
2307 main.cleanup()
2308 main.exit()
2309
Jon Hallbe379602015-03-24 13:39:32 -07002310 def apps( self, jsonFormat=True ):
2311 """
2312 Returns the output of the apps command for ONOS. This command lists
2313 information about installed ONOS applications
2314 """
2315 # Sample JSON object
2316 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2317 # "description":"ONOS OpenFlow protocol southbound providers",
2318 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2319 # "features":"[onos-openflow]","state":"ACTIVE"}]
2320 try:
2321 if jsonFormat:
2322 cmdStr = "onos:apps -j"
2323 output = self.sendline( cmdStr )
2324 assert "Error executing command" not in output
2325 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2326 cleanedOutput = ansiEscape.sub( '', output )
2327 return cleanedOutput
2328 else:
2329 cmdStr = "onos:apps"
2330 output = self.sendline( cmdStr )
2331 assert "Error executing command" not in output
2332 return output
2333 # FIXME: look at specific exceptions/Errors
2334 except AssertionError:
2335 main.log.error( "Error in processing onos:app command: " +
2336 str( output ) )
2337 return None
2338 except TypeError:
2339 main.log.exception( self.name + ": Object not as expected" )
2340 return None
2341 except pexpect.EOF:
2342 main.log.error( self.name + ": EOF exception found" )
2343 main.log.error( self.name + ": " + self.handle.before )
2344 main.cleanup()
2345 main.exit()
2346 except:
2347 main.log.exception( self.name + ": Uncaught exception!" )
2348 main.cleanup()
2349 main.exit()
2350
Jon Hall146f1522015-03-24 15:33:24 -07002351 def appStatus( self, appName ):
2352 """
2353 Uses the onos:apps cli command to return the status of an application.
2354 Returns:
2355 "ACTIVE" - If app is installed and activated
2356 "INSTALLED" - If app is installed and deactivated
2357 "UNINSTALLED" - If app is not installed
2358 None - on error
2359 """
2360 # FIXME also use app-ids to see if an uninstalled app is registered?
2361 # FIXME "UNREGISTERED"?
2362 try:
2363 if not isinstance( appName, types.StringType ):
2364 main.log.error( self.name + ".appStatus(): appName must be" +
2365 " a string" )
2366 return None
2367 output = self.apps( jsonFormat=True )
2368 appsJson = json.loads( output )
2369 state = None
2370 for app in appsJson:
2371 if appName == app.get('name'):
2372 state = app.get('state')
2373 break
2374 if state == "ACTIVE" or state == "INSTALLED":
2375 return state
2376 elif state is None:
2377 return "UNINSTALLED"
2378 elif state:
2379 main.log.error( "Unexpected state from 'onos:apps': " +
2380 str( state ) )
2381 return state
2382 except TypeError:
2383 main.log.exception( self.name + ": Object not as expected" )
2384 return None
2385 except pexpect.EOF:
2386 main.log.error( self.name + ": EOF exception found" )
2387 main.log.error( self.name + ": " + self.handle.before )
2388 main.cleanup()
2389 main.exit()
2390 except:
2391 main.log.exception( self.name + ": Uncaught exception!" )
2392 main.cleanup()
2393 main.exit()
2394
Jon Hallbe379602015-03-24 13:39:32 -07002395 def app( self, appName, option ):
2396 """
2397 Interacts with the app command for ONOS. This command manages
2398 application inventory.
2399 """
Jon Hallbe379602015-03-24 13:39:32 -07002400 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002401 # Validate argument types
2402 valid = True
2403 if not isinstance( appName, types.StringType ):
2404 main.log.error( self.name + ".app(): appName must be a " +
2405 "string" )
2406 valid = False
2407 if not isinstance( option, types.StringType ):
2408 main.log.error( self.name + ".app(): option must be a string" )
2409 valid = False
2410 if not valid:
2411 return main.FALSE
2412 # Validate Option
2413 option = option.lower()
2414 # NOTE: Install may become a valid option
2415 if option == "activate":
2416 pass
2417 elif option == "deactivate":
2418 pass
2419 elif option == "uninstall":
2420 pass
2421 else:
2422 # Invalid option
2423 main.log.error( "The ONOS app command argument only takes " +
2424 "the values: (activate|deactivate|uninstall)" +
2425 "; was given '" + option + "'")
2426 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002427 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002428 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002429 if "Error executing command" in output:
2430 main.log.error( "Error in processing onos:app command: " +
2431 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002432 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002433 elif "No such application" in output:
2434 main.log.error( "The application '" + appName +
2435 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07002436 return main.FALSE
2437 elif "Command not found:" in output:
2438 main.log.error( "Error in processing onos:app command: " +
2439 str( output ) )
2440 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002441 elif "Unsupported command:" in output:
2442 main.log.error( "Incorrect command given to 'app': " +
2443 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002444 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07002445 # else: Command was successful
2446 main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002447 return main.TRUE
2448 except TypeError:
2449 main.log.exception( self.name + ": Object not as expected" )
2450 return main.ERROR
2451 except pexpect.EOF:
2452 main.log.error( self.name + ": EOF exception found" )
2453 main.log.error( self.name + ": " + self.handle.before )
2454 main.cleanup()
2455 main.exit()
2456 except:
2457 main.log.exception( self.name + ": Uncaught exception!" )
2458 main.cleanup()
2459 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07002460
Jon Hallbd16b922015-03-26 17:53:15 -07002461 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002462 """
2463 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002464 appName is the hierarchical app name, not the feature name
2465 If check is True, method will check the status of the app after the
2466 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002467 Returns main.TRUE if the command was successfully sent
2468 main.FALSE if the cli responded with an error or given
2469 incorrect input
2470 """
2471 try:
2472 if not isinstance( appName, types.StringType ):
2473 main.log.error( self.name + ".activateApp(): appName must be" +
2474 " a string" )
2475 return main.FALSE
2476 status = self.appStatus( appName )
2477 if status == "INSTALLED":
2478 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002479 if check and response == main.TRUE:
2480 for i in range(10): # try 10 times then give up
2481 # TODO: Check with Thomas about this delay
2482 status = self.appStatus( appName )
2483 if status == "ACTIVE":
2484 return main.TRUE
2485 else:
2486 time.sleep( 1 )
2487 return main.FALSE
2488 else: # not 'check' or command didn't succeed
2489 return response
Jon Hall146f1522015-03-24 15:33:24 -07002490 elif status == "ACTIVE":
2491 return main.TRUE
2492 elif status == "UNINSTALLED":
2493 main.log.error( self.name + ": Tried to activate the " +
2494 "application '" + appName + "' which is not " +
2495 "installed." )
2496 else:
2497 main.log.error( "Unexpected return value from appStatus: " +
2498 str( status ) )
2499 return main.ERROR
2500 except TypeError:
2501 main.log.exception( self.name + ": Object not as expected" )
2502 return main.ERROR
2503 except pexpect.EOF:
2504 main.log.error( self.name + ": EOF exception found" )
2505 main.log.error( self.name + ": " + self.handle.before )
2506 main.cleanup()
2507 main.exit()
2508 except:
2509 main.log.exception( self.name + ": Uncaught exception!" )
2510 main.cleanup()
2511 main.exit()
2512
Jon Hallbd16b922015-03-26 17:53:15 -07002513 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002514 """
2515 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002516 appName is the hierarchical app name, not the feature name
2517 If check is True, method will check the status of the app after the
2518 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002519 Returns main.TRUE if the command was successfully sent
2520 main.FALSE if the cli responded with an error or given
2521 incorrect input
2522 """
2523 try:
2524 if not isinstance( appName, types.StringType ):
2525 main.log.error( self.name + ".deactivateApp(): appName must " +
2526 "be a string" )
2527 return main.FALSE
2528 status = self.appStatus( appName )
2529 if status == "INSTALLED":
2530 return main.TRUE
2531 elif status == "ACTIVE":
2532 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002533 if check and response == main.TRUE:
2534 for i in range(10): # try 10 times then give up
2535 status = self.appStatus( appName )
2536 if status == "INSTALLED":
2537 return main.TRUE
2538 else:
2539 time.sleep( 1 )
2540 return main.FALSE
2541 else: # not check or command didn't succeed
2542 return response
Jon Hall146f1522015-03-24 15:33:24 -07002543 elif status == "UNINSTALLED":
2544 main.log.warn( self.name + ": Tried to deactivate the " +
2545 "application '" + appName + "' which is not " +
2546 "installed." )
2547 return main.TRUE
2548 else:
2549 main.log.error( "Unexpected return value from appStatus: " +
2550 str( status ) )
2551 return main.ERROR
2552 except TypeError:
2553 main.log.exception( self.name + ": Object not as expected" )
2554 return main.ERROR
2555 except pexpect.EOF:
2556 main.log.error( self.name + ": EOF exception found" )
2557 main.log.error( self.name + ": " + self.handle.before )
2558 main.cleanup()
2559 main.exit()
2560 except:
2561 main.log.exception( self.name + ": Uncaught exception!" )
2562 main.cleanup()
2563 main.exit()
2564
Jon Hallbd16b922015-03-26 17:53:15 -07002565 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002566 """
2567 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002568 appName is the hierarchical app name, not the feature name
2569 If check is True, method will check the status of the app after the
2570 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002571 Returns main.TRUE if the command was successfully sent
2572 main.FALSE if the cli responded with an error or given
2573 incorrect input
2574 """
2575 # TODO: check with Thomas about the state machine for apps
2576 try:
2577 if not isinstance( appName, types.StringType ):
2578 main.log.error( self.name + ".uninstallApp(): appName must " +
2579 "be a string" )
2580 return main.FALSE
2581 status = self.appStatus( appName )
2582 if status == "INSTALLED":
2583 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002584 if check and response == main.TRUE:
2585 for i in range(10): # try 10 times then give up
2586 status = self.appStatus( appName )
2587 if status == "UNINSTALLED":
2588 return main.TRUE
2589 else:
2590 time.sleep( 1 )
2591 return main.FALSE
2592 else: # not check or command didn't succeed
2593 return response
Jon Hall146f1522015-03-24 15:33:24 -07002594 elif status == "ACTIVE":
2595 main.log.warn( self.name + ": Tried to uninstall the " +
2596 "application '" + appName + "' which is " +
2597 "currently active." )
2598 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002599 if check and response == main.TRUE:
2600 for i in range(10): # try 10 times then give up
2601 status = self.appStatus( appName )
2602 if status == "UNINSTALLED":
2603 return main.TRUE
2604 else:
2605 time.sleep( 1 )
2606 return main.FALSE
2607 else: # not check or command didn't succeed
2608 return response
Jon Hall146f1522015-03-24 15:33:24 -07002609 elif status == "UNINSTALLED":
2610 return main.TRUE
2611 else:
2612 main.log.error( "Unexpected return value from appStatus: " +
2613 str( status ) )
2614 return main.ERROR
2615 except TypeError:
2616 main.log.exception( self.name + ": Object not as expected" )
2617 return main.ERROR
2618 except pexpect.EOF:
2619 main.log.error( self.name + ": EOF exception found" )
2620 main.log.error( self.name + ": " + self.handle.before )
2621 main.cleanup()
2622 main.exit()
2623 except:
2624 main.log.exception( self.name + ": Uncaught exception!" )
2625 main.cleanup()
2626 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07002627
2628 def appIDs( self, jsonFormat=True ):
2629 """
2630 Show the mappings between app id and app names given by the 'app-ids'
2631 cli command
2632 """
2633 try:
2634 cmdStr = "app-ids"
2635 if jsonFormat:
2636 cmdStr += " -j"
2637 output = self.sendline( cmdStr )
2638 assert "Error executing command" not in output
2639 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2640 cleanedOutput = ansiEscape.sub( '', output )
2641 return cleanedOutput
2642 else:
2643 output = self.sendline( cmdStr )
2644 assert "Error executing command" not in output
2645 return output
2646 except AssertionError:
2647 main.log.error( "Error in processing onos:app-ids command: " +
2648 str( output ) )
2649 return None
2650 except TypeError:
2651 main.log.exception( self.name + ": Object not as expected" )
2652 return None
2653 except pexpect.EOF:
2654 main.log.error( self.name + ": EOF exception found" )
2655 main.log.error( self.name + ": " + self.handle.before )
2656 main.cleanup()
2657 main.exit()
2658 except:
2659 main.log.exception( self.name + ": Uncaught exception!" )
2660 main.cleanup()
2661 main.exit()
2662
2663 def appToIDCheck( self ):
2664 """
2665 This method will check that each application's ID listed in 'apps' is
2666 the same as the ID listed in 'app-ids'. The check will also check that
2667 there are no duplicate IDs issued. Note that an app ID should be
2668 a globaly unique numerical identifier for app/app-like features. Once
2669 an ID is registered, the ID is never freed up so that if an app is
2670 reinstalled it will have the same ID.
2671
2672 Returns: main.TRUE if the check passes and
2673 main.FALSE if the check fails or
2674 main.ERROR if there is some error in processing the test
2675 """
2676 try:
2677 ids = json.loads( self.appIDs( jsonFormat=True ) )
2678 apps = json.loads( self.apps( jsonFormat=True ) )
2679 result = main.TRUE
2680 for app in apps:
2681 appID = app.get( 'id' )
2682 if appID is None:
2683 main.log.error( "Error parsing app: " + str( app ) )
2684 result = main.FALSE
2685 appName = app.get( 'name' )
2686 if appName is None:
2687 main.log.error( "Error parsing app: " + str( app ) )
2688 result = main.FALSE
2689 # get the entry in ids that has the same appID
2690 current = filter(lambda item: item[ 'id' ] == appID, ids)
2691 main.log.debug( "Comparing " + str( app ) + " to " +
2692 str( current ) )
2693 if not current: # if ids doesn't have this id
2694 result = main.FALSE
2695 main.log.error( "'app-ids' does not have the ID for " +
2696 str( appName ) + " that apps does." )
2697 elif len( current ) > 1:
2698 # there is more than one app with this ID
2699 result = main.FALSE
2700 # We will log this later in the method
2701 elif not current[0][ 'name' ] == appName:
2702 currentName = current[0][ 'name' ]
2703 result = main.FALSE
2704 main.log.error( "'app-ids' has " + str( currentName ) +
2705 " registered under id:" + str( appID ) +
2706 " but 'apps' has " + str( appName ) )
2707 else:
2708 pass # id and name match!
2709 # now make sure that app-ids has no duplicates
2710 idsList = []
2711 namesList = []
2712 for item in ids:
2713 idsList.append( item[ 'id' ] )
2714 namesList.append( item[ 'name' ] )
2715 if len( idsList ) != len( set( idsList ) ) or\
2716 len( namesList ) != len( set( namesList ) ):
2717 main.log.error( "'app-ids' has some duplicate entries: \n"
2718 + json.dumps( ids,
2719 sort_keys=True,
2720 indent=4,
2721 separators=( ',', ': ' ) ) )
2722 result = main.FALSE
2723 return result
2724 except ( ValueError, TypeError ):
2725 main.log.exception( self.name + ": Object not as expected" )
2726 return main.ERROR
2727 except pexpect.EOF:
2728 main.log.error( self.name + ": EOF exception found" )
2729 main.log.error( self.name + ": " + self.handle.before )
2730 main.cleanup()
2731 main.exit()
2732 except:
2733 main.log.exception( self.name + ": Uncaught exception!" )
2734 main.cleanup()
2735 main.exit()
2736