blob: 6eaeb153a265d50481a51829206691f9a51bfb9d [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:
93 main.log.exception( "Exception in discconect of " + self.name )
94 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:
kelvin8ec71442015-01-15 16:57:00 -0800511 for line in lines[ 2:-1 ]:
512 # Bracket replacement is for Wiki-compliant
513 # formatting. '<' or '>' are interpreted
514 # as xml specific tags that cause errors
515 line = line.replace( "<", "[" )
516 line = line.replace( ">", "]" )
517 main.log.report( "\t" + line )
518 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400519 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800520 main.log.error( self.name + ": EOF exception found" )
521 main.log.error( self.name + ": " + self.handle.before )
Jon Hall45ec0922014-10-10 19:33:49 -0400522 main.cleanup()
523 main.exit()
Jon Hall368769f2014-11-19 15:43:35 -0800524 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800525 main.log.error( self.name + ": TIMEOUT exception found" )
526 main.log.error( self.name + ": " + self.handle.before )
Jon Hall368769f2014-11-19 15:43:35 -0800527 main.cleanup()
528 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800529 except Exception:
530 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall45ec0922014-10-10 19:33:49 -0400531 main.cleanup()
532 main.exit()
533
kelvin-onlabd3b64892015-01-20 13:26:24 -0800534 def createCellFile( self, benchIp, fileName, mnIpAddrs,
cameron@onlab.us75900962015-03-30 13:22:49 -0700535 appString, *onosIpAddrs ):
kelvin8ec71442015-01-15 16:57:00 -0800536 """
andrewonlab94282092014-10-10 13:00:11 -0400537 Creates a cell file based on arguments
538 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800539 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400540 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800541 * File name of the cell file ( fileName )
542 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800543 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400544 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800545 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400546 - Must be passed in as last arguments
kelvin8ec71442015-01-15 16:57:00 -0800547
andrewonlab94282092014-10-10 13:00:11 -0400548 NOTE: Assumes cells are located at:
549 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800550 """
551 # Variable initialization
kelvin-onlabd3b64892015-01-20 13:26:24 -0800552 cellDirectory = self.home + "/tools/test/cells/"
kelvin8ec71442015-01-15 16:57:00 -0800553 # We want to create the cell file in the dependencies directory
554 # of TestON first, then copy over to ONOS bench
kelvin-onlabd3b64892015-01-20 13:26:24 -0800555 tempDirectory = "/tmp/"
kelvin8ec71442015-01-15 16:57:00 -0800556 # Create the cell file in the directory for writing ( w+ )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800557 cellFile = open( tempDirectory + fileName, 'w+' )
kelvin8ec71442015-01-15 16:57:00 -0800558
cameron@onlab.us75900962015-03-30 13:22:49 -0700559 # App string is hardcoded environment variables
kelvin8ec71442015-01-15 16:57:00 -0800560 # That you may wish to use by default on startup.
cameron@onlab.us75900962015-03-30 13:22:49 -0700561 # Note that you may not want certain apps listed
kelvin8ec71442015-01-15 16:57:00 -0800562 # on here.
cameron@onlab.us75900962015-03-30 13:22:49 -0700563 appString = "export ONOS_APPS=" + appString
kelvin-onlabd3b64892015-01-20 13:26:24 -0800564 mnString = "export OCN="
565 onosString = "export OC"
566 tempCount = 1
kelvin8ec71442015-01-15 16:57:00 -0800567
kelvin-onlabd3b64892015-01-20 13:26:24 -0800568 # Create ONOSNIC ip address prefix
569 tempOnosIp = onosIpAddrs[ 0 ]
570 tempList = []
571 tempList = tempOnosIp.split( "." )
kelvin8ec71442015-01-15 16:57:00 -0800572 # Omit last element of list to format for NIC
kelvin-onlabd3b64892015-01-20 13:26:24 -0800573 tempList = tempList[ :-1 ]
kelvin8ec71442015-01-15 16:57:00 -0800574 # Structure the nic string ip
kelvin-onlabd3b64892015-01-20 13:26:24 -0800575 nicAddr = ".".join( tempList ) + ".*"
576 onosNicString = "export ONOS_NIC=" + nicAddr
andrewonlab94282092014-10-10 13:00:11 -0400577
578 try:
kelvin8ec71442015-01-15 16:57:00 -0800579 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800580 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400581
kelvin-onlabd3b64892015-01-20 13:26:24 -0800582 for arg in onosIpAddrs:
583 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800584 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400585 # export OC1="10.128.20.11"
586 # export OC2="10.128.20.12"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800587 cellFile.write( onosString + str( tempCount ) +
588 "=" + "\"" + arg + "\"" + "\n" )
589 tempCount = tempCount + 1
kelvin8ec71442015-01-15 16:57:00 -0800590
kelvin-onlabd3b64892015-01-20 13:26:24 -0800591 cellFile.write( mnString + "\"" + mnIpAddrs + "\"" + "\n" )
cameron@onlab.us75900962015-03-30 13:22:49 -0700592 cellFile.write( appString + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800593 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400594
kelvin8ec71442015-01-15 16:57:00 -0800595 # We use os.system to send the command to TestON cluster
596 # to account for the case in which TestON is not located
597 # on the same cluster as the ONOS bench
598 # Note that even if TestON is located on the same cluster
599 # as ONOS bench, you must setup passwordless ssh
600 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800601 os.system( "scp " + tempDirectory + fileName +
602 " admin@" + benchIp + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400603
andrewonlab2a6c9342014-10-16 13:40:15 -0400604 return main.TRUE
605
andrewonlab94282092014-10-10 13:00:11 -0400606 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800607 main.log.error( self.name + ": EOF exception found" )
608 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -0400609 main.cleanup()
610 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800611 except Exception:
612 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -0400613 main.cleanup()
614 main.exit()
615
kelvin-onlabd3b64892015-01-20 13:26:24 -0800616 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800617 """
andrewonlab95ca1462014-10-09 14:04:24 -0400618 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800619 """
andrewonlab95ca1462014-10-09 14:04:24 -0400620 try:
621 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800622 main.log.error( "Must define cellname" )
andrewonlab95ca1462014-10-09 14:04:24 -0400623 main.cleanup()
624 main.exit()
625 else:
kelvin8ec71442015-01-15 16:57:00 -0800626 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800627 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800628 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400629 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800630 self.handle.expect(str(cellname))
kelvin-onlabd3b64892015-01-20 13:26:24 -0800631 handleBefore = self.handle.before
632 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800633 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800634 self.handle.sendline("")
635 self.handle.expect("\$")
kelvin-onlabd3b64892015-01-20 13:26:24 -0800636 handleMore = self.handle.before
andrewonlab95ca1462014-10-09 14:04:24 -0400637
kelvin-onlabd3b64892015-01-20 13:26:24 -0800638 main.log.info( "Cell call returned: " + handleBefore +
639 handleAfter + handleMore )
andrewonlab95ca1462014-10-09 14:04:24 -0400640
641 return main.TRUE
642
643 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800644 main.log.error( self.name + ": EOF exception found" )
645 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ca1462014-10-09 14:04:24 -0400646 main.cleanup()
647 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800648 except Exception:
649 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ca1462014-10-09 14:04:24 -0400650 main.cleanup()
651 main.exit()
652
kelvin-onlabd3b64892015-01-20 13:26:24 -0800653 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800654 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400655 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800656 """
657 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400658
andrewonlabc03bf6c2014-10-09 14:56:18 -0400659 try:
kelvin8ec71442015-01-15 16:57:00 -0800660 # Clean handle by sending empty and expecting $
661 self.handle.sendline( "" )
662 self.handle.expect( "\$" )
663 self.handle.sendline( "onos-verify-cell" )
664 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800665 handleBefore = self.handle.before
666 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800667 # Get the rest of the handle
668 self.handle.sendline( "" )
669 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800670 handleMore = self.handle.before
andrewonlabc03bf6c2014-10-09 14:56:18 -0400671
kelvin-onlabd3b64892015-01-20 13:26:24 -0800672 main.log.info( "Verify cell returned: " + handleBefore +
673 handleAfter + handleMore )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400674
675 return main.TRUE
Jon Halla5cb6172015-02-23 09:28:28 -0800676 except pexpect.ExceptionPexpect as e:
677 main.log.error( self.name + ": Pexpect exception found of type " +
678 str( type( e ) ) )
679 main.log.error ( e.get_trace() )
kelvin8ec71442015-01-15 16:57:00 -0800680 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400681 main.cleanup()
682 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800683 except Exception:
684 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400685 main.cleanup()
686 main.exit()
687
andrew@onlab.usc169e432015-04-02 17:21:16 -0400688 def onosCfgSet( self, ONOSIp, configName, configParam ):
689 """
690 Uses 'onos <node-ip> cfg set' to change a parameter value of an
691 application.
692
693 ex)
694 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
695
696 ONOSIp = '10.0.0.1'
697 configName = 'org.onosproject.myapp'
698 configParam = 'appSetting 1'
699
700 """
701 try:
702 cfgStr = ( "onos "+str(ONOSIp)+" cfg set "+
703 str(configName) + " " +
704 str(configParam)
705 )
706
707 self.handle.sendline( "" )
708 self.handle.expect( "\$" )
709 self.handle.sendline( cfgStr )
710 self.handle.expect( "\$" )
711
712 # TODO: Add meaningful assertion
713
714 return main.TRUE
715
716 except pexpect.ExceptionPexpect as e:
717 main.log.error( self.name + ": Pexpect exception found of type " +
718 str( type( e ) ) )
719 main.log.error ( e.get_trace() )
720 main.log.error( self.name + ": " + self.handle.before )
721 main.cleanup()
722 main.exit()
723 except Exception:
724 main.log.exception( self.name + ": Uncaught exception!" )
725 main.cleanup()
726 main.exit()
727
kelvin-onlabd3b64892015-01-20 13:26:24 -0800728 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800729 """
andrewonlab05e362f2014-10-10 00:40:57 -0400730 Uses 'onos' command to send various ONOS CLI arguments.
731 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800732 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400733 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800734
735 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400736 CLI commands for ONOS. Try to use this function first
737 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800738 function.
739 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400740 by starting onos, and typing in 'onos' to enter the
741 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800742 available commands.
743 """
andrewonlab05e362f2014-10-10 00:40:57 -0400744 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800745 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800746 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400747 return main.FALSE
748 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800749 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400750 return main.FALSE
751
kelvin8ec71442015-01-15 16:57:00 -0800752 cmdstr = str( cmdstr )
753 self.handle.sendline( "" )
754 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400755
kelvin-onlabd3b64892015-01-20 13:26:24 -0800756 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800757 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400758
kelvin-onlabd3b64892015-01-20 13:26:24 -0800759 handleBefore = self.handle.before
Shreya Shaha73aaad2014-10-27 18:03:09 -0400760 print "handle_before = ", self.handle.before
kelvin-onlabd3b64892015-01-20 13:26:24 -0800761 # handleAfter = str( self.handle.after )
Jon Hall47a93fb2015-01-06 16:46:06 -0800762
kelvin8ec71442015-01-15 16:57:00 -0800763 # self.handle.sendline( "" )
764 # self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800765 # handleMore = str( self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400766
kelvin8ec71442015-01-15 16:57:00 -0800767 main.log.info( "Command sent successfully" )
andrewonlab05e362f2014-10-10 00:40:57 -0400768
kelvin8ec71442015-01-15 16:57:00 -0800769 # Obtain return handle that consists of result from
770 # the onos command. The string may need to be
771 # configured further.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800772 # returnString = handleBefore + handleAfter
773 returnString = handleBefore
774 print "return_string = ", returnString
775 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400776
777 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800778 main.log.error( self.name + ": EOF exception found" )
779 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400780 main.cleanup()
781 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800782 except Exception:
783 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab05e362f2014-10-10 00:40:57 -0400784 main.cleanup()
785 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400786
kelvin-onlabd3b64892015-01-20 13:26:24 -0800787 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800788 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400789 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800790 If -f option is provided, it also forces an uninstall.
791 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400792 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800793 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400794 files to certain onos nodes
795
796 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800797 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400798 try:
andrewonlab114768a2014-11-14 12:44:44 -0500799 if options:
kelvin8ec71442015-01-15 16:57:00 -0800800 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500801 else:
kelvin8ec71442015-01-15 16:57:00 -0800802 self.handle.sendline( "onos-install " + node )
803 self.handle.expect( "onos-install " )
804 # NOTE: this timeout may need to change depending on the network
805 # and size of ONOS
806 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800807 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800808 "ONOS\sis\salready\sinstalled",
809 pexpect.TIMEOUT ], timeout=60 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400810
Jon Hall7993bfc2014-10-09 16:30:14 -0400811 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800812 main.log.warn( "Network is unreachable" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400813 return main.FALSE
814 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800815 main.log.info(
816 "ONOS was installed on " +
817 node +
818 " and started" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400819 return main.TRUE
andrewonlabd9a73a72014-11-14 17:28:21 -0500820 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800821 main.log.info( "ONOS is already installed on " + node )
andrewonlabd9a73a72014-11-14 17:28:21 -0500822 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800823 elif i == 3:
824 main.log.info(
825 "Installation of ONOS on " +
826 node +
827 " timed out" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400828 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400829
830 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800831 main.log.error( self.name + ": EOF exception found" )
832 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400833 main.cleanup()
834 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800835 except Exception:
836 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400837 main.cleanup()
838 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400839
kelvin-onlabd3b64892015-01-20 13:26:24 -0800840 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800841 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400842 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400843 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800844 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400845 try:
kelvin8ec71442015-01-15 16:57:00 -0800846 self.handle.sendline( "" )
847 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800848 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800849 " start" )
850 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -0400851 "Job\sis\salready\srunning",
852 "start/running",
853 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800854 pexpect.TIMEOUT ], timeout=120 )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400855
856 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800857 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400858 return main.TRUE
859 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800860 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400861 return main.TRUE
862 else:
kelvin8ec71442015-01-15 16:57:00 -0800863 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400864 main.cleanup()
865 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -0400866 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800867 main.log.error( self.name + ": EOF exception found" )
868 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400869 main.cleanup()
870 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800871 except Exception:
872 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400873 main.cleanup()
874 main.exit()
875
kelvin-onlabd3b64892015-01-20 13:26:24 -0800876 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800877 """
andrewonlab2b30bd32014-10-09 16:48:55 -0400878 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400879 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800880 """
andrewonlab2b30bd32014-10-09 16:48:55 -0400881 try:
kelvin8ec71442015-01-15 16:57:00 -0800882 self.handle.sendline( "" )
883 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800884 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800885 " stop" )
886 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -0400887 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -0700888 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -0400889 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800890 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2b30bd32014-10-09 16:48:55 -0400891
892 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800893 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400894 return main.TRUE
895 elif i == 1:
Jon Hall65844a32015-03-09 19:09:37 -0700896 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800897 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -0400898 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700899 elif i == 2:
900 main.log.warn( "ONOS wasn't running" )
901 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -0400902 else:
kelvin8ec71442015-01-15 16:57:00 -0800903 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400904 return main.FALSE
905
906 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800907 main.log.error( self.name + ": EOF exception found" )
908 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -0400909 main.cleanup()
910 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800911 except Exception:
912 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400913 main.cleanup()
914 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800915
kelvin-onlabd3b64892015-01-20 13:26:24 -0800916 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -0800917 """
andrewonlabc8d47972014-10-09 16:52:36 -0400918 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -0800919 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -0400920 if needed
kelvin8ec71442015-01-15 16:57:00 -0800921 """
andrewonlabc8d47972014-10-09 16:52:36 -0400922 try:
kelvin8ec71442015-01-15 16:57:00 -0800923 self.handle.sendline( "" )
924 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800925 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800926 self.handle.expect( "\$" )
andrewonlabc8d47972014-10-09 16:52:36 -0400927
kelvin-onlabd3b64892015-01-20 13:26:24 -0800928 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
andrewonlab9dfd2082014-11-13 17:44:03 -0500929
kelvin8ec71442015-01-15 16:57:00 -0800930 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -0400931 return main.TRUE
932
933 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800934 main.log.error( self.name + ": EOF exception found" )
935 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -0400936 main.cleanup()
937 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800938 except Exception:
939 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc8d47972014-10-09 16:52:36 -0400940 main.cleanup()
941 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -0400942
kelvin-onlabd3b64892015-01-20 13:26:24 -0800943 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800944 """
andrewonlabaedc8332014-12-04 12:43:03 -0500945 Issues the command 'onos-die <node-ip>'
946 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -0800947 """
andrewonlabaedc8332014-12-04 12:43:03 -0500948 try:
kelvin8ec71442015-01-15 16:57:00 -0800949 self.handle.sendline( "" )
950 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800951 cmdStr = "onos-kill " + str( nodeIp )
952 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -0800953 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -0500954 "Killing\sONOS",
955 "ONOS\sprocess\sis\snot\srunning",
kelvin8ec71442015-01-15 16:57:00 -0800956 pexpect.TIMEOUT ], timeout=20 )
andrewonlabaedc8332014-12-04 12:43:03 -0500957 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800958 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800959 " was killed and stopped" )
andrewonlabaedc8332014-12-04 12:43:03 -0500960 return main.TRUE
961 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800962 main.log.info( "ONOS process was not running" )
andrewonlabaedc8332014-12-04 12:43:03 -0500963 return main.FALSE
964 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800965 main.log.error( self.name + ": EOF exception found" )
966 main.log.error( self.name + ": " + self.handle.before )
andrewonlabaedc8332014-12-04 12:43:03 -0500967 main.cleanup()
968 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800969 except Exception:
970 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabaedc8332014-12-04 12:43:03 -0500971 main.cleanup()
972 main.exit()
973
kelvin-onlabd3b64892015-01-20 13:26:24 -0800974 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800975 """
andrewonlabe8e56fd2014-10-09 17:12:44 -0400976 Calls the command: 'onos-kill [<node-ip>]'
977 "Remotely, and unceremoniously kills the ONOS instance running on
978 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -0800979 """
andrewonlabe8e56fd2014-10-09 17:12:44 -0400980 try:
kelvin8ec71442015-01-15 16:57:00 -0800981 self.handle.sendline( "" )
982 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800983 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800984 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -0400985 "\$",
986 "No\sroute\sto\shost",
987 "password:",
kelvin8ec71442015-01-15 16:57:00 -0800988 pexpect.TIMEOUT ], timeout=20 )
989
andrewonlabe8e56fd2014-10-09 17:12:44 -0400990 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800991 main.log.info(
992 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800993 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400994 return main.TRUE
995 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800996 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400997 return main.FALSE
998 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800999 main.log.info(
1000 "Passwordless login for host: " +
1001 str( nodeIp ) +
1002 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001003 return main.FALSE
1004 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001005 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001006 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001007
andrewonlabe8e56fd2014-10-09 17:12:44 -04001008 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001009 main.log.error( self.name + ": EOF exception found" )
1010 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001011 main.cleanup()
1012 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001013 except Exception:
1014 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001015 main.cleanup()
1016 main.exit()
1017
kelvin-onlabd3b64892015-01-20 13:26:24 -08001018 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001019 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001020 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001021 a cleaner environment.
1022
andrewonlab19fbdca2014-11-14 12:55:59 -05001023 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001024 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001025 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001026 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001027 try:
kelvin8ec71442015-01-15 16:57:00 -08001028 self.handle.sendline( "" )
1029 self.handle.expect( "\$" )
1030 self.handle.sendline( "onos-remove-raft-logs" )
1031 # Sometimes this command hangs
1032 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1033 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001034 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001035 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1036 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001037 if i == 1:
1038 return main.FALSE
shahshreya957feaa2015-03-23 16:08:29 -07001039 #self.handle.sendline( "" )
1040 #self.handle.expect( "\$" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001041 return main.TRUE
1042
1043 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001044 main.log.error( self.name + ": EOF exception found" )
1045 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -05001046 main.cleanup()
1047 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001048 except Exception:
1049 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001050 main.cleanup()
1051 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -05001052
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001054 """
1055 Calls the command 'onos-start-network [ <mininet-topo> ]
1056 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001057 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001058 cell."
andrewonlab94282092014-10-10 13:00:11 -04001059 * Specify mininet topology file name for mntopo
1060 * Topo files should be placed at:
1061 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001062
andrewonlab94282092014-10-10 13:00:11 -04001063 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001064 """
andrewonlab94282092014-10-10 13:00:11 -04001065 try:
1066 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001067 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001068 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001069
kelvin8ec71442015-01-15 16:57:00 -08001070 mntopo = str( mntopo )
1071 self.handle.sendline( "" )
1072 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -04001073
kelvin8ec71442015-01-15 16:57:00 -08001074 self.handle.sendline( "onos-start-network " + mntopo )
1075 self.handle.expect( "mininet>" )
1076 main.log.info( "Network started, entered mininet prompt" )
1077
1078 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001079
1080 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001081 main.log.error( self.name + ": EOF exception found" )
1082 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -04001083 main.cleanup()
1084 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001085 except Exception:
1086 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -04001087 main.cleanup()
1088 main.exit()
1089
Cameron Franke9c94fb02015-01-21 10:20:20 -08001090 def isup(self, node = "", timeout = 120):
kelvin8ec71442015-01-15 16:57:00 -08001091 """
1092 Run's onos-wait-for-start which only returns once ONOS is at run
Cameron Franke9c94fb02015-01-21 10:20:20 -08001093 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001094
Jon Hall7993bfc2014-10-09 16:30:14 -04001095 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001096 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001097 try:
Cameron Franke9c94fb02015-01-21 10:20:20 -08001098 self.handle.sendline("onos-wait-for-start " + node )
1099 self.handle.expect("onos-wait-for-start")
kelvin8ec71442015-01-15 16:57:00 -08001100 # NOTE: this timeout is arbitrary"
Cameron Franke9c94fb02015-01-21 10:20:20 -08001101 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001102 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001103 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001104 return main.TRUE
1105 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001106 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001107 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001108 main.log.error( "ONOS has not started yet" )
1109 self.handle.send( "\x03" ) # Control-C
1110 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001111 return main.FALSE
1112 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001113 main.log.error( self.name + ": EOF exception found" )
1114 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -04001115 main.cleanup()
1116 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001117 except Exception:
1118 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001119 main.cleanup()
1120 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001121
kelvin-onlabd3b64892015-01-20 13:26:24 -08001122 def pushTestIntentsShell(
1123 self,
1124 dpidSrc,
1125 dpidDst,
1126 numIntents,
1127 dirFile,
1128 onosIp,
1129 numMult="",
1130 appId="",
1131 report=True,
1132 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001133 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001134 Description:
kelvin8ec71442015-01-15 16:57:00 -08001135 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001136 better parallelize the results than the CLI
1137 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001138 * dpidSrc: specify source dpid
1139 * dpidDst: specify destination dpid
1140 * numIntents: specify number of intents to push
1141 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001142 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001143 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001144 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001145 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001146 """
1147 try:
1148 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001149 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001150 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001151 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001152 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001153 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001154
kelvin-onlabd3b64892015-01-20 13:26:24 -08001155 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1156 if not numMult:
1157 addIntents = addDpid + " " + str( numIntents )
1158 elif numMult:
1159 addIntents = addDpid + " " + str( numIntents ) + " " +\
1160 str( numMult )
1161 if appId:
1162 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001163 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001164 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001165
andrewonlabaedc8332014-12-04 12:43:03 -05001166 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001167 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001168 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001169 sendCmd = addApp + " &"
1170 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001171
kelvin-onlabd3b64892015-01-20 13:26:24 -08001172 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001173
1174 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001175 main.log.error( self.name + ": EOF exception found" )
1176 main.log.error( self.name + ": " + self.handle.before )
andrewonlabb66dfa12014-12-02 15:51:10 -05001177 main.cleanup()
1178 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001179 except Exception:
1180 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001181 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001182 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001183
kelvin-onlabd3b64892015-01-20 13:26:24 -08001184 def getTopology( self, topologyOutput ):
kelvin8ec71442015-01-15 16:57:00 -08001185 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001186 Definition:
1187 Loads a json topology output
1188 Return:
1189 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -08001190 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001191 import json
Jon Hall77f53ce2014-10-13 18:02:06 -04001192 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001193 # either onos:topology or 'topology' will work in CLI
1194 topology = json.loads(topologyOutput)
1195 print topology
Jon Hall77f53ce2014-10-13 18:02:06 -04001196 return topology
1197 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001198 main.log.error( self.name + ": EOF exception found" )
1199 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001200 main.cleanup()
1201 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001202 except Exception:
1203 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001204 main.cleanup()
1205 main.exit()
1206
kelvin-onlabd3b64892015-01-20 13:26:24 -08001207 def checkStatus(
1208 self,
1209 topologyResult,
1210 numoswitch,
1211 numolink,
1212 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001213 """
Jon Hallefbd9792015-03-05 16:11:36 -08001214 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001215 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001216 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08001217
Jon Hall77f53ce2014-10-13 18:02:06 -04001218 Params: ip = ip used for the onos cli
1219 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001220 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001221 logLevel = level to log to.
1222 Currently accepts 'info', 'warn' and 'report'
Jon Hall77f53ce2014-10-13 18:02:06 -04001223
1224
kelvin-onlabd3b64892015-01-20 13:26:24 -08001225 logLevel can
Jon Hall77f53ce2014-10-13 18:02:06 -04001226
Jon Hallefbd9792015-03-05 16:11:36 -08001227 Returns: main.TRUE if the number of switches and links are correct,
1228 main.FALSE if the number of switches and links is incorrect,
Jon Hall77f53ce2014-10-13 18:02:06 -04001229 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001230 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001231 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001232 topology = self.getTopology( topologyResult )
Jon Hall77f53ce2014-10-13 18:02:06 -04001233 if topology == {}:
1234 return main.ERROR
1235 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001236 # Is the number of switches is what we expected
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001237 devices = topology.get( 'deviceCount', False )
1238 links = topology.get( 'linkCount', False )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001239 if not devices or not links:
Jon Hall77f53ce2014-10-13 18:02:06 -04001240 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001241 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001242 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001243 linkCheck = ( int( links ) == int( numolink ) )
Jon Hallefbd9792015-03-05 16:11:36 -08001244 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08001245 # We expected the correct numbers
Jon Hall77f53ce2014-10-13 18:02:06 -04001246 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001247 + "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001248 result = main.TRUE
1249 else:
1250 output = output + \
Jon Hall274b6642015-02-17 11:57:17 -08001251 "The number of links and switches does not match " + \
1252 "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001253 result = main.FALSE
Jon Hallefbd9792015-03-05 16:11:36 -08001254 output = output + "\n ONOS sees %i devices" % int( devices )
1255 output = output + " (%i expected) " % int( numoswitch )
Jon Hall274b6642015-02-17 11:57:17 -08001256 output = output + "and %i links " % int( links )
1257 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001258 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001259 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001260 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001261 main.log.warn( output )
Jon Hall77f53ce2014-10-13 18:02:06 -04001262 else:
kelvin8ec71442015-01-15 16:57:00 -08001263 main.log.info( output )
1264 return result
Jon Hall77f53ce2014-10-13 18:02:06 -04001265 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001266 main.log.error( self.name + ": EOF exception found" )
1267 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001268 main.cleanup()
1269 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001270 except Exception:
1271 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001272 main.cleanup()
1273 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001274
kelvin-onlabd3b64892015-01-20 13:26:24 -08001275 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001276 """
andrewonlab970399c2014-11-07 13:09:32 -05001277 Capture all packet activity and store in specified
1278 directory/file
1279
1280 Required:
1281 * interface: interface to capture
1282 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001283 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001284 try:
1285 self.handle.sendline( "" )
1286 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001287
Jon Hallfebb1c72015-03-05 13:30:09 -08001288 self.handle.sendline( "tshark -i " + str( interface ) +
1289 " -t e -w " + str( dirFile ) + " &" )
1290 self.handle.sendline( "\r" )
1291 self.handle.expect( "Capturing on" )
1292 self.handle.sendline( "\r" )
1293 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001294
Jon Hallfebb1c72015-03-05 13:30:09 -08001295 main.log.info( "Tshark started capturing files on " +
1296 str( interface ) + " and saving to directory: " +
1297 str( dirFile ) )
1298 except pexpect.EOF:
1299 main.log.error( self.name + ": EOF exception found" )
1300 main.log.error( self.name + ": " + self.handle.before )
1301 main.cleanup()
1302 main.exit()
1303 except Exception:
1304 main.log.exception( self.name + ": Uncaught exception!" )
1305 main.cleanup()
1306 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001307
kelvin-onlabd3b64892015-01-20 13:26:24 -08001308 def runOnosTopoCfg( self, instanceName, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001309 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001310 On ONOS bench, run this command:
Jon Halle94919c2015-03-23 11:42:57 -07001311 {ONOS_HOME}/tools/test/bin/onos-topo-cfg $OC1 filename
kelvin-onlabd3b64892015-01-20 13:26:24 -08001312 which starts the rest and copies
1313 the json file to the onos instance
kelvin8ec71442015-01-15 16:57:00 -08001314 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001315 try:
kelvin8ec71442015-01-15 16:57:00 -08001316 self.handle.sendline( "" )
1317 self.handle.expect( "\$" )
Jon Halle94919c2015-03-23 11:42:57 -07001318 self.handle.sendline( "cd " + self.home + "/tools/test/bin" )
kelvin8ec71442015-01-15 16:57:00 -08001319 self.handle.expect( "/bin$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001320 cmd = "./onos-topo-cfg " + instanceName + " " + jsonFile
shahshreyae6c7cf42014-11-26 16:39:01 -08001321 print "cmd = ", cmd
kelvin8ec71442015-01-15 16:57:00 -08001322 self.handle.sendline( cmd )
1323 self.handle.expect( "\$" )
1324 self.handle.sendline( "cd ~" )
1325 self.handle.expect( "\$" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001326 return main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -08001327 except pexpect.EOF:
1328 main.log.error( self.name + ": EOF exception found" )
1329 main.log.error( self.name + ": " + self.handle.before )
1330 main.cleanup()
1331 main.exit()
1332 except Exception:
1333 main.log.exception( self.name + ": Uncaught exception!" )
1334 main.cleanup()
1335 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001336
kelvin-onlabd3b64892015-01-20 13:26:24 -08001337 def tsharkGrep( self, grep, directory, interface='eth0' ):
kelvin8ec71442015-01-15 16:57:00 -08001338 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001339 Required:
kelvin8ec71442015-01-15 16:57:00 -08001340 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001341 * directory to store results
1342 Optional:
1343 * interface - default: eth0
1344 Description:
1345 Uses tshark command to grep specific group of packets
1346 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001347 The timestamp is hardcoded to be in epoch
1348 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001349 try:
1350 self.handle.sendline( "" )
1351 self.handle.expect( "\$" )
1352 self.handle.sendline( "" )
1353 self.handle.sendline(
1354 "tshark -i " +
1355 str( interface ) +
1356 " -t e | grep --line-buffered \"" +
1357 str(grep) +
1358 "\" >" +
1359 directory +
1360 " &" )
1361 self.handle.sendline( "\r" )
1362 self.handle.expect( "Capturing on" )
1363 self.handle.sendline( "\r" )
1364 self.handle.expect( "\$" )
1365 except pexpect.EOF:
1366 main.log.error( self.name + ": EOF exception found" )
1367 main.log.error( self.name + ": " + self.handle.before )
1368 main.cleanup()
1369 main.exit()
1370 except Exception:
1371 main.log.exception( self.name + ": Uncaught exception!" )
1372 main.cleanup()
1373 main.exit()
1374
kelvin-onlabd3b64892015-01-20 13:26:24 -08001375 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001376 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001377 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001378 """
1379 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001380 try:
1381 self.execute( cmd="sudo rm /tmp/wireshark*" )
1382 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001383 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1384 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001385 self.handle.sendline( "" )
1386 main.log.info( "Tshark stopped" )
1387 except pexpect.EOF:
1388 main.log.error( self.name + ": EOF exception found" )
1389 main.log.error( self.name + ": " + self.handle.before )
1390 main.cleanup()
1391 main.exit()
1392 except Exception:
1393 main.log.exception( self.name + ": Uncaught exception!" )
1394 main.cleanup()
1395 main.exit()
1396
kelvin8ec71442015-01-15 16:57:00 -08001397 def ptpd( self, args ):
1398 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001399 Initiate ptp with user-specified args.
1400 Required:
1401 * args: specify string of args after command
1402 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001403 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001404 try:
kelvin8ec71442015-01-15 16:57:00 -08001405 self.handle.sendline( "sudo ptpd " + str( args ) )
1406 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001407 "Multiple",
1408 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001409 "\$" ] )
1410 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001411
andrewonlab0c38a4a2014-10-28 18:35:35 -04001412 if i == 0:
1413 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001414 main.log.info( "ptpd returned an error: " +
1415 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001416 return handle
1417 elif i == 1:
1418 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001419 main.log.error( "ptpd returned an error: " +
1420 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001421 return handle
1422 else:
1423 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001424
andrewonlab0c38a4a2014-10-28 18:35:35 -04001425 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001426 main.log.error( self.name + ": EOF exception found" )
1427 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001428 main.cleanup()
1429 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001430 except Exception:
1431 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001432 main.cleanup()
1433 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001434
kelvin-onlabd3b64892015-01-20 13:26:24 -08001435 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001436 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001437 """
1438 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001439 Current implementation of ONOS deletes its karaf
1440 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001441 you may want to use this function to capture
1442 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001443 Localtime will be attached to the filename
1444
1445 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001446 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001447 copy.
kelvin8ec71442015-01-15 16:57:00 -08001448 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001449 For copying multiple files, leave copyFileName
1450 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001451 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001452 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001453 ex ) /tmp/
1454 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001455 * copyFileName: If you want to rename the log
1456 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001457 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001458 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001459 try:
kelvin8ec71442015-01-15 16:57:00 -08001460 localtime = time.strftime( '%x %X' )
1461 localtime = localtime.replace( "/", "" )
1462 localtime = localtime.replace( " ", "_" )
1463 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001464 if destDir[ -1: ] != "/":
1465 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001466
kelvin-onlabd3b64892015-01-20 13:26:24 -08001467 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001468 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1469 str( destDir ) + str( copyFileName ) +
1470 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001471 self.handle.expect( "cp" )
1472 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001473 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001474 self.handle.sendline( "cp " + str( logToCopy ) +
1475 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001476 self.handle.expect( "cp" )
1477 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001478
kelvin8ec71442015-01-15 16:57:00 -08001479 return self.handle.before
1480
1481 except pexpect.EOF:
1482 main.log.error( "Copying files failed" )
1483 main.log.error( self.name + ": EOF exception found" )
1484 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001485 except Exception:
1486 main.log.exception( "Copying files failed" )
1487
kelvin-onlabd3b64892015-01-20 13:26:24 -08001488 def checkLogs( self, onosIp ):
kelvin8ec71442015-01-15 16:57:00 -08001489 """
Jon Hall94fd0472014-12-08 11:52:42 -08001490 runs onos-check-logs on the given onos node
1491 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001492 """
Jon Hall94fd0472014-12-08 11:52:42 -08001493 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001494 cmd = "onos-check-logs " + str( onosIp )
kelvin8ec71442015-01-15 16:57:00 -08001495 self.handle.sendline( cmd )
1496 self.handle.expect( cmd )
1497 self.handle.expect( "\$" )
Jon Hall94fd0472014-12-08 11:52:42 -08001498 response = self.handle.before
1499 return response
1500 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001501 main.log.error( "Lost ssh connection" )
1502 main.log.error( self.name + ": EOF exception found" )
1503 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001504 except Exception:
1505 main.log.exception( self.name + ": Uncaught exception!" )
1506 main.cleanup()
1507 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001508
kelvin-onlabd3b64892015-01-20 13:26:24 -08001509 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001510 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001511 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001512 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001513 try:
kelvin8ec71442015-01-15 16:57:00 -08001514 self.handle.sendline( "" )
1515 self.handle.expect( "\$" )
1516 self.handle.sendline( "onos-service " + str( node ) +
1517 " status" )
1518 i = self.handle.expect( [
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001519 "start/running",
1520 "stop/waiting",
kelvin8ec71442015-01-15 16:57:00 -08001521 pexpect.TIMEOUT ], timeout=120 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001522
1523 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001524 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001525 return main.TRUE
1526 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001527 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001528 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001529 main.cleanup()
1530 main.exit()
1531 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001532 main.log.error( self.name + ": EOF exception found" )
1533 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001534 main.cleanup()
1535 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001536 except Exception:
1537 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001538 main.cleanup()
1539 main.exit()
Jon Hall21270ac2015-02-16 17:59:55 -08001540
Jon Hall63604932015-02-26 17:09:50 -08001541 def setIpTables( self, ip, port='', action='add', packet_type='',
1542 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001543 """
Jon Hall21270ac2015-02-16 17:59:55 -08001544 Description:
1545 add or remove iptables rule to DROP (default) packets from
1546 specific IP and PORT
1547 Usage:
1548 * specify action ('add' or 'remove')
1549 when removing, pass in the same argument as you would add. It will
1550 delete that specific rule.
1551 * specify the ip to block
1552 * specify the destination port to block (defaults to all ports)
1553 * optional packet type to block (default tcp)
1554 * optional iptables rule (default DROP)
1555 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001556 * States boolean toggles adding all supported tcp states to the
1557 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001558 Returns:
1559 main.TRUE on success or
1560 main.FALSE if given invalid input or
1561 main.ERROR if there is an error in response from iptables
1562 WARNING:
1563 * This function uses root privilege iptables command which may result
1564 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001565 """
Jon Hall21270ac2015-02-16 17:59:55 -08001566 import time
1567
1568 # NOTE*********
1569 # The strict checking methods of this driver function is intentional
1570 # to discourage any misuse or error of iptables, which can cause
1571 # severe network errors
1572 # *************
1573
1574 # NOTE: Sleep needed to give some time for rule to be added and
1575 # registered to the instance. If you are calling this function
1576 # multiple times this sleep will prevent any errors.
1577 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001578 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001579 try:
1580 # input validation
1581 action_type = action.lower()
1582 rule = rule.upper()
1583 direction = direction.upper()
1584 if action_type != 'add' and action_type != 'remove':
1585 main.log.error( "Invalid action type. Use 'add' or "
1586 "'remove' table rule" )
1587 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1588 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1589 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1590 "'ACCEPT' or 'LOG' only." )
1591 if direction != 'INPUT' and direction != 'OUTPUT':
1592 # NOTE currently only supports rules INPUT and OUPTUT
1593 main.log.error( "Invalid rule. Valid directions are"
1594 " 'OUTPUT' or 'INPUT'" )
1595 return main.FALSE
1596 return main.FALSE
1597 return main.FALSE
1598 if action_type == 'add':
1599 # -A is the 'append' action of iptables
1600 actionFlag = '-A'
1601 elif action_type == 'remove':
1602 # -D is the 'delete' rule of iptables
1603 actionFlag = '-D'
1604 self.handle.sendline( "" )
1605 self.handle.expect( "\$" )
1606 cmd = "sudo iptables " + actionFlag + " " +\
1607 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001608 " -s " + str( ip )
Jon Hall63604932015-02-26 17:09:50 -08001609 # " -p " + str( packet_type ) +\
1610 if packet_type:
1611 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001612 if port:
1613 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001614 if states:
1615 cmd += " -m state --state="
1616 #FIXME- Allow user to configure which states to block
1617 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001618 cmd += " -j " + str( rule )
1619
1620 self.handle.sendline( cmd )
1621 self.handle.expect( "\$" )
1622 main.log.warn( self.handle.before )
1623
1624 info_string = "On " + str( self.name )
1625 info_string += " " + str( action_type )
1626 info_string += " iptable rule [ "
1627 info_string += " IP: " + str( ip )
1628 info_string += " Port: " + str( port )
1629 info_string += " Rule: " + str( rule )
1630 info_string += " Direction: " + str( direction ) + " ]"
1631 main.log.info( info_string )
1632 return main.TRUE
1633 except pexpect.TIMEOUT:
1634 main.log.exception( self.name + ": Timeout exception in "
1635 "setIpTables function" )
1636 return main.ERROR
1637 except pexpect.EOF:
1638 main.log.error( self.name + ": EOF exception found" )
1639 main.log.error( self.name + ": " + self.handle.before )
1640 main.cleanup()
1641 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001642 except Exception:
1643 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall21270ac2015-02-16 17:59:55 -08001644 main.cleanup()
1645 main.exit()
1646
Jon Hall0468b042015-02-19 19:08:21 -08001647 def detailed_status(self, log_filename):
Jon Hallefbd9792015-03-05 16:11:36 -08001648 """
Jon Hall0468b042015-02-19 19:08:21 -08001649 This method is used by STS to check the status of the controller
1650 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001651 """
Jon Hall0468b042015-02-19 19:08:21 -08001652 import re
1653 try:
1654 self.handle.sendline( "" )
1655 self.handle.expect( "\$" )
1656 self.handle.sendline( "cd " + self.home )
1657 self.handle.expect( "\$" )
1658 self.handle.sendline( "service onos status" )
1659 self.handle.expect( "\$" )
1660 response = self.handle.before
1661 if re.search( "onos start/running", response ):
1662 # onos start/running, process 10457
1663 return 'RUNNING'
1664 # FIXME: Implement this case
1665 # elif re.search( pattern, response ):
1666 # return 'STARTING'
1667 elif re.search( "onos stop/", response ):
1668 # onos stop/waiting
1669 # FIXME handle this differently?: onos stop/pre-stop
1670 return 'STOPPED'
1671 # FIXME: Implement this case
1672 # elif re.search( pattern, response ):
1673 # return 'FROZEN'
1674 else:
1675 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001676 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001677 main.log.warn( response )
1678 return 'ERROR', "Unknown response: %s" % response
1679 except pexpect.TIMEOUT:
1680 main.log.exception( self.name + ": Timeout exception in "
1681 "setIpTables function" )
1682 return 'ERROR', "Pexpect Timeout"
1683 except pexpect.EOF:
1684 main.log.error( self.name + ": EOF exception found" )
1685 main.log.error( self.name + ": " + self.handle.before )
1686 main.cleanup()
1687 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001688 except Exception:
1689 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall0468b042015-02-19 19:08:21 -08001690 main.cleanup()
1691 main.exit()
1692
andrew@onlab.us3b087132015-03-11 15:00:08 -07001693 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1694 '''
1695 Create/formats the LinkGraph.cfg file based on arguments
1696 -only creates a linear topology and connects islands
1697 -evenly distributes devices
1698 -must be called by ONOSbench
1699
1700 ONOSIpList - list of all of the node IPs to be used
1701
1702 deviceCount - number of switches to be assigned
1703 '''
1704 main.log.step("Creating link graph configuration file." )
1705 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
1706 tempFile = "/tmp/linkGraph.cfg"
1707
1708 linkGraph = open(tempFile, 'w+')
1709 linkGraph.write("# NullLinkProvider topology description (config file).\n")
1710 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
1711 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
1712
1713 clusterCount = len(ONOSIpList)
1714
1715 if type(deviceCount) is int or type(deviceCount) is str:
1716 deviceCount = int(deviceCount)
1717 switchList = [0]*(clusterCount+1)
1718 baselineSwitchCount = deviceCount/clusterCount
1719
1720 for node in range(1, clusterCount + 1):
1721 switchList[node] = baselineSwitchCount
1722
1723 for node in range(1, (deviceCount%clusterCount)+1):
1724 switchList[node] += 1
1725
1726 if type(deviceCount) is list:
1727 main.log.info("Using provided device distribution")
1728 switchList = [0]
1729 for i in deviceCount:
1730 switchList.append(int(i))
1731
1732 tempList = ['0']
1733 tempList.extend(ONOSIpList)
1734 ONOSIpList = tempList
1735
1736 myPort = 6
1737 lastSwitch = 0
1738 for node in range(1, clusterCount+1):
1739 if switchList[node] == 0:
1740 continue
1741
1742 linkGraph.write("graph " + ONOSIpList[node] + " {\n")
1743
1744 if node > 1:
1745 #connect to last device on previous node
1746 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
1747 linkGraph.write(line)
1748
1749 lastSwitch = 0
1750 for switch in range (0, switchList[node]-1):
1751 line = ""
1752 line = ("\t" + str(switch) + ":" + str(myPort))
1753 line += " -- "
1754 line += (str(switch+1) + ":" + str(myPort-1) + "\n")
1755 linkGraph.write(line)
1756 lastSwitch = switch+1
1757 lastIp = ONOSIpList[node]
1758
1759 #lastSwitch += 1
1760 if node < (clusterCount):
1761 #connect to first device on the next node
1762 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
1763 linkGraph.write(line)
1764
1765 linkGraph.write("}\n")
1766 linkGraph.close()
1767
1768 #SCP
1769 os.system( "scp " + tempFile + " admin@" + benchIp + ":" + linkGraphPath)
1770 main.log.info("linkGraph.cfg creation complete")
1771
cameron@onlab.us75900962015-03-30 13:22:49 -07001772 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001773
1774 '''
andrew@onlab.us3b087132015-03-11 15:00:08 -07001775 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
cameron@onlab.us75900962015-03-30 13:22:49 -07001776 deviceCount = number of switches to distribute, or list of values to use as custom distribution
1777 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 -07001778 '''
1779
cameron@onlab.us75900962015-03-30 13:22:49 -07001780 main.log.step("Configuring Null Device Provider" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07001781 clusterCount = len(ONOSIpList)
1782
cameron@onlab.us75900962015-03-30 13:22:49 -07001783 try:
1784
1785 if type(deviceCount) is int or type(deviceCount) is str:
1786 main.log.step("Creating device distribution")
1787 deviceCount = int(deviceCount)
1788 switchList = [0]*(clusterCount+1)
1789 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001790
cameron@onlab.us75900962015-03-30 13:22:49 -07001791 for node in range(1, clusterCount + 1):
1792 switchList[node] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001793
cameron@onlab.us75900962015-03-30 13:22:49 -07001794 for node in range(1, (deviceCount%clusterCount)+1):
1795 switchList[node] += 1
1796
1797 if type(deviceCount) is list:
1798 main.log.info("Using provided device distribution")
1799
1800 if len(deviceCount) == clusterCount:
1801 switchList = ['0']
1802 switchList.extend(deviceCount)
1803
1804 if len(deviceCount) == (clusterCount + 1):
1805 if deviceCount[0] == '0' or deviceCount[0] == 0:
1806 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001807
cameron@onlab.us75900962015-03-30 13:22:49 -07001808 assert len(switchList) == (clusterCount + 1)
1809
1810 except AssertionError:
1811 main.log.error( "Bad device/Ip list match")
1812 except TypeError:
1813 main.log.exception( self.name + ": Object not as expected" )
1814 return None
1815 except:
1816 main.log.exception( self.name + ": Uncaught exception!" )
1817 main.cleanup()
1818 main.exit()
1819
andrew@onlab.us3b087132015-03-11 15:00:08 -07001820
1821 ONOSIp = [0]
1822 ONOSIp.extend(ONOSIpList)
1823
1824 devicesString = "devConfigs = "
1825 for node in range(1, len(ONOSIp)):
1826 devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
1827 if node < clusterCount:
1828 devicesString += (",")
cameron@onlab.us75900962015-03-30 13:22:49 -07001829
1830 try:
1831 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
1832 self.handle.expect(":~")
1833 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) )
1834 self.handle.expect(":~")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001835
cameron@onlab.us75900962015-03-30 13:22:49 -07001836 for i in range(10):
1837 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider")
1838 self.handle.expect(":~")
1839 verification = self.handle.before
1840 if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification:
1841 break
1842 else:
1843 time.sleep(1)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001844
cameron@onlab.us2cc8bf12015-04-02 14:12:30 -07001845 assert ("value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification
cameron@onlab.us75900962015-03-30 13:22:49 -07001846
1847 except AssertionError:
1848 main.log.error("Incorrect Config settings: " + verification)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001849
cameron@onlab.us75900962015-03-30 13:22:49 -07001850 except:
1851 main.log.exception( self.name + ": Uncaught exception!" )
1852 main.cleanup()
1853 main.exit()
1854
1855 def configNullLink( self,fileName="/opt/onos/apache-karaf-3.0.2/etc/linkGraph.cfg", eventRate=0):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001856 '''
cameron@onlab.us75900962015-03-30 13:22:49 -07001857 fileName default is currently the same as the default on ONOS, specify alternate file if
1858 you want to use a different topology file than linkGraph.cfg
andrew@onlab.us3b087132015-03-11 15:00:08 -07001859 '''
1860
andrew@onlab.us3b087132015-03-11 15:00:08 -07001861
cameron@onlab.us75900962015-03-30 13:22:49 -07001862 try:
1863 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str(eventRate))
1864 self.handle.expect(":~")
1865 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
1866 self.handle.expect(":~")
1867
1868 for i in range(10):
1869 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider")
1870 self.handle.expect(":~")
1871 verification = self.handle.before
1872 if (" value=" + str(eventRate)) in verification and (" value=" + fileName) in verification:
1873 break
1874 else:
1875 time.sleep(1)
1876
1877 assert ("value=" + str(eventRate)) in verification and (" value=" + fileName) in verification
1878
1879 except pexpect.EOF:
1880 main.log.error( self.name + ": EOF exception found" )
1881 main.log.error( self.name + ": " + self.handle.before )
1882 main.cleanup()
1883 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07001884
cameron@onlab.us75900962015-03-30 13:22:49 -07001885 except AssertionError:
1886 main.log.info("Settings did not post to ONOS")
1887 main.log.error(varification)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001888
cameron@onlab.us75900962015-03-30 13:22:49 -07001889 except:
1890 main.log.exception( self.name + ": Uncaught exception!" )
1891 main.log.error(varification)
1892 main.cleanup()
1893 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07001894