blob: 9ba27908246801c984273b9ee2324d4a3a2cba3e [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,
shahshreyac2f97072015-03-19 17:04:29 -07001190 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001191 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001192 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001193 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001194 ethType="",
1195 ethSrc="",
1196 ethDst="",
1197 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001198 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001199 ipProto="",
1200 ipSrc="",
1201 ipDst="",
1202 tcpSrc="",
1203 tcpDst="",
1204 setEthSrc="",
1205 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001206 """
shahshreyad0c80432014-12-04 16:56:05 -08001207 Note:
shahshreya70622b12015-03-19 17:19:00 -07001208 This function assumes the format of all ingress devices
1209 is same. That is, all ingress devices include port nos
1210 with a "/" or all ingress devices could specify device
1211 ids and port nos seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001212 Required:
shahshreyac2f97072015-03-19 17:04:29 -07001213 * ingressDeviceList: List of device ids of ingress device
1214 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001215 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001216 Optional:
1217 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001218 * ethSrc: specify ethSrc ( i.e. src mac addr )
1219 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001220 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001221 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001222 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001223 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001224 * ipSrc: specify ip source address
1225 * ipDst: specify ip destination address
1226 * tcpSrc: specify tcp source port
1227 * tcpDst: specify tcp destination port
1228 * setEthSrc: action to Rewrite Source MAC Address
1229 * setEthDst: action to Rewrite Destination MAC Address
1230 Description:
kelvin8ec71442015-01-15 16:57:00 -08001231 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001232 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001233 Returns:
1234 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001235
Jon Halle3f39ff2015-01-13 11:50:53 -08001236 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001237 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001238 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001239 """
shahshreyad0c80432014-12-04 16:56:05 -08001240 try:
kelvin8ec71442015-01-15 16:57:00 -08001241 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001242 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001243 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001244 and not ipProto and not ipSrc and not ipDst\
1245 and not tcpSrc and not tcpDst and not setEthSrc\
1246 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001247 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001248
1249 else:
1250 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001251
shahshreyad0c80432014-12-04 16:56:05 -08001252 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001253 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001254 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001255 cmd += " --ethSrc " + str( ethSrc )
1256 if ethDst:
1257 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001258 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001259 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001260 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001261 cmd += " --lambda "
1262 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001263 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001264 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001265 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001266 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001267 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001268 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001269 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001270 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001271 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001272 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001273 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001274 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001275 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001276
kelvin8ec71442015-01-15 16:57:00 -08001277 # Check whether the user appended the port
1278 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001279
1280 if portIngressList is None:
1281 for ingressDevice in ingressDeviceList:
1282 if "/" in ingressDevice:
1283 cmd += " " + str( ingressDevice )
1284 else:
1285 main.log.error( "You must specify " +
1286 "the ingress port" )
1287 # TODO: perhaps more meaningful return
1288 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001289 else:
shahshreya70622b12015-03-19 17:19:00 -07001290 if len( ingressDeviceList ) == len( portIngressList )
1291 for ingressDevice,portIngress in zip( ingressDeviceList,portIngressList ):
1292 cmd += " " + \
1293 str( ingressDevice ) + "/" +\
1294 str( portIngress ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001295
kelvin-onlabd3b64892015-01-20 13:26:24 -08001296 if "/" in egressDevice:
1297 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001298 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001299 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001300 main.log.error( "You must specify " +
1301 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001302 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001303
kelvin8ec71442015-01-15 16:57:00 -08001304 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001305 str( egressDevice ) + "/" +\
1306 str( portEgress )
shahshreyac2f97072015-03-19 17:04:29 -07001307
kelvin8ec71442015-01-15 16:57:00 -08001308 print "cmd= ", cmd
kelvin-onlab898a6c62015-01-16 14:13:53 -08001309 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001310 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001311 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001312 main.log.error( "Error in adding multipoint-to-singlepoint " +
1313 "intent" )
1314 return None
shahshreyad0c80432014-12-04 16:56:05 -08001315 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001316 # TODO: print out all the options in this message?
1317 main.log.info( "Multipoint-to-singlepoint intent installed" +
shahshreyac2f97072015-03-19 17:04:29 -07001318 " failed " )
1319 return None
1320 #match = re.search('id=0x([\da-f]+),', handle)
1321 #if match:
1322 #return match.group()[3:-1]
1323 #else:
1324 #main.log.error( "Error, intent ID not found" )
1325 #return None
Jon Halld4d4b372015-01-28 16:02:41 -08001326 except TypeError:
1327 main.log.exception( self.name + ": Object not as expected" )
1328 return None
shahshreyad0c80432014-12-04 16:56:05 -08001329 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001330 main.log.error( self.name + ": EOF exception found" )
1331 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001332 main.cleanup()
1333 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001334 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001335 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001336 main.cleanup()
1337 main.exit()
1338
Jon Hallefbd9792015-03-05 16:11:36 -08001339 def removeIntent( self, intentId, app='org.onosproject.cli',
1340 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001341 """
shahshreya1c818fc2015-02-26 13:44:08 -08001342 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001343 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001344 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001345 -p or --purge: Purge the intent from the store after removal
1346
Jon Halle3f39ff2015-01-13 11:50:53 -08001347 Returns:
1348 main.False on error and
1349 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001350 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001351 try:
shahshreya1c818fc2015-02-26 13:44:08 -08001352 cmdStr = "remove-intent "
1353 if purge:
1354 cmdStr += " -p"
1355 if sync:
1356 cmdStr += " -s"
1357
1358 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001359 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001360 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001361 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001362 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001363 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001364 # TODO: Should this be main.TRUE
1365 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001366 except TypeError:
1367 main.log.exception( self.name + ": Object not as expected" )
1368 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001369 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001370 main.log.error( self.name + ": EOF exception found" )
1371 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001372 main.cleanup()
1373 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001374 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001375 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001376 main.cleanup()
1377 main.exit()
1378
kelvin-onlabd3b64892015-01-20 13:26:24 -08001379 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001380 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001381 NOTE: This method should be used after installing application:
1382 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001383 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001384 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001385 Description:
1386 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001387 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001388 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001389 if jsonFormat:
1390 cmdStr = "routes -j"
1391 handleTmp = self.sendline( cmdStr )
1392 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1393 handle = ansiEscape.sub( '', handleTmp )
pingping-lin8b306ac2014-11-17 18:13:51 -08001394 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001395 cmdStr = "routes"
1396 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001397 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001398 except TypeError:
1399 main.log.exception( self.name + ": Object not as expected" )
1400 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001401 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001402 main.log.error( self.name + ": EOF exception found" )
1403 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001404 main.cleanup()
1405 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001406 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001407 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001408 main.cleanup()
1409 main.exit()
1410
kelvin-onlabd3b64892015-01-20 13:26:24 -08001411 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001412 """
andrewonlab377693f2014-10-21 16:00:30 -04001413 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001414 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001415 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001416 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001417 """
andrewonlabe6745342014-10-17 14:29:13 -04001418 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001419 if jsonFormat:
1420 cmdStr = "intents -j"
1421 handle = self.sendline( cmdStr )
1422 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1423 handle = ansiEscape.sub( '', handle )
kelvin8ec71442015-01-15 16:57:00 -08001424 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001425 cmdStr = "intents"
1426 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001427 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001428 except TypeError:
1429 main.log.exception( self.name + ": Object not as expected" )
1430 return None
andrewonlabe6745342014-10-17 14:29:13 -04001431 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001432 main.log.error( self.name + ": EOF exception found" )
1433 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001434 main.cleanup()
1435 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001436 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001437 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001438 main.cleanup()
1439 main.exit()
1440
kelvin-onlab54400a92015-02-26 18:05:51 -08001441 def getIntentState(self, intentsId, intentsJson=None):
1442 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001443 Check intent state.
1444 Accepts a single intent ID (string type) or a list of intent IDs.
1445 Returns the state(string type) of the id if a single intent ID is
1446 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001447 Returns a dictionary with intent IDs as the key and its
1448 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001449 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001450 intentId: intent ID (string type)
1451 intentsJson: parsed json object from the onos:intents api
1452 Returns:
1453 state = An intent's state- INSTALL,WITHDRAWN etc.
1454 stateDict = Dictionary of intent's state. intent ID as the keys and
1455 state as the values.
1456 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001457 try:
1458 state = "State is Undefined"
1459 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001460 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001461 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001462 intentsJsonTemp = json.loads( intentsJson )
1463 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001464 for intent in intentsJsonTemp:
1465 if intentsId == intent['id']:
1466 state = intent['state']
1467 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001468 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1469 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001470 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001471 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001472 dictList = []
kelvin-onlab54400a92015-02-26 18:05:51 -08001473 for ID in intentsId:
kelvin-onlab07dbd012015-03-04 16:29:39 -08001474 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001475 for intents in intentsJsonTemp:
1476 if ID == intents['id']:
kelvin-onlab07dbd012015-03-04 16:29:39 -08001477 stateDict['state'] = intents['state']
1478 stateDict['id'] = ID
Jon Hallefbd9792015-03-05 16:11:36 -08001479 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001480 break
Jon Hallefbd9792015-03-05 16:11:36 -08001481 if len( intentsId ) != len( dictList ):
1482 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001483 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001484 else:
1485 main.log.info("Invalid intents ID entry")
1486 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001487 except TypeError:
1488 main.log.exception( self.name + ": Object not as expected" )
1489 return None
1490 except pexpect.EOF:
1491 main.log.error( self.name + ": EOF exception found" )
1492 main.log.error( self.name + ": " + self.handle.before )
1493 main.cleanup()
1494 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001495 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001496 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001497 main.cleanup()
1498 main.exit()
1499
kelvin-onlabd3b64892015-01-20 13:26:24 -08001500 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001501 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001502 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001503 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001504 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001505 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001506 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001507 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001508 if jsonFormat:
1509 cmdStr = "flows -j"
1510 handle = self.sendline( cmdStr )
1511 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1512 handle = ansiEscape.sub( '', handle )
Shreya Shah0f01c812014-10-26 20:15:28 -04001513 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001514 cmdStr = "flows"
1515 handle = self.sendline( cmdStr )
Jon Hall61282e32015-03-19 11:34:11 -07001516 if re.search( "Error:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001517 main.log.error( self.name + ".flows() response: " +
1518 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001519 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001520 except TypeError:
1521 main.log.exception( self.name + ": Object not as expected" )
1522 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001523 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001524 main.log.error( self.name + ": EOF exception found" )
1525 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001526 main.cleanup()
1527 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001528 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001529 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001530 main.cleanup()
1531 main.exit()
1532
kelvin-onlabd3b64892015-01-20 13:26:24 -08001533 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08001534 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001535 """
andrewonlab87852b02014-11-19 18:44:19 -05001536 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001537 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001538 a specific point-to-point intent definition
1539 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001540 * dpidSrc: specify source dpid
1541 * dpidDst: specify destination dpid
1542 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001543 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001544 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001545 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001546 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001547 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001548 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001549 """
andrewonlab87852b02014-11-19 18:44:19 -05001550 try:
kelvin8ec71442015-01-15 16:57:00 -08001551 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001552 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1553 str( numIntents )
1554 if numMult:
1555 cmd += " " + str( numMult )
1556 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001557 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001558 if appId:
1559 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001560 handle = self.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001561 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1562 handle = ansiEscape.sub( '', handle )
andrewonlab87852b02014-11-19 18:44:19 -05001563 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001564 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001565 main.log.info( handle )
1566 # Split result by newline
1567 newline = handle.split( "\r\r\n" )
1568 # Ignore the first object of list, which is empty
1569 newline = newline[ 1: ]
1570 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001571 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001572 result = result.split( ": " )
1573 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001574 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1575 main.log.info( latResult )
1576 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001577 else:
1578 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001579 except TypeError:
1580 main.log.exception( self.name + ": Object not as expected" )
1581 return None
andrewonlab87852b02014-11-19 18:44:19 -05001582 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001583 main.log.error( self.name + ": EOF exception found" )
1584 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001585 main.cleanup()
1586 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001587 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001588 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001589 main.cleanup()
1590 main.exit()
1591
kelvin-onlabd3b64892015-01-20 13:26:24 -08001592 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001593 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001594 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001595 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001596 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001597 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001598 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001599 if jsonFormat:
1600 cmdStr = "intents-events-metrics -j"
1601 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001602 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001603 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1604 handle = ansiEscape.sub( '', handle )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001605 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001606 cmdStr = "intents-events-metrics"
1607 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001608 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001609 except TypeError:
1610 main.log.exception( self.name + ": Object not as expected" )
1611 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001612 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001613 main.log.error( self.name + ": EOF exception found" )
1614 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001615 main.cleanup()
1616 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001617 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001618 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001619 main.cleanup()
1620 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001621
kelvin-onlabd3b64892015-01-20 13:26:24 -08001622 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001623 """
1624 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001625 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001626 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001627 """
andrewonlab867212a2014-10-22 20:13:38 -04001628 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001629 if jsonFormat:
1630 cmdStr = "topology-events-metrics -j"
1631 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001632 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001633 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1634 handle = ansiEscape.sub( '', handle )
andrewonlab867212a2014-10-22 20:13:38 -04001635 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001636 cmdStr = "topology-events-metrics"
1637 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07001638 if handle:
1639 return handle
1640 else:
1641 # Return empty json
1642 return '{}'
Jon Halld4d4b372015-01-28 16:02:41 -08001643 except TypeError:
1644 main.log.exception( self.name + ": Object not as expected" )
1645 return None
andrewonlab867212a2014-10-22 20:13:38 -04001646 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001647 main.log.error( self.name + ": EOF exception found" )
1648 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001649 main.cleanup()
1650 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001651 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001652 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001653 main.cleanup()
1654 main.exit()
1655
kelvin8ec71442015-01-15 16:57:00 -08001656 # Wrapper functions ****************
1657 # Wrapper functions use existing driver
1658 # functions and extends their use case.
1659 # For example, we may use the output of
1660 # a normal driver function, and parse it
1661 # using a wrapper function
andrewonlab7e4d2d32014-10-15 13:23:21 -04001662
kelvin-onlabd3b64892015-01-20 13:26:24 -08001663 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001664 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001665 Description:
1666 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001667 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001668 try:
kelvin8ec71442015-01-15 16:57:00 -08001669 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08001670 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08001671 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001672
kelvin8ec71442015-01-15 16:57:00 -08001673 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001674 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1675 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08001676 match = re.search('id=0x([\da-f]+),', intents)
1677 if match:
1678 tmpId = match.group()[3:-1]
1679 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001680 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001681
Jon Halld4d4b372015-01-28 16:02:41 -08001682 except TypeError:
1683 main.log.exception( self.name + ": Object not as expected" )
1684 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001685 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001686 main.log.error( self.name + ": EOF exception found" )
1687 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001688 main.cleanup()
1689 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001690 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001691 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001692 main.cleanup()
1693 main.exit()
1694
Jon Hall30b82fa2015-03-04 17:15:43 -08001695 def FlowAddedCount( self, deviceId ):
1696 """
1697 Determine the number of flow rules for the given device id that are
1698 in the added state
1699 """
1700 try:
1701 cmdStr = "flows any " + str( deviceId ) + " | " +\
1702 "grep 'state=ADDED' | wc -l"
1703 handle = self.sendline( cmdStr )
1704 return handle
1705 except pexpect.EOF:
1706 main.log.error( self.name + ": EOF exception found" )
1707 main.log.error( self.name + ": " + self.handle.before )
1708 main.cleanup()
1709 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001710 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08001711 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001712 main.cleanup()
1713 main.exit()
1714
kelvin-onlabd3b64892015-01-20 13:26:24 -08001715 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001716 """
andrewonlab95ce8322014-10-13 14:12:04 -04001717 Use 'devices' function to obtain list of all devices
1718 and parse the result to obtain a list of all device
1719 id's. Returns this list. Returns empty list if no
1720 devices exist
kelvin8ec71442015-01-15 16:57:00 -08001721 List is ordered sequentially
1722
andrewonlab95ce8322014-10-13 14:12:04 -04001723 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08001724 device id, and wish to execute other commands using
andrewonlab95ce8322014-10-13 14:12:04 -04001725 the ids. By obtaining the list of device ids on the fly,
1726 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08001727 """
andrewonlab95ce8322014-10-13 14:12:04 -04001728 try:
kelvin8ec71442015-01-15 16:57:00 -08001729 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08001730 devicesStr = self.devices( jsonFormat=False )
1731 idList = []
kelvin8ec71442015-01-15 16:57:00 -08001732
kelvin-onlabd3b64892015-01-20 13:26:24 -08001733 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08001734 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001735 return idList
kelvin8ec71442015-01-15 16:57:00 -08001736
1737 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001738 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08001739 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08001740 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08001741 # Split list further into arguments before and after string
1742 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08001743 # append to idList
1744 for arg in tempList:
1745 idList.append( arg.split( "id=" )[ 1 ] )
1746 return idList
andrewonlab95ce8322014-10-13 14:12:04 -04001747
Jon Halld4d4b372015-01-28 16:02:41 -08001748 except TypeError:
1749 main.log.exception( self.name + ": Object not as expected" )
1750 return None
andrewonlab95ce8322014-10-13 14:12:04 -04001751 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001752 main.log.error( self.name + ": EOF exception found" )
1753 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -04001754 main.cleanup()
1755 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001756 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001757 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04001758 main.cleanup()
1759 main.exit()
1760
kelvin-onlabd3b64892015-01-20 13:26:24 -08001761 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001762 """
andrewonlab7c211572014-10-15 16:45:20 -04001763 Uses 'nodes' function to obtain list of all nodes
1764 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08001765 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04001766 Returns:
1767 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08001768 """
andrewonlab7c211572014-10-15 16:45:20 -04001769 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001770 nodesStr = self.nodes()
1771 idList = []
andrewonlab7c211572014-10-15 16:45:20 -04001772
kelvin-onlabd3b64892015-01-20 13:26:24 -08001773 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08001774 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001775 return idList
andrewonlab7c211572014-10-15 16:45:20 -04001776
kelvin-onlabd3b64892015-01-20 13:26:24 -08001777 # Sample nodesStr output
kelvin8ec71442015-01-15 16:57:00 -08001778 # id=local, address=127.0.0.1:9876, state=ACTIVE *
andrewonlab7c211572014-10-15 16:45:20 -04001779
kelvin8ec71442015-01-15 16:57:00 -08001780 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001781 nodesList = nodesStr.split( "," )
1782 tempList = [ node for node in nodesList if "id=" in node ]
1783 for arg in tempList:
1784 idList.append( arg.split( "id=" )[ 1 ] )
andrewonlab7c211572014-10-15 16:45:20 -04001785
kelvin-onlabd3b64892015-01-20 13:26:24 -08001786 return idList
kelvin8ec71442015-01-15 16:57:00 -08001787
Jon Halld4d4b372015-01-28 16:02:41 -08001788 except TypeError:
1789 main.log.exception( self.name + ": Object not as expected" )
1790 return None
andrewonlab7c211572014-10-15 16:45:20 -04001791 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001792 main.log.error( self.name + ": EOF exception found" )
1793 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04001794 main.cleanup()
1795 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001796 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001797 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04001798 main.cleanup()
1799 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -04001800
kelvin-onlabd3b64892015-01-20 13:26:24 -08001801 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08001802 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001803 Return the first device from the devices api whose 'id' contains 'dpid'
1804 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001805 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001806 try:
kelvin8ec71442015-01-15 16:57:00 -08001807 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04001808 return None
1809 else:
kelvin8ec71442015-01-15 16:57:00 -08001810 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001811 rawDevices = self.devices()
1812 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08001813 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001814 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08001815 # print "%s in %s?" % ( dpid, device[ 'id' ] )
1816 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04001817 return device
1818 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001819 except TypeError:
1820 main.log.exception( self.name + ": Object not as expected" )
1821 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04001822 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001823 main.log.error( self.name + ": EOF exception found" )
1824 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04001825 main.cleanup()
1826 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001827 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001828 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04001829 main.cleanup()
1830 main.exit()
1831
kelvin-onlabd3b64892015-01-20 13:26:24 -08001832 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001833 """
Jon Hallefbd9792015-03-05 16:11:36 -08001834 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001835 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001836 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08001837
Jon Hall42db6dc2014-10-24 19:03:48 -04001838 Params: ip = ip used for the onos cli
1839 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001840 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001841 logLevel = level to log to. Currently accepts
1842 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04001843
1844
kelvin-onlabd3b64892015-01-20 13:26:24 -08001845 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04001846
Jon Hallefbd9792015-03-05 16:11:36 -08001847 Returns: main.TRUE if the number of switches and links are correct,
1848 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04001849 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001850 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001851 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001852 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04001853 if topology == {}:
1854 return main.ERROR
1855 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001856 # Is the number of switches is what we expected
1857 devices = topology.get( 'devices', False )
1858 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08001859 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04001860 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001861 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001862 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001863 linkCheck = ( int( links ) == int( numolink ) )
1864 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08001865 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08001866 output += "The number of links and switches match " +\
1867 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001868 result = main.TRUE
1869 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001870 output += "The number of links and switches does not match " +\
1871 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001872 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001873 output = output + "\n ONOS sees %i devices (%i expected) \
1874 and %i links (%i expected)" % (
1875 int( devices ), int( numoswitch ), int( links ),
1876 int( numolink ) )
1877 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001878 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001879 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001880 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04001881 else:
kelvin8ec71442015-01-15 16:57:00 -08001882 main.log.info( output )
1883 return result
Jon Halld4d4b372015-01-28 16:02:41 -08001884 except TypeError:
1885 main.log.exception( self.name + ": Object not as expected" )
1886 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001887 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001888 main.log.error( self.name + ": EOF exception found" )
1889 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001890 main.cleanup()
1891 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001892 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001893 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001894 main.cleanup()
1895 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001896
kelvin-onlabd3b64892015-01-20 13:26:24 -08001897 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08001898 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001899 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001900 deviceId must be the id of a device as seen in the onos devices command
1901 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04001902 role must be either master, standby, or none
1903
Jon Halle3f39ff2015-01-13 11:50:53 -08001904 Returns:
1905 main.TRUE or main.FALSE based on argument verification and
1906 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001907 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001908 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001909 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04001910 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08001911 cmdStr = "device-role " +\
1912 str( deviceId ) + " " +\
1913 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001914 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001915 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001916 if re.search( "Error", handle ):
1917 # end color output to escape any colours
1918 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08001919 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001920 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08001921 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08001922 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04001923 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001924 main.log.error( "Invalid 'role' given to device_role(). " +
1925 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04001926 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001927 except TypeError:
1928 main.log.exception( self.name + ": Object not as expected" )
1929 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04001930 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001931 main.log.error( self.name + ": EOF exception found" )
1932 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04001933 main.cleanup()
1934 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001935 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001936 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04001937 main.cleanup()
1938 main.exit()
1939
kelvin-onlabd3b64892015-01-20 13:26:24 -08001940 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001941 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001942 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08001943 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001944 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001945 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001946 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001947 if jsonFormat:
1948 cmdStr = "clusters -j"
1949 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001950 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001951 handle variable here contains some ANSI escape color code
1952 sequences at the end which are invisible in the print command
Jon Halle3f39ff2015-01-13 11:50:53 -08001953 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -08001954 function. The repr( handle ) output when printed shows the ANSI
1955 escape sequences. In json.loads( somestring ), this somestring
kelvin-onlabd3b64892015-01-20 13:26:24 -08001956 variable is actually repr( somestring ) and json.loads would
1957 fail with the escape sequence. So we take off that escape
1958 sequence using:
Jon Halle3f39ff2015-01-13 11:50:53 -08001959
kelvin-onlabd3b64892015-01-20 13:26:24 -08001960 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1961 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001962 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001963 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1964 handle1 = ansiEscape.sub( '', handle )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001965 return handle1
1966 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001967 cmdStr = "clusters"
1968 handle = self.sendline( cmdStr )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001969 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001970 except TypeError:
1971 main.log.exception( self.name + ": Object not as expected" )
1972 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08001973 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001974 main.log.error( self.name + ": EOF exception found" )
1975 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001976 main.cleanup()
1977 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001978 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001979 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001980 main.cleanup()
1981 main.exit()
1982
kelvin-onlabd3b64892015-01-20 13:26:24 -08001983 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001984 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001985 CLI command to get the current leader for the Election test application
1986 NOTE: Requires installation of the onos-app-election feature
1987 Returns: Node IP of the leader if one exists
1988 None if none exists
1989 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001990 """
Jon Hall94fd0472014-12-08 11:52:42 -08001991 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001992 cmdStr = "election-test-leader"
1993 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001994 # Leader
1995 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001996 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08001997 nodeSearch = re.search( leaderPattern, response )
1998 if nodeSearch:
1999 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002000 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002001 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002002 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002003 # no leader
2004 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002005 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002006 nullSearch = re.search( nullPattern, response )
2007 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002008 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002009 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002010 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002011 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002012 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002013 if re.search( errorPattern, response ):
2014 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002015 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002016 return main.FALSE
2017 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002018 main.log.error( "Error in election_test_leader: " +
2019 "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002020 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002021 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002022 except TypeError:
2023 main.log.exception( self.name + ": Object not as expected" )
2024 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002025 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002026 main.log.error( self.name + ": EOF exception found" )
2027 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002028 main.cleanup()
2029 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002030 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002031 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002032 main.cleanup()
2033 main.exit()
2034
kelvin-onlabd3b64892015-01-20 13:26:24 -08002035 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002036 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002037 CLI command to run for leadership of the Election test application.
2038 NOTE: Requires installation of the onos-app-election feature
2039 Returns: Main.TRUE on success
2040 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002041 """
Jon Hall94fd0472014-12-08 11:52:42 -08002042 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002043 cmdStr = "election-test-run"
2044 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002045 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002046 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002047 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002048 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002049 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002050 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002051 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002052 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002053 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002054 errorPattern = "Command\snot\sfound"
2055 if re.search( errorPattern, response ):
2056 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002057 return main.FALSE
2058 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002059 main.log.error( "Error in election_test_run: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002060 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002061 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002062 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002063 except TypeError:
2064 main.log.exception( self.name + ": Object not as expected" )
2065 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002066 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002067 main.log.error( self.name + ": EOF exception found" )
2068 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002069 main.cleanup()
2070 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002071 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002072 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002073 main.cleanup()
2074 main.exit()
2075
kelvin-onlabd3b64892015-01-20 13:26:24 -08002076 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002077 """
Jon Hall94fd0472014-12-08 11:52:42 -08002078 * CLI command to withdraw the local node from leadership election for
2079 * the Election test application.
2080 #NOTE: Requires installation of the onos-app-election feature
2081 Returns: Main.TRUE on success
2082 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002083 """
Jon Hall94fd0472014-12-08 11:52:42 -08002084 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002085 cmdStr = "election-test-withdraw"
2086 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002087 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002088 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002089 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002090 if re.search( successPattern, response ):
2091 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002092 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002093 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002094 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002095 errorPattern = "Command\snot\sfound"
2096 if re.search( errorPattern, response ):
2097 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002098 return main.FALSE
2099 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002100 main.log.error( "Error in election_test_withdraw: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002101 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002102 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002103 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002104 except TypeError:
2105 main.log.exception( self.name + ": Object not as expected" )
2106 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002107 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002108 main.log.error( self.name + ": EOF exception found" )
2109 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002110 main.cleanup()
2111 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002112 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002113 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002114 main.cleanup()
2115 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002116
kelvin8ec71442015-01-15 16:57:00 -08002117 def getDevicePortsEnabledCount( self, dpid ):
2118 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002119 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002120 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002121 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002122 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002123 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2124 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002125 if re.search( "No such device", output ):
2126 main.log.error( "Error in getting ports" )
2127 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002128 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002129 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002130 except TypeError:
2131 main.log.exception( self.name + ": Object not as expected" )
2132 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002133 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002134 main.log.error( self.name + ": EOF exception found" )
2135 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002136 main.cleanup()
2137 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002138 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002139 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002140 main.cleanup()
2141 main.exit()
2142
kelvin8ec71442015-01-15 16:57:00 -08002143 def getDeviceLinksActiveCount( self, dpid ):
2144 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002145 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002146 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002147 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002148 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002149 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2150 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002151 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002152 main.log.error( "Error in getting ports " )
2153 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002154 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002155 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002156 except TypeError:
2157 main.log.exception( self.name + ": Object not as expected" )
2158 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002159 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002160 main.log.error( self.name + ": EOF exception found" )
2161 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002162 main.cleanup()
2163 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002164 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002165 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002166 main.cleanup()
2167 main.exit()
2168
kelvin8ec71442015-01-15 16:57:00 -08002169 def getAllIntentIds( self ):
2170 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002171 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002172 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002173 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002174 cmdStr = "onos:intents | grep id="
2175 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002176 if re.search( "Error", output ):
2177 main.log.error( "Error in getting ports" )
2178 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002179 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002180 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002181 except TypeError:
2182 main.log.exception( self.name + ": Object not as expected" )
2183 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002184 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002185 main.log.error( self.name + ": EOF exception found" )
2186 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002187 main.cleanup()
2188 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002189 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002190 main.log.exception( self.name + ": Uncaught exception!" )
2191 main.cleanup()
2192 main.exit()
2193
Jon Hall73509952015-02-24 16:42:56 -08002194 def intentSummary( self ):
2195 """
Jon Hallefbd9792015-03-05 16:11:36 -08002196 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002197 """
2198 try:
2199 intents = self.intents( )
2200 intentStates = []
Jon Hall63604932015-02-26 17:09:50 -08002201 for intent in json.loads( intents ): # Iter through intents of a node
Jon Hall73509952015-02-24 16:42:56 -08002202 intentStates.append( intent.get( 'state', None ) )
Jon Hall63604932015-02-26 17:09:50 -08002203 out = [ (i, intentStates.count( i ) ) for i in set( intentStates ) ]
2204 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002205 return dict( out )
2206 except TypeError:
2207 main.log.exception( self.name + ": Object not as expected" )
2208 return None
2209 except pexpect.EOF:
2210 main.log.error( self.name + ": EOF exception found" )
2211 main.log.error( self.name + ": " + self.handle.before )
2212 main.cleanup()
2213 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002214 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002215 main.log.exception( self.name + ": Uncaught exception!" )
2216 main.cleanup()
2217 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002218
Jon Hall61282e32015-03-19 11:34:11 -07002219 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002220 """
2221 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002222 Optional argument:
2223 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002224 """
2225 # FIXME: add json output
Jon Hall61282e32015-03-19 11:34:11 -07002226 # Sample JSON
2227 # {
2228 # "electedTime": "13m ago",
2229 # "epoch": 4,
2230 # "leader": "10.128.30.17",
2231 # "topic": "intent-partition-3"
2232 # },
Jon Hall63604932015-02-26 17:09:50 -08002233 try:
Jon Hall61282e32015-03-19 11:34:11 -07002234 if jsonFormat:
2235 cmdStr = "onos:leaders -j"
2236 output = self.sendline( cmdStr )
2237 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2238 cleanedOutput = ansiEscape.sub( '', output )
2239 return cleanedOutput
2240 else:
2241 cmdStr = "onos:leaders"
2242 output = self.sendline( cmdStr )
2243 return output
Jon Hall63604932015-02-26 17:09:50 -08002244 except TypeError:
2245 main.log.exception( self.name + ": Object not as expected" )
2246 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002247 except pexpect.EOF:
2248 main.log.error( self.name + ": EOF exception found" )
2249 main.log.error( self.name + ": " + self.handle.before )
2250 main.cleanup()
2251 main.exit()
2252 except:
Jon Hall63604932015-02-26 17:09:50 -08002253 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002254 main.cleanup()
2255 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002256
Jon Hall61282e32015-03-19 11:34:11 -07002257 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002258 """
2259 Returns the output of the intent Pending map.
2260 """
Jon Hall63604932015-02-26 17:09:50 -08002261 try:
Jon Hall61282e32015-03-19 11:34:11 -07002262 if jsonFormat:
2263 cmdStr = "onos:intents -p -j"
2264 output = self.sendline( cmdStr )
2265 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2266 cleanedOutput = ansiEscape.sub( '', output )
2267 return cleanedOutput
2268 else:
2269 cmdStr = "onos:intents -p"
2270 output = self.sendline( cmdStr )
2271 return output
Jon Hall63604932015-02-26 17:09:50 -08002272 except TypeError:
2273 main.log.exception( self.name + ": Object not as expected" )
2274 return None
2275 except pexpect.EOF:
2276 main.log.error( self.name + ": EOF exception found" )
2277 main.log.error( self.name + ": " + self.handle.before )
2278 main.cleanup()
2279 main.exit()
2280 except:
2281 main.log.exception( self.name + ": Uncaught exception!" )
2282 main.cleanup()
2283 main.exit()
2284
Jon Hall61282e32015-03-19 11:34:11 -07002285 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002286 """
2287 Returns the output of the raft partitions command for ONOS.
2288 """
Jon Hall61282e32015-03-19 11:34:11 -07002289 # Sample JSON
2290 # {
2291 # "leader": "tcp://10.128.30.11:7238",
2292 # "members": [
2293 # "tcp://10.128.30.11:7238",
2294 # "tcp://10.128.30.17:7238",
2295 # "tcp://10.128.30.13:7238",
2296 # ],
2297 # "name": "p1",
2298 # "term": 3
2299 # },
Jon Hall63604932015-02-26 17:09:50 -08002300 try:
Jon Hall61282e32015-03-19 11:34:11 -07002301 if jsonFormat:
2302 cmdStr = "onos:partitions -j"
2303 output = self.sendline( cmdStr )
2304 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2305 cleanedOutput = ansiEscape.sub( '', output )
2306 return cleanedOutput
2307 else:
2308 cmdStr = "onos:partitions"
2309 output = self.sendline( cmdStr )
2310 return output
Jon Hall63604932015-02-26 17:09:50 -08002311 except TypeError:
2312 main.log.exception( self.name + ": Object not as expected" )
2313 return None
2314 except pexpect.EOF:
2315 main.log.error( self.name + ": EOF exception found" )
2316 main.log.error( self.name + ": " + self.handle.before )
2317 main.cleanup()
2318 main.exit()
2319 except:
2320 main.log.exception( self.name + ": Uncaught exception!" )
2321 main.cleanup()
2322 main.exit()
2323