blob: 8d95cfc19221d6a2475f66281b2922498418ca4c [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
pingping-lin6d23d9e2015-02-02 16:54:24 -080023from requests.models import Response
kelvin8ec71442015-01-15 16:57:00 -080024sys.path.append( "../" )
Jon Hall05b2b432014-10-08 19:53:25 -040025from drivers.common.clidriver import CLI
26
Jon Hall05b2b432014-10-08 19:53:25 -040027
kelvin8ec71442015-01-15 16:57:00 -080028class OnosDriver( CLI ):
Jon Hall05b2b432014-10-08 19:53:25 -040029
kelvin8ec71442015-01-15 16:57:00 -080030 def __init__( self ):
31 """
32 Initialize client
33 """
Jon Hallefbd9792015-03-05 16:11:36 -080034 self.name = None
35 self.home = None
36 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080037 super( CLI, self ).__init__()
38
39 def connect( self, **connectargs ):
40 """
Jon Hall05b2b432014-10-08 19:53:25 -040041 Creates ssh handle for ONOS "bench".
kelvin8ec71442015-01-15 16:57:00 -080042 """
Jon Hall05b2b432014-10-08 19:53:25 -040043 try:
44 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080045 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us3b087132015-03-11 15:00:08 -070046 self.home = "~/onos"
Jon Hall05b2b432014-10-08 19:53:25 -040047 for key in self.options:
48 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080049 self.home = self.options[ 'home' ]
Jon Hall05b2b432014-10-08 19:53:25 -040050 break
Jon Hall274b6642015-02-17 11:57:17 -080051 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070052 self.home = "~/onos"
Jon Hall21270ac2015-02-16 17:59:55 -080053
kelvin8ec71442015-01-15 16:57:00 -080054 self.name = self.options[ 'name' ]
55 self.handle = super( OnosDriver, self ).connect(
56 user_name=self.user_name,
kelvin-onlab08679eb2015-01-21 16:11:48 -080057 ip_address=self.ip_address,
kelvin-onlabd3b64892015-01-20 13:26:24 -080058 port=self.port,
59 pwd=self.pwd,
60 home=self.home )
Jon Hall05b2b432014-10-08 19:53:25 -040061
kelvin8ec71442015-01-15 16:57:00 -080062 self.handle.sendline( "cd " + self.home )
63 self.handle.expect( "\$" )
Jon Hall05b2b432014-10-08 19:53:25 -040064 if self.handle:
65 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080066 else:
67 main.log.info( "NO ONOS HANDLE" )
Jon Hall05b2b432014-10-08 19:53:25 -040068 return main.FALSE
69 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080070 main.log.error( self.name + ": EOF exception found" )
71 main.log.error( self.name + ": " + self.handle.before )
Jon Hall05b2b432014-10-08 19:53:25 -040072 main.cleanup()
73 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080074 except Exception:
75 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall05b2b432014-10-08 19:53:25 -040076 main.cleanup()
77 main.exit()
78
kelvin8ec71442015-01-15 16:57:00 -080079 def disconnect( self ):
80 """
Jon Hall05b2b432014-10-08 19:53:25 -040081 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -080082 """
Jon Halld61331b2015-02-17 16:35:47 -080083 response = main.TRUE
Jon Hall05b2b432014-10-08 19:53:25 -040084 try:
Jon Hall61282e32015-03-19 11:34:11 -070085 if self.handle:
86 self.handle.sendline( "" )
87 self.handle.expect( "\$" )
88 self.handle.sendline( "exit" )
89 self.handle.expect( "closed" )
Jon Hall05b2b432014-10-08 19:53:25 -040090 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080091 main.log.error( self.name + ": EOF exception found" )
92 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -070093 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -070094 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -070095 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -080096 except Exception:
97 main.log.exception( self.name + ": Connection failed to the host" )
Jon Hall05b2b432014-10-08 19:53:25 -040098 response = main.FALSE
99 return response
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400100
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400101 def getEpochMs( self ):
102 """
103 Returns milliseconds since epoch
104
105 When checking multiple nodes in a for loop,
106 around a hundred milliseconds of difference (ascending) is
107 generally acceptable due to calltime of the function.
108 Few seconds, however, is not and it means clocks
109 are off sync.
110 """
111 try:
112 self.handle.sendline( 'date +%s.%N' )
113 self.handle.expect( 'date \+\%s\.\%N' )
114 self.handle.expect( '\$' )
115 epochMs = self.handle.before
116 return epochMs
117 except Exception:
118 main.log.exception( 'Uncaught exception getting epoch time' )
119 main.cleanup()
120 main.exit()
121
pingping-lin57a56ce2015-05-20 16:43:48 -0700122 def onosPackage( self, opTimeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800123 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400124 Produce a self-contained tar.gz file that can be deployed
kelvin8ec71442015-01-15 16:57:00 -0800125 and executed on any platform with Java 7 JRE.
126 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400127 try:
kelvin8ec71442015-01-15 16:57:00 -0800128 self.handle.sendline( "onos-package" )
129 self.handle.expect( "onos-package" )
pingping-lin57a56ce2015-05-20 16:43:48 -0700130 self.handle.expect( "tar.gz", opTimeout )
kelvin8ec71442015-01-15 16:57:00 -0800131 handle = str( self.handle.before )
132 main.log.info( "onos-package command returned: " +
133 handle )
134 # As long as the sendline does not time out,
135 # return true. However, be careful to interpret
136 # the results of the onos-package command return
andrewonlab0748d2a2014-10-09 13:24:17 -0400137 return main.TRUE
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400138
andrewonlab7735d852014-10-09 13:02:47 -0400139 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800140 main.log.error( self.name + ": EOF exception found" )
141 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800142 except Exception:
143 main.log.exception( "Failed to package ONOS" )
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400144 main.cleanup()
145 main.exit()
146
kelvin-onlabd3b64892015-01-20 13:26:24 -0800147 def onosBuild( self ):
kelvin8ec71442015-01-15 16:57:00 -0800148 """
andrewonlab8790abb2014-11-06 13:51:54 -0500149 Use the pre defined script to build onos via mvn
kelvin8ec71442015-01-15 16:57:00 -0800150 """
andrewonlab8790abb2014-11-06 13:51:54 -0500151 try:
kelvin8ec71442015-01-15 16:57:00 -0800152 self.handle.sendline( "onos-build" )
153 self.handle.expect( "onos-build" )
154 i = self.handle.expect( [
kelvin-onlabd3b64892015-01-20 13:26:24 -0800155 "BUILD SUCCESS",
156 "ERROR",
157 "BUILD FAILED" ],
158 timeout=120 )
kelvin8ec71442015-01-15 16:57:00 -0800159 handle = str( self.handle.before )
andrewonlab8790abb2014-11-06 13:51:54 -0500160
kelvin8ec71442015-01-15 16:57:00 -0800161 main.log.info( "onos-build command returned: " +
162 handle )
andrewonlab8790abb2014-11-06 13:51:54 -0500163
164 if i == 0:
165 return main.TRUE
166 else:
167 return handle
168
169 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800170 main.log.error( self.name + ": EOF exception found" )
171 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800172 except Exception:
173 main.log.exception( "Failed to build ONOS" )
andrewonlab8790abb2014-11-06 13:51:54 -0500174 main.cleanup()
175 main.exit()
176
shahshreya9f531fe2015-06-10 12:03:51 -0700177 def cleanInstall( self, skipTest=False, mciTimeout=600 ):
kelvin8ec71442015-01-15 16:57:00 -0800178 """
179 Runs mvn clean install in the root of the ONOS directory.
180 This will clean all ONOS artifacts then compile each module
shahshreya9f531fe2015-06-10 12:03:51 -0700181 Optional:
182 skipTest - Does "-DskipTests -Dcheckstyle.skip -U -T 1C" which
183 skip the test. This will make the building faster.
184 Disregarding the credibility of the build
kelvin8ec71442015-01-15 16:57:00 -0800185 Returns: main.TRUE on success
Jon Hallde9d9aa2014-10-08 20:36:02 -0400186 On Failure, exits the test
kelvin8ec71442015-01-15 16:57:00 -0800187 """
Jon Hallde9d9aa2014-10-08 20:36:02 -0400188 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800189 main.log.info( "Running 'mvn clean install' on " +
190 str( self.name ) +
kelvin8ec71442015-01-15 16:57:00 -0800191 ". This may take some time." )
192 self.handle.sendline( "cd " + self.home )
193 self.handle.expect( "\$" )
Jon Hallea7818b2014-10-09 14:30:59 -0400194
kelvin8ec71442015-01-15 16:57:00 -0800195 self.handle.sendline( "" )
196 self.handle.expect( "\$" )
shahshreya9f531fe2015-06-10 12:03:51 -0700197
198 if not skipTest:
199 self.handle.sendline( "mvn clean install" )
200 self.handle.expect( "mvn clean install" )
201 else:
202 self.handle.sendline( "mvn clean install -DskipTests" +
203 " -Dcheckstyle.skip -U -T 1C" )
204 self.handle.expect( "mvn clean install -DskipTests" +
205 " -Dcheckstyle.skip -U -T 1C" )
kelvin8ec71442015-01-15 16:57:00 -0800206 while True:
207 i = self.handle.expect( [
Jon Hall274b6642015-02-17 11:57:17 -0800208 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
Jon Hallefbd9792015-03-05 16:11:36 -0800209 'Runtime\sEnvironment\sto\scontinue',
Jon Hallde9d9aa2014-10-08 20:36:02 -0400210 'BUILD\sFAILURE',
211 'BUILD\sSUCCESS',
Jon Halle94919c2015-03-23 11:42:57 -0700212 'onos\$', #TODO: fix this to be more generic?
Jon Hallde9d9aa2014-10-08 20:36:02 -0400213 'ONOS\$',
pingping-lin57a56ce2015-05-20 16:43:48 -0700214 pexpect.TIMEOUT ], mciTimeout )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400215 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800216 main.log.error( self.name + ":There is insufficient memory \
217 for the Java Runtime Environment to continue." )
218 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400219 main.cleanup()
220 main.exit()
221 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800222 main.log.error( self.name + ": Build failure!" )
223 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400224 main.cleanup()
225 main.exit()
226 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800227 main.log.info( self.name + ": Build success!" )
Jon Halle94919c2015-03-23 11:42:57 -0700228 elif i == 3 or i == 4:
kelvin8ec71442015-01-15 16:57:00 -0800229 main.log.info( self.name + ": Build complete" )
230 # Print the build time
Jon Hallf8ef52c2014-10-09 19:37:33 -0400231 for line in self.handle.before.splitlines():
232 if "Total time:" in line:
kelvin8ec71442015-01-15 16:57:00 -0800233 main.log.info( line )
234 self.handle.sendline( "" )
235 self.handle.expect( "\$", timeout=60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400236 return main.TRUE
Jon Halle94919c2015-03-23 11:42:57 -0700237 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800238 main.log.error(
239 self.name +
240 ": mvn clean install TIMEOUT!" )
241 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400242 main.cleanup()
243 main.exit()
244 else:
Jon Hall274b6642015-02-17 11:57:17 -0800245 main.log.error( self.name + ": unexpected response from " +
Jon Hallefbd9792015-03-05 16:11:36 -0800246 "mvn clean install" )
kelvin8ec71442015-01-15 16:57:00 -0800247 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400248 main.cleanup()
249 main.exit()
250 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800251 main.log.error( self.name + ": EOF exception found" )
252 main.log.error( self.name + ": " + self.handle.before )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400253 main.cleanup()
254 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800255 except Exception:
256 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400257 main.cleanup()
258 main.exit()
Jon Hallacabffd2014-10-09 12:36:53 -0400259
Jon Hall61282e32015-03-19 11:34:11 -0700260 def gitPull( self, comp1="", fastForward=True ):
kelvin8ec71442015-01-15 16:57:00 -0800261 """
Jon Hallacabffd2014-10-09 12:36:53 -0400262 Assumes that "git pull" works without login
Jon Hall47a93fb2015-01-06 16:46:06 -0800263
Jon Hall61282e32015-03-19 11:34:11 -0700264 If the fastForward boolean is set to true, only git pulls that can
265 be fast forwarded will be performed. IE if you have not local commits
266 in your branch.
267
Jon Hallacabffd2014-10-09 12:36:53 -0400268 This function will perform a git pull on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800269 If used as gitPull( "NODE" ) it will do git pull + NODE. This is
Jon Hallacabffd2014-10-09 12:36:53 -0400270 for the purpose of pulling from other nodes if necessary.
271
Jon Hall47a93fb2015-01-06 16:46:06 -0800272 Otherwise, this function will perform a git pull in the
Jon Hallacabffd2014-10-09 12:36:53 -0400273 ONOS repository. If it has any problems, it will return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -0800274 If it successfully does a gitPull, it will return a 1 ( main.TRUE )
Shreya Shahee15f6c2014-10-28 18:12:30 -0400275 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400276
kelvin8ec71442015-01-15 16:57:00 -0800277 """
Jon Hallacabffd2014-10-09 12:36:53 -0400278 try:
kelvin8ec71442015-01-15 16:57:00 -0800279 # main.log.info( self.name + ": Stopping ONOS" )
280 # self.stop()
281 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800282 self.handle.expect( self.home + "\$" )
Jon Hall61282e32015-03-19 11:34:11 -0700283 cmd = "git pull"
284 if comp1 != "":
285 cmd += ' ' + comp1
286 if fastForward:
287 cmd += ' ' + " --ff-only"
288 self.handle.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800289 i = self.handle.expect(
290 [
291 'fatal',
292 'Username\sfor\s(.*):\s',
293 '\sfile(s*) changed,\s',
294 'Already up-to-date',
295 'Aborting',
296 'You\sare\snot\scurrently\son\sa\sbranch',
Jon Hall274b6642015-02-17 11:57:17 -0800297 'You asked me to pull without telling me which branch you',
298 'Pull is not possible because you have unmerged files',
Jon Hall61282e32015-03-19 11:34:11 -0700299 'Please enter a commit message to explain why this merge',
300 'Found a swap file by the name',
301 'Please, commit your changes before you can merge.',
kelvin-onlabd3b64892015-01-20 13:26:24 -0800302 pexpect.TIMEOUT ],
303 timeout=300 )
kelvin8ec71442015-01-15 16:57:00 -0800304 # debug
kelvin-onlabd3b64892015-01-20 13:26:24 -0800305 # main.log.report( self.name +": DEBUG: \n"+
306 # "git pull response: " +
307 # str( self.handle.before ) + str( self.handle.after ) )
kelvin8ec71442015-01-15 16:57:00 -0800308 if i == 0:
Jon Hall61282e32015-03-19 11:34:11 -0700309 main.log.error( self.name + ": Git pull had some issue" )
310 output = self.handle.after
311 self.handle.expect( '\$' )
312 output += self.handle.before
313 main.log.warn( output )
Jon Hallacabffd2014-10-09 12:36:53 -0400314 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800315 elif i == 1:
316 main.log.error(
317 self.name +
318 ": Git Pull Asking for username. " )
Jon Hallacabffd2014-10-09 12:36:53 -0400319 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800320 elif i == 2:
321 main.log.info(
322 self.name +
323 ": Git Pull - pulling repository now" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800324 self.handle.expect( self.home + "\$", 120 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800325 # So that only when git pull is done, we do mvn clean compile
326 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800327 elif i == 3:
328 main.log.info( self.name + ": Git Pull - Already up to date" )
Jon Hall47a93fb2015-01-06 16:46:06 -0800329 return i
kelvin8ec71442015-01-15 16:57:00 -0800330 elif i == 4:
331 main.log.info(
332 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800333 ": Git Pull - Aborting..." +
334 "Are there conflicting git files?" )
Jon Hallacabffd2014-10-09 12:36:53 -0400335 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800336 elif i == 5:
337 main.log.info(
338 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800339 ": Git Pull - You are not currently " +
340 "on a branch so git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400341 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800342 elif i == 6:
343 main.log.info(
344 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800345 ": Git Pull - You have not configured an upstream " +
346 "branch to pull from. Git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400347 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800348 elif i == 7:
349 main.log.info(
350 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800351 ": Git Pull - Pull is not possible because " +
352 "you have unmerged files." )
Jon Hallacabffd2014-10-09 12:36:53 -0400353 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800354 elif i == 8:
Jon Hall61282e32015-03-19 11:34:11 -0700355 # NOTE: abandoning test since we can't reliably handle this
356 # there could be different default text editors and we
357 # also don't know if we actually want to make the commit
358 main.log.error( "Git pull resulted in a merge commit message" +
359 ". Exiting test!" )
360 main.cleanup()
361 main.exit()
362 elif i == 9: # Merge commit message but swap file exists
363 main.log.error( "Git pull resulted in a merge commit message" +
364 " but a swap file exists." )
365 try:
366 self.handle.send( 'A' ) # Abort
367 self.handle.expect( "\$" )
368 return main.ERROR
369 except Exception:
370 main.log.exception( "Couldn't exit editor prompt!")
371 main.cleanup()
372 main.exit()
373 elif i == 10: # In the middle of a merge commit
374 main.log.error( "Git branch is in the middle of a merge. " )
375 main.log.warn( self.handle.before + self.handle.after )
376 return main.ERROR
377 elif i == 11:
kelvin8ec71442015-01-15 16:57:00 -0800378 main.log.error( self.name + ": Git Pull - TIMEOUT" )
379 main.log.error(
380 self.name + " Response was: " + str(
381 self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400382 return main.ERROR
383 else:
kelvin8ec71442015-01-15 16:57:00 -0800384 main.log.error(
385 self.name +
386 ": Git Pull - Unexpected response, check for pull errors" )
Jon Hallacabffd2014-10-09 12:36:53 -0400387 return main.ERROR
388 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800389 main.log.error( self.name + ": EOF exception found" )
390 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400391 main.cleanup()
392 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800393 except Exception:
394 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400395 main.cleanup()
396 main.exit()
397
kelvin-onlabd3b64892015-01-20 13:26:24 -0800398 def gitCheckout( self, branch="master" ):
kelvin8ec71442015-01-15 16:57:00 -0800399 """
Jon Hallacabffd2014-10-09 12:36:53 -0400400 Assumes that "git pull" works without login
kelvin8ec71442015-01-15 16:57:00 -0800401
Jon Hallacabffd2014-10-09 12:36:53 -0400402 This function will perform a git git checkout on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800403 If used as gitCheckout( "branch" ) it will do git checkout
404 of the "branch".
Jon Hallacabffd2014-10-09 12:36:53 -0400405
406 Otherwise, this function will perform a git checkout of the master
kelvin8ec71442015-01-15 16:57:00 -0800407 branch of the ONOS repository. If it has any problems, it will return
408 main.ERROR.
409 If the branch was already the specified branch, or the git checkout was
Jon Hallacabffd2014-10-09 12:36:53 -0400410 successful then the function will return main.TRUE.
411
kelvin8ec71442015-01-15 16:57:00 -0800412 """
Jon Hallacabffd2014-10-09 12:36:53 -0400413 try:
kelvin8ec71442015-01-15 16:57:00 -0800414 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800415 self.handle.expect( self.home + "\$" )
Jon Hall274b6642015-02-17 11:57:17 -0800416 main.log.info( self.name +
417 ": Checking out git branch/ref: " + branch + "..." )
kelvin8ec71442015-01-15 16:57:00 -0800418 cmd = "git checkout " + branch
419 self.handle.sendline( cmd )
420 self.handle.expect( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800421 i = self.handle.expect(
Jon Hall274b6642015-02-17 11:57:17 -0800422 [ 'fatal',
Jon Hall61282e32015-03-19 11:34:11 -0700423 'Username for (.*): ',
424 'Already on \'',
Jon Hall7a8354f2015-06-10 15:37:00 -0700425 'Switched to (a new )?branch \'' + str( branch ),
Jon Hall274b6642015-02-17 11:57:17 -0800426 pexpect.TIMEOUT,
427 'error: Your local changes to the following files' +
Jon Hallefbd9792015-03-05 16:11:36 -0800428 'would be overwritten by checkout:',
Jon Hall274b6642015-02-17 11:57:17 -0800429 'error: you need to resolve your current index first',
430 "You are in 'detached HEAD' state.",
431 "HEAD is now at " ],
kelvin-onlabd3b64892015-01-20 13:26:24 -0800432 timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -0800433 if i == 0:
434 main.log.error(
435 self.name +
436 ": Git checkout had some issue..." )
437 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400438 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800439 elif i == 1:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800440 main.log.error(
441 self.name +
442 ": Git checkout asking for username." +
443 " Please configure your local git repository to be able " +
444 "to access your remote repository passwordlessly" )
Jon Hall274b6642015-02-17 11:57:17 -0800445 # TODO add support for authenticating
Jon Hallacabffd2014-10-09 12:36:53 -0400446 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800447 elif i == 2:
448 main.log.info(
449 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800450 ": Git Checkout %s : Already on this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800451 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800452 # main.log.info( "DEBUG: after checkout cmd = "+
453 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400454 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800455 elif i == 3:
456 main.log.info(
457 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800458 ": Git checkout %s - Switched to this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800459 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800460 # main.log.info( "DEBUG: after checkout cmd = "+
461 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400462 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800463 elif i == 4:
464 main.log.error( self.name + ": Git Checkout- TIMEOUT" )
465 main.log.error(
Jon Hall274b6642015-02-17 11:57:17 -0800466 self.name + " Response was: " + str( self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400467 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800468 elif i == 5:
469 self.handle.expect( "Aborting" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800470 main.log.error(
471 self.name +
472 ": Git checkout error: \n" +
Jon Hall274b6642015-02-17 11:57:17 -0800473 "Your local changes to the following files would" +
474 " be overwritten by checkout:" +
475 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800476 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500477 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800478 elif i == 6:
Jon Hall274b6642015-02-17 11:57:17 -0800479 main.log.error(
480 self.name +
481 ": Git checkout error: \n" +
482 "You need to resolve your current index first:" +
483 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800484 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500485 return main.ERROR
Jon Hall274b6642015-02-17 11:57:17 -0800486 elif i == 7:
487 main.log.info(
488 self.name +
489 ": Git checkout " + str( branch ) +
490 " - You are in 'detached HEAD' state. HEAD is now at " +
491 str( branch ) )
492 self.handle.expect( self.home + "\$" )
493 return main.TRUE
494 elif i == 8: # Already in detached HEAD on the specified commit
495 main.log.info(
496 self.name +
497 ": Git Checkout %s : Already on commit" % branch )
498 self.handle.expect( self.home + "\$" )
499 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400500 else:
kelvin8ec71442015-01-15 16:57:00 -0800501 main.log.error(
502 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800503 ": Git Checkout - Unexpected response, " +
504 "check for pull errors" )
kelvin8ec71442015-01-15 16:57:00 -0800505 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400506 return main.ERROR
507
508 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800509 main.log.error( self.name + ": EOF exception found" )
510 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400511 main.cleanup()
512 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800513 except Exception:
514 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400515 main.cleanup()
516 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400517
pingping-lin6d23d9e2015-02-02 16:54:24 -0800518 def getBranchName( self ):
pingping-linf30cf272015-05-29 15:54:07 -0700519 main.log.info( "self.home = " )
520 main.log.info( self.home )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800521 self.handle.sendline( "cd " + self.home )
pingping-lin9bf3d8f2015-05-29 16:05:28 -0700522 self.handle.expect( self.home + "\$" )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800523 self.handle.sendline( "git name-rev --name-only HEAD" )
524 self.handle.expect( "git name-rev --name-only HEAD" )
525 self.handle.expect( "\$" )
526
527 lines = self.handle.before.splitlines()
528 if lines[1] == "master":
529 return "master"
530 elif lines[1] == "onos-1.0":
531 return "onos-1.0"
532 else:
533 main.log.info( lines[1] )
534 return "unexpected ONOS branch for SDN-IP test"
535
kelvin-onlabd3b64892015-01-20 13:26:24 -0800536 def getVersion( self, report=False ):
kelvin8ec71442015-01-15 16:57:00 -0800537 """
Jon Hall274b6642015-02-17 11:57:17 -0800538 Writes the COMMIT number to the report to be parsed
Jon Hallefbd9792015-03-05 16:11:36 -0800539 by Jenkins data collector.
kelvin8ec71442015-01-15 16:57:00 -0800540 """
Jon Hall45ec0922014-10-10 19:33:49 -0400541 try:
kelvin8ec71442015-01-15 16:57:00 -0800542 self.handle.sendline( "" )
543 self.handle.expect( "\$" )
544 self.handle.sendline(
545 "cd " +
546 self.home +
Jon Hall274b6642015-02-17 11:57:17 -0800547 "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " +
548 " \"commit\" --color=never" )
kelvin8ec71442015-01-15 16:57:00 -0800549 # NOTE: for some reason there are backspaces inserted in this
550 # phrase when run from Jenkins on some tests
551 self.handle.expect( "never" )
552 self.handle.expect( "\$" )
553 response = ( self.name + ": \n" + str(
554 self.handle.before + self.handle.after ) )
555 self.handle.sendline( "cd " + self.home )
556 self.handle.expect( "\$" )
557 lines = response.splitlines()
Jon Hall45ec0922014-10-10 19:33:49 -0400558 for line in lines:
Jon Hallfd191202014-11-07 18:36:09 -0500559 print line
560 if report:
pingping-lin763ee042015-05-20 17:45:30 -0700561 main.log.wiki( "<blockquote>" )
kelvin8ec71442015-01-15 16:57:00 -0800562 for line in lines[ 2:-1 ]:
563 # Bracket replacement is for Wiki-compliant
564 # formatting. '<' or '>' are interpreted
565 # as xml specific tags that cause errors
566 line = line.replace( "<", "[" )
567 line = line.replace( ">", "]" )
pingping-lin763ee042015-05-20 17:45:30 -0700568 #main.log.wiki( "\t" + line )
569 main.log.wiki( line + "<br /> " )
570 main.log.summary( line )
571 main.log.wiki( "</blockquote>" )
572 main.log.summary("\n")
kelvin8ec71442015-01-15 16:57:00 -0800573 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400574 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800575 main.log.error( self.name + ": EOF exception found" )
576 main.log.error( self.name + ": " + self.handle.before )
Jon Hall45ec0922014-10-10 19:33:49 -0400577 main.cleanup()
578 main.exit()
Jon Hall368769f2014-11-19 15:43:35 -0800579 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800580 main.log.error( self.name + ": TIMEOUT exception found" )
581 main.log.error( self.name + ": " + self.handle.before )
Jon Hall368769f2014-11-19 15:43:35 -0800582 main.cleanup()
583 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800584 except Exception:
585 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall45ec0922014-10-10 19:33:49 -0400586 main.cleanup()
587 main.exit()
588
kelvin-onlabd3b64892015-01-20 13:26:24 -0800589 def createCellFile( self, benchIp, fileName, mnIpAddrs,
cameron@onlab.us75900962015-03-30 13:22:49 -0700590 appString, *onosIpAddrs ):
kelvin8ec71442015-01-15 16:57:00 -0800591 """
andrewonlab94282092014-10-10 13:00:11 -0400592 Creates a cell file based on arguments
593 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800594 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400595 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800596 * File name of the cell file ( fileName )
597 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800598 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400599 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800600 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400601 - Must be passed in as last arguments
kelvin8ec71442015-01-15 16:57:00 -0800602
andrewonlab94282092014-10-10 13:00:11 -0400603 NOTE: Assumes cells are located at:
604 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800605 """
606 # Variable initialization
Jon Hallf57a5ef2015-07-07 17:56:16 -0700607 cellDirectory = os.environ["ONOS_ROOT"] + "/tools/test/cells/"
kelvin8ec71442015-01-15 16:57:00 -0800608 # We want to create the cell file in the dependencies directory
609 # of TestON first, then copy over to ONOS bench
kelvin-onlabd3b64892015-01-20 13:26:24 -0800610 tempDirectory = "/tmp/"
kelvin8ec71442015-01-15 16:57:00 -0800611 # Create the cell file in the directory for writing ( w+ )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800612 cellFile = open( tempDirectory + fileName, 'w+' )
kelvin8ec71442015-01-15 16:57:00 -0800613
cameron@onlab.us75900962015-03-30 13:22:49 -0700614 # App string is hardcoded environment variables
kelvin8ec71442015-01-15 16:57:00 -0800615 # That you may wish to use by default on startup.
cameron@onlab.us75900962015-03-30 13:22:49 -0700616 # Note that you may not want certain apps listed
kelvin8ec71442015-01-15 16:57:00 -0800617 # on here.
cameron@onlab.us75900962015-03-30 13:22:49 -0700618 appString = "export ONOS_APPS=" + appString
kelvin-onlabd3b64892015-01-20 13:26:24 -0800619 mnString = "export OCN="
kelvin-onlabf70fd542015-05-07 18:41:40 -0700620 if mnIpAddrs == "":
621 mnString = ""
kelvin-onlabd3b64892015-01-20 13:26:24 -0800622 onosString = "export OC"
623 tempCount = 1
kelvin8ec71442015-01-15 16:57:00 -0800624
kelvin-onlabd3b64892015-01-20 13:26:24 -0800625 # Create ONOSNIC ip address prefix
626 tempOnosIp = onosIpAddrs[ 0 ]
627 tempList = []
628 tempList = tempOnosIp.split( "." )
kelvin8ec71442015-01-15 16:57:00 -0800629 # Omit last element of list to format for NIC
kelvin-onlabd3b64892015-01-20 13:26:24 -0800630 tempList = tempList[ :-1 ]
kelvin8ec71442015-01-15 16:57:00 -0800631 # Structure the nic string ip
kelvin-onlabd3b64892015-01-20 13:26:24 -0800632 nicAddr = ".".join( tempList ) + ".*"
633 onosNicString = "export ONOS_NIC=" + nicAddr
andrewonlab94282092014-10-10 13:00:11 -0400634
635 try:
kelvin8ec71442015-01-15 16:57:00 -0800636 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800637 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400638
kelvin-onlabd3b64892015-01-20 13:26:24 -0800639 for arg in onosIpAddrs:
640 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800641 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400642 # export OC1="10.128.20.11"
643 # export OC2="10.128.20.12"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800644 cellFile.write( onosString + str( tempCount ) +
645 "=" + "\"" + arg + "\"" + "\n" )
646 tempCount = tempCount + 1
kelvin8ec71442015-01-15 16:57:00 -0800647
kelvin-onlabd3b64892015-01-20 13:26:24 -0800648 cellFile.write( mnString + "\"" + mnIpAddrs + "\"" + "\n" )
cameron@onlab.us75900962015-03-30 13:22:49 -0700649 cellFile.write( appString + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800650 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400651
kelvin8ec71442015-01-15 16:57:00 -0800652 # We use os.system to send the command to TestON cluster
653 # to account for the case in which TestON is not located
654 # on the same cluster as the ONOS bench
655 # Note that even if TestON is located on the same cluster
656 # as ONOS bench, you must setup passwordless ssh
657 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800658 os.system( "scp " + tempDirectory + fileName +
659 " admin@" + benchIp + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400660
andrewonlab2a6c9342014-10-16 13:40:15 -0400661 return main.TRUE
662
andrewonlab94282092014-10-10 13:00:11 -0400663 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800664 main.log.error( self.name + ": EOF exception found" )
665 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -0400666 main.cleanup()
667 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800668 except Exception:
669 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -0400670 main.cleanup()
671 main.exit()
672
kelvin-onlabd3b64892015-01-20 13:26:24 -0800673 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800674 """
andrewonlab95ca1462014-10-09 14:04:24 -0400675 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800676 """
andrewonlab95ca1462014-10-09 14:04:24 -0400677 try:
678 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800679 main.log.error( "Must define cellname" )
andrewonlab95ca1462014-10-09 14:04:24 -0400680 main.cleanup()
681 main.exit()
682 else:
kelvin8ec71442015-01-15 16:57:00 -0800683 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800684 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800685 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400686 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800687 self.handle.expect(str(cellname))
kelvin-onlabd3b64892015-01-20 13:26:24 -0800688 handleBefore = self.handle.before
689 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800690 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800691 self.handle.sendline("")
692 self.handle.expect("\$")
kelvin-onlabd3b64892015-01-20 13:26:24 -0800693 handleMore = self.handle.before
andrewonlab95ca1462014-10-09 14:04:24 -0400694
kelvin-onlabd3b64892015-01-20 13:26:24 -0800695 main.log.info( "Cell call returned: " + handleBefore +
696 handleAfter + handleMore )
andrewonlab95ca1462014-10-09 14:04:24 -0400697
698 return main.TRUE
699
700 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800701 main.log.error( self.name + ": EOF exception found" )
702 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ca1462014-10-09 14:04:24 -0400703 main.cleanup()
704 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800705 except Exception:
706 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ca1462014-10-09 14:04:24 -0400707 main.cleanup()
708 main.exit()
709
kelvin-onlabd3b64892015-01-20 13:26:24 -0800710 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800711 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400712 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800713 """
714 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400715
andrewonlabc03bf6c2014-10-09 14:56:18 -0400716 try:
kelvin8ec71442015-01-15 16:57:00 -0800717 # Clean handle by sending empty and expecting $
718 self.handle.sendline( "" )
719 self.handle.expect( "\$" )
720 self.handle.sendline( "onos-verify-cell" )
721 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800722 handleBefore = self.handle.before
723 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800724 # Get the rest of the handle
725 self.handle.sendline( "" )
726 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800727 handleMore = self.handle.before
andrewonlabc03bf6c2014-10-09 14:56:18 -0400728
kelvin-onlabd3b64892015-01-20 13:26:24 -0800729 main.log.info( "Verify cell returned: " + handleBefore +
730 handleAfter + handleMore )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400731
732 return main.TRUE
Jon Halla5cb6172015-02-23 09:28:28 -0800733 except pexpect.ExceptionPexpect as e:
734 main.log.error( self.name + ": Pexpect exception found of type " +
735 str( type( e ) ) )
736 main.log.error ( e.get_trace() )
kelvin8ec71442015-01-15 16:57:00 -0800737 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400738 main.cleanup()
739 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800740 except Exception:
741 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400742 main.cleanup()
743 main.exit()
744
jenkins1e99e7b2015-04-02 18:15:39 -0700745 def onosCfgSet( self, ONOSIp, configName, configParam ):
746 """
747 Uses 'onos <node-ip> cfg set' to change a parameter value of an
748 application.
749
750 ex)
751 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
jenkins1e99e7b2015-04-02 18:15:39 -0700752 ONOSIp = '10.0.0.1'
753 configName = 'org.onosproject.myapp'
754 configParam = 'appSetting 1'
jenkins1e99e7b2015-04-02 18:15:39 -0700755 """
cameron@onlab.us78b89652015-07-08 15:21:03 -0700756 for i in range(5):
757 try:
758 cfgStr = ( "onos "+str(ONOSIp)+" cfg set "+
759 str(configName) + " " +
760 str(configParam)
761 )
jenkins1e99e7b2015-04-02 18:15:39 -0700762
cameron@onlab.us78b89652015-07-08 15:21:03 -0700763 self.handle.sendline( "" )
764 self.handle.expect( ":~" )
765 self.handle.sendline( cfgStr )
766 self.handle.expect("cfg set")
767 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700768
cameron@onlab.us78b89652015-07-08 15:21:03 -0700769 paramValue = configParam.split(" ")[1]
770 paramName = configParam.split(" ")[0]
771
772 checkStr = ( "onos " + str(ONOSIp) + """ cfg get " """ + str(configName) + " " + paramName + """ " """)
jenkins1e99e7b2015-04-02 18:15:39 -0700773
cameron@onlab.us78b89652015-07-08 15:21:03 -0700774 self.handle.sendline( checkStr )
775 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700776
cameron@onlab.us78b89652015-07-08 15:21:03 -0700777 if "value=" + paramValue + "," in self.handle.before:
778 main.log.info("cfg " + configName + " successfully set to " + configParam)
779 return main.TRUE
780
781 except pexpect.ExceptionPexpect as e:
782 main.log.error( self.name + ": Pexpect exception found of type " +
783 str( type( e ) ) )
784 main.log.error ( e.get_trace() )
785 main.log.error( self.name + ": " + self.handle.before )
786 main.cleanup()
787 main.exit()
788 except Exception:
789 main.log.exception( self.name + ": Uncaught exception!" )
790 main.cleanup()
791 main.exit()
792
793 time.sleep(5)
794
795 main.log.error("CFG SET FAILURE: " + configName + " " + configParam )
796 main.ONOSbench.handle.sendline("onos $OC1 cfg get")
797 main.ONOSbench.handle.expect("\$")
798 print main.ONOSbench.handle.before
799 main.ONOSbench.logReport( ONOSIp, ["ERROR","WARN","EXCEPT"], "d")
800 return main.FALSE
801
802
kelvin-onlabd3b64892015-01-20 13:26:24 -0800803 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800804 """
andrewonlab05e362f2014-10-10 00:40:57 -0400805 Uses 'onos' command to send various ONOS CLI arguments.
806 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800807 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400808 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800809
810 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400811 CLI commands for ONOS. Try to use this function first
812 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800813 function.
814 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400815 by starting onos, and typing in 'onos' to enter the
816 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800817 available commands.
818 """
andrewonlab05e362f2014-10-10 00:40:57 -0400819 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800820 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800821 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400822 return main.FALSE
823 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800824 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400825 return main.FALSE
826
kelvin8ec71442015-01-15 16:57:00 -0800827 cmdstr = str( cmdstr )
828 self.handle.sendline( "" )
829 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400830
kelvin-onlabd3b64892015-01-20 13:26:24 -0800831 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800832 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400833
kelvin-onlabd3b64892015-01-20 13:26:24 -0800834 handleBefore = self.handle.before
Shreya Shaha73aaad2014-10-27 18:03:09 -0400835 print "handle_before = ", self.handle.before
kelvin-onlabd3b64892015-01-20 13:26:24 -0800836 # handleAfter = str( self.handle.after )
Jon Hall47a93fb2015-01-06 16:46:06 -0800837
kelvin8ec71442015-01-15 16:57:00 -0800838 # self.handle.sendline( "" )
839 # self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800840 # handleMore = str( self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400841
kelvin8ec71442015-01-15 16:57:00 -0800842 main.log.info( "Command sent successfully" )
andrewonlab05e362f2014-10-10 00:40:57 -0400843
kelvin8ec71442015-01-15 16:57:00 -0800844 # Obtain return handle that consists of result from
845 # the onos command. The string may need to be
846 # configured further.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800847 # returnString = handleBefore + handleAfter
848 returnString = handleBefore
849 print "return_string = ", returnString
850 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400851
852 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800853 main.log.error( self.name + ": EOF exception found" )
854 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400855 main.cleanup()
856 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800857 except Exception:
858 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab05e362f2014-10-10 00:40:57 -0400859 main.cleanup()
860 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400861
kelvin-onlabd3b64892015-01-20 13:26:24 -0800862 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800863 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400864 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800865 If -f option is provided, it also forces an uninstall.
866 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400867 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800868 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400869 files to certain onos nodes
870
871 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800872 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400873 try:
andrewonlab114768a2014-11-14 12:44:44 -0500874 if options:
kelvin8ec71442015-01-15 16:57:00 -0800875 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500876 else:
kelvin8ec71442015-01-15 16:57:00 -0800877 self.handle.sendline( "onos-install " + node )
878 self.handle.expect( "onos-install " )
879 # NOTE: this timeout may need to change depending on the network
880 # and size of ONOS
881 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800882 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800883 "ONOS\sis\salready\sinstalled",
884 pexpect.TIMEOUT ], timeout=60 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400885
Jon Hall7993bfc2014-10-09 16:30:14 -0400886 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800887 main.log.warn( "Network is unreachable" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400888 return main.FALSE
889 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800890 main.log.info(
891 "ONOS was installed on " +
892 node +
893 " and started" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400894 return main.TRUE
andrewonlabd9a73a72014-11-14 17:28:21 -0500895 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800896 main.log.info( "ONOS is already installed on " + node )
andrewonlabd9a73a72014-11-14 17:28:21 -0500897 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800898 elif i == 3:
899 main.log.info(
900 "Installation of ONOS on " +
901 node +
902 " timed out" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400903 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400904
905 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800906 main.log.error( self.name + ": EOF exception found" )
907 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400908 main.cleanup()
909 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800910 except Exception:
911 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400912 main.cleanup()
913 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400914
kelvin-onlabd3b64892015-01-20 13:26:24 -0800915 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800916 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400917 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400918 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800919 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400920 try:
kelvin8ec71442015-01-15 16:57:00 -0800921 self.handle.sendline( "" )
922 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800923 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800924 " start" )
925 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -0400926 "Job\sis\salready\srunning",
927 "start/running",
928 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800929 pexpect.TIMEOUT ], timeout=120 )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400930
931 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800932 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400933 return main.TRUE
934 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800935 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400936 return main.TRUE
937 else:
kelvin8ec71442015-01-15 16:57:00 -0800938 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400939 main.cleanup()
940 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -0400941 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800942 main.log.error( self.name + ": EOF exception found" )
943 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400944 main.cleanup()
945 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800946 except Exception:
947 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400948 main.cleanup()
949 main.exit()
950
kelvin-onlabd3b64892015-01-20 13:26:24 -0800951 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800952 """
andrewonlab2b30bd32014-10-09 16:48:55 -0400953 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400954 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800955 """
andrewonlab2b30bd32014-10-09 16:48:55 -0400956 try:
kelvin8ec71442015-01-15 16:57:00 -0800957 self.handle.sendline( "" )
958 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800959 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800960 " stop" )
961 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -0400962 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -0700963 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -0400964 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800965 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2b30bd32014-10-09 16:48:55 -0400966
967 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800968 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400969 return main.TRUE
970 elif i == 1:
Jon Hall65844a32015-03-09 19:09:37 -0700971 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800972 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -0400973 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700974 elif i == 2:
975 main.log.warn( "ONOS wasn't running" )
976 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -0400977 else:
kelvin8ec71442015-01-15 16:57:00 -0800978 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400979 return main.FALSE
980
981 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800982 main.log.error( self.name + ": EOF exception found" )
983 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -0400984 main.cleanup()
985 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800986 except Exception:
987 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400988 main.cleanup()
989 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800990
kelvin-onlabd3b64892015-01-20 13:26:24 -0800991 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -0800992 """
andrewonlabc8d47972014-10-09 16:52:36 -0400993 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -0800994 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -0400995 if needed
kelvin8ec71442015-01-15 16:57:00 -0800996 """
andrewonlabc8d47972014-10-09 16:52:36 -0400997 try:
kelvin8ec71442015-01-15 16:57:00 -0800998 self.handle.sendline( "" )
pingping-lin763ee042015-05-20 17:45:30 -0700999 self.handle.expect( "\$", timeout=60 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001000 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001001 self.handle.expect( "\$" )
andrewonlabc8d47972014-10-09 16:52:36 -04001002
kelvin-onlabd3b64892015-01-20 13:26:24 -08001003 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
andrewonlab9dfd2082014-11-13 17:44:03 -05001004
kelvin8ec71442015-01-15 16:57:00 -08001005 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -04001006 return main.TRUE
1007
pingping-lin763ee042015-05-20 17:45:30 -07001008 except pexpect.TIMEOUT:
1009 main.log.exception( self.name + ": Timeout in onosUninstall" )
1010 return main.FALSE
andrewonlabc8d47972014-10-09 16:52:36 -04001011 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001012 main.log.error( self.name + ": EOF exception found" )
1013 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -04001014 main.cleanup()
1015 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001016 except Exception:
1017 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc8d47972014-10-09 16:52:36 -04001018 main.cleanup()
1019 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -04001020
kelvin-onlabd3b64892015-01-20 13:26:24 -08001021 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001022 """
andrewonlabaedc8332014-12-04 12:43:03 -05001023 Issues the command 'onos-die <node-ip>'
1024 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -08001025 """
andrewonlabaedc8332014-12-04 12:43:03 -05001026 try:
kelvin8ec71442015-01-15 16:57:00 -08001027 self.handle.sendline( "" )
1028 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001029 cmdStr = "onos-kill " + str( nodeIp )
1030 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001031 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -05001032 "Killing\sONOS",
1033 "ONOS\sprocess\sis\snot\srunning",
kelvin8ec71442015-01-15 16:57:00 -08001034 pexpect.TIMEOUT ], timeout=20 )
andrewonlabaedc8332014-12-04 12:43:03 -05001035 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001036 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001037 " was killed and stopped" )
andrewonlabaedc8332014-12-04 12:43:03 -05001038 return main.TRUE
1039 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001040 main.log.info( "ONOS process was not running" )
andrewonlabaedc8332014-12-04 12:43:03 -05001041 return main.FALSE
1042 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001043 main.log.error( self.name + ": EOF exception found" )
1044 main.log.error( self.name + ": " + self.handle.before )
andrewonlabaedc8332014-12-04 12:43:03 -05001045 main.cleanup()
1046 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001047 except Exception:
1048 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabaedc8332014-12-04 12:43:03 -05001049 main.cleanup()
1050 main.exit()
1051
kelvin-onlabd3b64892015-01-20 13:26:24 -08001052 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001053 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001054 Calls the command: 'onos-kill [<node-ip>]'
1055 "Remotely, and unceremoniously kills the ONOS instance running on
1056 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001057 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001058 try:
kelvin8ec71442015-01-15 16:57:00 -08001059 self.handle.sendline( "" )
1060 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001061 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001062 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -04001063 "\$",
1064 "No\sroute\sto\shost",
1065 "password:",
kelvin8ec71442015-01-15 16:57:00 -08001066 pexpect.TIMEOUT ], timeout=20 )
1067
andrewonlabe8e56fd2014-10-09 17:12:44 -04001068 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001069 main.log.info(
1070 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001071 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001072 return main.TRUE
1073 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001074 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001075 return main.FALSE
1076 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001077 main.log.info(
1078 "Passwordless login for host: " +
1079 str( nodeIp ) +
1080 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001081 return main.FALSE
1082 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001083 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001084 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001085
andrewonlabe8e56fd2014-10-09 17:12:44 -04001086 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001087 main.log.error( self.name + ": EOF exception found" )
1088 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001089 main.cleanup()
1090 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001091 except Exception:
1092 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001093 main.cleanup()
1094 main.exit()
1095
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001097 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001098 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001099 a cleaner environment.
1100
andrewonlab19fbdca2014-11-14 12:55:59 -05001101 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001102 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001103 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001104 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001105 try:
kelvin8ec71442015-01-15 16:57:00 -08001106 self.handle.sendline( "" )
1107 self.handle.expect( "\$" )
1108 self.handle.sendline( "onos-remove-raft-logs" )
1109 # Sometimes this command hangs
1110 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1111 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001112 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001113 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1114 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001115 if i == 1:
1116 return main.FALSE
shahshreya957feaa2015-03-23 16:08:29 -07001117 #self.handle.sendline( "" )
1118 #self.handle.expect( "\$" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001119 return main.TRUE
1120
1121 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001122 main.log.error( self.name + ": EOF exception found" )
1123 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -05001124 main.cleanup()
1125 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001126 except Exception:
1127 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001128 main.cleanup()
1129 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -05001130
kelvin-onlabd3b64892015-01-20 13:26:24 -08001131 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001132 """
1133 Calls the command 'onos-start-network [ <mininet-topo> ]
1134 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001135 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001136 cell."
andrewonlab94282092014-10-10 13:00:11 -04001137 * Specify mininet topology file name for mntopo
1138 * Topo files should be placed at:
1139 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001140
andrewonlab94282092014-10-10 13:00:11 -04001141 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001142 """
andrewonlab94282092014-10-10 13:00:11 -04001143 try:
1144 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001145 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001146 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001147
kelvin8ec71442015-01-15 16:57:00 -08001148 mntopo = str( mntopo )
1149 self.handle.sendline( "" )
1150 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -04001151
kelvin8ec71442015-01-15 16:57:00 -08001152 self.handle.sendline( "onos-start-network " + mntopo )
1153 self.handle.expect( "mininet>" )
1154 main.log.info( "Network started, entered mininet prompt" )
1155
1156 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001157
1158 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001159 main.log.error( self.name + ": EOF exception found" )
1160 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -04001161 main.cleanup()
1162 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001163 except Exception:
1164 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -04001165 main.cleanup()
1166 main.exit()
1167
Cameron Franke9c94fb02015-01-21 10:20:20 -08001168 def isup(self, node = "", timeout = 120):
kelvin8ec71442015-01-15 16:57:00 -08001169 """
1170 Run's onos-wait-for-start which only returns once ONOS is at run
Cameron Franke9c94fb02015-01-21 10:20:20 -08001171 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001172
Jon Hall7993bfc2014-10-09 16:30:14 -04001173 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001174 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001175 try:
Cameron Franke9c94fb02015-01-21 10:20:20 -08001176 self.handle.sendline("onos-wait-for-start " + node )
1177 self.handle.expect("onos-wait-for-start")
kelvin8ec71442015-01-15 16:57:00 -08001178 # NOTE: this timeout is arbitrary"
Cameron Franke9c94fb02015-01-21 10:20:20 -08001179 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001180 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001181 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001182 return main.TRUE
1183 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001184 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001185 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001186 main.log.error( "ONOS has not started yet" )
1187 self.handle.send( "\x03" ) # Control-C
1188 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001189 return main.FALSE
1190 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001191 main.log.error( self.name + ": EOF exception found" )
1192 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -04001193 main.cleanup()
1194 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001195 except Exception:
1196 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001197 main.cleanup()
1198 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001199
kelvin-onlabd3b64892015-01-20 13:26:24 -08001200 def pushTestIntentsShell(
1201 self,
1202 dpidSrc,
1203 dpidDst,
1204 numIntents,
1205 dirFile,
1206 onosIp,
1207 numMult="",
1208 appId="",
1209 report=True,
1210 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001211 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001212 Description:
kelvin8ec71442015-01-15 16:57:00 -08001213 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001214 better parallelize the results than the CLI
1215 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001216 * dpidSrc: specify source dpid
1217 * dpidDst: specify destination dpid
1218 * numIntents: specify number of intents to push
1219 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001220 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001221 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001222 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001223 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001224 """
1225 try:
1226 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001227 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001228 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001229 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001230 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001231 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001232
kelvin-onlabd3b64892015-01-20 13:26:24 -08001233 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1234 if not numMult:
1235 addIntents = addDpid + " " + str( numIntents )
1236 elif numMult:
1237 addIntents = addDpid + " " + str( numIntents ) + " " +\
1238 str( numMult )
1239 if appId:
1240 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001241 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001242 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001243
andrewonlabaedc8332014-12-04 12:43:03 -05001244 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001245 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001246 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001247 sendCmd = addApp + " &"
1248 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001249
kelvin-onlabd3b64892015-01-20 13:26:24 -08001250 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001251
1252 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001253 main.log.error( self.name + ": EOF exception found" )
1254 main.log.error( self.name + ": " + self.handle.before )
andrewonlabb66dfa12014-12-02 15:51:10 -05001255 main.cleanup()
1256 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001257 except Exception:
1258 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001259 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001260 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001261
kelvin-onlabd3b64892015-01-20 13:26:24 -08001262 def getTopology( self, topologyOutput ):
kelvin8ec71442015-01-15 16:57:00 -08001263 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001264 Definition:
1265 Loads a json topology output
1266 Return:
1267 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -08001268 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001269 import json
Jon Hall77f53ce2014-10-13 18:02:06 -04001270 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001271 # either onos:topology or 'topology' will work in CLI
1272 topology = json.loads(topologyOutput)
1273 print topology
Jon Hall77f53ce2014-10-13 18:02:06 -04001274 return topology
1275 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001276 main.log.error( self.name + ": EOF exception found" )
1277 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001278 main.cleanup()
1279 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001280 except Exception:
1281 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001282 main.cleanup()
1283 main.exit()
1284
kelvin-onlabd3b64892015-01-20 13:26:24 -08001285 def checkStatus(
1286 self,
1287 topologyResult,
1288 numoswitch,
1289 numolink,
1290 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001291 """
Jon Hallefbd9792015-03-05 16:11:36 -08001292 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001293 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001294 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08001295
Jon Hall77f53ce2014-10-13 18:02:06 -04001296 Params: ip = ip used for the onos cli
1297 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001298 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001299 logLevel = level to log to.
1300 Currently accepts 'info', 'warn' and 'report'
Jon Hall77f53ce2014-10-13 18:02:06 -04001301
1302
kelvin-onlabd3b64892015-01-20 13:26:24 -08001303 logLevel can
Jon Hall77f53ce2014-10-13 18:02:06 -04001304
Jon Hallefbd9792015-03-05 16:11:36 -08001305 Returns: main.TRUE if the number of switches and links are correct,
1306 main.FALSE if the number of switches and links is incorrect,
Jon Hall77f53ce2014-10-13 18:02:06 -04001307 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001308 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001309 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001310 topology = self.getTopology( topologyResult )
Jon Hall77f53ce2014-10-13 18:02:06 -04001311 if topology == {}:
1312 return main.ERROR
1313 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001314 # Is the number of switches is what we expected
shahshreya234a1682015-05-27 15:41:56 -07001315 devices = topology.get( 'devices', False )
1316 links = topology.get( 'links', False )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001317 if not devices or not links:
Jon Hall77f53ce2014-10-13 18:02:06 -04001318 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001319 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001320 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001321 linkCheck = ( int( links ) == int( numolink ) )
Jon Hallefbd9792015-03-05 16:11:36 -08001322 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08001323 # We expected the correct numbers
Jon Hall77f53ce2014-10-13 18:02:06 -04001324 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001325 + "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001326 result = main.TRUE
1327 else:
1328 output = output + \
Jon Hall274b6642015-02-17 11:57:17 -08001329 "The number of links and switches does not match " + \
1330 "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001331 result = main.FALSE
Jon Hallefbd9792015-03-05 16:11:36 -08001332 output = output + "\n ONOS sees %i devices" % int( devices )
1333 output = output + " (%i expected) " % int( numoswitch )
Jon Hall274b6642015-02-17 11:57:17 -08001334 output = output + "and %i links " % int( links )
1335 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001336 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001337 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001338 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001339 main.log.warn( output )
Jon Hall77f53ce2014-10-13 18:02:06 -04001340 else:
kelvin8ec71442015-01-15 16:57:00 -08001341 main.log.info( output )
1342 return result
Jon Hall77f53ce2014-10-13 18:02:06 -04001343 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001344 main.log.error( self.name + ": EOF exception found" )
1345 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001346 main.cleanup()
1347 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001348 except Exception:
1349 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001350 main.cleanup()
1351 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001352
kelvin-onlabd3b64892015-01-20 13:26:24 -08001353 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001354 """
andrewonlab970399c2014-11-07 13:09:32 -05001355 Capture all packet activity and store in specified
1356 directory/file
1357
1358 Required:
1359 * interface: interface to capture
1360 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001361 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001362 try:
1363 self.handle.sendline( "" )
1364 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001365
Jon Hallfebb1c72015-03-05 13:30:09 -08001366 self.handle.sendline( "tshark -i " + str( interface ) +
1367 " -t e -w " + str( dirFile ) + " &" )
1368 self.handle.sendline( "\r" )
1369 self.handle.expect( "Capturing on" )
1370 self.handle.sendline( "\r" )
1371 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001372
Jon Hallfebb1c72015-03-05 13:30:09 -08001373 main.log.info( "Tshark started capturing files on " +
1374 str( interface ) + " and saving to directory: " +
1375 str( dirFile ) )
1376 except pexpect.EOF:
1377 main.log.error( self.name + ": EOF exception found" )
1378 main.log.error( self.name + ": " + self.handle.before )
1379 main.cleanup()
1380 main.exit()
1381 except Exception:
1382 main.log.exception( self.name + ": Uncaught exception!" )
1383 main.cleanup()
1384 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001385
kelvin-onlabd3b64892015-01-20 13:26:24 -08001386 def runOnosTopoCfg( self, instanceName, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001387 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001388 On ONOS bench, run this command:
Jon Halle94919c2015-03-23 11:42:57 -07001389 {ONOS_HOME}/tools/test/bin/onos-topo-cfg $OC1 filename
kelvin-onlabd3b64892015-01-20 13:26:24 -08001390 which starts the rest and copies
1391 the json file to the onos instance
kelvin8ec71442015-01-15 16:57:00 -08001392 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001393 try:
kelvin8ec71442015-01-15 16:57:00 -08001394 self.handle.sendline( "" )
1395 self.handle.expect( "\$" )
Jon Halle94919c2015-03-23 11:42:57 -07001396 self.handle.sendline( "cd " + self.home + "/tools/test/bin" )
kelvin8ec71442015-01-15 16:57:00 -08001397 self.handle.expect( "/bin$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001398 cmd = "./onos-topo-cfg " + instanceName + " " + jsonFile
shahshreyae6c7cf42014-11-26 16:39:01 -08001399 print "cmd = ", cmd
kelvin8ec71442015-01-15 16:57:00 -08001400 self.handle.sendline( cmd )
1401 self.handle.expect( "\$" )
1402 self.handle.sendline( "cd ~" )
1403 self.handle.expect( "\$" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001404 return main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -08001405 except pexpect.EOF:
1406 main.log.error( self.name + ": EOF exception found" )
1407 main.log.error( self.name + ": " + self.handle.before )
1408 main.cleanup()
1409 main.exit()
1410 except Exception:
1411 main.log.exception( self.name + ": Uncaught exception!" )
1412 main.cleanup()
1413 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001414
jenkins1e99e7b2015-04-02 18:15:39 -07001415 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001416 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001417 Required:
kelvin8ec71442015-01-15 16:57:00 -08001418 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001419 * directory to store results
1420 Optional:
1421 * interface - default: eth0
jenkins1e99e7b2015-04-02 18:15:39 -07001422 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001423 Description:
1424 Uses tshark command to grep specific group of packets
1425 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001426 The timestamp is hardcoded to be in epoch
1427 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001428 try:
1429 self.handle.sendline( "" )
1430 self.handle.expect( "\$" )
1431 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001432 if grepOptions:
1433 grepStr = "grep "+str(grepOptions)
1434 else:
1435 grepStr = "grep"
1436
Jon Hallfebb1c72015-03-05 13:30:09 -08001437 self.handle.sendline(
1438 "tshark -i " +
1439 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001440 " -t e | " +
1441 grepStr + " --line-buffered \"" +
Jon Hallfebb1c72015-03-05 13:30:09 -08001442 str(grep) +
1443 "\" >" +
1444 directory +
1445 " &" )
1446 self.handle.sendline( "\r" )
1447 self.handle.expect( "Capturing on" )
1448 self.handle.sendline( "\r" )
1449 self.handle.expect( "\$" )
1450 except pexpect.EOF:
1451 main.log.error( self.name + ": EOF exception found" )
1452 main.log.error( self.name + ": " + self.handle.before )
1453 main.cleanup()
1454 main.exit()
1455 except Exception:
1456 main.log.exception( self.name + ": Uncaught exception!" )
1457 main.cleanup()
1458 main.exit()
1459
kelvin-onlabd3b64892015-01-20 13:26:24 -08001460 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001461 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001462 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001463 """
1464 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001465 try:
1466 self.execute( cmd="sudo rm /tmp/wireshark*" )
1467 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001468 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1469 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001470 self.handle.sendline( "" )
1471 main.log.info( "Tshark stopped" )
1472 except pexpect.EOF:
1473 main.log.error( self.name + ": EOF exception found" )
1474 main.log.error( self.name + ": " + self.handle.before )
1475 main.cleanup()
1476 main.exit()
1477 except Exception:
1478 main.log.exception( self.name + ": Uncaught exception!" )
1479 main.cleanup()
1480 main.exit()
1481
kelvin8ec71442015-01-15 16:57:00 -08001482 def ptpd( self, args ):
1483 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001484 Initiate ptp with user-specified args.
1485 Required:
1486 * args: specify string of args after command
1487 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001488 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001489 try:
kelvin8ec71442015-01-15 16:57:00 -08001490 self.handle.sendline( "sudo ptpd " + str( args ) )
1491 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001492 "Multiple",
1493 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001494 "\$" ] )
1495 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001496
andrewonlab0c38a4a2014-10-28 18:35:35 -04001497 if i == 0:
1498 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001499 main.log.info( "ptpd returned an error: " +
1500 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001501 return handle
1502 elif i == 1:
1503 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001504 main.log.error( "ptpd returned an error: " +
1505 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001506 return handle
1507 else:
1508 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001509
andrewonlab0c38a4a2014-10-28 18:35:35 -04001510 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001511 main.log.error( self.name + ": EOF exception found" )
1512 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001513 main.cleanup()
1514 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001515 except Exception:
1516 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001517 main.cleanup()
1518 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001519
kelvin-onlabd3b64892015-01-20 13:26:24 -08001520 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001521 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001522 """
1523 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001524 Current implementation of ONOS deletes its karaf
1525 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001526 you may want to use this function to capture
1527 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001528 Localtime will be attached to the filename
1529
1530 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001531 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001532 copy.
kelvin8ec71442015-01-15 16:57:00 -08001533 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001534 For copying multiple files, leave copyFileName
1535 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001536 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001537 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001538 ex ) /tmp/
1539 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001540 * copyFileName: If you want to rename the log
1541 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001542 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001543 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001544 try:
kelvin8ec71442015-01-15 16:57:00 -08001545 localtime = time.strftime( '%x %X' )
1546 localtime = localtime.replace( "/", "" )
1547 localtime = localtime.replace( " ", "_" )
1548 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001549 if destDir[ -1: ] != "/":
1550 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001551
kelvin-onlabd3b64892015-01-20 13:26:24 -08001552 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001553 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1554 str( destDir ) + str( copyFileName ) +
1555 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001556 self.handle.expect( "cp" )
1557 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001558 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001559 self.handle.sendline( "cp " + str( logToCopy ) +
1560 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001561 self.handle.expect( "cp" )
1562 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001563
kelvin8ec71442015-01-15 16:57:00 -08001564 return self.handle.before
1565
1566 except pexpect.EOF:
1567 main.log.error( "Copying files failed" )
1568 main.log.error( self.name + ": EOF exception found" )
1569 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001570 except Exception:
1571 main.log.exception( "Copying files failed" )
1572
Jon Hall16b72c42015-05-20 10:23:36 -07001573 def checkLogs( self, onosIp, restart=False):
kelvin8ec71442015-01-15 16:57:00 -08001574 """
Jon Hall94fd0472014-12-08 11:52:42 -08001575 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001576 If restart is True, use the old version of onos-check-logs which
1577 does not print the full stacktrace, but shows the entire log file,
1578 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001579 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001580 """
Jon Hall94fd0472014-12-08 11:52:42 -08001581 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001582 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001583 if restart:
1584 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001585 self.handle.sendline( cmd )
1586 self.handle.expect( cmd )
1587 self.handle.expect( "\$" )
Jon Hall94fd0472014-12-08 11:52:42 -08001588 response = self.handle.before
1589 return response
1590 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001591 main.log.error( "Lost ssh connection" )
1592 main.log.error( self.name + ": EOF exception found" )
1593 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001594 except Exception:
1595 main.log.exception( self.name + ": Uncaught exception!" )
1596 main.cleanup()
1597 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001598
kelvin-onlabd3b64892015-01-20 13:26:24 -08001599 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001600 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001601 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001602 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001603 try:
kelvin8ec71442015-01-15 16:57:00 -08001604 self.handle.sendline( "" )
1605 self.handle.expect( "\$" )
1606 self.handle.sendline( "onos-service " + str( node ) +
1607 " status" )
1608 i = self.handle.expect( [
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001609 "start/running",
1610 "stop/waiting",
kelvin8ec71442015-01-15 16:57:00 -08001611 pexpect.TIMEOUT ], timeout=120 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001612
1613 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001614 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001615 return main.TRUE
1616 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001617 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001618 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001619 main.cleanup()
1620 main.exit()
1621 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001622 main.log.error( self.name + ": EOF exception found" )
1623 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001624 main.cleanup()
1625 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001626 except Exception:
1627 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001628 main.cleanup()
1629 main.exit()
Jon Hall21270ac2015-02-16 17:59:55 -08001630
Jon Hall63604932015-02-26 17:09:50 -08001631 def setIpTables( self, ip, port='', action='add', packet_type='',
1632 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001633 """
Jon Hall21270ac2015-02-16 17:59:55 -08001634 Description:
1635 add or remove iptables rule to DROP (default) packets from
1636 specific IP and PORT
1637 Usage:
1638 * specify action ('add' or 'remove')
1639 when removing, pass in the same argument as you would add. It will
1640 delete that specific rule.
1641 * specify the ip to block
1642 * specify the destination port to block (defaults to all ports)
1643 * optional packet type to block (default tcp)
1644 * optional iptables rule (default DROP)
1645 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001646 * States boolean toggles adding all supported tcp states to the
1647 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001648 Returns:
1649 main.TRUE on success or
1650 main.FALSE if given invalid input or
1651 main.ERROR if there is an error in response from iptables
1652 WARNING:
1653 * This function uses root privilege iptables command which may result
1654 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001655 """
Jon Hall21270ac2015-02-16 17:59:55 -08001656 import time
1657
1658 # NOTE*********
1659 # The strict checking methods of this driver function is intentional
1660 # to discourage any misuse or error of iptables, which can cause
1661 # severe network errors
1662 # *************
1663
1664 # NOTE: Sleep needed to give some time for rule to be added and
1665 # registered to the instance. If you are calling this function
1666 # multiple times this sleep will prevent any errors.
1667 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001668 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001669 try:
1670 # input validation
1671 action_type = action.lower()
1672 rule = rule.upper()
1673 direction = direction.upper()
1674 if action_type != 'add' and action_type != 'remove':
1675 main.log.error( "Invalid action type. Use 'add' or "
1676 "'remove' table rule" )
1677 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1678 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1679 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1680 "'ACCEPT' or 'LOG' only." )
1681 if direction != 'INPUT' and direction != 'OUTPUT':
1682 # NOTE currently only supports rules INPUT and OUPTUT
1683 main.log.error( "Invalid rule. Valid directions are"
1684 " 'OUTPUT' or 'INPUT'" )
1685 return main.FALSE
1686 return main.FALSE
1687 return main.FALSE
1688 if action_type == 'add':
1689 # -A is the 'append' action of iptables
1690 actionFlag = '-A'
1691 elif action_type == 'remove':
1692 # -D is the 'delete' rule of iptables
1693 actionFlag = '-D'
1694 self.handle.sendline( "" )
1695 self.handle.expect( "\$" )
1696 cmd = "sudo iptables " + actionFlag + " " +\
1697 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001698 " -s " + str( ip )
Jon Hall63604932015-02-26 17:09:50 -08001699 # " -p " + str( packet_type ) +\
1700 if packet_type:
1701 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001702 if port:
1703 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001704 if states:
1705 cmd += " -m state --state="
1706 #FIXME- Allow user to configure which states to block
1707 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001708 cmd += " -j " + str( rule )
1709
1710 self.handle.sendline( cmd )
1711 self.handle.expect( "\$" )
1712 main.log.warn( self.handle.before )
1713
1714 info_string = "On " + str( self.name )
1715 info_string += " " + str( action_type )
1716 info_string += " iptable rule [ "
1717 info_string += " IP: " + str( ip )
1718 info_string += " Port: " + str( port )
1719 info_string += " Rule: " + str( rule )
1720 info_string += " Direction: " + str( direction ) + " ]"
1721 main.log.info( info_string )
1722 return main.TRUE
1723 except pexpect.TIMEOUT:
1724 main.log.exception( self.name + ": Timeout exception in "
1725 "setIpTables function" )
1726 return main.ERROR
1727 except pexpect.EOF:
1728 main.log.error( self.name + ": EOF exception found" )
1729 main.log.error( self.name + ": " + self.handle.before )
1730 main.cleanup()
1731 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001732 except Exception:
1733 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall21270ac2015-02-16 17:59:55 -08001734 main.cleanup()
1735 main.exit()
1736
Jon Hall0468b042015-02-19 19:08:21 -08001737 def detailed_status(self, log_filename):
Jon Hallefbd9792015-03-05 16:11:36 -08001738 """
Jon Hall0468b042015-02-19 19:08:21 -08001739 This method is used by STS to check the status of the controller
1740 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001741 """
Jon Hall0468b042015-02-19 19:08:21 -08001742 import re
1743 try:
1744 self.handle.sendline( "" )
1745 self.handle.expect( "\$" )
1746 self.handle.sendline( "cd " + self.home )
1747 self.handle.expect( "\$" )
1748 self.handle.sendline( "service onos status" )
1749 self.handle.expect( "\$" )
1750 response = self.handle.before
1751 if re.search( "onos start/running", response ):
1752 # onos start/running, process 10457
1753 return 'RUNNING'
1754 # FIXME: Implement this case
1755 # elif re.search( pattern, response ):
1756 # return 'STARTING'
1757 elif re.search( "onos stop/", response ):
1758 # onos stop/waiting
1759 # FIXME handle this differently?: onos stop/pre-stop
1760 return 'STOPPED'
1761 # FIXME: Implement this case
1762 # elif re.search( pattern, response ):
1763 # return 'FROZEN'
1764 else:
1765 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001766 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001767 main.log.warn( response )
1768 return 'ERROR', "Unknown response: %s" % response
1769 except pexpect.TIMEOUT:
1770 main.log.exception( self.name + ": Timeout exception in "
1771 "setIpTables function" )
1772 return 'ERROR', "Pexpect Timeout"
1773 except pexpect.EOF:
1774 main.log.error( self.name + ": EOF exception found" )
1775 main.log.error( self.name + ": " + self.handle.before )
1776 main.cleanup()
1777 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001778 except Exception:
1779 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall0468b042015-02-19 19:08:21 -08001780 main.cleanup()
1781 main.exit()
1782
andrew@onlab.us3b087132015-03-11 15:00:08 -07001783 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1784 '''
1785 Create/formats the LinkGraph.cfg file based on arguments
1786 -only creates a linear topology and connects islands
1787 -evenly distributes devices
1788 -must be called by ONOSbench
1789
1790 ONOSIpList - list of all of the node IPs to be used
1791
1792 deviceCount - number of switches to be assigned
1793 '''
1794 main.log.step("Creating link graph configuration file." )
1795 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
1796 tempFile = "/tmp/linkGraph.cfg"
1797
1798 linkGraph = open(tempFile, 'w+')
1799 linkGraph.write("# NullLinkProvider topology description (config file).\n")
1800 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
1801 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
1802
1803 clusterCount = len(ONOSIpList)
1804
1805 if type(deviceCount) is int or type(deviceCount) is str:
1806 deviceCount = int(deviceCount)
1807 switchList = [0]*(clusterCount+1)
1808 baselineSwitchCount = deviceCount/clusterCount
1809
1810 for node in range(1, clusterCount + 1):
1811 switchList[node] = baselineSwitchCount
1812
1813 for node in range(1, (deviceCount%clusterCount)+1):
1814 switchList[node] += 1
1815
1816 if type(deviceCount) is list:
1817 main.log.info("Using provided device distribution")
1818 switchList = [0]
1819 for i in deviceCount:
1820 switchList.append(int(i))
1821
1822 tempList = ['0']
1823 tempList.extend(ONOSIpList)
1824 ONOSIpList = tempList
1825
1826 myPort = 6
1827 lastSwitch = 0
1828 for node in range(1, clusterCount+1):
1829 if switchList[node] == 0:
1830 continue
1831
1832 linkGraph.write("graph " + ONOSIpList[node] + " {\n")
1833
1834 if node > 1:
1835 #connect to last device on previous node
1836 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
1837 linkGraph.write(line)
1838
1839 lastSwitch = 0
1840 for switch in range (0, switchList[node]-1):
1841 line = ""
1842 line = ("\t" + str(switch) + ":" + str(myPort))
1843 line += " -- "
1844 line += (str(switch+1) + ":" + str(myPort-1) + "\n")
1845 linkGraph.write(line)
1846 lastSwitch = switch+1
1847 lastIp = ONOSIpList[node]
1848
1849 #lastSwitch += 1
1850 if node < (clusterCount):
1851 #connect to first device on the next node
1852 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
1853 linkGraph.write(line)
1854
1855 linkGraph.write("}\n")
1856 linkGraph.close()
1857
1858 #SCP
1859 os.system( "scp " + tempFile + " admin@" + benchIp + ":" + linkGraphPath)
1860 main.log.info("linkGraph.cfg creation complete")
1861
cameron@onlab.us75900962015-03-30 13:22:49 -07001862 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001863
1864 '''
andrew@onlab.us3b087132015-03-11 15:00:08 -07001865 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
cameron@onlab.us75900962015-03-30 13:22:49 -07001866 deviceCount = number of switches to distribute, or list of values to use as custom distribution
1867 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 -07001868 '''
1869
cameron@onlab.us75900962015-03-30 13:22:49 -07001870 main.log.step("Configuring Null Device Provider" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07001871 clusterCount = len(ONOSIpList)
1872
cameron@onlab.us75900962015-03-30 13:22:49 -07001873 try:
1874
1875 if type(deviceCount) is int or type(deviceCount) is str:
1876 main.log.step("Creating device distribution")
1877 deviceCount = int(deviceCount)
1878 switchList = [0]*(clusterCount+1)
1879 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001880
cameron@onlab.us75900962015-03-30 13:22:49 -07001881 for node in range(1, clusterCount + 1):
1882 switchList[node] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001883
cameron@onlab.us75900962015-03-30 13:22:49 -07001884 for node in range(1, (deviceCount%clusterCount)+1):
1885 switchList[node] += 1
1886
1887 if type(deviceCount) is list:
1888 main.log.info("Using provided device distribution")
1889
1890 if len(deviceCount) == clusterCount:
1891 switchList = ['0']
1892 switchList.extend(deviceCount)
1893
1894 if len(deviceCount) == (clusterCount + 1):
1895 if deviceCount[0] == '0' or deviceCount[0] == 0:
1896 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001897
cameron@onlab.us75900962015-03-30 13:22:49 -07001898 assert len(switchList) == (clusterCount + 1)
1899
1900 except AssertionError:
1901 main.log.error( "Bad device/Ip list match")
1902 except TypeError:
1903 main.log.exception( self.name + ": Object not as expected" )
1904 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07001905 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001906 main.log.exception( self.name + ": Uncaught exception!" )
1907 main.cleanup()
1908 main.exit()
1909
andrew@onlab.us3b087132015-03-11 15:00:08 -07001910
1911 ONOSIp = [0]
1912 ONOSIp.extend(ONOSIpList)
1913
1914 devicesString = "devConfigs = "
1915 for node in range(1, len(ONOSIp)):
1916 devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
1917 if node < clusterCount:
1918 devicesString += (",")
cameron@onlab.us75900962015-03-30 13:22:49 -07001919
1920 try:
1921 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
1922 self.handle.expect(":~")
1923 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) )
1924 self.handle.expect(":~")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001925
cameron@onlab.us75900962015-03-30 13:22:49 -07001926 for i in range(10):
1927 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider")
1928 self.handle.expect(":~")
1929 verification = self.handle.before
1930 if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification:
1931 break
1932 else:
1933 time.sleep(1)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001934
cameron@onlab.us2cc8bf12015-04-02 14:12:30 -07001935 assert ("value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification
cameron@onlab.us75900962015-03-30 13:22:49 -07001936
1937 except AssertionError:
1938 main.log.error("Incorrect Config settings: " + verification)
Jon Hall77ba41c2015-04-06 10:25:40 -07001939 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001940 main.log.exception( self.name + ": Uncaught exception!" )
1941 main.cleanup()
1942 main.exit()
1943
cameron@onlab.usc80a8c82015-04-15 14:57:37 -07001944 def configNullLink( self,fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001945 '''
cameron@onlab.us75900962015-03-30 13:22:49 -07001946 fileName default is currently the same as the default on ONOS, specify alternate file if
1947 you want to use a different topology file than linkGraph.cfg
andrew@onlab.us3b087132015-03-11 15:00:08 -07001948 '''
1949
andrew@onlab.us3b087132015-03-11 15:00:08 -07001950
cameron@onlab.us75900962015-03-30 13:22:49 -07001951 try:
1952 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str(eventRate))
1953 self.handle.expect(":~")
1954 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
1955 self.handle.expect(":~")
1956
1957 for i in range(10):
1958 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider")
1959 self.handle.expect(":~")
1960 verification = self.handle.before
1961 if (" value=" + str(eventRate)) in verification and (" value=" + fileName) in verification:
1962 break
1963 else:
1964 time.sleep(1)
1965
1966 assert ("value=" + str(eventRate)) in verification and (" value=" + fileName) in verification
1967
1968 except pexpect.EOF:
1969 main.log.error( self.name + ": EOF exception found" )
1970 main.log.error( self.name + ": " + self.handle.before )
1971 main.cleanup()
1972 main.exit()
cameron@onlab.us75900962015-03-30 13:22:49 -07001973 except AssertionError:
1974 main.log.info("Settings did not post to ONOS")
1975 main.log.error(varification)
Jon Hall77ba41c2015-04-06 10:25:40 -07001976 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001977 main.log.exception( self.name + ": Uncaught exception!" )
1978 main.log.error(varification)
1979 main.cleanup()
1980 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07001981
cameron@onlab.us966d1be2015-05-15 14:54:09 -07001982 def getOnosIps(self):
cameron@onlab.us59d29d92015-05-11 14:31:54 -07001983
1984 import os
kelvin-onlab0a28a742015-05-18 16:03:13 -07001985
cameron@onlab.us966d1be2015-05-15 14:54:09 -07001986 # reads env for OC variables, also saves file with OC variables. If file and env conflict
1987 # priority goes to env. If file has OCs that are not in the env, the file OCs are used.
1988 # In other words, if the env is set, the test will use those values.
cameron@onlab.us59d29d92015-05-11 14:31:54 -07001989
cameron@onlab.us966d1be2015-05-15 14:54:09 -07001990 # returns a list of ip addresses for the onos nodes, will work with up to 7 nodes + OCN and OCI
1991 # returns in format [ OC1 ip, OC2 ...ect. , OCN, OCI ]
1992
1993 envONOSIps = {}
cameron@onlab.us59d29d92015-05-11 14:31:54 -07001994
1995 x = 1
1996 while True:
1997 try:
1998 temp = os.environ[ 'OC' + str(x) ]
cameron@onlab.us966d1be2015-05-15 14:54:09 -07001999 except KeyError:
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002000 break
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002001 envONOSIps[ ("OC" + str(x)) ] = temp
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002002 x += 1
2003
2004 try:
2005 temp = os.environ[ 'OCN' ]
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002006 envONOSIps[ "OCN" ] = temp
2007 except KeyError:
2008 main.log.info("OCN not set in env")
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002009
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002010 try:
2011 temp = os.environ[ 'OCI' ]
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002012 envONOSIps[ "OCI" ] = temp
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002013 except:
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002014 main.log.error("OCI not set in env")
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002015
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002016 print(str(envONOSIps))
2017
2018 order = [ "OC1", "OC2", "OC3","OC4","OC5","OC6","OC7","OCN","OCI" ]
2019 ONOSIps = []
2020
2021 try:
cameron@onlab.us2e166212015-05-19 14:28:25 -07002022 if os.path.exists("myIps"):
2023 ipFile = open("myIps","r+")
2024 else:
2025 ipFile = open("myIps","w+")
2026
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002027 fileONOSIps = ipFile.readlines()
2028 ipFile.close()
2029
2030 print str(fileONOSIps)
2031
2032 if str(fileONOSIps) == "[]":
2033 ipFile = open("myIps","w+")
2034 for key in envONOSIps:
2035 ipFile.write(key+ "=" + envONOSIps[key] + "\n")
2036 ipFile.close()
2037 for i in order:
2038 if i in envONOSIps:
2039 ONOSIps.append(envONOSIps[i])
2040
2041 return ONOSIps
2042
2043 else:
2044 fileDict = {}
2045 for line in fileONOSIps:
2046 line = line.replace("\n","")
2047 line = line.split("=")
2048 key = line[0]
2049 value = line[1]
2050 fileDict[key] = value
2051
2052 for x in envONOSIps:
2053 if x in fileDict:
2054 if envONOSIps[x] == fileDict[x]:
2055 continue
2056 else:
2057 fileDict[x] = envONOSIps[x]
2058 else:
2059 fileDict[x] = envONOSIps[x]
2060
2061 ipFile = open("myIps","w+")
2062 for key in order:
2063 if key in fileDict:
2064 ipFile.write(key + "=" + fileDict[key] + "\n")
2065 ONOSIps.append(fileDict[key])
2066 ipFile.close()
2067
2068 return ONOSIps
2069
2070 except IOError as a:
2071 main.log.error(a)
2072
kelvin-onlab0a28a742015-05-18 16:03:13 -07002073 except Exception as a:
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002074 main.log.error(a)
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002075
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002076
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002077 def logReport(self, nodeIp, searchTerms, outputMode="s"):
2078 '''
2079 - accepts either a list or a string for "searchTerms" these
2080 terms will be searched for in the log and have their
2081 instances counted
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002082
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002083 - nodeIp is the ip of the node whos log is to be scanned
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002084
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002085 - output modes:
2086 "s" - Simple. Quiet output mode that just prints
cameron@onlab.us2e166212015-05-19 14:28:25 -07002087 the occurences of each search term
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002088
cameron@onlab.us2e166212015-05-19 14:28:25 -07002089 "d" - Detailed. Prints number of occurences as well as the entire
2090 line for each of the last 5 occurences
2091
2092 - returns total of the number of instances of all search terms
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002093 '''
2094 main.log.info("========================== Log Report ===========================\n")
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002095
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002096 if type(searchTerms) is str:
2097 searchTerms = [searchTerms]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002098
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002099 logLines = [ [" "] for i in range(len(searchTerms)) ]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002100
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002101 for term in range(len(searchTerms)):
2102 logLines[term][0] = searchTerms[term]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002103
cameron@onlab.us2e166212015-05-19 14:28:25 -07002104 totalHits = 0
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002105 for term in range(len(searchTerms)):
2106 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep " + searchTerms[term]
2107 self.handle.sendline(cmd)
2108 self.handle.expect(":~")
2109 before = (self.handle.before).splitlines()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002110
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002111 count = [searchTerms[term],0]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002112
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002113 for line in before:
2114 if searchTerms[term] in line and "grep" not in line:
2115 count[1] += 1
2116 if before.index(line) > ( len(before) - 7 ):
2117 logLines[term].append(line)
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002118
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002119 main.log.info( str(count[0]) + ": " + str(count[1]) )
2120 if term == len(searchTerms)-1:
2121 print("\n")
cameron@onlab.us2e166212015-05-19 14:28:25 -07002122 totalHits += int(count[1])
2123
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002124 if outputMode != "s" and outputMode != "S":
2125 outputString = ""
2126 for i in logLines:
2127 outputString = i[0] + ": \n"
2128 for x in range(1,len(i)):
2129 outputString += ( i[x] + "\n" )
2130
2131 if outputString != (i[0] + ": \n"):
2132 main.log.info(outputString)
2133
2134 main.log.info("================================================================\n")
cameron@onlab.us2e166212015-05-19 14:28:25 -07002135 return totalHits
pingping-lin763ee042015-05-20 17:45:30 -07002136
Hari Krishnaade11a72015-07-01 17:06:46 -07002137 def getOnosIPfromCell(self):
2138 '''
2139 Returns the ONOS node names and their IP addresses as defined in the cell and applied to shell environment
Hari Krishnaa25104c2015-07-09 22:34:01 -07002140 Example output return: ['10.128.40.41','10.128.40.42','10.128.40.43']. This will work even if the Mininet is
2141 not part of the cell definition and also if there are multiple mininets, just by using static hostname
2142 in TOPO file.
2143 '''
Hari Krishnaade11a72015-07-01 17:06:46 -07002144 import re
2145 try:
2146 # Clean handle by sending empty and expecting $
2147 self.handle.sendline( "" )
2148 self.handle.expect( "\$" )
2149 self.handle.sendline( "cell" )
2150 self.handle.expect( "\$" )
2151 handleBefore = self.handle.before
2152 handleAfter = self.handle.after
2153 # Get the rest of the handle
2154 self.handle.sendline( "" )
2155 self.handle.expect( "\$" )
2156 handleMore = self.handle.before
2157 ipList = []
2158 cellOutput = handleBefore + handleAfter + handleMore
2159 cellOutput = cellOutput.replace("\r\r","")
2160 cellOutput = cellOutput.splitlines()
2161 for i in range( len(cellOutput) ):
2162 if( re.match( "OC", cellOutput[i] ) ):
2163 if( re.match( "OCI", cellOutput[i] ) or re.match( "OCN", cellOutput[i] ) ):
2164 continue
2165 else:
2166 onosIP = cellOutput[i].split("=")
Hari Krishnac195f3b2015-07-08 20:02:24 -07002167 ipList.append(onosIP[1])
Hari Krishnaade11a72015-07-01 17:06:46 -07002168 return ipList
2169 except pexpect.ExceptionPexpect as e:
2170 main.log.error( self.name + ": Pexpect exception found of type " +
2171 str( type( e ) ) )
2172 main.log.error ( e.get_trace() )
2173 main.log.error( self.name + ": " + self.handle.before )
2174 main.cleanup()
2175 main.exit()
2176 except Exception:
2177 main.log.exception( self.name + ": Uncaught exception!" )
2178 main.cleanup()
2179 main.exit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002180
2181 def copyMininetFile( self, fileName, localPath, userName, ip,
2182 mnPath='~/mininet/custom/', timeout = 60 ):
2183 """
2184 Description:
2185 Copy mininet topology file from dependency folder in the test folder
2186 and paste it to the mininet machine's mininet/custom folder
2187 Required:
2188 fileName - Name of the topology file to copy
2189 localPath - File path of the mininet topology file
2190 userName - User name of the mininet machine to send the file to
2191 ip - Ip address of the mininet machine
2192 Optional:
2193 mnPath - of the mininet directory to send the file to
2194 Return:
2195 Return main.TRUE if successfully copied the file otherwise
2196 return main.FALSE
2197 """
2198
2199 try:
2200 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2201 str( ip ) + ":" + mnPath + fileName
2202
2203 self.handle.sendline( "" )
2204 self.handle.expect( "\$" )
2205
2206 main.log.info( self.name + ": Execute: " + cmd )
2207
2208 self.handle.sendline( cmd )
2209
2210 i = self.handle.expect( [ 'No such file',
2211 "100%",
2212 pexpect.TIMEOUT ] )
2213
2214 if i == 0:
2215 main.log.error( self.name + ": File " + fileName +
2216 " does not exist!" )
2217 return main.FALSE
2218
2219 if i == 1:
2220 main.log.info( self.name + ": File " + fileName +
2221 " has been copied!" )
2222 self.handle.sendline( "" )
2223 self.handle.expect( "\$" )
2224 return main.TRUE
2225
2226 except pexpect.EOF:
2227 main.log.error( self.name + ": EOF exception found" )
2228 main.log.error( self.name + ": " + self.handle.before )
2229 main.cleanup()
2230 main.exit()
2231 except pexpect.TIMEOUT:
2232 main.log.error( self.name + ": TIMEOUT exception found" )
2233 main.log.error( self.name + ": " + self.handle.before )
2234 main.cleanup()
2235 main.exit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002236
2237 def jvmSet(self, memory=8):
2238
2239 import os
2240
2241 homeDir = os.path.expanduser('~')
2242 filename = "/onos/tools/package/bin/onos-service"
2243
2244 serviceConfig = open(homeDir + filename, 'w+')
2245 serviceConfig.write("#!/bin/bash\n ")
2246 serviceConfig.write("#------------------------------------- \n ")
2247 serviceConfig.write("# Starts ONOS Apache Karaf container\n ")
2248 serviceConfig.write("#------------------------------------- \n ")
2249 serviceConfig.write("#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n ")
2250 serviceConfig.write("""export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str(memory) + "G -Xmx" + str(memory) + """G}" \n """)
2251 serviceConfig.write("[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n")
2252 serviceConfig.write("""${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """)
2253 serviceConfig.close()
2254
2255 def createDBFile(self, testData):
2256
2257 filename = main.TEST + "DB"
2258 DBString = ""
2259
2260 for item in testData:
2261 if type(item) is string:
2262 item = "'" + item + "'"
2263 if testData.index(item) < len(testData-1):
2264 item += ","
2265 DBString += str(item)
2266
2267 DBFile = open(filename, "a")
2268 DBFile.write(DBString)
2269 DBFile.close()
2270
2271 def verifySummary(self, ONOSIp,*deviceCount):
2272
2273 self.handle.sendline("onos " + ONOSIp + " summary")
2274 self.handle.expect(":~")
2275
2276 summaryStr = self.handle.before
2277 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2278
2279 #passed = "SCC(s)=1" in summaryStr
2280 #if deviceCount:
2281 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
2282
2283
2284 if "SCC(s)=1," in summaryStr:
2285 passed = True
2286 print("Summary is verifed")
2287 else:
2288 print("Summary failed")
2289
2290 if deviceCount:
2291 print" ============================="
2292 checkStr = "devices=" + str(deviceCount[0]) + ","
2293 print "Checkstr: " + checkStr
2294 if checkStr not in summaryStr:
2295 passed = False
2296 print("Device count failed")
2297 else:
2298 print "device count verified"
2299
2300 return passed