blob: f96a60e0864605df002097cc17fa3be9af5aa965 [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
kelvin-onlabd3b64892015-01-20 13:26:24 -0800688 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800689 """
andrewonlab05e362f2014-10-10 00:40:57 -0400690 Uses 'onos' command to send various ONOS CLI arguments.
691 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800692 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400693 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800694
695 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400696 CLI commands for ONOS. Try to use this function first
697 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800698 function.
699 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400700 by starting onos, and typing in 'onos' to enter the
701 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800702 available commands.
703 """
andrewonlab05e362f2014-10-10 00:40:57 -0400704 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800705 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800706 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400707 return main.FALSE
708 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800709 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400710 return main.FALSE
711
kelvin8ec71442015-01-15 16:57:00 -0800712 cmdstr = str( cmdstr )
713 self.handle.sendline( "" )
714 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400715
kelvin-onlabd3b64892015-01-20 13:26:24 -0800716 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800717 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400718
kelvin-onlabd3b64892015-01-20 13:26:24 -0800719 handleBefore = self.handle.before
Shreya Shaha73aaad2014-10-27 18:03:09 -0400720 print "handle_before = ", self.handle.before
kelvin-onlabd3b64892015-01-20 13:26:24 -0800721 # handleAfter = str( self.handle.after )
Jon Hall47a93fb2015-01-06 16:46:06 -0800722
kelvin8ec71442015-01-15 16:57:00 -0800723 # self.handle.sendline( "" )
724 # self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800725 # handleMore = str( self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400726
kelvin8ec71442015-01-15 16:57:00 -0800727 main.log.info( "Command sent successfully" )
andrewonlab05e362f2014-10-10 00:40:57 -0400728
kelvin8ec71442015-01-15 16:57:00 -0800729 # Obtain return handle that consists of result from
730 # the onos command. The string may need to be
731 # configured further.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800732 # returnString = handleBefore + handleAfter
733 returnString = handleBefore
734 print "return_string = ", returnString
735 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400736
737 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800738 main.log.error( self.name + ": EOF exception found" )
739 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400740 main.cleanup()
741 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800742 except Exception:
743 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab05e362f2014-10-10 00:40:57 -0400744 main.cleanup()
745 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400746
kelvin-onlabd3b64892015-01-20 13:26:24 -0800747 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800748 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400749 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800750 If -f option is provided, it also forces an uninstall.
751 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400752 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800753 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400754 files to certain onos nodes
755
756 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800757 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400758 try:
andrewonlab114768a2014-11-14 12:44:44 -0500759 if options:
kelvin8ec71442015-01-15 16:57:00 -0800760 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500761 else:
kelvin8ec71442015-01-15 16:57:00 -0800762 self.handle.sendline( "onos-install " + node )
763 self.handle.expect( "onos-install " )
764 # NOTE: this timeout may need to change depending on the network
765 # and size of ONOS
766 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800767 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800768 "ONOS\sis\salready\sinstalled",
769 pexpect.TIMEOUT ], timeout=60 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400770
Jon Hall7993bfc2014-10-09 16:30:14 -0400771 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800772 main.log.warn( "Network is unreachable" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400773 return main.FALSE
774 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800775 main.log.info(
776 "ONOS was installed on " +
777 node +
778 " and started" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400779 return main.TRUE
andrewonlabd9a73a72014-11-14 17:28:21 -0500780 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800781 main.log.info( "ONOS is already installed on " + node )
andrewonlabd9a73a72014-11-14 17:28:21 -0500782 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800783 elif i == 3:
784 main.log.info(
785 "Installation of ONOS on " +
786 node +
787 " timed out" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400788 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400789
790 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800791 main.log.error( self.name + ": EOF exception found" )
792 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400793 main.cleanup()
794 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800795 except Exception:
796 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400797 main.cleanup()
798 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400799
kelvin-onlabd3b64892015-01-20 13:26:24 -0800800 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800801 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400802 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400803 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800804 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400805 try:
kelvin8ec71442015-01-15 16:57:00 -0800806 self.handle.sendline( "" )
807 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800808 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800809 " start" )
810 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -0400811 "Job\sis\salready\srunning",
812 "start/running",
813 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800814 pexpect.TIMEOUT ], timeout=120 )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400815
816 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800817 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400818 return main.TRUE
819 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800820 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400821 return main.TRUE
822 else:
kelvin8ec71442015-01-15 16:57:00 -0800823 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400824 main.cleanup()
825 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -0400826 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800827 main.log.error( self.name + ": EOF exception found" )
828 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400829 main.cleanup()
830 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800831 except Exception:
832 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400833 main.cleanup()
834 main.exit()
835
kelvin-onlabd3b64892015-01-20 13:26:24 -0800836 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800837 """
andrewonlab2b30bd32014-10-09 16:48:55 -0400838 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400839 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800840 """
andrewonlab2b30bd32014-10-09 16:48:55 -0400841 try:
kelvin8ec71442015-01-15 16:57:00 -0800842 self.handle.sendline( "" )
843 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800844 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800845 " stop" )
846 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -0400847 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -0700848 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -0400849 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800850 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2b30bd32014-10-09 16:48:55 -0400851
852 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800853 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400854 return main.TRUE
855 elif i == 1:
Jon Hall65844a32015-03-09 19:09:37 -0700856 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800857 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -0400858 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700859 elif i == 2:
860 main.log.warn( "ONOS wasn't running" )
861 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -0400862 else:
kelvin8ec71442015-01-15 16:57:00 -0800863 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400864 return main.FALSE
865
866 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800867 main.log.error( self.name + ": EOF exception found" )
868 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -0400869 main.cleanup()
870 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800871 except Exception:
872 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400873 main.cleanup()
874 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800875
kelvin-onlabd3b64892015-01-20 13:26:24 -0800876 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -0800877 """
andrewonlabc8d47972014-10-09 16:52:36 -0400878 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -0800879 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -0400880 if needed
kelvin8ec71442015-01-15 16:57:00 -0800881 """
andrewonlabc8d47972014-10-09 16:52:36 -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-uninstall " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800886 self.handle.expect( "\$" )
andrewonlabc8d47972014-10-09 16:52:36 -0400887
kelvin-onlabd3b64892015-01-20 13:26:24 -0800888 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
andrewonlab9dfd2082014-11-13 17:44:03 -0500889
kelvin8ec71442015-01-15 16:57:00 -0800890 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -0400891 return main.TRUE
892
893 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800894 main.log.error( self.name + ": EOF exception found" )
895 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -0400896 main.cleanup()
897 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800898 except Exception:
899 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc8d47972014-10-09 16:52:36 -0400900 main.cleanup()
901 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -0400902
kelvin-onlabd3b64892015-01-20 13:26:24 -0800903 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800904 """
andrewonlabaedc8332014-12-04 12:43:03 -0500905 Issues the command 'onos-die <node-ip>'
906 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -0800907 """
andrewonlabaedc8332014-12-04 12:43:03 -0500908 try:
kelvin8ec71442015-01-15 16:57:00 -0800909 self.handle.sendline( "" )
910 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800911 cmdStr = "onos-kill " + str( nodeIp )
912 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -0800913 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -0500914 "Killing\sONOS",
915 "ONOS\sprocess\sis\snot\srunning",
kelvin8ec71442015-01-15 16:57:00 -0800916 pexpect.TIMEOUT ], timeout=20 )
andrewonlabaedc8332014-12-04 12:43:03 -0500917 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800918 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800919 " was killed and stopped" )
andrewonlabaedc8332014-12-04 12:43:03 -0500920 return main.TRUE
921 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800922 main.log.info( "ONOS process was not running" )
andrewonlabaedc8332014-12-04 12:43:03 -0500923 return main.FALSE
924 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800925 main.log.error( self.name + ": EOF exception found" )
926 main.log.error( self.name + ": " + self.handle.before )
andrewonlabaedc8332014-12-04 12:43:03 -0500927 main.cleanup()
928 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800929 except Exception:
930 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabaedc8332014-12-04 12:43:03 -0500931 main.cleanup()
932 main.exit()
933
kelvin-onlabd3b64892015-01-20 13:26:24 -0800934 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800935 """
andrewonlabe8e56fd2014-10-09 17:12:44 -0400936 Calls the command: 'onos-kill [<node-ip>]'
937 "Remotely, and unceremoniously kills the ONOS instance running on
938 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -0800939 """
andrewonlabe8e56fd2014-10-09 17:12:44 -0400940 try:
kelvin8ec71442015-01-15 16:57:00 -0800941 self.handle.sendline( "" )
942 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800943 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800944 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -0400945 "\$",
946 "No\sroute\sto\shost",
947 "password:",
kelvin8ec71442015-01-15 16:57:00 -0800948 pexpect.TIMEOUT ], timeout=20 )
949
andrewonlabe8e56fd2014-10-09 17:12:44 -0400950 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800951 main.log.info(
952 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800953 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400954 return main.TRUE
955 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800956 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400957 return main.FALSE
958 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800959 main.log.info(
960 "Passwordless login for host: " +
961 str( nodeIp ) +
962 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400963 return main.FALSE
964 else:
Jon Hallefbd9792015-03-05 16:11:36 -0800965 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400966 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -0800967
andrewonlabe8e56fd2014-10-09 17:12:44 -0400968 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800969 main.log.error( self.name + ": EOF exception found" )
970 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400971 main.cleanup()
972 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800973 except Exception:
974 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400975 main.cleanup()
976 main.exit()
977
kelvin-onlabd3b64892015-01-20 13:26:24 -0800978 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -0800979 """
andrewonlab19fbdca2014-11-14 12:55:59 -0500980 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -0500981 a cleaner environment.
982
andrewonlab19fbdca2014-11-14 12:55:59 -0500983 Description:
Jon Hallfcc88622014-11-25 13:09:54 -0500984 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -0500985 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -0800986 """
andrewonlab19fbdca2014-11-14 12:55:59 -0500987 try:
kelvin8ec71442015-01-15 16:57:00 -0800988 self.handle.sendline( "" )
989 self.handle.expect( "\$" )
990 self.handle.sendline( "onos-remove-raft-logs" )
991 # Sometimes this command hangs
992 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
993 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -0500994 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800995 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
996 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -0500997 if i == 1:
998 return main.FALSE
shahshreya957feaa2015-03-23 16:08:29 -0700999 #self.handle.sendline( "" )
1000 #self.handle.expect( "\$" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001001 return main.TRUE
1002
1003 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001004 main.log.error( self.name + ": EOF exception found" )
1005 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -05001006 main.cleanup()
1007 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001008 except Exception:
1009 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001010 main.cleanup()
1011 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -05001012
kelvin-onlabd3b64892015-01-20 13:26:24 -08001013 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001014 """
1015 Calls the command 'onos-start-network [ <mininet-topo> ]
1016 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001017 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001018 cell."
andrewonlab94282092014-10-10 13:00:11 -04001019 * Specify mininet topology file name for mntopo
1020 * Topo files should be placed at:
1021 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001022
andrewonlab94282092014-10-10 13:00:11 -04001023 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001024 """
andrewonlab94282092014-10-10 13:00:11 -04001025 try:
1026 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001027 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001028 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001029
kelvin8ec71442015-01-15 16:57:00 -08001030 mntopo = str( mntopo )
1031 self.handle.sendline( "" )
1032 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -04001033
kelvin8ec71442015-01-15 16:57:00 -08001034 self.handle.sendline( "onos-start-network " + mntopo )
1035 self.handle.expect( "mininet>" )
1036 main.log.info( "Network started, entered mininet prompt" )
1037
1038 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001039
1040 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001041 main.log.error( self.name + ": EOF exception found" )
1042 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -04001043 main.cleanup()
1044 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001045 except Exception:
1046 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -04001047 main.cleanup()
1048 main.exit()
1049
Cameron Franke9c94fb02015-01-21 10:20:20 -08001050 def isup(self, node = "", timeout = 120):
kelvin8ec71442015-01-15 16:57:00 -08001051 """
1052 Run's onos-wait-for-start which only returns once ONOS is at run
Cameron Franke9c94fb02015-01-21 10:20:20 -08001053 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001054
Jon Hall7993bfc2014-10-09 16:30:14 -04001055 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001056 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001057 try:
Cameron Franke9c94fb02015-01-21 10:20:20 -08001058 self.handle.sendline("onos-wait-for-start " + node )
1059 self.handle.expect("onos-wait-for-start")
kelvin8ec71442015-01-15 16:57:00 -08001060 # NOTE: this timeout is arbitrary"
Cameron Franke9c94fb02015-01-21 10:20:20 -08001061 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001062 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001063 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001064 return main.TRUE
1065 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001066 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001067 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001068 main.log.error( "ONOS has not started yet" )
1069 self.handle.send( "\x03" ) # Control-C
1070 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001071 return main.FALSE
1072 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001073 main.log.error( self.name + ": EOF exception found" )
1074 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -04001075 main.cleanup()
1076 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001077 except Exception:
1078 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001079 main.cleanup()
1080 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001081
kelvin-onlabd3b64892015-01-20 13:26:24 -08001082 def pushTestIntentsShell(
1083 self,
1084 dpidSrc,
1085 dpidDst,
1086 numIntents,
1087 dirFile,
1088 onosIp,
1089 numMult="",
1090 appId="",
1091 report=True,
1092 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001093 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001094 Description:
kelvin8ec71442015-01-15 16:57:00 -08001095 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001096 better parallelize the results than the CLI
1097 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001098 * dpidSrc: specify source dpid
1099 * dpidDst: specify destination dpid
1100 * numIntents: specify number of intents to push
1101 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001102 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001103 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001104 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001105 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001106 """
1107 try:
1108 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001109 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001110 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001111 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001112 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001113 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001114
kelvin-onlabd3b64892015-01-20 13:26:24 -08001115 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1116 if not numMult:
1117 addIntents = addDpid + " " + str( numIntents )
1118 elif numMult:
1119 addIntents = addDpid + " " + str( numIntents ) + " " +\
1120 str( numMult )
1121 if appId:
1122 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001123 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001124 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001125
andrewonlabaedc8332014-12-04 12:43:03 -05001126 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001127 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001128 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 sendCmd = addApp + " &"
1130 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001131
kelvin-onlabd3b64892015-01-20 13:26:24 -08001132 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001133
1134 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001135 main.log.error( self.name + ": EOF exception found" )
1136 main.log.error( self.name + ": " + self.handle.before )
andrewonlabb66dfa12014-12-02 15:51:10 -05001137 main.cleanup()
1138 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001139 except Exception:
1140 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001141 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001142 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001143
kelvin-onlabd3b64892015-01-20 13:26:24 -08001144 def getTopology( self, topologyOutput ):
kelvin8ec71442015-01-15 16:57:00 -08001145 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001146 Definition:
1147 Loads a json topology output
1148 Return:
1149 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -08001150 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001151 import json
Jon Hall77f53ce2014-10-13 18:02:06 -04001152 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001153 # either onos:topology or 'topology' will work in CLI
1154 topology = json.loads(topologyOutput)
1155 print topology
Jon Hall77f53ce2014-10-13 18:02:06 -04001156 return topology
1157 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001158 main.log.error( self.name + ": EOF exception found" )
1159 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001160 main.cleanup()
1161 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001162 except Exception:
1163 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001164 main.cleanup()
1165 main.exit()
1166
kelvin-onlabd3b64892015-01-20 13:26:24 -08001167 def checkStatus(
1168 self,
1169 topologyResult,
1170 numoswitch,
1171 numolink,
1172 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001173 """
Jon Hallefbd9792015-03-05 16:11:36 -08001174 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001175 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001176 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08001177
Jon Hall77f53ce2014-10-13 18:02:06 -04001178 Params: ip = ip used for the onos cli
1179 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001180 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001181 logLevel = level to log to.
1182 Currently accepts 'info', 'warn' and 'report'
Jon Hall77f53ce2014-10-13 18:02:06 -04001183
1184
kelvin-onlabd3b64892015-01-20 13:26:24 -08001185 logLevel can
Jon Hall77f53ce2014-10-13 18:02:06 -04001186
Jon Hallefbd9792015-03-05 16:11:36 -08001187 Returns: main.TRUE if the number of switches and links are correct,
1188 main.FALSE if the number of switches and links is incorrect,
Jon Hall77f53ce2014-10-13 18:02:06 -04001189 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001190 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001191 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001192 topology = self.getTopology( topologyResult )
Jon Hall77f53ce2014-10-13 18:02:06 -04001193 if topology == {}:
1194 return main.ERROR
1195 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001196 # Is the number of switches is what we expected
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001197 devices = topology.get( 'deviceCount', False )
1198 links = topology.get( 'linkCount', False )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001199 if not devices or not links:
Jon Hall77f53ce2014-10-13 18:02:06 -04001200 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001201 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001202 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001203 linkCheck = ( int( links ) == int( numolink ) )
Jon Hallefbd9792015-03-05 16:11:36 -08001204 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08001205 # We expected the correct numbers
Jon Hall77f53ce2014-10-13 18:02:06 -04001206 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001207 + "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001208 result = main.TRUE
1209 else:
1210 output = output + \
Jon Hall274b6642015-02-17 11:57:17 -08001211 "The number of links and switches does not match " + \
1212 "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001213 result = main.FALSE
Jon Hallefbd9792015-03-05 16:11:36 -08001214 output = output + "\n ONOS sees %i devices" % int( devices )
1215 output = output + " (%i expected) " % int( numoswitch )
Jon Hall274b6642015-02-17 11:57:17 -08001216 output = output + "and %i links " % int( links )
1217 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001218 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001219 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001220 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001221 main.log.warn( output )
Jon Hall77f53ce2014-10-13 18:02:06 -04001222 else:
kelvin8ec71442015-01-15 16:57:00 -08001223 main.log.info( output )
1224 return result
Jon Hall77f53ce2014-10-13 18:02:06 -04001225 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001226 main.log.error( self.name + ": EOF exception found" )
1227 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001228 main.cleanup()
1229 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001230 except Exception:
1231 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001232 main.cleanup()
1233 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001234
kelvin-onlabd3b64892015-01-20 13:26:24 -08001235 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001236 """
andrewonlab970399c2014-11-07 13:09:32 -05001237 Capture all packet activity and store in specified
1238 directory/file
1239
1240 Required:
1241 * interface: interface to capture
1242 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001243 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001244 try:
1245 self.handle.sendline( "" )
1246 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001247
Jon Hallfebb1c72015-03-05 13:30:09 -08001248 self.handle.sendline( "tshark -i " + str( interface ) +
1249 " -t e -w " + str( dirFile ) + " &" )
1250 self.handle.sendline( "\r" )
1251 self.handle.expect( "Capturing on" )
1252 self.handle.sendline( "\r" )
1253 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001254
Jon Hallfebb1c72015-03-05 13:30:09 -08001255 main.log.info( "Tshark started capturing files on " +
1256 str( interface ) + " and saving to directory: " +
1257 str( dirFile ) )
1258 except pexpect.EOF:
1259 main.log.error( self.name + ": EOF exception found" )
1260 main.log.error( self.name + ": " + self.handle.before )
1261 main.cleanup()
1262 main.exit()
1263 except Exception:
1264 main.log.exception( self.name + ": Uncaught exception!" )
1265 main.cleanup()
1266 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001267
kelvin-onlabd3b64892015-01-20 13:26:24 -08001268 def runOnosTopoCfg( self, instanceName, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001269 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001270 On ONOS bench, run this command:
Jon Halle94919c2015-03-23 11:42:57 -07001271 {ONOS_HOME}/tools/test/bin/onos-topo-cfg $OC1 filename
kelvin-onlabd3b64892015-01-20 13:26:24 -08001272 which starts the rest and copies
1273 the json file to the onos instance
kelvin8ec71442015-01-15 16:57:00 -08001274 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001275 try:
kelvin8ec71442015-01-15 16:57:00 -08001276 self.handle.sendline( "" )
1277 self.handle.expect( "\$" )
Jon Halle94919c2015-03-23 11:42:57 -07001278 self.handle.sendline( "cd " + self.home + "/tools/test/bin" )
kelvin8ec71442015-01-15 16:57:00 -08001279 self.handle.expect( "/bin$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001280 cmd = "./onos-topo-cfg " + instanceName + " " + jsonFile
shahshreyae6c7cf42014-11-26 16:39:01 -08001281 print "cmd = ", cmd
kelvin8ec71442015-01-15 16:57:00 -08001282 self.handle.sendline( cmd )
1283 self.handle.expect( "\$" )
1284 self.handle.sendline( "cd ~" )
1285 self.handle.expect( "\$" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001286 return main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -08001287 except pexpect.EOF:
1288 main.log.error( self.name + ": EOF exception found" )
1289 main.log.error( self.name + ": " + self.handle.before )
1290 main.cleanup()
1291 main.exit()
1292 except Exception:
1293 main.log.exception( self.name + ": Uncaught exception!" )
1294 main.cleanup()
1295 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001296
kelvin-onlabd3b64892015-01-20 13:26:24 -08001297 def tsharkGrep( self, grep, directory, interface='eth0' ):
kelvin8ec71442015-01-15 16:57:00 -08001298 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001299 Required:
kelvin8ec71442015-01-15 16:57:00 -08001300 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001301 * directory to store results
1302 Optional:
1303 * interface - default: eth0
1304 Description:
1305 Uses tshark command to grep specific group of packets
1306 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001307 The timestamp is hardcoded to be in epoch
1308 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001309 try:
1310 self.handle.sendline( "" )
1311 self.handle.expect( "\$" )
1312 self.handle.sendline( "" )
1313 self.handle.sendline(
1314 "tshark -i " +
1315 str( interface ) +
1316 " -t e | grep --line-buffered \"" +
1317 str(grep) +
1318 "\" >" +
1319 directory +
1320 " &" )
1321 self.handle.sendline( "\r" )
1322 self.handle.expect( "Capturing on" )
1323 self.handle.sendline( "\r" )
1324 self.handle.expect( "\$" )
1325 except pexpect.EOF:
1326 main.log.error( self.name + ": EOF exception found" )
1327 main.log.error( self.name + ": " + self.handle.before )
1328 main.cleanup()
1329 main.exit()
1330 except Exception:
1331 main.log.exception( self.name + ": Uncaught exception!" )
1332 main.cleanup()
1333 main.exit()
1334
kelvin-onlabd3b64892015-01-20 13:26:24 -08001335 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001336 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001337 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001338 """
1339 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001340 try:
1341 self.execute( cmd="sudo rm /tmp/wireshark*" )
1342 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001343 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1344 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001345 self.handle.sendline( "" )
1346 main.log.info( "Tshark stopped" )
1347 except pexpect.EOF:
1348 main.log.error( self.name + ": EOF exception found" )
1349 main.log.error( self.name + ": " + self.handle.before )
1350 main.cleanup()
1351 main.exit()
1352 except Exception:
1353 main.log.exception( self.name + ": Uncaught exception!" )
1354 main.cleanup()
1355 main.exit()
1356
kelvin8ec71442015-01-15 16:57:00 -08001357 def ptpd( self, args ):
1358 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001359 Initiate ptp with user-specified args.
1360 Required:
1361 * args: specify string of args after command
1362 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001363 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001364 try:
kelvin8ec71442015-01-15 16:57:00 -08001365 self.handle.sendline( "sudo ptpd " + str( args ) )
1366 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001367 "Multiple",
1368 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001369 "\$" ] )
1370 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001371
andrewonlab0c38a4a2014-10-28 18:35:35 -04001372 if i == 0:
1373 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001374 main.log.info( "ptpd returned an error: " +
1375 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001376 return handle
1377 elif i == 1:
1378 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001379 main.log.error( "ptpd returned an error: " +
1380 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001381 return handle
1382 else:
1383 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001384
andrewonlab0c38a4a2014-10-28 18:35:35 -04001385 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001386 main.log.error( self.name + ": EOF exception found" )
1387 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001388 main.cleanup()
1389 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001390 except Exception:
1391 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001392 main.cleanup()
1393 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001394
kelvin-onlabd3b64892015-01-20 13:26:24 -08001395 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001396 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001397 """
1398 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001399 Current implementation of ONOS deletes its karaf
1400 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001401 you may want to use this function to capture
1402 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001403 Localtime will be attached to the filename
1404
1405 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001406 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001407 copy.
kelvin8ec71442015-01-15 16:57:00 -08001408 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001409 For copying multiple files, leave copyFileName
1410 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001411 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001412 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001413 ex ) /tmp/
1414 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001415 * copyFileName: If you want to rename the log
1416 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001417 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001418 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001419 try:
kelvin8ec71442015-01-15 16:57:00 -08001420 localtime = time.strftime( '%x %X' )
1421 localtime = localtime.replace( "/", "" )
1422 localtime = localtime.replace( " ", "_" )
1423 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001424 if destDir[ -1: ] != "/":
1425 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001426
kelvin-onlabd3b64892015-01-20 13:26:24 -08001427 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001428 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1429 str( destDir ) + str( copyFileName ) +
1430 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001431 self.handle.expect( "cp" )
1432 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001433 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001434 self.handle.sendline( "cp " + str( logToCopy ) +
1435 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001436 self.handle.expect( "cp" )
1437 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001438
kelvin8ec71442015-01-15 16:57:00 -08001439 return self.handle.before
1440
1441 except pexpect.EOF:
1442 main.log.error( "Copying files failed" )
1443 main.log.error( self.name + ": EOF exception found" )
1444 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001445 except Exception:
1446 main.log.exception( "Copying files failed" )
1447
kelvin-onlabd3b64892015-01-20 13:26:24 -08001448 def checkLogs( self, onosIp ):
kelvin8ec71442015-01-15 16:57:00 -08001449 """
Jon Hall94fd0472014-12-08 11:52:42 -08001450 runs onos-check-logs on the given onos node
1451 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001452 """
Jon Hall94fd0472014-12-08 11:52:42 -08001453 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001454 cmd = "onos-check-logs " + str( onosIp )
kelvin8ec71442015-01-15 16:57:00 -08001455 self.handle.sendline( cmd )
1456 self.handle.expect( cmd )
1457 self.handle.expect( "\$" )
Jon Hall94fd0472014-12-08 11:52:42 -08001458 response = self.handle.before
1459 return response
1460 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001461 main.log.error( "Lost ssh connection" )
1462 main.log.error( self.name + ": EOF exception found" )
1463 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001464 except Exception:
1465 main.log.exception( self.name + ": Uncaught exception!" )
1466 main.cleanup()
1467 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001468
kelvin-onlabd3b64892015-01-20 13:26:24 -08001469 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001470 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001471 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001472 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001473 try:
kelvin8ec71442015-01-15 16:57:00 -08001474 self.handle.sendline( "" )
1475 self.handle.expect( "\$" )
1476 self.handle.sendline( "onos-service " + str( node ) +
1477 " status" )
1478 i = self.handle.expect( [
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001479 "start/running",
1480 "stop/waiting",
kelvin8ec71442015-01-15 16:57:00 -08001481 pexpect.TIMEOUT ], timeout=120 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001482
1483 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001484 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001485 return main.TRUE
1486 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001487 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001488 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001489 main.cleanup()
1490 main.exit()
1491 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001492 main.log.error( self.name + ": EOF exception found" )
1493 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001494 main.cleanup()
1495 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001496 except Exception:
1497 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001498 main.cleanup()
1499 main.exit()
Jon Hall21270ac2015-02-16 17:59:55 -08001500
Jon Hall63604932015-02-26 17:09:50 -08001501 def setIpTables( self, ip, port='', action='add', packet_type='',
1502 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001503 """
Jon Hall21270ac2015-02-16 17:59:55 -08001504 Description:
1505 add or remove iptables rule to DROP (default) packets from
1506 specific IP and PORT
1507 Usage:
1508 * specify action ('add' or 'remove')
1509 when removing, pass in the same argument as you would add. It will
1510 delete that specific rule.
1511 * specify the ip to block
1512 * specify the destination port to block (defaults to all ports)
1513 * optional packet type to block (default tcp)
1514 * optional iptables rule (default DROP)
1515 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001516 * States boolean toggles adding all supported tcp states to the
1517 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001518 Returns:
1519 main.TRUE on success or
1520 main.FALSE if given invalid input or
1521 main.ERROR if there is an error in response from iptables
1522 WARNING:
1523 * This function uses root privilege iptables command which may result
1524 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001525 """
Jon Hall21270ac2015-02-16 17:59:55 -08001526 import time
1527
1528 # NOTE*********
1529 # The strict checking methods of this driver function is intentional
1530 # to discourage any misuse or error of iptables, which can cause
1531 # severe network errors
1532 # *************
1533
1534 # NOTE: Sleep needed to give some time for rule to be added and
1535 # registered to the instance. If you are calling this function
1536 # multiple times this sleep will prevent any errors.
1537 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001538 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001539 try:
1540 # input validation
1541 action_type = action.lower()
1542 rule = rule.upper()
1543 direction = direction.upper()
1544 if action_type != 'add' and action_type != 'remove':
1545 main.log.error( "Invalid action type. Use 'add' or "
1546 "'remove' table rule" )
1547 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1548 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1549 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1550 "'ACCEPT' or 'LOG' only." )
1551 if direction != 'INPUT' and direction != 'OUTPUT':
1552 # NOTE currently only supports rules INPUT and OUPTUT
1553 main.log.error( "Invalid rule. Valid directions are"
1554 " 'OUTPUT' or 'INPUT'" )
1555 return main.FALSE
1556 return main.FALSE
1557 return main.FALSE
1558 if action_type == 'add':
1559 # -A is the 'append' action of iptables
1560 actionFlag = '-A'
1561 elif action_type == 'remove':
1562 # -D is the 'delete' rule of iptables
1563 actionFlag = '-D'
1564 self.handle.sendline( "" )
1565 self.handle.expect( "\$" )
1566 cmd = "sudo iptables " + actionFlag + " " +\
1567 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001568 " -s " + str( ip )
Jon Hall63604932015-02-26 17:09:50 -08001569 # " -p " + str( packet_type ) +\
1570 if packet_type:
1571 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001572 if port:
1573 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001574 if states:
1575 cmd += " -m state --state="
1576 #FIXME- Allow user to configure which states to block
1577 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001578 cmd += " -j " + str( rule )
1579
1580 self.handle.sendline( cmd )
1581 self.handle.expect( "\$" )
1582 main.log.warn( self.handle.before )
1583
1584 info_string = "On " + str( self.name )
1585 info_string += " " + str( action_type )
1586 info_string += " iptable rule [ "
1587 info_string += " IP: " + str( ip )
1588 info_string += " Port: " + str( port )
1589 info_string += " Rule: " + str( rule )
1590 info_string += " Direction: " + str( direction ) + " ]"
1591 main.log.info( info_string )
1592 return main.TRUE
1593 except pexpect.TIMEOUT:
1594 main.log.exception( self.name + ": Timeout exception in "
1595 "setIpTables function" )
1596 return main.ERROR
1597 except pexpect.EOF:
1598 main.log.error( self.name + ": EOF exception found" )
1599 main.log.error( self.name + ": " + self.handle.before )
1600 main.cleanup()
1601 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001602 except Exception:
1603 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall21270ac2015-02-16 17:59:55 -08001604 main.cleanup()
1605 main.exit()
1606
Jon Hall0468b042015-02-19 19:08:21 -08001607 def detailed_status(self, log_filename):
Jon Hallefbd9792015-03-05 16:11:36 -08001608 """
Jon Hall0468b042015-02-19 19:08:21 -08001609 This method is used by STS to check the status of the controller
1610 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001611 """
Jon Hall0468b042015-02-19 19:08:21 -08001612 import re
1613 try:
1614 self.handle.sendline( "" )
1615 self.handle.expect( "\$" )
1616 self.handle.sendline( "cd " + self.home )
1617 self.handle.expect( "\$" )
1618 self.handle.sendline( "service onos status" )
1619 self.handle.expect( "\$" )
1620 response = self.handle.before
1621 if re.search( "onos start/running", response ):
1622 # onos start/running, process 10457
1623 return 'RUNNING'
1624 # FIXME: Implement this case
1625 # elif re.search( pattern, response ):
1626 # return 'STARTING'
1627 elif re.search( "onos stop/", response ):
1628 # onos stop/waiting
1629 # FIXME handle this differently?: onos stop/pre-stop
1630 return 'STOPPED'
1631 # FIXME: Implement this case
1632 # elif re.search( pattern, response ):
1633 # return 'FROZEN'
1634 else:
1635 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001636 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001637 main.log.warn( response )
1638 return 'ERROR', "Unknown response: %s" % response
1639 except pexpect.TIMEOUT:
1640 main.log.exception( self.name + ": Timeout exception in "
1641 "setIpTables function" )
1642 return 'ERROR', "Pexpect Timeout"
1643 except pexpect.EOF:
1644 main.log.error( self.name + ": EOF exception found" )
1645 main.log.error( self.name + ": " + self.handle.before )
1646 main.cleanup()
1647 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001648 except Exception:
1649 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall0468b042015-02-19 19:08:21 -08001650 main.cleanup()
1651 main.exit()
1652
andrew@onlab.us3b087132015-03-11 15:00:08 -07001653 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1654 '''
1655 Create/formats the LinkGraph.cfg file based on arguments
1656 -only creates a linear topology and connects islands
1657 -evenly distributes devices
1658 -must be called by ONOSbench
1659
1660 ONOSIpList - list of all of the node IPs to be used
1661
1662 deviceCount - number of switches to be assigned
1663 '''
1664 main.log.step("Creating link graph configuration file." )
1665 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
1666 tempFile = "/tmp/linkGraph.cfg"
1667
1668 linkGraph = open(tempFile, 'w+')
1669 linkGraph.write("# NullLinkProvider topology description (config file).\n")
1670 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
1671 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
1672
1673 clusterCount = len(ONOSIpList)
1674
1675 if type(deviceCount) is int or type(deviceCount) is str:
1676 deviceCount = int(deviceCount)
1677 switchList = [0]*(clusterCount+1)
1678 baselineSwitchCount = deviceCount/clusterCount
1679
1680 for node in range(1, clusterCount + 1):
1681 switchList[node] = baselineSwitchCount
1682
1683 for node in range(1, (deviceCount%clusterCount)+1):
1684 switchList[node] += 1
1685
1686 if type(deviceCount) is list:
1687 main.log.info("Using provided device distribution")
1688 switchList = [0]
1689 for i in deviceCount:
1690 switchList.append(int(i))
1691
1692 tempList = ['0']
1693 tempList.extend(ONOSIpList)
1694 ONOSIpList = tempList
1695
1696 myPort = 6
1697 lastSwitch = 0
1698 for node in range(1, clusterCount+1):
1699 if switchList[node] == 0:
1700 continue
1701
1702 linkGraph.write("graph " + ONOSIpList[node] + " {\n")
1703
1704 if node > 1:
1705 #connect to last device on previous node
1706 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
1707 linkGraph.write(line)
1708
1709 lastSwitch = 0
1710 for switch in range (0, switchList[node]-1):
1711 line = ""
1712 line = ("\t" + str(switch) + ":" + str(myPort))
1713 line += " -- "
1714 line += (str(switch+1) + ":" + str(myPort-1) + "\n")
1715 linkGraph.write(line)
1716 lastSwitch = switch+1
1717 lastIp = ONOSIpList[node]
1718
1719 #lastSwitch += 1
1720 if node < (clusterCount):
1721 #connect to first device on the next node
1722 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
1723 linkGraph.write(line)
1724
1725 linkGraph.write("}\n")
1726 linkGraph.close()
1727
1728 #SCP
1729 os.system( "scp " + tempFile + " admin@" + benchIp + ":" + linkGraphPath)
1730 main.log.info("linkGraph.cfg creation complete")
1731
cameron@onlab.us75900962015-03-30 13:22:49 -07001732 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001733
1734 '''
andrew@onlab.us3b087132015-03-11 15:00:08 -07001735 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
cameron@onlab.us75900962015-03-30 13:22:49 -07001736 deviceCount = number of switches to distribute, or list of values to use as custom distribution
1737 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 -07001738 '''
1739
cameron@onlab.us75900962015-03-30 13:22:49 -07001740 main.log.step("Configuring Null Device Provider" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07001741 clusterCount = len(ONOSIpList)
1742
cameron@onlab.us75900962015-03-30 13:22:49 -07001743 try:
1744
1745 if type(deviceCount) is int or type(deviceCount) is str:
1746 main.log.step("Creating device distribution")
1747 deviceCount = int(deviceCount)
1748 switchList = [0]*(clusterCount+1)
1749 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001750
cameron@onlab.us75900962015-03-30 13:22:49 -07001751 for node in range(1, clusterCount + 1):
1752 switchList[node] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001753
cameron@onlab.us75900962015-03-30 13:22:49 -07001754 for node in range(1, (deviceCount%clusterCount)+1):
1755 switchList[node] += 1
1756
1757 if type(deviceCount) is list:
1758 main.log.info("Using provided device distribution")
1759
1760 if len(deviceCount) == clusterCount:
1761 switchList = ['0']
1762 switchList.extend(deviceCount)
1763
1764 if len(deviceCount) == (clusterCount + 1):
1765 if deviceCount[0] == '0' or deviceCount[0] == 0:
1766 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001767
cameron@onlab.us75900962015-03-30 13:22:49 -07001768 assert len(switchList) == (clusterCount + 1)
1769
1770 except AssertionError:
1771 main.log.error( "Bad device/Ip list match")
1772 except TypeError:
1773 main.log.exception( self.name + ": Object not as expected" )
1774 return None
1775 except:
1776 main.log.exception( self.name + ": Uncaught exception!" )
1777 main.cleanup()
1778 main.exit()
1779
andrew@onlab.us3b087132015-03-11 15:00:08 -07001780
1781 ONOSIp = [0]
1782 ONOSIp.extend(ONOSIpList)
1783
1784 devicesString = "devConfigs = "
1785 for node in range(1, len(ONOSIp)):
1786 devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
1787 if node < clusterCount:
1788 devicesString += (",")
cameron@onlab.us75900962015-03-30 13:22:49 -07001789
1790 try:
1791 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
1792 self.handle.expect(":~")
1793 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) )
1794 self.handle.expect(":~")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001795
cameron@onlab.us75900962015-03-30 13:22:49 -07001796 for i in range(10):
1797 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider")
1798 self.handle.expect(":~")
1799 verification = self.handle.before
1800 if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification:
1801 break
1802 else:
1803 time.sleep(1)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001804
cameron@onlab.us75900962015-03-30 13:22:49 -07001805 assert ("value=" + str(numPorts)) in verification and (" value=" + fileName) in verification
1806
1807 except AssertionError:
1808 main.log.error("Incorrect Config settings: " + verification)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001809
cameron@onlab.us75900962015-03-30 13:22:49 -07001810 except:
1811 main.log.exception( self.name + ": Uncaught exception!" )
1812 main.cleanup()
1813 main.exit()
1814
1815 def configNullLink( self,fileName="/opt/onos/apache-karaf-3.0.2/etc/linkGraph.cfg", eventRate=0):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001816 '''
cameron@onlab.us75900962015-03-30 13:22:49 -07001817 fileName default is currently the same as the default on ONOS, specify alternate file if
1818 you want to use a different topology file than linkGraph.cfg
andrew@onlab.us3b087132015-03-11 15:00:08 -07001819 '''
1820
andrew@onlab.us3b087132015-03-11 15:00:08 -07001821
cameron@onlab.us75900962015-03-30 13:22:49 -07001822 try:
1823 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str(eventRate))
1824 self.handle.expect(":~")
1825 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
1826 self.handle.expect(":~")
1827
1828 for i in range(10):
1829 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider")
1830 self.handle.expect(":~")
1831 verification = self.handle.before
1832 if (" value=" + str(eventRate)) in verification and (" value=" + fileName) in verification:
1833 break
1834 else:
1835 time.sleep(1)
1836
1837 assert ("value=" + str(eventRate)) in verification and (" value=" + fileName) in verification
1838
1839 except pexpect.EOF:
1840 main.log.error( self.name + ": EOF exception found" )
1841 main.log.error( self.name + ": " + self.handle.before )
1842 main.cleanup()
1843 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07001844
cameron@onlab.us75900962015-03-30 13:22:49 -07001845 except AssertionError:
1846 main.log.info("Settings did not post to ONOS")
1847 main.log.error(varification)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001848
cameron@onlab.us75900962015-03-30 13:22:49 -07001849 except:
1850 main.log.exception( self.name + ": Uncaught exception!" )
1851 main.log.error(varification)
1852 main.cleanup()
1853 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07001854