blob: 7520f466be3a1d9d8e238b4622cff709b77a2d16 [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
Jon Hall6801cda2015-07-15 14:13:45 -070021import types
Jon Hall05b2b432014-10-08 19:53:25 -040022import pexpect
kelvin-onlaba4074292015-07-09 15:19:49 -070023import os
andrewonlab7735d852014-10-09 13:02:47 -040024import os.path
pingping-lin6d23d9e2015-02-02 16:54:24 -080025from requests.models import Response
kelvin8ec71442015-01-15 16:57:00 -080026sys.path.append( "../" )
Jon Hall05b2b432014-10-08 19:53:25 -040027from drivers.common.clidriver import CLI
28
Jon Hall05b2b432014-10-08 19:53:25 -040029
kelvin8ec71442015-01-15 16:57:00 -080030class OnosDriver( CLI ):
Jon Hall05b2b432014-10-08 19:53:25 -040031
kelvin8ec71442015-01-15 16:57:00 -080032 def __init__( self ):
33 """
34 Initialize client
35 """
Jon Hallefbd9792015-03-05 16:11:36 -080036 self.name = None
37 self.home = None
38 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080039 super( CLI, self ).__init__()
40
41 def connect( self, **connectargs ):
42 """
Jon Hall05b2b432014-10-08 19:53:25 -040043 Creates ssh handle for ONOS "bench".
kelvin-onlaba4074292015-07-09 15:19:49 -070044 NOTE:
45 The ip_address would come from the topo file using the host tag, the
46 value can be an environment variable as well as a "localhost" to get
47 the ip address needed to ssh to the "bench"
kelvin8ec71442015-01-15 16:57:00 -080048 """
Jon Hall05b2b432014-10-08 19:53:25 -040049 try:
50 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080051 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us3b087132015-03-11 15:00:08 -070052 self.home = "~/onos"
Jon Hall05b2b432014-10-08 19:53:25 -040053 for key in self.options:
54 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080055 self.home = self.options[ 'home' ]
Jon Hall05b2b432014-10-08 19:53:25 -040056 break
Jon Hall274b6642015-02-17 11:57:17 -080057 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070058 self.home = "~/onos"
Jon Hall21270ac2015-02-16 17:59:55 -080059
kelvin8ec71442015-01-15 16:57:00 -080060 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070061
kelvin-onlabc2b79102015-07-14 11:41:20 -070062 # The 'nodes' tag is optional and it is not required in .topo file
kelvin-onlaba4074292015-07-09 15:19:49 -070063 for key in self.options:
64 if key == "nodes":
kelvin-onlabc2b79102015-07-14 11:41:20 -070065 # Maximum number of ONOS nodes to run, if there is any
kelvin-onlaba4074292015-07-09 15:19:49 -070066 self.maxNodes = int( self.options[ 'nodes' ] )
67 break
68 self.maxNodes = None
69
kelvin-onlabc2b79102015-07-14 11:41:20 -070070 if self.maxNodes == None or self.maxNodes == "":
71 self.maxNodes = 100
kelvin-onlaba4074292015-07-09 15:19:49 -070072
kelvin-onlabc2b79102015-07-14 11:41:20 -070073
74 # Grabs all OC environment variables based on max number of nodes
kelvin-onlaba4074292015-07-09 15:19:49 -070075 self.onosIps = {} # Dictionary of all possible ONOS ip
76
77 try:
78 if self.maxNodes:
kelvin-onlaba4074292015-07-09 15:19:49 -070079 for i in range( self.maxNodes ):
80 envString = "OC" + str( i + 1 )
kelvin-onlabc2b79102015-07-14 11:41:20 -070081 # If there is no more OC# then break the loop
82 if os.getenv( envString ):
83 self.onosIps[ envString ] = os.getenv( envString )
84 else:
85 self.maxNodes = len( self.onosIps )
86 main.log.info( self.name +
87 ": Created cluster data with " +
88 str( self.maxNodes ) +
89 " maximum number" +
90 " of nodes" )
91 break
kelvin-onlaba4074292015-07-09 15:19:49 -070092
93 if not self.onosIps:
94 main.log.info( "Could not read any environment variable"
95 + " please load a cell file with all" +
96 " onos IP" )
Jon Hall5cf14d52015-07-16 12:15:19 -070097 self.maxNodes = None
kelvin-onlaba4074292015-07-09 15:19:49 -070098 else:
99 main.log.info( self.name + ": Found " +
100 str( self.onosIps.values() ) +
101 " ONOS IPs" )
kelvin-onlaba4074292015-07-09 15:19:49 -0700102 except KeyError:
103 main.log.info( "Invalid environment variable" )
104 except Exception as inst:
105 main.log.error( "Uncaught exception: " + str( inst ) )
106
107 try:
108 if os.getenv( str( self.ip_address ) ) != None:
109 self.ip_address = os.getenv( str( self.ip_address ) )
110 else:
111 main.log.info( self.name +
112 ": Trying to connect to " +
113 self.ip_address )
kelvin-onlaba4074292015-07-09 15:19:49 -0700114 except KeyError:
115 main.log.info( "Invalid host name," +
116 " connecting to local host instead" )
117 self.ip_address = 'localhost'
118 except Exception as inst:
119 main.log.error( "Uncaught exception: " + str( inst ) )
120
kelvin8ec71442015-01-15 16:57:00 -0800121 self.handle = super( OnosDriver, self ).connect(
122 user_name=self.user_name,
kelvin-onlab08679eb2015-01-21 16:11:48 -0800123 ip_address=self.ip_address,
kelvin-onlabd3b64892015-01-20 13:26:24 -0800124 port=self.port,
125 pwd=self.pwd,
126 home=self.home )
Jon Hall05b2b432014-10-08 19:53:25 -0400127
Jon Hall05b2b432014-10-08 19:53:25 -0400128 if self.handle:
Jon Hall0fc0d452015-07-14 09:49:58 -0700129 self.handle.sendline( "cd " + self.home )
130 self.handle.expect( "\$" )
Jon Hall05b2b432014-10-08 19:53:25 -0400131 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800132 else:
Jon Hall0fc0d452015-07-14 09:49:58 -0700133 main.log.info( "Failed to create ONOS handle" )
Jon Hall05b2b432014-10-08 19:53:25 -0400134 return main.FALSE
135 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800136 main.log.error( self.name + ": EOF exception found" )
137 main.log.error( self.name + ": " + self.handle.before )
Jon Hall05b2b432014-10-08 19:53:25 -0400138 main.cleanup()
139 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800140 except Exception:
141 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall05b2b432014-10-08 19:53:25 -0400142 main.cleanup()
143 main.exit()
144
kelvin8ec71442015-01-15 16:57:00 -0800145 def disconnect( self ):
146 """
Jon Hall05b2b432014-10-08 19:53:25 -0400147 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800148 """
Jon Halld61331b2015-02-17 16:35:47 -0800149 response = main.TRUE
Jon Hall05b2b432014-10-08 19:53:25 -0400150 try:
Jon Hall61282e32015-03-19 11:34:11 -0700151 if self.handle:
152 self.handle.sendline( "" )
153 self.handle.expect( "\$" )
154 self.handle.sendline( "exit" )
155 self.handle.expect( "closed" )
Jon Hall05b2b432014-10-08 19:53:25 -0400156 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800157 main.log.error( self.name + ": EOF exception found" )
158 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700159 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700160 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700161 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800162 except Exception:
163 main.log.exception( self.name + ": Connection failed to the host" )
Jon Hall05b2b432014-10-08 19:53:25 -0400164 response = main.FALSE
165 return response
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400166
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400167 def getEpochMs( self ):
168 """
169 Returns milliseconds since epoch
170
171 When checking multiple nodes in a for loop,
172 around a hundred milliseconds of difference (ascending) is
173 generally acceptable due to calltime of the function.
174 Few seconds, however, is not and it means clocks
175 are off sync.
176 """
177 try:
178 self.handle.sendline( 'date +%s.%N' )
179 self.handle.expect( 'date \+\%s\.\%N' )
180 self.handle.expect( '\$' )
181 epochMs = self.handle.before
182 return epochMs
183 except Exception:
184 main.log.exception( 'Uncaught exception getting epoch time' )
185 main.cleanup()
186 main.exit()
187
pingping-lin57a56ce2015-05-20 16:43:48 -0700188 def onosPackage( self, opTimeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800189 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400190 Produce a self-contained tar.gz file that can be deployed
kelvin8ec71442015-01-15 16:57:00 -0800191 and executed on any platform with Java 7 JRE.
192 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400193 try:
kelvin8ec71442015-01-15 16:57:00 -0800194 self.handle.sendline( "onos-package" )
195 self.handle.expect( "onos-package" )
pingping-lin57a56ce2015-05-20 16:43:48 -0700196 self.handle.expect( "tar.gz", opTimeout )
kelvin8ec71442015-01-15 16:57:00 -0800197 handle = str( self.handle.before )
198 main.log.info( "onos-package command returned: " +
199 handle )
200 # As long as the sendline does not time out,
201 # return true. However, be careful to interpret
202 # the results of the onos-package command return
andrewonlab0748d2a2014-10-09 13:24:17 -0400203 return main.TRUE
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400204
andrewonlab7735d852014-10-09 13:02:47 -0400205 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800206 main.log.error( self.name + ": EOF exception found" )
207 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800208 except Exception:
209 main.log.exception( "Failed to package ONOS" )
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400210 main.cleanup()
211 main.exit()
212
kelvin-onlabd3b64892015-01-20 13:26:24 -0800213 def onosBuild( self ):
kelvin8ec71442015-01-15 16:57:00 -0800214 """
andrewonlab8790abb2014-11-06 13:51:54 -0500215 Use the pre defined script to build onos via mvn
kelvin8ec71442015-01-15 16:57:00 -0800216 """
andrewonlab8790abb2014-11-06 13:51:54 -0500217 try:
kelvin8ec71442015-01-15 16:57:00 -0800218 self.handle.sendline( "onos-build" )
219 self.handle.expect( "onos-build" )
220 i = self.handle.expect( [
kelvin-onlabd3b64892015-01-20 13:26:24 -0800221 "BUILD SUCCESS",
222 "ERROR",
223 "BUILD FAILED" ],
224 timeout=120 )
kelvin8ec71442015-01-15 16:57:00 -0800225 handle = str( self.handle.before )
andrewonlab8790abb2014-11-06 13:51:54 -0500226
kelvin8ec71442015-01-15 16:57:00 -0800227 main.log.info( "onos-build command returned: " +
228 handle )
andrewonlab8790abb2014-11-06 13:51:54 -0500229
230 if i == 0:
231 return main.TRUE
232 else:
233 return handle
234
235 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800236 main.log.error( self.name + ": EOF exception found" )
237 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800238 except Exception:
239 main.log.exception( "Failed to build ONOS" )
andrewonlab8790abb2014-11-06 13:51:54 -0500240 main.cleanup()
241 main.exit()
242
shahshreya9f531fe2015-06-10 12:03:51 -0700243 def cleanInstall( self, skipTest=False, mciTimeout=600 ):
kelvin8ec71442015-01-15 16:57:00 -0800244 """
245 Runs mvn clean install in the root of the ONOS directory.
246 This will clean all ONOS artifacts then compile each module
shahshreya9f531fe2015-06-10 12:03:51 -0700247 Optional:
248 skipTest - Does "-DskipTests -Dcheckstyle.skip -U -T 1C" which
249 skip the test. This will make the building faster.
250 Disregarding the credibility of the build
kelvin8ec71442015-01-15 16:57:00 -0800251 Returns: main.TRUE on success
Jon Hallde9d9aa2014-10-08 20:36:02 -0400252 On Failure, exits the test
kelvin8ec71442015-01-15 16:57:00 -0800253 """
Jon Hallde9d9aa2014-10-08 20:36:02 -0400254 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800255 main.log.info( "Running 'mvn clean install' on " +
256 str( self.name ) +
kelvin8ec71442015-01-15 16:57:00 -0800257 ". This may take some time." )
258 self.handle.sendline( "cd " + self.home )
259 self.handle.expect( "\$" )
Jon Hallea7818b2014-10-09 14:30:59 -0400260
kelvin8ec71442015-01-15 16:57:00 -0800261 self.handle.sendline( "" )
262 self.handle.expect( "\$" )
shahshreya9f531fe2015-06-10 12:03:51 -0700263
264 if not skipTest:
265 self.handle.sendline( "mvn clean install" )
266 self.handle.expect( "mvn clean install" )
267 else:
268 self.handle.sendline( "mvn clean install -DskipTests" +
269 " -Dcheckstyle.skip -U -T 1C" )
270 self.handle.expect( "mvn clean install -DskipTests" +
271 " -Dcheckstyle.skip -U -T 1C" )
kelvin8ec71442015-01-15 16:57:00 -0800272 while True:
273 i = self.handle.expect( [
Jon Hall274b6642015-02-17 11:57:17 -0800274 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
Jon Hallefbd9792015-03-05 16:11:36 -0800275 'Runtime\sEnvironment\sto\scontinue',
Jon Hallde9d9aa2014-10-08 20:36:02 -0400276 'BUILD\sFAILURE',
277 'BUILD\sSUCCESS',
Jon Halle94919c2015-03-23 11:42:57 -0700278 'onos\$', #TODO: fix this to be more generic?
Jon Hallde9d9aa2014-10-08 20:36:02 -0400279 'ONOS\$',
pingping-lin57a56ce2015-05-20 16:43:48 -0700280 pexpect.TIMEOUT ], mciTimeout )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400281 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800282 main.log.error( self.name + ":There is insufficient memory \
283 for the Java Runtime Environment to continue." )
284 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400285 main.cleanup()
286 main.exit()
287 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800288 main.log.error( self.name + ": Build failure!" )
289 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400290 main.cleanup()
291 main.exit()
292 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800293 main.log.info( self.name + ": Build success!" )
Jon Halle94919c2015-03-23 11:42:57 -0700294 elif i == 3 or i == 4:
kelvin8ec71442015-01-15 16:57:00 -0800295 main.log.info( self.name + ": Build complete" )
296 # Print the build time
Jon Hallf8ef52c2014-10-09 19:37:33 -0400297 for line in self.handle.before.splitlines():
298 if "Total time:" in line:
kelvin8ec71442015-01-15 16:57:00 -0800299 main.log.info( line )
300 self.handle.sendline( "" )
301 self.handle.expect( "\$", timeout=60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400302 return main.TRUE
Jon Halle94919c2015-03-23 11:42:57 -0700303 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800304 main.log.error(
305 self.name +
306 ": mvn clean install TIMEOUT!" )
307 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400308 main.cleanup()
309 main.exit()
310 else:
Jon Hall274b6642015-02-17 11:57:17 -0800311 main.log.error( self.name + ": unexpected response from " +
Jon Hallefbd9792015-03-05 16:11:36 -0800312 "mvn clean install" )
kelvin8ec71442015-01-15 16:57:00 -0800313 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400314 main.cleanup()
315 main.exit()
316 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800317 main.log.error( self.name + ": EOF exception found" )
318 main.log.error( self.name + ": " + self.handle.before )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400319 main.cleanup()
320 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800321 except Exception:
322 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400323 main.cleanup()
324 main.exit()
Jon Hallacabffd2014-10-09 12:36:53 -0400325
Jon Hall61282e32015-03-19 11:34:11 -0700326 def gitPull( self, comp1="", fastForward=True ):
kelvin8ec71442015-01-15 16:57:00 -0800327 """
Jon Hallacabffd2014-10-09 12:36:53 -0400328 Assumes that "git pull" works without login
Jon Hall47a93fb2015-01-06 16:46:06 -0800329
Jon Hall61282e32015-03-19 11:34:11 -0700330 If the fastForward boolean is set to true, only git pulls that can
331 be fast forwarded will be performed. IE if you have not local commits
332 in your branch.
333
Jon Hallacabffd2014-10-09 12:36:53 -0400334 This function will perform a git pull on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800335 If used as gitPull( "NODE" ) it will do git pull + NODE. This is
Jon Hallacabffd2014-10-09 12:36:53 -0400336 for the purpose of pulling from other nodes if necessary.
337
Jon Hall47a93fb2015-01-06 16:46:06 -0800338 Otherwise, this function will perform a git pull in the
Jon Hallacabffd2014-10-09 12:36:53 -0400339 ONOS repository. If it has any problems, it will return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -0800340 If it successfully does a gitPull, it will return a 1 ( main.TRUE )
Shreya Shahee15f6c2014-10-28 18:12:30 -0400341 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400342
kelvin8ec71442015-01-15 16:57:00 -0800343 """
Jon Hallacabffd2014-10-09 12:36:53 -0400344 try:
kelvin8ec71442015-01-15 16:57:00 -0800345 # main.log.info( self.name + ": Stopping ONOS" )
346 # self.stop()
347 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800348 self.handle.expect( self.home + "\$" )
Jon Hall61282e32015-03-19 11:34:11 -0700349 cmd = "git pull"
350 if comp1 != "":
351 cmd += ' ' + comp1
352 if fastForward:
353 cmd += ' ' + " --ff-only"
354 self.handle.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800355 i = self.handle.expect(
356 [
357 'fatal',
358 'Username\sfor\s(.*):\s',
359 '\sfile(s*) changed,\s',
360 'Already up-to-date',
361 'Aborting',
362 'You\sare\snot\scurrently\son\sa\sbranch',
Jon Hall274b6642015-02-17 11:57:17 -0800363 'You asked me to pull without telling me which branch you',
364 'Pull is not possible because you have unmerged files',
Jon Hall61282e32015-03-19 11:34:11 -0700365 'Please enter a commit message to explain why this merge',
366 'Found a swap file by the name',
367 'Please, commit your changes before you can merge.',
kelvin-onlabd3b64892015-01-20 13:26:24 -0800368 pexpect.TIMEOUT ],
369 timeout=300 )
kelvin8ec71442015-01-15 16:57:00 -0800370 # debug
kelvin-onlabd3b64892015-01-20 13:26:24 -0800371 # main.log.report( self.name +": DEBUG: \n"+
372 # "git pull response: " +
373 # str( self.handle.before ) + str( self.handle.after ) )
kelvin8ec71442015-01-15 16:57:00 -0800374 if i == 0:
Jon Hall61282e32015-03-19 11:34:11 -0700375 main.log.error( self.name + ": Git pull had some issue" )
376 output = self.handle.after
377 self.handle.expect( '\$' )
378 output += self.handle.before
379 main.log.warn( output )
Jon Hallacabffd2014-10-09 12:36:53 -0400380 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800381 elif i == 1:
382 main.log.error(
383 self.name +
384 ": Git Pull Asking for username. " )
Jon Hallacabffd2014-10-09 12:36:53 -0400385 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800386 elif i == 2:
387 main.log.info(
388 self.name +
389 ": Git Pull - pulling repository now" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800390 self.handle.expect( self.home + "\$", 120 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800391 # So that only when git pull is done, we do mvn clean compile
392 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800393 elif i == 3:
394 main.log.info( self.name + ": Git Pull - Already up to date" )
Jon Hall47a93fb2015-01-06 16:46:06 -0800395 return i
kelvin8ec71442015-01-15 16:57:00 -0800396 elif i == 4:
397 main.log.info(
398 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800399 ": Git Pull - Aborting..." +
400 "Are there conflicting git files?" )
Jon Hallacabffd2014-10-09 12:36:53 -0400401 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800402 elif i == 5:
403 main.log.info(
404 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800405 ": Git Pull - You are not currently " +
406 "on a branch so git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400407 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800408 elif i == 6:
409 main.log.info(
410 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800411 ": Git Pull - You have not configured an upstream " +
412 "branch to pull from. Git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400413 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800414 elif i == 7:
415 main.log.info(
416 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800417 ": Git Pull - Pull is not possible because " +
418 "you have unmerged files." )
Jon Hallacabffd2014-10-09 12:36:53 -0400419 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800420 elif i == 8:
Jon Hall61282e32015-03-19 11:34:11 -0700421 # NOTE: abandoning test since we can't reliably handle this
422 # there could be different default text editors and we
423 # also don't know if we actually want to make the commit
424 main.log.error( "Git pull resulted in a merge commit message" +
425 ". Exiting test!" )
426 main.cleanup()
427 main.exit()
428 elif i == 9: # Merge commit message but swap file exists
429 main.log.error( "Git pull resulted in a merge commit message" +
430 " but a swap file exists." )
431 try:
432 self.handle.send( 'A' ) # Abort
433 self.handle.expect( "\$" )
434 return main.ERROR
435 except Exception:
436 main.log.exception( "Couldn't exit editor prompt!")
437 main.cleanup()
438 main.exit()
439 elif i == 10: # In the middle of a merge commit
440 main.log.error( "Git branch is in the middle of a merge. " )
441 main.log.warn( self.handle.before + self.handle.after )
442 return main.ERROR
443 elif i == 11:
kelvin8ec71442015-01-15 16:57:00 -0800444 main.log.error( self.name + ": Git Pull - TIMEOUT" )
445 main.log.error(
446 self.name + " Response was: " + str(
447 self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400448 return main.ERROR
449 else:
kelvin8ec71442015-01-15 16:57:00 -0800450 main.log.error(
451 self.name +
452 ": Git Pull - Unexpected response, check for pull errors" )
Jon Hallacabffd2014-10-09 12:36:53 -0400453 return main.ERROR
454 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800455 main.log.error( self.name + ": EOF exception found" )
456 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400457 main.cleanup()
458 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800459 except Exception:
460 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400461 main.cleanup()
462 main.exit()
463
kelvin-onlabd3b64892015-01-20 13:26:24 -0800464 def gitCheckout( self, branch="master" ):
kelvin8ec71442015-01-15 16:57:00 -0800465 """
Jon Hallacabffd2014-10-09 12:36:53 -0400466 Assumes that "git pull" works without login
kelvin8ec71442015-01-15 16:57:00 -0800467
Jon Hallacabffd2014-10-09 12:36:53 -0400468 This function will perform a git git checkout on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800469 If used as gitCheckout( "branch" ) it will do git checkout
470 of the "branch".
Jon Hallacabffd2014-10-09 12:36:53 -0400471
472 Otherwise, this function will perform a git checkout of the master
kelvin8ec71442015-01-15 16:57:00 -0800473 branch of the ONOS repository. If it has any problems, it will return
474 main.ERROR.
475 If the branch was already the specified branch, or the git checkout was
Jon Hallacabffd2014-10-09 12:36:53 -0400476 successful then the function will return main.TRUE.
477
kelvin8ec71442015-01-15 16:57:00 -0800478 """
Jon Hallacabffd2014-10-09 12:36:53 -0400479 try:
kelvin8ec71442015-01-15 16:57:00 -0800480 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800481 self.handle.expect( self.home + "\$" )
Jon Hall274b6642015-02-17 11:57:17 -0800482 main.log.info( self.name +
483 ": Checking out git branch/ref: " + branch + "..." )
kelvin8ec71442015-01-15 16:57:00 -0800484 cmd = "git checkout " + branch
485 self.handle.sendline( cmd )
486 self.handle.expect( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800487 i = self.handle.expect(
Jon Hall274b6642015-02-17 11:57:17 -0800488 [ 'fatal',
Jon Hall61282e32015-03-19 11:34:11 -0700489 'Username for (.*): ',
490 'Already on \'',
Jon Hall7a8354f2015-06-10 15:37:00 -0700491 'Switched to (a new )?branch \'' + str( branch ),
Jon Hall274b6642015-02-17 11:57:17 -0800492 pexpect.TIMEOUT,
493 'error: Your local changes to the following files' +
Jon Hallefbd9792015-03-05 16:11:36 -0800494 'would be overwritten by checkout:',
Jon Hall274b6642015-02-17 11:57:17 -0800495 'error: you need to resolve your current index first',
496 "You are in 'detached HEAD' state.",
497 "HEAD is now at " ],
kelvin-onlabd3b64892015-01-20 13:26:24 -0800498 timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -0800499 if i == 0:
500 main.log.error(
501 self.name +
502 ": Git checkout had some issue..." )
503 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400504 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800505 elif i == 1:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800506 main.log.error(
507 self.name +
508 ": Git checkout asking for username." +
509 " Please configure your local git repository to be able " +
510 "to access your remote repository passwordlessly" )
Jon Hall274b6642015-02-17 11:57:17 -0800511 # TODO add support for authenticating
Jon Hallacabffd2014-10-09 12:36:53 -0400512 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800513 elif i == 2:
514 main.log.info(
515 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800516 ": Git Checkout %s : Already on this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800517 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800518 # main.log.info( "DEBUG: after checkout cmd = "+
519 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400520 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800521 elif i == 3:
522 main.log.info(
523 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800524 ": Git checkout %s - Switched to this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800525 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800526 # main.log.info( "DEBUG: after checkout cmd = "+
527 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400528 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800529 elif i == 4:
530 main.log.error( self.name + ": Git Checkout- TIMEOUT" )
531 main.log.error(
Jon Hall274b6642015-02-17 11:57:17 -0800532 self.name + " Response was: " + str( self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400533 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800534 elif i == 5:
535 self.handle.expect( "Aborting" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800536 main.log.error(
537 self.name +
538 ": Git checkout error: \n" +
Jon Hall274b6642015-02-17 11:57:17 -0800539 "Your local changes to the following files would" +
540 " be overwritten by checkout:" +
541 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800542 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500543 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800544 elif i == 6:
Jon Hall274b6642015-02-17 11:57:17 -0800545 main.log.error(
546 self.name +
547 ": Git checkout error: \n" +
548 "You need to resolve your current index first:" +
549 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800550 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500551 return main.ERROR
Jon Hall274b6642015-02-17 11:57:17 -0800552 elif i == 7:
553 main.log.info(
554 self.name +
555 ": Git checkout " + str( branch ) +
556 " - You are in 'detached HEAD' state. HEAD is now at " +
557 str( branch ) )
558 self.handle.expect( self.home + "\$" )
559 return main.TRUE
560 elif i == 8: # Already in detached HEAD on the specified commit
561 main.log.info(
562 self.name +
563 ": Git Checkout %s : Already on commit" % branch )
564 self.handle.expect( self.home + "\$" )
565 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400566 else:
kelvin8ec71442015-01-15 16:57:00 -0800567 main.log.error(
568 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800569 ": Git Checkout - Unexpected response, " +
570 "check for pull errors" )
kelvin8ec71442015-01-15 16:57:00 -0800571 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400572 return main.ERROR
573
574 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 Hallacabffd2014-10-09 12:36:53 -0400577 main.cleanup()
578 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800579 except Exception:
580 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400581 main.cleanup()
582 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400583
pingping-lin6d23d9e2015-02-02 16:54:24 -0800584 def getBranchName( self ):
pingping-linf30cf272015-05-29 15:54:07 -0700585 main.log.info( "self.home = " )
586 main.log.info( self.home )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800587 self.handle.sendline( "cd " + self.home )
pingping-lin9bf3d8f2015-05-29 16:05:28 -0700588 self.handle.expect( self.home + "\$" )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800589 self.handle.sendline( "git name-rev --name-only HEAD" )
590 self.handle.expect( "git name-rev --name-only HEAD" )
591 self.handle.expect( "\$" )
592
593 lines = self.handle.before.splitlines()
594 if lines[1] == "master":
595 return "master"
596 elif lines[1] == "onos-1.0":
597 return "onos-1.0"
598 else:
599 main.log.info( lines[1] )
600 return "unexpected ONOS branch for SDN-IP test"
601
kelvin-onlabd3b64892015-01-20 13:26:24 -0800602 def getVersion( self, report=False ):
kelvin8ec71442015-01-15 16:57:00 -0800603 """
Jon Hall274b6642015-02-17 11:57:17 -0800604 Writes the COMMIT number to the report to be parsed
Jon Hallefbd9792015-03-05 16:11:36 -0800605 by Jenkins data collector.
kelvin8ec71442015-01-15 16:57:00 -0800606 """
Jon Hall45ec0922014-10-10 19:33:49 -0400607 try:
kelvin8ec71442015-01-15 16:57:00 -0800608 self.handle.sendline( "" )
609 self.handle.expect( "\$" )
610 self.handle.sendline(
611 "cd " +
612 self.home +
Jon Hall274b6642015-02-17 11:57:17 -0800613 "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " +
614 " \"commit\" --color=never" )
kelvin8ec71442015-01-15 16:57:00 -0800615 # NOTE: for some reason there are backspaces inserted in this
616 # phrase when run from Jenkins on some tests
617 self.handle.expect( "never" )
618 self.handle.expect( "\$" )
619 response = ( self.name + ": \n" + str(
620 self.handle.before + self.handle.after ) )
621 self.handle.sendline( "cd " + self.home )
622 self.handle.expect( "\$" )
623 lines = response.splitlines()
Jon Hall45ec0922014-10-10 19:33:49 -0400624 for line in lines:
Jon Hallfd191202014-11-07 18:36:09 -0500625 print line
626 if report:
pingping-lin763ee042015-05-20 17:45:30 -0700627 main.log.wiki( "<blockquote>" )
kelvin8ec71442015-01-15 16:57:00 -0800628 for line in lines[ 2:-1 ]:
629 # Bracket replacement is for Wiki-compliant
630 # formatting. '<' or '>' are interpreted
631 # as xml specific tags that cause errors
632 line = line.replace( "<", "[" )
633 line = line.replace( ">", "]" )
pingping-lin763ee042015-05-20 17:45:30 -0700634 #main.log.wiki( "\t" + line )
635 main.log.wiki( line + "<br /> " )
636 main.log.summary( line )
637 main.log.wiki( "</blockquote>" )
638 main.log.summary("\n")
kelvin8ec71442015-01-15 16:57:00 -0800639 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400640 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800641 main.log.error( self.name + ": EOF exception found" )
642 main.log.error( self.name + ": " + self.handle.before )
Jon Hall45ec0922014-10-10 19:33:49 -0400643 main.cleanup()
644 main.exit()
Jon Hall368769f2014-11-19 15:43:35 -0800645 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800646 main.log.error( self.name + ": TIMEOUT exception found" )
647 main.log.error( self.name + ": " + self.handle.before )
Jon Hall368769f2014-11-19 15:43:35 -0800648 main.cleanup()
649 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800650 except Exception:
651 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall45ec0922014-10-10 19:33:49 -0400652 main.cleanup()
653 main.exit()
654
kelvin-onlabd3b64892015-01-20 13:26:24 -0800655 def createCellFile( self, benchIp, fileName, mnIpAddrs,
kelvin-onlaba4074292015-07-09 15:19:49 -0700656 appString, onosIpAddrs ):
kelvin8ec71442015-01-15 16:57:00 -0800657 """
andrewonlab94282092014-10-10 13:00:11 -0400658 Creates a cell file based on arguments
659 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800660 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400661 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800662 * File name of the cell file ( fileName )
663 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800664 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400665 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800666 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400667 - Must be passed in as last arguments
kelvin8ec71442015-01-15 16:57:00 -0800668
andrewonlab94282092014-10-10 13:00:11 -0400669 NOTE: Assumes cells are located at:
670 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800671 """
672 # Variable initialization
Jon Hall6801cda2015-07-15 14:13:45 -0700673 cellDirectory = self.home + "/tools/test/cells/"
kelvin8ec71442015-01-15 16:57:00 -0800674 # We want to create the cell file in the dependencies directory
675 # of TestON first, then copy over to ONOS bench
kelvin-onlabd3b64892015-01-20 13:26:24 -0800676 tempDirectory = "/tmp/"
kelvin8ec71442015-01-15 16:57:00 -0800677 # Create the cell file in the directory for writing ( w+ )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800678 cellFile = open( tempDirectory + fileName, 'w+' )
Jon Hall6801cda2015-07-15 14:13:45 -0700679 if isinstance( onosIpAddrs, types.StringType ):
680 onosIpAddrs = [ onosIpAddrs ]
kelvin8ec71442015-01-15 16:57:00 -0800681
cameron@onlab.us75900962015-03-30 13:22:49 -0700682 # App string is hardcoded environment variables
kelvin8ec71442015-01-15 16:57:00 -0800683 # That you may wish to use by default on startup.
cameron@onlab.us75900962015-03-30 13:22:49 -0700684 # Note that you may not want certain apps listed
kelvin8ec71442015-01-15 16:57:00 -0800685 # on here.
cameron@onlab.us75900962015-03-30 13:22:49 -0700686 appString = "export ONOS_APPS=" + appString
kelvin-onlabd3b64892015-01-20 13:26:24 -0800687 mnString = "export OCN="
kelvin-onlabf70fd542015-05-07 18:41:40 -0700688 if mnIpAddrs == "":
689 mnString = ""
kelvin-onlabd3b64892015-01-20 13:26:24 -0800690 onosString = "export OC"
691 tempCount = 1
kelvin8ec71442015-01-15 16:57:00 -0800692
kelvin-onlabd3b64892015-01-20 13:26:24 -0800693 # Create ONOSNIC ip address prefix
kelvin-onlaba4074292015-07-09 15:19:49 -0700694 tempOnosIp = str( onosIpAddrs[ 0 ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800695 tempList = []
696 tempList = tempOnosIp.split( "." )
kelvin8ec71442015-01-15 16:57:00 -0800697 # Omit last element of list to format for NIC
kelvin-onlabd3b64892015-01-20 13:26:24 -0800698 tempList = tempList[ :-1 ]
kelvin8ec71442015-01-15 16:57:00 -0800699 # Structure the nic string ip
kelvin-onlabd3b64892015-01-20 13:26:24 -0800700 nicAddr = ".".join( tempList ) + ".*"
701 onosNicString = "export ONOS_NIC=" + nicAddr
andrewonlab94282092014-10-10 13:00:11 -0400702
703 try:
kelvin8ec71442015-01-15 16:57:00 -0800704 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800705 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400706
kelvin-onlabd3b64892015-01-20 13:26:24 -0800707 for arg in onosIpAddrs:
708 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800709 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400710 # export OC1="10.128.20.11"
711 # export OC2="10.128.20.12"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800712 cellFile.write( onosString + str( tempCount ) +
713 "=" + "\"" + arg + "\"" + "\n" )
714 tempCount = tempCount + 1
kelvin8ec71442015-01-15 16:57:00 -0800715
kelvin-onlabd3b64892015-01-20 13:26:24 -0800716 cellFile.write( mnString + "\"" + mnIpAddrs + "\"" + "\n" )
cameron@onlab.us75900962015-03-30 13:22:49 -0700717 cellFile.write( appString + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800718 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400719
kelvin8ec71442015-01-15 16:57:00 -0800720 # We use os.system to send the command to TestON cluster
721 # to account for the case in which TestON is not located
722 # on the same cluster as the ONOS bench
723 # Note that even if TestON is located on the same cluster
724 # as ONOS bench, you must setup passwordless ssh
725 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabc2b79102015-07-14 11:41:20 -0700726 os.system( "scp " + tempDirectory + fileName + " " +
727 self.user_name + "@" + self.ip_address + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400728
andrewonlab2a6c9342014-10-16 13:40:15 -0400729 return main.TRUE
730
andrewonlab94282092014-10-10 13:00:11 -0400731 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800732 main.log.error( self.name + ": EOF exception found" )
733 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -0400734 main.cleanup()
735 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800736 except Exception:
737 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -0400738 main.cleanup()
739 main.exit()
740
kelvin-onlabd3b64892015-01-20 13:26:24 -0800741 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800742 """
andrewonlab95ca1462014-10-09 14:04:24 -0400743 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800744 """
Hari Krishna03f530e2015-07-10 17:28:27 -0700745 import re
andrewonlab95ca1462014-10-09 14:04:24 -0400746 try:
747 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800748 main.log.error( "Must define cellname" )
andrewonlab95ca1462014-10-09 14:04:24 -0400749 main.cleanup()
750 main.exit()
751 else:
kelvin8ec71442015-01-15 16:57:00 -0800752 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800753 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800754 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400755 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800756 self.handle.expect(str(cellname))
kelvin-onlabd3b64892015-01-20 13:26:24 -0800757 handleBefore = self.handle.before
758 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800759 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800760 self.handle.sendline("")
761 self.handle.expect("\$")
kelvin-onlabd3b64892015-01-20 13:26:24 -0800762 handleMore = self.handle.before
andrewonlab95ca1462014-10-09 14:04:24 -0400763
Hari Krishna03f530e2015-07-10 17:28:27 -0700764 cell_result = handleBefore + handleAfter + handleMore
765 print cell_result
766 if( re.search( "No such cell", cell_result ) ):
767 main.log.error( "Cell call returned: " + handleBefore +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800768 handleAfter + handleMore )
Hari Krishna03f530e2015-07-10 17:28:27 -0700769 main.cleanup()
770 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400771 return main.TRUE
772
773 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800774 main.log.error( self.name + ": EOF exception found" )
775 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ca1462014-10-09 14:04:24 -0400776 main.cleanup()
777 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800778 except Exception:
779 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ca1462014-10-09 14:04:24 -0400780 main.cleanup()
781 main.exit()
782
kelvin-onlabd3b64892015-01-20 13:26:24 -0800783 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800784 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400785 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800786 """
787 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400788
andrewonlabc03bf6c2014-10-09 14:56:18 -0400789 try:
kelvin8ec71442015-01-15 16:57:00 -0800790 # Clean handle by sending empty and expecting $
791 self.handle.sendline( "" )
792 self.handle.expect( "\$" )
793 self.handle.sendline( "onos-verify-cell" )
794 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800795 handleBefore = self.handle.before
796 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800797 # Get the rest of the handle
798 self.handle.sendline( "" )
799 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800800 handleMore = self.handle.before
andrewonlabc03bf6c2014-10-09 14:56:18 -0400801
kelvin-onlabd3b64892015-01-20 13:26:24 -0800802 main.log.info( "Verify cell returned: " + handleBefore +
803 handleAfter + handleMore )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400804
805 return main.TRUE
Jon Halla5cb6172015-02-23 09:28:28 -0800806 except pexpect.ExceptionPexpect as e:
807 main.log.error( self.name + ": Pexpect exception found of type " +
808 str( type( e ) ) )
809 main.log.error ( e.get_trace() )
kelvin8ec71442015-01-15 16:57:00 -0800810 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400811 main.cleanup()
812 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800813 except Exception:
814 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400815 main.cleanup()
816 main.exit()
817
jenkins1e99e7b2015-04-02 18:15:39 -0700818 def onosCfgSet( self, ONOSIp, configName, configParam ):
819 """
820 Uses 'onos <node-ip> cfg set' to change a parameter value of an
821 application.
822
823 ex)
824 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
jenkins1e99e7b2015-04-02 18:15:39 -0700825 ONOSIp = '10.0.0.1'
826 configName = 'org.onosproject.myapp'
827 configParam = 'appSetting 1'
jenkins1e99e7b2015-04-02 18:15:39 -0700828 """
cameron@onlab.us78b89652015-07-08 15:21:03 -0700829 for i in range(5):
830 try:
831 cfgStr = ( "onos "+str(ONOSIp)+" cfg set "+
832 str(configName) + " " +
833 str(configParam)
834 )
jenkins1e99e7b2015-04-02 18:15:39 -0700835
cameron@onlab.us78b89652015-07-08 15:21:03 -0700836 self.handle.sendline( "" )
837 self.handle.expect( ":~" )
838 self.handle.sendline( cfgStr )
839 self.handle.expect("cfg set")
840 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700841
cameron@onlab.us78b89652015-07-08 15:21:03 -0700842 paramValue = configParam.split(" ")[1]
843 paramName = configParam.split(" ")[0]
844
845 checkStr = ( "onos " + str(ONOSIp) + """ cfg get " """ + str(configName) + " " + paramName + """ " """)
jenkins1e99e7b2015-04-02 18:15:39 -0700846
cameron@onlab.us78b89652015-07-08 15:21:03 -0700847 self.handle.sendline( checkStr )
848 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700849
cameron@onlab.us78b89652015-07-08 15:21:03 -0700850 if "value=" + paramValue + "," in self.handle.before:
851 main.log.info("cfg " + configName + " successfully set to " + configParam)
852 return main.TRUE
853
854 except pexpect.ExceptionPexpect as e:
855 main.log.error( self.name + ": Pexpect exception found of type " +
856 str( type( e ) ) )
857 main.log.error ( e.get_trace() )
858 main.log.error( self.name + ": " + self.handle.before )
859 main.cleanup()
860 main.exit()
861 except Exception:
862 main.log.exception( self.name + ": Uncaught exception!" )
863 main.cleanup()
864 main.exit()
865
866 time.sleep(5)
867
868 main.log.error("CFG SET FAILURE: " + configName + " " + configParam )
869 main.ONOSbench.handle.sendline("onos $OC1 cfg get")
870 main.ONOSbench.handle.expect("\$")
871 print main.ONOSbench.handle.before
872 main.ONOSbench.logReport( ONOSIp, ["ERROR","WARN","EXCEPT"], "d")
873 return main.FALSE
874
875
kelvin-onlabd3b64892015-01-20 13:26:24 -0800876 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800877 """
andrewonlab05e362f2014-10-10 00:40:57 -0400878 Uses 'onos' command to send various ONOS CLI arguments.
879 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800880 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400881 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800882
883 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400884 CLI commands for ONOS. Try to use this function first
885 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800886 function.
887 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400888 by starting onos, and typing in 'onos' to enter the
889 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800890 available commands.
891 """
andrewonlab05e362f2014-10-10 00:40:57 -0400892 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800893 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800894 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400895 return main.FALSE
896 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800897 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400898 return main.FALSE
899
kelvin8ec71442015-01-15 16:57:00 -0800900 cmdstr = str( cmdstr )
901 self.handle.sendline( "" )
902 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400903
kelvin-onlabd3b64892015-01-20 13:26:24 -0800904 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800905 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400906
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 handleBefore = self.handle.before
Shreya Shaha73aaad2014-10-27 18:03:09 -0400908 print "handle_before = ", self.handle.before
kelvin-onlabd3b64892015-01-20 13:26:24 -0800909 # handleAfter = str( self.handle.after )
Jon Hall47a93fb2015-01-06 16:46:06 -0800910
kelvin8ec71442015-01-15 16:57:00 -0800911 # self.handle.sendline( "" )
912 # self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800913 # handleMore = str( self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400914
kelvin8ec71442015-01-15 16:57:00 -0800915 main.log.info( "Command sent successfully" )
andrewonlab05e362f2014-10-10 00:40:57 -0400916
kelvin8ec71442015-01-15 16:57:00 -0800917 # Obtain return handle that consists of result from
918 # the onos command. The string may need to be
919 # configured further.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800920 # returnString = handleBefore + handleAfter
921 returnString = handleBefore
922 print "return_string = ", returnString
923 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400924
925 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800926 main.log.error( self.name + ": EOF exception found" )
927 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400928 main.cleanup()
929 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800930 except Exception:
931 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab05e362f2014-10-10 00:40:57 -0400932 main.cleanup()
933 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400934
kelvin-onlabd3b64892015-01-20 13:26:24 -0800935 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800936 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400937 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800938 If -f option is provided, it also forces an uninstall.
939 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400940 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800941 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400942 files to certain onos nodes
943
944 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800945 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400946 try:
andrewonlab114768a2014-11-14 12:44:44 -0500947 if options:
kelvin8ec71442015-01-15 16:57:00 -0800948 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500949 else:
kelvin8ec71442015-01-15 16:57:00 -0800950 self.handle.sendline( "onos-install " + node )
951 self.handle.expect( "onos-install " )
952 # NOTE: this timeout may need to change depending on the network
953 # and size of ONOS
954 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800955 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800956 "ONOS\sis\salready\sinstalled",
957 pexpect.TIMEOUT ], timeout=60 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400958
Jon Hall7993bfc2014-10-09 16:30:14 -0400959 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800960 main.log.warn( "Network is unreachable" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400961 return main.FALSE
962 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800963 main.log.info(
964 "ONOS was installed on " +
965 node +
966 " and started" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400967 return main.TRUE
andrewonlabd9a73a72014-11-14 17:28:21 -0500968 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800969 main.log.info( "ONOS is already installed on " + node )
andrewonlabd9a73a72014-11-14 17:28:21 -0500970 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800971 elif i == 3:
972 main.log.info(
973 "Installation of ONOS on " +
974 node +
975 " timed out" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400976 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400977
978 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800979 main.log.error( self.name + ": EOF exception found" )
980 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400981 main.cleanup()
982 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800983 except Exception:
984 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400985 main.cleanup()
986 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400987
kelvin-onlabd3b64892015-01-20 13:26:24 -0800988 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800989 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400990 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400991 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800992 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400993 try:
kelvin8ec71442015-01-15 16:57:00 -0800994 self.handle.sendline( "" )
995 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800996 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800997 " start" )
998 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -0400999 "Job\sis\salready\srunning",
1000 "start/running",
1001 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -08001002 pexpect.TIMEOUT ], timeout=120 )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001003
1004 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001005 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001006 return main.TRUE
1007 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001008 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001009 return main.TRUE
1010 else:
kelvin8ec71442015-01-15 16:57:00 -08001011 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001012 main.cleanup()
1013 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001014 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001015 main.log.error( self.name + ": EOF exception found" )
1016 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001017 main.cleanup()
1018 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001019 except Exception:
1020 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001021 main.cleanup()
1022 main.exit()
1023
kelvin-onlabd3b64892015-01-20 13:26:24 -08001024 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001025 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001026 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001027 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001028 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001029 try:
kelvin8ec71442015-01-15 16:57:00 -08001030 self.handle.sendline( "" )
1031 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001032 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001033 " stop" )
1034 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -04001035 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -07001036 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -04001037 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -08001038 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2b30bd32014-10-09 16:48:55 -04001039
1040 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001041 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001042 return main.TRUE
1043 elif i == 1:
Jon Hall65844a32015-03-09 19:09:37 -07001044 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001045 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -04001046 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -07001047 elif i == 2:
1048 main.log.warn( "ONOS wasn't running" )
1049 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -04001050 else:
kelvin8ec71442015-01-15 16:57:00 -08001051 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001052 return main.FALSE
1053
1054 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001055 main.log.error( self.name + ": EOF exception found" )
1056 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -04001057 main.cleanup()
1058 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001059 except Exception:
1060 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001061 main.cleanup()
1062 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001063
kelvin-onlabd3b64892015-01-20 13:26:24 -08001064 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -08001065 """
andrewonlabc8d47972014-10-09 16:52:36 -04001066 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -08001067 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -04001068 if needed
kelvin8ec71442015-01-15 16:57:00 -08001069 """
andrewonlabc8d47972014-10-09 16:52:36 -04001070 try:
kelvin8ec71442015-01-15 16:57:00 -08001071 self.handle.sendline( "" )
pingping-lin763ee042015-05-20 17:45:30 -07001072 self.handle.expect( "\$", timeout=60 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001073 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001074 self.handle.expect( "\$" )
andrewonlabc8d47972014-10-09 16:52:36 -04001075
kelvin-onlabd3b64892015-01-20 13:26:24 -08001076 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
andrewonlab9dfd2082014-11-13 17:44:03 -05001077
kelvin8ec71442015-01-15 16:57:00 -08001078 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -04001079 return main.TRUE
1080
pingping-lin763ee042015-05-20 17:45:30 -07001081 except pexpect.TIMEOUT:
1082 main.log.exception( self.name + ": Timeout in onosUninstall" )
1083 return main.FALSE
andrewonlabc8d47972014-10-09 16:52:36 -04001084 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001085 main.log.error( self.name + ": EOF exception found" )
1086 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -04001087 main.cleanup()
1088 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001089 except Exception:
1090 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc8d47972014-10-09 16:52:36 -04001091 main.cleanup()
1092 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -04001093
kelvin-onlabd3b64892015-01-20 13:26:24 -08001094 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001095 """
andrewonlabaedc8332014-12-04 12:43:03 -05001096 Issues the command 'onos-die <node-ip>'
1097 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -08001098 """
andrewonlabaedc8332014-12-04 12:43:03 -05001099 try:
kelvin8ec71442015-01-15 16:57:00 -08001100 self.handle.sendline( "" )
1101 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001102 cmdStr = "onos-kill " + str( nodeIp )
1103 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001104 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -05001105 "Killing\sONOS",
1106 "ONOS\sprocess\sis\snot\srunning",
kelvin8ec71442015-01-15 16:57:00 -08001107 pexpect.TIMEOUT ], timeout=20 )
andrewonlabaedc8332014-12-04 12:43:03 -05001108 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001109 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001110 " was killed and stopped" )
andrewonlabaedc8332014-12-04 12:43:03 -05001111 return main.TRUE
1112 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001113 main.log.info( "ONOS process was not running" )
andrewonlabaedc8332014-12-04 12:43:03 -05001114 return main.FALSE
1115 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001116 main.log.error( self.name + ": EOF exception found" )
1117 main.log.error( self.name + ": " + self.handle.before )
andrewonlabaedc8332014-12-04 12:43:03 -05001118 main.cleanup()
1119 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001120 except Exception:
1121 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabaedc8332014-12-04 12:43:03 -05001122 main.cleanup()
1123 main.exit()
1124
kelvin-onlabd3b64892015-01-20 13:26:24 -08001125 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001126 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001127 Calls the command: 'onos-kill [<node-ip>]'
1128 "Remotely, and unceremoniously kills the ONOS instance running on
1129 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001130 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001131 try:
kelvin8ec71442015-01-15 16:57:00 -08001132 self.handle.sendline( "" )
1133 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001135 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -04001136 "\$",
1137 "No\sroute\sto\shost",
1138 "password:",
kelvin8ec71442015-01-15 16:57:00 -08001139 pexpect.TIMEOUT ], timeout=20 )
1140
andrewonlabe8e56fd2014-10-09 17:12:44 -04001141 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001142 main.log.info(
1143 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001144 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001145 return main.TRUE
1146 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001147 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001148 return main.FALSE
1149 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001150 main.log.info(
1151 "Passwordless login for host: " +
1152 str( nodeIp ) +
1153 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001154 return main.FALSE
1155 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001156 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001157 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001158
andrewonlabe8e56fd2014-10-09 17:12:44 -04001159 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001160 main.log.error( self.name + ": EOF exception found" )
1161 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001162 main.cleanup()
1163 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001164 except Exception:
1165 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001166 main.cleanup()
1167 main.exit()
1168
kelvin-onlabd3b64892015-01-20 13:26:24 -08001169 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001170 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001171 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001172 a cleaner environment.
1173
andrewonlab19fbdca2014-11-14 12:55:59 -05001174 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001175 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001176 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001177 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001178 try:
kelvin8ec71442015-01-15 16:57:00 -08001179 self.handle.sendline( "" )
1180 self.handle.expect( "\$" )
1181 self.handle.sendline( "onos-remove-raft-logs" )
1182 # Sometimes this command hangs
1183 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1184 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001185 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001186 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1187 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001188 if i == 1:
1189 return main.FALSE
shahshreya957feaa2015-03-23 16:08:29 -07001190 #self.handle.sendline( "" )
1191 #self.handle.expect( "\$" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001192 return main.TRUE
1193
1194 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001195 main.log.error( self.name + ": EOF exception found" )
1196 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -05001197 main.cleanup()
1198 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001199 except Exception:
1200 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001201 main.cleanup()
1202 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -05001203
kelvin-onlabd3b64892015-01-20 13:26:24 -08001204 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001205 """
1206 Calls the command 'onos-start-network [ <mininet-topo> ]
1207 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001208 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001209 cell."
andrewonlab94282092014-10-10 13:00:11 -04001210 * Specify mininet topology file name for mntopo
1211 * Topo files should be placed at:
1212 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001213
andrewonlab94282092014-10-10 13:00:11 -04001214 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001215 """
andrewonlab94282092014-10-10 13:00:11 -04001216 try:
1217 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001218 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001219 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001220
kelvin8ec71442015-01-15 16:57:00 -08001221 mntopo = str( mntopo )
1222 self.handle.sendline( "" )
1223 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -04001224
kelvin8ec71442015-01-15 16:57:00 -08001225 self.handle.sendline( "onos-start-network " + mntopo )
1226 self.handle.expect( "mininet>" )
1227 main.log.info( "Network started, entered mininet prompt" )
1228
1229 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001230
1231 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001232 main.log.error( self.name + ": EOF exception found" )
1233 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -04001234 main.cleanup()
1235 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001236 except Exception:
1237 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -04001238 main.cleanup()
1239 main.exit()
1240
Cameron Franke9c94fb02015-01-21 10:20:20 -08001241 def isup(self, node = "", timeout = 120):
kelvin8ec71442015-01-15 16:57:00 -08001242 """
1243 Run's onos-wait-for-start which only returns once ONOS is at run
Cameron Franke9c94fb02015-01-21 10:20:20 -08001244 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001245
Jon Hall7993bfc2014-10-09 16:30:14 -04001246 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001247 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001248 try:
Cameron Franke9c94fb02015-01-21 10:20:20 -08001249 self.handle.sendline("onos-wait-for-start " + node )
1250 self.handle.expect("onos-wait-for-start")
kelvin8ec71442015-01-15 16:57:00 -08001251 # NOTE: this timeout is arbitrary"
Cameron Franke9c94fb02015-01-21 10:20:20 -08001252 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001253 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001254 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001255 return main.TRUE
1256 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001257 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001258 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001259 main.log.error( "ONOS has not started yet" )
1260 self.handle.send( "\x03" ) # Control-C
1261 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001262 return main.FALSE
1263 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001264 main.log.error( self.name + ": EOF exception found" )
1265 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -04001266 main.cleanup()
1267 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001268 except Exception:
1269 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001270 main.cleanup()
1271 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001272
kelvin-onlabd3b64892015-01-20 13:26:24 -08001273 def pushTestIntentsShell(
1274 self,
1275 dpidSrc,
1276 dpidDst,
1277 numIntents,
1278 dirFile,
1279 onosIp,
1280 numMult="",
1281 appId="",
1282 report=True,
1283 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001284 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001285 Description:
kelvin8ec71442015-01-15 16:57:00 -08001286 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001287 better parallelize the results than the CLI
1288 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001289 * dpidSrc: specify source dpid
1290 * dpidDst: specify destination dpid
1291 * numIntents: specify number of intents to push
1292 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001293 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001294 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001295 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001296 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001297 """
1298 try:
1299 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001300 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001301 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001302 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001303 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001304 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001305
kelvin-onlabd3b64892015-01-20 13:26:24 -08001306 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1307 if not numMult:
1308 addIntents = addDpid + " " + str( numIntents )
1309 elif numMult:
1310 addIntents = addDpid + " " + str( numIntents ) + " " +\
1311 str( numMult )
1312 if appId:
1313 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001314 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001315 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001316
andrewonlabaedc8332014-12-04 12:43:03 -05001317 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001318 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001319 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001320 sendCmd = addApp + " &"
1321 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001322
kelvin-onlabd3b64892015-01-20 13:26:24 -08001323 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001324
1325 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 )
andrewonlabb66dfa12014-12-02 15:51:10 -05001328 main.cleanup()
1329 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001330 except Exception:
1331 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001332 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001333 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001334
kelvin-onlabd3b64892015-01-20 13:26:24 -08001335 def getTopology( self, topologyOutput ):
kelvin8ec71442015-01-15 16:57:00 -08001336 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001337 Definition:
1338 Loads a json topology output
1339 Return:
1340 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -08001341 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001342 import json
Jon Hall77f53ce2014-10-13 18:02:06 -04001343 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001344 # either onos:topology or 'topology' will work in CLI
1345 topology = json.loads(topologyOutput)
1346 print topology
Jon Hall77f53ce2014-10-13 18:02:06 -04001347 return topology
1348 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001349 main.log.error( self.name + ": EOF exception found" )
1350 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001351 main.cleanup()
1352 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001353 except Exception:
1354 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001355 main.cleanup()
1356 main.exit()
1357
kelvin-onlabd3b64892015-01-20 13:26:24 -08001358 def checkStatus(
1359 self,
1360 topologyResult,
1361 numoswitch,
1362 numolink,
1363 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001364 """
Jon Hallefbd9792015-03-05 16:11:36 -08001365 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001366 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001367 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08001368
Jon Hall77f53ce2014-10-13 18:02:06 -04001369 Params: ip = ip used for the onos cli
1370 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001371 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001372 logLevel = level to log to.
1373 Currently accepts 'info', 'warn' and 'report'
Jon Hall77f53ce2014-10-13 18:02:06 -04001374
1375
kelvin-onlabd3b64892015-01-20 13:26:24 -08001376 logLevel can
Jon Hall77f53ce2014-10-13 18:02:06 -04001377
Jon Hallefbd9792015-03-05 16:11:36 -08001378 Returns: main.TRUE if the number of switches and links are correct,
1379 main.FALSE if the number of switches and links is incorrect,
Jon Hall77f53ce2014-10-13 18:02:06 -04001380 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001381 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001382 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001383 topology = self.getTopology( topologyResult )
Jon Hall77f53ce2014-10-13 18:02:06 -04001384 if topology == {}:
1385 return main.ERROR
1386 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001387 # Is the number of switches is what we expected
shahshreya234a1682015-05-27 15:41:56 -07001388 devices = topology.get( 'devices', False )
1389 links = topology.get( 'links', False )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001390 if not devices or not links:
Jon Hall77f53ce2014-10-13 18:02:06 -04001391 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001392 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001393 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001394 linkCheck = ( int( links ) == int( numolink ) )
Jon Hallefbd9792015-03-05 16:11:36 -08001395 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08001396 # We expected the correct numbers
Jon Hall77f53ce2014-10-13 18:02:06 -04001397 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001398 + "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001399 result = main.TRUE
1400 else:
1401 output = output + \
Jon Hall274b6642015-02-17 11:57:17 -08001402 "The number of links and switches does not match " + \
1403 "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001404 result = main.FALSE
Jon Hallefbd9792015-03-05 16:11:36 -08001405 output = output + "\n ONOS sees %i devices" % int( devices )
1406 output = output + " (%i expected) " % int( numoswitch )
Jon Hall274b6642015-02-17 11:57:17 -08001407 output = output + "and %i links " % int( links )
1408 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001409 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001410 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001411 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001412 main.log.warn( output )
Jon Hall77f53ce2014-10-13 18:02:06 -04001413 else:
kelvin8ec71442015-01-15 16:57:00 -08001414 main.log.info( output )
1415 return result
Jon Hall77f53ce2014-10-13 18:02:06 -04001416 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001417 main.log.error( self.name + ": EOF exception found" )
1418 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001419 main.cleanup()
1420 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001421 except Exception:
1422 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001423 main.cleanup()
1424 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001425
kelvin-onlabd3b64892015-01-20 13:26:24 -08001426 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001427 """
andrewonlab970399c2014-11-07 13:09:32 -05001428 Capture all packet activity and store in specified
1429 directory/file
1430
1431 Required:
1432 * interface: interface to capture
1433 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001434 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001435 try:
1436 self.handle.sendline( "" )
1437 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001438
Jon Hallfebb1c72015-03-05 13:30:09 -08001439 self.handle.sendline( "tshark -i " + str( interface ) +
1440 " -t e -w " + str( dirFile ) + " &" )
1441 self.handle.sendline( "\r" )
1442 self.handle.expect( "Capturing on" )
1443 self.handle.sendline( "\r" )
1444 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001445
Jon Hallfebb1c72015-03-05 13:30:09 -08001446 main.log.info( "Tshark started capturing files on " +
1447 str( interface ) + " and saving to directory: " +
1448 str( dirFile ) )
1449 except pexpect.EOF:
1450 main.log.error( self.name + ": EOF exception found" )
1451 main.log.error( self.name + ": " + self.handle.before )
1452 main.cleanup()
1453 main.exit()
1454 except Exception:
1455 main.log.exception( self.name + ": Uncaught exception!" )
1456 main.cleanup()
1457 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001458
kelvin-onlabd3b64892015-01-20 13:26:24 -08001459 def runOnosTopoCfg( self, instanceName, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001460 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001461 On ONOS bench, run this command:
Jon Halle94919c2015-03-23 11:42:57 -07001462 {ONOS_HOME}/tools/test/bin/onos-topo-cfg $OC1 filename
kelvin-onlabd3b64892015-01-20 13:26:24 -08001463 which starts the rest and copies
1464 the json file to the onos instance
kelvin8ec71442015-01-15 16:57:00 -08001465 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001466 try:
kelvin8ec71442015-01-15 16:57:00 -08001467 self.handle.sendline( "" )
1468 self.handle.expect( "\$" )
Jon Halle94919c2015-03-23 11:42:57 -07001469 self.handle.sendline( "cd " + self.home + "/tools/test/bin" )
kelvin8ec71442015-01-15 16:57:00 -08001470 self.handle.expect( "/bin$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001471 cmd = "./onos-topo-cfg " + instanceName + " " + jsonFile
shahshreyae6c7cf42014-11-26 16:39:01 -08001472 print "cmd = ", cmd
kelvin8ec71442015-01-15 16:57:00 -08001473 self.handle.sendline( cmd )
1474 self.handle.expect( "\$" )
1475 self.handle.sendline( "cd ~" )
1476 self.handle.expect( "\$" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001477 return main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -08001478 except pexpect.EOF:
1479 main.log.error( self.name + ": EOF exception found" )
1480 main.log.error( self.name + ": " + self.handle.before )
1481 main.cleanup()
1482 main.exit()
1483 except Exception:
1484 main.log.exception( self.name + ": Uncaught exception!" )
1485 main.cleanup()
1486 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001487
jenkins1e99e7b2015-04-02 18:15:39 -07001488 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001489 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001490 Required:
kelvin8ec71442015-01-15 16:57:00 -08001491 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001492 * directory to store results
1493 Optional:
1494 * interface - default: eth0
jenkins1e99e7b2015-04-02 18:15:39 -07001495 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001496 Description:
1497 Uses tshark command to grep specific group of packets
1498 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001499 The timestamp is hardcoded to be in epoch
1500 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001501 try:
1502 self.handle.sendline( "" )
1503 self.handle.expect( "\$" )
1504 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001505 if grepOptions:
1506 grepStr = "grep "+str(grepOptions)
1507 else:
1508 grepStr = "grep"
1509
Jon Hallfebb1c72015-03-05 13:30:09 -08001510 self.handle.sendline(
1511 "tshark -i " +
1512 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001513 " -t e | " +
1514 grepStr + " --line-buffered \"" +
Jon Hallfebb1c72015-03-05 13:30:09 -08001515 str(grep) +
1516 "\" >" +
1517 directory +
1518 " &" )
1519 self.handle.sendline( "\r" )
1520 self.handle.expect( "Capturing on" )
1521 self.handle.sendline( "\r" )
1522 self.handle.expect( "\$" )
1523 except pexpect.EOF:
1524 main.log.error( self.name + ": EOF exception found" )
1525 main.log.error( self.name + ": " + self.handle.before )
1526 main.cleanup()
1527 main.exit()
1528 except Exception:
1529 main.log.exception( self.name + ": Uncaught exception!" )
1530 main.cleanup()
1531 main.exit()
1532
kelvin-onlabd3b64892015-01-20 13:26:24 -08001533 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001534 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001535 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001536 """
1537 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001538 try:
1539 self.execute( cmd="sudo rm /tmp/wireshark*" )
1540 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001541 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1542 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001543 self.handle.sendline( "" )
1544 main.log.info( "Tshark stopped" )
1545 except pexpect.EOF:
1546 main.log.error( self.name + ": EOF exception found" )
1547 main.log.error( self.name + ": " + self.handle.before )
1548 main.cleanup()
1549 main.exit()
1550 except Exception:
1551 main.log.exception( self.name + ": Uncaught exception!" )
1552 main.cleanup()
1553 main.exit()
1554
kelvin8ec71442015-01-15 16:57:00 -08001555 def ptpd( self, args ):
1556 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001557 Initiate ptp with user-specified args.
1558 Required:
1559 * args: specify string of args after command
1560 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001561 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001562 try:
kelvin8ec71442015-01-15 16:57:00 -08001563 self.handle.sendline( "sudo ptpd " + str( args ) )
1564 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001565 "Multiple",
1566 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001567 "\$" ] )
1568 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001569
andrewonlab0c38a4a2014-10-28 18:35:35 -04001570 if i == 0:
1571 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001572 main.log.info( "ptpd returned an error: " +
1573 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001574 return handle
1575 elif i == 1:
1576 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001577 main.log.error( "ptpd returned an error: " +
1578 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001579 return handle
1580 else:
1581 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001582
andrewonlab0c38a4a2014-10-28 18:35:35 -04001583 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001584 main.log.error( self.name + ": EOF exception found" )
1585 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001586 main.cleanup()
1587 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001588 except Exception:
1589 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001590 main.cleanup()
1591 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001592
kelvin-onlabd3b64892015-01-20 13:26:24 -08001593 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001594 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001595 """
1596 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001597 Current implementation of ONOS deletes its karaf
1598 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001599 you may want to use this function to capture
1600 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001601 Localtime will be attached to the filename
1602
1603 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001604 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001605 copy.
kelvin8ec71442015-01-15 16:57:00 -08001606 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001607 For copying multiple files, leave copyFileName
1608 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001609 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001610 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001611 ex ) /tmp/
1612 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001613 * copyFileName: If you want to rename the log
1614 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001615 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001616 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001617 try:
kelvin8ec71442015-01-15 16:57:00 -08001618 localtime = time.strftime( '%x %X' )
1619 localtime = localtime.replace( "/", "" )
1620 localtime = localtime.replace( " ", "_" )
1621 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001622 if destDir[ -1: ] != "/":
1623 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001624
kelvin-onlabd3b64892015-01-20 13:26:24 -08001625 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001626 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1627 str( destDir ) + str( copyFileName ) +
1628 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001629 self.handle.expect( "cp" )
1630 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001631 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001632 self.handle.sendline( "cp " + str( logToCopy ) +
1633 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001634 self.handle.expect( "cp" )
1635 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001636
kelvin8ec71442015-01-15 16:57:00 -08001637 return self.handle.before
1638
1639 except pexpect.EOF:
1640 main.log.error( "Copying files failed" )
1641 main.log.error( self.name + ": EOF exception found" )
1642 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001643 except Exception:
1644 main.log.exception( "Copying files failed" )
1645
Jon Hall16b72c42015-05-20 10:23:36 -07001646 def checkLogs( self, onosIp, restart=False):
kelvin8ec71442015-01-15 16:57:00 -08001647 """
Jon Hall94fd0472014-12-08 11:52:42 -08001648 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001649 If restart is True, use the old version of onos-check-logs which
1650 does not print the full stacktrace, but shows the entire log file,
1651 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001652 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001653 """
Jon Hall94fd0472014-12-08 11:52:42 -08001654 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001655 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001656 if restart:
1657 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001658 self.handle.sendline( cmd )
1659 self.handle.expect( cmd )
1660 self.handle.expect( "\$" )
Jon Hall94fd0472014-12-08 11:52:42 -08001661 response = self.handle.before
1662 return response
1663 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001664 main.log.error( "Lost ssh connection" )
1665 main.log.error( self.name + ": EOF exception found" )
1666 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001667 except Exception:
1668 main.log.exception( self.name + ": Uncaught exception!" )
1669 main.cleanup()
1670 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001671
kelvin-onlabd3b64892015-01-20 13:26:24 -08001672 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001673 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001674 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001675 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001676 try:
kelvin8ec71442015-01-15 16:57:00 -08001677 self.handle.sendline( "" )
1678 self.handle.expect( "\$" )
1679 self.handle.sendline( "onos-service " + str( node ) +
1680 " status" )
1681 i = self.handle.expect( [
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001682 "start/running",
1683 "stop/waiting",
kelvin8ec71442015-01-15 16:57:00 -08001684 pexpect.TIMEOUT ], timeout=120 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001685
1686 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001687 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001688 return main.TRUE
1689 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001690 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001691 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001692 main.cleanup()
1693 main.exit()
1694 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001695 main.log.error( self.name + ": EOF exception found" )
1696 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001697 main.cleanup()
1698 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001699 except Exception:
1700 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001701 main.cleanup()
1702 main.exit()
Jon Hall21270ac2015-02-16 17:59:55 -08001703
Jon Hall63604932015-02-26 17:09:50 -08001704 def setIpTables( self, ip, port='', action='add', packet_type='',
1705 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001706 """
Jon Hall21270ac2015-02-16 17:59:55 -08001707 Description:
1708 add or remove iptables rule to DROP (default) packets from
1709 specific IP and PORT
1710 Usage:
1711 * specify action ('add' or 'remove')
1712 when removing, pass in the same argument as you would add. It will
1713 delete that specific rule.
1714 * specify the ip to block
1715 * specify the destination port to block (defaults to all ports)
1716 * optional packet type to block (default tcp)
1717 * optional iptables rule (default DROP)
1718 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001719 * States boolean toggles adding all supported tcp states to the
1720 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001721 Returns:
1722 main.TRUE on success or
1723 main.FALSE if given invalid input or
1724 main.ERROR if there is an error in response from iptables
1725 WARNING:
1726 * This function uses root privilege iptables command which may result
1727 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001728 """
Jon Hall21270ac2015-02-16 17:59:55 -08001729 import time
1730
1731 # NOTE*********
1732 # The strict checking methods of this driver function is intentional
1733 # to discourage any misuse or error of iptables, which can cause
1734 # severe network errors
1735 # *************
1736
1737 # NOTE: Sleep needed to give some time for rule to be added and
1738 # registered to the instance. If you are calling this function
1739 # multiple times this sleep will prevent any errors.
1740 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001741 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001742 try:
1743 # input validation
1744 action_type = action.lower()
1745 rule = rule.upper()
1746 direction = direction.upper()
1747 if action_type != 'add' and action_type != 'remove':
1748 main.log.error( "Invalid action type. Use 'add' or "
1749 "'remove' table rule" )
1750 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1751 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1752 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1753 "'ACCEPT' or 'LOG' only." )
1754 if direction != 'INPUT' and direction != 'OUTPUT':
1755 # NOTE currently only supports rules INPUT and OUPTUT
1756 main.log.error( "Invalid rule. Valid directions are"
1757 " 'OUTPUT' or 'INPUT'" )
1758 return main.FALSE
1759 return main.FALSE
1760 return main.FALSE
1761 if action_type == 'add':
1762 # -A is the 'append' action of iptables
1763 actionFlag = '-A'
1764 elif action_type == 'remove':
1765 # -D is the 'delete' rule of iptables
1766 actionFlag = '-D'
1767 self.handle.sendline( "" )
1768 self.handle.expect( "\$" )
1769 cmd = "sudo iptables " + actionFlag + " " +\
1770 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001771 " -s " + str( ip )
Jon Hall63604932015-02-26 17:09:50 -08001772 # " -p " + str( packet_type ) +\
1773 if packet_type:
1774 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001775 if port:
1776 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001777 if states:
1778 cmd += " -m state --state="
1779 #FIXME- Allow user to configure which states to block
1780 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001781 cmd += " -j " + str( rule )
1782
1783 self.handle.sendline( cmd )
1784 self.handle.expect( "\$" )
1785 main.log.warn( self.handle.before )
1786
1787 info_string = "On " + str( self.name )
1788 info_string += " " + str( action_type )
1789 info_string += " iptable rule [ "
1790 info_string += " IP: " + str( ip )
1791 info_string += " Port: " + str( port )
1792 info_string += " Rule: " + str( rule )
1793 info_string += " Direction: " + str( direction ) + " ]"
1794 main.log.info( info_string )
1795 return main.TRUE
1796 except pexpect.TIMEOUT:
1797 main.log.exception( self.name + ": Timeout exception in "
1798 "setIpTables function" )
1799 return main.ERROR
1800 except pexpect.EOF:
1801 main.log.error( self.name + ": EOF exception found" )
1802 main.log.error( self.name + ": " + self.handle.before )
1803 main.cleanup()
1804 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001805 except Exception:
1806 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall21270ac2015-02-16 17:59:55 -08001807 main.cleanup()
1808 main.exit()
1809
Jon Hall0468b042015-02-19 19:08:21 -08001810 def detailed_status(self, log_filename):
Jon Hallefbd9792015-03-05 16:11:36 -08001811 """
Jon Hall0468b042015-02-19 19:08:21 -08001812 This method is used by STS to check the status of the controller
1813 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001814 """
Jon Hall0468b042015-02-19 19:08:21 -08001815 import re
1816 try:
1817 self.handle.sendline( "" )
1818 self.handle.expect( "\$" )
1819 self.handle.sendline( "cd " + self.home )
1820 self.handle.expect( "\$" )
1821 self.handle.sendline( "service onos status" )
1822 self.handle.expect( "\$" )
1823 response = self.handle.before
1824 if re.search( "onos start/running", response ):
1825 # onos start/running, process 10457
1826 return 'RUNNING'
1827 # FIXME: Implement this case
1828 # elif re.search( pattern, response ):
1829 # return 'STARTING'
1830 elif re.search( "onos stop/", response ):
1831 # onos stop/waiting
1832 # FIXME handle this differently?: onos stop/pre-stop
1833 return 'STOPPED'
1834 # FIXME: Implement this case
1835 # elif re.search( pattern, response ):
1836 # return 'FROZEN'
1837 else:
1838 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001839 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001840 main.log.warn( response )
1841 return 'ERROR', "Unknown response: %s" % response
1842 except pexpect.TIMEOUT:
1843 main.log.exception( self.name + ": Timeout exception in "
1844 "setIpTables function" )
1845 return 'ERROR', "Pexpect Timeout"
1846 except pexpect.EOF:
1847 main.log.error( self.name + ": EOF exception found" )
1848 main.log.error( self.name + ": " + self.handle.before )
1849 main.cleanup()
1850 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001851 except Exception:
1852 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall0468b042015-02-19 19:08:21 -08001853 main.cleanup()
1854 main.exit()
1855
andrew@onlab.us3b087132015-03-11 15:00:08 -07001856 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1857 '''
1858 Create/formats the LinkGraph.cfg file based on arguments
1859 -only creates a linear topology and connects islands
1860 -evenly distributes devices
1861 -must be called by ONOSbench
1862
1863 ONOSIpList - list of all of the node IPs to be used
1864
1865 deviceCount - number of switches to be assigned
1866 '''
1867 main.log.step("Creating link graph configuration file." )
1868 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
1869 tempFile = "/tmp/linkGraph.cfg"
1870
1871 linkGraph = open(tempFile, 'w+')
1872 linkGraph.write("# NullLinkProvider topology description (config file).\n")
1873 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
1874 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
1875
1876 clusterCount = len(ONOSIpList)
1877
1878 if type(deviceCount) is int or type(deviceCount) is str:
1879 deviceCount = int(deviceCount)
1880 switchList = [0]*(clusterCount+1)
1881 baselineSwitchCount = deviceCount/clusterCount
1882
1883 for node in range(1, clusterCount + 1):
1884 switchList[node] = baselineSwitchCount
1885
1886 for node in range(1, (deviceCount%clusterCount)+1):
1887 switchList[node] += 1
1888
1889 if type(deviceCount) is list:
1890 main.log.info("Using provided device distribution")
1891 switchList = [0]
1892 for i in deviceCount:
1893 switchList.append(int(i))
1894
1895 tempList = ['0']
1896 tempList.extend(ONOSIpList)
1897 ONOSIpList = tempList
1898
1899 myPort = 6
1900 lastSwitch = 0
1901 for node in range(1, clusterCount+1):
1902 if switchList[node] == 0:
1903 continue
1904
1905 linkGraph.write("graph " + ONOSIpList[node] + " {\n")
1906
1907 if node > 1:
1908 #connect to last device on previous node
1909 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
1910 linkGraph.write(line)
1911
1912 lastSwitch = 0
1913 for switch in range (0, switchList[node]-1):
1914 line = ""
1915 line = ("\t" + str(switch) + ":" + str(myPort))
1916 line += " -- "
1917 line += (str(switch+1) + ":" + str(myPort-1) + "\n")
1918 linkGraph.write(line)
1919 lastSwitch = switch+1
1920 lastIp = ONOSIpList[node]
1921
1922 #lastSwitch += 1
1923 if node < (clusterCount):
1924 #connect to first device on the next node
1925 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
1926 linkGraph.write(line)
1927
1928 linkGraph.write("}\n")
1929 linkGraph.close()
1930
1931 #SCP
kelvin-onlabc2b79102015-07-14 11:41:20 -07001932 os.system( "scp " + tempFile + " " + self.user_name + "@" + benchIp + ":" + linkGraphPath)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001933 main.log.info("linkGraph.cfg creation complete")
1934
cameron@onlab.us75900962015-03-30 13:22:49 -07001935 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001936
1937 '''
andrew@onlab.us3b087132015-03-11 15:00:08 -07001938 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
cameron@onlab.us75900962015-03-30 13:22:49 -07001939 deviceCount = number of switches to distribute, or list of values to use as custom distribution
1940 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 -07001941 '''
1942
cameron@onlab.us75900962015-03-30 13:22:49 -07001943 main.log.step("Configuring Null Device Provider" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07001944 clusterCount = len(ONOSIpList)
1945
cameron@onlab.us75900962015-03-30 13:22:49 -07001946 try:
1947
1948 if type(deviceCount) is int or type(deviceCount) is str:
1949 main.log.step("Creating device distribution")
1950 deviceCount = int(deviceCount)
1951 switchList = [0]*(clusterCount+1)
1952 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001953
cameron@onlab.us75900962015-03-30 13:22:49 -07001954 for node in range(1, clusterCount + 1):
1955 switchList[node] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001956
cameron@onlab.us75900962015-03-30 13:22:49 -07001957 for node in range(1, (deviceCount%clusterCount)+1):
1958 switchList[node] += 1
1959
1960 if type(deviceCount) is list:
1961 main.log.info("Using provided device distribution")
1962
1963 if len(deviceCount) == clusterCount:
1964 switchList = ['0']
1965 switchList.extend(deviceCount)
1966
1967 if len(deviceCount) == (clusterCount + 1):
1968 if deviceCount[0] == '0' or deviceCount[0] == 0:
1969 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001970
cameron@onlab.us75900962015-03-30 13:22:49 -07001971 assert len(switchList) == (clusterCount + 1)
1972
1973 except AssertionError:
1974 main.log.error( "Bad device/Ip list match")
1975 except TypeError:
1976 main.log.exception( self.name + ": Object not as expected" )
1977 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07001978 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001979 main.log.exception( self.name + ": Uncaught exception!" )
1980 main.cleanup()
1981 main.exit()
1982
andrew@onlab.us3b087132015-03-11 15:00:08 -07001983
1984 ONOSIp = [0]
1985 ONOSIp.extend(ONOSIpList)
1986
1987 devicesString = "devConfigs = "
1988 for node in range(1, len(ONOSIp)):
1989 devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
1990 if node < clusterCount:
1991 devicesString += (",")
cameron@onlab.us75900962015-03-30 13:22:49 -07001992
1993 try:
1994 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
1995 self.handle.expect(":~")
1996 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) )
1997 self.handle.expect(":~")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001998
cameron@onlab.us75900962015-03-30 13:22:49 -07001999 for i in range(10):
2000 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider")
2001 self.handle.expect(":~")
2002 verification = self.handle.before
2003 if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification:
2004 break
2005 else:
2006 time.sleep(1)
andrew@onlab.us3b087132015-03-11 15:00:08 -07002007
cameron@onlab.us2cc8bf12015-04-02 14:12:30 -07002008 assert ("value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification
cameron@onlab.us75900962015-03-30 13:22:49 -07002009
2010 except AssertionError:
2011 main.log.error("Incorrect Config settings: " + verification)
Jon Hall77ba41c2015-04-06 10:25:40 -07002012 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002013 main.log.exception( self.name + ": Uncaught exception!" )
2014 main.cleanup()
2015 main.exit()
2016
cameron@onlab.usc80a8c82015-04-15 14:57:37 -07002017 def configNullLink( self,fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0):
andrew@onlab.us3b087132015-03-11 15:00:08 -07002018 '''
cameron@onlab.us75900962015-03-30 13:22:49 -07002019 fileName default is currently the same as the default on ONOS, specify alternate file if
2020 you want to use a different topology file than linkGraph.cfg
andrew@onlab.us3b087132015-03-11 15:00:08 -07002021 '''
2022
andrew@onlab.us3b087132015-03-11 15:00:08 -07002023
cameron@onlab.us75900962015-03-30 13:22:49 -07002024 try:
2025 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str(eventRate))
2026 self.handle.expect(":~")
2027 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
2028 self.handle.expect(":~")
2029
2030 for i in range(10):
2031 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider")
2032 self.handle.expect(":~")
2033 verification = self.handle.before
2034 if (" value=" + str(eventRate)) in verification and (" value=" + fileName) in verification:
2035 break
2036 else:
2037 time.sleep(1)
2038
2039 assert ("value=" + str(eventRate)) in verification and (" value=" + fileName) in verification
2040
2041 except pexpect.EOF:
2042 main.log.error( self.name + ": EOF exception found" )
2043 main.log.error( self.name + ": " + self.handle.before )
2044 main.cleanup()
2045 main.exit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002046 except AssertionError:
2047 main.log.info("Settings did not post to ONOS")
2048 main.log.error(varification)
Jon Hall77ba41c2015-04-06 10:25:40 -07002049 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002050 main.log.exception( self.name + ": Uncaught exception!" )
2051 main.log.error(varification)
2052 main.cleanup()
2053 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07002054
kelvin-onlaba4074292015-07-09 15:19:49 -07002055 def getOnosIps( self ):
2056 """
2057 Get all onos IPs stored in
2058 """
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002059
kelvin-onlaba4074292015-07-09 15:19:49 -07002060 return sorted( self.onosIps.values() )
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002061
kelvin-onlaba4074292015-07-09 15:19:49 -07002062 def logReport( self, nodeIp, searchTerms, outputMode="s" ):
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002063 '''
2064 - accepts either a list or a string for "searchTerms" these
2065 terms will be searched for in the log and have their
2066 instances counted
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002067
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002068 - nodeIp is the ip of the node whos log is to be scanned
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002069
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002070 - output modes:
2071 "s" - Simple. Quiet output mode that just prints
cameron@onlab.us2e166212015-05-19 14:28:25 -07002072 the occurences of each search term
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002073
cameron@onlab.us2e166212015-05-19 14:28:25 -07002074 "d" - Detailed. Prints number of occurences as well as the entire
2075 line for each of the last 5 occurences
2076
2077 - returns total of the number of instances of all search terms
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002078 '''
2079 main.log.info("========================== Log Report ===========================\n")
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002080
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002081 if type(searchTerms) is str:
2082 searchTerms = [searchTerms]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002083
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002084 logLines = [ [" "] for i in range(len(searchTerms)) ]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002085
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002086 for term in range(len(searchTerms)):
2087 logLines[term][0] = searchTerms[term]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002088
cameron@onlab.us2e166212015-05-19 14:28:25 -07002089 totalHits = 0
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002090 for term in range(len(searchTerms)):
2091 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep " + searchTerms[term]
2092 self.handle.sendline(cmd)
2093 self.handle.expect(":~")
2094 before = (self.handle.before).splitlines()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002095
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002096 count = [searchTerms[term],0]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002097
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002098 for line in before:
2099 if searchTerms[term] in line and "grep" not in line:
2100 count[1] += 1
2101 if before.index(line) > ( len(before) - 7 ):
2102 logLines[term].append(line)
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002103
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002104 main.log.info( str(count[0]) + ": " + str(count[1]) )
2105 if term == len(searchTerms)-1:
2106 print("\n")
cameron@onlab.us2e166212015-05-19 14:28:25 -07002107 totalHits += int(count[1])
2108
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002109 if outputMode != "s" and outputMode != "S":
2110 outputString = ""
2111 for i in logLines:
2112 outputString = i[0] + ": \n"
2113 for x in range(1,len(i)):
2114 outputString += ( i[x] + "\n" )
2115
2116 if outputString != (i[0] + ": \n"):
2117 main.log.info(outputString)
2118
2119 main.log.info("================================================================\n")
Hari Krishnabe4b97b2015-07-15 12:19:43 -07002120 return totalHits
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002121
2122 def copyMininetFile( self, fileName, localPath, userName, ip,
2123 mnPath='~/mininet/custom/', timeout = 60 ):
2124 """
2125 Description:
2126 Copy mininet topology file from dependency folder in the test folder
2127 and paste it to the mininet machine's mininet/custom folder
2128 Required:
2129 fileName - Name of the topology file to copy
2130 localPath - File path of the mininet topology file
2131 userName - User name of the mininet machine to send the file to
2132 ip - Ip address of the mininet machine
2133 Optional:
2134 mnPath - of the mininet directory to send the file to
2135 Return:
2136 Return main.TRUE if successfully copied the file otherwise
2137 return main.FALSE
2138 """
2139
2140 try:
2141 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2142 str( ip ) + ":" + mnPath + fileName
2143
2144 self.handle.sendline( "" )
2145 self.handle.expect( "\$" )
2146
2147 main.log.info( self.name + ": Execute: " + cmd )
2148
2149 self.handle.sendline( cmd )
2150
2151 i = self.handle.expect( [ 'No such file',
2152 "100%",
2153 pexpect.TIMEOUT ] )
2154
2155 if i == 0:
2156 main.log.error( self.name + ": File " + fileName +
2157 " does not exist!" )
2158 return main.FALSE
2159
2160 if i == 1:
2161 main.log.info( self.name + ": File " + fileName +
2162 " has been copied!" )
2163 self.handle.sendline( "" )
2164 self.handle.expect( "\$" )
2165 return main.TRUE
2166
2167 except pexpect.EOF:
2168 main.log.error( self.name + ": EOF exception found" )
2169 main.log.error( self.name + ": " + self.handle.before )
2170 main.cleanup()
2171 main.exit()
2172 except pexpect.TIMEOUT:
2173 main.log.error( self.name + ": TIMEOUT exception found" )
2174 main.log.error( self.name + ": " + self.handle.before )
2175 main.cleanup()
2176 main.exit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002177
2178 def jvmSet(self, memory=8):
2179
2180 import os
2181
2182 homeDir = os.path.expanduser('~')
2183 filename = "/onos/tools/package/bin/onos-service"
2184
2185 serviceConfig = open(homeDir + filename, 'w+')
2186 serviceConfig.write("#!/bin/bash\n ")
2187 serviceConfig.write("#------------------------------------- \n ")
2188 serviceConfig.write("# Starts ONOS Apache Karaf container\n ")
2189 serviceConfig.write("#------------------------------------- \n ")
2190 serviceConfig.write("#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n ")
2191 serviceConfig.write("""export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str(memory) + "G -Xmx" + str(memory) + """G}" \n """)
2192 serviceConfig.write("[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n")
2193 serviceConfig.write("""${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """)
2194 serviceConfig.close()
2195
2196 def createDBFile(self, testData):
2197
2198 filename = main.TEST + "DB"
2199 DBString = ""
2200
2201 for item in testData:
2202 if type(item) is string:
2203 item = "'" + item + "'"
2204 if testData.index(item) < len(testData-1):
2205 item += ","
2206 DBString += str(item)
2207
2208 DBFile = open(filename, "a")
2209 DBFile.write(DBString)
2210 DBFile.close()
2211
2212 def verifySummary(self, ONOSIp,*deviceCount):
2213
2214 self.handle.sendline("onos " + ONOSIp + " summary")
2215 self.handle.expect(":~")
2216
2217 summaryStr = self.handle.before
2218 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2219
2220 #passed = "SCC(s)=1" in summaryStr
2221 #if deviceCount:
2222 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
2223
2224
2225 if "SCC(s)=1," in summaryStr:
2226 passed = True
2227 print("Summary is verifed")
2228 else:
2229 print("Summary failed")
2230
2231 if deviceCount:
2232 print" ============================="
2233 checkStr = "devices=" + str(deviceCount[0]) + ","
2234 print "Checkstr: " + checkStr
2235 if checkStr not in summaryStr:
2236 passed = False
2237 print("Device count failed")
2238 else:
2239 print "device count verified"
2240
2241 return passed