blob: b05a1321b3ff6d908a0d5f66d71ac27b8b95a188 [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
Jon Hall05b2b432014-10-08 19:53:25 -040022import traceback
andrewonlab7735d852014-10-09 13:02:47 -040023import os.path
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 """
34 super( CLI, self ).__init__()
35
36 def connect( self, **connectargs ):
37 """
Jon Hall05b2b432014-10-08 19:53:25 -040038 Creates ssh handle for ONOS "bench".
kelvin8ec71442015-01-15 16:57:00 -080039 """
Jon Hall05b2b432014-10-08 19:53:25 -040040 try:
41 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080042 vars( self )[ key ] = connectargs[ key ]
Jon Hall05b2b432014-10-08 19:53:25 -040043 self.home = "~/ONOS"
44 for key in self.options:
45 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080046 self.home = self.options[ 'home' ]
Jon Hall05b2b432014-10-08 19:53:25 -040047 break
48
kelvin8ec71442015-01-15 16:57:00 -080049 self.name = self.options[ 'name' ]
50 self.handle = super( OnosDriver, self ).connect(
kelvin-onlabd3b64892015-01-20 13:26:24 -080051 userName=self.userName,
52 ipAddress=self.ipAddress,
53 port=self.port,
54 pwd=self.pwd,
55 home=self.home )
Jon Hall05b2b432014-10-08 19:53:25 -040056
kelvin8ec71442015-01-15 16:57:00 -080057 self.handle.sendline( "cd " + self.home )
58 self.handle.expect( "\$" )
Jon Hall05b2b432014-10-08 19:53:25 -040059 if self.handle:
60 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080061 else:
62 main.log.info( "NO ONOS HANDLE" )
Jon Hall05b2b432014-10-08 19:53:25 -040063 return main.FALSE
64 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080065 main.log.error( self.name + ": EOF exception found" )
66 main.log.error( self.name + ": " + self.handle.before )
Jon Hall05b2b432014-10-08 19:53:25 -040067 main.cleanup()
68 main.exit()
69 except:
kelvin-onlabd3b64892015-01-20 13:26:24 -080070 main.log.info( self.name + ":" * 30 )
kelvin-onlab64b33712015-01-21 15:26:15 -080071 main.log.error( traceback.print_exc() )
kelvin-onlabd3b64892015-01-20 13:26:24 -080072 main.log.info( ":" * 30 )
Jon Hall05b2b432014-10-08 19:53:25 -040073 main.cleanup()
74 main.exit()
75
kelvin8ec71442015-01-15 16:57:00 -080076 def disconnect( self ):
77 """
Jon Hall05b2b432014-10-08 19:53:25 -040078 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -080079 """
Jon Hall05b2b432014-10-08 19:53:25 -040080 response = ''
81 try:
kelvin8ec71442015-01-15 16:57:00 -080082 self.handle.sendline( "" )
83 self.handle.expect( "\$" )
84 self.handle.sendline( "exit" )
85 self.handle.expect( "closed" )
Jon Hall05b2b432014-10-08 19:53:25 -040086 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080087 main.log.error( self.name + ": EOF exception found" )
88 main.log.error( self.name + ": " + self.handle.before )
Jon Hall05b2b432014-10-08 19:53:25 -040089 except:
kelvin8ec71442015-01-15 16:57:00 -080090 main.log.error( self.name + ": Connection failed to the host" )
Jon Hall05b2b432014-10-08 19:53:25 -040091 response = main.FALSE
92 return response
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -040093
kelvin-onlabd3b64892015-01-20 13:26:24 -080094 def onosPackage( self ):
kelvin8ec71442015-01-15 16:57:00 -080095 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -040096 Produce a self-contained tar.gz file that can be deployed
kelvin8ec71442015-01-15 16:57:00 -080097 and executed on any platform with Java 7 JRE.
98 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -040099 try:
kelvin8ec71442015-01-15 16:57:00 -0800100 self.handle.sendline( "onos-package" )
101 self.handle.expect( "onos-package" )
102 self.handle.expect( "tar.gz", timeout=30 )
103 handle = str( self.handle.before )
104 main.log.info( "onos-package command returned: " +
105 handle )
106 # As long as the sendline does not time out,
107 # return true. However, be careful to interpret
108 # the results of the onos-package command return
andrewonlab0748d2a2014-10-09 13:24:17 -0400109 return main.TRUE
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400110
andrewonlab7735d852014-10-09 13:02:47 -0400111 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800112 main.log.error( self.name + ": EOF exception found" )
113 main.log.error( self.name + ": " + self.handle.before )
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400114 except:
kelvin8ec71442015-01-15 16:57:00 -0800115 main.log.error( "Failed to package ONOS" )
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400116 main.cleanup()
117 main.exit()
118
kelvin-onlabd3b64892015-01-20 13:26:24 -0800119 def onosBuild( self ):
kelvin8ec71442015-01-15 16:57:00 -0800120 """
andrewonlab8790abb2014-11-06 13:51:54 -0500121 Use the pre defined script to build onos via mvn
kelvin8ec71442015-01-15 16:57:00 -0800122 """
andrewonlab8790abb2014-11-06 13:51:54 -0500123 try:
kelvin8ec71442015-01-15 16:57:00 -0800124 self.handle.sendline( "onos-build" )
125 self.handle.expect( "onos-build" )
126 i = self.handle.expect( [
kelvin-onlabd3b64892015-01-20 13:26:24 -0800127 "BUILD SUCCESS",
128 "ERROR",
129 "BUILD FAILED" ],
130 timeout=120 )
kelvin8ec71442015-01-15 16:57:00 -0800131 handle = str( self.handle.before )
andrewonlab8790abb2014-11-06 13:51:54 -0500132
kelvin8ec71442015-01-15 16:57:00 -0800133 main.log.info( "onos-build command returned: " +
134 handle )
andrewonlab8790abb2014-11-06 13:51:54 -0500135
136 if i == 0:
137 return main.TRUE
138 else:
139 return handle
140
141 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800142 main.log.error( self.name + ": EOF exception found" )
143 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8790abb2014-11-06 13:51:54 -0500144 except:
kelvin8ec71442015-01-15 16:57:00 -0800145 main.log.error( "Failed to build ONOS" )
andrewonlab8790abb2014-11-06 13:51:54 -0500146 main.cleanup()
147 main.exit()
148
kelvin-onlabd3b64892015-01-20 13:26:24 -0800149 def cleanInstall( self ):
kelvin8ec71442015-01-15 16:57:00 -0800150 """
151 Runs mvn clean install in the root of the ONOS directory.
152 This will clean all ONOS artifacts then compile each module
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400153
kelvin8ec71442015-01-15 16:57:00 -0800154 Returns: main.TRUE on success
Jon Hallde9d9aa2014-10-08 20:36:02 -0400155 On Failure, exits the test
kelvin8ec71442015-01-15 16:57:00 -0800156 """
Jon Hallde9d9aa2014-10-08 20:36:02 -0400157 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800158 main.log.info( "Running 'mvn clean install' on " +
159 str( self.name ) +
kelvin8ec71442015-01-15 16:57:00 -0800160 ". This may take some time." )
161 self.handle.sendline( "cd " + self.home )
162 self.handle.expect( "\$" )
Jon Hallea7818b2014-10-09 14:30:59 -0400163
kelvin8ec71442015-01-15 16:57:00 -0800164 self.handle.sendline( "" )
165 self.handle.expect( "\$" )
166 self.handle.sendline( "mvn clean install" )
167 self.handle.expect( "mvn clean install" )
168 while True:
169 i = self.handle.expect( [
Jon Hallde9d9aa2014-10-08 20:36:02 -0400170 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s\
171 Runtime\sEnvironment\sto\scontinue',
172 'BUILD\sFAILURE',
173 'BUILD\sSUCCESS',
174 'ONOS\$',
kelvin8ec71442015-01-15 16:57:00 -0800175 pexpect.TIMEOUT ], timeout=600 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400176 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800177 main.log.error( self.name + ":There is insufficient memory \
178 for the Java Runtime Environment to continue." )
179 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400180 main.cleanup()
181 main.exit()
182 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800183 main.log.error( self.name + ": Build failure!" )
184 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400185 main.cleanup()
186 main.exit()
187 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800188 main.log.info( self.name + ": Build success!" )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400189 elif i == 3:
kelvin8ec71442015-01-15 16:57:00 -0800190 main.log.info( self.name + ": Build complete" )
191 # Print the build time
Jon Hallf8ef52c2014-10-09 19:37:33 -0400192 for line in self.handle.before.splitlines():
193 if "Total time:" in line:
kelvin8ec71442015-01-15 16:57:00 -0800194 main.log.info( line )
195 self.handle.sendline( "" )
196 self.handle.expect( "\$", timeout=60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400197 return main.TRUE
198 elif i == 4:
kelvin8ec71442015-01-15 16:57:00 -0800199 main.log.error(
200 self.name +
201 ": mvn clean install TIMEOUT!" )
202 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400203 main.cleanup()
204 main.exit()
205 else:
kelvin8ec71442015-01-15 16:57:00 -0800206 main.log.error( self.name + ": unexpected response from \
207 mvn clean install" )
208 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400209 main.cleanup()
210 main.exit()
211 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800212 main.log.error( self.name + ": EOF exception found" )
213 main.log.error( self.name + ": " + self.handle.before )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400214 main.cleanup()
215 main.exit()
216 except:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800217 main.log.info( self.name + ":" * 60 )
kelvin-onlab64b33712015-01-21 15:26:15 -0800218 main.log.error( traceback.print_exc() )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800219 main.log.info( ":" * 60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400220 main.cleanup()
221 main.exit()
Jon Hallacabffd2014-10-09 12:36:53 -0400222
kelvin-onlabd3b64892015-01-20 13:26:24 -0800223 def gitPull( self, comp1="" ):
kelvin8ec71442015-01-15 16:57:00 -0800224 """
Jon Hallacabffd2014-10-09 12:36:53 -0400225 Assumes that "git pull" works without login
Jon Hall47a93fb2015-01-06 16:46:06 -0800226
Jon Hallacabffd2014-10-09 12:36:53 -0400227 This function will perform a git pull on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800228 If used as gitPull( "NODE" ) it will do git pull + NODE. This is
Jon Hallacabffd2014-10-09 12:36:53 -0400229 for the purpose of pulling from other nodes if necessary.
230
Jon Hall47a93fb2015-01-06 16:46:06 -0800231 Otherwise, this function will perform a git pull in the
Jon Hallacabffd2014-10-09 12:36:53 -0400232 ONOS repository. If it has any problems, it will return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -0800233 If it successfully does a gitPull, it will return a 1 ( main.TRUE )
Shreya Shahee15f6c2014-10-28 18:12:30 -0400234 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400235
kelvin8ec71442015-01-15 16:57:00 -0800236 """
Jon Hallacabffd2014-10-09 12:36:53 -0400237 try:
kelvin8ec71442015-01-15 16:57:00 -0800238 # main.log.info( self.name + ": Stopping ONOS" )
239 # self.stop()
240 self.handle.sendline( "cd " + self.home )
241 self.handle.expect( "ONOS\$" )
242 if comp1 == "":
243 self.handle.sendline( "git pull" )
Jon Hallacabffd2014-10-09 12:36:53 -0400244 else:
kelvin8ec71442015-01-15 16:57:00 -0800245 self.handle.sendline( "git pull " + comp1 )
Jon Hall47a93fb2015-01-06 16:46:06 -0800246
kelvin-onlabd3b64892015-01-20 13:26:24 -0800247 i = self.handle.expect(
248 [
249 'fatal',
250 'Username\sfor\s(.*):\s',
251 '\sfile(s*) changed,\s',
252 'Already up-to-date',
253 'Aborting',
254 'You\sare\snot\scurrently\son\sa\sbranch',
255 'You\sasked\sme\sto\spull\swithout\stelling\sme\swhich\
256 \sbranch\syou',
257 'Pull\sis\snot\spossible\sbecause\syou\shave\sunmerged\
258 \sfiles',
259 pexpect.TIMEOUT ],
260 timeout=300 )
kelvin8ec71442015-01-15 16:57:00 -0800261 # debug
kelvin-onlabd3b64892015-01-20 13:26:24 -0800262 # main.log.report( self.name +": DEBUG: \n"+
263 # "git pull response: " +
264 # str( self.handle.before ) + str( self.handle.after ) )
kelvin8ec71442015-01-15 16:57:00 -0800265 if i == 0:
266 main.log.error( self.name + ": Git pull had some issue..." )
Jon Hallacabffd2014-10-09 12:36:53 -0400267 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800268 elif i == 1:
269 main.log.error(
270 self.name +
271 ": Git Pull Asking for username. " )
Jon Hallacabffd2014-10-09 12:36:53 -0400272 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800273 elif i == 2:
274 main.log.info(
275 self.name +
276 ": Git Pull - pulling repository now" )
277 self.handle.expect( "ONOS\$", 120 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800278 # So that only when git pull is done, we do mvn clean compile
279 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800280 elif i == 3:
281 main.log.info( self.name + ": Git Pull - Already up to date" )
Jon Hall47a93fb2015-01-06 16:46:06 -0800282 return i
kelvin8ec71442015-01-15 16:57:00 -0800283 elif i == 4:
284 main.log.info(
285 self.name +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800286 ": Git Pull - Aborting...\
287 Are there conflicting git files?" )
Jon Hallacabffd2014-10-09 12:36:53 -0400288 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800289 elif i == 5:
290 main.log.info(
291 self.name +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800292 ": Git Pull - You are not currently\
293 on a branch so git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400294 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800295 elif i == 6:
296 main.log.info(
297 self.name +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800298 ": Git Pull - You have not configured\
299 an upstream branch to pull from\
300 . Git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400301 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800302 elif i == 7:
303 main.log.info(
304 self.name +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800305 ": Git Pull - Pull is not possible\
306 because you have unmerged files." )
Jon Hallacabffd2014-10-09 12:36:53 -0400307 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800308 elif i == 8:
309 main.log.error( self.name + ": Git Pull - TIMEOUT" )
310 main.log.error(
311 self.name + " Response was: " + str(
312 self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400313 return main.ERROR
314 else:
kelvin8ec71442015-01-15 16:57:00 -0800315 main.log.error(
316 self.name +
317 ": Git Pull - Unexpected response, check for pull errors" )
Jon Hallacabffd2014-10-09 12:36:53 -0400318 return main.ERROR
319 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800320 main.log.error( self.name + ": EOF exception found" )
321 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400322 main.cleanup()
323 main.exit()
324 except:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800325 main.log.info( self.name + ":" * 60 )
kelvin-onlab64b33712015-01-21 15:26:15 -0800326 main.log.error( traceback.print_exc() )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800327 main.log.info( ":" * 80 )
Jon Hallacabffd2014-10-09 12:36:53 -0400328 main.cleanup()
329 main.exit()
330
kelvin-onlabd3b64892015-01-20 13:26:24 -0800331 def gitCheckout( self, branch="master" ):
kelvin8ec71442015-01-15 16:57:00 -0800332 """
Jon Hallacabffd2014-10-09 12:36:53 -0400333 Assumes that "git pull" works without login
kelvin8ec71442015-01-15 16:57:00 -0800334
Jon Hallacabffd2014-10-09 12:36:53 -0400335 This function will perform a git git checkout on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800336 If used as gitCheckout( "branch" ) it will do git checkout
337 of the "branch".
Jon Hallacabffd2014-10-09 12:36:53 -0400338
339 Otherwise, this function will perform a git checkout of the master
kelvin8ec71442015-01-15 16:57:00 -0800340 branch of the ONOS repository. If it has any problems, it will return
341 main.ERROR.
342 If the branch was already the specified branch, or the git checkout was
Jon Hallacabffd2014-10-09 12:36:53 -0400343 successful then the function will return main.TRUE.
344
kelvin8ec71442015-01-15 16:57:00 -0800345 """
Jon Hallacabffd2014-10-09 12:36:53 -0400346 try:
kelvin8ec71442015-01-15 16:57:00 -0800347 self.handle.sendline( "cd " + self.home )
348 self.handle.expect( "ONOS\$" )
349 main.log.info(
350 self.name +
351 ": Checking out git branch: " +
352 branch +
353 "..." )
354 cmd = "git checkout " + branch
355 self.handle.sendline( cmd )
356 self.handle.expect( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800357 i = self.handle.expect(
358 [
359 'fatal',
360 'Username\sfor\s(.*):\s',
361 'Already\son\s\'',
362 'Switched\sto\sbranch\s\'' +
363 str( branch ),
364 pexpect.TIMEOUT,
365 'error: Your local changes to the following files\
366 would be overwritten by checkout:',
367 'error: you need to resolve your current index first' ],
368 timeout=60 )
Jon Hallacabffd2014-10-09 12:36:53 -0400369
kelvin8ec71442015-01-15 16:57:00 -0800370 if i == 0:
371 main.log.error(
372 self.name +
373 ": Git checkout had some issue..." )
374 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400375 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800376 elif i == 1:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800377 main.log.error(
378 self.name +
379 ": Git checkout asking for username." +
380 " Please configure your local git repository to be able " +
381 "to access your remote repository passwordlessly" )
Jon Hallacabffd2014-10-09 12:36:53 -0400382 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800383 elif i == 2:
384 main.log.info(
385 self.name +
386 ": Git Checkout %s : Already on this branch" %
387 branch )
388 self.handle.expect( "ONOS\$" )
389 # main.log.info( "DEBUG: after checkout cmd = "+
390 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400391 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800392 elif i == 3:
393 main.log.info(
394 self.name +
395 ": Git checkout %s - Switched to this branch" %
396 branch )
397 self.handle.expect( "ONOS\$" )
398 # main.log.info( "DEBUG: after checkout cmd = "+
399 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400400 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800401 elif i == 4:
402 main.log.error( self.name + ": Git Checkout- TIMEOUT" )
403 main.log.error(
404 self.name + " Response was: " + str(
405 self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400406 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800407 elif i == 5:
408 self.handle.expect( "Aborting" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800409 main.log.error(
410 self.name +
411 ": Git checkout error: \n" +
412 "Your local changes to the following\
413 files would be overwritten by checkout:" +
414 str(
415 self.handle.before ) )
kelvin8ec71442015-01-15 16:57:00 -0800416 self.handle.expect( "ONOS\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500417 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800418 elif i == 6:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800419 main.log.error( self.name +
420 ": Git checkout error: \n" +
421 "You need to resolve your\
422 current index first:" +
kelvin8ec71442015-01-15 16:57:00 -0800423 str( self.handle.before ) )
424 self.handle.expect( "ONOS\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500425 return main.ERROR
Jon Hallacabffd2014-10-09 12:36:53 -0400426 else:
kelvin8ec71442015-01-15 16:57:00 -0800427 main.log.error(
428 self.name +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800429 ": Git Checkout - Unexpected response,\
430 check for pull errors" )
kelvin8ec71442015-01-15 16:57:00 -0800431 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400432 return main.ERROR
433
434 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800435 main.log.error( self.name + ": EOF exception found" )
436 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400437 main.cleanup()
438 main.exit()
439 except:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800440 main.log.info( self.name + ":" * 60 )
kelvin-onlab64b33712015-01-21 15:26:15 -0800441 main.log.error( traceback.print_exc() )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800442 main.log.info( ":" * 80 )
Jon Hallacabffd2014-10-09 12:36:53 -0400443 main.cleanup()
444 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400445
kelvin-onlabd3b64892015-01-20 13:26:24 -0800446 def getVersion( self, report=False ):
kelvin8ec71442015-01-15 16:57:00 -0800447 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800448 Writes the COMMIT number to the report to be parsed\
449 by Jenkins data collecter.
kelvin8ec71442015-01-15 16:57:00 -0800450 """
Jon Hall45ec0922014-10-10 19:33:49 -0400451 try:
kelvin8ec71442015-01-15 16:57:00 -0800452 self.handle.sendline( "export TERM=xterm-256color" )
453 self.handle.expect( "xterm-256color" )
454 self.handle.expect( "\$" )
455 self.handle.sendline( "" )
456 self.handle.expect( "\$" )
457 self.handle.sendline(
458 "cd " +
459 self.home +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800460 "; git log -1 --pretty=fuller --decorate=short | grep -A 6\
461 \"commit\" --color=never" )
kelvin8ec71442015-01-15 16:57:00 -0800462 # NOTE: for some reason there are backspaces inserted in this
463 # phrase when run from Jenkins on some tests
464 self.handle.expect( "never" )
465 self.handle.expect( "\$" )
466 response = ( self.name + ": \n" + str(
467 self.handle.before + self.handle.after ) )
468 self.handle.sendline( "cd " + self.home )
469 self.handle.expect( "\$" )
470 lines = response.splitlines()
Jon Hall45ec0922014-10-10 19:33:49 -0400471 for line in lines:
Jon Hallfd191202014-11-07 18:36:09 -0500472 print line
473 if report:
kelvin8ec71442015-01-15 16:57:00 -0800474 for line in lines[ 2:-1 ]:
475 # Bracket replacement is for Wiki-compliant
476 # formatting. '<' or '>' are interpreted
477 # as xml specific tags that cause errors
478 line = line.replace( "<", "[" )
479 line = line.replace( ">", "]" )
480 main.log.report( "\t" + line )
481 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400482 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800483 main.log.error( self.name + ": EOF exception found" )
484 main.log.error( self.name + ": " + self.handle.before )
Jon Hall45ec0922014-10-10 19:33:49 -0400485 main.cleanup()
486 main.exit()
Jon Hall368769f2014-11-19 15:43:35 -0800487 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800488 main.log.error( self.name + ": TIMEOUT exception found" )
489 main.log.error( self.name + ": " + self.handle.before )
Jon Hall368769f2014-11-19 15:43:35 -0800490 main.cleanup()
491 main.exit()
Jon Hall45ec0922014-10-10 19:33:49 -0400492 except:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800493 main.log.info( self.name + ":" * 60 )
kelvin-onlab64b33712015-01-21 15:26:15 -0800494 main.log.error( traceback.print_exc() )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800495 main.log.info( ":" * 80 )
Jon Hall45ec0922014-10-10 19:33:49 -0400496 main.cleanup()
497 main.exit()
498
kelvin-onlabd3b64892015-01-20 13:26:24 -0800499 def createCellFile( self, benchIp, fileName, mnIpAddrs,
500 extraFeatureString, *onosIpAddrs ):
kelvin8ec71442015-01-15 16:57:00 -0800501 """
andrewonlab94282092014-10-10 13:00:11 -0400502 Creates a cell file based on arguments
503 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800504 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400505 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800506 * File name of the cell file ( fileName )
507 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800508 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400509 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800510 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400511 - Must be passed in as last arguments
kelvin8ec71442015-01-15 16:57:00 -0800512
andrewonlab94282092014-10-10 13:00:11 -0400513 NOTE: Assumes cells are located at:
514 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800515 """
516 # Variable initialization
kelvin-onlabd3b64892015-01-20 13:26:24 -0800517 cellDirectory = self.home + "/tools/test/cells/"
kelvin8ec71442015-01-15 16:57:00 -0800518 # We want to create the cell file in the dependencies directory
519 # of TestON first, then copy over to ONOS bench
kelvin-onlabd3b64892015-01-20 13:26:24 -0800520 tempDirectory = "/tmp/"
kelvin8ec71442015-01-15 16:57:00 -0800521 # Create the cell file in the directory for writing ( w+ )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800522 cellFile = open( tempDirectory + fileName, 'w+' )
kelvin8ec71442015-01-15 16:57:00 -0800523
524 # Feature string is hardcoded environment variables
525 # That you may wish to use by default on startup.
526 # Note that you may not want certain features listed
527 # on here.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800528 coreFeatureString = "export ONOS_FEATURES=webconsole,onos-api," +\
529 "onos-cli,onos-openflow," + extraFeatureString
530 mnString = "export OCN="
531 onosString = "export OC"
532 tempCount = 1
kelvin8ec71442015-01-15 16:57:00 -0800533
kelvin-onlabd3b64892015-01-20 13:26:24 -0800534 # Create ONOSNIC ip address prefix
535 tempOnosIp = onosIpAddrs[ 0 ]
536 tempList = []
537 tempList = tempOnosIp.split( "." )
kelvin8ec71442015-01-15 16:57:00 -0800538 # Omit last element of list to format for NIC
kelvin-onlabd3b64892015-01-20 13:26:24 -0800539 tempList = tempList[ :-1 ]
kelvin8ec71442015-01-15 16:57:00 -0800540 # Structure the nic string ip
kelvin-onlabd3b64892015-01-20 13:26:24 -0800541 nicAddr = ".".join( tempList ) + ".*"
542 onosNicString = "export ONOS_NIC=" + nicAddr
andrewonlab94282092014-10-10 13:00:11 -0400543
544 try:
kelvin8ec71442015-01-15 16:57:00 -0800545 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800546 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400547
kelvin-onlabd3b64892015-01-20 13:26:24 -0800548 for arg in onosIpAddrs:
549 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800550 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400551 # export OC1="10.128.20.11"
552 # export OC2="10.128.20.12"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800553 cellFile.write( onosString + str( tempCount ) +
554 "=" + "\"" + arg + "\"" + "\n" )
555 tempCount = tempCount + 1
kelvin8ec71442015-01-15 16:57:00 -0800556
kelvin-onlabd3b64892015-01-20 13:26:24 -0800557 cellFile.write( mnString + "\"" + mnIpAddrs + "\"" + "\n" )
558 cellFile.write( coreFeatureString + "\n" )
559 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400560
kelvin8ec71442015-01-15 16:57:00 -0800561 # We use os.system to send the command to TestON cluster
562 # to account for the case in which TestON is not located
563 # on the same cluster as the ONOS bench
564 # Note that even if TestON is located on the same cluster
565 # as ONOS bench, you must setup passwordless ssh
566 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800567 os.system( "scp " + tempDirectory + fileName +
568 " admin@" + benchIp + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400569
andrewonlab2a6c9342014-10-16 13:40:15 -0400570 return main.TRUE
571
andrewonlab94282092014-10-10 13:00:11 -0400572 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800573 main.log.error( self.name + ": EOF exception found" )
574 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -0400575 main.cleanup()
576 main.exit()
577 except:
kelvin8ec71442015-01-15 16:57:00 -0800578 main.log.info( self.name + ":::::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -0800579 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -0800580 main.log.info( ":::::::" )
andrewonlab94282092014-10-10 13:00:11 -0400581 main.cleanup()
582 main.exit()
583
kelvin-onlabd3b64892015-01-20 13:26:24 -0800584 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800585 """
andrewonlab95ca1462014-10-09 14:04:24 -0400586 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800587 """
andrewonlab95ca1462014-10-09 14:04:24 -0400588 try:
589 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800590 main.log.error( "Must define cellname" )
andrewonlab95ca1462014-10-09 14:04:24 -0400591 main.cleanup()
592 main.exit()
593 else:
kelvin8ec71442015-01-15 16:57:00 -0800594 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800595 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800596 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400597 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800598 self.handle.expect(str(cellname))
599 handle_before = self.handle.before
600 handle_after = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800601 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800602 self.handle.sendline("")
603 self.handle.expect("\$")
604 handle_more = self.handle.before
andrewonlab95ca1462014-10-09 14:04:24 -0400605
kelvin-onlabd3b64892015-01-20 13:26:24 -0800606 main.log.info( "Cell call returned: " + handleBefore +
607 handleAfter + handleMore )
andrewonlab95ca1462014-10-09 14:04:24 -0400608
609 return main.TRUE
610
611 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800612 main.log.error( self.name + ": EOF exception found" )
613 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ca1462014-10-09 14:04:24 -0400614 main.cleanup()
615 main.exit()
616 except:
kelvin8ec71442015-01-15 16:57:00 -0800617 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -0800618 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -0800619 main.log.info( self.name + " ::::::" )
andrewonlab95ca1462014-10-09 14:04:24 -0400620 main.cleanup()
621 main.exit()
622
kelvin-onlabd3b64892015-01-20 13:26:24 -0800623 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800624 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400625 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800626 """
627 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400628
andrewonlabc03bf6c2014-10-09 14:56:18 -0400629 try:
kelvin8ec71442015-01-15 16:57:00 -0800630 # Clean handle by sending empty and expecting $
631 self.handle.sendline( "" )
632 self.handle.expect( "\$" )
633 self.handle.sendline( "onos-verify-cell" )
634 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800635 handleBefore = self.handle.before
636 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800637 # Get the rest of the handle
638 self.handle.sendline( "" )
639 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800640 handleMore = self.handle.before
andrewonlabc03bf6c2014-10-09 14:56:18 -0400641
kelvin-onlabd3b64892015-01-20 13:26:24 -0800642 main.log.info( "Verify cell returned: " + handleBefore +
643 handleAfter + handleMore )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400644
645 return main.TRUE
Jon Hall7993bfc2014-10-09 16:30:14 -0400646 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800647 main.log.error( self.name + ": EOF exception found" )
648 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400649 main.cleanup()
650 main.exit()
651 except:
kelvin8ec71442015-01-15 16:57:00 -0800652 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -0800653 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -0800654 main.log.info( self.name + " ::::::" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400655 main.cleanup()
656 main.exit()
657
kelvin-onlabd3b64892015-01-20 13:26:24 -0800658 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800659 """
andrewonlab05e362f2014-10-10 00:40:57 -0400660 Uses 'onos' command to send various ONOS CLI arguments.
661 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800662 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400663 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800664
665 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400666 CLI commands for ONOS. Try to use this function first
667 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800668 function.
669 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400670 by starting onos, and typing in 'onos' to enter the
671 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800672 available commands.
673 """
andrewonlab05e362f2014-10-10 00:40:57 -0400674 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800675 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800676 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400677 return main.FALSE
678 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800679 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400680 return main.FALSE
681
kelvin8ec71442015-01-15 16:57:00 -0800682 cmdstr = str( cmdstr )
683 self.handle.sendline( "" )
684 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400685
kelvin-onlabd3b64892015-01-20 13:26:24 -0800686 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800687 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400688
kelvin-onlabd3b64892015-01-20 13:26:24 -0800689 handleBefore = self.handle.before
Shreya Shaha73aaad2014-10-27 18:03:09 -0400690 print "handle_before = ", self.handle.before
kelvin-onlabd3b64892015-01-20 13:26:24 -0800691 # handleAfter = str( self.handle.after )
Jon Hall47a93fb2015-01-06 16:46:06 -0800692
kelvin8ec71442015-01-15 16:57:00 -0800693 # self.handle.sendline( "" )
694 # self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800695 # handleMore = str( self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400696
kelvin8ec71442015-01-15 16:57:00 -0800697 main.log.info( "Command sent successfully" )
andrewonlab05e362f2014-10-10 00:40:57 -0400698
kelvin8ec71442015-01-15 16:57:00 -0800699 # Obtain return handle that consists of result from
700 # the onos command. The string may need to be
701 # configured further.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800702 # returnString = handleBefore + handleAfter
703 returnString = handleBefore
704 print "return_string = ", returnString
705 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400706
707 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800708 main.log.error( self.name + ": EOF exception found" )
709 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400710 main.cleanup()
711 main.exit()
712 except:
kelvin8ec71442015-01-15 16:57:00 -0800713 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -0800714 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -0800715 main.log.info( self.name + " ::::::" )
andrewonlab05e362f2014-10-10 00:40:57 -0400716 main.cleanup()
717 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400718
kelvin-onlabd3b64892015-01-20 13:26:24 -0800719 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800720 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400721 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800722 If -f option is provided, it also forces an uninstall.
723 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400724 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800725 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400726 files to certain onos nodes
727
728 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800729 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400730 try:
andrewonlab114768a2014-11-14 12:44:44 -0500731 if options:
kelvin8ec71442015-01-15 16:57:00 -0800732 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500733 else:
kelvin8ec71442015-01-15 16:57:00 -0800734 self.handle.sendline( "onos-install " + node )
735 self.handle.expect( "onos-install " )
736 # NOTE: this timeout may need to change depending on the network
737 # and size of ONOS
738 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800739 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800740 "ONOS\sis\salready\sinstalled",
741 pexpect.TIMEOUT ], timeout=60 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400742
Jon Hall7993bfc2014-10-09 16:30:14 -0400743 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800744 main.log.warn( "Network is unreachable" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400745 return main.FALSE
746 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800747 main.log.info(
748 "ONOS was installed on " +
749 node +
750 " and started" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400751 return main.TRUE
andrewonlabd9a73a72014-11-14 17:28:21 -0500752 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800753 main.log.info( "ONOS is already installed on " + node )
andrewonlabd9a73a72014-11-14 17:28:21 -0500754 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800755 elif i == 3:
756 main.log.info(
757 "Installation of ONOS on " +
758 node +
759 " timed out" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400760 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400761
762 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800763 main.log.error( self.name + ": EOF exception found" )
764 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400765 main.cleanup()
766 main.exit()
767 except:
kelvin8ec71442015-01-15 16:57:00 -0800768 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -0800769 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -0800770 main.log.info( self.name + " ::::::" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400771 main.cleanup()
772 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400773
kelvin-onlabd3b64892015-01-20 13:26:24 -0800774 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800775 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400776 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400777 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800778 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400779 try:
kelvin8ec71442015-01-15 16:57:00 -0800780 self.handle.sendline( "" )
781 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800782 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800783 " start" )
784 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -0400785 "Job\sis\salready\srunning",
786 "start/running",
787 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800788 pexpect.TIMEOUT ], timeout=120 )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400789
790 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800791 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400792 return main.TRUE
793 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800794 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400795 return main.TRUE
796 else:
kelvin8ec71442015-01-15 16:57:00 -0800797 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400798 main.cleanup()
799 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -0400800 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800801 main.log.error( self.name + ": EOF exception found" )
802 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400803 main.cleanup()
804 main.exit()
805 except:
kelvin8ec71442015-01-15 16:57:00 -0800806 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -0800807 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -0800808 main.log.info( self.name + " ::::::" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400809 main.cleanup()
810 main.exit()
811
kelvin-onlabd3b64892015-01-20 13:26:24 -0800812 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800813 """
andrewonlab2b30bd32014-10-09 16:48:55 -0400814 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400815 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800816 """
andrewonlab2b30bd32014-10-09 16:48:55 -0400817 try:
kelvin8ec71442015-01-15 16:57:00 -0800818 self.handle.sendline( "" )
819 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800820 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800821 " stop" )
822 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -0400823 "stop/waiting",
824 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800825 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2b30bd32014-10-09 16:48:55 -0400826
827 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800828 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400829 return main.TRUE
830 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800831 main.log.info( "Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800832 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -0400833 return main.FALSE
834 else:
kelvin8ec71442015-01-15 16:57:00 -0800835 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400836 return main.FALSE
837
838 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800839 main.log.error( self.name + ": EOF exception found" )
840 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -0400841 main.cleanup()
842 main.exit()
843 except:
kelvin8ec71442015-01-15 16:57:00 -0800844 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -0800845 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -0800846 main.log.info( self.name + " ::::::" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400847 main.cleanup()
848 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800849
kelvin-onlabd3b64892015-01-20 13:26:24 -0800850 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -0800851 """
andrewonlabc8d47972014-10-09 16:52:36 -0400852 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -0800853 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -0400854 if needed
kelvin8ec71442015-01-15 16:57:00 -0800855 """
andrewonlabc8d47972014-10-09 16:52:36 -0400856 try:
kelvin8ec71442015-01-15 16:57:00 -0800857 self.handle.sendline( "" )
858 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800859 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800860 self.handle.expect( "\$" )
andrewonlabc8d47972014-10-09 16:52:36 -0400861
kelvin-onlabd3b64892015-01-20 13:26:24 -0800862 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
andrewonlab9dfd2082014-11-13 17:44:03 -0500863
kelvin8ec71442015-01-15 16:57:00 -0800864 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -0400865 return main.TRUE
866
867 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800868 main.log.error( self.name + ": EOF exception found" )
869 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -0400870 main.cleanup()
871 main.exit()
872 except:
kelvin8ec71442015-01-15 16:57:00 -0800873 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -0800874 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -0800875 main.log.info( self.name + " ::::::" )
andrewonlabc8d47972014-10-09 16:52:36 -0400876 main.cleanup()
877 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -0400878
kelvin-onlabd3b64892015-01-20 13:26:24 -0800879 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800880 """
andrewonlabaedc8332014-12-04 12:43:03 -0500881 Issues the command 'onos-die <node-ip>'
882 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -0800883 """
andrewonlabaedc8332014-12-04 12:43:03 -0500884 try:
kelvin8ec71442015-01-15 16:57:00 -0800885 self.handle.sendline( "" )
886 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800887 cmdStr = "onos-kill " + str( nodeIp )
888 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -0800889 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -0500890 "Killing\sONOS",
891 "ONOS\sprocess\sis\snot\srunning",
kelvin8ec71442015-01-15 16:57:00 -0800892 pexpect.TIMEOUT ], timeout=20 )
andrewonlabaedc8332014-12-04 12:43:03 -0500893 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800894 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800895 " was killed and stopped" )
andrewonlabaedc8332014-12-04 12:43:03 -0500896 return main.TRUE
897 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800898 main.log.info( "ONOS process was not running" )
andrewonlabaedc8332014-12-04 12:43:03 -0500899 return main.FALSE
900 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800901 main.log.error( self.name + ": EOF exception found" )
902 main.log.error( self.name + ": " + self.handle.before )
andrewonlabaedc8332014-12-04 12:43:03 -0500903 main.cleanup()
904 main.exit()
905 except:
kelvin8ec71442015-01-15 16:57:00 -0800906 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -0800907 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -0800908 main.log.info( self.name + " ::::::" )
andrewonlabaedc8332014-12-04 12:43:03 -0500909 main.cleanup()
910 main.exit()
911
kelvin-onlabd3b64892015-01-20 13:26:24 -0800912 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800913 """
andrewonlabe8e56fd2014-10-09 17:12:44 -0400914 Calls the command: 'onos-kill [<node-ip>]'
915 "Remotely, and unceremoniously kills the ONOS instance running on
916 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -0800917 """
andrewonlabe8e56fd2014-10-09 17:12:44 -0400918 try:
kelvin8ec71442015-01-15 16:57:00 -0800919 self.handle.sendline( "" )
920 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800921 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800922 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -0400923 "\$",
924 "No\sroute\sto\shost",
925 "password:",
kelvin8ec71442015-01-15 16:57:00 -0800926 pexpect.TIMEOUT ], timeout=20 )
927
andrewonlabe8e56fd2014-10-09 17:12:44 -0400928 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800929 main.log.info(
930 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800931 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400932 return main.TRUE
933 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800934 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400935 return main.FALSE
936 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800937 main.log.info(
938 "Passwordless login for host: " +
939 str( nodeIp ) +
940 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400941 return main.FALSE
942 else:
kelvin8ec71442015-01-15 16:57:00 -0800943 main.log.info( "ONOS instasnce was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400944 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -0800945
andrewonlabe8e56fd2014-10-09 17:12:44 -0400946 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800947 main.log.error( self.name + ": EOF exception found" )
948 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400949 main.cleanup()
950 main.exit()
951 except:
kelvin8ec71442015-01-15 16:57:00 -0800952 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -0800953 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -0800954 main.log.info( self.name + " ::::::" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400955 main.cleanup()
956 main.exit()
957
kelvin-onlabd3b64892015-01-20 13:26:24 -0800958 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -0800959 """
andrewonlab19fbdca2014-11-14 12:55:59 -0500960 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -0500961 a cleaner environment.
962
andrewonlab19fbdca2014-11-14 12:55:59 -0500963 Description:
Jon Hallfcc88622014-11-25 13:09:54 -0500964 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -0500965 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -0800966 """
andrewonlab19fbdca2014-11-14 12:55:59 -0500967 try:
kelvin8ec71442015-01-15 16:57:00 -0800968 self.handle.sendline( "" )
969 self.handle.expect( "\$" )
970 self.handle.sendline( "onos-remove-raft-logs" )
971 # Sometimes this command hangs
972 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
973 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -0500974 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800975 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
976 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -0500977 if i == 1:
978 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -0800979 self.handle.sendline( "" )
980 self.handle.expect( "\$" )
andrewonlab19fbdca2014-11-14 12:55:59 -0500981 return main.TRUE
982
983 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800984 main.log.error( self.name + ": EOF exception found" )
985 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -0500986 main.cleanup()
987 main.exit()
988 except:
kelvin8ec71442015-01-15 16:57:00 -0800989 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -0800990 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -0800991 main.log.info( self.name + " ::::::" )
andrewonlab19fbdca2014-11-14 12:55:59 -0500992 main.cleanup()
993 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -0500994
kelvin-onlabd3b64892015-01-20 13:26:24 -0800995 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -0800996 """
997 Calls the command 'onos-start-network [ <mininet-topo> ]
998 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -0400999 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001000 cell."
andrewonlab94282092014-10-10 13:00:11 -04001001 * Specify mininet topology file name for mntopo
1002 * Topo files should be placed at:
1003 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001004
andrewonlab94282092014-10-10 13:00:11 -04001005 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001006 """
andrewonlab94282092014-10-10 13:00:11 -04001007 try:
1008 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001009 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001010 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001011
kelvin8ec71442015-01-15 16:57:00 -08001012 mntopo = str( mntopo )
1013 self.handle.sendline( "" )
1014 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -04001015
kelvin8ec71442015-01-15 16:57:00 -08001016 self.handle.sendline( "onos-start-network " + mntopo )
1017 self.handle.expect( "mininet>" )
1018 main.log.info( "Network started, entered mininet prompt" )
1019
1020 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001021
1022 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001023 main.log.error( self.name + ": EOF exception found" )
1024 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -04001025 main.cleanup()
1026 main.exit()
1027 except:
kelvin8ec71442015-01-15 16:57:00 -08001028 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -08001029 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -08001030 main.log.info( self.name + " ::::::" )
andrewonlab94282092014-10-10 13:00:11 -04001031 main.cleanup()
1032 main.exit()
1033
Cameron Franke9c94fb02015-01-21 10:20:20 -08001034 def isup(self, node = "", timeout = 120):
kelvin8ec71442015-01-15 16:57:00 -08001035 """
1036 Run's onos-wait-for-start which only returns once ONOS is at run
Cameron Franke9c94fb02015-01-21 10:20:20 -08001037 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001038
Jon Hall7993bfc2014-10-09 16:30:14 -04001039 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001040 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001041 try:
Cameron Franke9c94fb02015-01-21 10:20:20 -08001042 self.handle.sendline("onos-wait-for-start " + node )
1043 self.handle.expect("onos-wait-for-start")
kelvin8ec71442015-01-15 16:57:00 -08001044 # NOTE: this timeout is arbitrary"
Cameron Franke9c94fb02015-01-21 10:20:20 -08001045 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001046 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001047 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001048 return main.TRUE
1049 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001050 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001051 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001052 main.log.error( "ONOS has not started yet" )
1053 self.handle.send( "\x03" ) # Control-C
1054 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001055 return main.FALSE
1056 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001057 main.log.error( self.name + ": EOF exception found" )
1058 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -04001059 main.cleanup()
1060 main.exit()
1061 except:
kelvin8ec71442015-01-15 16:57:00 -08001062 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -08001063 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -08001064 main.log.info( self.name + " ::::::" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001065 main.cleanup()
1066 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001067
kelvin-onlabd3b64892015-01-20 13:26:24 -08001068 def pushTestIntentsShell(
1069 self,
1070 dpidSrc,
1071 dpidDst,
1072 numIntents,
1073 dirFile,
1074 onosIp,
1075 numMult="",
1076 appId="",
1077 report=True,
1078 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001079 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001080 Description:
kelvin8ec71442015-01-15 16:57:00 -08001081 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001082 better parallelize the results than the CLI
1083 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001084 * dpidSrc: specify source dpid
1085 * dpidDst: specify destination dpid
1086 * numIntents: specify number of intents to push
1087 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001088 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001089 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001090 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001091 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001092 """
1093 try:
1094 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001095 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001097 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001098 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001099 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001100
kelvin-onlabd3b64892015-01-20 13:26:24 -08001101 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1102 if not numMult:
1103 addIntents = addDpid + " " + str( numIntents )
1104 elif numMult:
1105 addIntents = addDpid + " " + str( numIntents ) + " " +\
1106 str( numMult )
1107 if appId:
1108 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001109 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001110 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001111
andrewonlabaedc8332014-12-04 12:43:03 -05001112 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001113 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001114 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001115 sendCmd = addApp + " &"
1116 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001117
kelvin-onlabd3b64892015-01-20 13:26:24 -08001118 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001119
1120 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001121 main.log.error( self.name + ": EOF exception found" )
1122 main.log.error( self.name + ": " + self.handle.before )
andrewonlabb66dfa12014-12-02 15:51:10 -05001123 main.cleanup()
1124 main.exit()
1125 except:
kelvin8ec71442015-01-15 16:57:00 -08001126 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -08001127 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -08001128 main.log.info( self.name + " ::::::" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001129 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001130 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001131
kelvin-onlabd3b64892015-01-20 13:26:24 -08001132 def getTopology( self, topologyOutput ):
kelvin8ec71442015-01-15 16:57:00 -08001133 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001134 parses the onos:topology output
kelvin8ec71442015-01-15 16:57:00 -08001135 Returns: a topology dict populated by the key values found in
Jon Hall77f53ce2014-10-13 18:02:06 -04001136 the cli command.
kelvin8ec71442015-01-15 16:57:00 -08001137 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001138 try:
kelvin8ec71442015-01-15 16:57:00 -08001139 # call the cli to get the topology summary
1140 # cmdstr = "onos:topology"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001141 # cliResult = self.onosCli( ip, cmdstr )
1142 # print "cli_result = ", cliResult
Jon Hall77f53ce2014-10-13 18:02:06 -04001143
kelvin8ec71442015-01-15 16:57:00 -08001144 # Parse the output
Jon Hall77f53ce2014-10-13 18:02:06 -04001145 topology = {}
kelvin-onlabd3b64892015-01-20 13:26:24 -08001146 # for line in cliResult.split( "\n" ):
1147 for line in topologyOutput.splitlines():
kelvin8ec71442015-01-15 16:57:00 -08001148 if not line.startswith( "time=" ):
Jon Hall77f53ce2014-10-13 18:02:06 -04001149 continue
kelvin8ec71442015-01-15 16:57:00 -08001150 # else
1151 # print line
1152 for var in line.split( "," ):
1153 # print "'"+var+"'"
1154 # print "'"+var.strip()+"'"
1155 key, value = var.strip().split( "=" )
1156 topology[ key ] = value
1157 # print "topology = ", topology
1158 # devices = topology.get( 'devices', False )
1159 # print "devices = ", devices
1160 # links = topology.get( 'links', False )
1161 # print "links = ", links
1162 # SCCs = topology.get( 'SCC(s)', False )
1163 # print "SCCs = ", SCCs
1164 # paths = topology.get( 'paths', False )
1165 # print "paths = ", paths
Jon Hall77f53ce2014-10-13 18:02:06 -04001166
1167 return topology
1168 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001169 main.log.error( self.name + ": EOF exception found" )
1170 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001171 main.cleanup()
1172 main.exit()
1173 except:
kelvin8ec71442015-01-15 16:57:00 -08001174 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -08001175 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -08001176 main.log.info( self.name + " ::::::" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001177 main.cleanup()
1178 main.exit()
1179
kelvin-onlabd3b64892015-01-20 13:26:24 -08001180 def checkStatus(
1181 self,
1182 topologyResult,
1183 numoswitch,
1184 numolink,
1185 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001186 """
1187 Checks the number of swithes & links that ONOS sees against the
1188 supplied values. By default this will report to main.log, but the
Jon Hall77f53ce2014-10-13 18:02:06 -04001189 log level can be specifid.
kelvin8ec71442015-01-15 16:57:00 -08001190
Jon Hall77f53ce2014-10-13 18:02:06 -04001191 Params: ip = ip used for the onos cli
1192 numoswitch = expected number of switches
1193 numlink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001194 logLevel = level to log to.
1195 Currently accepts 'info', 'warn' and 'report'
Jon Hall77f53ce2014-10-13 18:02:06 -04001196
1197
kelvin-onlabd3b64892015-01-20 13:26:24 -08001198 logLevel can
Jon Hall77f53ce2014-10-13 18:02:06 -04001199
kelvin8ec71442015-01-15 16:57:00 -08001200 Returns: main.TRUE if the number of switchs and links are correct,
Jon Hall77f53ce2014-10-13 18:02:06 -04001201 main.FALSE if the numer of switches and links is incorrect,
1202 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001203 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001204 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001205 topology = self.getTopology( topologyResult )
Jon Hall77f53ce2014-10-13 18:02:06 -04001206 if topology == {}:
1207 return main.ERROR
1208 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001209 # Is the number of switches is what we expected
1210 devices = topology.get( 'devices', False )
1211 links = topology.get( 'links', False )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001212 if not devices or not links:
Jon Hall77f53ce2014-10-13 18:02:06 -04001213 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001214 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001215 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001216 linkCheck = ( int( links ) == int( numolink ) )
1217 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08001218 # We expected the correct numbers
Jon Hall77f53ce2014-10-13 18:02:06 -04001219 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001220 + "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001221 result = main.TRUE
1222 else:
1223 output = output + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001224 "The number of links and switches does not match\
1225 what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001226 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001227 output = output + "\n ONOS sees %i devices (%i expected)\
1228 and %i links (%i expected)" %\
1229 ( int( devices ), int( numoswitch ),
1230 int( links ), int( numolink ) )
1231 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001232 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001233 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001234 main.log.warn( output )
Jon Hall77f53ce2014-10-13 18:02:06 -04001235 else:
kelvin8ec71442015-01-15 16:57:00 -08001236 main.log.info( output )
1237 return result
Jon Hall77f53ce2014-10-13 18:02:06 -04001238 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001239 main.log.error( self.name + ": EOF exception found" )
1240 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001241 main.cleanup()
1242 main.exit()
1243 except:
kelvin8ec71442015-01-15 16:57:00 -08001244 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -08001245 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -08001246 main.log.info( self.name + " ::::::" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001247 main.cleanup()
1248 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001249
kelvin-onlabd3b64892015-01-20 13:26:24 -08001250 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001251 """
andrewonlab970399c2014-11-07 13:09:32 -05001252 Capture all packet activity and store in specified
1253 directory/file
1254
1255 Required:
1256 * interface: interface to capture
1257 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001258 """
1259 self.handle.sendline( "" )
1260 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001261
kelvin8ec71442015-01-15 16:57:00 -08001262 self.handle.sendline( "tshark -i " + str( interface ) +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001263 " -t e -w " + str( dirFile ) + " &" )
kelvin8ec71442015-01-15 16:57:00 -08001264 self.handle.sendline( "\r" )
1265 self.handle.expect( "Capturing on" )
1266 self.handle.sendline( "\r" )
1267 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001268
kelvin8ec71442015-01-15 16:57:00 -08001269 main.log.info( "Tshark started capturing files on " +
1270 str( interface ) + " and saving to directory: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001271 str( dirFile ) )
Shreya Shaha73aaad2014-10-27 18:03:09 -04001272
kelvin-onlabd3b64892015-01-20 13:26:24 -08001273 def runOnosTopoCfg( self, instanceName, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001274 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001275 On ONOS bench, run this command:
1276 ./~/ONOS/tools/test/bin/onos-topo-cfg $OC1 filename
1277 which starts the rest and copies
1278 the json file to the onos instance
kelvin8ec71442015-01-15 16:57:00 -08001279 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001280 try:
kelvin8ec71442015-01-15 16:57:00 -08001281 self.handle.sendline( "" )
1282 self.handle.expect( "\$" )
1283 self.handle.sendline( "cd ~/ONOS/tools/test/bin" )
1284 self.handle.expect( "/bin$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001285 cmd = "./onos-topo-cfg " + instanceName + " " + jsonFile
shahshreyae6c7cf42014-11-26 16:39:01 -08001286 print "cmd = ", cmd
kelvin8ec71442015-01-15 16:57:00 -08001287 self.handle.sendline( cmd )
1288 self.handle.expect( "\$" )
1289 self.handle.sendline( "cd ~" )
1290 self.handle.expect( "\$" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001291 return main.TRUE
1292 except:
1293 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001294
kelvin-onlabd3b64892015-01-20 13:26:24 -08001295 def tsharkGrep( self, grep, directory, interface='eth0' ):
kelvin8ec71442015-01-15 16:57:00 -08001296 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001297 Required:
kelvin8ec71442015-01-15 16:57:00 -08001298 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001299 * directory to store results
1300 Optional:
1301 * interface - default: eth0
1302 Description:
1303 Uses tshark command to grep specific group of packets
1304 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001305 The timestamp is hardcoded to be in epoch
1306 """
1307 self.handle.sendline( "" )
1308 self.handle.expect( "\$" )
1309 self.handle.sendline( "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001310 self.handle.sendline(
1311 "tshark -i " +
1312 str( interface ) +
1313 " -t e | grep --line-buffered \"" +
1314 str(grep) +
1315 "\" >" +
1316 directory +
1317 " &" )
kelvin8ec71442015-01-15 16:57:00 -08001318 self.handle.sendline( "\r" )
1319 self.handle.expect( "Capturing on" )
1320 self.handle.sendline( "\r" )
1321 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001322
kelvin-onlabd3b64892015-01-20 13:26:24 -08001323 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001324 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001325 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001326 """
1327 # Remove all pcap from previous captures
1328 self.execute( cmd="sudo rm /tmp/wireshark*" )
1329 self.handle.sendline( "" )
1330 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\" |" +
1331 " grep -v grep | awk '{print $2}'`" )
1332 self.handle.sendline( "" )
1333 main.log.info( "Tshark stopped" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001334
kelvin8ec71442015-01-15 16:57:00 -08001335 def ptpd( self, args ):
1336 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001337 Initiate ptp with user-specified args.
1338 Required:
1339 * args: specify string of args after command
1340 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001341 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001342 try:
kelvin8ec71442015-01-15 16:57:00 -08001343 self.handle.sendline( "sudo ptpd " + str( args ) )
1344 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001345 "Multiple",
1346 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001347 "\$" ] )
1348 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001349
andrewonlab0c38a4a2014-10-28 18:35:35 -04001350 if i == 0:
1351 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001352 main.log.info( "ptpd returned an error: " +
1353 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001354 return handle
1355 elif i == 1:
1356 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001357 main.log.error( "ptpd returned an error: " +
1358 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001359 return handle
1360 else:
1361 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001362
andrewonlab0c38a4a2014-10-28 18:35:35 -04001363 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001364 main.log.error( self.name + ": EOF exception found" )
1365 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001366 main.cleanup()
1367 main.exit()
1368 except:
kelvin8ec71442015-01-15 16:57:00 -08001369 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -08001370 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -08001371 main.log.info( self.name + " ::::::" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001372 main.cleanup()
1373 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001374
kelvin-onlabd3b64892015-01-20 13:26:24 -08001375 def cpLogsToDir( self, logToCopy,
1376 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001377 """
1378 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001379 Current implementation of ONOS deletes its karaf
1380 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001381 you may want to use this function to capture
1382 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001383 Localtime will be attached to the filename
1384
1385 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001386 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001387 copy.
kelvin8ec71442015-01-15 16:57:00 -08001388 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001389 For copying multiple files, leave copyFileName
1390 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001391 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001392 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001393 ex ) /tmp/
1394 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001395 * copyFileName: If you want to rename the log
1396 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001397 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001398 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001399 try:
kelvin8ec71442015-01-15 16:57:00 -08001400 localtime = time.strftime( '%x %X' )
1401 localtime = localtime.replace( "/", "" )
1402 localtime = localtime.replace( " ", "_" )
1403 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001404 if destDir[ -1: ] != "/":
1405 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001406
kelvin-onlabd3b64892015-01-20 13:26:24 -08001407 if copyFileName:
1408 self.handle.sendline(
1409 "cp " +
1410 str( logToCopy ) +
1411 " " +
1412 str( destDir ) +
1413 str( copyFileName ) +
1414 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001415 self.handle.expect( "cp" )
1416 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001417 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001418 self.handle.sendline( "cp " + str( logToCopy ) +
1419 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001420 self.handle.expect( "cp" )
1421 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001422
kelvin8ec71442015-01-15 16:57:00 -08001423 return self.handle.before
1424
1425 except pexpect.EOF:
1426 main.log.error( "Copying files failed" )
1427 main.log.error( self.name + ": EOF exception found" )
1428 main.log.error( self.name + ": " + self.handle.before )
1429 except:
1430 main.log.error( "Copying files failed" )
1431 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -08001432 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -08001433 main.log.info( self.name + " ::::::" )
1434
kelvin-onlabd3b64892015-01-20 13:26:24 -08001435 def checkLogs( self, onosIp ):
kelvin8ec71442015-01-15 16:57:00 -08001436 """
Jon Hall94fd0472014-12-08 11:52:42 -08001437 runs onos-check-logs on the given onos node
1438 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001439 """
Jon Hall94fd0472014-12-08 11:52:42 -08001440 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001441 cmd = "onos-check-logs " + str( onosIp )
kelvin8ec71442015-01-15 16:57:00 -08001442 self.handle.sendline( cmd )
1443 self.handle.expect( cmd )
1444 self.handle.expect( "\$" )
Jon Hall94fd0472014-12-08 11:52:42 -08001445 response = self.handle.before
1446 return response
1447 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001448 main.log.error( "Lost ssh connection" )
1449 main.log.error( self.name + ": EOF exception found" )
1450 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001451 except:
kelvin8ec71442015-01-15 16:57:00 -08001452 main.log.error( "Some error in check_logs:" )
1453 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -08001454 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -08001455 main.log.info( self.name + " ::::::" )
Jon Hall94fd0472014-12-08 11:52:42 -08001456
kelvin-onlabd3b64892015-01-20 13:26:24 -08001457 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001458 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001459 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001460 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001461 try:
kelvin8ec71442015-01-15 16:57:00 -08001462 self.handle.sendline( "" )
1463 self.handle.expect( "\$" )
1464 self.handle.sendline( "onos-service " + str( node ) +
1465 " status" )
1466 i = self.handle.expect( [
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001467 "start/running",
1468 "stop/waiting",
kelvin8ec71442015-01-15 16:57:00 -08001469 pexpect.TIMEOUT ], timeout=120 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001470
1471 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001472 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001473 return main.TRUE
1474 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001475 main.log.info( "ONOS is stopped" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001476 return main.FALSE
1477 else:
kelvin8ec71442015-01-15 16:57:00 -08001478 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001479 main.cleanup()
1480 main.exit()
1481 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001482 main.log.error( self.name + ": EOF exception found" )
1483 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001484 main.cleanup()
1485 main.exit()
1486 except:
kelvin8ec71442015-01-15 16:57:00 -08001487 main.log.info( self.name + " ::::::" )
kelvin-onlab64b33712015-01-21 15:26:15 -08001488 main.log.error( traceback.print_exc() )
kelvin8ec71442015-01-15 16:57:00 -08001489 main.log.info( self.name + " ::::::" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001490 main.cleanup()
1491 main.exit()