blob: 9ea663caf9216d4b5d6aef96bc909b95173d3924 [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
kelvin-onlabd3b64892015-01-20 13:26:24 -0800607 cellDirectory = self.home + "/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
752
753 ONOSIp = '10.0.0.1'
754 configName = 'org.onosproject.myapp'
755 configParam = 'appSetting 1'
756
757 """
758 try:
759 cfgStr = ( "onos "+str(ONOSIp)+" cfg set "+
760 str(configName) + " " +
761 str(configParam)
762 )
763
764 self.handle.sendline( "" )
765 self.handle.expect( "\$" )
766 self.handle.sendline( cfgStr )
767 self.handle.expect( "\$" )
768
769 # TODO: Add meaningful assertion
770
771 return main.TRUE
772
773 except pexpect.ExceptionPexpect as e:
774 main.log.error( self.name + ": Pexpect exception found of type " +
775 str( type( e ) ) )
776 main.log.error ( e.get_trace() )
777 main.log.error( self.name + ": " + self.handle.before )
778 main.cleanup()
779 main.exit()
780 except Exception:
781 main.log.exception( self.name + ": Uncaught exception!" )
782 main.cleanup()
783 main.exit()
784
kelvin-onlabd3b64892015-01-20 13:26:24 -0800785 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800786 """
andrewonlab05e362f2014-10-10 00:40:57 -0400787 Uses 'onos' command to send various ONOS CLI arguments.
788 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800789 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400790 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800791
792 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400793 CLI commands for ONOS. Try to use this function first
794 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800795 function.
796 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400797 by starting onos, and typing in 'onos' to enter the
798 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800799 available commands.
800 """
andrewonlab05e362f2014-10-10 00:40:57 -0400801 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800802 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800803 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400804 return main.FALSE
805 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800806 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400807 return main.FALSE
808
kelvin8ec71442015-01-15 16:57:00 -0800809 cmdstr = str( cmdstr )
810 self.handle.sendline( "" )
811 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400812
kelvin-onlabd3b64892015-01-20 13:26:24 -0800813 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800814 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400815
kelvin-onlabd3b64892015-01-20 13:26:24 -0800816 handleBefore = self.handle.before
Shreya Shaha73aaad2014-10-27 18:03:09 -0400817 print "handle_before = ", self.handle.before
kelvin-onlabd3b64892015-01-20 13:26:24 -0800818 # handleAfter = str( self.handle.after )
Jon Hall47a93fb2015-01-06 16:46:06 -0800819
kelvin8ec71442015-01-15 16:57:00 -0800820 # self.handle.sendline( "" )
821 # self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800822 # handleMore = str( self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400823
kelvin8ec71442015-01-15 16:57:00 -0800824 main.log.info( "Command sent successfully" )
andrewonlab05e362f2014-10-10 00:40:57 -0400825
kelvin8ec71442015-01-15 16:57:00 -0800826 # Obtain return handle that consists of result from
827 # the onos command. The string may need to be
828 # configured further.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800829 # returnString = handleBefore + handleAfter
830 returnString = handleBefore
831 print "return_string = ", returnString
832 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400833
834 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800835 main.log.error( self.name + ": EOF exception found" )
836 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400837 main.cleanup()
838 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800839 except Exception:
840 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab05e362f2014-10-10 00:40:57 -0400841 main.cleanup()
842 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400843
kelvin-onlabd3b64892015-01-20 13:26:24 -0800844 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800845 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400846 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800847 If -f option is provided, it also forces an uninstall.
848 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400849 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800850 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400851 files to certain onos nodes
852
853 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800854 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400855 try:
andrewonlab114768a2014-11-14 12:44:44 -0500856 if options:
kelvin8ec71442015-01-15 16:57:00 -0800857 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500858 else:
kelvin8ec71442015-01-15 16:57:00 -0800859 self.handle.sendline( "onos-install " + node )
860 self.handle.expect( "onos-install " )
861 # NOTE: this timeout may need to change depending on the network
862 # and size of ONOS
863 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800864 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800865 "ONOS\sis\salready\sinstalled",
866 pexpect.TIMEOUT ], timeout=60 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400867
Jon Hall7993bfc2014-10-09 16:30:14 -0400868 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800869 main.log.warn( "Network is unreachable" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400870 return main.FALSE
871 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800872 main.log.info(
873 "ONOS was installed on " +
874 node +
875 " and started" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400876 return main.TRUE
andrewonlabd9a73a72014-11-14 17:28:21 -0500877 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800878 main.log.info( "ONOS is already installed on " + node )
andrewonlabd9a73a72014-11-14 17:28:21 -0500879 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800880 elif i == 3:
881 main.log.info(
882 "Installation of ONOS on " +
883 node +
884 " timed out" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400885 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400886
887 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800888 main.log.error( self.name + ": EOF exception found" )
889 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400890 main.cleanup()
891 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800892 except Exception:
893 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400894 main.cleanup()
895 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400896
kelvin-onlabd3b64892015-01-20 13:26:24 -0800897 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800898 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400899 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400900 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800901 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400902 try:
kelvin8ec71442015-01-15 16:57:00 -0800903 self.handle.sendline( "" )
904 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800905 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800906 " start" )
907 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -0400908 "Job\sis\salready\srunning",
909 "start/running",
910 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800911 pexpect.TIMEOUT ], timeout=120 )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400912
913 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800914 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400915 return main.TRUE
916 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800917 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400918 return main.TRUE
919 else:
kelvin8ec71442015-01-15 16:57:00 -0800920 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400921 main.cleanup()
922 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -0400923 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800924 main.log.error( self.name + ": EOF exception found" )
925 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400926 main.cleanup()
927 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800928 except Exception:
929 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400930 main.cleanup()
931 main.exit()
932
kelvin-onlabd3b64892015-01-20 13:26:24 -0800933 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800934 """
andrewonlab2b30bd32014-10-09 16:48:55 -0400935 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400936 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800937 """
andrewonlab2b30bd32014-10-09 16:48:55 -0400938 try:
kelvin8ec71442015-01-15 16:57:00 -0800939 self.handle.sendline( "" )
940 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800941 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800942 " stop" )
943 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -0400944 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -0700945 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -0400946 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800947 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2b30bd32014-10-09 16:48:55 -0400948
949 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800950 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400951 return main.TRUE
952 elif i == 1:
Jon Hall65844a32015-03-09 19:09:37 -0700953 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800954 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -0400955 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700956 elif i == 2:
957 main.log.warn( "ONOS wasn't running" )
958 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -0400959 else:
kelvin8ec71442015-01-15 16:57:00 -0800960 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400961 return main.FALSE
962
963 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800964 main.log.error( self.name + ": EOF exception found" )
965 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -0400966 main.cleanup()
967 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800968 except Exception:
969 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400970 main.cleanup()
971 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800972
kelvin-onlabd3b64892015-01-20 13:26:24 -0800973 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -0800974 """
andrewonlabc8d47972014-10-09 16:52:36 -0400975 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -0800976 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -0400977 if needed
kelvin8ec71442015-01-15 16:57:00 -0800978 """
andrewonlabc8d47972014-10-09 16:52:36 -0400979 try:
kelvin8ec71442015-01-15 16:57:00 -0800980 self.handle.sendline( "" )
pingping-lin763ee042015-05-20 17:45:30 -0700981 self.handle.expect( "\$", timeout=60 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800982 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800983 self.handle.expect( "\$" )
andrewonlabc8d47972014-10-09 16:52:36 -0400984
kelvin-onlabd3b64892015-01-20 13:26:24 -0800985 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
andrewonlab9dfd2082014-11-13 17:44:03 -0500986
kelvin8ec71442015-01-15 16:57:00 -0800987 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -0400988 return main.TRUE
989
pingping-lin763ee042015-05-20 17:45:30 -0700990 except pexpect.TIMEOUT:
991 main.log.exception( self.name + ": Timeout in onosUninstall" )
992 return main.FALSE
andrewonlabc8d47972014-10-09 16:52:36 -0400993 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800994 main.log.error( self.name + ": EOF exception found" )
995 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -0400996 main.cleanup()
997 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800998 except Exception:
999 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc8d47972014-10-09 16:52:36 -04001000 main.cleanup()
1001 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -04001002
kelvin-onlabd3b64892015-01-20 13:26:24 -08001003 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001004 """
andrewonlabaedc8332014-12-04 12:43:03 -05001005 Issues the command 'onos-die <node-ip>'
1006 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -08001007 """
andrewonlabaedc8332014-12-04 12:43:03 -05001008 try:
kelvin8ec71442015-01-15 16:57:00 -08001009 self.handle.sendline( "" )
1010 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001011 cmdStr = "onos-kill " + str( nodeIp )
1012 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001013 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -05001014 "Killing\sONOS",
1015 "ONOS\sprocess\sis\snot\srunning",
kelvin8ec71442015-01-15 16:57:00 -08001016 pexpect.TIMEOUT ], timeout=20 )
andrewonlabaedc8332014-12-04 12:43:03 -05001017 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001018 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001019 " was killed and stopped" )
andrewonlabaedc8332014-12-04 12:43:03 -05001020 return main.TRUE
1021 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001022 main.log.info( "ONOS process was not running" )
andrewonlabaedc8332014-12-04 12:43:03 -05001023 return main.FALSE
1024 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001025 main.log.error( self.name + ": EOF exception found" )
1026 main.log.error( self.name + ": " + self.handle.before )
andrewonlabaedc8332014-12-04 12:43:03 -05001027 main.cleanup()
1028 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001029 except Exception:
1030 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabaedc8332014-12-04 12:43:03 -05001031 main.cleanup()
1032 main.exit()
1033
kelvin-onlabd3b64892015-01-20 13:26:24 -08001034 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001035 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001036 Calls the command: 'onos-kill [<node-ip>]'
1037 "Remotely, and unceremoniously kills the ONOS instance running on
1038 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001039 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001040 try:
kelvin8ec71442015-01-15 16:57:00 -08001041 self.handle.sendline( "" )
1042 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001043 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001044 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -04001045 "\$",
1046 "No\sroute\sto\shost",
1047 "password:",
kelvin8ec71442015-01-15 16:57:00 -08001048 pexpect.TIMEOUT ], timeout=20 )
1049
andrewonlabe8e56fd2014-10-09 17:12:44 -04001050 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001051 main.log.info(
1052 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001054 return main.TRUE
1055 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001056 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001057 return main.FALSE
1058 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001059 main.log.info(
1060 "Passwordless login for host: " +
1061 str( nodeIp ) +
1062 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001063 return main.FALSE
1064 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001065 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001066 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001067
andrewonlabe8e56fd2014-10-09 17:12:44 -04001068 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001069 main.log.error( self.name + ": EOF exception found" )
1070 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001071 main.cleanup()
1072 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001073 except Exception:
1074 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001075 main.cleanup()
1076 main.exit()
1077
kelvin-onlabd3b64892015-01-20 13:26:24 -08001078 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001079 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001080 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001081 a cleaner environment.
1082
andrewonlab19fbdca2014-11-14 12:55:59 -05001083 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001084 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001085 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001086 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001087 try:
kelvin8ec71442015-01-15 16:57:00 -08001088 self.handle.sendline( "" )
1089 self.handle.expect( "\$" )
1090 self.handle.sendline( "onos-remove-raft-logs" )
1091 # Sometimes this command hangs
1092 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1093 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001094 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001095 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1096 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001097 if i == 1:
1098 return main.FALSE
shahshreya957feaa2015-03-23 16:08:29 -07001099 #self.handle.sendline( "" )
1100 #self.handle.expect( "\$" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001101 return main.TRUE
1102
1103 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001104 main.log.error( self.name + ": EOF exception found" )
1105 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -05001106 main.cleanup()
1107 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001108 except Exception:
1109 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001110 main.cleanup()
1111 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -05001112
kelvin-onlabd3b64892015-01-20 13:26:24 -08001113 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001114 """
1115 Calls the command 'onos-start-network [ <mininet-topo> ]
1116 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001117 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001118 cell."
andrewonlab94282092014-10-10 13:00:11 -04001119 * Specify mininet topology file name for mntopo
1120 * Topo files should be placed at:
1121 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001122
andrewonlab94282092014-10-10 13:00:11 -04001123 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001124 """
andrewonlab94282092014-10-10 13:00:11 -04001125 try:
1126 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001127 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001128 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001129
kelvin8ec71442015-01-15 16:57:00 -08001130 mntopo = str( mntopo )
1131 self.handle.sendline( "" )
1132 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -04001133
kelvin8ec71442015-01-15 16:57:00 -08001134 self.handle.sendline( "onos-start-network " + mntopo )
1135 self.handle.expect( "mininet>" )
1136 main.log.info( "Network started, entered mininet prompt" )
1137
1138 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001139
1140 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001141 main.log.error( self.name + ": EOF exception found" )
1142 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -04001143 main.cleanup()
1144 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001145 except Exception:
1146 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -04001147 main.cleanup()
1148 main.exit()
1149
Cameron Franke9c94fb02015-01-21 10:20:20 -08001150 def isup(self, node = "", timeout = 120):
kelvin8ec71442015-01-15 16:57:00 -08001151 """
1152 Run's onos-wait-for-start which only returns once ONOS is at run
Cameron Franke9c94fb02015-01-21 10:20:20 -08001153 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001154
Jon Hall7993bfc2014-10-09 16:30:14 -04001155 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001156 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001157 try:
Cameron Franke9c94fb02015-01-21 10:20:20 -08001158 self.handle.sendline("onos-wait-for-start " + node )
1159 self.handle.expect("onos-wait-for-start")
kelvin8ec71442015-01-15 16:57:00 -08001160 # NOTE: this timeout is arbitrary"
Cameron Franke9c94fb02015-01-21 10:20:20 -08001161 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001162 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001163 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001164 return main.TRUE
1165 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001166 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001167 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001168 main.log.error( "ONOS has not started yet" )
1169 self.handle.send( "\x03" ) # Control-C
1170 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001171 return main.FALSE
1172 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001173 main.log.error( self.name + ": EOF exception found" )
1174 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -04001175 main.cleanup()
1176 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001177 except Exception:
1178 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001179 main.cleanup()
1180 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001181
kelvin-onlabd3b64892015-01-20 13:26:24 -08001182 def pushTestIntentsShell(
1183 self,
1184 dpidSrc,
1185 dpidDst,
1186 numIntents,
1187 dirFile,
1188 onosIp,
1189 numMult="",
1190 appId="",
1191 report=True,
1192 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001193 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001194 Description:
kelvin8ec71442015-01-15 16:57:00 -08001195 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001196 better parallelize the results than the CLI
1197 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001198 * dpidSrc: specify source dpid
1199 * dpidDst: specify destination dpid
1200 * numIntents: specify number of intents to push
1201 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001202 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001203 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001204 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001205 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001206 """
1207 try:
1208 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001209 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001210 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001211 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001212 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001213 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001214
kelvin-onlabd3b64892015-01-20 13:26:24 -08001215 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1216 if not numMult:
1217 addIntents = addDpid + " " + str( numIntents )
1218 elif numMult:
1219 addIntents = addDpid + " " + str( numIntents ) + " " +\
1220 str( numMult )
1221 if appId:
1222 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001223 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001224 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001225
andrewonlabaedc8332014-12-04 12:43:03 -05001226 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001227 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001228 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001229 sendCmd = addApp + " &"
1230 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001231
kelvin-onlabd3b64892015-01-20 13:26:24 -08001232 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001233
1234 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001235 main.log.error( self.name + ": EOF exception found" )
1236 main.log.error( self.name + ": " + self.handle.before )
andrewonlabb66dfa12014-12-02 15:51:10 -05001237 main.cleanup()
1238 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001239 except Exception:
1240 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001241 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001242 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001243
kelvin-onlabd3b64892015-01-20 13:26:24 -08001244 def getTopology( self, topologyOutput ):
kelvin8ec71442015-01-15 16:57:00 -08001245 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001246 Definition:
1247 Loads a json topology output
1248 Return:
1249 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -08001250 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001251 import json
Jon Hall77f53ce2014-10-13 18:02:06 -04001252 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001253 # either onos:topology or 'topology' will work in CLI
1254 topology = json.loads(topologyOutput)
1255 print topology
Jon Hall77f53ce2014-10-13 18:02:06 -04001256 return topology
1257 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001258 main.log.error( self.name + ": EOF exception found" )
1259 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001260 main.cleanup()
1261 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001262 except Exception:
1263 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001264 main.cleanup()
1265 main.exit()
1266
kelvin-onlabd3b64892015-01-20 13:26:24 -08001267 def checkStatus(
1268 self,
1269 topologyResult,
1270 numoswitch,
1271 numolink,
1272 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001273 """
Jon Hallefbd9792015-03-05 16:11:36 -08001274 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001275 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001276 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08001277
Jon Hall77f53ce2014-10-13 18:02:06 -04001278 Params: ip = ip used for the onos cli
1279 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001280 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001281 logLevel = level to log to.
1282 Currently accepts 'info', 'warn' and 'report'
Jon Hall77f53ce2014-10-13 18:02:06 -04001283
1284
kelvin-onlabd3b64892015-01-20 13:26:24 -08001285 logLevel can
Jon Hall77f53ce2014-10-13 18:02:06 -04001286
Jon Hallefbd9792015-03-05 16:11:36 -08001287 Returns: main.TRUE if the number of switches and links are correct,
1288 main.FALSE if the number of switches and links is incorrect,
Jon Hall77f53ce2014-10-13 18:02:06 -04001289 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001290 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001291 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001292 topology = self.getTopology( topologyResult )
Jon Hall77f53ce2014-10-13 18:02:06 -04001293 if topology == {}:
1294 return main.ERROR
1295 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001296 # Is the number of switches is what we expected
shahshreya234a1682015-05-27 15:41:56 -07001297 devices = topology.get( 'devices', False )
1298 links = topology.get( 'links', False )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001299 if not devices or not links:
Jon Hall77f53ce2014-10-13 18:02:06 -04001300 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001301 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001302 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001303 linkCheck = ( int( links ) == int( numolink ) )
Jon Hallefbd9792015-03-05 16:11:36 -08001304 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08001305 # We expected the correct numbers
Jon Hall77f53ce2014-10-13 18:02:06 -04001306 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001307 + "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001308 result = main.TRUE
1309 else:
1310 output = output + \
Jon Hall274b6642015-02-17 11:57:17 -08001311 "The number of links and switches does not match " + \
1312 "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001313 result = main.FALSE
Jon Hallefbd9792015-03-05 16:11:36 -08001314 output = output + "\n ONOS sees %i devices" % int( devices )
1315 output = output + " (%i expected) " % int( numoswitch )
Jon Hall274b6642015-02-17 11:57:17 -08001316 output = output + "and %i links " % int( links )
1317 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001318 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001319 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001320 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001321 main.log.warn( output )
Jon Hall77f53ce2014-10-13 18:02:06 -04001322 else:
kelvin8ec71442015-01-15 16:57:00 -08001323 main.log.info( output )
1324 return result
Jon Hall77f53ce2014-10-13 18:02:06 -04001325 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001326 main.log.error( self.name + ": EOF exception found" )
1327 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001328 main.cleanup()
1329 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001330 except Exception:
1331 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001332 main.cleanup()
1333 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001334
kelvin-onlabd3b64892015-01-20 13:26:24 -08001335 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001336 """
andrewonlab970399c2014-11-07 13:09:32 -05001337 Capture all packet activity and store in specified
1338 directory/file
1339
1340 Required:
1341 * interface: interface to capture
1342 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001343 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001344 try:
1345 self.handle.sendline( "" )
1346 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001347
Jon Hallfebb1c72015-03-05 13:30:09 -08001348 self.handle.sendline( "tshark -i " + str( interface ) +
1349 " -t e -w " + str( dirFile ) + " &" )
1350 self.handle.sendline( "\r" )
1351 self.handle.expect( "Capturing on" )
1352 self.handle.sendline( "\r" )
1353 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001354
Jon Hallfebb1c72015-03-05 13:30:09 -08001355 main.log.info( "Tshark started capturing files on " +
1356 str( interface ) + " and saving to directory: " +
1357 str( dirFile ) )
1358 except pexpect.EOF:
1359 main.log.error( self.name + ": EOF exception found" )
1360 main.log.error( self.name + ": " + self.handle.before )
1361 main.cleanup()
1362 main.exit()
1363 except Exception:
1364 main.log.exception( self.name + ": Uncaught exception!" )
1365 main.cleanup()
1366 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001367
kelvin-onlabd3b64892015-01-20 13:26:24 -08001368 def runOnosTopoCfg( self, instanceName, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001369 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001370 On ONOS bench, run this command:
Jon Halle94919c2015-03-23 11:42:57 -07001371 {ONOS_HOME}/tools/test/bin/onos-topo-cfg $OC1 filename
kelvin-onlabd3b64892015-01-20 13:26:24 -08001372 which starts the rest and copies
1373 the json file to the onos instance
kelvin8ec71442015-01-15 16:57:00 -08001374 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001375 try:
kelvin8ec71442015-01-15 16:57:00 -08001376 self.handle.sendline( "" )
1377 self.handle.expect( "\$" )
Jon Halle94919c2015-03-23 11:42:57 -07001378 self.handle.sendline( "cd " + self.home + "/tools/test/bin" )
kelvin8ec71442015-01-15 16:57:00 -08001379 self.handle.expect( "/bin$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001380 cmd = "./onos-topo-cfg " + instanceName + " " + jsonFile
shahshreyae6c7cf42014-11-26 16:39:01 -08001381 print "cmd = ", cmd
kelvin8ec71442015-01-15 16:57:00 -08001382 self.handle.sendline( cmd )
1383 self.handle.expect( "\$" )
1384 self.handle.sendline( "cd ~" )
1385 self.handle.expect( "\$" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001386 return main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -08001387 except pexpect.EOF:
1388 main.log.error( self.name + ": EOF exception found" )
1389 main.log.error( self.name + ": " + self.handle.before )
1390 main.cleanup()
1391 main.exit()
1392 except Exception:
1393 main.log.exception( self.name + ": Uncaught exception!" )
1394 main.cleanup()
1395 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001396
jenkins1e99e7b2015-04-02 18:15:39 -07001397 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001398 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001399 Required:
kelvin8ec71442015-01-15 16:57:00 -08001400 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001401 * directory to store results
1402 Optional:
1403 * interface - default: eth0
jenkins1e99e7b2015-04-02 18:15:39 -07001404 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001405 Description:
1406 Uses tshark command to grep specific group of packets
1407 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001408 The timestamp is hardcoded to be in epoch
1409 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001410 try:
1411 self.handle.sendline( "" )
1412 self.handle.expect( "\$" )
1413 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001414 if grepOptions:
1415 grepStr = "grep "+str(grepOptions)
1416 else:
1417 grepStr = "grep"
1418
Jon Hallfebb1c72015-03-05 13:30:09 -08001419 self.handle.sendline(
1420 "tshark -i " +
1421 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001422 " -t e | " +
1423 grepStr + " --line-buffered \"" +
Jon Hallfebb1c72015-03-05 13:30:09 -08001424 str(grep) +
1425 "\" >" +
1426 directory +
1427 " &" )
1428 self.handle.sendline( "\r" )
1429 self.handle.expect( "Capturing on" )
1430 self.handle.sendline( "\r" )
1431 self.handle.expect( "\$" )
1432 except pexpect.EOF:
1433 main.log.error( self.name + ": EOF exception found" )
1434 main.log.error( self.name + ": " + self.handle.before )
1435 main.cleanup()
1436 main.exit()
1437 except Exception:
1438 main.log.exception( self.name + ": Uncaught exception!" )
1439 main.cleanup()
1440 main.exit()
1441
kelvin-onlabd3b64892015-01-20 13:26:24 -08001442 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001443 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001444 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001445 """
1446 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001447 try:
1448 self.execute( cmd="sudo rm /tmp/wireshark*" )
1449 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001450 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1451 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001452 self.handle.sendline( "" )
1453 main.log.info( "Tshark stopped" )
1454 except pexpect.EOF:
1455 main.log.error( self.name + ": EOF exception found" )
1456 main.log.error( self.name + ": " + self.handle.before )
1457 main.cleanup()
1458 main.exit()
1459 except Exception:
1460 main.log.exception( self.name + ": Uncaught exception!" )
1461 main.cleanup()
1462 main.exit()
1463
kelvin8ec71442015-01-15 16:57:00 -08001464 def ptpd( self, args ):
1465 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001466 Initiate ptp with user-specified args.
1467 Required:
1468 * args: specify string of args after command
1469 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001470 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001471 try:
kelvin8ec71442015-01-15 16:57:00 -08001472 self.handle.sendline( "sudo ptpd " + str( args ) )
1473 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001474 "Multiple",
1475 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001476 "\$" ] )
1477 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001478
andrewonlab0c38a4a2014-10-28 18:35:35 -04001479 if i == 0:
1480 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001481 main.log.info( "ptpd returned an error: " +
1482 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001483 return handle
1484 elif i == 1:
1485 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001486 main.log.error( "ptpd returned an error: " +
1487 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001488 return handle
1489 else:
1490 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001491
andrewonlab0c38a4a2014-10-28 18:35:35 -04001492 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001493 main.log.error( self.name + ": EOF exception found" )
1494 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001495 main.cleanup()
1496 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001497 except Exception:
1498 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001499 main.cleanup()
1500 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001501
kelvin-onlabd3b64892015-01-20 13:26:24 -08001502 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001503 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001504 """
1505 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001506 Current implementation of ONOS deletes its karaf
1507 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001508 you may want to use this function to capture
1509 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001510 Localtime will be attached to the filename
1511
1512 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001513 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001514 copy.
kelvin8ec71442015-01-15 16:57:00 -08001515 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001516 For copying multiple files, leave copyFileName
1517 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001518 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001519 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001520 ex ) /tmp/
1521 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001522 * copyFileName: If you want to rename the log
1523 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001524 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001525 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001526 try:
kelvin8ec71442015-01-15 16:57:00 -08001527 localtime = time.strftime( '%x %X' )
1528 localtime = localtime.replace( "/", "" )
1529 localtime = localtime.replace( " ", "_" )
1530 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001531 if destDir[ -1: ] != "/":
1532 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001533
kelvin-onlabd3b64892015-01-20 13:26:24 -08001534 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001535 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1536 str( destDir ) + str( copyFileName ) +
1537 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001538 self.handle.expect( "cp" )
1539 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001540 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001541 self.handle.sendline( "cp " + str( logToCopy ) +
1542 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001543 self.handle.expect( "cp" )
1544 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001545
kelvin8ec71442015-01-15 16:57:00 -08001546 return self.handle.before
1547
1548 except pexpect.EOF:
1549 main.log.error( "Copying files failed" )
1550 main.log.error( self.name + ": EOF exception found" )
1551 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001552 except Exception:
1553 main.log.exception( "Copying files failed" )
1554
Jon Hall16b72c42015-05-20 10:23:36 -07001555 def checkLogs( self, onosIp, restart=False):
kelvin8ec71442015-01-15 16:57:00 -08001556 """
Jon Hall94fd0472014-12-08 11:52:42 -08001557 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001558 If restart is True, use the old version of onos-check-logs which
1559 does not print the full stacktrace, but shows the entire log file,
1560 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001561 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001562 """
Jon Hall94fd0472014-12-08 11:52:42 -08001563 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001564 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001565 if restart:
1566 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001567 self.handle.sendline( cmd )
1568 self.handle.expect( cmd )
1569 self.handle.expect( "\$" )
Jon Hall94fd0472014-12-08 11:52:42 -08001570 response = self.handle.before
1571 return response
1572 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001573 main.log.error( "Lost ssh connection" )
1574 main.log.error( self.name + ": EOF exception found" )
1575 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001576 except Exception:
1577 main.log.exception( self.name + ": Uncaught exception!" )
1578 main.cleanup()
1579 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001580
kelvin-onlabd3b64892015-01-20 13:26:24 -08001581 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001582 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001583 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001584 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001585 try:
kelvin8ec71442015-01-15 16:57:00 -08001586 self.handle.sendline( "" )
1587 self.handle.expect( "\$" )
1588 self.handle.sendline( "onos-service " + str( node ) +
1589 " status" )
1590 i = self.handle.expect( [
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001591 "start/running",
1592 "stop/waiting",
kelvin8ec71442015-01-15 16:57:00 -08001593 pexpect.TIMEOUT ], timeout=120 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001594
1595 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001596 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001597 return main.TRUE
1598 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001599 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001600 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001601 main.cleanup()
1602 main.exit()
1603 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001604 main.log.error( self.name + ": EOF exception found" )
1605 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001606 main.cleanup()
1607 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001608 except Exception:
1609 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001610 main.cleanup()
1611 main.exit()
Jon Hall21270ac2015-02-16 17:59:55 -08001612
Jon Hall63604932015-02-26 17:09:50 -08001613 def setIpTables( self, ip, port='', action='add', packet_type='',
1614 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001615 """
Jon Hall21270ac2015-02-16 17:59:55 -08001616 Description:
1617 add or remove iptables rule to DROP (default) packets from
1618 specific IP and PORT
1619 Usage:
1620 * specify action ('add' or 'remove')
1621 when removing, pass in the same argument as you would add. It will
1622 delete that specific rule.
1623 * specify the ip to block
1624 * specify the destination port to block (defaults to all ports)
1625 * optional packet type to block (default tcp)
1626 * optional iptables rule (default DROP)
1627 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001628 * States boolean toggles adding all supported tcp states to the
1629 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001630 Returns:
1631 main.TRUE on success or
1632 main.FALSE if given invalid input or
1633 main.ERROR if there is an error in response from iptables
1634 WARNING:
1635 * This function uses root privilege iptables command which may result
1636 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001637 """
Jon Hall21270ac2015-02-16 17:59:55 -08001638 import time
1639
1640 # NOTE*********
1641 # The strict checking methods of this driver function is intentional
1642 # to discourage any misuse or error of iptables, which can cause
1643 # severe network errors
1644 # *************
1645
1646 # NOTE: Sleep needed to give some time for rule to be added and
1647 # registered to the instance. If you are calling this function
1648 # multiple times this sleep will prevent any errors.
1649 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001650 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001651 try:
1652 # input validation
1653 action_type = action.lower()
1654 rule = rule.upper()
1655 direction = direction.upper()
1656 if action_type != 'add' and action_type != 'remove':
1657 main.log.error( "Invalid action type. Use 'add' or "
1658 "'remove' table rule" )
1659 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1660 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1661 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1662 "'ACCEPT' or 'LOG' only." )
1663 if direction != 'INPUT' and direction != 'OUTPUT':
1664 # NOTE currently only supports rules INPUT and OUPTUT
1665 main.log.error( "Invalid rule. Valid directions are"
1666 " 'OUTPUT' or 'INPUT'" )
1667 return main.FALSE
1668 return main.FALSE
1669 return main.FALSE
1670 if action_type == 'add':
1671 # -A is the 'append' action of iptables
1672 actionFlag = '-A'
1673 elif action_type == 'remove':
1674 # -D is the 'delete' rule of iptables
1675 actionFlag = '-D'
1676 self.handle.sendline( "" )
1677 self.handle.expect( "\$" )
1678 cmd = "sudo iptables " + actionFlag + " " +\
1679 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001680 " -s " + str( ip )
Jon Hall63604932015-02-26 17:09:50 -08001681 # " -p " + str( packet_type ) +\
1682 if packet_type:
1683 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001684 if port:
1685 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001686 if states:
1687 cmd += " -m state --state="
1688 #FIXME- Allow user to configure which states to block
1689 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001690 cmd += " -j " + str( rule )
1691
1692 self.handle.sendline( cmd )
1693 self.handle.expect( "\$" )
1694 main.log.warn( self.handle.before )
1695
1696 info_string = "On " + str( self.name )
1697 info_string += " " + str( action_type )
1698 info_string += " iptable rule [ "
1699 info_string += " IP: " + str( ip )
1700 info_string += " Port: " + str( port )
1701 info_string += " Rule: " + str( rule )
1702 info_string += " Direction: " + str( direction ) + " ]"
1703 main.log.info( info_string )
1704 return main.TRUE
1705 except pexpect.TIMEOUT:
1706 main.log.exception( self.name + ": Timeout exception in "
1707 "setIpTables function" )
1708 return main.ERROR
1709 except pexpect.EOF:
1710 main.log.error( self.name + ": EOF exception found" )
1711 main.log.error( self.name + ": " + self.handle.before )
1712 main.cleanup()
1713 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001714 except Exception:
1715 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall21270ac2015-02-16 17:59:55 -08001716 main.cleanup()
1717 main.exit()
1718
Jon Hall0468b042015-02-19 19:08:21 -08001719 def detailed_status(self, log_filename):
Jon Hallefbd9792015-03-05 16:11:36 -08001720 """
Jon Hall0468b042015-02-19 19:08:21 -08001721 This method is used by STS to check the status of the controller
1722 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001723 """
Jon Hall0468b042015-02-19 19:08:21 -08001724 import re
1725 try:
1726 self.handle.sendline( "" )
1727 self.handle.expect( "\$" )
1728 self.handle.sendline( "cd " + self.home )
1729 self.handle.expect( "\$" )
1730 self.handle.sendline( "service onos status" )
1731 self.handle.expect( "\$" )
1732 response = self.handle.before
1733 if re.search( "onos start/running", response ):
1734 # onos start/running, process 10457
1735 return 'RUNNING'
1736 # FIXME: Implement this case
1737 # elif re.search( pattern, response ):
1738 # return 'STARTING'
1739 elif re.search( "onos stop/", response ):
1740 # onos stop/waiting
1741 # FIXME handle this differently?: onos stop/pre-stop
1742 return 'STOPPED'
1743 # FIXME: Implement this case
1744 # elif re.search( pattern, response ):
1745 # return 'FROZEN'
1746 else:
1747 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001748 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001749 main.log.warn( response )
1750 return 'ERROR', "Unknown response: %s" % response
1751 except pexpect.TIMEOUT:
1752 main.log.exception( self.name + ": Timeout exception in "
1753 "setIpTables function" )
1754 return 'ERROR', "Pexpect Timeout"
1755 except pexpect.EOF:
1756 main.log.error( self.name + ": EOF exception found" )
1757 main.log.error( self.name + ": " + self.handle.before )
1758 main.cleanup()
1759 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001760 except Exception:
1761 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall0468b042015-02-19 19:08:21 -08001762 main.cleanup()
1763 main.exit()
1764
andrew@onlab.us3b087132015-03-11 15:00:08 -07001765 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1766 '''
1767 Create/formats the LinkGraph.cfg file based on arguments
1768 -only creates a linear topology and connects islands
1769 -evenly distributes devices
1770 -must be called by ONOSbench
1771
1772 ONOSIpList - list of all of the node IPs to be used
1773
1774 deviceCount - number of switches to be assigned
1775 '''
1776 main.log.step("Creating link graph configuration file." )
1777 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
1778 tempFile = "/tmp/linkGraph.cfg"
1779
1780 linkGraph = open(tempFile, 'w+')
1781 linkGraph.write("# NullLinkProvider topology description (config file).\n")
1782 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
1783 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
1784
1785 clusterCount = len(ONOSIpList)
1786
1787 if type(deviceCount) is int or type(deviceCount) is str:
1788 deviceCount = int(deviceCount)
1789 switchList = [0]*(clusterCount+1)
1790 baselineSwitchCount = deviceCount/clusterCount
1791
1792 for node in range(1, clusterCount + 1):
1793 switchList[node] = baselineSwitchCount
1794
1795 for node in range(1, (deviceCount%clusterCount)+1):
1796 switchList[node] += 1
1797
1798 if type(deviceCount) is list:
1799 main.log.info("Using provided device distribution")
1800 switchList = [0]
1801 for i in deviceCount:
1802 switchList.append(int(i))
1803
1804 tempList = ['0']
1805 tempList.extend(ONOSIpList)
1806 ONOSIpList = tempList
1807
1808 myPort = 6
1809 lastSwitch = 0
1810 for node in range(1, clusterCount+1):
1811 if switchList[node] == 0:
1812 continue
1813
1814 linkGraph.write("graph " + ONOSIpList[node] + " {\n")
1815
1816 if node > 1:
1817 #connect to last device on previous node
1818 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
1819 linkGraph.write(line)
1820
1821 lastSwitch = 0
1822 for switch in range (0, switchList[node]-1):
1823 line = ""
1824 line = ("\t" + str(switch) + ":" + str(myPort))
1825 line += " -- "
1826 line += (str(switch+1) + ":" + str(myPort-1) + "\n")
1827 linkGraph.write(line)
1828 lastSwitch = switch+1
1829 lastIp = ONOSIpList[node]
1830
1831 #lastSwitch += 1
1832 if node < (clusterCount):
1833 #connect to first device on the next node
1834 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
1835 linkGraph.write(line)
1836
1837 linkGraph.write("}\n")
1838 linkGraph.close()
1839
1840 #SCP
1841 os.system( "scp " + tempFile + " admin@" + benchIp + ":" + linkGraphPath)
1842 main.log.info("linkGraph.cfg creation complete")
1843
cameron@onlab.us75900962015-03-30 13:22:49 -07001844 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001845
1846 '''
andrew@onlab.us3b087132015-03-11 15:00:08 -07001847 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
cameron@onlab.us75900962015-03-30 13:22:49 -07001848 deviceCount = number of switches to distribute, or list of values to use as custom distribution
1849 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 -07001850 '''
1851
cameron@onlab.us75900962015-03-30 13:22:49 -07001852 main.log.step("Configuring Null Device Provider" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07001853 clusterCount = len(ONOSIpList)
1854
cameron@onlab.us75900962015-03-30 13:22:49 -07001855 try:
1856
1857 if type(deviceCount) is int or type(deviceCount) is str:
1858 main.log.step("Creating device distribution")
1859 deviceCount = int(deviceCount)
1860 switchList = [0]*(clusterCount+1)
1861 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001862
cameron@onlab.us75900962015-03-30 13:22:49 -07001863 for node in range(1, clusterCount + 1):
1864 switchList[node] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001865
cameron@onlab.us75900962015-03-30 13:22:49 -07001866 for node in range(1, (deviceCount%clusterCount)+1):
1867 switchList[node] += 1
1868
1869 if type(deviceCount) is list:
1870 main.log.info("Using provided device distribution")
1871
1872 if len(deviceCount) == clusterCount:
1873 switchList = ['0']
1874 switchList.extend(deviceCount)
1875
1876 if len(deviceCount) == (clusterCount + 1):
1877 if deviceCount[0] == '0' or deviceCount[0] == 0:
1878 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001879
cameron@onlab.us75900962015-03-30 13:22:49 -07001880 assert len(switchList) == (clusterCount + 1)
1881
1882 except AssertionError:
1883 main.log.error( "Bad device/Ip list match")
1884 except TypeError:
1885 main.log.exception( self.name + ": Object not as expected" )
1886 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07001887 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001888 main.log.exception( self.name + ": Uncaught exception!" )
1889 main.cleanup()
1890 main.exit()
1891
andrew@onlab.us3b087132015-03-11 15:00:08 -07001892
1893 ONOSIp = [0]
1894 ONOSIp.extend(ONOSIpList)
1895
1896 devicesString = "devConfigs = "
1897 for node in range(1, len(ONOSIp)):
1898 devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
1899 if node < clusterCount:
1900 devicesString += (",")
cameron@onlab.us75900962015-03-30 13:22:49 -07001901
1902 try:
1903 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
1904 self.handle.expect(":~")
1905 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) )
1906 self.handle.expect(":~")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001907
cameron@onlab.us75900962015-03-30 13:22:49 -07001908 for i in range(10):
1909 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider")
1910 self.handle.expect(":~")
1911 verification = self.handle.before
1912 if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification:
1913 break
1914 else:
1915 time.sleep(1)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001916
cameron@onlab.us2cc8bf12015-04-02 14:12:30 -07001917 assert ("value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification
cameron@onlab.us75900962015-03-30 13:22:49 -07001918
1919 except AssertionError:
1920 main.log.error("Incorrect Config settings: " + verification)
Jon Hall77ba41c2015-04-06 10:25:40 -07001921 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001922 main.log.exception( self.name + ": Uncaught exception!" )
1923 main.cleanup()
1924 main.exit()
1925
cameron@onlab.usc80a8c82015-04-15 14:57:37 -07001926 def configNullLink( self,fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001927 '''
cameron@onlab.us75900962015-03-30 13:22:49 -07001928 fileName default is currently the same as the default on ONOS, specify alternate file if
1929 you want to use a different topology file than linkGraph.cfg
andrew@onlab.us3b087132015-03-11 15:00:08 -07001930 '''
1931
andrew@onlab.us3b087132015-03-11 15:00:08 -07001932
cameron@onlab.us75900962015-03-30 13:22:49 -07001933 try:
1934 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str(eventRate))
1935 self.handle.expect(":~")
1936 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
1937 self.handle.expect(":~")
1938
1939 for i in range(10):
1940 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider")
1941 self.handle.expect(":~")
1942 verification = self.handle.before
1943 if (" value=" + str(eventRate)) in verification and (" value=" + fileName) in verification:
1944 break
1945 else:
1946 time.sleep(1)
1947
1948 assert ("value=" + str(eventRate)) in verification and (" value=" + fileName) in verification
1949
1950 except pexpect.EOF:
1951 main.log.error( self.name + ": EOF exception found" )
1952 main.log.error( self.name + ": " + self.handle.before )
1953 main.cleanup()
1954 main.exit()
cameron@onlab.us75900962015-03-30 13:22:49 -07001955 except AssertionError:
1956 main.log.info("Settings did not post to ONOS")
1957 main.log.error(varification)
Jon Hall77ba41c2015-04-06 10:25:40 -07001958 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001959 main.log.exception( self.name + ": Uncaught exception!" )
1960 main.log.error(varification)
1961 main.cleanup()
1962 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07001963
cameron@onlab.us966d1be2015-05-15 14:54:09 -07001964 def getOnosIps(self):
cameron@onlab.us59d29d92015-05-11 14:31:54 -07001965
1966 import os
kelvin-onlab0a28a742015-05-18 16:03:13 -07001967
cameron@onlab.us966d1be2015-05-15 14:54:09 -07001968 # reads env for OC variables, also saves file with OC variables. If file and env conflict
1969 # priority goes to env. If file has OCs that are not in the env, the file OCs are used.
1970 # In other words, if the env is set, the test will use those values.
cameron@onlab.us59d29d92015-05-11 14:31:54 -07001971
cameron@onlab.us966d1be2015-05-15 14:54:09 -07001972 # returns a list of ip addresses for the onos nodes, will work with up to 7 nodes + OCN and OCI
1973 # returns in format [ OC1 ip, OC2 ...ect. , OCN, OCI ]
1974
1975 envONOSIps = {}
cameron@onlab.us59d29d92015-05-11 14:31:54 -07001976
1977 x = 1
1978 while True:
1979 try:
1980 temp = os.environ[ 'OC' + str(x) ]
cameron@onlab.us966d1be2015-05-15 14:54:09 -07001981 except KeyError:
cameron@onlab.us59d29d92015-05-11 14:31:54 -07001982 break
cameron@onlab.us966d1be2015-05-15 14:54:09 -07001983 envONOSIps[ ("OC" + str(x)) ] = temp
cameron@onlab.us59d29d92015-05-11 14:31:54 -07001984 x += 1
1985
1986 try:
1987 temp = os.environ[ 'OCN' ]
cameron@onlab.us966d1be2015-05-15 14:54:09 -07001988 envONOSIps[ "OCN" ] = temp
1989 except KeyError:
1990 main.log.info("OCN not set in env")
cameron@onlab.us59d29d92015-05-11 14:31:54 -07001991
cameron@onlab.us59d29d92015-05-11 14:31:54 -07001992 try:
1993 temp = os.environ[ 'OCI' ]
cameron@onlab.us966d1be2015-05-15 14:54:09 -07001994 envONOSIps[ "OCI" ] = temp
cameron@onlab.us59d29d92015-05-11 14:31:54 -07001995 except:
cameron@onlab.us966d1be2015-05-15 14:54:09 -07001996 main.log.error("OCI not set in env")
cameron@onlab.us59d29d92015-05-11 14:31:54 -07001997
cameron@onlab.us966d1be2015-05-15 14:54:09 -07001998 print(str(envONOSIps))
1999
2000 order = [ "OC1", "OC2", "OC3","OC4","OC5","OC6","OC7","OCN","OCI" ]
2001 ONOSIps = []
2002
2003 try:
cameron@onlab.us2e166212015-05-19 14:28:25 -07002004 if os.path.exists("myIps"):
2005 ipFile = open("myIps","r+")
2006 else:
2007 ipFile = open("myIps","w+")
2008
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002009 fileONOSIps = ipFile.readlines()
2010 ipFile.close()
2011
2012 print str(fileONOSIps)
2013
2014 if str(fileONOSIps) == "[]":
2015 ipFile = open("myIps","w+")
2016 for key in envONOSIps:
2017 ipFile.write(key+ "=" + envONOSIps[key] + "\n")
2018 ipFile.close()
2019 for i in order:
2020 if i in envONOSIps:
2021 ONOSIps.append(envONOSIps[i])
2022
2023 return ONOSIps
2024
2025 else:
2026 fileDict = {}
2027 for line in fileONOSIps:
2028 line = line.replace("\n","")
2029 line = line.split("=")
2030 key = line[0]
2031 value = line[1]
2032 fileDict[key] = value
2033
2034 for x in envONOSIps:
2035 if x in fileDict:
2036 if envONOSIps[x] == fileDict[x]:
2037 continue
2038 else:
2039 fileDict[x] = envONOSIps[x]
2040 else:
2041 fileDict[x] = envONOSIps[x]
2042
2043 ipFile = open("myIps","w+")
2044 for key in order:
2045 if key in fileDict:
2046 ipFile.write(key + "=" + fileDict[key] + "\n")
2047 ONOSIps.append(fileDict[key])
2048 ipFile.close()
2049
2050 return ONOSIps
2051
2052 except IOError as a:
2053 main.log.error(a)
2054
kelvin-onlab0a28a742015-05-18 16:03:13 -07002055 except Exception as a:
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002056 main.log.error(a)
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002057
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002058
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002059 def logReport(self, nodeIp, searchTerms, outputMode="s"):
2060 '''
2061 - accepts either a list or a string for "searchTerms" these
2062 terms will be searched for in the log and have their
2063 instances counted
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002064
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002065 - nodeIp is the ip of the node whos log is to be scanned
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002066
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002067 - output modes:
2068 "s" - Simple. Quiet output mode that just prints
cameron@onlab.us2e166212015-05-19 14:28:25 -07002069 the occurences of each search term
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002070
cameron@onlab.us2e166212015-05-19 14:28:25 -07002071 "d" - Detailed. Prints number of occurences as well as the entire
2072 line for each of the last 5 occurences
2073
2074 - returns total of the number of instances of all search terms
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002075 '''
2076 main.log.info("========================== Log Report ===========================\n")
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002077
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002078 if type(searchTerms) is str:
2079 searchTerms = [searchTerms]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002080
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002081 logLines = [ [" "] for i in range(len(searchTerms)) ]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002082
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002083 for term in range(len(searchTerms)):
2084 logLines[term][0] = searchTerms[term]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002085
cameron@onlab.us2e166212015-05-19 14:28:25 -07002086 totalHits = 0
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002087 for term in range(len(searchTerms)):
2088 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep " + searchTerms[term]
2089 self.handle.sendline(cmd)
2090 self.handle.expect(":~")
2091 before = (self.handle.before).splitlines()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002092
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002093 count = [searchTerms[term],0]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002094
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002095 for line in before:
2096 if searchTerms[term] in line and "grep" not in line:
2097 count[1] += 1
2098 if before.index(line) > ( len(before) - 7 ):
2099 logLines[term].append(line)
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002100
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002101 main.log.info( str(count[0]) + ": " + str(count[1]) )
2102 if term == len(searchTerms)-1:
2103 print("\n")
cameron@onlab.us2e166212015-05-19 14:28:25 -07002104 totalHits += int(count[1])
2105
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002106 if outputMode != "s" and outputMode != "S":
2107 outputString = ""
2108 for i in logLines:
2109 outputString = i[0] + ": \n"
2110 for x in range(1,len(i)):
2111 outputString += ( i[x] + "\n" )
2112
2113 if outputString != (i[0] + ": \n"):
2114 main.log.info(outputString)
2115
2116 main.log.info("================================================================\n")
cameron@onlab.us2e166212015-05-19 14:28:25 -07002117 return totalHits
pingping-lin763ee042015-05-20 17:45:30 -07002118
2119 def getOnosIpFromEnv(self):
2120
2121 import string
2122
2123 # returns a list of ip addresses for the onos nodes, will work with up to 7 nodes + OCN and OCI
2124 # returns in format [ 'x', OC1 ip, OC2 i... ect. ... , ONN ip ]
2125
2126 self.handle.sendline("env| grep OC")
2127 self.handle.expect(":~")
2128 rawOutput = self.handle.before
2129 print rawOutput
2130 print "-----------------------------"
2131 print repr(rawOutput)
2132 mpa = dict.fromkeys(range(32))
2133 translated = rawOutput.translate(mpa)
2134 print translated
2135
2136
2137 # create list with only the lines that have the needed IPs
2138 unparsedIps = []
2139
2140 # remove preceeding or trailing lines
2141 for line in rawOutput:
2142 if "OC" in line and "=" in line:
2143 unparsedIps.append(str(line))
2144
2145 # determine cluster size
2146 clusterCount = 0
2147 for line in unparsedIps:
2148 line = str(line)
2149 print line
2150 temp = line.replace("OC","")
2151 print("line index " + str(line.index("=")))
2152 OCindex = temp[0]
2153 for i in range(0, 7):
2154 if OCindex == str(i) and i > clusterCount:
2155 clusterCount == i
2156 print(clusterCount)
2157 # create list to hold ips such that OC1 is at list[1] and OCN and OCI are at the end (in that order)
2158 ONOSIps = ["x"] * (clusterCount + 3)
2159
2160 # populate list
2161 for line in unparsedIps:
2162 main.log.info(line)##########
2163 temp = str(line.replace("OC",""))
2164 main.log.info(str(list(temp)))
2165 OCindex = temp[0]
2166 main.log.info(OCindex)############
2167 if OCindex == "N":
2168 ONOSIps[ clusterCount + 1 ] = temp.replace("N=","")
2169
2170 if OCindex == "I":
2171 ONOSIps[ clusterCount + 2 ] = temp.replace("I=","")
2172
2173 else:
2174 ONOSIps[ int(OCindex) ] = temp.replace((OCindex + "=") ,"")
2175
2176 # validate
2177 for x in ONOSIps:
2178 if ONOSIps.index(x) != 0 and x == "x":
2179 main.log.error("ENV READ FAILURE, MISSING DATA: \n\n" + str(ONOSIps) + "\n\n")
2180
2181 return ONOSIps
2182
kelvin-onlab0a28a742015-05-18 16:03:13 -07002183
pingping-lin763ee042015-05-20 17:45:30 -07002184 def onosErrorLog(self, nodeIp):
2185
2186 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep WARN"
2187 self.handle.sendline(cmd)
2188 self.handle.expect(":~")
2189 before = (self.handle.before).splitlines()
kelvin-onlab0a28a742015-05-18 16:03:13 -07002190
pingping-lin763ee042015-05-20 17:45:30 -07002191 warnings = []
2192
2193 for line in before:
2194 if "WARN" in line and "grep" not in line:
2195 warnings.append(line)
2196 main.warnings[main.warnings[0]+1] = line
2197 main.warnings[0] += 1
2198 if main.warnings[0] >= 10:
2199 main.warnings[0] = 0
2200
2201 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep ERROR"
2202 self.handle.sendline(cmd)
2203 self.handle.expect(":~")
2204 before = (self.handle.before).splitlines()
2205
2206 errors = []
2207
2208 for line in before:
2209 if "ERROR" in line and "grep" not in line:
2210 errors.append(line)
2211 main.errors[main.errors[0]+1] = line
2212 main.errors[0] += 1
2213 if main.errors[0] >= 10:
2214 main.errors[0] = 0
2215
2216 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep Exept"
2217 self.handle.sendline(cmd)
2218 self.handle.expect(":~")
2219 before = (self.handle.before).splitlines()
2220
2221 exceptions = []
2222
2223 for line in before:
2224 if "Except" in line and "grep" not in line:
2225 exceptions.append(line)
2226 main.exceptions[main.errors[0]+1] = line
2227 main.exceptions[0] += 1
2228 if main.exceptions[0] >= 10:
2229 main.exceptions[0] = 0
2230
2231
2232
2233 ################################################################
2234
2235 msg1 = "WARNINGS: \n"
2236 for i in main.warnings:
2237 if type(i) is not int:
2238 msg1 += ( i + "\n")
2239
2240 msg2 = "ERRORS: \n"
2241 for i in main.errors:
2242 if type(i) is not int:
2243 msg2 += ( i + "\n")
2244
2245 msg3 = "EXCEPTIONS: \n"
2246 for i in main.exceptions:
2247 if type(i) is not int:
2248 msg3 += ( i + "\n")
2249
2250 main.log.info("===============================================================\n")
2251 main.log.info( "Warnings: " + str(len(warnings)))
2252 main.log.info( "Errors: " + str(len(errors)))
2253 main.log.info( "Exceptions: " + str(len(exceptions)))
2254 if len(warnings) > 0:
2255 main.log.info(msg1)
2256 if len(errors) > 0:
2257 main.log.info(msg2)
2258 if len(exceptions) > 0:
2259 main.log.info(msg3)
2260 main.log.info("===============================================================\n")
Hari Krishnaade11a72015-07-01 17:06:46 -07002261
2262 def getOnosIPfromCell(self):
2263 '''
2264 Returns the ONOS node names and their IP addresses as defined in the cell and applied to shell environment
2265 Example output return: [['OC1', '10.128.40.41'], ['OC2', '10.128.40.42'], ['OC3', '10.128.40.43']]
2266 '''
2267 import re
2268 try:
2269 # Clean handle by sending empty and expecting $
2270 self.handle.sendline( "" )
2271 self.handle.expect( "\$" )
2272 self.handle.sendline( "cell" )
2273 self.handle.expect( "\$" )
2274 handleBefore = self.handle.before
2275 handleAfter = self.handle.after
2276 # Get the rest of the handle
2277 self.handle.sendline( "" )
2278 self.handle.expect( "\$" )
2279 handleMore = self.handle.before
2280 ipList = []
2281 cellOutput = handleBefore + handleAfter + handleMore
2282 cellOutput = cellOutput.replace("\r\r","")
2283 cellOutput = cellOutput.splitlines()
2284 for i in range( len(cellOutput) ):
2285 if( re.match( "OC", cellOutput[i] ) ):
2286 if( re.match( "OCI", cellOutput[i] ) or re.match( "OCN", cellOutput[i] ) ):
2287 continue
2288 else:
2289 onosIP = cellOutput[i].split("=")
2290 # below step could me changed to return only IP if node name is not needed.
2291 ipList.append(onosIP)
2292 return ipList
2293 except pexpect.ExceptionPexpect as e:
2294 main.log.error( self.name + ": Pexpect exception found of type " +
2295 str( type( e ) ) )
2296 main.log.error ( e.get_trace() )
2297 main.log.error( self.name + ": " + self.handle.before )
2298 main.cleanup()
2299 main.exit()
2300 except Exception:
2301 main.log.exception( self.name + ": Uncaught exception!" )
2302 main.cleanup()
2303 main.exit()