blob: db05e24f595d43f9e58b84d5e4c5eeda554d1c8c [file] [log] [blame]
Jon Hall05b2b432014-10-08 19:53:25 -04001#!/usr/bin/env python
andrewonlabe8e56fd2014-10-09 17:12:44 -04002
kelvin8ec71442015-01-15 16:57:00 -08003"""
4This driver interacts with ONOS bench, the OSGi platform
5that configures the ONOS nodes. ( aka ONOS-next )
andrewonlabe8e56fd2014-10-09 17:12:44 -04006
kelvin8ec71442015-01-15 16:57:00 -08007Please follow the coding style demonstrated by existing
andrewonlabe8e56fd2014-10-09 17:12:44 -04008functions and document properly.
9
10If you are a contributor to the driver, please
11list your email here for future contact:
12
13jhall@onlab.us
14andrew@onlab.us
15
16OCT 9 2014
17
kelvin8ec71442015-01-15 16:57:00 -080018"""
andrewonlab7735d852014-10-09 13:02:47 -040019import sys
Jon Hall05b2b432014-10-08 19:53:25 -040020import time
21import pexpect
andrewonlab7735d852014-10-09 13:02:47 -040022import os.path
pingping-lin6d23d9e2015-02-02 16:54:24 -080023from requests.models import Response
kelvin8ec71442015-01-15 16:57:00 -080024sys.path.append( "../" )
Jon Hall05b2b432014-10-08 19:53:25 -040025from drivers.common.clidriver import CLI
26
Jon Hall05b2b432014-10-08 19:53:25 -040027
kelvin8ec71442015-01-15 16:57:00 -080028class OnosDriver( CLI ):
Jon Hall05b2b432014-10-08 19:53:25 -040029
kelvin8ec71442015-01-15 16:57:00 -080030 def __init__( self ):
31 """
32 Initialize client
33 """
pingping-lin763ee042015-05-20 17:45:30 -070034 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 """
Jon Hall05b2b432014-10-08 19:53:25 -040041 Creates ssh handle for ONOS "bench".
kelvin8ec71442015-01-15 16:57:00 -080042 """
Jon Hall05b2b432014-10-08 19:53:25 -040043 try:
44 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080045 vars( self )[ key ] = connectargs[ key ]
pingping-lin763ee042015-05-20 17:45:30 -070046 self.home = "~/onos"
Jon Hall05b2b432014-10-08 19:53:25 -040047 for key in self.options:
48 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080049 self.home = self.options[ 'home' ]
Jon Hall05b2b432014-10-08 19:53:25 -040050 break
pingping-lin763ee042015-05-20 17:45:30 -070051 if self.home is None or self.home == "":
52 self.home = "~/onos"
Jon Hall05b2b432014-10-08 19:53:25 -040053
kelvin8ec71442015-01-15 16:57:00 -080054 self.name = self.options[ 'name' ]
55 self.handle = super( OnosDriver, self ).connect(
56 user_name=self.user_name,
kelvin-onlab08679eb2015-01-21 16:11:48 -080057 ip_address=self.ip_address,
kelvin-onlabd3b64892015-01-20 13:26:24 -080058 port=self.port,
59 pwd=self.pwd,
60 home=self.home )
Jon Hall05b2b432014-10-08 19:53:25 -040061
kelvin8ec71442015-01-15 16:57:00 -080062 self.handle.sendline( "cd " + self.home )
63 self.handle.expect( "\$" )
Jon Hall05b2b432014-10-08 19:53:25 -040064 if self.handle:
65 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080066 else:
67 main.log.info( "NO ONOS HANDLE" )
Jon Hall05b2b432014-10-08 19:53:25 -040068 return main.FALSE
69 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080070 main.log.error( self.name + ": EOF exception found" )
71 main.log.error( self.name + ": " + self.handle.before )
Jon Hall05b2b432014-10-08 19:53:25 -040072 main.cleanup()
73 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -070074 except Exception:
75 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall05b2b432014-10-08 19:53:25 -040076 main.cleanup()
77 main.exit()
78
kelvin8ec71442015-01-15 16:57:00 -080079 def disconnect( self ):
80 """
Jon Hall05b2b432014-10-08 19:53:25 -040081 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -080082 """
pingping-lin763ee042015-05-20 17:45:30 -070083 response = main.TRUE
Jon Hall05b2b432014-10-08 19:53:25 -040084 try:
pingping-lin763ee042015-05-20 17:45:30 -070085 if self.handle:
86 self.handle.sendline( "" )
87 self.handle.expect( "\$" )
88 self.handle.sendline( "exit" )
89 self.handle.expect( "closed" )
Jon Hall05b2b432014-10-08 19:53:25 -040090 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080091 main.log.error( self.name + ": EOF exception found" )
92 main.log.error( self.name + ": " + self.handle.before )
pingping-lin763ee042015-05-20 17:45:30 -070093 except ValueError:
94 main.log.exception( "Exception in disconnect of " + self.name )
95 response = main.TRUE
96 except Exception:
97 main.log.exception( self.name + ": Connection failed to the host" )
Jon Hall05b2b432014-10-08 19:53:25 -040098 response = main.FALSE
99 return response
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400100
pingping-lin57a56ce2015-05-20 16:43:48 -0700101 def onosPackage( self, opTimeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800102 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400103 Produce a self-contained tar.gz file that can be deployed
kelvin8ec71442015-01-15 16:57:00 -0800104 and executed on any platform with Java 7 JRE.
105 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400106 try:
kelvin8ec71442015-01-15 16:57:00 -0800107 self.handle.sendline( "onos-package" )
108 self.handle.expect( "onos-package" )
pingping-lin57a56ce2015-05-20 16:43:48 -0700109 self.handle.expect( "tar.gz", opTimeout )
kelvin8ec71442015-01-15 16:57:00 -0800110 handle = str( self.handle.before )
111 main.log.info( "onos-package command returned: " +
112 handle )
113 # As long as the sendline does not time out,
114 # return true. However, be careful to interpret
115 # the results of the onos-package command return
andrewonlab0748d2a2014-10-09 13:24:17 -0400116 return main.TRUE
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400117
andrewonlab7735d852014-10-09 13:02:47 -0400118 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800119 main.log.error( self.name + ": EOF exception found" )
120 main.log.error( self.name + ": " + self.handle.before )
pingping-lin763ee042015-05-20 17:45:30 -0700121 except Exception:
122 main.log.exception( "Failed to package ONOS" )
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400123 main.cleanup()
124 main.exit()
125
kelvin-onlabd3b64892015-01-20 13:26:24 -0800126 def onosBuild( self ):
kelvin8ec71442015-01-15 16:57:00 -0800127 """
andrewonlab8790abb2014-11-06 13:51:54 -0500128 Use the pre defined script to build onos via mvn
kelvin8ec71442015-01-15 16:57:00 -0800129 """
andrewonlab8790abb2014-11-06 13:51:54 -0500130 try:
kelvin8ec71442015-01-15 16:57:00 -0800131 self.handle.sendline( "onos-build" )
132 self.handle.expect( "onos-build" )
133 i = self.handle.expect( [
kelvin-onlabd3b64892015-01-20 13:26:24 -0800134 "BUILD SUCCESS",
135 "ERROR",
136 "BUILD FAILED" ],
137 timeout=120 )
kelvin8ec71442015-01-15 16:57:00 -0800138 handle = str( self.handle.before )
andrewonlab8790abb2014-11-06 13:51:54 -0500139
kelvin8ec71442015-01-15 16:57:00 -0800140 main.log.info( "onos-build command returned: " +
141 handle )
andrewonlab8790abb2014-11-06 13:51:54 -0500142
143 if i == 0:
144 return main.TRUE
145 else:
146 return handle
147
148 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800149 main.log.error( self.name + ": EOF exception found" )
150 main.log.error( self.name + ": " + self.handle.before )
pingping-lin763ee042015-05-20 17:45:30 -0700151 except Exception:
152 main.log.exception( "Failed to build ONOS" )
andrewonlab8790abb2014-11-06 13:51:54 -0500153 main.cleanup()
154 main.exit()
155
pingping-lin57a56ce2015-05-20 16:43:48 -0700156 def cleanInstall( self, mciTimeout=600 ):
kelvin8ec71442015-01-15 16:57:00 -0800157 """
158 Runs mvn clean install in the root of the ONOS directory.
159 This will clean all ONOS artifacts then compile each module
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400160
kelvin8ec71442015-01-15 16:57:00 -0800161 Returns: main.TRUE on success
Jon Hallde9d9aa2014-10-08 20:36:02 -0400162 On Failure, exits the test
kelvin8ec71442015-01-15 16:57:00 -0800163 """
Jon Hallde9d9aa2014-10-08 20:36:02 -0400164 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800165 main.log.info( "Running 'mvn clean install' on " +
166 str( self.name ) +
kelvin8ec71442015-01-15 16:57:00 -0800167 ". This may take some time." )
168 self.handle.sendline( "cd " + self.home )
169 self.handle.expect( "\$" )
Jon Hallea7818b2014-10-09 14:30:59 -0400170
kelvin8ec71442015-01-15 16:57:00 -0800171 self.handle.sendline( "" )
172 self.handle.expect( "\$" )
173 self.handle.sendline( "mvn clean install" )
174 self.handle.expect( "mvn clean install" )
175 while True:
176 i = self.handle.expect( [
pingping-lin763ee042015-05-20 17:45:30 -0700177 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
178 'Runtime\sEnvironment\sto\scontinue',
Jon Hallde9d9aa2014-10-08 20:36:02 -0400179 'BUILD\sFAILURE',
180 'BUILD\sSUCCESS',
pingping-lin763ee042015-05-20 17:45:30 -0700181 'onos\$', #TODO: fix this to be more generic?
Jon Hallde9d9aa2014-10-08 20:36:02 -0400182 'ONOS\$',
pingping-lin57a56ce2015-05-20 16:43:48 -0700183 pexpect.TIMEOUT ], mciTimeout )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400184 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800185 main.log.error( self.name + ":There is insufficient memory \
186 for the Java Runtime Environment to continue." )
187 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400188 main.cleanup()
189 main.exit()
190 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800191 main.log.error( self.name + ": Build failure!" )
192 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400193 main.cleanup()
194 main.exit()
195 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800196 main.log.info( self.name + ": Build success!" )
pingping-lin763ee042015-05-20 17:45:30 -0700197 elif i == 3 or i == 4:
kelvin8ec71442015-01-15 16:57:00 -0800198 main.log.info( self.name + ": Build complete" )
199 # Print the build time
Jon Hallf8ef52c2014-10-09 19:37:33 -0400200 for line in self.handle.before.splitlines():
201 if "Total time:" in line:
kelvin8ec71442015-01-15 16:57:00 -0800202 main.log.info( line )
203 self.handle.sendline( "" )
204 self.handle.expect( "\$", timeout=60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400205 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -0700206 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800207 main.log.error(
208 self.name +
209 ": mvn clean install TIMEOUT!" )
210 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400211 main.cleanup()
212 main.exit()
213 else:
pingping-lin763ee042015-05-20 17:45:30 -0700214 main.log.error( self.name + ": unexpected response from " +
215 "mvn clean install" )
kelvin8ec71442015-01-15 16:57:00 -0800216 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400217 main.cleanup()
218 main.exit()
219 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800220 main.log.error( self.name + ": EOF exception found" )
221 main.log.error( self.name + ": " + self.handle.before )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400222 main.cleanup()
223 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700224 except Exception:
225 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400226 main.cleanup()
227 main.exit()
Jon Hallacabffd2014-10-09 12:36:53 -0400228
pingping-lin763ee042015-05-20 17:45:30 -0700229 def gitPull( self, comp1="", fastForward=True ):
kelvin8ec71442015-01-15 16:57:00 -0800230 """
Jon Hallacabffd2014-10-09 12:36:53 -0400231 Assumes that "git pull" works without login
Jon Hall47a93fb2015-01-06 16:46:06 -0800232
pingping-lin763ee042015-05-20 17:45:30 -0700233 If the fastForward boolean is set to true, only git pulls that can
234 be fast forwarded will be performed. IE if you have not local commits
235 in your branch.
236
Jon Hallacabffd2014-10-09 12:36:53 -0400237 This function will perform a git pull on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 If used as gitPull( "NODE" ) it will do git pull + NODE. This is
Jon Hallacabffd2014-10-09 12:36:53 -0400239 for the purpose of pulling from other nodes if necessary.
240
Jon Hall47a93fb2015-01-06 16:46:06 -0800241 Otherwise, this function will perform a git pull in the
Jon Hallacabffd2014-10-09 12:36:53 -0400242 ONOS repository. If it has any problems, it will return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -0800243 If it successfully does a gitPull, it will return a 1 ( main.TRUE )
Shreya Shahee15f6c2014-10-28 18:12:30 -0400244 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400245
kelvin8ec71442015-01-15 16:57:00 -0800246 """
Jon Hallacabffd2014-10-09 12:36:53 -0400247 try:
kelvin8ec71442015-01-15 16:57:00 -0800248 # main.log.info( self.name + ": Stopping ONOS" )
249 # self.stop()
250 self.handle.sendline( "cd " + self.home )
pingping-lin763ee042015-05-20 17:45:30 -0700251 self.handle.expect( self.home + "\$" )
252 cmd = "git pull"
253 if comp1 != "":
254 cmd += ' ' + comp1
255 if fastForward:
256 cmd += ' ' + " --ff-only"
257 self.handle.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800258 i = self.handle.expect(
259 [
260 'fatal',
261 'Username\sfor\s(.*):\s',
262 '\sfile(s*) changed,\s',
263 'Already up-to-date',
264 'Aborting',
265 'You\sare\snot\scurrently\son\sa\sbranch',
pingping-lin763ee042015-05-20 17:45:30 -0700266 'You asked me to pull without telling me which branch you',
267 'Pull is not possible because you have unmerged files',
268 'Please enter a commit message to explain why this merge',
269 'Found a swap file by the name',
270 'Please, commit your changes before you can merge.',
kelvin-onlabd3b64892015-01-20 13:26:24 -0800271 pexpect.TIMEOUT ],
272 timeout=300 )
kelvin8ec71442015-01-15 16:57:00 -0800273 # debug
kelvin-onlabd3b64892015-01-20 13:26:24 -0800274 # main.log.report( self.name +": DEBUG: \n"+
275 # "git pull response: " +
276 # str( self.handle.before ) + str( self.handle.after ) )
kelvin8ec71442015-01-15 16:57:00 -0800277 if i == 0:
pingping-lin763ee042015-05-20 17:45:30 -0700278 main.log.error( self.name + ": Git pull had some issue" )
279 output = self.handle.after
280 self.handle.expect( '\$' )
281 output += self.handle.before
282 main.log.warn( output )
Jon Hallacabffd2014-10-09 12:36:53 -0400283 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800284 elif i == 1:
285 main.log.error(
286 self.name +
287 ": Git Pull Asking for username. " )
Jon Hallacabffd2014-10-09 12:36:53 -0400288 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800289 elif i == 2:
290 main.log.info(
291 self.name +
292 ": Git Pull - pulling repository now" )
pingping-lin763ee042015-05-20 17:45:30 -0700293 self.handle.expect( self.home + "\$", 120 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800294 # So that only when git pull is done, we do mvn clean compile
295 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800296 elif i == 3:
297 main.log.info( self.name + ": Git Pull - Already up to date" )
Jon Hall47a93fb2015-01-06 16:46:06 -0800298 return i
kelvin8ec71442015-01-15 16:57:00 -0800299 elif i == 4:
300 main.log.info(
301 self.name +
pingping-lin763ee042015-05-20 17:45:30 -0700302 ": Git Pull - Aborting..." +
303 "Are there conflicting git files?" )
Jon Hallacabffd2014-10-09 12:36:53 -0400304 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800305 elif i == 5:
306 main.log.info(
307 self.name +
pingping-lin763ee042015-05-20 17:45:30 -0700308 ": Git Pull - You are not currently " +
309 "on a branch so git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400310 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800311 elif i == 6:
312 main.log.info(
313 self.name +
pingping-lin763ee042015-05-20 17:45:30 -0700314 ": Git Pull - You have not configured an upstream " +
315 "branch to pull from. Git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400316 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800317 elif i == 7:
318 main.log.info(
319 self.name +
pingping-lin763ee042015-05-20 17:45:30 -0700320 ": Git Pull - Pull is not possible because " +
321 "you have unmerged files." )
Jon Hallacabffd2014-10-09 12:36:53 -0400322 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800323 elif i == 8:
pingping-lin763ee042015-05-20 17:45:30 -0700324 # NOTE: abandoning test since we can't reliably handle this
325 # there could be different default text editors and we
326 # also don't know if we actually want to make the commit
327 main.log.error( "Git pull resulted in a merge commit message" +
328 ". Exiting test!" )
329 main.cleanup()
330 main.exit()
331 elif i == 9: # Merge commit message but swap file exists
332 main.log.error( "Git pull resulted in a merge commit message" +
333 " but a swap file exists." )
334 try:
335 self.handle.send( 'A' ) # Abort
336 self.handle.expect( "\$" )
337 return main.ERROR
338 except Exception:
339 main.log.exception( "Couldn't exit editor prompt!")
340 main.cleanup()
341 main.exit()
342 elif i == 10: # In the middle of a merge commit
343 main.log.error( "Git branch is in the middle of a merge. " )
344 main.log.warn( self.handle.before + self.handle.after )
345 return main.ERROR
346 elif i == 11:
kelvin8ec71442015-01-15 16:57:00 -0800347 main.log.error( self.name + ": Git Pull - TIMEOUT" )
348 main.log.error(
349 self.name + " Response was: " + str(
350 self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400351 return main.ERROR
352 else:
kelvin8ec71442015-01-15 16:57:00 -0800353 main.log.error(
354 self.name +
355 ": Git Pull - Unexpected response, check for pull errors" )
Jon Hallacabffd2014-10-09 12:36:53 -0400356 return main.ERROR
357 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800358 main.log.error( self.name + ": EOF exception found" )
359 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400360 main.cleanup()
361 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700362 except Exception:
363 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400364 main.cleanup()
365 main.exit()
366
kelvin-onlabd3b64892015-01-20 13:26:24 -0800367 def gitCheckout( self, branch="master" ):
kelvin8ec71442015-01-15 16:57:00 -0800368 """
Jon Hallacabffd2014-10-09 12:36:53 -0400369 Assumes that "git pull" works without login
kelvin8ec71442015-01-15 16:57:00 -0800370
Jon Hallacabffd2014-10-09 12:36:53 -0400371 This function will perform a git git checkout on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800372 If used as gitCheckout( "branch" ) it will do git checkout
373 of the "branch".
Jon Hallacabffd2014-10-09 12:36:53 -0400374
375 Otherwise, this function will perform a git checkout of the master
kelvin8ec71442015-01-15 16:57:00 -0800376 branch of the ONOS repository. If it has any problems, it will return
377 main.ERROR.
378 If the branch was already the specified branch, or the git checkout was
Jon Hallacabffd2014-10-09 12:36:53 -0400379 successful then the function will return main.TRUE.
380
kelvin8ec71442015-01-15 16:57:00 -0800381 """
Jon Hallacabffd2014-10-09 12:36:53 -0400382 try:
kelvin8ec71442015-01-15 16:57:00 -0800383 self.handle.sendline( "cd " + self.home )
pingping-lin763ee042015-05-20 17:45:30 -0700384 self.handle.expect( self.home + "\$" )
385 main.log.info( self.name +
386 ": Checking out git branch/ref: " + branch + "..." )
kelvin8ec71442015-01-15 16:57:00 -0800387 cmd = "git checkout " + branch
388 self.handle.sendline( cmd )
389 self.handle.expect( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800390 i = self.handle.expect(
pingping-lin763ee042015-05-20 17:45:30 -0700391 [ 'fatal',
392 'Username for (.*): ',
393 'Already on \'',
394 'Switched to branch \'' + str( branch ),
395 pexpect.TIMEOUT,
396 'error: Your local changes to the following files' +
397 'would be overwritten by checkout:',
398 'error: you need to resolve your current index first',
399 "You are in 'detached HEAD' state.",
400 "HEAD is now at " ],
kelvin-onlabd3b64892015-01-20 13:26:24 -0800401 timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -0800402 if i == 0:
403 main.log.error(
404 self.name +
405 ": Git checkout had some issue..." )
406 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400407 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800408 elif i == 1:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800409 main.log.error(
410 self.name +
411 ": Git checkout asking for username." +
412 " Please configure your local git repository to be able " +
413 "to access your remote repository passwordlessly" )
pingping-lin763ee042015-05-20 17:45:30 -0700414 # TODO add support for authenticating
Jon Hallacabffd2014-10-09 12:36:53 -0400415 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800416 elif i == 2:
417 main.log.info(
418 self.name +
pingping-lin763ee042015-05-20 17:45:30 -0700419 ": Git Checkout %s : Already on this branch" % branch )
420 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800421 # main.log.info( "DEBUG: after checkout cmd = "+
422 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400423 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800424 elif i == 3:
425 main.log.info(
426 self.name +
pingping-lin763ee042015-05-20 17:45:30 -0700427 ": Git checkout %s - Switched to this branch" % branch )
428 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800429 # main.log.info( "DEBUG: after checkout cmd = "+
430 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400431 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800432 elif i == 4:
433 main.log.error( self.name + ": Git Checkout- TIMEOUT" )
434 main.log.error(
pingping-lin763ee042015-05-20 17:45:30 -0700435 self.name + " Response was: " + str( self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400436 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800437 elif i == 5:
438 self.handle.expect( "Aborting" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800439 main.log.error(
440 self.name +
441 ": Git checkout error: \n" +
pingping-lin763ee042015-05-20 17:45:30 -0700442 "Your local changes to the following files would" +
443 " be overwritten by checkout:" +
444 str( self.handle.before ) )
445 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500446 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800447 elif i == 6:
pingping-lin763ee042015-05-20 17:45:30 -0700448 main.log.error(
449 self.name +
450 ": Git checkout error: \n" +
451 "You need to resolve your current index first:" +
452 str( self.handle.before ) )
453 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500454 return main.ERROR
pingping-lin763ee042015-05-20 17:45:30 -0700455 elif i == 7:
456 main.log.info(
457 self.name +
458 ": Git checkout " + str( branch ) +
459 " - You are in 'detached HEAD' state. HEAD is now at " +
460 str( branch ) )
461 self.handle.expect( self.home + "\$" )
462 return main.TRUE
463 elif i == 8: # Already in detached HEAD on the specified commit
464 main.log.info(
465 self.name +
466 ": Git Checkout %s : Already on commit" % branch )
467 self.handle.expect( self.home + "\$" )
468 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400469 else:
kelvin8ec71442015-01-15 16:57:00 -0800470 main.log.error(
471 self.name +
pingping-lin763ee042015-05-20 17:45:30 -0700472 ": Git Checkout - Unexpected response, " +
473 "check for pull errors" )
kelvin8ec71442015-01-15 16:57:00 -0800474 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400475 return main.ERROR
476
477 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800478 main.log.error( self.name + ": EOF exception found" )
479 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400480 main.cleanup()
481 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700482 except Exception:
483 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400484 main.cleanup()
485 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400486
pingping-lin6d23d9e2015-02-02 16:54:24 -0800487 def getBranchName( self ):
pingping-linf30cf272015-05-29 15:54:07 -0700488 main.log.info( "self.home = " )
489 main.log.info( self.home )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800490 self.handle.sendline( "cd " + self.home )
pingping-lin9bf3d8f2015-05-29 16:05:28 -0700491 self.handle.expect( self.home + "\$" )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800492 self.handle.sendline( "git name-rev --name-only HEAD" )
493 self.handle.expect( "git name-rev --name-only HEAD" )
494 self.handle.expect( "\$" )
495
496 lines = self.handle.before.splitlines()
497 if lines[1] == "master":
498 return "master"
499 elif lines[1] == "onos-1.0":
500 return "onos-1.0"
501 else:
502 main.log.info( lines[1] )
503 return "unexpected ONOS branch for SDN-IP test"
504
kelvin-onlabd3b64892015-01-20 13:26:24 -0800505 def getVersion( self, report=False ):
kelvin8ec71442015-01-15 16:57:00 -0800506 """
pingping-lin763ee042015-05-20 17:45:30 -0700507 Writes the COMMIT number to the report to be parsed
508 by Jenkins data collector.
kelvin8ec71442015-01-15 16:57:00 -0800509 """
Jon Hall45ec0922014-10-10 19:33:49 -0400510 try:
kelvin8ec71442015-01-15 16:57:00 -0800511 self.handle.sendline( "" )
512 self.handle.expect( "\$" )
513 self.handle.sendline(
514 "cd " +
515 self.home +
pingping-lin763ee042015-05-20 17:45:30 -0700516 "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " +
517 " \"commit\" --color=never" )
kelvin8ec71442015-01-15 16:57:00 -0800518 # NOTE: for some reason there are backspaces inserted in this
519 # phrase when run from Jenkins on some tests
520 self.handle.expect( "never" )
521 self.handle.expect( "\$" )
522 response = ( self.name + ": \n" + str(
523 self.handle.before + self.handle.after ) )
524 self.handle.sendline( "cd " + self.home )
525 self.handle.expect( "\$" )
526 lines = response.splitlines()
Jon Hall45ec0922014-10-10 19:33:49 -0400527 for line in lines:
Jon Hallfd191202014-11-07 18:36:09 -0500528 print line
529 if report:
pingping-lin763ee042015-05-20 17:45:30 -0700530 main.log.wiki( "<blockquote>" )
kelvin8ec71442015-01-15 16:57:00 -0800531 for line in lines[ 2:-1 ]:
532 # Bracket replacement is for Wiki-compliant
533 # formatting. '<' or '>' are interpreted
534 # as xml specific tags that cause errors
535 line = line.replace( "<", "[" )
536 line = line.replace( ">", "]" )
pingping-lin763ee042015-05-20 17:45:30 -0700537 #main.log.wiki( "\t" + line )
538 main.log.wiki( line + "<br /> " )
539 main.log.summary( line )
540 main.log.wiki( "</blockquote>" )
541 main.log.summary("\n")
kelvin8ec71442015-01-15 16:57:00 -0800542 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400543 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800544 main.log.error( self.name + ": EOF exception found" )
545 main.log.error( self.name + ": " + self.handle.before )
Jon Hall45ec0922014-10-10 19:33:49 -0400546 main.cleanup()
547 main.exit()
Jon Hall368769f2014-11-19 15:43:35 -0800548 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800549 main.log.error( self.name + ": TIMEOUT exception found" )
550 main.log.error( self.name + ": " + self.handle.before )
Jon Hall368769f2014-11-19 15:43:35 -0800551 main.cleanup()
552 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700553 except Exception:
554 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall45ec0922014-10-10 19:33:49 -0400555 main.cleanup()
556 main.exit()
557
kelvin-onlabd3b64892015-01-20 13:26:24 -0800558 def createCellFile( self, benchIp, fileName, mnIpAddrs,
pingping-lin763ee042015-05-20 17:45:30 -0700559 appString, *onosIpAddrs ):
kelvin8ec71442015-01-15 16:57:00 -0800560 """
andrewonlab94282092014-10-10 13:00:11 -0400561 Creates a cell file based on arguments
562 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800563 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400564 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800565 * File name of the cell file ( fileName )
566 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800567 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400568 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800569 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400570 - Must be passed in as last arguments
kelvin8ec71442015-01-15 16:57:00 -0800571
andrewonlab94282092014-10-10 13:00:11 -0400572 NOTE: Assumes cells are located at:
573 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800574 """
575 # Variable initialization
kelvin-onlabd3b64892015-01-20 13:26:24 -0800576 cellDirectory = self.home + "/tools/test/cells/"
kelvin8ec71442015-01-15 16:57:00 -0800577 # We want to create the cell file in the dependencies directory
578 # of TestON first, then copy over to ONOS bench
kelvin-onlabd3b64892015-01-20 13:26:24 -0800579 tempDirectory = "/tmp/"
kelvin8ec71442015-01-15 16:57:00 -0800580 # Create the cell file in the directory for writing ( w+ )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800581 cellFile = open( tempDirectory + fileName, 'w+' )
kelvin8ec71442015-01-15 16:57:00 -0800582
pingping-lin763ee042015-05-20 17:45:30 -0700583 # App string is hardcoded environment variables
kelvin8ec71442015-01-15 16:57:00 -0800584 # That you may wish to use by default on startup.
pingping-lin763ee042015-05-20 17:45:30 -0700585 # Note that you may not want certain apps listed
kelvin8ec71442015-01-15 16:57:00 -0800586 # on here.
pingping-lin763ee042015-05-20 17:45:30 -0700587 appString = "export ONOS_APPS=" + appString
kelvin-onlabd3b64892015-01-20 13:26:24 -0800588 mnString = "export OCN="
589 onosString = "export OC"
590 tempCount = 1
kelvin8ec71442015-01-15 16:57:00 -0800591
kelvin-onlabd3b64892015-01-20 13:26:24 -0800592 # Create ONOSNIC ip address prefix
593 tempOnosIp = onosIpAddrs[ 0 ]
594 tempList = []
595 tempList = tempOnosIp.split( "." )
kelvin8ec71442015-01-15 16:57:00 -0800596 # Omit last element of list to format for NIC
kelvin-onlabd3b64892015-01-20 13:26:24 -0800597 tempList = tempList[ :-1 ]
kelvin8ec71442015-01-15 16:57:00 -0800598 # Structure the nic string ip
kelvin-onlabd3b64892015-01-20 13:26:24 -0800599 nicAddr = ".".join( tempList ) + ".*"
600 onosNicString = "export ONOS_NIC=" + nicAddr
andrewonlab94282092014-10-10 13:00:11 -0400601
602 try:
kelvin8ec71442015-01-15 16:57:00 -0800603 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800604 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400605
kelvin-onlabd3b64892015-01-20 13:26:24 -0800606 for arg in onosIpAddrs:
607 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800608 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400609 # export OC1="10.128.20.11"
610 # export OC2="10.128.20.12"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800611 cellFile.write( onosString + str( tempCount ) +
612 "=" + "\"" + arg + "\"" + "\n" )
613 tempCount = tempCount + 1
kelvin8ec71442015-01-15 16:57:00 -0800614
kelvin-onlabd3b64892015-01-20 13:26:24 -0800615 cellFile.write( mnString + "\"" + mnIpAddrs + "\"" + "\n" )
pingping-lin763ee042015-05-20 17:45:30 -0700616 cellFile.write( appString + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800617 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400618
kelvin8ec71442015-01-15 16:57:00 -0800619 # We use os.system to send the command to TestON cluster
620 # to account for the case in which TestON is not located
621 # on the same cluster as the ONOS bench
622 # Note that even if TestON is located on the same cluster
623 # as ONOS bench, you must setup passwordless ssh
624 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800625 os.system( "scp " + tempDirectory + fileName +
626 " admin@" + benchIp + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400627
andrewonlab2a6c9342014-10-16 13:40:15 -0400628 return main.TRUE
629
andrewonlab94282092014-10-10 13:00:11 -0400630 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800631 main.log.error( self.name + ": EOF exception found" )
632 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -0400633 main.cleanup()
634 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700635 except Exception:
636 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -0400637 main.cleanup()
638 main.exit()
639
kelvin-onlabd3b64892015-01-20 13:26:24 -0800640 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800641 """
andrewonlab95ca1462014-10-09 14:04:24 -0400642 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800643 """
andrewonlab95ca1462014-10-09 14:04:24 -0400644 try:
645 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800646 main.log.error( "Must define cellname" )
andrewonlab95ca1462014-10-09 14:04:24 -0400647 main.cleanup()
648 main.exit()
649 else:
kelvin8ec71442015-01-15 16:57:00 -0800650 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800651 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800652 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400653 # and that this driver will have to change accordingly
pingping-lin763ee042015-05-20 17:45:30 -0700654 self.handle.expect(str(cellname))
kelvin-onlabd3b64892015-01-20 13:26:24 -0800655 handleBefore = self.handle.before
656 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800657 # Get the rest of the handle
pingping-lin763ee042015-05-20 17:45:30 -0700658 self.handle.sendline("")
659 self.handle.expect("\$")
kelvin-onlabd3b64892015-01-20 13:26:24 -0800660 handleMore = self.handle.before
andrewonlab95ca1462014-10-09 14:04:24 -0400661
kelvin-onlabd3b64892015-01-20 13:26:24 -0800662 main.log.info( "Cell call returned: " + handleBefore +
663 handleAfter + handleMore )
andrewonlab95ca1462014-10-09 14:04:24 -0400664
665 return main.TRUE
666
667 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800668 main.log.error( self.name + ": EOF exception found" )
669 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ca1462014-10-09 14:04:24 -0400670 main.cleanup()
671 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700672 except Exception:
673 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ca1462014-10-09 14:04:24 -0400674 main.cleanup()
675 main.exit()
676
kelvin-onlabd3b64892015-01-20 13:26:24 -0800677 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800678 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400679 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800680 """
681 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400682
andrewonlabc03bf6c2014-10-09 14:56:18 -0400683 try:
kelvin8ec71442015-01-15 16:57:00 -0800684 # Clean handle by sending empty and expecting $
685 self.handle.sendline( "" )
686 self.handle.expect( "\$" )
687 self.handle.sendline( "onos-verify-cell" )
688 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800689 handleBefore = self.handle.before
690 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800691 # Get the rest of the handle
692 self.handle.sendline( "" )
693 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800694 handleMore = self.handle.before
andrewonlabc03bf6c2014-10-09 14:56:18 -0400695
kelvin-onlabd3b64892015-01-20 13:26:24 -0800696 main.log.info( "Verify cell returned: " + handleBefore +
697 handleAfter + handleMore )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400698
699 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -0700700 except pexpect.ExceptionPexpect as e:
701 main.log.error( self.name + ": Pexpect exception found of type " +
702 str( type( e ) ) )
703 main.log.error ( e.get_trace() )
kelvin8ec71442015-01-15 16:57:00 -0800704 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400705 main.cleanup()
706 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700707 except Exception:
708 main.log.exception( self.name + ": Uncaught exception!" )
709 main.cleanup()
710 main.exit()
711
712 def onosCfgSet( self, ONOSIp, configName, configParam ):
713 """
714 Uses 'onos <node-ip> cfg set' to change a parameter value of an
715 application.
716
717 ex)
718 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
719
720 ONOSIp = '10.0.0.1'
721 configName = 'org.onosproject.myapp'
722 configParam = 'appSetting 1'
723
724 """
725 try:
726 cfgStr = ( "onos "+str(ONOSIp)+" cfg set "+
727 str(configName) + " " +
728 str(configParam)
729 )
730
731 self.handle.sendline( "" )
732 self.handle.expect( "\$" )
733 self.handle.sendline( cfgStr )
734 self.handle.expect( "\$" )
735
736 # TODO: Add meaningful assertion
737
738 return main.TRUE
739
740 except pexpect.ExceptionPexpect as e:
741 main.log.error( self.name + ": Pexpect exception found of type " +
742 str( type( e ) ) )
743 main.log.error ( e.get_trace() )
744 main.log.error( self.name + ": " + self.handle.before )
745 main.cleanup()
746 main.exit()
747 except Exception:
748 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400749 main.cleanup()
750 main.exit()
751
kelvin-onlabd3b64892015-01-20 13:26:24 -0800752 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800753 """
andrewonlab05e362f2014-10-10 00:40:57 -0400754 Uses 'onos' command to send various ONOS CLI arguments.
755 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800756 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400757 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800758
759 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400760 CLI commands for ONOS. Try to use this function first
761 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800762 function.
763 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400764 by starting onos, and typing in 'onos' to enter the
765 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800766 available commands.
767 """
andrewonlab05e362f2014-10-10 00:40:57 -0400768 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800769 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800770 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400771 return main.FALSE
772 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800773 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400774 return main.FALSE
775
kelvin8ec71442015-01-15 16:57:00 -0800776 cmdstr = str( cmdstr )
777 self.handle.sendline( "" )
778 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400779
kelvin-onlabd3b64892015-01-20 13:26:24 -0800780 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800781 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400782
kelvin-onlabd3b64892015-01-20 13:26:24 -0800783 handleBefore = self.handle.before
Shreya Shaha73aaad2014-10-27 18:03:09 -0400784 print "handle_before = ", self.handle.before
kelvin-onlabd3b64892015-01-20 13:26:24 -0800785 # handleAfter = str( self.handle.after )
Jon Hall47a93fb2015-01-06 16:46:06 -0800786
kelvin8ec71442015-01-15 16:57:00 -0800787 # self.handle.sendline( "" )
788 # self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800789 # handleMore = str( self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400790
kelvin8ec71442015-01-15 16:57:00 -0800791 main.log.info( "Command sent successfully" )
andrewonlab05e362f2014-10-10 00:40:57 -0400792
kelvin8ec71442015-01-15 16:57:00 -0800793 # Obtain return handle that consists of result from
794 # the onos command. The string may need to be
795 # configured further.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800796 # returnString = handleBefore + handleAfter
797 returnString = handleBefore
798 print "return_string = ", returnString
799 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400800
801 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800802 main.log.error( self.name + ": EOF exception found" )
803 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400804 main.cleanup()
805 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700806 except Exception:
807 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab05e362f2014-10-10 00:40:57 -0400808 main.cleanup()
809 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400810
kelvin-onlabd3b64892015-01-20 13:26:24 -0800811 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800812 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400813 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800814 If -f option is provided, it also forces an uninstall.
815 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400816 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800817 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400818 files to certain onos nodes
819
820 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800821 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400822 try:
andrewonlab114768a2014-11-14 12:44:44 -0500823 if options:
kelvin8ec71442015-01-15 16:57:00 -0800824 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500825 else:
kelvin8ec71442015-01-15 16:57:00 -0800826 self.handle.sendline( "onos-install " + node )
827 self.handle.expect( "onos-install " )
828 # NOTE: this timeout may need to change depending on the network
829 # and size of ONOS
830 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800831 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800832 "ONOS\sis\salready\sinstalled",
833 pexpect.TIMEOUT ], timeout=60 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400834
Jon Hall7993bfc2014-10-09 16:30:14 -0400835 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800836 main.log.warn( "Network is unreachable" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400837 return main.FALSE
838 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800839 main.log.info(
840 "ONOS was installed on " +
841 node +
842 " and started" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400843 return main.TRUE
andrewonlabd9a73a72014-11-14 17:28:21 -0500844 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800845 main.log.info( "ONOS is already installed on " + node )
andrewonlabd9a73a72014-11-14 17:28:21 -0500846 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800847 elif i == 3:
848 main.log.info(
849 "Installation of ONOS on " +
850 node +
851 " timed out" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400852 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400853
854 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800855 main.log.error( self.name + ": EOF exception found" )
856 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400857 main.cleanup()
858 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700859 except Exception:
860 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400861 main.cleanup()
862 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400863
kelvin-onlabd3b64892015-01-20 13:26:24 -0800864 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800865 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400866 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400867 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800868 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400869 try:
kelvin8ec71442015-01-15 16:57:00 -0800870 self.handle.sendline( "" )
871 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800872 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800873 " start" )
874 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -0400875 "Job\sis\salready\srunning",
876 "start/running",
877 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800878 pexpect.TIMEOUT ], timeout=120 )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400879
880 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800881 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400882 return main.TRUE
883 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800884 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400885 return main.TRUE
886 else:
kelvin8ec71442015-01-15 16:57:00 -0800887 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400888 main.cleanup()
889 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -0400890 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800891 main.log.error( self.name + ": EOF exception found" )
892 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400893 main.cleanup()
894 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700895 except Exception:
896 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400897 main.cleanup()
898 main.exit()
899
kelvin-onlabd3b64892015-01-20 13:26:24 -0800900 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800901 """
andrewonlab2b30bd32014-10-09 16:48:55 -0400902 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400903 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800904 """
andrewonlab2b30bd32014-10-09 16:48:55 -0400905 try:
kelvin8ec71442015-01-15 16:57:00 -0800906 self.handle.sendline( "" )
907 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800908 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800909 " stop" )
910 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -0400911 "stop/waiting",
pingping-lin763ee042015-05-20 17:45:30 -0700912 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -0400913 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800914 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2b30bd32014-10-09 16:48:55 -0400915
916 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800917 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400918 return main.TRUE
919 elif i == 1:
pingping-lin763ee042015-05-20 17:45:30 -0700920 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800921 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -0400922 return main.FALSE
pingping-lin763ee042015-05-20 17:45:30 -0700923 elif i == 2:
924 main.log.warn( "ONOS wasn't running" )
925 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -0400926 else:
kelvin8ec71442015-01-15 16:57:00 -0800927 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400928 return main.FALSE
929
930 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800931 main.log.error( self.name + ": EOF exception found" )
932 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -0400933 main.cleanup()
934 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700935 except Exception:
936 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400937 main.cleanup()
938 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800939
kelvin-onlabd3b64892015-01-20 13:26:24 -0800940 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -0800941 """
andrewonlabc8d47972014-10-09 16:52:36 -0400942 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -0800943 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -0400944 if needed
kelvin8ec71442015-01-15 16:57:00 -0800945 """
andrewonlabc8d47972014-10-09 16:52:36 -0400946 try:
kelvin8ec71442015-01-15 16:57:00 -0800947 self.handle.sendline( "" )
pingping-lin763ee042015-05-20 17:45:30 -0700948 self.handle.expect( "\$", timeout=60 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800949 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800950 self.handle.expect( "\$" )
andrewonlabc8d47972014-10-09 16:52:36 -0400951
kelvin-onlabd3b64892015-01-20 13:26:24 -0800952 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
andrewonlab9dfd2082014-11-13 17:44:03 -0500953
kelvin8ec71442015-01-15 16:57:00 -0800954 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -0400955 return main.TRUE
956
pingping-lin763ee042015-05-20 17:45:30 -0700957 except pexpect.TIMEOUT:
958 main.log.exception( self.name + ": Timeout in onosUninstall" )
959 return main.FALSE
andrewonlabc8d47972014-10-09 16:52:36 -0400960 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800961 main.log.error( self.name + ": EOF exception found" )
962 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -0400963 main.cleanup()
964 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700965 except Exception:
966 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc8d47972014-10-09 16:52:36 -0400967 main.cleanup()
968 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -0400969
kelvin-onlabd3b64892015-01-20 13:26:24 -0800970 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800971 """
andrewonlabaedc8332014-12-04 12:43:03 -0500972 Issues the command 'onos-die <node-ip>'
973 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -0800974 """
andrewonlabaedc8332014-12-04 12:43:03 -0500975 try:
kelvin8ec71442015-01-15 16:57:00 -0800976 self.handle.sendline( "" )
977 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800978 cmdStr = "onos-kill " + str( nodeIp )
979 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -0800980 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -0500981 "Killing\sONOS",
982 "ONOS\sprocess\sis\snot\srunning",
kelvin8ec71442015-01-15 16:57:00 -0800983 pexpect.TIMEOUT ], timeout=20 )
andrewonlabaedc8332014-12-04 12:43:03 -0500984 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800985 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800986 " was killed and stopped" )
andrewonlabaedc8332014-12-04 12:43:03 -0500987 return main.TRUE
988 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800989 main.log.info( "ONOS process was not running" )
andrewonlabaedc8332014-12-04 12:43:03 -0500990 return main.FALSE
991 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800992 main.log.error( self.name + ": EOF exception found" )
993 main.log.error( self.name + ": " + self.handle.before )
andrewonlabaedc8332014-12-04 12:43:03 -0500994 main.cleanup()
995 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700996 except Exception:
997 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabaedc8332014-12-04 12:43:03 -0500998 main.cleanup()
999 main.exit()
1000
kelvin-onlabd3b64892015-01-20 13:26:24 -08001001 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001002 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001003 Calls the command: 'onos-kill [<node-ip>]'
1004 "Remotely, and unceremoniously kills the ONOS instance running on
1005 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001006 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001007 try:
kelvin8ec71442015-01-15 16:57:00 -08001008 self.handle.sendline( "" )
1009 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001010 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001011 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -04001012 "\$",
1013 "No\sroute\sto\shost",
1014 "password:",
kelvin8ec71442015-01-15 16:57:00 -08001015 pexpect.TIMEOUT ], timeout=20 )
1016
andrewonlabe8e56fd2014-10-09 17:12:44 -04001017 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001018 main.log.info(
1019 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001020 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001021 return main.TRUE
1022 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001023 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001024 return main.FALSE
1025 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001026 main.log.info(
1027 "Passwordless login for host: " +
1028 str( nodeIp ) +
1029 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001030 return main.FALSE
1031 else:
pingping-lin763ee042015-05-20 17:45:30 -07001032 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001033 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001034
andrewonlabe8e56fd2014-10-09 17:12:44 -04001035 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001036 main.log.error( self.name + ": EOF exception found" )
1037 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001038 main.cleanup()
1039 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001040 except Exception:
1041 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001042 main.cleanup()
1043 main.exit()
1044
kelvin-onlabd3b64892015-01-20 13:26:24 -08001045 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001046 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001047 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001048 a cleaner environment.
1049
andrewonlab19fbdca2014-11-14 12:55:59 -05001050 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001051 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001052 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001053 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001054 try:
kelvin8ec71442015-01-15 16:57:00 -08001055 self.handle.sendline( "" )
1056 self.handle.expect( "\$" )
1057 self.handle.sendline( "onos-remove-raft-logs" )
1058 # Sometimes this command hangs
1059 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1060 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001061 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001062 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1063 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001064 if i == 1:
1065 return main.FALSE
pingping-lin763ee042015-05-20 17:45:30 -07001066 #self.handle.sendline( "" )
1067 #self.handle.expect( "\$" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001068 return main.TRUE
1069
1070 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001071 main.log.error( self.name + ": EOF exception found" )
1072 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -05001073 main.cleanup()
1074 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001075 except Exception:
1076 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001077 main.cleanup()
1078 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -05001079
kelvin-onlabd3b64892015-01-20 13:26:24 -08001080 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001081 """
1082 Calls the command 'onos-start-network [ <mininet-topo> ]
1083 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001084 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001085 cell."
andrewonlab94282092014-10-10 13:00:11 -04001086 * Specify mininet topology file name for mntopo
1087 * Topo files should be placed at:
1088 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001089
andrewonlab94282092014-10-10 13:00:11 -04001090 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001091 """
andrewonlab94282092014-10-10 13:00:11 -04001092 try:
1093 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001094 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001095 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001096
kelvin8ec71442015-01-15 16:57:00 -08001097 mntopo = str( mntopo )
1098 self.handle.sendline( "" )
1099 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -04001100
kelvin8ec71442015-01-15 16:57:00 -08001101 self.handle.sendline( "onos-start-network " + mntopo )
1102 self.handle.expect( "mininet>" )
1103 main.log.info( "Network started, entered mininet prompt" )
1104
1105 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001106
1107 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001108 main.log.error( self.name + ": EOF exception found" )
1109 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -04001110 main.cleanup()
1111 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001112 except Exception:
1113 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -04001114 main.cleanup()
1115 main.exit()
1116
pingping-lin763ee042015-05-20 17:45:30 -07001117 def isup(self, node = "", timeout = 120):
kelvin8ec71442015-01-15 16:57:00 -08001118 """
1119 Run's onos-wait-for-start which only returns once ONOS is at run
pingping-lin763ee042015-05-20 17:45:30 -07001120 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001121
Jon Hall7993bfc2014-10-09 16:30:14 -04001122 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001123 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001124 try:
pingping-lin763ee042015-05-20 17:45:30 -07001125 self.handle.sendline("onos-wait-for-start " + node )
1126 self.handle.expect("onos-wait-for-start")
kelvin8ec71442015-01-15 16:57:00 -08001127 # NOTE: this timeout is arbitrary"
pingping-lin763ee042015-05-20 17:45:30 -07001128 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001129 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001130 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001131 return main.TRUE
1132 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001133 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001134 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001135 main.log.error( "ONOS has not started yet" )
1136 self.handle.send( "\x03" ) # Control-C
1137 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001138 return main.FALSE
1139 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001140 main.log.error( self.name + ": EOF exception found" )
1141 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -04001142 main.cleanup()
1143 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001144 except Exception:
1145 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001146 main.cleanup()
1147 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001148
kelvin-onlabd3b64892015-01-20 13:26:24 -08001149 def pushTestIntentsShell(
1150 self,
1151 dpidSrc,
1152 dpidDst,
1153 numIntents,
1154 dirFile,
1155 onosIp,
1156 numMult="",
1157 appId="",
1158 report=True,
1159 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001160 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001161 Description:
kelvin8ec71442015-01-15 16:57:00 -08001162 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001163 better parallelize the results than the CLI
1164 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001165 * dpidSrc: specify source dpid
1166 * dpidDst: specify destination dpid
1167 * numIntents: specify number of intents to push
1168 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001169 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001170 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001171 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001172 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001173 """
1174 try:
1175 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001176 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001177 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001178 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001179 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001180 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001181
kelvin-onlabd3b64892015-01-20 13:26:24 -08001182 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1183 if not numMult:
1184 addIntents = addDpid + " " + str( numIntents )
1185 elif numMult:
1186 addIntents = addDpid + " " + str( numIntents ) + " " +\
1187 str( numMult )
1188 if appId:
1189 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001190 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001191 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001192
andrewonlabaedc8332014-12-04 12:43:03 -05001193 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001194 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001195 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001196 sendCmd = addApp + " &"
1197 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001198
kelvin-onlabd3b64892015-01-20 13:26:24 -08001199 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001200
1201 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001202 main.log.error( self.name + ": EOF exception found" )
1203 main.log.error( self.name + ": " + self.handle.before )
andrewonlabb66dfa12014-12-02 15:51:10 -05001204 main.cleanup()
1205 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001206 except Exception:
1207 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001208 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001209 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001210
kelvin-onlabd3b64892015-01-20 13:26:24 -08001211 def getTopology( self, topologyOutput ):
kelvin8ec71442015-01-15 16:57:00 -08001212 """
pingping-lin763ee042015-05-20 17:45:30 -07001213 Definition:
1214 Loads a json topology output
1215 Return:
1216 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -08001217 """
pingping-lin763ee042015-05-20 17:45:30 -07001218 import json
Jon Hall77f53ce2014-10-13 18:02:06 -04001219 try:
pingping-lin763ee042015-05-20 17:45:30 -07001220 # either onos:topology or 'topology' will work in CLI
1221 topology = json.loads(topologyOutput)
1222 print topology
Jon Hall77f53ce2014-10-13 18:02:06 -04001223 return topology
1224 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001225 main.log.error( self.name + ": EOF exception found" )
1226 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001227 main.cleanup()
1228 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001229 except Exception:
1230 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001231 main.cleanup()
1232 main.exit()
1233
kelvin-onlabd3b64892015-01-20 13:26:24 -08001234 def checkStatus(
1235 self,
1236 topologyResult,
1237 numoswitch,
1238 numolink,
1239 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001240 """
pingping-lin763ee042015-05-20 17:45:30 -07001241 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001242 supplied values. By default this will report to main.log, but the
pingping-lin763ee042015-05-20 17:45:30 -07001243 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08001244
Jon Hall77f53ce2014-10-13 18:02:06 -04001245 Params: ip = ip used for the onos cli
1246 numoswitch = expected number of switches
pingping-lin763ee042015-05-20 17:45:30 -07001247 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001248 logLevel = level to log to.
1249 Currently accepts 'info', 'warn' and 'report'
Jon Hall77f53ce2014-10-13 18:02:06 -04001250
1251
kelvin-onlabd3b64892015-01-20 13:26:24 -08001252 logLevel can
Jon Hall77f53ce2014-10-13 18:02:06 -04001253
pingping-lin763ee042015-05-20 17:45:30 -07001254 Returns: main.TRUE if the number of switches and links are correct,
1255 main.FALSE if the number of switches and links is incorrect,
Jon Hall77f53ce2014-10-13 18:02:06 -04001256 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001257 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001258 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 topology = self.getTopology( topologyResult )
Jon Hall77f53ce2014-10-13 18:02:06 -04001260 if topology == {}:
1261 return main.ERROR
1262 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001263 # Is the number of switches is what we expected
pingping-lin763ee042015-05-20 17:45:30 -07001264 devices = topology.get( 'deviceCount', False )
1265 links = topology.get( 'linkCount', False )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001266 if not devices or not links:
Jon Hall77f53ce2014-10-13 18:02:06 -04001267 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001268 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001269 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001270 linkCheck = ( int( links ) == int( numolink ) )
pingping-lin763ee042015-05-20 17:45:30 -07001271 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08001272 # We expected the correct numbers
Jon Hall77f53ce2014-10-13 18:02:06 -04001273 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001274 + "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001275 result = main.TRUE
1276 else:
1277 output = output + \
pingping-lin763ee042015-05-20 17:45:30 -07001278 "The number of links and switches does not match " + \
1279 "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001280 result = main.FALSE
pingping-lin763ee042015-05-20 17:45:30 -07001281 output = output + "\n ONOS sees %i devices" % int( devices )
1282 output = output + " (%i expected) " % int( numoswitch )
1283 output = output + "and %i links " % int( links )
1284 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001285 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001286 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001287 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001288 main.log.warn( output )
Jon Hall77f53ce2014-10-13 18:02:06 -04001289 else:
kelvin8ec71442015-01-15 16:57:00 -08001290 main.log.info( output )
1291 return result
Jon Hall77f53ce2014-10-13 18:02:06 -04001292 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001293 main.log.error( self.name + ": EOF exception found" )
1294 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001295 main.cleanup()
1296 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001297 except Exception:
1298 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001299 main.cleanup()
1300 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001301
kelvin-onlabd3b64892015-01-20 13:26:24 -08001302 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001303 """
andrewonlab970399c2014-11-07 13:09:32 -05001304 Capture all packet activity and store in specified
1305 directory/file
1306
1307 Required:
1308 * interface: interface to capture
1309 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001310 """
pingping-lin763ee042015-05-20 17:45:30 -07001311 try:
1312 self.handle.sendline( "" )
1313 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001314
pingping-lin763ee042015-05-20 17:45:30 -07001315 self.handle.sendline( "tshark -i " + str( interface ) +
1316 " -t e -w " + str( dirFile ) + " &" )
1317 self.handle.sendline( "\r" )
1318 self.handle.expect( "Capturing on" )
1319 self.handle.sendline( "\r" )
1320 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001321
pingping-lin763ee042015-05-20 17:45:30 -07001322 main.log.info( "Tshark started capturing files on " +
1323 str( interface ) + " and saving to directory: " +
1324 str( dirFile ) )
1325 except pexpect.EOF:
1326 main.log.error( self.name + ": EOF exception found" )
1327 main.log.error( self.name + ": " + self.handle.before )
1328 main.cleanup()
1329 main.exit()
1330 except Exception:
1331 main.log.exception( self.name + ": Uncaught exception!" )
1332 main.cleanup()
1333 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001334
kelvin-onlabd3b64892015-01-20 13:26:24 -08001335 def runOnosTopoCfg( self, instanceName, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001336 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001337 On ONOS bench, run this command:
pingping-lin763ee042015-05-20 17:45:30 -07001338 {ONOS_HOME}/tools/test/bin/onos-topo-cfg $OC1 filename
kelvin-onlabd3b64892015-01-20 13:26:24 -08001339 which starts the rest and copies
1340 the json file to the onos instance
kelvin8ec71442015-01-15 16:57:00 -08001341 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001342 try:
kelvin8ec71442015-01-15 16:57:00 -08001343 self.handle.sendline( "" )
1344 self.handle.expect( "\$" )
pingping-lin763ee042015-05-20 17:45:30 -07001345 self.handle.sendline( "cd " + self.home + "/tools/test/bin" )
kelvin8ec71442015-01-15 16:57:00 -08001346 self.handle.expect( "/bin$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001347 cmd = "./onos-topo-cfg " + instanceName + " " + jsonFile
shahshreyae6c7cf42014-11-26 16:39:01 -08001348 print "cmd = ", cmd
kelvin8ec71442015-01-15 16:57:00 -08001349 self.handle.sendline( cmd )
1350 self.handle.expect( "\$" )
1351 self.handle.sendline( "cd ~" )
1352 self.handle.expect( "\$" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001353 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -07001354 except pexpect.EOF:
1355 main.log.error( self.name + ": EOF exception found" )
1356 main.log.error( self.name + ": " + self.handle.before )
1357 main.cleanup()
1358 main.exit()
1359 except Exception:
1360 main.log.exception( self.name + ": Uncaught exception!" )
1361 main.cleanup()
1362 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001363
pingping-lin763ee042015-05-20 17:45:30 -07001364 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001365 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001366 Required:
kelvin8ec71442015-01-15 16:57:00 -08001367 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001368 * directory to store results
1369 Optional:
1370 * interface - default: eth0
pingping-lin763ee042015-05-20 17:45:30 -07001371 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001372 Description:
1373 Uses tshark command to grep specific group of packets
1374 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001375 The timestamp is hardcoded to be in epoch
1376 """
pingping-lin763ee042015-05-20 17:45:30 -07001377 try:
1378 self.handle.sendline( "" )
1379 self.handle.expect( "\$" )
1380 self.handle.sendline( "" )
1381 if grepOptions:
1382 grepStr = "grep "+str(grepOptions)
1383 else:
1384 grepStr = "grep"
1385
1386 self.handle.sendline(
1387 "tshark -i " +
1388 str( interface ) +
1389 " -t e | " +
1390 grepStr + " --line-buffered \"" +
1391 str(grep) +
1392 "\" >" +
1393 directory +
1394 " &" )
1395 self.handle.sendline( "\r" )
1396 self.handle.expect( "Capturing on" )
1397 self.handle.sendline( "\r" )
1398 self.handle.expect( "\$" )
1399 except pexpect.EOF:
1400 main.log.error( self.name + ": EOF exception found" )
1401 main.log.error( self.name + ": " + self.handle.before )
1402 main.cleanup()
1403 main.exit()
1404 except Exception:
1405 main.log.exception( self.name + ": Uncaught exception!" )
1406 main.cleanup()
1407 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001408
kelvin-onlabd3b64892015-01-20 13:26:24 -08001409 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001410 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001411 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001412 """
1413 # Remove all pcap from previous captures
pingping-lin763ee042015-05-20 17:45:30 -07001414 try:
1415 self.execute( cmd="sudo rm /tmp/wireshark*" )
1416 self.handle.sendline( "" )
1417 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1418 " | grep -v grep | awk '{print $2}'`" )
1419 self.handle.sendline( "" )
1420 main.log.info( "Tshark stopped" )
1421 except pexpect.EOF:
1422 main.log.error( self.name + ": EOF exception found" )
1423 main.log.error( self.name + ": " + self.handle.before )
1424 main.cleanup()
1425 main.exit()
1426 except Exception:
1427 main.log.exception( self.name + ": Uncaught exception!" )
1428 main.cleanup()
1429 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001430
kelvin8ec71442015-01-15 16:57:00 -08001431 def ptpd( self, args ):
1432 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001433 Initiate ptp with user-specified args.
1434 Required:
1435 * args: specify string of args after command
1436 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001437 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001438 try:
kelvin8ec71442015-01-15 16:57:00 -08001439 self.handle.sendline( "sudo ptpd " + str( args ) )
1440 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001441 "Multiple",
1442 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001443 "\$" ] )
1444 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001445
andrewonlab0c38a4a2014-10-28 18:35:35 -04001446 if i == 0:
1447 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001448 main.log.info( "ptpd returned an error: " +
1449 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001450 return handle
1451 elif i == 1:
1452 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001453 main.log.error( "ptpd returned an error: " +
1454 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001455 return handle
1456 else:
1457 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001458
andrewonlab0c38a4a2014-10-28 18:35:35 -04001459 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001460 main.log.error( self.name + ": EOF exception found" )
1461 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001462 main.cleanup()
1463 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001464 except Exception:
1465 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001466 main.cleanup()
1467 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001468
kelvin-onlabd3b64892015-01-20 13:26:24 -08001469 def cpLogsToDir( self, logToCopy,
pingping-lin763ee042015-05-20 17:45:30 -07001470 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001471 """
1472 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001473 Current implementation of ONOS deletes its karaf
1474 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001475 you may want to use this function to capture
1476 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001477 Localtime will be attached to the filename
1478
1479 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001480 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001481 copy.
kelvin8ec71442015-01-15 16:57:00 -08001482 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001483 For copying multiple files, leave copyFileName
1484 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001485 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001486 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001487 ex ) /tmp/
1488 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001489 * copyFileName: If you want to rename the log
1490 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001491 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001492 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001493 try:
kelvin8ec71442015-01-15 16:57:00 -08001494 localtime = time.strftime( '%x %X' )
1495 localtime = localtime.replace( "/", "" )
1496 localtime = localtime.replace( " ", "_" )
1497 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001498 if destDir[ -1: ] != "/":
1499 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001500
kelvin-onlabd3b64892015-01-20 13:26:24 -08001501 if copyFileName:
pingping-lin763ee042015-05-20 17:45:30 -07001502 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1503 str( destDir ) + str( copyFileName ) +
1504 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001505 self.handle.expect( "cp" )
1506 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001507 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001508 self.handle.sendline( "cp " + str( logToCopy ) +
1509 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001510 self.handle.expect( "cp" )
1511 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001512
kelvin8ec71442015-01-15 16:57:00 -08001513 return self.handle.before
1514
1515 except pexpect.EOF:
1516 main.log.error( "Copying files failed" )
1517 main.log.error( self.name + ": EOF exception found" )
1518 main.log.error( self.name + ": " + self.handle.before )
pingping-lin763ee042015-05-20 17:45:30 -07001519 except Exception:
1520 main.log.exception( "Copying files failed" )
kelvin8ec71442015-01-15 16:57:00 -08001521
kelvin-onlabd3b64892015-01-20 13:26:24 -08001522 def checkLogs( self, onosIp ):
kelvin8ec71442015-01-15 16:57:00 -08001523 """
Jon Hall94fd0472014-12-08 11:52:42 -08001524 runs onos-check-logs on the given onos node
1525 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001526 """
Jon Hall94fd0472014-12-08 11:52:42 -08001527 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001528 cmd = "onos-check-logs " + str( onosIp )
kelvin8ec71442015-01-15 16:57:00 -08001529 self.handle.sendline( cmd )
1530 self.handle.expect( cmd )
1531 self.handle.expect( "\$" )
Jon Hall94fd0472014-12-08 11:52:42 -08001532 response = self.handle.before
1533 return response
1534 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001535 main.log.error( "Lost ssh connection" )
1536 main.log.error( self.name + ": EOF exception found" )
1537 main.log.error( self.name + ": " + self.handle.before )
pingping-lin763ee042015-05-20 17:45:30 -07001538 except Exception:
1539 main.log.exception( self.name + ": Uncaught exception!" )
1540 main.cleanup()
1541 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001542
kelvin-onlabd3b64892015-01-20 13:26:24 -08001543 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001544 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001545 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001546 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001547 try:
kelvin8ec71442015-01-15 16:57:00 -08001548 self.handle.sendline( "" )
1549 self.handle.expect( "\$" )
1550 self.handle.sendline( "onos-service " + str( node ) +
1551 " status" )
1552 i = self.handle.expect( [
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001553 "start/running",
1554 "stop/waiting",
kelvin8ec71442015-01-15 16:57:00 -08001555 pexpect.TIMEOUT ], timeout=120 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001556
1557 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001558 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001559 return main.TRUE
1560 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001561 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001562 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001563 main.cleanup()
1564 main.exit()
1565 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001566 main.log.error( self.name + ": EOF exception found" )
1567 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001568 main.cleanup()
1569 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001570 except Exception:
1571 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001572 main.cleanup()
1573 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -07001574
1575 def setIpTables( self, ip, port='', action='add', packet_type='',
1576 direction='INPUT', rule='DROP', states=True ):
1577 """
1578 Description:
1579 add or remove iptables rule to DROP (default) packets from
1580 specific IP and PORT
1581 Usage:
1582 * specify action ('add' or 'remove')
1583 when removing, pass in the same argument as you would add. It will
1584 delete that specific rule.
1585 * specify the ip to block
1586 * specify the destination port to block (defaults to all ports)
1587 * optional packet type to block (default tcp)
1588 * optional iptables rule (default DROP)
1589 * optional direction to block (default 'INPUT')
1590 * States boolean toggles adding all supported tcp states to the
1591 firewall rule
1592 Returns:
1593 main.TRUE on success or
1594 main.FALSE if given invalid input or
1595 main.ERROR if there is an error in response from iptables
1596 WARNING:
1597 * This function uses root privilege iptables command which may result
1598 in unwanted network errors. USE WITH CAUTION
1599 """
1600 import time
1601
1602 # NOTE*********
1603 # The strict checking methods of this driver function is intentional
1604 # to discourage any misuse or error of iptables, which can cause
1605 # severe network errors
1606 # *************
1607
1608 # NOTE: Sleep needed to give some time for rule to be added and
1609 # registered to the instance. If you are calling this function
1610 # multiple times this sleep will prevent any errors.
1611 # DO NOT REMOVE
1612 # time.sleep( 5 )
1613 try:
1614 # input validation
1615 action_type = action.lower()
1616 rule = rule.upper()
1617 direction = direction.upper()
1618 if action_type != 'add' and action_type != 'remove':
1619 main.log.error( "Invalid action type. Use 'add' or "
1620 "'remove' table rule" )
1621 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1622 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1623 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1624 "'ACCEPT' or 'LOG' only." )
1625 if direction != 'INPUT' and direction != 'OUTPUT':
1626 # NOTE currently only supports rules INPUT and OUPTUT
1627 main.log.error( "Invalid rule. Valid directions are"
1628 " 'OUTPUT' or 'INPUT'" )
1629 return main.FALSE
1630 return main.FALSE
1631 return main.FALSE
1632 if action_type == 'add':
1633 # -A is the 'append' action of iptables
1634 actionFlag = '-A'
1635 elif action_type == 'remove':
1636 # -D is the 'delete' rule of iptables
1637 actionFlag = '-D'
1638 self.handle.sendline( "" )
1639 self.handle.expect( "\$" )
1640 cmd = "sudo iptables " + actionFlag + " " +\
1641 direction +\
1642 " -s " + str( ip )
1643 # " -p " + str( packet_type ) +\
1644 if packet_type:
1645 cmd += " -p " + str( packet_type )
1646 if port:
1647 cmd += " --dport " + str( port )
1648 if states:
1649 cmd += " -m state --state="
1650 #FIXME- Allow user to configure which states to block
1651 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
1652 cmd += " -j " + str( rule )
1653
1654 self.handle.sendline( cmd )
1655 self.handle.expect( "\$" )
1656 main.log.warn( self.handle.before )
1657
1658 info_string = "On " + str( self.name )
1659 info_string += " " + str( action_type )
1660 info_string += " iptable rule [ "
1661 info_string += " IP: " + str( ip )
1662 info_string += " Port: " + str( port )
1663 info_string += " Rule: " + str( rule )
1664 info_string += " Direction: " + str( direction ) + " ]"
1665 main.log.info( info_string )
1666 return main.TRUE
1667 except pexpect.TIMEOUT:
1668 main.log.exception( self.name + ": Timeout exception in "
1669 "setIpTables function" )
1670 return main.ERROR
1671 except pexpect.EOF:
1672 main.log.error( self.name + ": EOF exception found" )
1673 main.log.error( self.name + ": " + self.handle.before )
1674 main.cleanup()
1675 main.exit()
1676 except Exception:
1677 main.log.exception( self.name + ": Uncaught exception!" )
1678 main.cleanup()
1679 main.exit()
1680
1681 def detailed_status(self, log_filename):
1682 """
1683 This method is used by STS to check the status of the controller
1684 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
1685 """
1686 import re
1687 try:
1688 self.handle.sendline( "" )
1689 self.handle.expect( "\$" )
1690 self.handle.sendline( "cd " + self.home )
1691 self.handle.expect( "\$" )
1692 self.handle.sendline( "service onos status" )
1693 self.handle.expect( "\$" )
1694 response = self.handle.before
1695 if re.search( "onos start/running", response ):
1696 # onos start/running, process 10457
1697 return 'RUNNING'
1698 # FIXME: Implement this case
1699 # elif re.search( pattern, response ):
1700 # return 'STARTING'
1701 elif re.search( "onos stop/", response ):
1702 # onos stop/waiting
1703 # FIXME handle this differently?: onos stop/pre-stop
1704 return 'STOPPED'
1705 # FIXME: Implement this case
1706 # elif re.search( pattern, response ):
1707 # return 'FROZEN'
1708 else:
1709 main.log.warn( self.name +
1710 " WARNING: status received unknown response" )
1711 main.log.warn( response )
1712 return 'ERROR', "Unknown response: %s" % response
1713 except pexpect.TIMEOUT:
1714 main.log.exception( self.name + ": Timeout exception in "
1715 "setIpTables function" )
1716 return 'ERROR', "Pexpect Timeout"
1717 except pexpect.EOF:
1718 main.log.error( self.name + ": EOF exception found" )
1719 main.log.error( self.name + ": " + self.handle.before )
1720 main.cleanup()
1721 main.exit()
1722 except Exception:
1723 main.log.exception( self.name + ": Uncaught exception!" )
1724 main.cleanup()
1725 main.exit()
1726
1727 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1728 '''
1729 Create/formats the LinkGraph.cfg file based on arguments
1730 -only creates a linear topology and connects islands
1731 -evenly distributes devices
1732 -must be called by ONOSbench
1733
1734 ONOSIpList - list of all of the node IPs to be used
1735
1736 deviceCount - number of switches to be assigned
1737 '''
1738 main.log.step("Creating link graph configuration file." )
1739 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
1740 tempFile = "/tmp/linkGraph.cfg"
1741
1742 linkGraph = open(tempFile, 'w+')
1743 linkGraph.write("# NullLinkProvider topology description (config file).\n")
1744 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
1745 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
1746
1747 clusterCount = len(ONOSIpList)
1748
1749 if type(deviceCount) is int or type(deviceCount) is str:
1750 deviceCount = int(deviceCount)
1751 switchList = [0]*(clusterCount+1)
1752 baselineSwitchCount = deviceCount/clusterCount
1753
1754 for node in range(1, clusterCount + 1):
1755 switchList[node] = baselineSwitchCount
1756
1757 for node in range(1, (deviceCount%clusterCount)+1):
1758 switchList[node] += 1
1759
1760 if type(deviceCount) is list:
1761 main.log.info("Using provided device distribution")
1762 switchList = [0]
1763 for i in deviceCount:
1764 switchList.append(int(i))
1765
1766 tempList = ['0']
1767 tempList.extend(ONOSIpList)
1768 ONOSIpList = tempList
1769
1770 myPort = 6
1771 lastSwitch = 0
1772 for node in range(1, clusterCount+1):
1773 if switchList[node] == 0:
1774 continue
1775
1776 linkGraph.write("graph " + ONOSIpList[node] + " {\n")
1777
1778 if node > 1:
1779 #connect to last device on previous node
1780 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
1781 linkGraph.write(line)
1782
1783 lastSwitch = 0
1784 for switch in range (0, switchList[node]-1):
1785 line = ""
1786 line = ("\t" + str(switch) + ":" + str(myPort))
1787 line += " -- "
1788 line += (str(switch+1) + ":" + str(myPort-1) + "\n")
1789 linkGraph.write(line)
1790 lastSwitch = switch+1
1791 lastIp = ONOSIpList[node]
1792
1793 #lastSwitch += 1
1794 if node < (clusterCount):
1795 #connect to first device on the next node
1796 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
1797 linkGraph.write(line)
1798
1799 linkGraph.write("}\n")
1800 linkGraph.close()
1801
1802 #SCP
1803 os.system( "scp " + tempFile + " admin@" + benchIp + ":" + linkGraphPath)
1804 main.log.info("linkGraph.cfg creation complete")
1805
1806 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
1807
1808 '''
1809 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
1810 deviceCount = number of switches to distribute, or list of values to use as custom distribution
1811 numPorts = number of ports per device. Defaults to 10 both in this function and in ONOS. Optional arg
1812 '''
1813
1814 main.log.step("Configuring Null Device Provider" )
1815 clusterCount = len(ONOSIpList)
1816
1817 try:
1818
1819 if type(deviceCount) is int or type(deviceCount) is str:
1820 main.log.step("Creating device distribution")
1821 deviceCount = int(deviceCount)
1822 switchList = [0]*(clusterCount+1)
1823 baselineSwitchCount = deviceCount/clusterCount
1824
1825 for node in range(1, clusterCount + 1):
1826 switchList[node] = baselineSwitchCount
1827
1828 for node in range(1, (deviceCount%clusterCount)+1):
1829 switchList[node] += 1
1830
1831 if type(deviceCount) is list:
1832 main.log.info("Using provided device distribution")
1833
1834 if len(deviceCount) == clusterCount:
1835 switchList = ['0']
1836 switchList.extend(deviceCount)
1837
1838 if len(deviceCount) == (clusterCount + 1):
1839 if deviceCount[0] == '0' or deviceCount[0] == 0:
1840 switchList = deviceCount
1841
1842 assert len(switchList) == (clusterCount + 1)
1843
1844 except AssertionError:
1845 main.log.error( "Bad device/Ip list match")
1846 except TypeError:
1847 main.log.exception( self.name + ": Object not as expected" )
1848 return None
1849 except Exception:
1850 main.log.exception( self.name + ": Uncaught exception!" )
1851 main.cleanup()
1852 main.exit()
1853
1854
1855 ONOSIp = [0]
1856 ONOSIp.extend(ONOSIpList)
1857
1858 devicesString = "devConfigs = "
1859 for node in range(1, len(ONOSIp)):
1860 devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
1861 if node < clusterCount:
1862 devicesString += (",")
1863
1864 try:
1865 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
1866 self.handle.expect(":~")
1867 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) )
1868 self.handle.expect(":~")
1869
1870 for i in range(10):
1871 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider")
1872 self.handle.expect(":~")
1873 verification = self.handle.before
1874 if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification:
1875 break
1876 else:
1877 time.sleep(1)
1878
1879 assert ("value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification
1880
1881 except AssertionError:
1882 main.log.error("Incorrect Config settings: " + verification)
1883 except Exception:
1884 main.log.exception( self.name + ": Uncaught exception!" )
1885 main.cleanup()
1886 main.exit()
1887
1888 def configNullLink( self,fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0):
1889 '''
1890 fileName default is currently the same as the default on ONOS, specify alternate file if
1891 you want to use a different topology file than linkGraph.cfg
1892 '''
1893
1894
1895 try:
1896 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str(eventRate))
1897 self.handle.expect(":~")
1898 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
1899 self.handle.expect(":~")
1900
1901 for i in range(10):
1902 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider")
1903 self.handle.expect(":~")
1904 verification = self.handle.before
1905 if (" value=" + str(eventRate)) in verification and (" value=" + fileName) in verification:
1906 break
1907 else:
1908 time.sleep(1)
1909
1910 assert ("value=" + str(eventRate)) in verification and (" value=" + fileName) in verification
1911
1912 except pexpect.EOF:
1913 main.log.error( self.name + ": EOF exception found" )
1914 main.log.error( self.name + ": " + self.handle.before )
1915 main.cleanup()
1916 main.exit()
1917 except AssertionError:
1918 main.log.info("Settings did not post to ONOS")
1919 main.log.error(varification)
1920 except Exception:
1921 main.log.exception( self.name + ": Uncaught exception!" )
1922 main.log.error(varification)
1923 main.cleanup()
1924 main.exit()
1925
1926
1927 def getOnosIpFromEnv(self):
1928
1929 import string
1930
1931 # returns a list of ip addresses for the onos nodes, will work with up to 7 nodes + OCN and OCI
1932 # returns in format [ 'x', OC1 ip, OC2 i... ect. ... , ONN ip ]
1933
1934 self.handle.sendline("env| grep OC")
1935 self.handle.expect(":~")
1936 rawOutput = self.handle.before
1937 print rawOutput
1938 print "-----------------------------"
1939 print repr(rawOutput)
1940 mpa = dict.fromkeys(range(32))
1941 translated = rawOutput.translate(mpa)
1942 print translated
1943
1944
1945 # create list with only the lines that have the needed IPs
1946 unparsedIps = []
1947
1948 # remove preceeding or trailing lines
1949 for line in rawOutput:
1950 if "OC" in line and "=" in line:
1951 unparsedIps.append(str(line))
1952
1953 # determine cluster size
1954 clusterCount = 0
1955 for line in unparsedIps:
1956 line = str(line)
1957 print line
1958 temp = line.replace("OC","")
1959 print("line index " + str(line.index("=")))
1960 OCindex = temp[0]
1961 for i in range(0, 7):
1962 if OCindex == str(i) and i > clusterCount:
1963 clusterCount == i
1964 print(clusterCount)
1965 # create list to hold ips such that OC1 is at list[1] and OCN and OCI are at the end (in that order)
1966 ONOSIps = ["x"] * (clusterCount + 3)
1967
1968 # populate list
1969 for line in unparsedIps:
1970 main.log.info(line)##########
1971 temp = str(line.replace("OC",""))
1972 main.log.info(str(list(temp)))
1973 OCindex = temp[0]
1974 main.log.info(OCindex)############
1975 if OCindex == "N":
1976 ONOSIps[ clusterCount + 1 ] = temp.replace("N=","")
1977
1978 if OCindex == "I":
1979 ONOSIps[ clusterCount + 2 ] = temp.replace("I=","")
1980
1981 else:
1982 ONOSIps[ int(OCindex) ] = temp.replace((OCindex + "=") ,"")
1983
1984 # validate
1985 for x in ONOSIps:
1986 if ONOSIps.index(x) != 0 and x == "x":
1987 main.log.error("ENV READ FAILURE, MISSING DATA: \n\n" + str(ONOSIps) + "\n\n")
1988
1989 return ONOSIps
1990
1991
1992 def onosErrorLog(self, nodeIp):
1993
1994 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep WARN"
1995 self.handle.sendline(cmd)
1996 self.handle.expect(":~")
1997 before = (self.handle.before).splitlines()
1998
1999 warnings = []
2000
2001 for line in before:
2002 if "WARN" in line and "grep" not in line:
2003 warnings.append(line)
2004 main.warnings[main.warnings[0]+1] = line
2005 main.warnings[0] += 1
2006 if main.warnings[0] >= 10:
2007 main.warnings[0] = 0
2008
2009 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep ERROR"
2010 self.handle.sendline(cmd)
2011 self.handle.expect(":~")
2012 before = (self.handle.before).splitlines()
2013
2014 errors = []
2015
2016 for line in before:
2017 if "ERROR" in line and "grep" not in line:
2018 errors.append(line)
2019 main.errors[main.errors[0]+1] = line
2020 main.errors[0] += 1
2021 if main.errors[0] >= 10:
2022 main.errors[0] = 0
2023
2024 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep Exept"
2025 self.handle.sendline(cmd)
2026 self.handle.expect(":~")
2027 before = (self.handle.before).splitlines()
2028
2029 exceptions = []
2030
2031 for line in before:
2032 if "Except" in line and "grep" not in line:
2033 exceptions.append(line)
2034 main.exceptions[main.errors[0]+1] = line
2035 main.exceptions[0] += 1
2036 if main.exceptions[0] >= 10:
2037 main.exceptions[0] = 0
2038
2039
2040
2041 ################################################################
2042
2043 msg1 = "WARNINGS: \n"
2044 for i in main.warnings:
2045 if type(i) is not int:
2046 msg1 += ( i + "\n")
2047
2048 msg2 = "ERRORS: \n"
2049 for i in main.errors:
2050 if type(i) is not int:
2051 msg2 += ( i + "\n")
2052
2053 msg3 = "EXCEPTIONS: \n"
2054 for i in main.exceptions:
2055 if type(i) is not int:
2056 msg3 += ( i + "\n")
2057
2058 main.log.info("===============================================================\n")
2059 main.log.info( "Warnings: " + str(len(warnings)))
2060 main.log.info( "Errors: " + str(len(errors)))
2061 main.log.info( "Exceptions: " + str(len(exceptions)))
2062 if len(warnings) > 0:
2063 main.log.info(msg1)
2064 if len(errors) > 0:
2065 main.log.info(msg2)
2066 if len(exceptions) > 0:
2067 main.log.info(msg3)
2068 main.log.info("===============================================================\n")
2069