blob: 946faffc9c9f89e1f7edb47e66df6afc6a5b46cf [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
kelvin8ec71442015-01-15 16:57:00 -080024sys.path.append( "../" )
andrewonlab95ce8322014-10-13 14:12:04 -040025from drivers.common.clidriver import CLI
26
andrewonlab95ce8322014-10-13 14:12:04 -040027
kelvin8ec71442015-01-15 16:57:00 -080028class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040029
kelvin8ec71442015-01-15 16:57:00 -080030 def __init__( self ):
31 """
32 Initialize client
33 """
Jon Hallefbd9792015-03-05 16:11:36 -080034 self.name = None
35 self.home = None
36 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080037 super( CLI, self ).__init__()
38
39 def connect( self, **connectargs ):
40 """
andrewonlab95ce8322014-10-13 14:12:04 -040041 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080042 """
andrewonlab95ce8322014-10-13 14:12:04 -040043 try:
44 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080045 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070046 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040047 for key in self.options:
48 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080049 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040050 break
kelvin-onlabfb521662015-02-27 09:52:40 -080051 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070052 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040053
kelvin8ec71442015-01-15 16:57:00 -080054 self.name = self.options[ 'name' ]
55 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080056 user_name=self.user_name,
57 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080058 port=self.port,
59 pwd=self.pwd,
60 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040061
kelvin8ec71442015-01-15 16:57:00 -080062 self.handle.sendline( "cd " + self.home )
63 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040064 if self.handle:
65 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080066 else:
67 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040068 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080069 except TypeError:
70 main.log.exception( self.name + ": Object not as expected" )
71 return None
andrewonlab95ce8322014-10-13 14:12:04 -040072 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080073 main.log.error( self.name + ": EOF exception found" )
74 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040075 main.cleanup()
76 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080077 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -080078 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -040079 main.cleanup()
80 main.exit()
81
kelvin8ec71442015-01-15 16:57:00 -080082 def disconnect( self ):
83 """
andrewonlab95ce8322014-10-13 14:12:04 -040084 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -080085 """
Jon Halld61331b2015-02-17 16:35:47 -080086 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -040087 try:
Jon Hall61282e32015-03-19 11:34:11 -070088 if self.handle:
89 i = self.logout()
90 if i == main.TRUE:
91 self.handle.sendline( "" )
92 self.handle.expect( "\$" )
93 self.handle.sendline( "exit" )
94 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -080095 except TypeError:
96 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -080097 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -040098 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080099 main.log.error( self.name + ": EOF exception found" )
100 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700101 except ValueError:
102 main.log.exception( "Exception in discconect of " + self.name )
103 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800104 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800105 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400106 response = main.FALSE
107 return response
108
kelvin8ec71442015-01-15 16:57:00 -0800109 def logout( self ):
110 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500111 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700112 Returns main.TRUE if exited CLI and
113 main.FALSE on timeout (not guranteed you are disconnected)
114 None on TypeError
115 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800116 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500117 try:
Jon Hall61282e32015-03-19 11:34:11 -0700118 if self.handle:
119 self.handle.sendline( "" )
120 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
121 timeout=10 )
122 if i == 0: # In ONOS CLI
123 self.handle.sendline( "logout" )
124 self.handle.expect( "\$" )
125 return main.TRUE
126 elif i == 1: # not in CLI
127 return main.TRUE
128 elif i == 3: # Timeout
129 return main.FALSE
130 else:
andrewonlab9627f432014-11-14 12:45:10 -0500131 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800132 except TypeError:
133 main.log.exception( self.name + ": Object not as expected" )
134 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500135 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800136 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700137 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500138 main.cleanup()
139 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700140 except ValueError:
141 main.log.error( self.name + "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800142 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800143 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500144 main.cleanup()
145 main.exit()
146
kelvin-onlabd3b64892015-01-20 13:26:24 -0800147 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800148 """
andrewonlab95ce8322014-10-13 14:12:04 -0400149 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800150
andrewonlab95ce8322014-10-13 14:12:04 -0400151 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800152 """
andrewonlab95ce8322014-10-13 14:12:04 -0400153 try:
154 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800155 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400156 main.cleanup()
157 main.exit()
158 else:
kelvin8ec71442015-01-15 16:57:00 -0800159 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800160 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800161 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400162 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800163 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800164 handleBefore = self.handle.before
165 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800166 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800167 self.handle.sendline("")
168 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800169 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400170
kelvin-onlabd3b64892015-01-20 13:26:24 -0800171 main.log.info( "Cell call returned: " + handleBefore +
172 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400173
174 return main.TRUE
175
Jon Halld4d4b372015-01-28 16:02:41 -0800176 except TypeError:
177 main.log.exception( self.name + ": Object not as expected" )
178 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400179 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800180 main.log.error( self.name + ": eof exception found" )
181 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400182 main.cleanup()
183 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800184 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800185 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400186 main.cleanup()
187 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800188
kelvin-onlabd3b64892015-01-20 13:26:24 -0800189 def startOnosCli( self, ONOSIp, karafTimeout="" ):
kelvin8ec71442015-01-15 16:57:00 -0800190 """
Jon Hallefbd9792015-03-05 16:11:36 -0800191 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800192 by user would be used to set the current karaf shell idle timeout.
193 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800194 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800195 Below is an example to start a session with 60 seconds idle timeout
196 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800197
Hari Krishna25d42f72015-01-05 15:08:28 -0800198 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800199 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800200
kelvin-onlabd3b64892015-01-20 13:26:24 -0800201 Note: karafTimeout is left as str so that this could be read
202 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800203 """
andrewonlab95ce8322014-10-13 14:12:04 -0400204 try:
kelvin8ec71442015-01-15 16:57:00 -0800205 self.handle.sendline( "" )
206 x = self.handle.expect( [
207 "\$", "onos>" ], timeout=10 )
andrewonlab48829f62014-11-17 13:49:01 -0500208
209 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800210 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500211 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400212
kelvin8ec71442015-01-15 16:57:00 -0800213 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800214 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800215 i = self.handle.expect( [
216 "onos>",
kelvin-onlab898a6c62015-01-16 14:13:53 -0800217 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400218
219 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800220 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800221 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800222 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800223 "config:property-set -p org.apache.karaf.shell\
224 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800225 karafTimeout )
226 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800227 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800228 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400229 return main.TRUE
230 else:
kelvin8ec71442015-01-15 16:57:00 -0800231 # If failed, send ctrl+c to process and try again
232 main.log.info( "Starting CLI failed. Retrying..." )
233 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800234 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800235 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
236 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400237 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800239 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800240 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800241 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800242 "config:property-set -p org.apache.karaf.shell\
243 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800244 karafTimeout )
245 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800246 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800247 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400248 return main.TRUE
249 else:
kelvin8ec71442015-01-15 16:57:00 -0800250 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800251 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400252 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400253
Jon Halld4d4b372015-01-28 16:02:41 -0800254 except TypeError:
255 main.log.exception( self.name + ": Object not as expected" )
256 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400257 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800258 main.log.error( self.name + ": EOF exception found" )
259 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400260 main.cleanup()
261 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800262 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800263 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400264 main.cleanup()
265 main.exit()
266
Jon Hallefbd9792015-03-05 16:11:36 -0800267 def log( self, cmdStr, level="" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800268 """
269 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800270 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800271 returns main.FALSE if Error occurred
kelvin-onlab338f5512015-02-06 10:53:16 -0800272 Available level: DEBUG, TRACE, INFO, WARN, ERROR
273 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800274 """
275 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800276 lvlStr = ""
277 if level:
278 lvlStr = "--level=" + level
279
kelvin-onlab9f541032015-02-04 16:19:53 -0800280 self.handle.sendline( "" )
281 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800282 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
kelvin-onlab9f541032015-02-04 16:19:53 -0800283 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800284
kelvin-onlab9f541032015-02-04 16:19:53 -0800285 response = self.handle.before
286 if re.search( "Error", response ):
287 return main.FALSE
288 return main.TRUE
289
290 except pexpect.EOF:
291 main.log.error( self.name + ": EOF exception found" )
292 main.log.error( self.name + ": " + self.handle.before )
293 main.cleanup()
294 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800295 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800296 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400297 main.cleanup()
298 main.exit()
299
kelvin-onlabd3b64892015-01-20 13:26:24 -0800300 def sendline( self, cmdStr ):
kelvin8ec71442015-01-15 16:57:00 -0800301 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800302 Send a completely user specified string to
303 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400304 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800305
andrewonlaba18f6bf2014-10-13 19:31:54 -0400306 Warning: There are no sanity checking to commands
307 sent using this method.
kelvin8ec71442015-01-15 16:57:00 -0800308 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400309 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800310 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
311 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800312 self.handle.sendline( cmdStr )
Jon Hall63604932015-02-26 17:09:50 -0800313 i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
314 response = self.handle.before
315 if i == 2:
316 self.handle.sendline()
317 self.handle.expect( "\$" )
318 response += self.handle.before
319 print response
320 try:
321 print self.handle.after
322 except:
323 pass
324 # TODO: do something with i
kelvin-onlabd3b64892015-01-20 13:26:24 -0800325 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
kelvin-onlab898a6c62015-01-16 14:13:53 -0800326 + self.name + "." )
Jon Hall7bdfc122015-01-23 11:45:32 -0800327 # Remove control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800328 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800329 response = ansiEscape.sub( '', response )
kelvin-onlabfb521662015-02-27 09:52:40 -0800330 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800331 response = re.sub( r"\s\r", "", response )
332 response = response.strip()
333 # parse for just the output, remove the cmd from response
334 output = response.split( cmdStr, 1 )[1]
Jon Hall7bdfc122015-01-23 11:45:32 -0800335 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800336 except TypeError:
337 main.log.exception( self.name + ": Object not as expected" )
338 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400339 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800340 main.log.error( self.name + ": EOF exception found" )
341 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400342 main.cleanup()
343 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800344 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800345 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400346 main.cleanup()
347 main.exit()
348
kelvin8ec71442015-01-15 16:57:00 -0800349 # IMPORTANT NOTE:
350 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800351 # the cli command changing 'a:b' with 'aB'.
352 # Ex ) onos:topology > onosTopology
353 # onos:links > onosLinks
354 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800355
kelvin-onlabd3b64892015-01-20 13:26:24 -0800356 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800357 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400358 Adds a new cluster node by ID and address information.
359 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800360 * nodeId
361 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400362 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800363 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800364 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400365 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800366 cmdStr = "add-node " + str( nodeId ) + " " +\
367 str( ONOSIp ) + " " + str( tcpPort )
368 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800369 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800370 main.log.error( "Error in adding node" )
371 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800372 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400373 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800374 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400375 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800376 except TypeError:
377 main.log.exception( self.name + ": Object not as expected" )
378 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400379 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800380 main.log.error( self.name + ": EOF exception found" )
381 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400382 main.cleanup()
383 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800384 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800385 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400386 main.cleanup()
387 main.exit()
388
kelvin-onlabd3b64892015-01-20 13:26:24 -0800389 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800390 """
andrewonlab86dc3082014-10-13 18:18:38 -0400391 Removes a cluster by ID
392 Issues command: 'remove-node [<node-id>]'
393 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800394 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800395 """
andrewonlab86dc3082014-10-13 18:18:38 -0400396 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400397
kelvin-onlabd3b64892015-01-20 13:26:24 -0800398 cmdStr = "remove-node " + str( nodeId )
399 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800400 # TODO: add error checking. Does ONOS give any errors?
andrewonlab86dc3082014-10-13 18:18:38 -0400401
402 return main.TRUE
Jon Halle3f39ff2015-01-13 11:50:53 -0800403
Jon Halld4d4b372015-01-28 16:02:41 -0800404 except TypeError:
405 main.log.exception( self.name + ": Object not as expected" )
406 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400407 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800408 main.log.error( self.name + ": EOF exception found" )
409 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400410 main.cleanup()
411 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800412 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800413 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400414 main.cleanup()
415 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400416
Jon Hall61282e32015-03-19 11:34:11 -0700417 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800418 """
andrewonlab7c211572014-10-15 16:45:20 -0400419 List the nodes currently visible
420 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700421 Optional argument:
422 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800423 """
andrewonlab7c211572014-10-15 16:45:20 -0400424 try:
Jon Hall61282e32015-03-19 11:34:11 -0700425 if jsonFormat:
426 cmdStr = "nodes -j"
427 output = self.sendline( cmdStr )
428 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
429 parsedOutput = ansiEscape.sub( '', output )
430 return parsedOutput
431 else:
432 cmdStr = "nodes"
433 output = self.sendline( cmdStr )
434 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800435 except TypeError:
436 main.log.exception( self.name + ": Object not as expected" )
437 return None
andrewonlab7c211572014-10-15 16:45:20 -0400438 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800439 main.log.error( self.name + ": EOF exception found" )
440 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400441 main.cleanup()
442 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800443 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800444 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400445 main.cleanup()
446 main.exit()
447
kelvin8ec71442015-01-15 16:57:00 -0800448 def topology( self ):
449 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700450 Definition:
451 Returns the ouput of topology command.
452 Return:
453 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800454 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700455 import json
andrewonlab95ce8322014-10-13 14:12:04 -0400456 try:
Jon Halle3f39ff2015-01-13 11:50:53 -0800457 # either onos:topology or 'topology' will work in CLI
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700458 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800459 handle = self.sendline( cmdStr )
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700460 main.log.info( "topology -j returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400461 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800462 except TypeError:
463 main.log.exception( self.name + ": Object not as expected" )
464 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400465 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800466 main.log.error( self.name + ": EOF exception found" )
467 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400468 main.cleanup()
469 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800470 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800471 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400472 main.cleanup()
473 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800474
kelvin-onlabd3b64892015-01-20 13:26:24 -0800475 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800476 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800477 Installs a specified feature
andrewonlabc2d05aa2014-10-13 16:51:10 -0400478 by issuing command: 'onos> feature:install <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800479 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400480 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800481 cmdStr = "feature:install " + str( featureStr )
482 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800483 # TODO: Check for possible error responses from karaf
andrewonlabc2d05aa2014-10-13 16:51:10 -0400484 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800485 except TypeError:
486 main.log.exception( self.name + ": Object not as expected" )
487 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400488 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800489 main.log.error( self.name + ": EOF exception found" )
490 main.log.error( self.name + ": " + self.handle.before )
491 main.log.report( "Failed to install feature" )
492 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400493 main.cleanup()
494 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800495 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800496 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800497 main.log.report( "Failed to install feature" )
498 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400499 main.cleanup()
500 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800501
kelvin-onlabd3b64892015-01-20 13:26:24 -0800502 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800503 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400504 Uninstalls a specified feature
505 by issuing command: 'onos> feature:uninstall <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800506 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400507 try:
Jon Hall30b82fa2015-03-04 17:15:43 -0800508 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
509 handle = self.sendline( cmdStr )
510 if handle != '':
511 cmdStr = "feature:uninstall " + str( featureStr )
512 self.sendline( cmdStr )
513 # TODO: Check for possible error responses from karaf
514 else:
Jon Hallefbd9792015-03-05 16:11:36 -0800515 main.log.info( "Feature needs to be installed before " +
516 "uninstalling it" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400517 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800518 except TypeError:
519 main.log.exception( self.name + ": Object not as expected" )
520 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400521 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800522 main.log.error( self.name + ": EOF exception found" )
523 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400524 main.cleanup()
525 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800526 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800527 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400528 main.cleanup()
529 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800530
jenkins7ead5a82015-03-13 10:28:21 -0700531 def deviceRemove( self, deviceId ):
532 """
533 Removes particular device from storage
534
535 TODO: refactor this function
536 """
537 try:
538 cmdStr = "device-remove "+str(deviceId)
539 handle = self.sendline( cmdStr )
540 return main.TRUE
541 except TypeError:
542 main.log.exception( self.name + ": Object not as expected" )
543 return None
544 except pexpect.EOF:
545 main.log.error( self.name + ": EOF exception found" )
546 main.log.error( self.name + ": " + self.handle.before )
547 main.cleanup()
548 main.exit()
549 except Exception:
550 main.log.exception( self.name + ": Uncaught exception!" )
551 main.cleanup()
552 main.exit()
553
554
555
kelvin-onlabd3b64892015-01-20 13:26:24 -0800556 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800557 """
Jon Hall7b02d952014-10-17 20:14:54 -0400558 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400559 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800560 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800561 """
andrewonlab86dc3082014-10-13 18:18:38 -0400562 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800563 if jsonFormat:
564 cmdStr = "devices -j"
565 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800566 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800567 handle variable here contains some ANSI escape color code
568 sequences at the end which are invisible in the print command
569 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800570 function. The repr( handle ) output when printed shows the
571 ANSI escape sequences. In json.loads( somestring ), this
572 somestring variable is actually repr( somestring ) and
Jon Halle3f39ff2015-01-13 11:50:53 -0800573 json.loads would fail with the escape sequence. So we take off
574 that escape sequence using:
575
kelvin-onlabd3b64892015-01-20 13:26:24 -0800576 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
577 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800578 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800579 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
580 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400581 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400582 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800583 cmdStr = "devices"
584 handle = self.sendline( cmdStr )
Jon Hallcd707292014-10-17 19:06:17 -0400585 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800586 except TypeError:
587 main.log.exception( self.name + ": Object not as expected" )
588 return None
andrewonlab7c211572014-10-15 16:45:20 -0400589 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800590 main.log.error( self.name + ": EOF exception found" )
591 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400592 main.cleanup()
593 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800594 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800595 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400596 main.cleanup()
597 main.exit()
598
kelvin-onlabd3b64892015-01-20 13:26:24 -0800599 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800600 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800601 This balances the devices across all controllers
602 by issuing command: 'onos> onos:balance-masters'
603 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800604 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800605 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800606 cmdStr = "onos:balance-masters"
607 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800608 # TODO: Check for error responses from ONOS
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800609 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800610 except TypeError:
611 main.log.exception( self.name + ": Object not as expected" )
612 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800613 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800614 main.log.error( self.name + ": EOF exception found" )
615 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800616 main.cleanup()
617 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800618 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800619 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800620 main.cleanup()
621 main.exit()
622
kelvin-onlabd3b64892015-01-20 13:26:24 -0800623 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800624 """
Jon Halle8217482014-10-17 13:49:14 -0400625 Lists all core links
626 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800627 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800628 """
Jon Halle8217482014-10-17 13:49:14 -0400629 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800630 if jsonFormat:
631 cmdStr = "links -j"
632 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800633 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800634 handle variable here contains some ANSI escape color code
635 sequences at the end which are invisible in the print command
636 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800637 function. The repr( handle ) output when printed shows the ANSI
638 escape sequences. In json.loads( somestring ), this somestring
639 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800640 fail with the escape sequence. So we take off that escape
641 sequence using:
642
kelvin-onlabd3b64892015-01-20 13:26:24 -0800643 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
644 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800645 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800646 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
647 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400648 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400649 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800650 cmdStr = "links"
651 handle = self.sendline( cmdStr )
Jon Halla001c392014-10-17 18:50:59 -0400652 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800653 except TypeError:
654 main.log.exception( self.name + ": Object not as expected" )
655 return None
Jon Halle8217482014-10-17 13:49:14 -0400656 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800657 main.log.error( self.name + ": EOF exception found" )
658 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400659 main.cleanup()
660 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800661 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800662 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400663 main.cleanup()
664 main.exit()
665
kelvin-onlabd3b64892015-01-20 13:26:24 -0800666 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800667 """
Jon Halle8217482014-10-17 13:49:14 -0400668 Lists all ports
669 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800670 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800671 """
Jon Halle8217482014-10-17 13:49:14 -0400672 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800673 if jsonFormat:
674 cmdStr = "ports -j"
675 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800676 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800677 handle variable here contains some ANSI escape color code
678 sequences at the end which are invisible in the print command
679 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800680 function. The repr( handle ) output when printed shows the ANSI
681 escape sequences. In json.loads( somestring ), this somestring
682 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800683 fail with the escape sequence. So we take off that escape
Jon Hallefbd9792015-03-05 16:11:36 -0800684 sequence using the following commands:
Jon Halle3f39ff2015-01-13 11:50:53 -0800685
kelvin-onlabd3b64892015-01-20 13:26:24 -0800686 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
687 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800688 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800689 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
690 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400691 return handle1
692
Jon Halle8217482014-10-17 13:49:14 -0400693 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800694 cmdStr = "ports"
695 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800696 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800697 except TypeError:
698 main.log.exception( self.name + ": Object not as expected" )
699 return None
Jon Halle8217482014-10-17 13:49:14 -0400700 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800701 main.log.error( self.name + ": EOF exception found" )
702 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400703 main.cleanup()
704 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800705 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800706 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400707 main.cleanup()
708 main.exit()
709
kelvin-onlabd3b64892015-01-20 13:26:24 -0800710 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800711 """
Jon Hall983a1702014-10-28 18:44:22 -0400712 Lists all devices and the controllers with roles assigned to them
713 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800714 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800715 """
andrewonlab7c211572014-10-15 16:45:20 -0400716 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800717 if jsonFormat:
718 cmdStr = "roles -j"
719 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800720 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800721 handle variable here contains some ANSI escape color code
722 sequences at the end which are invisible in the print command
723 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800724 function. The repr( handle ) output when printed shows the ANSI
725 escape sequences. In json.loads( somestring ), this somestring
726 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800727 fail with the escape sequence.
Jon Hallb1290e82014-11-18 16:17:48 -0500728
Jon Halle3f39ff2015-01-13 11:50:53 -0800729 So we take off that escape sequence using the following
730 commads:
731
kelvin-onlabd3b64892015-01-20 13:26:24 -0800732 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
733 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800734 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800735 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
736 handle1 = ansiEscape.sub( '', handle )
Jon Hall983a1702014-10-28 18:44:22 -0400737 return handle1
andrewonlab7c211572014-10-15 16:45:20 -0400738
andrewonlab7c211572014-10-15 16:45:20 -0400739 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800740 cmdStr = "roles"
741 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800742 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800743 except TypeError:
744 main.log.exception( self.name + ": Object not as expected" )
745 return None
Jon Hall983a1702014-10-28 18:44:22 -0400746 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800747 main.log.error( self.name + ": EOF exception found" )
748 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400749 main.cleanup()
750 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800751 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800752 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400753 main.cleanup()
754 main.exit()
755
kelvin-onlabd3b64892015-01-20 13:26:24 -0800756 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800757 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800758 Given the a string containing the json representation of the "roles"
759 cli command and a partial or whole device id, returns a json object
760 containing the roles output for the first device whose id contains
761 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400762
763 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800764 A dict of the role assignments for the given device or
765 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800766 """
Jon Hall983a1702014-10-28 18:44:22 -0400767 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800768 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400769 return None
770 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800771 rawRoles = self.roles()
772 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800773 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800774 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800775 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800776 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400777 return device
778 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800779 except TypeError:
780 main.log.exception( self.name + ": Object not as expected" )
781 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400782 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800783 main.log.error( self.name + ": EOF exception found" )
784 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400785 main.cleanup()
786 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800787 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800788 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400789 main.cleanup()
790 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800791
kelvin-onlabd3b64892015-01-20 13:26:24 -0800792 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800793 """
Jon Hall94fd0472014-12-08 11:52:42 -0800794 Iterates through each device and checks if there is a master assigned
795 Returns: main.TRUE if each device has a master
796 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800797 """
Jon Hall94fd0472014-12-08 11:52:42 -0800798 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800799 rawRoles = self.roles()
800 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800801 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800802 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800803 # print device
804 if device[ 'master' ] == "none":
805 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800806 return main.FALSE
807 return main.TRUE
808
Jon Halld4d4b372015-01-28 16:02:41 -0800809 except TypeError:
810 main.log.exception( self.name + ": Object not as expected" )
811 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800812 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800813 main.log.error( self.name + ": EOF exception found" )
814 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800815 main.cleanup()
816 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800817 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800818 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800819 main.cleanup()
820 main.exit()
821
kelvin-onlabd3b64892015-01-20 13:26:24 -0800822 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800823 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400824 Returns string of paths, and the cost.
825 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800826 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400827 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800828 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
829 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800830 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800831 main.log.error( "Error in getting paths" )
832 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400833 else:
kelvin8ec71442015-01-15 16:57:00 -0800834 path = handle.split( ";" )[ 0 ]
835 cost = handle.split( ";" )[ 1 ]
836 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800837 except TypeError:
838 main.log.exception( self.name + ": Object not as expected" )
839 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400840 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800841 main.log.error( self.name + ": EOF exception found" )
842 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400843 main.cleanup()
844 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800845 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800846 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400847 main.cleanup()
848 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800849
kelvin-onlabd3b64892015-01-20 13:26:24 -0800850 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800851 """
Jon Hallffb386d2014-11-21 13:43:38 -0800852 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400853 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800854 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800855 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400856 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800857 if jsonFormat:
858 cmdStr = "hosts -j"
859 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800860 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800861 handle variable here contains some ANSI escape color code
862 sequences at the end which are invisible in the print command
863 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800864 function. The repr( handle ) output when printed shows the ANSI
865 escape sequences. In json.loads( somestring ), this somestring
866 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800867 fail with the escape sequence. So we take off that escape
868 sequence using:
869
kelvin-onlabd3b64892015-01-20 13:26:24 -0800870 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
871 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800872 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800873 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
874 handle1 = ansiEscape.sub( '', handle )
Jon Hall42db6dc2014-10-24 19:03:48 -0400875 return handle1
876 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800877 cmdStr = "hosts"
878 handle = self.sendline( cmdStr )
Jon Hall42db6dc2014-10-24 19:03:48 -0400879 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800880 except TypeError:
881 main.log.exception( self.name + ": Object not as expected" )
882 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400883 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800884 main.log.error( self.name + ": EOF exception found" )
885 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400886 main.cleanup()
887 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800888 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800889 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400890 main.cleanup()
891 main.exit()
892
kelvin-onlabd3b64892015-01-20 13:26:24 -0800893 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800894 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400895 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800896
Jon Hallefbd9792015-03-05 16:11:36 -0800897 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800898 partial mac address
899
Jon Hall42db6dc2014-10-24 19:03:48 -0400900 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800901 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400902 try:
kelvin8ec71442015-01-15 16:57:00 -0800903 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400904 return None
905 else:
906 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 rawHosts = self.hosts()
908 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800909 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800910 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800911 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800912 if not host:
913 pass
914 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400915 return host
916 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800917 except TypeError:
918 main.log.exception( self.name + ": Object not as expected" )
919 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400920 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800921 main.log.error( self.name + ": EOF exception found" )
922 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400923 main.cleanup()
924 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800925 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800926 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400927 main.cleanup()
928 main.exit()
929
kelvin-onlabd3b64892015-01-20 13:26:24 -0800930 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800931 """
932 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400933 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800934
andrewonlab3f0a4af2014-10-17 12:25:14 -0400935 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800936 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400937 IMPORTANT:
938 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800939 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400940 Furthermore, it assumes that value of VLAN is '-1'
941 Description:
kelvin8ec71442015-01-15 16:57:00 -0800942 Converts mininet hosts ( h1, h2, h3... ) into
943 ONOS format ( 00:00:00:00:00:01/-1 , ... )
944 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400945 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800946 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400947
kelvin-onlabd3b64892015-01-20 13:26:24 -0800948 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800949 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800950 hostHex = hex( int( host ) ).zfill( 12 )
951 hostHex = str( hostHex ).replace( 'x', '0' )
952 i = iter( str( hostHex ) )
953 hostHex = ":".join( a + b for a, b in zip( i, i ) )
954 hostHex = hostHex + "/-1"
955 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400956
kelvin-onlabd3b64892015-01-20 13:26:24 -0800957 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400958
Jon Halld4d4b372015-01-28 16:02:41 -0800959 except TypeError:
960 main.log.exception( self.name + ": Object not as expected" )
961 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400962 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800963 main.log.error( self.name + ": EOF exception found" )
964 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400965 main.cleanup()
966 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800967 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800968 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400969 main.cleanup()
970 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400971
kelvin-onlabd3b64892015-01-20 13:26:24 -0800972 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800973 """
andrewonlabe6745342014-10-17 14:29:13 -0400974 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800975 * hostIdOne: ONOS host id for host1
976 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400977 Description:
Jon Hallefbd9792015-03-05 16:11:36 -0800978 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500979 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -0800980 Returns:
981 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -0800982 """
andrewonlabe6745342014-10-17 14:29:13 -0400983 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800984 cmdStr = "add-host-intent " + str( hostIdOne ) +\
985 " " + str( hostIdTwo )
986 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800987 if re.search( "Error", handle ):
988 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -0700989 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800990 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -0800991 else:
992 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -0800993 str( hostIdOne ) + " and " + str( hostIdTwo ) )
994 match = re.search('id=0x([\da-f]+),', handle)
995 if match:
996 return match.group()[3:-1]
997 else:
998 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -0700999 main.log.debug( "Response from ONOS was: " +
1000 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001001 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001002 except TypeError:
1003 main.log.exception( self.name + ": Object not as expected" )
1004 return None
andrewonlabe6745342014-10-17 14:29:13 -04001005 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001006 main.log.error( self.name + ": EOF exception found" )
1007 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001008 main.cleanup()
1009 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001010 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001011 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001012 main.cleanup()
1013 main.exit()
1014
kelvin-onlabd3b64892015-01-20 13:26:24 -08001015 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001016 """
andrewonlab7b31d232014-10-24 13:31:47 -04001017 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001018 * ingressDevice: device id of ingress device
1019 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001020 Optional:
1021 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001022 Description:
1023 Adds an optical intent by specifying an ingress and egress device
1024 Returns:
1025 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001026 """
andrewonlab7b31d232014-10-24 13:31:47 -04001027 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001028 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1029 " " + str( egressDevice )
1030 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001031 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001032 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001033 main.log.error( "Error in adding Optical intent" )
1034 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001035 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001036 main.log.info( "Optical intent installed between " +
1037 str( ingressDevice ) + " and " +
1038 str( egressDevice ) )
1039 match = re.search('id=0x([\da-f]+),', handle)
1040 if match:
1041 return match.group()[3:-1]
1042 else:
1043 main.log.error( "Error, intent ID not found" )
1044 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001045 except TypeError:
1046 main.log.exception( self.name + ": Object not as expected" )
1047 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001048 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001049 main.log.error( self.name + ": EOF exception found" )
1050 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001051 main.cleanup()
1052 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001053 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001054 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001055 main.cleanup()
1056 main.exit()
1057
kelvin-onlabd3b64892015-01-20 13:26:24 -08001058 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001059 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001060 ingressDevice,
1061 egressDevice,
1062 portIngress="",
1063 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001064 ethType="",
1065 ethSrc="",
1066 ethDst="",
1067 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001068 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001069 ipProto="",
1070 ipSrc="",
1071 ipDst="",
1072 tcpSrc="",
1073 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001074 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001075 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001076 * ingressDevice: device id of ingress device
1077 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001078 Optional:
1079 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001080 * ethSrc: specify ethSrc ( i.e. src mac addr )
1081 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001082 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001083 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001084 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001085 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001086 * ipSrc: specify ip source address
1087 * ipDst: specify ip destination address
1088 * tcpSrc: specify tcp source port
1089 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001090 Description:
kelvin8ec71442015-01-15 16:57:00 -08001091 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001092 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001093 Returns:
1094 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001095
Jon Halle3f39ff2015-01-13 11:50:53 -08001096 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001097 options developers provide for point-to-point
1098 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001099 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001100 try:
kelvin8ec71442015-01-15 16:57:00 -08001101 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001102 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001103 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001104 and not ipProto and not ipSrc and not ipDst \
1105 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001106 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001107
andrewonlab289e4b72014-10-21 21:24:18 -04001108 else:
andrewonlab36af3822014-11-18 17:48:18 -05001109 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001110
andrewonlab0c0a6772014-10-22 12:31:18 -04001111 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001112 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001113 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001114 cmd += " --ethSrc " + str( ethSrc )
1115 if ethDst:
1116 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001117 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001118 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001120 cmd += " --lambda "
1121 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001122 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001123 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001124 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001125 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001126 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001127 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001128 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001129 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001130 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001131
kelvin8ec71442015-01-15 16:57:00 -08001132 # Check whether the user appended the port
1133 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 if "/" in ingressDevice:
1135 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001136 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001137 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001138 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001139 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001140 # Would it make sense to throw an exception and exit
1141 # the test?
1142 return None
andrewonlab36af3822014-11-18 17:48:18 -05001143
kelvin8ec71442015-01-15 16:57:00 -08001144 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001145 str( ingressDevice ) + "/" +\
1146 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001147
kelvin-onlabd3b64892015-01-20 13:26:24 -08001148 if "/" in egressDevice:
1149 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001150 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001151 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001152 main.log.error( "You must specify the egress port" )
1153 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001154
kelvin8ec71442015-01-15 16:57:00 -08001155 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001156 str( egressDevice ) + "/" +\
1157 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001158
kelvin-onlab898a6c62015-01-16 14:13:53 -08001159 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001160 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001161 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001162 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001163 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001164 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001165 # TODO: print out all the options in this message?
1166 main.log.info( "Point-to-point intent installed between " +
1167 str( ingressDevice ) + " and " +
1168 str( egressDevice ) )
1169 match = re.search('id=0x([\da-f]+),', handle)
1170 if match:
1171 return match.group()[3:-1]
1172 else:
1173 main.log.error( "Error, intent ID not found" )
1174 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001175 except TypeError:
1176 main.log.exception( self.name + ": Object not as expected" )
1177 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001178 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001179 main.log.error( self.name + ": EOF exception found" )
1180 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001181 main.cleanup()
1182 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001183 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001184 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001185 main.cleanup()
1186 main.exit()
1187
kelvin-onlabd3b64892015-01-20 13:26:24 -08001188 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001189 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001190 ingressDevice1,
1191 ingressDevice2,
1192 egressDevice,
kelvin-onlabfb521662015-02-27 09:52:40 -08001193 portIngress1="",
1194 portIngress2="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001195 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001196 ethType="",
1197 ethSrc="",
1198 ethDst="",
1199 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001200 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001201 ipProto="",
1202 ipSrc="",
1203 ipDst="",
1204 tcpSrc="",
1205 tcpDst="",
1206 setEthSrc="",
1207 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001208 """
shahshreyad0c80432014-12-04 16:56:05 -08001209 Note:
Jon Halle3f39ff2015-01-13 11:50:53 -08001210 This function assumes that there would be 2 ingress devices and
1211 one egress device. For more number of ingress devices, this
1212 function needs to be modified
shahshreyad0c80432014-12-04 16:56:05 -08001213 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001214 * ingressDevice1: device id of ingress device1
1215 * ingressDevice2: device id of ingress device2
1216 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001217 Optional:
1218 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001219 * ethSrc: specify ethSrc ( i.e. src mac addr )
1220 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001221 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001222 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001223 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001224 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001225 * ipSrc: specify ip source address
1226 * ipDst: specify ip destination address
1227 * tcpSrc: specify tcp source port
1228 * tcpDst: specify tcp destination port
1229 * setEthSrc: action to Rewrite Source MAC Address
1230 * setEthDst: action to Rewrite Destination MAC Address
1231 Description:
kelvin8ec71442015-01-15 16:57:00 -08001232 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001233 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001234 Returns:
1235 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001236
Jon Halle3f39ff2015-01-13 11:50:53 -08001237 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001238 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001239 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001240 """
shahshreyad0c80432014-12-04 16:56:05 -08001241 try:
kelvin8ec71442015-01-15 16:57:00 -08001242 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001243 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001244 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001245 and not ipProto and not ipSrc and not ipDst\
1246 and not tcpSrc and not tcpDst and not setEthSrc\
1247 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001248 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001249
1250 else:
1251 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001252
shahshreyad0c80432014-12-04 16:56:05 -08001253 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001254 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001255 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001256 cmd += " --ethSrc " + str( ethSrc )
1257 if ethDst:
1258 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001259 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001260 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001261 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001262 cmd += " --lambda "
1263 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001264 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001265 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001266 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001267 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001268 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001269 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001270 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001271 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001272 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001273 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001274 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001275 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001276 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001277
kelvin8ec71442015-01-15 16:57:00 -08001278 # Check whether the user appended the port
1279 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001280 if "/" in ingressDevice1:
1281 cmd += " " + str( ingressDevice1 )
shahshreyad0c80432014-12-04 16:56:05 -08001282 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001283 if not portIngress1:
kelvin8ec71442015-01-15 16:57:00 -08001284 main.log.error( "You must specify " +
1285 "the ingress port1" )
1286 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001287 return None
shahshreyad0c80432014-12-04 16:56:05 -08001288
kelvin8ec71442015-01-15 16:57:00 -08001289 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001290 str( ingressDevice1 ) + "/" +\
1291 str( portIngress1 ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001292
kelvin-onlabd3b64892015-01-20 13:26:24 -08001293 if "/" in ingressDevice2:
1294 cmd += " " + str( ingressDevice2 )
shahshreyad0c80432014-12-04 16:56:05 -08001295 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001296 if not portIngress2:
kelvin8ec71442015-01-15 16:57:00 -08001297 main.log.error( "You must specify " +
1298 "the ingress port2" )
1299 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001300 return None
shahshreyad0c80432014-12-04 16:56:05 -08001301
kelvin8ec71442015-01-15 16:57:00 -08001302 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001303 str( ingressDevice2 ) + "/" +\
1304 str( portIngress2 ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001305
kelvin-onlabd3b64892015-01-20 13:26:24 -08001306 if "/" in egressDevice:
1307 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001308 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001309 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001310 main.log.error( "You must specify " +
1311 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001312 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001313
kelvin8ec71442015-01-15 16:57:00 -08001314 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001315 str( egressDevice ) + "/" +\
1316 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001317 print "cmd= ", cmd
kelvin-onlab898a6c62015-01-16 14:13:53 -08001318 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001319 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001320 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001321 main.log.error( "Error in adding multipoint-to-singlepoint " +
1322 "intent" )
1323 return None
shahshreyad0c80432014-12-04 16:56:05 -08001324 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001325 # TODO: print out all the options in this message?
1326 main.log.info( "Multipoint-to-singlepoint intent installed" +
1327 " between " + str( ingressDevice1 ) + ", " +
1328 str( ingressDevice2 ) + " and " +
1329 str( egressDevice ) )
1330 match = re.search('id=0x([\da-f]+),', handle)
1331 if match:
1332 return match.group()[3:-1]
1333 else:
1334 main.log.error( "Error, intent ID not found" )
1335 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001336 except TypeError:
1337 main.log.exception( self.name + ": Object not as expected" )
1338 return None
shahshreyad0c80432014-12-04 16:56:05 -08001339 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001340 main.log.error( self.name + ": EOF exception found" )
1341 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001342 main.cleanup()
1343 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001344 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001345 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001346 main.cleanup()
1347 main.exit()
1348
Jon Hallefbd9792015-03-05 16:11:36 -08001349 def removeIntent( self, intentId, app='org.onosproject.cli',
1350 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001351 """
shahshreya1c818fc2015-02-26 13:44:08 -08001352 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001353 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001354 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001355 -p or --purge: Purge the intent from the store after removal
1356
Jon Halle3f39ff2015-01-13 11:50:53 -08001357 Returns:
1358 main.False on error and
1359 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001360 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001361 try:
shahshreya1c818fc2015-02-26 13:44:08 -08001362 cmdStr = "remove-intent "
1363 if purge:
1364 cmdStr += " -p"
1365 if sync:
1366 cmdStr += " -s"
1367
1368 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001369 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001370 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001371 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001372 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001373 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001374 # TODO: Should this be main.TRUE
1375 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001376 except TypeError:
1377 main.log.exception( self.name + ": Object not as expected" )
1378 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001379 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001380 main.log.error( self.name + ": EOF exception found" )
1381 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001382 main.cleanup()
1383 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001384 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001385 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001386 main.cleanup()
1387 main.exit()
1388
kelvin-onlabd3b64892015-01-20 13:26:24 -08001389 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001390 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001391 NOTE: This method should be used after installing application:
1392 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001393 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001394 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001395 Description:
1396 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001397 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001398 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001399 if jsonFormat:
1400 cmdStr = "routes -j"
1401 handleTmp = self.sendline( cmdStr )
1402 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1403 handle = ansiEscape.sub( '', handleTmp )
pingping-lin8b306ac2014-11-17 18:13:51 -08001404 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001405 cmdStr = "routes"
1406 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001407 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001408 except TypeError:
1409 main.log.exception( self.name + ": Object not as expected" )
1410 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001411 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001412 main.log.error( self.name + ": EOF exception found" )
1413 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001414 main.cleanup()
1415 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001416 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001417 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001418 main.cleanup()
1419 main.exit()
1420
kelvin-onlabd3b64892015-01-20 13:26:24 -08001421 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001422 """
andrewonlab377693f2014-10-21 16:00:30 -04001423 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001424 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001425 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001426 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001427 """
andrewonlabe6745342014-10-17 14:29:13 -04001428 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001429 if jsonFormat:
1430 cmdStr = "intents -j"
1431 handle = self.sendline( cmdStr )
1432 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1433 handle = ansiEscape.sub( '', handle )
kelvin8ec71442015-01-15 16:57:00 -08001434 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001435 cmdStr = "intents"
1436 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001437 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001438 except TypeError:
1439 main.log.exception( self.name + ": Object not as expected" )
1440 return None
andrewonlabe6745342014-10-17 14:29:13 -04001441 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001442 main.log.error( self.name + ": EOF exception found" )
1443 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001444 main.cleanup()
1445 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001446 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001447 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001448 main.cleanup()
1449 main.exit()
1450
kelvin-onlab54400a92015-02-26 18:05:51 -08001451 def getIntentState(self, intentsId, intentsJson=None):
1452 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001453 Check intent state.
1454 Accepts a single intent ID (string type) or a list of intent IDs.
1455 Returns the state(string type) of the id if a single intent ID is
1456 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001457 Returns a dictionary with intent IDs as the key and its
1458 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001459 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001460 intentId: intent ID (string type)
1461 intentsJson: parsed json object from the onos:intents api
1462 Returns:
1463 state = An intent's state- INSTALL,WITHDRAWN etc.
1464 stateDict = Dictionary of intent's state. intent ID as the keys and
1465 state as the values.
1466 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001467 try:
1468 state = "State is Undefined"
1469 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001470 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001471 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001472 intentsJsonTemp = json.loads( intentsJson )
1473 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001474 for intent in intentsJsonTemp:
1475 if intentsId == intent['id']:
1476 state = intent['state']
1477 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001478 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1479 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001480 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001481 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001482 dictList = []
kelvin-onlab54400a92015-02-26 18:05:51 -08001483 for ID in intentsId:
kelvin-onlab07dbd012015-03-04 16:29:39 -08001484 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001485 for intents in intentsJsonTemp:
1486 if ID == intents['id']:
kelvin-onlab07dbd012015-03-04 16:29:39 -08001487 stateDict['state'] = intents['state']
1488 stateDict['id'] = ID
Jon Hallefbd9792015-03-05 16:11:36 -08001489 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001490 break
Jon Hallefbd9792015-03-05 16:11:36 -08001491 if len( intentsId ) != len( dictList ):
1492 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001493 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001494 else:
1495 main.log.info("Invalid intents ID entry")
1496 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001497 except TypeError:
1498 main.log.exception( self.name + ": Object not as expected" )
1499 return None
1500 except pexpect.EOF:
1501 main.log.error( self.name + ": EOF exception found" )
1502 main.log.error( self.name + ": " + self.handle.before )
1503 main.cleanup()
1504 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001505 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001506 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001507 main.cleanup()
1508 main.exit()
1509
kelvin-onlabd3b64892015-01-20 13:26:24 -08001510 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001511 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001512 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001513 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001514 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001515 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001516 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001517 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001518 if jsonFormat:
1519 cmdStr = "flows -j"
1520 handle = self.sendline( cmdStr )
1521 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1522 handle = ansiEscape.sub( '', handle )
Shreya Shah0f01c812014-10-26 20:15:28 -04001523 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001524 cmdStr = "flows"
1525 handle = self.sendline( cmdStr )
Jon Hall61282e32015-03-19 11:34:11 -07001526 if re.search( "Error:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001527 main.log.error( self.name + ".flows() response: " +
1528 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001529 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001530 except TypeError:
1531 main.log.exception( self.name + ": Object not as expected" )
1532 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001533 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001534 main.log.error( self.name + ": EOF exception found" )
1535 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001536 main.cleanup()
1537 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001538 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001539 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001540 main.cleanup()
1541 main.exit()
1542
kelvin-onlabd3b64892015-01-20 13:26:24 -08001543 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08001544 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001545 """
andrewonlab87852b02014-11-19 18:44:19 -05001546 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001547 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001548 a specific point-to-point intent definition
1549 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001550 * dpidSrc: specify source dpid
1551 * dpidDst: specify destination dpid
1552 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001553 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001554 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001555 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001556 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001557 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001558 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001559 """
andrewonlab87852b02014-11-19 18:44:19 -05001560 try:
kelvin8ec71442015-01-15 16:57:00 -08001561 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001562 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1563 str( numIntents )
1564 if numMult:
1565 cmd += " " + str( numMult )
1566 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001567 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001568 if appId:
1569 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001570 handle = self.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001571 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1572 handle = ansiEscape.sub( '', handle )
andrewonlab87852b02014-11-19 18:44:19 -05001573 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001574 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001575 main.log.info( handle )
1576 # Split result by newline
1577 newline = handle.split( "\r\r\n" )
1578 # Ignore the first object of list, which is empty
1579 newline = newline[ 1: ]
1580 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001581 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001582 result = result.split( ": " )
1583 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001584 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1585 main.log.info( latResult )
1586 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001587 else:
1588 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001589 except TypeError:
1590 main.log.exception( self.name + ": Object not as expected" )
1591 return None
andrewonlab87852b02014-11-19 18:44:19 -05001592 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001593 main.log.error( self.name + ": EOF exception found" )
1594 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001595 main.cleanup()
1596 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001597 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001598 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001599 main.cleanup()
1600 main.exit()
1601
kelvin-onlabd3b64892015-01-20 13:26:24 -08001602 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001603 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001604 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001605 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001606 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001607 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001608 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001609 if jsonFormat:
1610 cmdStr = "intents-events-metrics -j"
1611 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001612 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001613 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1614 handle = ansiEscape.sub( '', handle )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001615 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001616 cmdStr = "intents-events-metrics"
1617 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001618 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001619 except TypeError:
1620 main.log.exception( self.name + ": Object not as expected" )
1621 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001622 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001623 main.log.error( self.name + ": EOF exception found" )
1624 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001625 main.cleanup()
1626 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001627 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001628 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001629 main.cleanup()
1630 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001631
kelvin-onlabd3b64892015-01-20 13:26:24 -08001632 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001633 """
1634 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001635 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001636 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001637 """
andrewonlab867212a2014-10-22 20:13:38 -04001638 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001639 if jsonFormat:
1640 cmdStr = "topology-events-metrics -j"
1641 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001642 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001643 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1644 handle = ansiEscape.sub( '', handle )
andrewonlab867212a2014-10-22 20:13:38 -04001645 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001646 cmdStr = "topology-events-metrics"
1647 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07001648 if handle:
1649 return handle
1650 else:
1651 # Return empty json
1652 return '{}'
Jon Halld4d4b372015-01-28 16:02:41 -08001653 except TypeError:
1654 main.log.exception( self.name + ": Object not as expected" )
1655 return None
andrewonlab867212a2014-10-22 20:13:38 -04001656 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001657 main.log.error( self.name + ": EOF exception found" )
1658 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001659 main.cleanup()
1660 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001661 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001662 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001663 main.cleanup()
1664 main.exit()
1665
kelvin8ec71442015-01-15 16:57:00 -08001666 # Wrapper functions ****************
1667 # Wrapper functions use existing driver
1668 # functions and extends their use case.
1669 # For example, we may use the output of
1670 # a normal driver function, and parse it
1671 # using a wrapper function
andrewonlab7e4d2d32014-10-15 13:23:21 -04001672
kelvin-onlabd3b64892015-01-20 13:26:24 -08001673 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001674 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001675 Description:
1676 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001677 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001678 try:
kelvin8ec71442015-01-15 16:57:00 -08001679 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08001680 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08001681 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001682
kelvin8ec71442015-01-15 16:57:00 -08001683 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001684 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1685 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08001686 match = re.search('id=0x([\da-f]+),', intents)
1687 if match:
1688 tmpId = match.group()[3:-1]
1689 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001690 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001691
Jon Halld4d4b372015-01-28 16:02:41 -08001692 except TypeError:
1693 main.log.exception( self.name + ": Object not as expected" )
1694 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001695 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001696 main.log.error( self.name + ": EOF exception found" )
1697 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001698 main.cleanup()
1699 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001700 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001701 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001702 main.cleanup()
1703 main.exit()
1704
Jon Hall30b82fa2015-03-04 17:15:43 -08001705 def FlowAddedCount( self, deviceId ):
1706 """
1707 Determine the number of flow rules for the given device id that are
1708 in the added state
1709 """
1710 try:
1711 cmdStr = "flows any " + str( deviceId ) + " | " +\
1712 "grep 'state=ADDED' | wc -l"
1713 handle = self.sendline( cmdStr )
1714 return handle
1715 except pexpect.EOF:
1716 main.log.error( self.name + ": EOF exception found" )
1717 main.log.error( self.name + ": " + self.handle.before )
1718 main.cleanup()
1719 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001720 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08001721 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001722 main.cleanup()
1723 main.exit()
1724
kelvin-onlabd3b64892015-01-20 13:26:24 -08001725 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001726 """
andrewonlab95ce8322014-10-13 14:12:04 -04001727 Use 'devices' function to obtain list of all devices
1728 and parse the result to obtain a list of all device
1729 id's. Returns this list. Returns empty list if no
1730 devices exist
kelvin8ec71442015-01-15 16:57:00 -08001731 List is ordered sequentially
1732
andrewonlab95ce8322014-10-13 14:12:04 -04001733 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08001734 device id, and wish to execute other commands using
andrewonlab95ce8322014-10-13 14:12:04 -04001735 the ids. By obtaining the list of device ids on the fly,
1736 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08001737 """
andrewonlab95ce8322014-10-13 14:12:04 -04001738 try:
kelvin8ec71442015-01-15 16:57:00 -08001739 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08001740 devicesStr = self.devices( jsonFormat=False )
1741 idList = []
kelvin8ec71442015-01-15 16:57:00 -08001742
kelvin-onlabd3b64892015-01-20 13:26:24 -08001743 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08001744 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001745 return idList
kelvin8ec71442015-01-15 16:57:00 -08001746
1747 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001748 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08001749 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08001750 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08001751 # Split list further into arguments before and after string
1752 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08001753 # append to idList
1754 for arg in tempList:
1755 idList.append( arg.split( "id=" )[ 1 ] )
1756 return idList
andrewonlab95ce8322014-10-13 14:12:04 -04001757
Jon Halld4d4b372015-01-28 16:02:41 -08001758 except TypeError:
1759 main.log.exception( self.name + ": Object not as expected" )
1760 return None
andrewonlab95ce8322014-10-13 14:12:04 -04001761 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001762 main.log.error( self.name + ": EOF exception found" )
1763 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -04001764 main.cleanup()
1765 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001766 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001767 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04001768 main.cleanup()
1769 main.exit()
1770
kelvin-onlabd3b64892015-01-20 13:26:24 -08001771 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001772 """
andrewonlab7c211572014-10-15 16:45:20 -04001773 Uses 'nodes' function to obtain list of all nodes
1774 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08001775 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04001776 Returns:
1777 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08001778 """
andrewonlab7c211572014-10-15 16:45:20 -04001779 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001780 nodesStr = self.nodes()
1781 idList = []
andrewonlab7c211572014-10-15 16:45:20 -04001782
kelvin-onlabd3b64892015-01-20 13:26:24 -08001783 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08001784 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001785 return idList
andrewonlab7c211572014-10-15 16:45:20 -04001786
kelvin-onlabd3b64892015-01-20 13:26:24 -08001787 # Sample nodesStr output
kelvin8ec71442015-01-15 16:57:00 -08001788 # id=local, address=127.0.0.1:9876, state=ACTIVE *
andrewonlab7c211572014-10-15 16:45:20 -04001789
kelvin8ec71442015-01-15 16:57:00 -08001790 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001791 nodesList = nodesStr.split( "," )
1792 tempList = [ node for node in nodesList if "id=" in node ]
1793 for arg in tempList:
1794 idList.append( arg.split( "id=" )[ 1 ] )
andrewonlab7c211572014-10-15 16:45:20 -04001795
kelvin-onlabd3b64892015-01-20 13:26:24 -08001796 return idList
kelvin8ec71442015-01-15 16:57:00 -08001797
Jon Halld4d4b372015-01-28 16:02:41 -08001798 except TypeError:
1799 main.log.exception( self.name + ": Object not as expected" )
1800 return None
andrewonlab7c211572014-10-15 16:45:20 -04001801 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001802 main.log.error( self.name + ": EOF exception found" )
1803 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04001804 main.cleanup()
1805 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001806 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001807 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04001808 main.cleanup()
1809 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -04001810
kelvin-onlabd3b64892015-01-20 13:26:24 -08001811 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08001812 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001813 Return the first device from the devices api whose 'id' contains 'dpid'
1814 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001815 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001816 try:
kelvin8ec71442015-01-15 16:57:00 -08001817 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04001818 return None
1819 else:
kelvin8ec71442015-01-15 16:57:00 -08001820 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001821 rawDevices = self.devices()
1822 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08001823 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001824 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08001825 # print "%s in %s?" % ( dpid, device[ 'id' ] )
1826 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04001827 return device
1828 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001829 except TypeError:
1830 main.log.exception( self.name + ": Object not as expected" )
1831 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04001832 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001833 main.log.error( self.name + ": EOF exception found" )
1834 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04001835 main.cleanup()
1836 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001837 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001838 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04001839 main.cleanup()
1840 main.exit()
1841
kelvin-onlabd3b64892015-01-20 13:26:24 -08001842 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001843 """
Jon Hallefbd9792015-03-05 16:11:36 -08001844 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001845 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001846 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08001847
Jon Hall42db6dc2014-10-24 19:03:48 -04001848 Params: ip = ip used for the onos cli
1849 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001850 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001851 logLevel = level to log to. Currently accepts
1852 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04001853
1854
kelvin-onlabd3b64892015-01-20 13:26:24 -08001855 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04001856
Jon Hallefbd9792015-03-05 16:11:36 -08001857 Returns: main.TRUE if the number of switches and links are correct,
1858 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04001859 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001860 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001861 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001862 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04001863 if topology == {}:
1864 return main.ERROR
1865 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001866 # Is the number of switches is what we expected
1867 devices = topology.get( 'devices', False )
1868 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08001869 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04001870 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001871 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001872 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001873 linkCheck = ( int( links ) == int( numolink ) )
1874 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08001875 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08001876 output += "The number of links and switches match " +\
1877 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001878 result = main.TRUE
1879 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001880 output += "The number of links and switches does not match " +\
1881 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001882 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001883 output = output + "\n ONOS sees %i devices (%i expected) \
1884 and %i links (%i expected)" % (
1885 int( devices ), int( numoswitch ), int( links ),
1886 int( numolink ) )
1887 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001888 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001889 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001890 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04001891 else:
kelvin8ec71442015-01-15 16:57:00 -08001892 main.log.info( output )
1893 return result
Jon Halld4d4b372015-01-28 16:02:41 -08001894 except TypeError:
1895 main.log.exception( self.name + ": Object not as expected" )
1896 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001897 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001898 main.log.error( self.name + ": EOF exception found" )
1899 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001900 main.cleanup()
1901 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001902 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001903 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001904 main.cleanup()
1905 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001906
kelvin-onlabd3b64892015-01-20 13:26:24 -08001907 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08001908 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001909 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001910 deviceId must be the id of a device as seen in the onos devices command
1911 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04001912 role must be either master, standby, or none
1913
Jon Halle3f39ff2015-01-13 11:50:53 -08001914 Returns:
1915 main.TRUE or main.FALSE based on argument verification and
1916 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001917 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001918 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001919 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04001920 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08001921 cmdStr = "device-role " +\
1922 str( deviceId ) + " " +\
1923 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001924 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001925 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001926 if re.search( "Error", handle ):
1927 # end color output to escape any colours
1928 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08001929 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001930 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08001931 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08001932 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04001933 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001934 main.log.error( "Invalid 'role' given to device_role(). " +
1935 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04001936 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001937 except TypeError:
1938 main.log.exception( self.name + ": Object not as expected" )
1939 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04001940 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001941 main.log.error( self.name + ": EOF exception found" )
1942 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04001943 main.cleanup()
1944 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001945 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001946 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04001947 main.cleanup()
1948 main.exit()
1949
kelvin-onlabd3b64892015-01-20 13:26:24 -08001950 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001951 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001952 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08001953 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001954 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001955 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001956 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001957 if jsonFormat:
1958 cmdStr = "clusters -j"
1959 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001960 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001961 handle variable here contains some ANSI escape color code
1962 sequences at the end which are invisible in the print command
Jon Halle3f39ff2015-01-13 11:50:53 -08001963 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -08001964 function. The repr( handle ) output when printed shows the ANSI
1965 escape sequences. In json.loads( somestring ), this somestring
kelvin-onlabd3b64892015-01-20 13:26:24 -08001966 variable is actually repr( somestring ) and json.loads would
1967 fail with the escape sequence. So we take off that escape
1968 sequence using:
Jon Halle3f39ff2015-01-13 11:50:53 -08001969
kelvin-onlabd3b64892015-01-20 13:26:24 -08001970 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1971 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001972 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001973 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1974 handle1 = ansiEscape.sub( '', handle )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001975 return handle1
1976 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001977 cmdStr = "clusters"
1978 handle = self.sendline( cmdStr )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001979 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001980 except TypeError:
1981 main.log.exception( self.name + ": Object not as expected" )
1982 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08001983 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001984 main.log.error( self.name + ": EOF exception found" )
1985 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001986 main.cleanup()
1987 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001988 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001989 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001990 main.cleanup()
1991 main.exit()
1992
kelvin-onlabd3b64892015-01-20 13:26:24 -08001993 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001994 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001995 CLI command to get the current leader for the Election test application
1996 NOTE: Requires installation of the onos-app-election feature
1997 Returns: Node IP of the leader if one exists
1998 None if none exists
1999 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002000 """
Jon Hall94fd0472014-12-08 11:52:42 -08002001 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002002 cmdStr = "election-test-leader"
2003 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002004 # Leader
2005 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002006 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002007 nodeSearch = re.search( leaderPattern, response )
2008 if nodeSearch:
2009 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002010 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002011 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002012 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002013 # no leader
2014 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002015 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002016 nullSearch = re.search( nullPattern, response )
2017 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002018 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002019 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002020 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002021 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002022 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002023 if re.search( errorPattern, response ):
2024 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002025 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002026 return main.FALSE
2027 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002028 main.log.error( "Error in election_test_leader: " +
2029 "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002030 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002031 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002032 except TypeError:
2033 main.log.exception( self.name + ": Object not as expected" )
2034 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002035 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002036 main.log.error( self.name + ": EOF exception found" )
2037 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002038 main.cleanup()
2039 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002040 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002041 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002042 main.cleanup()
2043 main.exit()
2044
kelvin-onlabd3b64892015-01-20 13:26:24 -08002045 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002046 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002047 CLI command to run for leadership of the Election test application.
2048 NOTE: Requires installation of the onos-app-election feature
2049 Returns: Main.TRUE on success
2050 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002051 """
Jon Hall94fd0472014-12-08 11:52:42 -08002052 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002053 cmdStr = "election-test-run"
2054 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002055 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002056 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002057 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002058 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002059 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002060 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002061 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002062 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002063 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002064 errorPattern = "Command\snot\sfound"
2065 if re.search( errorPattern, response ):
2066 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002067 return main.FALSE
2068 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002069 main.log.error( "Error in election_test_run: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002070 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002071 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002072 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002073 except TypeError:
2074 main.log.exception( self.name + ": Object not as expected" )
2075 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002076 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002077 main.log.error( self.name + ": EOF exception found" )
2078 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002079 main.cleanup()
2080 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002081 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002082 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002083 main.cleanup()
2084 main.exit()
2085
kelvin-onlabd3b64892015-01-20 13:26:24 -08002086 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002087 """
Jon Hall94fd0472014-12-08 11:52:42 -08002088 * CLI command to withdraw the local node from leadership election for
2089 * the Election test application.
2090 #NOTE: Requires installation of the onos-app-election feature
2091 Returns: Main.TRUE on success
2092 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002093 """
Jon Hall94fd0472014-12-08 11:52:42 -08002094 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002095 cmdStr = "election-test-withdraw"
2096 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002097 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002098 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002099 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002100 if re.search( successPattern, response ):
2101 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002102 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002103 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002104 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002105 errorPattern = "Command\snot\sfound"
2106 if re.search( errorPattern, response ):
2107 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002108 return main.FALSE
2109 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002110 main.log.error( "Error in election_test_withdraw: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002111 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002112 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002113 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002114 except TypeError:
2115 main.log.exception( self.name + ": Object not as expected" )
2116 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002117 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002118 main.log.error( self.name + ": EOF exception found" )
2119 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002120 main.cleanup()
2121 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002122 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002123 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002124 main.cleanup()
2125 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002126
kelvin8ec71442015-01-15 16:57:00 -08002127 def getDevicePortsEnabledCount( self, dpid ):
2128 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002129 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002130 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002131 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002132 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002133 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2134 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002135 if re.search( "No such device", output ):
2136 main.log.error( "Error in getting ports" )
2137 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002138 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002139 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002140 except TypeError:
2141 main.log.exception( self.name + ": Object not as expected" )
2142 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002143 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002144 main.log.error( self.name + ": EOF exception found" )
2145 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002146 main.cleanup()
2147 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002148 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002149 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002150 main.cleanup()
2151 main.exit()
2152
kelvin8ec71442015-01-15 16:57:00 -08002153 def getDeviceLinksActiveCount( self, dpid ):
2154 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002155 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002156 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002157 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002158 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002159 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2160 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002161 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002162 main.log.error( "Error in getting ports " )
2163 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002164 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002165 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002166 except TypeError:
2167 main.log.exception( self.name + ": Object not as expected" )
2168 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002169 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002170 main.log.error( self.name + ": EOF exception found" )
2171 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002172 main.cleanup()
2173 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002174 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002175 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002176 main.cleanup()
2177 main.exit()
2178
kelvin8ec71442015-01-15 16:57:00 -08002179 def getAllIntentIds( self ):
2180 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002181 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002182 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002183 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002184 cmdStr = "onos:intents | grep id="
2185 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002186 if re.search( "Error", output ):
2187 main.log.error( "Error in getting ports" )
2188 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002189 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002190 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002191 except TypeError:
2192 main.log.exception( self.name + ": Object not as expected" )
2193 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002194 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002195 main.log.error( self.name + ": EOF exception found" )
2196 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002197 main.cleanup()
2198 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002199 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002200 main.log.exception( self.name + ": Uncaught exception!" )
2201 main.cleanup()
2202 main.exit()
2203
Jon Hall73509952015-02-24 16:42:56 -08002204 def intentSummary( self ):
2205 """
Jon Hallefbd9792015-03-05 16:11:36 -08002206 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002207 """
2208 try:
2209 intents = self.intents( )
2210 intentStates = []
Jon Hall63604932015-02-26 17:09:50 -08002211 for intent in json.loads( intents ): # Iter through intents of a node
Jon Hall73509952015-02-24 16:42:56 -08002212 intentStates.append( intent.get( 'state', None ) )
Jon Hall63604932015-02-26 17:09:50 -08002213 out = [ (i, intentStates.count( i ) ) for i in set( intentStates ) ]
2214 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002215 return dict( out )
2216 except TypeError:
2217 main.log.exception( self.name + ": Object not as expected" )
2218 return None
2219 except pexpect.EOF:
2220 main.log.error( self.name + ": EOF exception found" )
2221 main.log.error( self.name + ": " + self.handle.before )
2222 main.cleanup()
2223 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002224 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002225 main.log.exception( self.name + ": Uncaught exception!" )
2226 main.cleanup()
2227 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002228
Jon Hall61282e32015-03-19 11:34:11 -07002229 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002230 """
2231 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002232 Optional argument:
2233 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002234 """
2235 # FIXME: add json output
Jon Hall61282e32015-03-19 11:34:11 -07002236 # Sample JSON
2237 # {
2238 # "electedTime": "13m ago",
2239 # "epoch": 4,
2240 # "leader": "10.128.30.17",
2241 # "topic": "intent-partition-3"
2242 # },
Jon Hall63604932015-02-26 17:09:50 -08002243 try:
Jon Hall61282e32015-03-19 11:34:11 -07002244 if jsonFormat:
2245 cmdStr = "onos:leaders -j"
2246 output = self.sendline( cmdStr )
2247 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2248 cleanedOutput = ansiEscape.sub( '', output )
2249 return cleanedOutput
2250 else:
2251 cmdStr = "onos:leaders"
2252 output = self.sendline( cmdStr )
2253 return output
Jon Hall63604932015-02-26 17:09:50 -08002254 except TypeError:
2255 main.log.exception( self.name + ": Object not as expected" )
2256 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002257 except pexpect.EOF:
2258 main.log.error( self.name + ": EOF exception found" )
2259 main.log.error( self.name + ": " + self.handle.before )
2260 main.cleanup()
2261 main.exit()
2262 except:
Jon Hall63604932015-02-26 17:09:50 -08002263 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002264 main.cleanup()
2265 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002266
Jon Hall61282e32015-03-19 11:34:11 -07002267 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002268 """
2269 Returns the output of the intent Pending map.
2270 """
Jon Hall63604932015-02-26 17:09:50 -08002271 try:
Jon Hall61282e32015-03-19 11:34:11 -07002272 if jsonFormat:
2273 cmdStr = "onos:intents -p -j"
2274 output = self.sendline( cmdStr )
2275 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2276 cleanedOutput = ansiEscape.sub( '', output )
2277 return cleanedOutput
2278 else:
2279 cmdStr = "onos:intents -p"
2280 output = self.sendline( cmdStr )
2281 return output
Jon Hall63604932015-02-26 17:09:50 -08002282 except TypeError:
2283 main.log.exception( self.name + ": Object not as expected" )
2284 return None
2285 except pexpect.EOF:
2286 main.log.error( self.name + ": EOF exception found" )
2287 main.log.error( self.name + ": " + self.handle.before )
2288 main.cleanup()
2289 main.exit()
2290 except:
2291 main.log.exception( self.name + ": Uncaught exception!" )
2292 main.cleanup()
2293 main.exit()
2294
Jon Hall61282e32015-03-19 11:34:11 -07002295 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002296 """
2297 Returns the output of the raft partitions command for ONOS.
2298 """
Jon Hall61282e32015-03-19 11:34:11 -07002299 # Sample JSON
2300 # {
2301 # "leader": "tcp://10.128.30.11:7238",
2302 # "members": [
2303 # "tcp://10.128.30.11:7238",
2304 # "tcp://10.128.30.17:7238",
2305 # "tcp://10.128.30.13:7238",
2306 # ],
2307 # "name": "p1",
2308 # "term": 3
2309 # },
Jon Hall63604932015-02-26 17:09:50 -08002310 try:
Jon Hall61282e32015-03-19 11:34:11 -07002311 if jsonFormat:
2312 cmdStr = "onos:partitions -j"
2313 output = self.sendline( cmdStr )
2314 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2315 cleanedOutput = ansiEscape.sub( '', output )
2316 return cleanedOutput
2317 else:
2318 cmdStr = "onos:partitions"
2319 output = self.sendline( cmdStr )
2320 return output
Jon Hall63604932015-02-26 17:09:50 -08002321 except TypeError:
2322 main.log.exception( self.name + ": Object not as expected" )
2323 return None
2324 except pexpect.EOF:
2325 main.log.error( self.name + ": EOF exception found" )
2326 main.log.error( self.name + ": " + self.handle.before )
2327 main.cleanup()
2328 main.exit()
2329 except:
2330 main.log.exception( self.name + ": Uncaught exception!" )
2331 main.cleanup()
2332 main.exit()
2333