blob: d20d044dc36fc8b6f472a9252cf7f94b3c7f446c [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-onlabb9408212015-04-01 13:34:04 -07001315 match = re.search('id=0x([\da-f]+),', handle)
1316 if match:
1317 return match.group()[3:-1]
1318 else:
1319 main.log.error( "Error, intent ID not found" )
1320 return None
1321 except TypeError:
1322 main.log.exception( self.name + ": Object not as expected" )
1323 return None
1324 except pexpect.EOF:
1325 main.log.error( self.name + ": EOF exception found" )
1326 main.log.error( self.name + ": " + self.handle.before )
1327 main.cleanup()
1328 main.exit()
1329 except Exception:
1330 main.log.exception( self.name + ": Uncaught exception!" )
1331 main.cleanup()
1332 main.exit()
1333
1334 def addSinglepointToMultipointIntent(
1335 self,
1336 ingressDevice,
1337 egressDeviceList,
1338 portIngress="",
1339 portEgressList=None,
1340 ethType="",
1341 ethSrc="",
1342 ethDst="",
1343 bandwidth="",
1344 lambdaAlloc=False,
1345 ipProto="",
1346 ipSrc="",
1347 ipDst="",
1348 tcpSrc="",
1349 tcpDst="",
1350 setEthSrc="",
1351 setEthDst="" ):
1352 """
1353 Note:
1354 This function assumes the format of all egress devices
1355 is same. That is, all egress devices include port numbers
1356 with a "/" or all egress devices could specify device
1357 ids and port numbers seperately.
1358 Required:
1359 * EgressDeviceList: List of device ids of egress device
1360 ( Atleast 2 eress devices required in the list )
1361 * ingressDevice: device id of ingress device
1362 Optional:
1363 * ethType: specify ethType
1364 * ethSrc: specify ethSrc ( i.e. src mac addr )
1365 * ethDst: specify ethDst ( i.e. dst mac addr )
1366 * bandwidth: specify bandwidth capacity of link
1367 * lambdaAlloc: if True, intent will allocate lambda
1368 for the specified intent
1369 * ipProto: specify ip protocol
1370 * ipSrc: specify ip source address
1371 * ipDst: specify ip destination address
1372 * tcpSrc: specify tcp source port
1373 * tcpDst: specify tcp destination port
1374 * setEthSrc: action to Rewrite Source MAC Address
1375 * setEthDst: action to Rewrite Destination MAC Address
1376 Description:
1377 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1378 specifying device id's and optional fields
1379 Returns:
1380 A string of the intent id or None on error
1381
1382 NOTE: This function may change depending on the
1383 options developers provide for singlepoint-to-multipoint
1384 intent via cli
1385 """
1386 try:
1387 # If there are no optional arguments
1388 if not ethType and not ethSrc and not ethDst\
1389 and not bandwidth and not lambdaAlloc\
1390 and not ipProto and not ipSrc and not ipDst\
1391 and not tcpSrc and not tcpDst and not setEthSrc\
1392 and not setEthDst:
1393 cmd = "add-single-to-multi-intent"
1394
1395 else:
1396 cmd = "add-single-to-multi-intent"
1397
1398 if ethType:
1399 cmd += " --ethType " + str( ethType )
1400 if ethSrc:
1401 cmd += " --ethSrc " + str( ethSrc )
1402 if ethDst:
1403 cmd += " --ethDst " + str( ethDst )
1404 if bandwidth:
1405 cmd += " --bandwidth " + str( bandwidth )
1406 if lambdaAlloc:
1407 cmd += " --lambda "
1408 if ipProto:
1409 cmd += " --ipProto " + str( ipProto )
1410 if ipSrc:
1411 cmd += " --ipSrc " + str( ipSrc )
1412 if ipDst:
1413 cmd += " --ipDst " + str( ipDst )
1414 if tcpSrc:
1415 cmd += " --tcpSrc " + str( tcpSrc )
1416 if tcpDst:
1417 cmd += " --tcpDst " + str( tcpDst )
1418 if setEthSrc:
1419 cmd += " --setEthSrc " + str( setEthSrc )
1420 if setEthDst:
1421 cmd += " --setEthDst " + str( setEthDst )
1422
1423 # Check whether the user appended the port
1424 # or provided it as an input
1425
1426 if "/" in ingressDevice:
1427 cmd += " " + str( ingressDevice )
1428 else:
1429 if not portIngress:
1430 main.log.error( "You must specify " +
1431 "the Ingress port" )
1432 return main.FALSE
1433
1434 cmd += " " +\
1435 str( ingressDevice ) + "/" +\
1436 str( portIngress )
1437
1438 if portEgressList is None:
1439 for egressDevice in egressDeviceList:
1440 if "/" in egressDevice:
1441 cmd += " " + str( egressDevice )
1442 else:
1443 main.log.error( "You must specify " +
1444 "the egress port" )
1445 # TODO: perhaps more meaningful return
1446 return main.FALSE
1447 else:
1448 if len( egressDeviceList ) == len( portEgressList ):
1449 for egressDevice, portEgress in zip( egressDeviceList, portEgressList ):
1450 cmd += " " + \
1451 str( egressDevice ) + "/" +\
1452 str( portEgress )
1453
1454 print "cmd= ", cmd
1455 handle = self.sendline( cmd )
1456 # If error, return error message
1457 if re.search( "Error", handle ):
1458 main.log.error( "Error in adding singlepoint-to-multipoint " +
1459 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001460 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001461 else:
1462 match = re.search('id=0x([\da-f]+),', handle)
1463 if match:
1464 return match.group()[3:-1]
1465 else:
1466 main.log.error( "Error, intent ID not found" )
1467 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001468 except TypeError:
1469 main.log.exception( self.name + ": Object not as expected" )
1470 return None
shahshreyad0c80432014-12-04 16:56:05 -08001471 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001472 main.log.error( self.name + ": EOF exception found" )
1473 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001474 main.cleanup()
1475 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001476 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001477 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001478 main.cleanup()
1479 main.exit()
1480
Jon Hallefbd9792015-03-05 16:11:36 -08001481 def removeIntent( self, intentId, app='org.onosproject.cli',
1482 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001483 """
shahshreya1c818fc2015-02-26 13:44:08 -08001484 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001485 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001486 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001487 -p or --purge: Purge the intent from the store after removal
1488
Jon Halle3f39ff2015-01-13 11:50:53 -08001489 Returns:
1490 main.False on error and
1491 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001492 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001493 try:
shahshreya1c818fc2015-02-26 13:44:08 -08001494 cmdStr = "remove-intent "
1495 if purge:
1496 cmdStr += " -p"
1497 if sync:
1498 cmdStr += " -s"
1499
1500 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001501 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001502 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001503 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001504 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001505 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001506 # TODO: Should this be main.TRUE
1507 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001508 except TypeError:
1509 main.log.exception( self.name + ": Object not as expected" )
1510 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001511 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001512 main.log.error( self.name + ": EOF exception found" )
1513 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001514 main.cleanup()
1515 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001516 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001517 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001518 main.cleanup()
1519 main.exit()
1520
kelvin-onlabd3b64892015-01-20 13:26:24 -08001521 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001522 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001523 NOTE: This method should be used after installing application:
1524 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001525 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001526 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001527 Description:
1528 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001529 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001530 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001531 if jsonFormat:
1532 cmdStr = "routes -j"
1533 handleTmp = self.sendline( cmdStr )
1534 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1535 handle = ansiEscape.sub( '', handleTmp )
pingping-lin8b306ac2014-11-17 18:13:51 -08001536 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001537 cmdStr = "routes"
1538 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001539 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001540 except TypeError:
1541 main.log.exception( self.name + ": Object not as expected" )
1542 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001543 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001544 main.log.error( self.name + ": EOF exception found" )
1545 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001546 main.cleanup()
1547 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001548 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001549 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001550 main.cleanup()
1551 main.exit()
1552
kelvin-onlabd3b64892015-01-20 13:26:24 -08001553 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001554 """
andrewonlab377693f2014-10-21 16:00:30 -04001555 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001556 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001557 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001558 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001559 """
andrewonlabe6745342014-10-17 14:29:13 -04001560 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001561 if jsonFormat:
1562 cmdStr = "intents -j"
1563 handle = self.sendline( cmdStr )
1564 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1565 handle = ansiEscape.sub( '', handle )
kelvin8ec71442015-01-15 16:57:00 -08001566 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001567 cmdStr = "intents"
1568 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001569 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001570 except TypeError:
1571 main.log.exception( self.name + ": Object not as expected" )
1572 return None
andrewonlabe6745342014-10-17 14:29:13 -04001573 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001574 main.log.error( self.name + ": EOF exception found" )
1575 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001576 main.cleanup()
1577 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001578 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001579 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001580 main.cleanup()
1581 main.exit()
1582
kelvin-onlab54400a92015-02-26 18:05:51 -08001583 def getIntentState(self, intentsId, intentsJson=None):
1584 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001585 Check intent state.
1586 Accepts a single intent ID (string type) or a list of intent IDs.
1587 Returns the state(string type) of the id if a single intent ID is
1588 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001589 Returns a dictionary with intent IDs as the key and its
1590 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001591 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001592 intentId: intent ID (string type)
1593 intentsJson: parsed json object from the onos:intents api
1594 Returns:
1595 state = An intent's state- INSTALL,WITHDRAWN etc.
1596 stateDict = Dictionary of intent's state. intent ID as the keys and
1597 state as the values.
1598 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001599 try:
1600 state = "State is Undefined"
1601 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001602 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001603 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001604 intentsJsonTemp = json.loads( intentsJson )
1605 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001606 for intent in intentsJsonTemp:
1607 if intentsId == intent['id']:
1608 state = intent['state']
1609 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001610 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1611 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001612 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001613 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001614 dictList = []
kelvin-onlab54400a92015-02-26 18:05:51 -08001615 for ID in intentsId:
kelvin-onlab07dbd012015-03-04 16:29:39 -08001616 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001617 for intents in intentsJsonTemp:
1618 if ID == intents['id']:
kelvin-onlab07dbd012015-03-04 16:29:39 -08001619 stateDict['state'] = intents['state']
1620 stateDict['id'] = ID
Jon Hallefbd9792015-03-05 16:11:36 -08001621 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001622 break
Jon Hallefbd9792015-03-05 16:11:36 -08001623 if len( intentsId ) != len( dictList ):
1624 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001625 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001626 else:
1627 main.log.info("Invalid intents ID entry")
1628 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001629 except TypeError:
1630 main.log.exception( self.name + ": Object not as expected" )
1631 return None
1632 except pexpect.EOF:
1633 main.log.error( self.name + ": EOF exception found" )
1634 main.log.error( self.name + ": " + self.handle.before )
1635 main.cleanup()
1636 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001637 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001638 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001639 main.cleanup()
1640 main.exit()
1641
kelvin-onlabd3b64892015-01-20 13:26:24 -08001642 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001643 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001644 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001645 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001646 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001647 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001648 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001649 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001650 if jsonFormat:
1651 cmdStr = "flows -j"
1652 handle = self.sendline( cmdStr )
1653 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1654 handle = ansiEscape.sub( '', handle )
Shreya Shah0f01c812014-10-26 20:15:28 -04001655 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001656 cmdStr = "flows"
1657 handle = self.sendline( cmdStr )
Jon Hall61282e32015-03-19 11:34:11 -07001658 if re.search( "Error:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001659 main.log.error( self.name + ".flows() response: " +
1660 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001661 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001662 except TypeError:
1663 main.log.exception( self.name + ": Object not as expected" )
1664 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001665 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001666 main.log.error( self.name + ": EOF exception found" )
1667 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001668 main.cleanup()
1669 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001670 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001671 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001672 main.cleanup()
1673 main.exit()
1674
kelvin-onlabd3b64892015-01-20 13:26:24 -08001675 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08001676 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001677 """
andrewonlab87852b02014-11-19 18:44:19 -05001678 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001679 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001680 a specific point-to-point intent definition
1681 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001682 * dpidSrc: specify source dpid
1683 * dpidDst: specify destination dpid
1684 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001685 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001686 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001687 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001688 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001689 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001690 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001691 """
andrewonlab87852b02014-11-19 18:44:19 -05001692 try:
kelvin8ec71442015-01-15 16:57:00 -08001693 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001694 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1695 str( numIntents )
1696 if numMult:
1697 cmd += " " + str( numMult )
1698 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001699 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001700 if appId:
1701 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001702 handle = self.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001703 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1704 handle = ansiEscape.sub( '', handle )
andrewonlab87852b02014-11-19 18:44:19 -05001705 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001706 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001707 main.log.info( handle )
1708 # Split result by newline
1709 newline = handle.split( "\r\r\n" )
1710 # Ignore the first object of list, which is empty
1711 newline = newline[ 1: ]
1712 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001713 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001714 result = result.split( ": " )
1715 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001716 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1717 main.log.info( latResult )
1718 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001719 else:
1720 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001721 except TypeError:
1722 main.log.exception( self.name + ": Object not as expected" )
1723 return None
andrewonlab87852b02014-11-19 18:44:19 -05001724 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001725 main.log.error( self.name + ": EOF exception found" )
1726 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001727 main.cleanup()
1728 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001729 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001730 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001731 main.cleanup()
1732 main.exit()
1733
kelvin-onlabd3b64892015-01-20 13:26:24 -08001734 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001735 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001736 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001737 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001738 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001739 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001740 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001741 if jsonFormat:
1742 cmdStr = "intents-events-metrics -j"
1743 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001744 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001745 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1746 handle = ansiEscape.sub( '', handle )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001747 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001748 cmdStr = "intents-events-metrics"
1749 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001750 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001751 except TypeError:
1752 main.log.exception( self.name + ": Object not as expected" )
1753 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001754 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001755 main.log.error( self.name + ": EOF exception found" )
1756 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001757 main.cleanup()
1758 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001759 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001760 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001761 main.cleanup()
1762 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001763
kelvin-onlabd3b64892015-01-20 13:26:24 -08001764 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001765 """
1766 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001767 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001768 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001769 """
andrewonlab867212a2014-10-22 20:13:38 -04001770 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001771 if jsonFormat:
1772 cmdStr = "topology-events-metrics -j"
1773 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001774 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001775 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1776 handle = ansiEscape.sub( '', handle )
andrewonlab867212a2014-10-22 20:13:38 -04001777 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001778 cmdStr = "topology-events-metrics"
1779 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07001780 if handle:
1781 return handle
1782 else:
Jon Hallbe379602015-03-24 13:39:32 -07001783 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07001784 return '{}'
Jon Halld4d4b372015-01-28 16:02:41 -08001785 except TypeError:
1786 main.log.exception( self.name + ": Object not as expected" )
1787 return None
andrewonlab867212a2014-10-22 20:13:38 -04001788 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001789 main.log.error( self.name + ": EOF exception found" )
1790 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001791 main.cleanup()
1792 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001793 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001794 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001795 main.cleanup()
1796 main.exit()
1797
kelvin8ec71442015-01-15 16:57:00 -08001798 # Wrapper functions ****************
1799 # Wrapper functions use existing driver
1800 # functions and extends their use case.
1801 # For example, we may use the output of
1802 # a normal driver function, and parse it
1803 # using a wrapper function
andrewonlab7e4d2d32014-10-15 13:23:21 -04001804
kelvin-onlabd3b64892015-01-20 13:26:24 -08001805 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001806 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001807 Description:
1808 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001809 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001810 try:
kelvin8ec71442015-01-15 16:57:00 -08001811 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08001812 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08001813 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001814
kelvin8ec71442015-01-15 16:57:00 -08001815 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001816 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1817 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08001818 match = re.search('id=0x([\da-f]+),', intents)
1819 if match:
1820 tmpId = match.group()[3:-1]
1821 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001822 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001823
Jon Halld4d4b372015-01-28 16:02:41 -08001824 except TypeError:
1825 main.log.exception( self.name + ": Object not as expected" )
1826 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001827 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001828 main.log.error( self.name + ": EOF exception found" )
1829 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001830 main.cleanup()
1831 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001832 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001833 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001834 main.cleanup()
1835 main.exit()
1836
Jon Hall30b82fa2015-03-04 17:15:43 -08001837 def FlowAddedCount( self, deviceId ):
1838 """
1839 Determine the number of flow rules for the given device id that are
1840 in the added state
1841 """
1842 try:
1843 cmdStr = "flows any " + str( deviceId ) + " | " +\
1844 "grep 'state=ADDED' | wc -l"
1845 handle = self.sendline( cmdStr )
1846 return handle
1847 except pexpect.EOF:
1848 main.log.error( self.name + ": EOF exception found" )
1849 main.log.error( self.name + ": " + self.handle.before )
1850 main.cleanup()
1851 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001852 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08001853 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001854 main.cleanup()
1855 main.exit()
1856
kelvin-onlabd3b64892015-01-20 13:26:24 -08001857 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001858 """
andrewonlab95ce8322014-10-13 14:12:04 -04001859 Use 'devices' function to obtain list of all devices
1860 and parse the result to obtain a list of all device
1861 id's. Returns this list. Returns empty list if no
1862 devices exist
kelvin8ec71442015-01-15 16:57:00 -08001863 List is ordered sequentially
1864
andrewonlab95ce8322014-10-13 14:12:04 -04001865 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08001866 device id, and wish to execute other commands using
andrewonlab95ce8322014-10-13 14:12:04 -04001867 the ids. By obtaining the list of device ids on the fly,
1868 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08001869 """
andrewonlab95ce8322014-10-13 14:12:04 -04001870 try:
kelvin8ec71442015-01-15 16:57:00 -08001871 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08001872 devicesStr = self.devices( jsonFormat=False )
1873 idList = []
kelvin8ec71442015-01-15 16:57:00 -08001874
kelvin-onlabd3b64892015-01-20 13:26:24 -08001875 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08001876 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001877 return idList
kelvin8ec71442015-01-15 16:57:00 -08001878
1879 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001880 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08001881 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08001882 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08001883 # Split list further into arguments before and after string
1884 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08001885 # append to idList
1886 for arg in tempList:
1887 idList.append( arg.split( "id=" )[ 1 ] )
1888 return idList
andrewonlab95ce8322014-10-13 14:12:04 -04001889
Jon Halld4d4b372015-01-28 16:02:41 -08001890 except TypeError:
1891 main.log.exception( self.name + ": Object not as expected" )
1892 return None
andrewonlab95ce8322014-10-13 14:12:04 -04001893 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001894 main.log.error( self.name + ": EOF exception found" )
1895 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -04001896 main.cleanup()
1897 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001898 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001899 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04001900 main.cleanup()
1901 main.exit()
1902
kelvin-onlabd3b64892015-01-20 13:26:24 -08001903 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001904 """
andrewonlab7c211572014-10-15 16:45:20 -04001905 Uses 'nodes' function to obtain list of all nodes
1906 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08001907 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04001908 Returns:
1909 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08001910 """
andrewonlab7c211572014-10-15 16:45:20 -04001911 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07001912 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001913 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07001914 # Sample nodesStr output
1915 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08001916 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08001917 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001918 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07001919 nodesJson = json.loads( nodesStr )
1920 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001921 return idList
kelvin8ec71442015-01-15 16:57:00 -08001922
Jon Halld4d4b372015-01-28 16:02:41 -08001923 except TypeError:
1924 main.log.exception( self.name + ": Object not as expected" )
1925 return None
andrewonlab7c211572014-10-15 16:45:20 -04001926 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001927 main.log.error( self.name + ": EOF exception found" )
1928 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04001929 main.cleanup()
1930 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001931 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001932 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04001933 main.cleanup()
1934 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -04001935
kelvin-onlabd3b64892015-01-20 13:26:24 -08001936 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08001937 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001938 Return the first device from the devices api whose 'id' contains 'dpid'
1939 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001940 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001941 try:
kelvin8ec71442015-01-15 16:57:00 -08001942 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04001943 return None
1944 else:
kelvin8ec71442015-01-15 16:57:00 -08001945 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001946 rawDevices = self.devices()
1947 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08001948 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001949 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08001950 # print "%s in %s?" % ( dpid, device[ 'id' ] )
1951 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04001952 return device
1953 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001954 except TypeError:
1955 main.log.exception( self.name + ": Object not as expected" )
1956 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04001957 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001958 main.log.error( self.name + ": EOF exception found" )
1959 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04001960 main.cleanup()
1961 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001962 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001963 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04001964 main.cleanup()
1965 main.exit()
1966
kelvin-onlabd3b64892015-01-20 13:26:24 -08001967 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001968 """
Jon Hallefbd9792015-03-05 16:11:36 -08001969 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001970 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001971 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08001972
Jon Hall42db6dc2014-10-24 19:03:48 -04001973 Params: ip = ip used for the onos cli
1974 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001975 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001976 logLevel = level to log to. Currently accepts
1977 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04001978
1979
kelvin-onlabd3b64892015-01-20 13:26:24 -08001980 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04001981
Jon Hallefbd9792015-03-05 16:11:36 -08001982 Returns: main.TRUE if the number of switches and links are correct,
1983 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04001984 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001985 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001986 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001987 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04001988 if topology == {}:
1989 return main.ERROR
1990 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001991 # Is the number of switches is what we expected
1992 devices = topology.get( 'devices', False )
1993 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08001994 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04001995 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001996 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001997 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001998 linkCheck = ( int( links ) == int( numolink ) )
1999 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002000 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002001 output += "The number of links and switches match " +\
2002 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002003 result = main.TRUE
2004 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002005 output += "The number of links and switches does not match " +\
2006 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002007 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002008 output = output + "\n ONOS sees %i devices (%i expected) \
2009 and %i links (%i expected)" % (
2010 int( devices ), int( numoswitch ), int( links ),
2011 int( numolink ) )
2012 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002013 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002014 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002015 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002016 else:
kelvin8ec71442015-01-15 16:57:00 -08002017 main.log.info( output )
2018 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002019 except TypeError:
2020 main.log.exception( self.name + ": Object not as expected" )
2021 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002022 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002023 main.log.error( self.name + ": EOF exception found" )
2024 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002025 main.cleanup()
2026 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002027 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002028 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002029 main.cleanup()
2030 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002031
kelvin-onlabd3b64892015-01-20 13:26:24 -08002032 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002033 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002034 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002035 deviceId must be the id of a device as seen in the onos devices command
2036 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002037 role must be either master, standby, or none
2038
Jon Halle3f39ff2015-01-13 11:50:53 -08002039 Returns:
2040 main.TRUE or main.FALSE based on argument verification and
2041 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002042 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002043 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002044 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002045 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002046 cmdStr = "device-role " +\
2047 str( deviceId ) + " " +\
2048 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002049 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002050 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002051 if re.search( "Error", handle ):
2052 # end color output to escape any colours
2053 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002054 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002055 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002056 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002057 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002058 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002059 main.log.error( "Invalid 'role' given to device_role(). " +
2060 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002061 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002062 except TypeError:
2063 main.log.exception( self.name + ": Object not as expected" )
2064 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002065 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002066 main.log.error( self.name + ": EOF exception found" )
2067 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002068 main.cleanup()
2069 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002070 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002071 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002072 main.cleanup()
2073 main.exit()
2074
kelvin-onlabd3b64892015-01-20 13:26:24 -08002075 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002076 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002077 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002078 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002079 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002080 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002081 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002082 if jsonFormat:
2083 cmdStr = "clusters -j"
2084 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002085 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002086 handle variable here contains some ANSI escape color code
2087 sequences at the end which are invisible in the print command
Jon Halle3f39ff2015-01-13 11:50:53 -08002088 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -08002089 function. The repr( handle ) output when printed shows the ANSI
2090 escape sequences. In json.loads( somestring ), this somestring
kelvin-onlabd3b64892015-01-20 13:26:24 -08002091 variable is actually repr( somestring ) and json.loads would
2092 fail with the escape sequence. So we take off that escape
2093 sequence using:
Jon Halle3f39ff2015-01-13 11:50:53 -08002094
kelvin-onlabd3b64892015-01-20 13:26:24 -08002095 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2096 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002097 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08002098 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2099 handle1 = ansiEscape.sub( '', handle )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002100 return handle1
2101 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002102 cmdStr = "clusters"
2103 handle = self.sendline( cmdStr )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002104 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002105 except TypeError:
2106 main.log.exception( self.name + ": Object not as expected" )
2107 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002108 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002109 main.log.error( self.name + ": EOF exception found" )
2110 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002111 main.cleanup()
2112 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002113 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002114 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002115 main.cleanup()
2116 main.exit()
2117
kelvin-onlabd3b64892015-01-20 13:26:24 -08002118 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002119 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002120 CLI command to get the current leader for the Election test application
2121 NOTE: Requires installation of the onos-app-election feature
2122 Returns: Node IP of the leader if one exists
2123 None if none exists
2124 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002125 """
Jon Hall94fd0472014-12-08 11:52:42 -08002126 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002127 cmdStr = "election-test-leader"
2128 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002129 # Leader
2130 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002131 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002132 nodeSearch = re.search( leaderPattern, response )
2133 if nodeSearch:
2134 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002135 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002136 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002137 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002138 # no leader
2139 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002140 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002141 nullSearch = re.search( nullPattern, response )
2142 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002143 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002144 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002145 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002146 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002147 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002148 if re.search( errorPattern, response ):
2149 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002150 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002151 return main.FALSE
2152 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002153 main.log.error( "Error in election_test_leader: " +
2154 "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002155 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002156 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002157 except TypeError:
2158 main.log.exception( self.name + ": Object not as expected" )
2159 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002160 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002161 main.log.error( self.name + ": EOF exception found" )
2162 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002163 main.cleanup()
2164 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002165 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002166 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002167 main.cleanup()
2168 main.exit()
2169
kelvin-onlabd3b64892015-01-20 13:26:24 -08002170 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002171 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002172 CLI command to run for leadership of the Election test application.
2173 NOTE: Requires installation of the onos-app-election feature
2174 Returns: Main.TRUE on success
2175 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002176 """
Jon Hall94fd0472014-12-08 11:52:42 -08002177 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002178 cmdStr = "election-test-run"
2179 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002180 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002181 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002182 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002183 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002184 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002185 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002186 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002187 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002188 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002189 errorPattern = "Command\snot\sfound"
2190 if re.search( errorPattern, response ):
2191 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002192 return main.FALSE
2193 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002194 main.log.error( "Error in election_test_run: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002195 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002196 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002197 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002198 except TypeError:
2199 main.log.exception( self.name + ": Object not as expected" )
2200 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002201 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002202 main.log.error( self.name + ": EOF exception found" )
2203 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002204 main.cleanup()
2205 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002206 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002207 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002208 main.cleanup()
2209 main.exit()
2210
kelvin-onlabd3b64892015-01-20 13:26:24 -08002211 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002212 """
Jon Hall94fd0472014-12-08 11:52:42 -08002213 * CLI command to withdraw the local node from leadership election for
2214 * the Election test application.
2215 #NOTE: Requires installation of the onos-app-election feature
2216 Returns: Main.TRUE on success
2217 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002218 """
Jon Hall94fd0472014-12-08 11:52:42 -08002219 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002220 cmdStr = "election-test-withdraw"
2221 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002222 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002223 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002224 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002225 if re.search( successPattern, response ):
2226 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002227 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002228 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002229 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002230 errorPattern = "Command\snot\sfound"
2231 if re.search( errorPattern, response ):
2232 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002233 return main.FALSE
2234 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002235 main.log.error( "Error in election_test_withdraw: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002236 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002237 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002238 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002239 except TypeError:
2240 main.log.exception( self.name + ": Object not as expected" )
2241 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002242 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002243 main.log.error( self.name + ": EOF exception found" )
2244 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002245 main.cleanup()
2246 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002247 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002248 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002249 main.cleanup()
2250 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002251
kelvin8ec71442015-01-15 16:57:00 -08002252 def getDevicePortsEnabledCount( self, dpid ):
2253 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002254 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002255 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002256 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002257 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002258 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2259 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002260 if re.search( "No such device", output ):
2261 main.log.error( "Error in getting ports" )
2262 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002263 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002264 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002265 except TypeError:
2266 main.log.exception( self.name + ": Object not as expected" )
2267 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002268 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002269 main.log.error( self.name + ": EOF exception found" )
2270 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002271 main.cleanup()
2272 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002273 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002274 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002275 main.cleanup()
2276 main.exit()
2277
kelvin8ec71442015-01-15 16:57:00 -08002278 def getDeviceLinksActiveCount( self, dpid ):
2279 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002280 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002281 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002282 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002283 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002284 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2285 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002286 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002287 main.log.error( "Error in getting ports " )
2288 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002289 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002290 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002291 except TypeError:
2292 main.log.exception( self.name + ": Object not as expected" )
2293 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002294 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002295 main.log.error( self.name + ": EOF exception found" )
2296 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002297 main.cleanup()
2298 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002299 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002300 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002301 main.cleanup()
2302 main.exit()
2303
kelvin8ec71442015-01-15 16:57:00 -08002304 def getAllIntentIds( self ):
2305 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002306 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002307 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002308 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002309 cmdStr = "onos:intents | grep id="
2310 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002311 if re.search( "Error", output ):
2312 main.log.error( "Error in getting ports" )
2313 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002314 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002315 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002316 except TypeError:
2317 main.log.exception( self.name + ": Object not as expected" )
2318 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002319 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002320 main.log.error( self.name + ": EOF exception found" )
2321 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002322 main.cleanup()
2323 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002324 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002325 main.log.exception( self.name + ": Uncaught exception!" )
2326 main.cleanup()
2327 main.exit()
2328
Jon Hall73509952015-02-24 16:42:56 -08002329 def intentSummary( self ):
2330 """
Jon Hallefbd9792015-03-05 16:11:36 -08002331 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002332 """
2333 try:
2334 intents = self.intents( )
2335 intentStates = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002336 for intent in json.loads( intents ):
Jon Hall73509952015-02-24 16:42:56 -08002337 intentStates.append( intent.get( 'state', None ) )
Jon Hall63604932015-02-26 17:09:50 -08002338 out = [ (i, intentStates.count( i ) ) for i in set( intentStates ) ]
2339 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002340 return dict( out )
2341 except TypeError:
2342 main.log.exception( self.name + ": Object not as expected" )
2343 return None
2344 except pexpect.EOF:
2345 main.log.error( self.name + ": EOF exception found" )
2346 main.log.error( self.name + ": " + self.handle.before )
2347 main.cleanup()
2348 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002349 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002350 main.log.exception( self.name + ": Uncaught exception!" )
2351 main.cleanup()
2352 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002353
Jon Hall61282e32015-03-19 11:34:11 -07002354 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002355 """
2356 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002357 Optional argument:
2358 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002359 """
2360 # FIXME: add json output
Jon Hall61282e32015-03-19 11:34:11 -07002361 # Sample JSON
2362 # {
2363 # "electedTime": "13m ago",
2364 # "epoch": 4,
2365 # "leader": "10.128.30.17",
2366 # "topic": "intent-partition-3"
2367 # },
Jon Hall63604932015-02-26 17:09:50 -08002368 try:
Jon Hall61282e32015-03-19 11:34:11 -07002369 if jsonFormat:
2370 cmdStr = "onos:leaders -j"
2371 output = self.sendline( cmdStr )
2372 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2373 cleanedOutput = ansiEscape.sub( '', output )
2374 return cleanedOutput
2375 else:
2376 cmdStr = "onos:leaders"
2377 output = self.sendline( cmdStr )
2378 return output
Jon Hall63604932015-02-26 17:09:50 -08002379 except TypeError:
2380 main.log.exception( self.name + ": Object not as expected" )
2381 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002382 except pexpect.EOF:
2383 main.log.error( self.name + ": EOF exception found" )
2384 main.log.error( self.name + ": " + self.handle.before )
2385 main.cleanup()
2386 main.exit()
2387 except:
Jon Hall63604932015-02-26 17:09:50 -08002388 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002389 main.cleanup()
2390 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002391
Jon Hall61282e32015-03-19 11:34:11 -07002392 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002393 """
2394 Returns the output of the intent Pending map.
2395 """
Jon Hall63604932015-02-26 17:09:50 -08002396 try:
Jon Hall61282e32015-03-19 11:34:11 -07002397 if jsonFormat:
2398 cmdStr = "onos:intents -p -j"
2399 output = self.sendline( cmdStr )
2400 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2401 cleanedOutput = ansiEscape.sub( '', output )
2402 return cleanedOutput
2403 else:
2404 cmdStr = "onos:intents -p"
2405 output = self.sendline( cmdStr )
2406 return output
Jon Hall63604932015-02-26 17:09:50 -08002407 except TypeError:
2408 main.log.exception( self.name + ": Object not as expected" )
2409 return None
2410 except pexpect.EOF:
2411 main.log.error( self.name + ": EOF exception found" )
2412 main.log.error( self.name + ": " + self.handle.before )
2413 main.cleanup()
2414 main.exit()
2415 except:
2416 main.log.exception( self.name + ": Uncaught exception!" )
2417 main.cleanup()
2418 main.exit()
2419
Jon Hall61282e32015-03-19 11:34:11 -07002420 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002421 """
2422 Returns the output of the raft partitions command for ONOS.
2423 """
Jon Hall61282e32015-03-19 11:34:11 -07002424 # Sample JSON
2425 # {
2426 # "leader": "tcp://10.128.30.11:7238",
2427 # "members": [
2428 # "tcp://10.128.30.11:7238",
2429 # "tcp://10.128.30.17:7238",
2430 # "tcp://10.128.30.13:7238",
2431 # ],
2432 # "name": "p1",
2433 # "term": 3
2434 # },
Jon Hall63604932015-02-26 17:09:50 -08002435 try:
Jon Hall61282e32015-03-19 11:34:11 -07002436 if jsonFormat:
2437 cmdStr = "onos:partitions -j"
2438 output = self.sendline( cmdStr )
2439 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2440 cleanedOutput = ansiEscape.sub( '', output )
2441 return cleanedOutput
2442 else:
2443 cmdStr = "onos:partitions"
2444 output = self.sendline( cmdStr )
2445 return output
Jon Hall63604932015-02-26 17:09:50 -08002446 except TypeError:
2447 main.log.exception( self.name + ": Object not as expected" )
2448 return None
2449 except pexpect.EOF:
2450 main.log.error( self.name + ": EOF exception found" )
2451 main.log.error( self.name + ": " + self.handle.before )
2452 main.cleanup()
2453 main.exit()
2454 except:
2455 main.log.exception( self.name + ": Uncaught exception!" )
2456 main.cleanup()
2457 main.exit()
2458
Jon Hallbe379602015-03-24 13:39:32 -07002459 def apps( self, jsonFormat=True ):
2460 """
2461 Returns the output of the apps command for ONOS. This command lists
2462 information about installed ONOS applications
2463 """
2464 # Sample JSON object
2465 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2466 # "description":"ONOS OpenFlow protocol southbound providers",
2467 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2468 # "features":"[onos-openflow]","state":"ACTIVE"}]
2469 try:
2470 if jsonFormat:
2471 cmdStr = "onos:apps -j"
2472 output = self.sendline( cmdStr )
2473 assert "Error executing command" not in output
2474 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2475 cleanedOutput = ansiEscape.sub( '', output )
2476 return cleanedOutput
2477 else:
2478 cmdStr = "onos:apps"
2479 output = self.sendline( cmdStr )
2480 assert "Error executing command" not in output
2481 return output
2482 # FIXME: look at specific exceptions/Errors
2483 except AssertionError:
2484 main.log.error( "Error in processing onos:app command: " +
2485 str( output ) )
2486 return None
2487 except TypeError:
2488 main.log.exception( self.name + ": Object not as expected" )
2489 return None
2490 except pexpect.EOF:
2491 main.log.error( self.name + ": EOF exception found" )
2492 main.log.error( self.name + ": " + self.handle.before )
2493 main.cleanup()
2494 main.exit()
2495 except:
2496 main.log.exception( self.name + ": Uncaught exception!" )
2497 main.cleanup()
2498 main.exit()
2499
Jon Hall146f1522015-03-24 15:33:24 -07002500 def appStatus( self, appName ):
2501 """
2502 Uses the onos:apps cli command to return the status of an application.
2503 Returns:
2504 "ACTIVE" - If app is installed and activated
2505 "INSTALLED" - If app is installed and deactivated
2506 "UNINSTALLED" - If app is not installed
2507 None - on error
2508 """
Jon Hall146f1522015-03-24 15:33:24 -07002509 try:
2510 if not isinstance( appName, types.StringType ):
2511 main.log.error( self.name + ".appStatus(): appName must be" +
2512 " a string" )
2513 return None
2514 output = self.apps( jsonFormat=True )
2515 appsJson = json.loads( output )
2516 state = None
2517 for app in appsJson:
2518 if appName == app.get('name'):
2519 state = app.get('state')
2520 break
2521 if state == "ACTIVE" or state == "INSTALLED":
2522 return state
2523 elif state is None:
2524 return "UNINSTALLED"
2525 elif state:
2526 main.log.error( "Unexpected state from 'onos:apps': " +
2527 str( state ) )
2528 return state
2529 except TypeError:
2530 main.log.exception( self.name + ": Object not as expected" )
2531 return None
2532 except pexpect.EOF:
2533 main.log.error( self.name + ": EOF exception found" )
2534 main.log.error( self.name + ": " + self.handle.before )
2535 main.cleanup()
2536 main.exit()
2537 except:
2538 main.log.exception( self.name + ": Uncaught exception!" )
2539 main.cleanup()
2540 main.exit()
2541
Jon Hallbe379602015-03-24 13:39:32 -07002542 def app( self, appName, option ):
2543 """
2544 Interacts with the app command for ONOS. This command manages
2545 application inventory.
2546 """
Jon Hallbe379602015-03-24 13:39:32 -07002547 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002548 # Validate argument types
2549 valid = True
2550 if not isinstance( appName, types.StringType ):
2551 main.log.error( self.name + ".app(): appName must be a " +
2552 "string" )
2553 valid = False
2554 if not isinstance( option, types.StringType ):
2555 main.log.error( self.name + ".app(): option must be a string" )
2556 valid = False
2557 if not valid:
2558 return main.FALSE
2559 # Validate Option
2560 option = option.lower()
2561 # NOTE: Install may become a valid option
2562 if option == "activate":
2563 pass
2564 elif option == "deactivate":
2565 pass
2566 elif option == "uninstall":
2567 pass
2568 else:
2569 # Invalid option
2570 main.log.error( "The ONOS app command argument only takes " +
2571 "the values: (activate|deactivate|uninstall)" +
2572 "; was given '" + option + "'")
2573 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002574 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002575 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002576 if "Error executing command" in output:
2577 main.log.error( "Error in processing onos:app command: " +
2578 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002579 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002580 elif "No such application" in output:
2581 main.log.error( "The application '" + appName +
2582 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07002583 return main.FALSE
2584 elif "Command not found:" in output:
2585 main.log.error( "Error in processing onos:app command: " +
2586 str( output ) )
2587 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002588 elif "Unsupported command:" in output:
2589 main.log.error( "Incorrect command given to 'app': " +
2590 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002591 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07002592 # else: Command was successful
Jon Hall050e1bd2015-03-30 13:33:02 -07002593 #main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002594 return main.TRUE
2595 except TypeError:
2596 main.log.exception( self.name + ": Object not as expected" )
2597 return main.ERROR
2598 except pexpect.EOF:
2599 main.log.error( self.name + ": EOF exception found" )
2600 main.log.error( self.name + ": " + self.handle.before )
2601 main.cleanup()
2602 main.exit()
2603 except:
2604 main.log.exception( self.name + ": Uncaught exception!" )
2605 main.cleanup()
2606 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07002607
Jon Hallbd16b922015-03-26 17:53:15 -07002608 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002609 """
2610 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002611 appName is the hierarchical app name, not the feature name
2612 If check is True, method will check the status of the app after the
2613 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002614 Returns main.TRUE if the command was successfully sent
2615 main.FALSE if the cli responded with an error or given
2616 incorrect input
2617 """
2618 try:
2619 if not isinstance( appName, types.StringType ):
2620 main.log.error( self.name + ".activateApp(): appName must be" +
2621 " a string" )
2622 return main.FALSE
2623 status = self.appStatus( appName )
2624 if status == "INSTALLED":
2625 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002626 if check and response == main.TRUE:
2627 for i in range(10): # try 10 times then give up
2628 # TODO: Check with Thomas about this delay
2629 status = self.appStatus( appName )
2630 if status == "ACTIVE":
2631 return main.TRUE
2632 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07002633 main.log.debug( "The state of application " +
2634 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07002635 time.sleep( 1 )
2636 return main.FALSE
2637 else: # not 'check' or command didn't succeed
2638 return response
Jon Hall146f1522015-03-24 15:33:24 -07002639 elif status == "ACTIVE":
2640 return main.TRUE
2641 elif status == "UNINSTALLED":
2642 main.log.error( self.name + ": Tried to activate the " +
2643 "application '" + appName + "' which is not " +
2644 "installed." )
2645 else:
2646 main.log.error( "Unexpected return value from appStatus: " +
2647 str( status ) )
2648 return main.ERROR
2649 except TypeError:
2650 main.log.exception( self.name + ": Object not as expected" )
2651 return main.ERROR
2652 except pexpect.EOF:
2653 main.log.error( self.name + ": EOF exception found" )
2654 main.log.error( self.name + ": " + self.handle.before )
2655 main.cleanup()
2656 main.exit()
2657 except:
2658 main.log.exception( self.name + ": Uncaught exception!" )
2659 main.cleanup()
2660 main.exit()
2661
Jon Hallbd16b922015-03-26 17:53:15 -07002662 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002663 """
2664 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002665 appName is the hierarchical app name, not the feature name
2666 If check is True, method will check the status of the app after the
2667 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002668 Returns main.TRUE if the command was successfully sent
2669 main.FALSE if the cli responded with an error or given
2670 incorrect input
2671 """
2672 try:
2673 if not isinstance( appName, types.StringType ):
2674 main.log.error( self.name + ".deactivateApp(): appName must " +
2675 "be a string" )
2676 return main.FALSE
2677 status = self.appStatus( appName )
2678 if status == "INSTALLED":
2679 return main.TRUE
2680 elif status == "ACTIVE":
2681 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002682 if check and response == main.TRUE:
2683 for i in range(10): # try 10 times then give up
2684 status = self.appStatus( appName )
2685 if status == "INSTALLED":
2686 return main.TRUE
2687 else:
2688 time.sleep( 1 )
2689 return main.FALSE
2690 else: # not check or command didn't succeed
2691 return response
Jon Hall146f1522015-03-24 15:33:24 -07002692 elif status == "UNINSTALLED":
2693 main.log.warn( self.name + ": Tried to deactivate the " +
2694 "application '" + appName + "' which is not " +
2695 "installed." )
2696 return main.TRUE
2697 else:
2698 main.log.error( "Unexpected return value from appStatus: " +
2699 str( status ) )
2700 return main.ERROR
2701 except TypeError:
2702 main.log.exception( self.name + ": Object not as expected" )
2703 return main.ERROR
2704 except pexpect.EOF:
2705 main.log.error( self.name + ": EOF exception found" )
2706 main.log.error( self.name + ": " + self.handle.before )
2707 main.cleanup()
2708 main.exit()
2709 except:
2710 main.log.exception( self.name + ": Uncaught exception!" )
2711 main.cleanup()
2712 main.exit()
2713
Jon Hallbd16b922015-03-26 17:53:15 -07002714 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002715 """
2716 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002717 appName is the hierarchical app name, not the feature name
2718 If check is True, method will check the status of the app after the
2719 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002720 Returns main.TRUE if the command was successfully sent
2721 main.FALSE if the cli responded with an error or given
2722 incorrect input
2723 """
2724 # TODO: check with Thomas about the state machine for apps
2725 try:
2726 if not isinstance( appName, types.StringType ):
2727 main.log.error( self.name + ".uninstallApp(): appName must " +
2728 "be a string" )
2729 return main.FALSE
2730 status = self.appStatus( appName )
2731 if status == "INSTALLED":
2732 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002733 if check and response == main.TRUE:
2734 for i in range(10): # try 10 times then give up
2735 status = self.appStatus( appName )
2736 if status == "UNINSTALLED":
2737 return main.TRUE
2738 else:
2739 time.sleep( 1 )
2740 return main.FALSE
2741 else: # not check or command didn't succeed
2742 return response
Jon Hall146f1522015-03-24 15:33:24 -07002743 elif status == "ACTIVE":
2744 main.log.warn( self.name + ": Tried to uninstall the " +
2745 "application '" + appName + "' which is " +
2746 "currently active." )
2747 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002748 if check and response == main.TRUE:
2749 for i in range(10): # try 10 times then give up
2750 status = self.appStatus( appName )
2751 if status == "UNINSTALLED":
2752 return main.TRUE
2753 else:
2754 time.sleep( 1 )
2755 return main.FALSE
2756 else: # not check or command didn't succeed
2757 return response
Jon Hall146f1522015-03-24 15:33:24 -07002758 elif status == "UNINSTALLED":
2759 return main.TRUE
2760 else:
2761 main.log.error( "Unexpected return value from appStatus: " +
2762 str( status ) )
2763 return main.ERROR
2764 except TypeError:
2765 main.log.exception( self.name + ": Object not as expected" )
2766 return main.ERROR
2767 except pexpect.EOF:
2768 main.log.error( self.name + ": EOF exception found" )
2769 main.log.error( self.name + ": " + self.handle.before )
2770 main.cleanup()
2771 main.exit()
2772 except:
2773 main.log.exception( self.name + ": Uncaught exception!" )
2774 main.cleanup()
2775 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07002776
2777 def appIDs( self, jsonFormat=True ):
2778 """
2779 Show the mappings between app id and app names given by the 'app-ids'
2780 cli command
2781 """
2782 try:
2783 cmdStr = "app-ids"
2784 if jsonFormat:
2785 cmdStr += " -j"
2786 output = self.sendline( cmdStr )
2787 assert "Error executing command" not in output
2788 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2789 cleanedOutput = ansiEscape.sub( '', output )
2790 return cleanedOutput
2791 else:
2792 output = self.sendline( cmdStr )
2793 assert "Error executing command" not in output
2794 return output
2795 except AssertionError:
2796 main.log.error( "Error in processing onos:app-ids command: " +
2797 str( output ) )
2798 return None
2799 except TypeError:
2800 main.log.exception( self.name + ": Object not as expected" )
2801 return None
2802 except pexpect.EOF:
2803 main.log.error( self.name + ": EOF exception found" )
2804 main.log.error( self.name + ": " + self.handle.before )
2805 main.cleanup()
2806 main.exit()
2807 except:
2808 main.log.exception( self.name + ": Uncaught exception!" )
2809 main.cleanup()
2810 main.exit()
2811
2812 def appToIDCheck( self ):
2813 """
2814 This method will check that each application's ID listed in 'apps' is
2815 the same as the ID listed in 'app-ids'. The check will also check that
2816 there are no duplicate IDs issued. Note that an app ID should be
2817 a globaly unique numerical identifier for app/app-like features. Once
2818 an ID is registered, the ID is never freed up so that if an app is
2819 reinstalled it will have the same ID.
2820
2821 Returns: main.TRUE if the check passes and
2822 main.FALSE if the check fails or
2823 main.ERROR if there is some error in processing the test
2824 """
2825 try:
2826 ids = json.loads( self.appIDs( jsonFormat=True ) )
2827 apps = json.loads( self.apps( jsonFormat=True ) )
2828 result = main.TRUE
2829 for app in apps:
2830 appID = app.get( 'id' )
2831 if appID is None:
2832 main.log.error( "Error parsing app: " + str( app ) )
2833 result = main.FALSE
2834 appName = app.get( 'name' )
2835 if appName is None:
2836 main.log.error( "Error parsing app: " + str( app ) )
2837 result = main.FALSE
2838 # get the entry in ids that has the same appID
2839 current = filter(lambda item: item[ 'id' ] == appID, ids)
Jon Hall050e1bd2015-03-30 13:33:02 -07002840 # main.log.debug( "Comparing " + str( app ) + " to " +
2841 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07002842 if not current: # if ids doesn't have this id
2843 result = main.FALSE
2844 main.log.error( "'app-ids' does not have the ID for " +
2845 str( appName ) + " that apps does." )
2846 elif len( current ) > 1:
2847 # there is more than one app with this ID
2848 result = main.FALSE
2849 # We will log this later in the method
2850 elif not current[0][ 'name' ] == appName:
2851 currentName = current[0][ 'name' ]
2852 result = main.FALSE
2853 main.log.error( "'app-ids' has " + str( currentName ) +
2854 " registered under id:" + str( appID ) +
2855 " but 'apps' has " + str( appName ) )
2856 else:
2857 pass # id and name match!
2858 # now make sure that app-ids has no duplicates
2859 idsList = []
2860 namesList = []
2861 for item in ids:
2862 idsList.append( item[ 'id' ] )
2863 namesList.append( item[ 'name' ] )
2864 if len( idsList ) != len( set( idsList ) ) or\
2865 len( namesList ) != len( set( namesList ) ):
2866 main.log.error( "'app-ids' has some duplicate entries: \n"
2867 + json.dumps( ids,
2868 sort_keys=True,
2869 indent=4,
2870 separators=( ',', ': ' ) ) )
2871 result = main.FALSE
2872 return result
2873 except ( ValueError, TypeError ):
2874 main.log.exception( self.name + ": Object not as expected" )
2875 return main.ERROR
2876 except pexpect.EOF:
2877 main.log.error( self.name + ": EOF exception found" )
2878 main.log.error( self.name + ": " + self.handle.before )
2879 main.cleanup()
2880 main.exit()
2881 except:
2882 main.log.exception( self.name + ": Uncaught exception!" )
2883 main.cleanup()
2884 main.exit()
2885