blob: 90255f891b8482e8d29ac3b52e40615d974019a4 [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
jenkins1e99e7b2015-04-02 18:15:39 -0700688 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
728
kelvin-onlabd3b64892015-01-20 13:26:24 -0800729 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800730 """
andrewonlab05e362f2014-10-10 00:40:57 -0400731 Uses 'onos' command to send various ONOS CLI arguments.
732 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800733 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400734 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800735
736 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400737 CLI commands for ONOS. Try to use this function first
738 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800739 function.
740 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400741 by starting onos, and typing in 'onos' to enter the
742 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800743 available commands.
744 """
andrewonlab05e362f2014-10-10 00:40:57 -0400745 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800746 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800747 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400748 return main.FALSE
749 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800750 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400751 return main.FALSE
752
kelvin8ec71442015-01-15 16:57:00 -0800753 cmdstr = str( cmdstr )
754 self.handle.sendline( "" )
755 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400756
kelvin-onlabd3b64892015-01-20 13:26:24 -0800757 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800758 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400759
kelvin-onlabd3b64892015-01-20 13:26:24 -0800760 handleBefore = self.handle.before
Shreya Shaha73aaad2014-10-27 18:03:09 -0400761 print "handle_before = ", self.handle.before
kelvin-onlabd3b64892015-01-20 13:26:24 -0800762 # handleAfter = str( self.handle.after )
Jon Hall47a93fb2015-01-06 16:46:06 -0800763
kelvin8ec71442015-01-15 16:57:00 -0800764 # self.handle.sendline( "" )
765 # self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800766 # handleMore = str( self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400767
kelvin8ec71442015-01-15 16:57:00 -0800768 main.log.info( "Command sent successfully" )
andrewonlab05e362f2014-10-10 00:40:57 -0400769
kelvin8ec71442015-01-15 16:57:00 -0800770 # Obtain return handle that consists of result from
771 # the onos command. The string may need to be
772 # configured further.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800773 # returnString = handleBefore + handleAfter
774 returnString = handleBefore
775 print "return_string = ", returnString
776 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400777
778 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800779 main.log.error( self.name + ": EOF exception found" )
780 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400781 main.cleanup()
782 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800783 except Exception:
784 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab05e362f2014-10-10 00:40:57 -0400785 main.cleanup()
786 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400787
kelvin-onlabd3b64892015-01-20 13:26:24 -0800788 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800789 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400790 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800791 If -f option is provided, it also forces an uninstall.
792 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400793 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800794 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400795 files to certain onos nodes
796
797 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800798 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400799 try:
andrewonlab114768a2014-11-14 12:44:44 -0500800 if options:
kelvin8ec71442015-01-15 16:57:00 -0800801 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500802 else:
kelvin8ec71442015-01-15 16:57:00 -0800803 self.handle.sendline( "onos-install " + node )
804 self.handle.expect( "onos-install " )
805 # NOTE: this timeout may need to change depending on the network
806 # and size of ONOS
807 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800808 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800809 "ONOS\sis\salready\sinstalled",
810 pexpect.TIMEOUT ], timeout=60 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400811
Jon Hall7993bfc2014-10-09 16:30:14 -0400812 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800813 main.log.warn( "Network is unreachable" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400814 return main.FALSE
815 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800816 main.log.info(
817 "ONOS was installed on " +
818 node +
819 " and started" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400820 return main.TRUE
andrewonlabd9a73a72014-11-14 17:28:21 -0500821 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800822 main.log.info( "ONOS is already installed on " + node )
andrewonlabd9a73a72014-11-14 17:28:21 -0500823 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800824 elif i == 3:
825 main.log.info(
826 "Installation of ONOS on " +
827 node +
828 " timed out" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400829 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400830
831 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800832 main.log.error( self.name + ": EOF exception found" )
833 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400834 main.cleanup()
835 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800836 except Exception:
837 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400838 main.cleanup()
839 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400840
kelvin-onlabd3b64892015-01-20 13:26:24 -0800841 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800842 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400843 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400844 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800845 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400846 try:
kelvin8ec71442015-01-15 16:57:00 -0800847 self.handle.sendline( "" )
848 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800849 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800850 " start" )
851 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -0400852 "Job\sis\salready\srunning",
853 "start/running",
854 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800855 pexpect.TIMEOUT ], timeout=120 )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400856
857 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800858 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400859 return main.TRUE
860 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800861 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400862 return main.TRUE
863 else:
kelvin8ec71442015-01-15 16:57:00 -0800864 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400865 main.cleanup()
866 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -0400867 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800868 main.log.error( self.name + ": EOF exception found" )
869 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400870 main.cleanup()
871 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800872 except Exception:
873 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400874 main.cleanup()
875 main.exit()
876
kelvin-onlabd3b64892015-01-20 13:26:24 -0800877 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800878 """
andrewonlab2b30bd32014-10-09 16:48:55 -0400879 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400880 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800881 """
andrewonlab2b30bd32014-10-09 16:48:55 -0400882 try:
kelvin8ec71442015-01-15 16:57:00 -0800883 self.handle.sendline( "" )
884 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800885 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800886 " stop" )
887 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -0400888 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -0700889 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -0400890 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800891 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2b30bd32014-10-09 16:48:55 -0400892
893 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800894 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400895 return main.TRUE
896 elif i == 1:
Jon Hall65844a32015-03-09 19:09:37 -0700897 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800898 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -0400899 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700900 elif i == 2:
901 main.log.warn( "ONOS wasn't running" )
902 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -0400903 else:
kelvin8ec71442015-01-15 16:57:00 -0800904 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400905 return main.FALSE
906
907 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800908 main.log.error( self.name + ": EOF exception found" )
909 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -0400910 main.cleanup()
911 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800912 except Exception:
913 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400914 main.cleanup()
915 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800916
kelvin-onlabd3b64892015-01-20 13:26:24 -0800917 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -0800918 """
andrewonlabc8d47972014-10-09 16:52:36 -0400919 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -0800920 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -0400921 if needed
kelvin8ec71442015-01-15 16:57:00 -0800922 """
andrewonlabc8d47972014-10-09 16:52:36 -0400923 try:
kelvin8ec71442015-01-15 16:57:00 -0800924 self.handle.sendline( "" )
925 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800926 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800927 self.handle.expect( "\$" )
andrewonlabc8d47972014-10-09 16:52:36 -0400928
kelvin-onlabd3b64892015-01-20 13:26:24 -0800929 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
andrewonlab9dfd2082014-11-13 17:44:03 -0500930
kelvin8ec71442015-01-15 16:57:00 -0800931 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -0400932 return main.TRUE
933
934 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800935 main.log.error( self.name + ": EOF exception found" )
936 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -0400937 main.cleanup()
938 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800939 except Exception:
940 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc8d47972014-10-09 16:52:36 -0400941 main.cleanup()
942 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -0400943
kelvin-onlabd3b64892015-01-20 13:26:24 -0800944 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800945 """
andrewonlabaedc8332014-12-04 12:43:03 -0500946 Issues the command 'onos-die <node-ip>'
947 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -0800948 """
andrewonlabaedc8332014-12-04 12:43:03 -0500949 try:
kelvin8ec71442015-01-15 16:57:00 -0800950 self.handle.sendline( "" )
951 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800952 cmdStr = "onos-kill " + str( nodeIp )
953 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -0800954 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -0500955 "Killing\sONOS",
956 "ONOS\sprocess\sis\snot\srunning",
kelvin8ec71442015-01-15 16:57:00 -0800957 pexpect.TIMEOUT ], timeout=20 )
andrewonlabaedc8332014-12-04 12:43:03 -0500958 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800959 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800960 " was killed and stopped" )
andrewonlabaedc8332014-12-04 12:43:03 -0500961 return main.TRUE
962 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800963 main.log.info( "ONOS process was not running" )
andrewonlabaedc8332014-12-04 12:43:03 -0500964 return main.FALSE
965 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800966 main.log.error( self.name + ": EOF exception found" )
967 main.log.error( self.name + ": " + self.handle.before )
andrewonlabaedc8332014-12-04 12:43:03 -0500968 main.cleanup()
969 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800970 except Exception:
971 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabaedc8332014-12-04 12:43:03 -0500972 main.cleanup()
973 main.exit()
974
kelvin-onlabd3b64892015-01-20 13:26:24 -0800975 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800976 """
andrewonlabe8e56fd2014-10-09 17:12:44 -0400977 Calls the command: 'onos-kill [<node-ip>]'
978 "Remotely, and unceremoniously kills the ONOS instance running on
979 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -0800980 """
andrewonlabe8e56fd2014-10-09 17:12:44 -0400981 try:
kelvin8ec71442015-01-15 16:57:00 -0800982 self.handle.sendline( "" )
983 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800984 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800985 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -0400986 "\$",
987 "No\sroute\sto\shost",
988 "password:",
kelvin8ec71442015-01-15 16:57:00 -0800989 pexpect.TIMEOUT ], timeout=20 )
990
andrewonlabe8e56fd2014-10-09 17:12:44 -0400991 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800992 main.log.info(
993 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800994 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400995 return main.TRUE
996 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800997 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400998 return main.FALSE
999 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001000 main.log.info(
1001 "Passwordless login for host: " +
1002 str( nodeIp ) +
1003 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001004 return main.FALSE
1005 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001006 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001007 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001008
andrewonlabe8e56fd2014-10-09 17:12:44 -04001009 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001010 main.log.error( self.name + ": EOF exception found" )
1011 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001012 main.cleanup()
1013 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001014 except Exception:
1015 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001016 main.cleanup()
1017 main.exit()
1018
kelvin-onlabd3b64892015-01-20 13:26:24 -08001019 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001020 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001021 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001022 a cleaner environment.
1023
andrewonlab19fbdca2014-11-14 12:55:59 -05001024 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001025 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001026 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001027 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001028 try:
kelvin8ec71442015-01-15 16:57:00 -08001029 self.handle.sendline( "" )
1030 self.handle.expect( "\$" )
1031 self.handle.sendline( "onos-remove-raft-logs" )
1032 # Sometimes this command hangs
1033 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1034 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001035 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001036 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1037 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001038 if i == 1:
1039 return main.FALSE
shahshreya957feaa2015-03-23 16:08:29 -07001040 #self.handle.sendline( "" )
1041 #self.handle.expect( "\$" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001042 return main.TRUE
1043
1044 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001045 main.log.error( self.name + ": EOF exception found" )
1046 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -05001047 main.cleanup()
1048 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001049 except Exception:
1050 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001051 main.cleanup()
1052 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -05001053
kelvin-onlabd3b64892015-01-20 13:26:24 -08001054 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001055 """
1056 Calls the command 'onos-start-network [ <mininet-topo> ]
1057 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001058 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001059 cell."
andrewonlab94282092014-10-10 13:00:11 -04001060 * Specify mininet topology file name for mntopo
1061 * Topo files should be placed at:
1062 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001063
andrewonlab94282092014-10-10 13:00:11 -04001064 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001065 """
andrewonlab94282092014-10-10 13:00:11 -04001066 try:
1067 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001068 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001069 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001070
kelvin8ec71442015-01-15 16:57:00 -08001071 mntopo = str( mntopo )
1072 self.handle.sendline( "" )
1073 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -04001074
kelvin8ec71442015-01-15 16:57:00 -08001075 self.handle.sendline( "onos-start-network " + mntopo )
1076 self.handle.expect( "mininet>" )
1077 main.log.info( "Network started, entered mininet prompt" )
1078
1079 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001080
1081 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001082 main.log.error( self.name + ": EOF exception found" )
1083 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -04001084 main.cleanup()
1085 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001086 except Exception:
1087 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -04001088 main.cleanup()
1089 main.exit()
1090
Cameron Franke9c94fb02015-01-21 10:20:20 -08001091 def isup(self, node = "", timeout = 120):
kelvin8ec71442015-01-15 16:57:00 -08001092 """
1093 Run's onos-wait-for-start which only returns once ONOS is at run
Cameron Franke9c94fb02015-01-21 10:20:20 -08001094 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001095
Jon Hall7993bfc2014-10-09 16:30:14 -04001096 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001097 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001098 try:
Cameron Franke9c94fb02015-01-21 10:20:20 -08001099 self.handle.sendline("onos-wait-for-start " + node )
1100 self.handle.expect("onos-wait-for-start")
kelvin8ec71442015-01-15 16:57:00 -08001101 # NOTE: this timeout is arbitrary"
Cameron Franke9c94fb02015-01-21 10:20:20 -08001102 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001103 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001104 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001105 return main.TRUE
1106 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001107 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001108 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001109 main.log.error( "ONOS has not started yet" )
1110 self.handle.send( "\x03" ) # Control-C
1111 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001112 return main.FALSE
1113 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001114 main.log.error( self.name + ": EOF exception found" )
1115 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -04001116 main.cleanup()
1117 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001118 except Exception:
1119 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001120 main.cleanup()
1121 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001122
kelvin-onlabd3b64892015-01-20 13:26:24 -08001123 def pushTestIntentsShell(
1124 self,
1125 dpidSrc,
1126 dpidDst,
1127 numIntents,
1128 dirFile,
1129 onosIp,
1130 numMult="",
1131 appId="",
1132 report=True,
1133 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001134 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001135 Description:
kelvin8ec71442015-01-15 16:57:00 -08001136 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001137 better parallelize the results than the CLI
1138 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001139 * dpidSrc: specify source dpid
1140 * dpidDst: specify destination dpid
1141 * numIntents: specify number of intents to push
1142 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001143 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001144 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001145 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001146 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001147 """
1148 try:
1149 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001150 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001151 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001152 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001153 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001154 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001155
kelvin-onlabd3b64892015-01-20 13:26:24 -08001156 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1157 if not numMult:
1158 addIntents = addDpid + " " + str( numIntents )
1159 elif numMult:
1160 addIntents = addDpid + " " + str( numIntents ) + " " +\
1161 str( numMult )
1162 if appId:
1163 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001164 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001165 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001166
andrewonlabaedc8332014-12-04 12:43:03 -05001167 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001168 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001169 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001170 sendCmd = addApp + " &"
1171 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001172
kelvin-onlabd3b64892015-01-20 13:26:24 -08001173 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001174
1175 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001176 main.log.error( self.name + ": EOF exception found" )
1177 main.log.error( self.name + ": " + self.handle.before )
andrewonlabb66dfa12014-12-02 15:51:10 -05001178 main.cleanup()
1179 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001180 except Exception:
1181 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001182 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001183 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001184
kelvin-onlabd3b64892015-01-20 13:26:24 -08001185 def getTopology( self, topologyOutput ):
kelvin8ec71442015-01-15 16:57:00 -08001186 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001187 Definition:
1188 Loads a json topology output
1189 Return:
1190 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -08001191 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001192 import json
Jon Hall77f53ce2014-10-13 18:02:06 -04001193 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001194 # either onos:topology or 'topology' will work in CLI
1195 topology = json.loads(topologyOutput)
1196 print topology
Jon Hall77f53ce2014-10-13 18:02:06 -04001197 return topology
1198 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001199 main.log.error( self.name + ": EOF exception found" )
1200 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001201 main.cleanup()
1202 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001203 except Exception:
1204 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001205 main.cleanup()
1206 main.exit()
1207
kelvin-onlabd3b64892015-01-20 13:26:24 -08001208 def checkStatus(
1209 self,
1210 topologyResult,
1211 numoswitch,
1212 numolink,
1213 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001214 """
Jon Hallefbd9792015-03-05 16:11:36 -08001215 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001216 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001217 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08001218
Jon Hall77f53ce2014-10-13 18:02:06 -04001219 Params: ip = ip used for the onos cli
1220 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001221 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001222 logLevel = level to log to.
1223 Currently accepts 'info', 'warn' and 'report'
Jon Hall77f53ce2014-10-13 18:02:06 -04001224
1225
kelvin-onlabd3b64892015-01-20 13:26:24 -08001226 logLevel can
Jon Hall77f53ce2014-10-13 18:02:06 -04001227
Jon Hallefbd9792015-03-05 16:11:36 -08001228 Returns: main.TRUE if the number of switches and links are correct,
1229 main.FALSE if the number of switches and links is incorrect,
Jon Hall77f53ce2014-10-13 18:02:06 -04001230 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001231 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001232 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001233 topology = self.getTopology( topologyResult )
Jon Hall77f53ce2014-10-13 18:02:06 -04001234 if topology == {}:
1235 return main.ERROR
1236 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001237 # Is the number of switches is what we expected
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001238 devices = topology.get( 'deviceCount', False )
1239 links = topology.get( 'linkCount', False )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001240 if not devices or not links:
Jon Hall77f53ce2014-10-13 18:02:06 -04001241 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001242 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001243 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001244 linkCheck = ( int( links ) == int( numolink ) )
Jon Hallefbd9792015-03-05 16:11:36 -08001245 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08001246 # We expected the correct numbers
Jon Hall77f53ce2014-10-13 18:02:06 -04001247 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001248 + "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001249 result = main.TRUE
1250 else:
1251 output = output + \
Jon Hall274b6642015-02-17 11:57:17 -08001252 "The number of links and switches does not match " + \
1253 "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001254 result = main.FALSE
Jon Hallefbd9792015-03-05 16:11:36 -08001255 output = output + "\n ONOS sees %i devices" % int( devices )
1256 output = output + " (%i expected) " % int( numoswitch )
Jon Hall274b6642015-02-17 11:57:17 -08001257 output = output + "and %i links " % int( links )
1258 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001260 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001261 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001262 main.log.warn( output )
Jon Hall77f53ce2014-10-13 18:02:06 -04001263 else:
kelvin8ec71442015-01-15 16:57:00 -08001264 main.log.info( output )
1265 return result
Jon Hall77f53ce2014-10-13 18:02:06 -04001266 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001267 main.log.error( self.name + ": EOF exception found" )
1268 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001269 main.cleanup()
1270 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001271 except Exception:
1272 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001273 main.cleanup()
1274 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001275
kelvin-onlabd3b64892015-01-20 13:26:24 -08001276 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001277 """
andrewonlab970399c2014-11-07 13:09:32 -05001278 Capture all packet activity and store in specified
1279 directory/file
1280
1281 Required:
1282 * interface: interface to capture
1283 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001284 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001285 try:
1286 self.handle.sendline( "" )
1287 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001288
Jon Hallfebb1c72015-03-05 13:30:09 -08001289 self.handle.sendline( "tshark -i " + str( interface ) +
1290 " -t e -w " + str( dirFile ) + " &" )
1291 self.handle.sendline( "\r" )
1292 self.handle.expect( "Capturing on" )
1293 self.handle.sendline( "\r" )
1294 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001295
Jon Hallfebb1c72015-03-05 13:30:09 -08001296 main.log.info( "Tshark started capturing files on " +
1297 str( interface ) + " and saving to directory: " +
1298 str( dirFile ) )
1299 except pexpect.EOF:
1300 main.log.error( self.name + ": EOF exception found" )
1301 main.log.error( self.name + ": " + self.handle.before )
1302 main.cleanup()
1303 main.exit()
1304 except Exception:
1305 main.log.exception( self.name + ": Uncaught exception!" )
1306 main.cleanup()
1307 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001308
kelvin-onlabd3b64892015-01-20 13:26:24 -08001309 def runOnosTopoCfg( self, instanceName, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001310 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001311 On ONOS bench, run this command:
Jon Halle94919c2015-03-23 11:42:57 -07001312 {ONOS_HOME}/tools/test/bin/onos-topo-cfg $OC1 filename
kelvin-onlabd3b64892015-01-20 13:26:24 -08001313 which starts the rest and copies
1314 the json file to the onos instance
kelvin8ec71442015-01-15 16:57:00 -08001315 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001316 try:
kelvin8ec71442015-01-15 16:57:00 -08001317 self.handle.sendline( "" )
1318 self.handle.expect( "\$" )
Jon Halle94919c2015-03-23 11:42:57 -07001319 self.handle.sendline( "cd " + self.home + "/tools/test/bin" )
kelvin8ec71442015-01-15 16:57:00 -08001320 self.handle.expect( "/bin$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001321 cmd = "./onos-topo-cfg " + instanceName + " " + jsonFile
shahshreyae6c7cf42014-11-26 16:39:01 -08001322 print "cmd = ", cmd
kelvin8ec71442015-01-15 16:57:00 -08001323 self.handle.sendline( cmd )
1324 self.handle.expect( "\$" )
1325 self.handle.sendline( "cd ~" )
1326 self.handle.expect( "\$" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001327 return main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -08001328 except pexpect.EOF:
1329 main.log.error( self.name + ": EOF exception found" )
1330 main.log.error( self.name + ": " + self.handle.before )
1331 main.cleanup()
1332 main.exit()
1333 except Exception:
1334 main.log.exception( self.name + ": Uncaught exception!" )
1335 main.cleanup()
1336 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001337
jenkins1e99e7b2015-04-02 18:15:39 -07001338 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001339 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001340 Required:
kelvin8ec71442015-01-15 16:57:00 -08001341 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001342 * directory to store results
1343 Optional:
1344 * interface - default: eth0
jenkins1e99e7b2015-04-02 18:15:39 -07001345 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001346 Description:
1347 Uses tshark command to grep specific group of packets
1348 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001349 The timestamp is hardcoded to be in epoch
1350 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001351 try:
1352 self.handle.sendline( "" )
1353 self.handle.expect( "\$" )
1354 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001355 if grepOptions:
1356 grepStr = "grep "+str(grepOptions)
1357 else:
1358 grepStr = "grep"
1359
Jon Hallfebb1c72015-03-05 13:30:09 -08001360 self.handle.sendline(
1361 "tshark -i " +
1362 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001363 " -t e | " +
1364 grepStr + " --line-buffered \"" +
Jon Hallfebb1c72015-03-05 13:30:09 -08001365 str(grep) +
1366 "\" >" +
1367 directory +
1368 " &" )
1369 self.handle.sendline( "\r" )
1370 self.handle.expect( "Capturing on" )
1371 self.handle.sendline( "\r" )
1372 self.handle.expect( "\$" )
1373 except pexpect.EOF:
1374 main.log.error( self.name + ": EOF exception found" )
1375 main.log.error( self.name + ": " + self.handle.before )
1376 main.cleanup()
1377 main.exit()
1378 except Exception:
1379 main.log.exception( self.name + ": Uncaught exception!" )
1380 main.cleanup()
1381 main.exit()
1382
kelvin-onlabd3b64892015-01-20 13:26:24 -08001383 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001384 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001385 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001386 """
1387 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001388 try:
1389 self.execute( cmd="sudo rm /tmp/wireshark*" )
1390 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001391 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1392 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001393 self.handle.sendline( "" )
1394 main.log.info( "Tshark stopped" )
1395 except pexpect.EOF:
1396 main.log.error( self.name + ": EOF exception found" )
1397 main.log.error( self.name + ": " + self.handle.before )
1398 main.cleanup()
1399 main.exit()
1400 except Exception:
1401 main.log.exception( self.name + ": Uncaught exception!" )
1402 main.cleanup()
1403 main.exit()
1404
kelvin8ec71442015-01-15 16:57:00 -08001405 def ptpd( self, args ):
1406 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001407 Initiate ptp with user-specified args.
1408 Required:
1409 * args: specify string of args after command
1410 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001411 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001412 try:
kelvin8ec71442015-01-15 16:57:00 -08001413 self.handle.sendline( "sudo ptpd " + str( args ) )
1414 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001415 "Multiple",
1416 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001417 "\$" ] )
1418 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001419
andrewonlab0c38a4a2014-10-28 18:35:35 -04001420 if i == 0:
1421 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001422 main.log.info( "ptpd returned an error: " +
1423 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001424 return handle
1425 elif i == 1:
1426 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001427 main.log.error( "ptpd returned an error: " +
1428 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001429 return handle
1430 else:
1431 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001432
andrewonlab0c38a4a2014-10-28 18:35:35 -04001433 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001434 main.log.error( self.name + ": EOF exception found" )
1435 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001436 main.cleanup()
1437 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001438 except Exception:
1439 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001440 main.cleanup()
1441 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001442
kelvin-onlabd3b64892015-01-20 13:26:24 -08001443 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001444 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001445 """
1446 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001447 Current implementation of ONOS deletes its karaf
1448 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001449 you may want to use this function to capture
1450 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001451 Localtime will be attached to the filename
1452
1453 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001454 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001455 copy.
kelvin8ec71442015-01-15 16:57:00 -08001456 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001457 For copying multiple files, leave copyFileName
1458 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001459 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001460 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001461 ex ) /tmp/
1462 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001463 * copyFileName: If you want to rename the log
1464 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001465 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001466 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001467 try:
kelvin8ec71442015-01-15 16:57:00 -08001468 localtime = time.strftime( '%x %X' )
1469 localtime = localtime.replace( "/", "" )
1470 localtime = localtime.replace( " ", "_" )
1471 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001472 if destDir[ -1: ] != "/":
1473 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001474
kelvin-onlabd3b64892015-01-20 13:26:24 -08001475 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001476 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1477 str( destDir ) + str( copyFileName ) +
1478 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001479 self.handle.expect( "cp" )
1480 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001481 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001482 self.handle.sendline( "cp " + str( logToCopy ) +
1483 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001484 self.handle.expect( "cp" )
1485 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001486
kelvin8ec71442015-01-15 16:57:00 -08001487 return self.handle.before
1488
1489 except pexpect.EOF:
1490 main.log.error( "Copying files failed" )
1491 main.log.error( self.name + ": EOF exception found" )
1492 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001493 except Exception:
1494 main.log.exception( "Copying files failed" )
1495
kelvin-onlabd3b64892015-01-20 13:26:24 -08001496 def checkLogs( self, onosIp ):
kelvin8ec71442015-01-15 16:57:00 -08001497 """
Jon Hall94fd0472014-12-08 11:52:42 -08001498 runs onos-check-logs on the given onos node
1499 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001500 """
Jon Hall94fd0472014-12-08 11:52:42 -08001501 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001502 cmd = "onos-check-logs " + str( onosIp )
kelvin8ec71442015-01-15 16:57:00 -08001503 self.handle.sendline( cmd )
1504 self.handle.expect( cmd )
1505 self.handle.expect( "\$" )
Jon Hall94fd0472014-12-08 11:52:42 -08001506 response = self.handle.before
1507 return response
1508 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001509 main.log.error( "Lost ssh connection" )
1510 main.log.error( self.name + ": EOF exception found" )
1511 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001512 except Exception:
1513 main.log.exception( self.name + ": Uncaught exception!" )
1514 main.cleanup()
1515 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001516
kelvin-onlabd3b64892015-01-20 13:26:24 -08001517 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001518 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001519 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001520 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001521 try:
kelvin8ec71442015-01-15 16:57:00 -08001522 self.handle.sendline( "" )
1523 self.handle.expect( "\$" )
1524 self.handle.sendline( "onos-service " + str( node ) +
1525 " status" )
1526 i = self.handle.expect( [
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001527 "start/running",
1528 "stop/waiting",
kelvin8ec71442015-01-15 16:57:00 -08001529 pexpect.TIMEOUT ], timeout=120 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001530
1531 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001532 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001533 return main.TRUE
1534 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001535 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001536 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001537 main.cleanup()
1538 main.exit()
1539 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001540 main.log.error( self.name + ": EOF exception found" )
1541 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001542 main.cleanup()
1543 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001544 except Exception:
1545 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001546 main.cleanup()
1547 main.exit()
Jon Hall21270ac2015-02-16 17:59:55 -08001548
Jon Hall63604932015-02-26 17:09:50 -08001549 def setIpTables( self, ip, port='', action='add', packet_type='',
1550 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001551 """
Jon Hall21270ac2015-02-16 17:59:55 -08001552 Description:
1553 add or remove iptables rule to DROP (default) packets from
1554 specific IP and PORT
1555 Usage:
1556 * specify action ('add' or 'remove')
1557 when removing, pass in the same argument as you would add. It will
1558 delete that specific rule.
1559 * specify the ip to block
1560 * specify the destination port to block (defaults to all ports)
1561 * optional packet type to block (default tcp)
1562 * optional iptables rule (default DROP)
1563 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001564 * States boolean toggles adding all supported tcp states to the
1565 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001566 Returns:
1567 main.TRUE on success or
1568 main.FALSE if given invalid input or
1569 main.ERROR if there is an error in response from iptables
1570 WARNING:
1571 * This function uses root privilege iptables command which may result
1572 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001573 """
Jon Hall21270ac2015-02-16 17:59:55 -08001574 import time
1575
1576 # NOTE*********
1577 # The strict checking methods of this driver function is intentional
1578 # to discourage any misuse or error of iptables, which can cause
1579 # severe network errors
1580 # *************
1581
1582 # NOTE: Sleep needed to give some time for rule to be added and
1583 # registered to the instance. If you are calling this function
1584 # multiple times this sleep will prevent any errors.
1585 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001586 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001587 try:
1588 # input validation
1589 action_type = action.lower()
1590 rule = rule.upper()
1591 direction = direction.upper()
1592 if action_type != 'add' and action_type != 'remove':
1593 main.log.error( "Invalid action type. Use 'add' or "
1594 "'remove' table rule" )
1595 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1596 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1597 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1598 "'ACCEPT' or 'LOG' only." )
1599 if direction != 'INPUT' and direction != 'OUTPUT':
1600 # NOTE currently only supports rules INPUT and OUPTUT
1601 main.log.error( "Invalid rule. Valid directions are"
1602 " 'OUTPUT' or 'INPUT'" )
1603 return main.FALSE
1604 return main.FALSE
1605 return main.FALSE
1606 if action_type == 'add':
1607 # -A is the 'append' action of iptables
1608 actionFlag = '-A'
1609 elif action_type == 'remove':
1610 # -D is the 'delete' rule of iptables
1611 actionFlag = '-D'
1612 self.handle.sendline( "" )
1613 self.handle.expect( "\$" )
1614 cmd = "sudo iptables " + actionFlag + " " +\
1615 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001616 " -s " + str( ip )
Jon Hall63604932015-02-26 17:09:50 -08001617 # " -p " + str( packet_type ) +\
1618 if packet_type:
1619 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001620 if port:
1621 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001622 if states:
1623 cmd += " -m state --state="
1624 #FIXME- Allow user to configure which states to block
1625 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001626 cmd += " -j " + str( rule )
1627
1628 self.handle.sendline( cmd )
1629 self.handle.expect( "\$" )
1630 main.log.warn( self.handle.before )
1631
1632 info_string = "On " + str( self.name )
1633 info_string += " " + str( action_type )
1634 info_string += " iptable rule [ "
1635 info_string += " IP: " + str( ip )
1636 info_string += " Port: " + str( port )
1637 info_string += " Rule: " + str( rule )
1638 info_string += " Direction: " + str( direction ) + " ]"
1639 main.log.info( info_string )
1640 return main.TRUE
1641 except pexpect.TIMEOUT:
1642 main.log.exception( self.name + ": Timeout exception in "
1643 "setIpTables function" )
1644 return main.ERROR
1645 except pexpect.EOF:
1646 main.log.error( self.name + ": EOF exception found" )
1647 main.log.error( self.name + ": " + self.handle.before )
1648 main.cleanup()
1649 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001650 except Exception:
1651 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall21270ac2015-02-16 17:59:55 -08001652 main.cleanup()
1653 main.exit()
1654
Jon Hall0468b042015-02-19 19:08:21 -08001655 def detailed_status(self, log_filename):
Jon Hallefbd9792015-03-05 16:11:36 -08001656 """
Jon Hall0468b042015-02-19 19:08:21 -08001657 This method is used by STS to check the status of the controller
1658 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001659 """
Jon Hall0468b042015-02-19 19:08:21 -08001660 import re
1661 try:
1662 self.handle.sendline( "" )
1663 self.handle.expect( "\$" )
1664 self.handle.sendline( "cd " + self.home )
1665 self.handle.expect( "\$" )
1666 self.handle.sendline( "service onos status" )
1667 self.handle.expect( "\$" )
1668 response = self.handle.before
1669 if re.search( "onos start/running", response ):
1670 # onos start/running, process 10457
1671 return 'RUNNING'
1672 # FIXME: Implement this case
1673 # elif re.search( pattern, response ):
1674 # return 'STARTING'
1675 elif re.search( "onos stop/", response ):
1676 # onos stop/waiting
1677 # FIXME handle this differently?: onos stop/pre-stop
1678 return 'STOPPED'
1679 # FIXME: Implement this case
1680 # elif re.search( pattern, response ):
1681 # return 'FROZEN'
1682 else:
1683 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001684 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001685 main.log.warn( response )
1686 return 'ERROR', "Unknown response: %s" % response
1687 except pexpect.TIMEOUT:
1688 main.log.exception( self.name + ": Timeout exception in "
1689 "setIpTables function" )
1690 return 'ERROR', "Pexpect Timeout"
1691 except pexpect.EOF:
1692 main.log.error( self.name + ": EOF exception found" )
1693 main.log.error( self.name + ": " + self.handle.before )
1694 main.cleanup()
1695 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001696 except Exception:
1697 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall0468b042015-02-19 19:08:21 -08001698 main.cleanup()
1699 main.exit()
1700
andrew@onlab.us3b087132015-03-11 15:00:08 -07001701 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1702 '''
1703 Create/formats the LinkGraph.cfg file based on arguments
1704 -only creates a linear topology and connects islands
1705 -evenly distributes devices
1706 -must be called by ONOSbench
1707
1708 ONOSIpList - list of all of the node IPs to be used
1709
1710 deviceCount - number of switches to be assigned
1711 '''
1712 main.log.step("Creating link graph configuration file." )
1713 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
1714 tempFile = "/tmp/linkGraph.cfg"
1715
1716 linkGraph = open(tempFile, 'w+')
1717 linkGraph.write("# NullLinkProvider topology description (config file).\n")
1718 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
1719 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
1720
1721 clusterCount = len(ONOSIpList)
1722
1723 if type(deviceCount) is int or type(deviceCount) is str:
1724 deviceCount = int(deviceCount)
1725 switchList = [0]*(clusterCount+1)
1726 baselineSwitchCount = deviceCount/clusterCount
1727
1728 for node in range(1, clusterCount + 1):
1729 switchList[node] = baselineSwitchCount
1730
1731 for node in range(1, (deviceCount%clusterCount)+1):
1732 switchList[node] += 1
1733
1734 if type(deviceCount) is list:
1735 main.log.info("Using provided device distribution")
1736 switchList = [0]
1737 for i in deviceCount:
1738 switchList.append(int(i))
1739
1740 tempList = ['0']
1741 tempList.extend(ONOSIpList)
1742 ONOSIpList = tempList
1743
1744 myPort = 6
1745 lastSwitch = 0
1746 for node in range(1, clusterCount+1):
1747 if switchList[node] == 0:
1748 continue
1749
1750 linkGraph.write("graph " + ONOSIpList[node] + " {\n")
1751
1752 if node > 1:
1753 #connect to last device on previous node
1754 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
1755 linkGraph.write(line)
1756
1757 lastSwitch = 0
1758 for switch in range (0, switchList[node]-1):
1759 line = ""
1760 line = ("\t" + str(switch) + ":" + str(myPort))
1761 line += " -- "
1762 line += (str(switch+1) + ":" + str(myPort-1) + "\n")
1763 linkGraph.write(line)
1764 lastSwitch = switch+1
1765 lastIp = ONOSIpList[node]
1766
1767 #lastSwitch += 1
1768 if node < (clusterCount):
1769 #connect to first device on the next node
1770 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
1771 linkGraph.write(line)
1772
1773 linkGraph.write("}\n")
1774 linkGraph.close()
1775
1776 #SCP
1777 os.system( "scp " + tempFile + " admin@" + benchIp + ":" + linkGraphPath)
1778 main.log.info("linkGraph.cfg creation complete")
1779
cameron@onlab.us75900962015-03-30 13:22:49 -07001780 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001781
1782 '''
andrew@onlab.us3b087132015-03-11 15:00:08 -07001783 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
cameron@onlab.us75900962015-03-30 13:22:49 -07001784 deviceCount = number of switches to distribute, or list of values to use as custom distribution
1785 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 -07001786 '''
1787
cameron@onlab.us75900962015-03-30 13:22:49 -07001788 main.log.step("Configuring Null Device Provider" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07001789 clusterCount = len(ONOSIpList)
1790
cameron@onlab.us75900962015-03-30 13:22:49 -07001791 try:
1792
1793 if type(deviceCount) is int or type(deviceCount) is str:
1794 main.log.step("Creating device distribution")
1795 deviceCount = int(deviceCount)
1796 switchList = [0]*(clusterCount+1)
1797 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001798
cameron@onlab.us75900962015-03-30 13:22:49 -07001799 for node in range(1, clusterCount + 1):
1800 switchList[node] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001801
cameron@onlab.us75900962015-03-30 13:22:49 -07001802 for node in range(1, (deviceCount%clusterCount)+1):
1803 switchList[node] += 1
1804
1805 if type(deviceCount) is list:
1806 main.log.info("Using provided device distribution")
1807
1808 if len(deviceCount) == clusterCount:
1809 switchList = ['0']
1810 switchList.extend(deviceCount)
1811
1812 if len(deviceCount) == (clusterCount + 1):
1813 if deviceCount[0] == '0' or deviceCount[0] == 0:
1814 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001815
cameron@onlab.us75900962015-03-30 13:22:49 -07001816 assert len(switchList) == (clusterCount + 1)
1817
1818 except AssertionError:
1819 main.log.error( "Bad device/Ip list match")
1820 except TypeError:
1821 main.log.exception( self.name + ": Object not as expected" )
1822 return None
1823 except:
1824 main.log.exception( self.name + ": Uncaught exception!" )
1825 main.cleanup()
1826 main.exit()
1827
andrew@onlab.us3b087132015-03-11 15:00:08 -07001828
1829 ONOSIp = [0]
1830 ONOSIp.extend(ONOSIpList)
1831
1832 devicesString = "devConfigs = "
1833 for node in range(1, len(ONOSIp)):
1834 devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
1835 if node < clusterCount:
1836 devicesString += (",")
cameron@onlab.us75900962015-03-30 13:22:49 -07001837
1838 try:
1839 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
1840 self.handle.expect(":~")
1841 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) )
1842 self.handle.expect(":~")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001843
cameron@onlab.us75900962015-03-30 13:22:49 -07001844 for i in range(10):
1845 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider")
1846 self.handle.expect(":~")
1847 verification = self.handle.before
1848 if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification:
1849 break
1850 else:
1851 time.sleep(1)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001852
cameron@onlab.us75900962015-03-30 13:22:49 -07001853 assert ("value=" + str(numPorts)) in verification and (" value=" + fileName) in verification
1854
1855 except AssertionError:
1856 main.log.error("Incorrect Config settings: " + verification)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001857
cameron@onlab.us75900962015-03-30 13:22:49 -07001858 except:
1859 main.log.exception( self.name + ": Uncaught exception!" )
1860 main.cleanup()
1861 main.exit()
1862
1863 def configNullLink( self,fileName="/opt/onos/apache-karaf-3.0.2/etc/linkGraph.cfg", eventRate=0):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001864 '''
cameron@onlab.us75900962015-03-30 13:22:49 -07001865 fileName default is currently the same as the default on ONOS, specify alternate file if
1866 you want to use a different topology file than linkGraph.cfg
andrew@onlab.us3b087132015-03-11 15:00:08 -07001867 '''
1868
andrew@onlab.us3b087132015-03-11 15:00:08 -07001869
cameron@onlab.us75900962015-03-30 13:22:49 -07001870 try:
1871 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str(eventRate))
1872 self.handle.expect(":~")
1873 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
1874 self.handle.expect(":~")
1875
1876 for i in range(10):
1877 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider")
1878 self.handle.expect(":~")
1879 verification = self.handle.before
1880 if (" value=" + str(eventRate)) in verification and (" value=" + fileName) in verification:
1881 break
1882 else:
1883 time.sleep(1)
1884
1885 assert ("value=" + str(eventRate)) in verification and (" value=" + fileName) in verification
1886
1887 except pexpect.EOF:
1888 main.log.error( self.name + ": EOF exception found" )
1889 main.log.error( self.name + ": " + self.handle.before )
1890 main.cleanup()
1891 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07001892
cameron@onlab.us75900962015-03-30 13:22:49 -07001893 except AssertionError:
1894 main.log.info("Settings did not post to ONOS")
1895 main.log.error(varification)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001896
cameron@onlab.us75900962015-03-30 13:22:49 -07001897 except:
1898 main.log.exception( self.name + ": Uncaught exception!" )
1899 main.log.error(varification)
1900 main.cleanup()
1901 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07001902