blob: 1f153ee4eaf5bd37a24741fed031db23c785bd75 [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
kelvin8ec71442015-01-15 16:57:00 -080023sys.path.append( "../" )
Jon Hall05b2b432014-10-08 19:53:25 -040024from drivers.common.clidriver import CLI
25
Jon Hall05b2b432014-10-08 19:53:25 -040026
kelvin8ec71442015-01-15 16:57:00 -080027class OnosDriver( CLI ):
Jon Hall05b2b432014-10-08 19:53:25 -040028
kelvin8ec71442015-01-15 16:57:00 -080029 def __init__( self ):
30 """
31 Initialize client
32 """
Jon Hallefbd9792015-03-05 16:11:36 -080033 self.name = None
34 self.home = None
35 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080036 super( CLI, self ).__init__()
37
38 def connect( self, **connectargs ):
39 """
Jon Hall05b2b432014-10-08 19:53:25 -040040 Creates ssh handle for ONOS "bench".
kelvin8ec71442015-01-15 16:57:00 -080041 """
Jon Hall05b2b432014-10-08 19:53:25 -040042 try:
43 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080044 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us3b087132015-03-11 15:00:08 -070045 self.home = "~/onos"
Jon Hall05b2b432014-10-08 19:53:25 -040046 for key in self.options:
47 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080048 self.home = self.options[ 'home' ]
Jon Hall05b2b432014-10-08 19:53:25 -040049 break
Jon Hall274b6642015-02-17 11:57:17 -080050 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070051 self.home = "~/onos"
Jon Hall21270ac2015-02-16 17:59:55 -080052
kelvin8ec71442015-01-15 16:57:00 -080053 self.name = self.options[ 'name' ]
54 self.handle = super( OnosDriver, self ).connect(
55 user_name=self.user_name,
kelvin-onlab08679eb2015-01-21 16:11:48 -080056 ip_address=self.ip_address,
kelvin-onlabd3b64892015-01-20 13:26:24 -080057 port=self.port,
58 pwd=self.pwd,
59 home=self.home )
Jon Hall05b2b432014-10-08 19:53:25 -040060
kelvin8ec71442015-01-15 16:57:00 -080061 self.handle.sendline( "cd " + self.home )
62 self.handle.expect( "\$" )
Jon Hall05b2b432014-10-08 19:53:25 -040063 if self.handle:
64 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080065 else:
66 main.log.info( "NO ONOS HANDLE" )
Jon Hall05b2b432014-10-08 19:53:25 -040067 return main.FALSE
68 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080069 main.log.error( self.name + ": EOF exception found" )
70 main.log.error( self.name + ": " + self.handle.before )
Jon Hall05b2b432014-10-08 19:53:25 -040071 main.cleanup()
72 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080073 except Exception:
74 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall05b2b432014-10-08 19:53:25 -040075 main.cleanup()
76 main.exit()
77
kelvin8ec71442015-01-15 16:57:00 -080078 def disconnect( self ):
79 """
Jon Hall05b2b432014-10-08 19:53:25 -040080 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -080081 """
Jon Halld61331b2015-02-17 16:35:47 -080082 response = main.TRUE
Jon Hall05b2b432014-10-08 19:53:25 -040083 try:
Jon Hall61282e32015-03-19 11:34:11 -070084 if self.handle:
85 self.handle.sendline( "" )
86 self.handle.expect( "\$" )
87 self.handle.sendline( "exit" )
88 self.handle.expect( "closed" )
Jon Hall05b2b432014-10-08 19:53:25 -040089 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080090 main.log.error( self.name + ": EOF exception found" )
91 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -070092 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -070093 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -070094 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -080095 except Exception:
96 main.log.exception( self.name + ": Connection failed to the host" )
Jon Hall05b2b432014-10-08 19:53:25 -040097 response = main.FALSE
98 return response
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -040099
kelvin-onlabd3b64892015-01-20 13:26:24 -0800100 def onosPackage( self ):
kelvin8ec71442015-01-15 16:57:00 -0800101 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400102 Produce a self-contained tar.gz file that can be deployed
kelvin8ec71442015-01-15 16:57:00 -0800103 and executed on any platform with Java 7 JRE.
104 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400105 try:
kelvin8ec71442015-01-15 16:57:00 -0800106 self.handle.sendline( "onos-package" )
107 self.handle.expect( "onos-package" )
108 self.handle.expect( "tar.gz", timeout=30 )
109 handle = str( self.handle.before )
110 main.log.info( "onos-package command returned: " +
111 handle )
112 # As long as the sendline does not time out,
113 # return true. However, be careful to interpret
114 # the results of the onos-package command return
andrewonlab0748d2a2014-10-09 13:24:17 -0400115 return main.TRUE
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400116
andrewonlab7735d852014-10-09 13:02:47 -0400117 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800118 main.log.error( self.name + ": EOF exception found" )
119 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800120 except Exception:
121 main.log.exception( "Failed to package ONOS" )
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400122 main.cleanup()
123 main.exit()
124
kelvin-onlabd3b64892015-01-20 13:26:24 -0800125 def onosBuild( self ):
kelvin8ec71442015-01-15 16:57:00 -0800126 """
andrewonlab8790abb2014-11-06 13:51:54 -0500127 Use the pre defined script to build onos via mvn
kelvin8ec71442015-01-15 16:57:00 -0800128 """
andrewonlab8790abb2014-11-06 13:51:54 -0500129 try:
kelvin8ec71442015-01-15 16:57:00 -0800130 self.handle.sendline( "onos-build" )
131 self.handle.expect( "onos-build" )
132 i = self.handle.expect( [
kelvin-onlabd3b64892015-01-20 13:26:24 -0800133 "BUILD SUCCESS",
134 "ERROR",
135 "BUILD FAILED" ],
136 timeout=120 )
kelvin8ec71442015-01-15 16:57:00 -0800137 handle = str( self.handle.before )
andrewonlab8790abb2014-11-06 13:51:54 -0500138
kelvin8ec71442015-01-15 16:57:00 -0800139 main.log.info( "onos-build command returned: " +
140 handle )
andrewonlab8790abb2014-11-06 13:51:54 -0500141
142 if i == 0:
143 return main.TRUE
144 else:
145 return handle
146
147 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800148 main.log.error( self.name + ": EOF exception found" )
149 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800150 except Exception:
151 main.log.exception( "Failed to build ONOS" )
andrewonlab8790abb2014-11-06 13:51:54 -0500152 main.cleanup()
153 main.exit()
154
kelvin-onlabd3b64892015-01-20 13:26:24 -0800155 def cleanInstall( self ):
kelvin8ec71442015-01-15 16:57:00 -0800156 """
157 Runs mvn clean install in the root of the ONOS directory.
158 This will clean all ONOS artifacts then compile each module
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400159
kelvin8ec71442015-01-15 16:57:00 -0800160 Returns: main.TRUE on success
Jon Hallde9d9aa2014-10-08 20:36:02 -0400161 On Failure, exits the test
kelvin8ec71442015-01-15 16:57:00 -0800162 """
Jon Hallde9d9aa2014-10-08 20:36:02 -0400163 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800164 main.log.info( "Running 'mvn clean install' on " +
165 str( self.name ) +
kelvin8ec71442015-01-15 16:57:00 -0800166 ". This may take some time." )
167 self.handle.sendline( "cd " + self.home )
168 self.handle.expect( "\$" )
Jon Hallea7818b2014-10-09 14:30:59 -0400169
kelvin8ec71442015-01-15 16:57:00 -0800170 self.handle.sendline( "" )
171 self.handle.expect( "\$" )
172 self.handle.sendline( "mvn clean install" )
173 self.handle.expect( "mvn clean install" )
174 while True:
175 i = self.handle.expect( [
Jon Hall274b6642015-02-17 11:57:17 -0800176 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
Jon Hallefbd9792015-03-05 16:11:36 -0800177 'Runtime\sEnvironment\sto\scontinue',
Jon Hallde9d9aa2014-10-08 20:36:02 -0400178 'BUILD\sFAILURE',
179 'BUILD\sSUCCESS',
Jon Halle94919c2015-03-23 11:42:57 -0700180 'onos\$', #TODO: fix this to be more generic?
Jon Hallde9d9aa2014-10-08 20:36:02 -0400181 'ONOS\$',
kelvin8ec71442015-01-15 16:57:00 -0800182 pexpect.TIMEOUT ], timeout=600 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400183 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800184 main.log.error( self.name + ":There is insufficient memory \
185 for the Java Runtime Environment to continue." )
186 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400187 main.cleanup()
188 main.exit()
189 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800190 main.log.error( self.name + ": Build failure!" )
191 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400192 main.cleanup()
193 main.exit()
194 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800195 main.log.info( self.name + ": Build success!" )
Jon Halle94919c2015-03-23 11:42:57 -0700196 elif i == 3 or i == 4:
kelvin8ec71442015-01-15 16:57:00 -0800197 main.log.info( self.name + ": Build complete" )
198 # Print the build time
Jon Hallf8ef52c2014-10-09 19:37:33 -0400199 for line in self.handle.before.splitlines():
200 if "Total time:" in line:
kelvin8ec71442015-01-15 16:57:00 -0800201 main.log.info( line )
202 self.handle.sendline( "" )
203 self.handle.expect( "\$", timeout=60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400204 return main.TRUE
Jon Halle94919c2015-03-23 11:42:57 -0700205 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800206 main.log.error(
207 self.name +
208 ": mvn clean install TIMEOUT!" )
209 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400210 main.cleanup()
211 main.exit()
212 else:
Jon Hall274b6642015-02-17 11:57:17 -0800213 main.log.error( self.name + ": unexpected response from " +
Jon Hallefbd9792015-03-05 16:11:36 -0800214 "mvn clean install" )
kelvin8ec71442015-01-15 16:57:00 -0800215 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400216 main.cleanup()
217 main.exit()
218 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800219 main.log.error( self.name + ": EOF exception found" )
220 main.log.error( self.name + ": " + self.handle.before )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400221 main.cleanup()
222 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800223 except Exception:
224 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400225 main.cleanup()
226 main.exit()
Jon Hallacabffd2014-10-09 12:36:53 -0400227
Jon Hall61282e32015-03-19 11:34:11 -0700228 def gitPull( self, comp1="", fastForward=True ):
kelvin8ec71442015-01-15 16:57:00 -0800229 """
Jon Hallacabffd2014-10-09 12:36:53 -0400230 Assumes that "git pull" works without login
Jon Hall47a93fb2015-01-06 16:46:06 -0800231
Jon Hall61282e32015-03-19 11:34:11 -0700232 If the fastForward boolean is set to true, only git pulls that can
233 be fast forwarded will be performed. IE if you have not local commits
234 in your branch.
235
Jon Hallacabffd2014-10-09 12:36:53 -0400236 This function will perform a git pull on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 If used as gitPull( "NODE" ) it will do git pull + NODE. This is
Jon Hallacabffd2014-10-09 12:36:53 -0400238 for the purpose of pulling from other nodes if necessary.
239
Jon Hall47a93fb2015-01-06 16:46:06 -0800240 Otherwise, this function will perform a git pull in the
Jon Hallacabffd2014-10-09 12:36:53 -0400241 ONOS repository. If it has any problems, it will return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -0800242 If it successfully does a gitPull, it will return a 1 ( main.TRUE )
Shreya Shahee15f6c2014-10-28 18:12:30 -0400243 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400244
kelvin8ec71442015-01-15 16:57:00 -0800245 """
Jon Hallacabffd2014-10-09 12:36:53 -0400246 try:
kelvin8ec71442015-01-15 16:57:00 -0800247 # main.log.info( self.name + ": Stopping ONOS" )
248 # self.stop()
249 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800250 self.handle.expect( self.home + "\$" )
Jon Hall61282e32015-03-19 11:34:11 -0700251 cmd = "git pull"
252 if comp1 != "":
253 cmd += ' ' + comp1
254 if fastForward:
255 cmd += ' ' + " --ff-only"
256 self.handle.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800257 i = self.handle.expect(
258 [
259 'fatal',
260 'Username\sfor\s(.*):\s',
261 '\sfile(s*) changed,\s',
262 'Already up-to-date',
263 'Aborting',
264 'You\sare\snot\scurrently\son\sa\sbranch',
Jon Hall274b6642015-02-17 11:57:17 -0800265 'You asked me to pull without telling me which branch you',
266 'Pull is not possible because you have unmerged files',
Jon Hall61282e32015-03-19 11:34:11 -0700267 'Please enter a commit message to explain why this merge',
268 'Found a swap file by the name',
269 'Please, commit your changes before you can merge.',
kelvin-onlabd3b64892015-01-20 13:26:24 -0800270 pexpect.TIMEOUT ],
271 timeout=300 )
kelvin8ec71442015-01-15 16:57:00 -0800272 # debug
kelvin-onlabd3b64892015-01-20 13:26:24 -0800273 # main.log.report( self.name +": DEBUG: \n"+
274 # "git pull response: " +
275 # str( self.handle.before ) + str( self.handle.after ) )
kelvin8ec71442015-01-15 16:57:00 -0800276 if i == 0:
Jon Hall61282e32015-03-19 11:34:11 -0700277 main.log.error( self.name + ": Git pull had some issue" )
278 output = self.handle.after
279 self.handle.expect( '\$' )
280 output += self.handle.before
281 main.log.warn( output )
Jon Hallacabffd2014-10-09 12:36:53 -0400282 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800283 elif i == 1:
284 main.log.error(
285 self.name +
286 ": Git Pull Asking for username. " )
Jon Hallacabffd2014-10-09 12:36:53 -0400287 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800288 elif i == 2:
289 main.log.info(
290 self.name +
291 ": Git Pull - pulling repository now" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800292 self.handle.expect( self.home + "\$", 120 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800293 # So that only when git pull is done, we do mvn clean compile
294 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800295 elif i == 3:
296 main.log.info( self.name + ": Git Pull - Already up to date" )
Jon Hall47a93fb2015-01-06 16:46:06 -0800297 return i
kelvin8ec71442015-01-15 16:57:00 -0800298 elif i == 4:
299 main.log.info(
300 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800301 ": Git Pull - Aborting..." +
302 "Are there conflicting git files?" )
Jon Hallacabffd2014-10-09 12:36:53 -0400303 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800304 elif i == 5:
305 main.log.info(
306 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800307 ": Git Pull - You are not currently " +
308 "on a branch so git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400309 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800310 elif i == 6:
311 main.log.info(
312 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800313 ": Git Pull - You have not configured an upstream " +
314 "branch to pull from. Git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400315 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800316 elif i == 7:
317 main.log.info(
318 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800319 ": Git Pull - Pull is not possible because " +
320 "you have unmerged files." )
Jon Hallacabffd2014-10-09 12:36:53 -0400321 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800322 elif i == 8:
Jon Hall61282e32015-03-19 11:34:11 -0700323 # NOTE: abandoning test since we can't reliably handle this
324 # there could be different default text editors and we
325 # also don't know if we actually want to make the commit
326 main.log.error( "Git pull resulted in a merge commit message" +
327 ". Exiting test!" )
328 main.cleanup()
329 main.exit()
330 elif i == 9: # Merge commit message but swap file exists
331 main.log.error( "Git pull resulted in a merge commit message" +
332 " but a swap file exists." )
333 try:
334 self.handle.send( 'A' ) # Abort
335 self.handle.expect( "\$" )
336 return main.ERROR
337 except Exception:
338 main.log.exception( "Couldn't exit editor prompt!")
339 main.cleanup()
340 main.exit()
341 elif i == 10: # In the middle of a merge commit
342 main.log.error( "Git branch is in the middle of a merge. " )
343 main.log.warn( self.handle.before + self.handle.after )
344 return main.ERROR
345 elif i == 11:
kelvin8ec71442015-01-15 16:57:00 -0800346 main.log.error( self.name + ": Git Pull - TIMEOUT" )
347 main.log.error(
348 self.name + " Response was: " + str(
349 self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400350 return main.ERROR
351 else:
kelvin8ec71442015-01-15 16:57:00 -0800352 main.log.error(
353 self.name +
354 ": Git Pull - Unexpected response, check for pull errors" )
Jon Hallacabffd2014-10-09 12:36:53 -0400355 return main.ERROR
356 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800357 main.log.error( self.name + ": EOF exception found" )
358 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400359 main.cleanup()
360 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800361 except Exception:
362 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400363 main.cleanup()
364 main.exit()
365
kelvin-onlabd3b64892015-01-20 13:26:24 -0800366 def gitCheckout( self, branch="master" ):
kelvin8ec71442015-01-15 16:57:00 -0800367 """
Jon Hallacabffd2014-10-09 12:36:53 -0400368 Assumes that "git pull" works without login
kelvin8ec71442015-01-15 16:57:00 -0800369
Jon Hallacabffd2014-10-09 12:36:53 -0400370 This function will perform a git git checkout on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800371 If used as gitCheckout( "branch" ) it will do git checkout
372 of the "branch".
Jon Hallacabffd2014-10-09 12:36:53 -0400373
374 Otherwise, this function will perform a git checkout of the master
kelvin8ec71442015-01-15 16:57:00 -0800375 branch of the ONOS repository. If it has any problems, it will return
376 main.ERROR.
377 If the branch was already the specified branch, or the git checkout was
Jon Hallacabffd2014-10-09 12:36:53 -0400378 successful then the function will return main.TRUE.
379
kelvin8ec71442015-01-15 16:57:00 -0800380 """
Jon Hallacabffd2014-10-09 12:36:53 -0400381 try:
kelvin8ec71442015-01-15 16:57:00 -0800382 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800383 self.handle.expect( self.home + "\$" )
Jon Hall274b6642015-02-17 11:57:17 -0800384 main.log.info( self.name +
385 ": Checking out git branch/ref: " + branch + "..." )
kelvin8ec71442015-01-15 16:57:00 -0800386 cmd = "git checkout " + branch
387 self.handle.sendline( cmd )
388 self.handle.expect( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800389 i = self.handle.expect(
Jon Hall274b6642015-02-17 11:57:17 -0800390 [ 'fatal',
Jon Hall61282e32015-03-19 11:34:11 -0700391 'Username for (.*): ',
392 'Already on \'',
393 'Switched to branch \'' + str( branch ),
Jon Hall274b6642015-02-17 11:57:17 -0800394 pexpect.TIMEOUT,
395 'error: Your local changes to the following files' +
Jon Hallefbd9792015-03-05 16:11:36 -0800396 'would be overwritten by checkout:',
Jon Hall274b6642015-02-17 11:57:17 -0800397 'error: you need to resolve your current index first',
398 "You are in 'detached HEAD' state.",
399 "HEAD is now at " ],
kelvin-onlabd3b64892015-01-20 13:26:24 -0800400 timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -0800401 if i == 0:
402 main.log.error(
403 self.name +
404 ": Git checkout had some issue..." )
405 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400406 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800407 elif i == 1:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800408 main.log.error(
409 self.name +
410 ": Git checkout asking for username." +
411 " Please configure your local git repository to be able " +
412 "to access your remote repository passwordlessly" )
Jon Hall274b6642015-02-17 11:57:17 -0800413 # TODO add support for authenticating
Jon Hallacabffd2014-10-09 12:36:53 -0400414 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800415 elif i == 2:
416 main.log.info(
417 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800418 ": Git Checkout %s : Already on this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800419 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800420 # main.log.info( "DEBUG: after checkout cmd = "+
421 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400422 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800423 elif i == 3:
424 main.log.info(
425 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800426 ": Git checkout %s - Switched to this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800427 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800428 # main.log.info( "DEBUG: after checkout cmd = "+
429 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400430 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800431 elif i == 4:
432 main.log.error( self.name + ": Git Checkout- TIMEOUT" )
433 main.log.error(
Jon Hall274b6642015-02-17 11:57:17 -0800434 self.name + " Response was: " + str( self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400435 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800436 elif i == 5:
437 self.handle.expect( "Aborting" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800438 main.log.error(
439 self.name +
440 ": Git checkout error: \n" +
Jon Hall274b6642015-02-17 11:57:17 -0800441 "Your local changes to the following files would" +
442 " be overwritten by checkout:" +
443 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800444 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500445 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800446 elif i == 6:
Jon Hall274b6642015-02-17 11:57:17 -0800447 main.log.error(
448 self.name +
449 ": Git checkout error: \n" +
450 "You need to resolve your current index first:" +
451 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800452 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500453 return main.ERROR
Jon Hall274b6642015-02-17 11:57:17 -0800454 elif i == 7:
455 main.log.info(
456 self.name +
457 ": Git checkout " + str( branch ) +
458 " - You are in 'detached HEAD' state. HEAD is now at " +
459 str( branch ) )
460 self.handle.expect( self.home + "\$" )
461 return main.TRUE
462 elif i == 8: # Already in detached HEAD on the specified commit
463 main.log.info(
464 self.name +
465 ": Git Checkout %s : Already on commit" % branch )
466 self.handle.expect( self.home + "\$" )
467 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400468 else:
kelvin8ec71442015-01-15 16:57:00 -0800469 main.log.error(
470 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800471 ": Git Checkout - Unexpected response, " +
472 "check for pull errors" )
kelvin8ec71442015-01-15 16:57:00 -0800473 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400474 return main.ERROR
475
476 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800477 main.log.error( self.name + ": EOF exception found" )
478 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400479 main.cleanup()
480 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800481 except Exception:
482 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400483 main.cleanup()
484 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400485
kelvin-onlabd3b64892015-01-20 13:26:24 -0800486 def getVersion( self, report=False ):
kelvin8ec71442015-01-15 16:57:00 -0800487 """
Jon Hall274b6642015-02-17 11:57:17 -0800488 Writes the COMMIT number to the report to be parsed
Jon Hallefbd9792015-03-05 16:11:36 -0800489 by Jenkins data collector.
kelvin8ec71442015-01-15 16:57:00 -0800490 """
Jon Hall45ec0922014-10-10 19:33:49 -0400491 try:
kelvin8ec71442015-01-15 16:57:00 -0800492 self.handle.sendline( "" )
493 self.handle.expect( "\$" )
494 self.handle.sendline(
495 "cd " +
496 self.home +
Jon Hall274b6642015-02-17 11:57:17 -0800497 "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " +
498 " \"commit\" --color=never" )
kelvin8ec71442015-01-15 16:57:00 -0800499 # NOTE: for some reason there are backspaces inserted in this
500 # phrase when run from Jenkins on some tests
501 self.handle.expect( "never" )
502 self.handle.expect( "\$" )
503 response = ( self.name + ": \n" + str(
504 self.handle.before + self.handle.after ) )
505 self.handle.sendline( "cd " + self.home )
506 self.handle.expect( "\$" )
507 lines = response.splitlines()
Jon Hall45ec0922014-10-10 19:33:49 -0400508 for line in lines:
Jon Hallfd191202014-11-07 18:36:09 -0500509 print line
510 if report:
Jon Hall82a7dad2015-04-30 16:26:08 -0700511 main.log.wiki( "<blockquote>" )
kelvin8ec71442015-01-15 16:57:00 -0800512 for line in lines[ 2:-1 ]:
513 # Bracket replacement is for Wiki-compliant
514 # formatting. '<' or '>' are interpreted
515 # as xml specific tags that cause errors
516 line = line.replace( "<", "[" )
517 line = line.replace( ">", "]" )
Jon Hall82a7dad2015-04-30 16:26:08 -0700518 #main.log.wiki( "\t" + line )
519 main.log.wiki( line + "<br /> " )
520 main.log.summary( line )
521 main.log.wiki( "</blockquote>" )
522 main.log.summary("\n")
kelvin8ec71442015-01-15 16:57:00 -0800523 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400524 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800525 main.log.error( self.name + ": EOF exception found" )
526 main.log.error( self.name + ": " + self.handle.before )
Jon Hall45ec0922014-10-10 19:33:49 -0400527 main.cleanup()
528 main.exit()
Jon Hall368769f2014-11-19 15:43:35 -0800529 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800530 main.log.error( self.name + ": TIMEOUT exception found" )
531 main.log.error( self.name + ": " + self.handle.before )
Jon Hall368769f2014-11-19 15:43:35 -0800532 main.cleanup()
533 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800534 except Exception:
535 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall45ec0922014-10-10 19:33:49 -0400536 main.cleanup()
537 main.exit()
538
kelvin-onlabd3b64892015-01-20 13:26:24 -0800539 def createCellFile( self, benchIp, fileName, mnIpAddrs,
cameron@onlab.us75900962015-03-30 13:22:49 -0700540 appString, *onosIpAddrs ):
kelvin8ec71442015-01-15 16:57:00 -0800541 """
andrewonlab94282092014-10-10 13:00:11 -0400542 Creates a cell file based on arguments
543 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800544 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400545 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800546 * File name of the cell file ( fileName )
547 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800548 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400549 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800550 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400551 - Must be passed in as last arguments
kelvin8ec71442015-01-15 16:57:00 -0800552
andrewonlab94282092014-10-10 13:00:11 -0400553 NOTE: Assumes cells are located at:
554 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800555 """
556 # Variable initialization
kelvin-onlabd3b64892015-01-20 13:26:24 -0800557 cellDirectory = self.home + "/tools/test/cells/"
kelvin8ec71442015-01-15 16:57:00 -0800558 # We want to create the cell file in the dependencies directory
559 # of TestON first, then copy over to ONOS bench
kelvin-onlabd3b64892015-01-20 13:26:24 -0800560 tempDirectory = "/tmp/"
kelvin8ec71442015-01-15 16:57:00 -0800561 # Create the cell file in the directory for writing ( w+ )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800562 cellFile = open( tempDirectory + fileName, 'w+' )
kelvin8ec71442015-01-15 16:57:00 -0800563
cameron@onlab.us75900962015-03-30 13:22:49 -0700564 # App string is hardcoded environment variables
kelvin8ec71442015-01-15 16:57:00 -0800565 # That you may wish to use by default on startup.
cameron@onlab.us75900962015-03-30 13:22:49 -0700566 # Note that you may not want certain apps listed
kelvin8ec71442015-01-15 16:57:00 -0800567 # on here.
cameron@onlab.us75900962015-03-30 13:22:49 -0700568 appString = "export ONOS_APPS=" + appString
kelvin-onlabd3b64892015-01-20 13:26:24 -0800569 mnString = "export OCN="
570 onosString = "export OC"
571 tempCount = 1
kelvin8ec71442015-01-15 16:57:00 -0800572
kelvin-onlabd3b64892015-01-20 13:26:24 -0800573 # Create ONOSNIC ip address prefix
574 tempOnosIp = onosIpAddrs[ 0 ]
575 tempList = []
576 tempList = tempOnosIp.split( "." )
kelvin8ec71442015-01-15 16:57:00 -0800577 # Omit last element of list to format for NIC
kelvin-onlabd3b64892015-01-20 13:26:24 -0800578 tempList = tempList[ :-1 ]
kelvin8ec71442015-01-15 16:57:00 -0800579 # Structure the nic string ip
kelvin-onlabd3b64892015-01-20 13:26:24 -0800580 nicAddr = ".".join( tempList ) + ".*"
581 onosNicString = "export ONOS_NIC=" + nicAddr
andrewonlab94282092014-10-10 13:00:11 -0400582
583 try:
kelvin8ec71442015-01-15 16:57:00 -0800584 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800585 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400586
kelvin-onlabd3b64892015-01-20 13:26:24 -0800587 for arg in onosIpAddrs:
588 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800589 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400590 # export OC1="10.128.20.11"
591 # export OC2="10.128.20.12"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800592 cellFile.write( onosString + str( tempCount ) +
593 "=" + "\"" + arg + "\"" + "\n" )
594 tempCount = tempCount + 1
kelvin8ec71442015-01-15 16:57:00 -0800595
kelvin-onlabd3b64892015-01-20 13:26:24 -0800596 cellFile.write( mnString + "\"" + mnIpAddrs + "\"" + "\n" )
cameron@onlab.us75900962015-03-30 13:22:49 -0700597 cellFile.write( appString + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800598 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400599
kelvin8ec71442015-01-15 16:57:00 -0800600 # We use os.system to send the command to TestON cluster
601 # to account for the case in which TestON is not located
602 # on the same cluster as the ONOS bench
603 # Note that even if TestON is located on the same cluster
604 # as ONOS bench, you must setup passwordless ssh
605 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800606 os.system( "scp " + tempDirectory + fileName +
607 " admin@" + benchIp + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400608
andrewonlab2a6c9342014-10-16 13:40:15 -0400609 return main.TRUE
610
andrewonlab94282092014-10-10 13:00:11 -0400611 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 )
andrewonlab94282092014-10-10 13:00:11 -0400614 main.cleanup()
615 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800616 except Exception:
617 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -0400618 main.cleanup()
619 main.exit()
620
kelvin-onlabd3b64892015-01-20 13:26:24 -0800621 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800622 """
andrewonlab95ca1462014-10-09 14:04:24 -0400623 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800624 """
andrewonlab95ca1462014-10-09 14:04:24 -0400625 try:
626 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800627 main.log.error( "Must define cellname" )
andrewonlab95ca1462014-10-09 14:04:24 -0400628 main.cleanup()
629 main.exit()
630 else:
kelvin8ec71442015-01-15 16:57:00 -0800631 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800632 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800633 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400634 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800635 self.handle.expect(str(cellname))
kelvin-onlabd3b64892015-01-20 13:26:24 -0800636 handleBefore = self.handle.before
637 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800638 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800639 self.handle.sendline("")
640 self.handle.expect("\$")
kelvin-onlabd3b64892015-01-20 13:26:24 -0800641 handleMore = self.handle.before
andrewonlab95ca1462014-10-09 14:04:24 -0400642
kelvin-onlabd3b64892015-01-20 13:26:24 -0800643 main.log.info( "Cell call returned: " + handleBefore +
644 handleAfter + handleMore )
andrewonlab95ca1462014-10-09 14:04:24 -0400645
646 return main.TRUE
647
648 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800649 main.log.error( self.name + ": EOF exception found" )
650 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ca1462014-10-09 14:04:24 -0400651 main.cleanup()
652 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800653 except Exception:
654 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ca1462014-10-09 14:04:24 -0400655 main.cleanup()
656 main.exit()
657
kelvin-onlabd3b64892015-01-20 13:26:24 -0800658 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800659 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400660 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800661 """
662 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400663
andrewonlabc03bf6c2014-10-09 14:56:18 -0400664 try:
kelvin8ec71442015-01-15 16:57:00 -0800665 # Clean handle by sending empty and expecting $
666 self.handle.sendline( "" )
667 self.handle.expect( "\$" )
668 self.handle.sendline( "onos-verify-cell" )
669 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800670 handleBefore = self.handle.before
671 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800672 # Get the rest of the handle
673 self.handle.sendline( "" )
674 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800675 handleMore = self.handle.before
andrewonlabc03bf6c2014-10-09 14:56:18 -0400676
kelvin-onlabd3b64892015-01-20 13:26:24 -0800677 main.log.info( "Verify cell returned: " + handleBefore +
678 handleAfter + handleMore )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400679
680 return main.TRUE
Jon Halla5cb6172015-02-23 09:28:28 -0800681 except pexpect.ExceptionPexpect as e:
682 main.log.error( self.name + ": Pexpect exception found of type " +
683 str( type( e ) ) )
684 main.log.error ( e.get_trace() )
kelvin8ec71442015-01-15 16:57:00 -0800685 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400686 main.cleanup()
687 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800688 except Exception:
689 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400690 main.cleanup()
691 main.exit()
692
jenkins1e99e7b2015-04-02 18:15:39 -0700693 def onosCfgSet( self, ONOSIp, configName, configParam ):
694 """
695 Uses 'onos <node-ip> cfg set' to change a parameter value of an
696 application.
697
698 ex)
699 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
700
701 ONOSIp = '10.0.0.1'
702 configName = 'org.onosproject.myapp'
703 configParam = 'appSetting 1'
704
705 """
706 try:
707 cfgStr = ( "onos "+str(ONOSIp)+" cfg set "+
708 str(configName) + " " +
709 str(configParam)
710 )
711
712 self.handle.sendline( "" )
713 self.handle.expect( "\$" )
714 self.handle.sendline( cfgStr )
715 self.handle.expect( "\$" )
716
717 # TODO: Add meaningful assertion
718
719 return main.TRUE
720
721 except pexpect.ExceptionPexpect as e:
722 main.log.error( self.name + ": Pexpect exception found of type " +
723 str( type( e ) ) )
724 main.log.error ( e.get_trace() )
725 main.log.error( self.name + ": " + self.handle.before )
726 main.cleanup()
727 main.exit()
728 except Exception:
729 main.log.exception( self.name + ": Uncaught exception!" )
730 main.cleanup()
731 main.exit()
732
kelvin-onlabd3b64892015-01-20 13:26:24 -0800733 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800734 """
andrewonlab05e362f2014-10-10 00:40:57 -0400735 Uses 'onos' command to send various ONOS CLI arguments.
736 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800737 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400738 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800739
740 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400741 CLI commands for ONOS. Try to use this function first
742 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800743 function.
744 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400745 by starting onos, and typing in 'onos' to enter the
746 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800747 available commands.
748 """
andrewonlab05e362f2014-10-10 00:40:57 -0400749 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800750 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800751 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400752 return main.FALSE
753 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800754 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400755 return main.FALSE
756
kelvin8ec71442015-01-15 16:57:00 -0800757 cmdstr = str( cmdstr )
758 self.handle.sendline( "" )
759 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400760
kelvin-onlabd3b64892015-01-20 13:26:24 -0800761 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800762 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400763
kelvin-onlabd3b64892015-01-20 13:26:24 -0800764 handleBefore = self.handle.before
Shreya Shaha73aaad2014-10-27 18:03:09 -0400765 print "handle_before = ", self.handle.before
kelvin-onlabd3b64892015-01-20 13:26:24 -0800766 # handleAfter = str( self.handle.after )
Jon Hall47a93fb2015-01-06 16:46:06 -0800767
kelvin8ec71442015-01-15 16:57:00 -0800768 # self.handle.sendline( "" )
769 # self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800770 # handleMore = str( self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400771
kelvin8ec71442015-01-15 16:57:00 -0800772 main.log.info( "Command sent successfully" )
andrewonlab05e362f2014-10-10 00:40:57 -0400773
kelvin8ec71442015-01-15 16:57:00 -0800774 # Obtain return handle that consists of result from
775 # the onos command. The string may need to be
776 # configured further.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800777 # returnString = handleBefore + handleAfter
778 returnString = handleBefore
779 print "return_string = ", returnString
780 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400781
782 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800783 main.log.error( self.name + ": EOF exception found" )
784 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400785 main.cleanup()
786 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800787 except Exception:
788 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab05e362f2014-10-10 00:40:57 -0400789 main.cleanup()
790 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400791
kelvin-onlabd3b64892015-01-20 13:26:24 -0800792 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800793 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400794 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800795 If -f option is provided, it also forces an uninstall.
796 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400797 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800798 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400799 files to certain onos nodes
800
801 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800802 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400803 try:
andrewonlab114768a2014-11-14 12:44:44 -0500804 if options:
kelvin8ec71442015-01-15 16:57:00 -0800805 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500806 else:
kelvin8ec71442015-01-15 16:57:00 -0800807 self.handle.sendline( "onos-install " + node )
808 self.handle.expect( "onos-install " )
809 # NOTE: this timeout may need to change depending on the network
810 # and size of ONOS
811 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800812 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800813 "ONOS\sis\salready\sinstalled",
814 pexpect.TIMEOUT ], timeout=60 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400815
Jon Hall7993bfc2014-10-09 16:30:14 -0400816 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800817 main.log.warn( "Network is unreachable" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400818 return main.FALSE
819 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800820 main.log.info(
821 "ONOS was installed on " +
822 node +
823 " and started" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400824 return main.TRUE
andrewonlabd9a73a72014-11-14 17:28:21 -0500825 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800826 main.log.info( "ONOS is already installed on " + node )
andrewonlabd9a73a72014-11-14 17:28:21 -0500827 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800828 elif i == 3:
829 main.log.info(
830 "Installation of ONOS on " +
831 node +
832 " timed out" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400833 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400834
835 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800836 main.log.error( self.name + ": EOF exception found" )
837 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400838 main.cleanup()
839 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800840 except Exception:
841 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400842 main.cleanup()
843 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400844
kelvin-onlabd3b64892015-01-20 13:26:24 -0800845 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800846 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400847 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400848 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800849 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400850 try:
kelvin8ec71442015-01-15 16:57:00 -0800851 self.handle.sendline( "" )
852 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800853 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800854 " start" )
855 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -0400856 "Job\sis\salready\srunning",
857 "start/running",
858 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800859 pexpect.TIMEOUT ], timeout=120 )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400860
861 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800862 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400863 return main.TRUE
864 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800865 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400866 return main.TRUE
867 else:
kelvin8ec71442015-01-15 16:57:00 -0800868 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400869 main.cleanup()
870 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -0400871 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800872 main.log.error( self.name + ": EOF exception found" )
873 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400874 main.cleanup()
875 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800876 except Exception:
877 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400878 main.cleanup()
879 main.exit()
880
kelvin-onlabd3b64892015-01-20 13:26:24 -0800881 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800882 """
andrewonlab2b30bd32014-10-09 16:48:55 -0400883 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400884 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800885 """
andrewonlab2b30bd32014-10-09 16:48:55 -0400886 try:
kelvin8ec71442015-01-15 16:57:00 -0800887 self.handle.sendline( "" )
888 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800889 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800890 " stop" )
891 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -0400892 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -0700893 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -0400894 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800895 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2b30bd32014-10-09 16:48:55 -0400896
897 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800898 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400899 return main.TRUE
900 elif i == 1:
Jon Hall65844a32015-03-09 19:09:37 -0700901 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800902 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -0400903 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700904 elif i == 2:
905 main.log.warn( "ONOS wasn't running" )
906 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -0400907 else:
kelvin8ec71442015-01-15 16:57:00 -0800908 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400909 return main.FALSE
910
911 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800912 main.log.error( self.name + ": EOF exception found" )
913 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -0400914 main.cleanup()
915 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800916 except Exception:
917 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400918 main.cleanup()
919 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800920
kelvin-onlabd3b64892015-01-20 13:26:24 -0800921 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -0800922 """
andrewonlabc8d47972014-10-09 16:52:36 -0400923 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -0800924 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -0400925 if needed
kelvin8ec71442015-01-15 16:57:00 -0800926 """
andrewonlabc8d47972014-10-09 16:52:36 -0400927 try:
kelvin8ec71442015-01-15 16:57:00 -0800928 self.handle.sendline( "" )
929 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800930 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800931 self.handle.expect( "\$" )
andrewonlabc8d47972014-10-09 16:52:36 -0400932
kelvin-onlabd3b64892015-01-20 13:26:24 -0800933 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
andrewonlab9dfd2082014-11-13 17:44:03 -0500934
kelvin8ec71442015-01-15 16:57:00 -0800935 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -0400936 return main.TRUE
937
938 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800939 main.log.error( self.name + ": EOF exception found" )
940 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -0400941 main.cleanup()
942 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800943 except Exception:
944 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc8d47972014-10-09 16:52:36 -0400945 main.cleanup()
946 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -0400947
kelvin-onlabd3b64892015-01-20 13:26:24 -0800948 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800949 """
andrewonlabaedc8332014-12-04 12:43:03 -0500950 Issues the command 'onos-die <node-ip>'
951 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -0800952 """
andrewonlabaedc8332014-12-04 12:43:03 -0500953 try:
kelvin8ec71442015-01-15 16:57:00 -0800954 self.handle.sendline( "" )
955 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800956 cmdStr = "onos-kill " + str( nodeIp )
957 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -0800958 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -0500959 "Killing\sONOS",
960 "ONOS\sprocess\sis\snot\srunning",
kelvin8ec71442015-01-15 16:57:00 -0800961 pexpect.TIMEOUT ], timeout=20 )
andrewonlabaedc8332014-12-04 12:43:03 -0500962 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800963 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800964 " was killed and stopped" )
andrewonlabaedc8332014-12-04 12:43:03 -0500965 return main.TRUE
966 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800967 main.log.info( "ONOS process was not running" )
andrewonlabaedc8332014-12-04 12:43:03 -0500968 return main.FALSE
969 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800970 main.log.error( self.name + ": EOF exception found" )
971 main.log.error( self.name + ": " + self.handle.before )
andrewonlabaedc8332014-12-04 12:43:03 -0500972 main.cleanup()
973 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800974 except Exception:
975 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabaedc8332014-12-04 12:43:03 -0500976 main.cleanup()
977 main.exit()
978
kelvin-onlabd3b64892015-01-20 13:26:24 -0800979 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800980 """
andrewonlabe8e56fd2014-10-09 17:12:44 -0400981 Calls the command: 'onos-kill [<node-ip>]'
982 "Remotely, and unceremoniously kills the ONOS instance running on
983 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -0800984 """
andrewonlabe8e56fd2014-10-09 17:12:44 -0400985 try:
kelvin8ec71442015-01-15 16:57:00 -0800986 self.handle.sendline( "" )
987 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800988 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800989 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -0400990 "\$",
991 "No\sroute\sto\shost",
992 "password:",
kelvin8ec71442015-01-15 16:57:00 -0800993 pexpect.TIMEOUT ], timeout=20 )
994
andrewonlabe8e56fd2014-10-09 17:12:44 -0400995 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800996 main.log.info(
997 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800998 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400999 return main.TRUE
1000 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001001 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001002 return main.FALSE
1003 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001004 main.log.info(
1005 "Passwordless login for host: " +
1006 str( nodeIp ) +
1007 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001008 return main.FALSE
1009 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001010 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001011 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001012
andrewonlabe8e56fd2014-10-09 17:12:44 -04001013 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001014 main.log.error( self.name + ": EOF exception found" )
1015 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001016 main.cleanup()
1017 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001018 except Exception:
1019 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001020 main.cleanup()
1021 main.exit()
1022
kelvin-onlabd3b64892015-01-20 13:26:24 -08001023 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001024 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001025 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001026 a cleaner environment.
1027
andrewonlab19fbdca2014-11-14 12:55:59 -05001028 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001029 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001030 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001031 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001032 try:
kelvin8ec71442015-01-15 16:57:00 -08001033 self.handle.sendline( "" )
1034 self.handle.expect( "\$" )
1035 self.handle.sendline( "onos-remove-raft-logs" )
1036 # Sometimes this command hangs
1037 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1038 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001039 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001040 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1041 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001042 if i == 1:
1043 return main.FALSE
shahshreya957feaa2015-03-23 16:08:29 -07001044 #self.handle.sendline( "" )
1045 #self.handle.expect( "\$" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001046 return main.TRUE
1047
1048 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001049 main.log.error( self.name + ": EOF exception found" )
1050 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -05001051 main.cleanup()
1052 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001053 except Exception:
1054 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001055 main.cleanup()
1056 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -05001057
kelvin-onlabd3b64892015-01-20 13:26:24 -08001058 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001059 """
1060 Calls the command 'onos-start-network [ <mininet-topo> ]
1061 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001062 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001063 cell."
andrewonlab94282092014-10-10 13:00:11 -04001064 * Specify mininet topology file name for mntopo
1065 * Topo files should be placed at:
1066 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001067
andrewonlab94282092014-10-10 13:00:11 -04001068 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001069 """
andrewonlab94282092014-10-10 13:00:11 -04001070 try:
1071 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001072 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001073 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001074
kelvin8ec71442015-01-15 16:57:00 -08001075 mntopo = str( mntopo )
1076 self.handle.sendline( "" )
1077 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -04001078
kelvin8ec71442015-01-15 16:57:00 -08001079 self.handle.sendline( "onos-start-network " + mntopo )
1080 self.handle.expect( "mininet>" )
1081 main.log.info( "Network started, entered mininet prompt" )
1082
1083 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001084
1085 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001086 main.log.error( self.name + ": EOF exception found" )
1087 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -04001088 main.cleanup()
1089 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001090 except Exception:
1091 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -04001092 main.cleanup()
1093 main.exit()
1094
Cameron Franke9c94fb02015-01-21 10:20:20 -08001095 def isup(self, node = "", timeout = 120):
kelvin8ec71442015-01-15 16:57:00 -08001096 """
1097 Run's onos-wait-for-start which only returns once ONOS is at run
Cameron Franke9c94fb02015-01-21 10:20:20 -08001098 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001099
Jon Hall7993bfc2014-10-09 16:30:14 -04001100 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001101 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001102 try:
Cameron Franke9c94fb02015-01-21 10:20:20 -08001103 self.handle.sendline("onos-wait-for-start " + node )
1104 self.handle.expect("onos-wait-for-start")
kelvin8ec71442015-01-15 16:57:00 -08001105 # NOTE: this timeout is arbitrary"
Cameron Franke9c94fb02015-01-21 10:20:20 -08001106 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001107 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001108 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001109 return main.TRUE
1110 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001111 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001112 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001113 main.log.error( "ONOS has not started yet" )
1114 self.handle.send( "\x03" ) # Control-C
1115 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001116 return main.FALSE
1117 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001118 main.log.error( self.name + ": EOF exception found" )
1119 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -04001120 main.cleanup()
1121 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001122 except Exception:
1123 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001124 main.cleanup()
1125 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001126
kelvin-onlabd3b64892015-01-20 13:26:24 -08001127 def pushTestIntentsShell(
1128 self,
1129 dpidSrc,
1130 dpidDst,
1131 numIntents,
1132 dirFile,
1133 onosIp,
1134 numMult="",
1135 appId="",
1136 report=True,
1137 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001138 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001139 Description:
kelvin8ec71442015-01-15 16:57:00 -08001140 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001141 better parallelize the results than the CLI
1142 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001143 * dpidSrc: specify source dpid
1144 * dpidDst: specify destination dpid
1145 * numIntents: specify number of intents to push
1146 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001147 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001148 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001149 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001150 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001151 """
1152 try:
1153 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001154 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001155 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001156 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001157 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001158 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001159
kelvin-onlabd3b64892015-01-20 13:26:24 -08001160 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1161 if not numMult:
1162 addIntents = addDpid + " " + str( numIntents )
1163 elif numMult:
1164 addIntents = addDpid + " " + str( numIntents ) + " " +\
1165 str( numMult )
1166 if appId:
1167 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001168 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001169 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001170
andrewonlabaedc8332014-12-04 12:43:03 -05001171 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001172 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001173 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001174 sendCmd = addApp + " &"
1175 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001176
kelvin-onlabd3b64892015-01-20 13:26:24 -08001177 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001178
1179 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001180 main.log.error( self.name + ": EOF exception found" )
1181 main.log.error( self.name + ": " + self.handle.before )
andrewonlabb66dfa12014-12-02 15:51:10 -05001182 main.cleanup()
1183 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001184 except Exception:
1185 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001186 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001187 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001188
kelvin-onlabd3b64892015-01-20 13:26:24 -08001189 def getTopology( self, topologyOutput ):
kelvin8ec71442015-01-15 16:57:00 -08001190 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001191 Definition:
1192 Loads a json topology output
1193 Return:
1194 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -08001195 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001196 import json
Jon Hall77f53ce2014-10-13 18:02:06 -04001197 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001198 # either onos:topology or 'topology' will work in CLI
1199 topology = json.loads(topologyOutput)
1200 print topology
Jon Hall77f53ce2014-10-13 18:02:06 -04001201 return topology
1202 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001203 main.log.error( self.name + ": EOF exception found" )
1204 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001205 main.cleanup()
1206 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001207 except Exception:
1208 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001209 main.cleanup()
1210 main.exit()
1211
kelvin-onlabd3b64892015-01-20 13:26:24 -08001212 def checkStatus(
1213 self,
1214 topologyResult,
1215 numoswitch,
1216 numolink,
1217 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001218 """
Jon Hallefbd9792015-03-05 16:11:36 -08001219 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001220 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001221 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08001222
Jon Hall77f53ce2014-10-13 18:02:06 -04001223 Params: ip = ip used for the onos cli
1224 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001225 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001226 logLevel = level to log to.
1227 Currently accepts 'info', 'warn' and 'report'
Jon Hall77f53ce2014-10-13 18:02:06 -04001228
1229
kelvin-onlabd3b64892015-01-20 13:26:24 -08001230 logLevel can
Jon Hall77f53ce2014-10-13 18:02:06 -04001231
Jon Hallefbd9792015-03-05 16:11:36 -08001232 Returns: main.TRUE if the number of switches and links are correct,
1233 main.FALSE if the number of switches and links is incorrect,
Jon Hall77f53ce2014-10-13 18:02:06 -04001234 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001235 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001236 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001237 topology = self.getTopology( topologyResult )
Jon Hall77f53ce2014-10-13 18:02:06 -04001238 if topology == {}:
1239 return main.ERROR
1240 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001241 # Is the number of switches is what we expected
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001242 devices = topology.get( 'deviceCount', False )
1243 links = topology.get( 'linkCount', False )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001244 if not devices or not links:
Jon Hall77f53ce2014-10-13 18:02:06 -04001245 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001246 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001247 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001248 linkCheck = ( int( links ) == int( numolink ) )
Jon Hallefbd9792015-03-05 16:11:36 -08001249 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08001250 # We expected the correct numbers
Jon Hall77f53ce2014-10-13 18:02:06 -04001251 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001252 + "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001253 result = main.TRUE
1254 else:
1255 output = output + \
Jon Hall274b6642015-02-17 11:57:17 -08001256 "The number of links and switches does not match " + \
1257 "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001258 result = main.FALSE
Jon Hallefbd9792015-03-05 16:11:36 -08001259 output = output + "\n ONOS sees %i devices" % int( devices )
1260 output = output + " (%i expected) " % int( numoswitch )
Jon Hall274b6642015-02-17 11:57:17 -08001261 output = output + "and %i links " % int( links )
1262 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001263 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001264 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001265 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001266 main.log.warn( output )
Jon Hall77f53ce2014-10-13 18:02:06 -04001267 else:
kelvin8ec71442015-01-15 16:57:00 -08001268 main.log.info( output )
1269 return result
Jon Hall77f53ce2014-10-13 18:02:06 -04001270 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001271 main.log.error( self.name + ": EOF exception found" )
1272 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001273 main.cleanup()
1274 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001275 except Exception:
1276 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001277 main.cleanup()
1278 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001279
kelvin-onlabd3b64892015-01-20 13:26:24 -08001280 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001281 """
andrewonlab970399c2014-11-07 13:09:32 -05001282 Capture all packet activity and store in specified
1283 directory/file
1284
1285 Required:
1286 * interface: interface to capture
1287 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001288 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001289 try:
1290 self.handle.sendline( "" )
1291 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001292
Jon Hallfebb1c72015-03-05 13:30:09 -08001293 self.handle.sendline( "tshark -i " + str( interface ) +
1294 " -t e -w " + str( dirFile ) + " &" )
1295 self.handle.sendline( "\r" )
1296 self.handle.expect( "Capturing on" )
1297 self.handle.sendline( "\r" )
1298 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001299
Jon Hallfebb1c72015-03-05 13:30:09 -08001300 main.log.info( "Tshark started capturing files on " +
1301 str( interface ) + " and saving to directory: " +
1302 str( dirFile ) )
1303 except pexpect.EOF:
1304 main.log.error( self.name + ": EOF exception found" )
1305 main.log.error( self.name + ": " + self.handle.before )
1306 main.cleanup()
1307 main.exit()
1308 except Exception:
1309 main.log.exception( self.name + ": Uncaught exception!" )
1310 main.cleanup()
1311 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001312
kelvin-onlabd3b64892015-01-20 13:26:24 -08001313 def runOnosTopoCfg( self, instanceName, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001314 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001315 On ONOS bench, run this command:
Jon Halle94919c2015-03-23 11:42:57 -07001316 {ONOS_HOME}/tools/test/bin/onos-topo-cfg $OC1 filename
kelvin-onlabd3b64892015-01-20 13:26:24 -08001317 which starts the rest and copies
1318 the json file to the onos instance
kelvin8ec71442015-01-15 16:57:00 -08001319 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001320 try:
kelvin8ec71442015-01-15 16:57:00 -08001321 self.handle.sendline( "" )
1322 self.handle.expect( "\$" )
Jon Halle94919c2015-03-23 11:42:57 -07001323 self.handle.sendline( "cd " + self.home + "/tools/test/bin" )
kelvin8ec71442015-01-15 16:57:00 -08001324 self.handle.expect( "/bin$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001325 cmd = "./onos-topo-cfg " + instanceName + " " + jsonFile
shahshreyae6c7cf42014-11-26 16:39:01 -08001326 print "cmd = ", cmd
kelvin8ec71442015-01-15 16:57:00 -08001327 self.handle.sendline( cmd )
1328 self.handle.expect( "\$" )
1329 self.handle.sendline( "cd ~" )
1330 self.handle.expect( "\$" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001331 return main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -08001332 except pexpect.EOF:
1333 main.log.error( self.name + ": EOF exception found" )
1334 main.log.error( self.name + ": " + self.handle.before )
1335 main.cleanup()
1336 main.exit()
1337 except Exception:
1338 main.log.exception( self.name + ": Uncaught exception!" )
1339 main.cleanup()
1340 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001341
jenkins1e99e7b2015-04-02 18:15:39 -07001342 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001343 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001344 Required:
kelvin8ec71442015-01-15 16:57:00 -08001345 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001346 * directory to store results
1347 Optional:
1348 * interface - default: eth0
jenkins1e99e7b2015-04-02 18:15:39 -07001349 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001350 Description:
1351 Uses tshark command to grep specific group of packets
1352 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001353 The timestamp is hardcoded to be in epoch
1354 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001355 try:
1356 self.handle.sendline( "" )
1357 self.handle.expect( "\$" )
1358 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001359 if grepOptions:
1360 grepStr = "grep "+str(grepOptions)
1361 else:
1362 grepStr = "grep"
1363
Jon Hallfebb1c72015-03-05 13:30:09 -08001364 self.handle.sendline(
1365 "tshark -i " +
1366 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001367 " -t e | " +
1368 grepStr + " --line-buffered \"" +
Jon Hallfebb1c72015-03-05 13:30:09 -08001369 str(grep) +
1370 "\" >" +
1371 directory +
1372 " &" )
1373 self.handle.sendline( "\r" )
1374 self.handle.expect( "Capturing on" )
1375 self.handle.sendline( "\r" )
1376 self.handle.expect( "\$" )
1377 except pexpect.EOF:
1378 main.log.error( self.name + ": EOF exception found" )
1379 main.log.error( self.name + ": " + self.handle.before )
1380 main.cleanup()
1381 main.exit()
1382 except Exception:
1383 main.log.exception( self.name + ": Uncaught exception!" )
1384 main.cleanup()
1385 main.exit()
1386
kelvin-onlabd3b64892015-01-20 13:26:24 -08001387 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001388 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001389 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001390 """
1391 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001392 try:
1393 self.execute( cmd="sudo rm /tmp/wireshark*" )
1394 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001395 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1396 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001397 self.handle.sendline( "" )
1398 main.log.info( "Tshark stopped" )
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()
1408
kelvin8ec71442015-01-15 16:57:00 -08001409 def ptpd( self, args ):
1410 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001411 Initiate ptp with user-specified args.
1412 Required:
1413 * args: specify string of args after command
1414 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001415 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001416 try:
kelvin8ec71442015-01-15 16:57:00 -08001417 self.handle.sendline( "sudo ptpd " + str( args ) )
1418 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001419 "Multiple",
1420 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001421 "\$" ] )
1422 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001423
andrewonlab0c38a4a2014-10-28 18:35:35 -04001424 if i == 0:
1425 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001426 main.log.info( "ptpd returned an error: " +
1427 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001428 return handle
1429 elif i == 1:
1430 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001431 main.log.error( "ptpd returned an error: " +
1432 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001433 return handle
1434 else:
1435 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001436
andrewonlab0c38a4a2014-10-28 18:35:35 -04001437 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001438 main.log.error( self.name + ": EOF exception found" )
1439 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001440 main.cleanup()
1441 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001442 except Exception:
1443 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001444 main.cleanup()
1445 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001446
kelvin-onlabd3b64892015-01-20 13:26:24 -08001447 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001448 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001449 """
1450 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001451 Current implementation of ONOS deletes its karaf
1452 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001453 you may want to use this function to capture
1454 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001455 Localtime will be attached to the filename
1456
1457 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001458 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001459 copy.
kelvin8ec71442015-01-15 16:57:00 -08001460 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001461 For copying multiple files, leave copyFileName
1462 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001463 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001464 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001465 ex ) /tmp/
1466 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001467 * copyFileName: If you want to rename the log
1468 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001469 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001470 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001471 try:
kelvin8ec71442015-01-15 16:57:00 -08001472 localtime = time.strftime( '%x %X' )
1473 localtime = localtime.replace( "/", "" )
1474 localtime = localtime.replace( " ", "_" )
1475 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001476 if destDir[ -1: ] != "/":
1477 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001478
kelvin-onlabd3b64892015-01-20 13:26:24 -08001479 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001480 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1481 str( destDir ) + str( copyFileName ) +
1482 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001483 self.handle.expect( "cp" )
1484 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001485 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001486 self.handle.sendline( "cp " + str( logToCopy ) +
1487 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001488 self.handle.expect( "cp" )
1489 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001490
kelvin8ec71442015-01-15 16:57:00 -08001491 return self.handle.before
1492
1493 except pexpect.EOF:
1494 main.log.error( "Copying files failed" )
1495 main.log.error( self.name + ": EOF exception found" )
1496 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001497 except Exception:
1498 main.log.exception( "Copying files failed" )
1499
kelvin-onlabd3b64892015-01-20 13:26:24 -08001500 def checkLogs( self, onosIp ):
kelvin8ec71442015-01-15 16:57:00 -08001501 """
Jon Hall94fd0472014-12-08 11:52:42 -08001502 runs onos-check-logs on the given onos node
1503 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001504 """
Jon Hall94fd0472014-12-08 11:52:42 -08001505 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001506 cmd = "onos-check-logs " + str( onosIp )
kelvin8ec71442015-01-15 16:57:00 -08001507 self.handle.sendline( cmd )
1508 self.handle.expect( cmd )
1509 self.handle.expect( "\$" )
Jon Hall94fd0472014-12-08 11:52:42 -08001510 response = self.handle.before
1511 return response
1512 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001513 main.log.error( "Lost ssh connection" )
1514 main.log.error( self.name + ": EOF exception found" )
1515 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001516 except Exception:
1517 main.log.exception( self.name + ": Uncaught exception!" )
1518 main.cleanup()
1519 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001520
kelvin-onlabd3b64892015-01-20 13:26:24 -08001521 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001522 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001523 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001524 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001525 try:
kelvin8ec71442015-01-15 16:57:00 -08001526 self.handle.sendline( "" )
1527 self.handle.expect( "\$" )
1528 self.handle.sendline( "onos-service " + str( node ) +
1529 " status" )
1530 i = self.handle.expect( [
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001531 "start/running",
1532 "stop/waiting",
kelvin8ec71442015-01-15 16:57:00 -08001533 pexpect.TIMEOUT ], timeout=120 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001534
1535 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001536 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001537 return main.TRUE
1538 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001539 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001540 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001541 main.cleanup()
1542 main.exit()
1543 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001544 main.log.error( self.name + ": EOF exception found" )
1545 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001546 main.cleanup()
1547 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001548 except Exception:
1549 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001550 main.cleanup()
1551 main.exit()
Jon Hall21270ac2015-02-16 17:59:55 -08001552
Jon Hall63604932015-02-26 17:09:50 -08001553 def setIpTables( self, ip, port='', action='add', packet_type='',
1554 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001555 """
Jon Hall21270ac2015-02-16 17:59:55 -08001556 Description:
1557 add or remove iptables rule to DROP (default) packets from
1558 specific IP and PORT
1559 Usage:
1560 * specify action ('add' or 'remove')
1561 when removing, pass in the same argument as you would add. It will
1562 delete that specific rule.
1563 * specify the ip to block
1564 * specify the destination port to block (defaults to all ports)
1565 * optional packet type to block (default tcp)
1566 * optional iptables rule (default DROP)
1567 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001568 * States boolean toggles adding all supported tcp states to the
1569 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001570 Returns:
1571 main.TRUE on success or
1572 main.FALSE if given invalid input or
1573 main.ERROR if there is an error in response from iptables
1574 WARNING:
1575 * This function uses root privilege iptables command which may result
1576 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001577 """
Jon Hall21270ac2015-02-16 17:59:55 -08001578 import time
1579
1580 # NOTE*********
1581 # The strict checking methods of this driver function is intentional
1582 # to discourage any misuse or error of iptables, which can cause
1583 # severe network errors
1584 # *************
1585
1586 # NOTE: Sleep needed to give some time for rule to be added and
1587 # registered to the instance. If you are calling this function
1588 # multiple times this sleep will prevent any errors.
1589 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001590 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001591 try:
1592 # input validation
1593 action_type = action.lower()
1594 rule = rule.upper()
1595 direction = direction.upper()
1596 if action_type != 'add' and action_type != 'remove':
1597 main.log.error( "Invalid action type. Use 'add' or "
1598 "'remove' table rule" )
1599 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1600 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1601 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1602 "'ACCEPT' or 'LOG' only." )
1603 if direction != 'INPUT' and direction != 'OUTPUT':
1604 # NOTE currently only supports rules INPUT and OUPTUT
1605 main.log.error( "Invalid rule. Valid directions are"
1606 " 'OUTPUT' or 'INPUT'" )
1607 return main.FALSE
1608 return main.FALSE
1609 return main.FALSE
1610 if action_type == 'add':
1611 # -A is the 'append' action of iptables
1612 actionFlag = '-A'
1613 elif action_type == 'remove':
1614 # -D is the 'delete' rule of iptables
1615 actionFlag = '-D'
1616 self.handle.sendline( "" )
1617 self.handle.expect( "\$" )
1618 cmd = "sudo iptables " + actionFlag + " " +\
1619 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001620 " -s " + str( ip )
Jon Hall63604932015-02-26 17:09:50 -08001621 # " -p " + str( packet_type ) +\
1622 if packet_type:
1623 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001624 if port:
1625 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001626 if states:
1627 cmd += " -m state --state="
1628 #FIXME- Allow user to configure which states to block
1629 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001630 cmd += " -j " + str( rule )
1631
1632 self.handle.sendline( cmd )
1633 self.handle.expect( "\$" )
1634 main.log.warn( self.handle.before )
1635
1636 info_string = "On " + str( self.name )
1637 info_string += " " + str( action_type )
1638 info_string += " iptable rule [ "
1639 info_string += " IP: " + str( ip )
1640 info_string += " Port: " + str( port )
1641 info_string += " Rule: " + str( rule )
1642 info_string += " Direction: " + str( direction ) + " ]"
1643 main.log.info( info_string )
1644 return main.TRUE
1645 except pexpect.TIMEOUT:
1646 main.log.exception( self.name + ": Timeout exception in "
1647 "setIpTables function" )
1648 return main.ERROR
1649 except pexpect.EOF:
1650 main.log.error( self.name + ": EOF exception found" )
1651 main.log.error( self.name + ": " + self.handle.before )
1652 main.cleanup()
1653 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001654 except Exception:
1655 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall21270ac2015-02-16 17:59:55 -08001656 main.cleanup()
1657 main.exit()
1658
Jon Hall0468b042015-02-19 19:08:21 -08001659 def detailed_status(self, log_filename):
Jon Hallefbd9792015-03-05 16:11:36 -08001660 """
Jon Hall0468b042015-02-19 19:08:21 -08001661 This method is used by STS to check the status of the controller
1662 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001663 """
Jon Hall0468b042015-02-19 19:08:21 -08001664 import re
1665 try:
1666 self.handle.sendline( "" )
1667 self.handle.expect( "\$" )
1668 self.handle.sendline( "cd " + self.home )
1669 self.handle.expect( "\$" )
1670 self.handle.sendline( "service onos status" )
1671 self.handle.expect( "\$" )
1672 response = self.handle.before
1673 if re.search( "onos start/running", response ):
1674 # onos start/running, process 10457
1675 return 'RUNNING'
1676 # FIXME: Implement this case
1677 # elif re.search( pattern, response ):
1678 # return 'STARTING'
1679 elif re.search( "onos stop/", response ):
1680 # onos stop/waiting
1681 # FIXME handle this differently?: onos stop/pre-stop
1682 return 'STOPPED'
1683 # FIXME: Implement this case
1684 # elif re.search( pattern, response ):
1685 # return 'FROZEN'
1686 else:
1687 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001688 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001689 main.log.warn( response )
1690 return 'ERROR', "Unknown response: %s" % response
1691 except pexpect.TIMEOUT:
1692 main.log.exception( self.name + ": Timeout exception in "
1693 "setIpTables function" )
1694 return 'ERROR', "Pexpect Timeout"
1695 except pexpect.EOF:
1696 main.log.error( self.name + ": EOF exception found" )
1697 main.log.error( self.name + ": " + self.handle.before )
1698 main.cleanup()
1699 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001700 except Exception:
1701 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall0468b042015-02-19 19:08:21 -08001702 main.cleanup()
1703 main.exit()
1704
andrew@onlab.us3b087132015-03-11 15:00:08 -07001705 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1706 '''
1707 Create/formats the LinkGraph.cfg file based on arguments
1708 -only creates a linear topology and connects islands
1709 -evenly distributes devices
1710 -must be called by ONOSbench
1711
1712 ONOSIpList - list of all of the node IPs to be used
1713
1714 deviceCount - number of switches to be assigned
1715 '''
1716 main.log.step("Creating link graph configuration file." )
1717 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
1718 tempFile = "/tmp/linkGraph.cfg"
1719
1720 linkGraph = open(tempFile, 'w+')
1721 linkGraph.write("# NullLinkProvider topology description (config file).\n")
1722 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
1723 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
1724
1725 clusterCount = len(ONOSIpList)
1726
1727 if type(deviceCount) is int or type(deviceCount) is str:
1728 deviceCount = int(deviceCount)
1729 switchList = [0]*(clusterCount+1)
1730 baselineSwitchCount = deviceCount/clusterCount
1731
1732 for node in range(1, clusterCount + 1):
1733 switchList[node] = baselineSwitchCount
1734
1735 for node in range(1, (deviceCount%clusterCount)+1):
1736 switchList[node] += 1
1737
1738 if type(deviceCount) is list:
1739 main.log.info("Using provided device distribution")
1740 switchList = [0]
1741 for i in deviceCount:
1742 switchList.append(int(i))
1743
1744 tempList = ['0']
1745 tempList.extend(ONOSIpList)
1746 ONOSIpList = tempList
1747
1748 myPort = 6
1749 lastSwitch = 0
1750 for node in range(1, clusterCount+1):
1751 if switchList[node] == 0:
1752 continue
1753
1754 linkGraph.write("graph " + ONOSIpList[node] + " {\n")
1755
1756 if node > 1:
1757 #connect to last device on previous node
1758 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
1759 linkGraph.write(line)
1760
1761 lastSwitch = 0
1762 for switch in range (0, switchList[node]-1):
1763 line = ""
1764 line = ("\t" + str(switch) + ":" + str(myPort))
1765 line += " -- "
1766 line += (str(switch+1) + ":" + str(myPort-1) + "\n")
1767 linkGraph.write(line)
1768 lastSwitch = switch+1
1769 lastIp = ONOSIpList[node]
1770
1771 #lastSwitch += 1
1772 if node < (clusterCount):
1773 #connect to first device on the next node
1774 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
1775 linkGraph.write(line)
1776
1777 linkGraph.write("}\n")
1778 linkGraph.close()
1779
1780 #SCP
1781 os.system( "scp " + tempFile + " admin@" + benchIp + ":" + linkGraphPath)
1782 main.log.info("linkGraph.cfg creation complete")
1783
cameron@onlab.us75900962015-03-30 13:22:49 -07001784 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001785
1786 '''
andrew@onlab.us3b087132015-03-11 15:00:08 -07001787 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
cameron@onlab.us75900962015-03-30 13:22:49 -07001788 deviceCount = number of switches to distribute, or list of values to use as custom distribution
1789 numPorts = number of ports per device. Defaults to 10 both in this function and in ONOS. Optional arg
andrew@onlab.us3b087132015-03-11 15:00:08 -07001790 '''
1791
cameron@onlab.us75900962015-03-30 13:22:49 -07001792 main.log.step("Configuring Null Device Provider" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07001793 clusterCount = len(ONOSIpList)
1794
cameron@onlab.us75900962015-03-30 13:22:49 -07001795 try:
1796
1797 if type(deviceCount) is int or type(deviceCount) is str:
1798 main.log.step("Creating device distribution")
1799 deviceCount = int(deviceCount)
1800 switchList = [0]*(clusterCount+1)
1801 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001802
cameron@onlab.us75900962015-03-30 13:22:49 -07001803 for node in range(1, clusterCount + 1):
1804 switchList[node] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001805
cameron@onlab.us75900962015-03-30 13:22:49 -07001806 for node in range(1, (deviceCount%clusterCount)+1):
1807 switchList[node] += 1
1808
1809 if type(deviceCount) is list:
1810 main.log.info("Using provided device distribution")
1811
1812 if len(deviceCount) == clusterCount:
1813 switchList = ['0']
1814 switchList.extend(deviceCount)
1815
1816 if len(deviceCount) == (clusterCount + 1):
1817 if deviceCount[0] == '0' or deviceCount[0] == 0:
1818 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001819
cameron@onlab.us75900962015-03-30 13:22:49 -07001820 assert len(switchList) == (clusterCount + 1)
1821
1822 except AssertionError:
1823 main.log.error( "Bad device/Ip list match")
1824 except TypeError:
1825 main.log.exception( self.name + ": Object not as expected" )
1826 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07001827 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001828 main.log.exception( self.name + ": Uncaught exception!" )
1829 main.cleanup()
1830 main.exit()
1831
andrew@onlab.us3b087132015-03-11 15:00:08 -07001832
1833 ONOSIp = [0]
1834 ONOSIp.extend(ONOSIpList)
1835
1836 devicesString = "devConfigs = "
1837 for node in range(1, len(ONOSIp)):
1838 devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
1839 if node < clusterCount:
1840 devicesString += (",")
cameron@onlab.us75900962015-03-30 13:22:49 -07001841
1842 try:
1843 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
1844 self.handle.expect(":~")
1845 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) )
1846 self.handle.expect(":~")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001847
cameron@onlab.us75900962015-03-30 13:22:49 -07001848 for i in range(10):
1849 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider")
1850 self.handle.expect(":~")
1851 verification = self.handle.before
1852 if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification:
1853 break
1854 else:
1855 time.sleep(1)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001856
cameron@onlab.us2cc8bf12015-04-02 14:12:30 -07001857 assert ("value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification
cameron@onlab.us75900962015-03-30 13:22:49 -07001858
1859 except AssertionError:
1860 main.log.error("Incorrect Config settings: " + verification)
Jon Hall77ba41c2015-04-06 10:25:40 -07001861 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001862 main.log.exception( self.name + ": Uncaught exception!" )
1863 main.cleanup()
1864 main.exit()
1865
cameron@onlab.usc80a8c82015-04-15 14:57:37 -07001866 def configNullLink( self,fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001867 '''
cameron@onlab.us75900962015-03-30 13:22:49 -07001868 fileName default is currently the same as the default on ONOS, specify alternate file if
1869 you want to use a different topology file than linkGraph.cfg
andrew@onlab.us3b087132015-03-11 15:00:08 -07001870 '''
1871
andrew@onlab.us3b087132015-03-11 15:00:08 -07001872
cameron@onlab.us75900962015-03-30 13:22:49 -07001873 try:
1874 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str(eventRate))
1875 self.handle.expect(":~")
1876 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
1877 self.handle.expect(":~")
1878
1879 for i in range(10):
1880 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider")
1881 self.handle.expect(":~")
1882 verification = self.handle.before
1883 if (" value=" + str(eventRate)) in verification and (" value=" + fileName) in verification:
1884 break
1885 else:
1886 time.sleep(1)
1887
1888 assert ("value=" + str(eventRate)) in verification and (" value=" + fileName) in verification
1889
1890 except pexpect.EOF:
1891 main.log.error( self.name + ": EOF exception found" )
1892 main.log.error( self.name + ": " + self.handle.before )
1893 main.cleanup()
1894 main.exit()
cameron@onlab.us75900962015-03-30 13:22:49 -07001895 except AssertionError:
1896 main.log.info("Settings did not post to ONOS")
1897 main.log.error(varification)
Jon Hall77ba41c2015-04-06 10:25:40 -07001898 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001899 main.log.exception( self.name + ": Uncaught exception!" )
1900 main.log.error(varification)
1901 main.cleanup()
1902 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07001903