blob: 8a87a49812e7d571d9e210a337eb31cb6d0ff363 [file] [log] [blame]
Jon Hall05b2b432014-10-08 19:53:25 -04001#!/usr/bin/env python
andrewonlabe8e56fd2014-10-09 17:12:44 -04002
kelvin8ec71442015-01-15 16:57:00 -08003"""
4This driver interacts with ONOS bench, the OSGi platform
5that configures the ONOS nodes. ( aka ONOS-next )
andrewonlabe8e56fd2014-10-09 17:12:44 -04006
kelvin8ec71442015-01-15 16:57:00 -08007Please follow the coding style demonstrated by existing
andrewonlabe8e56fd2014-10-09 17:12:44 -04008functions and document properly.
9
10If you are a contributor to the driver, please
11list your email here for future contact:
12
13jhall@onlab.us
14andrew@onlab.us
15
16OCT 9 2014
17
kelvin8ec71442015-01-15 16:57:00 -080018"""
andrewonlab7735d852014-10-09 13:02:47 -040019import sys
Jon Hall05b2b432014-10-08 19:53:25 -040020import time
21import pexpect
kelvin-onlaba4074292015-07-09 15:19:49 -070022import os
andrewonlab7735d852014-10-09 13:02:47 -040023import os.path
pingping-lin6d23d9e2015-02-02 16:54:24 -080024from requests.models import Response
kelvin8ec71442015-01-15 16:57:00 -080025sys.path.append( "../" )
Jon Hall05b2b432014-10-08 19:53:25 -040026from drivers.common.clidriver import CLI
27
Jon Hall05b2b432014-10-08 19:53:25 -040028
kelvin8ec71442015-01-15 16:57:00 -080029class OnosDriver( CLI ):
Jon Hall05b2b432014-10-08 19:53:25 -040030
kelvin8ec71442015-01-15 16:57:00 -080031 def __init__( self ):
32 """
33 Initialize client
34 """
Jon Hallefbd9792015-03-05 16:11:36 -080035 self.name = None
36 self.home = None
37 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080038 super( CLI, self ).__init__()
39
40 def connect( self, **connectargs ):
41 """
Jon Hall05b2b432014-10-08 19:53:25 -040042 Creates ssh handle for ONOS "bench".
kelvin-onlaba4074292015-07-09 15:19:49 -070043 NOTE:
44 The ip_address would come from the topo file using the host tag, the
45 value can be an environment variable as well as a "localhost" to get
46 the ip address needed to ssh to the "bench"
kelvin8ec71442015-01-15 16:57:00 -080047 """
Jon Hall05b2b432014-10-08 19:53:25 -040048 try:
49 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080050 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us3b087132015-03-11 15:00:08 -070051 self.home = "~/onos"
Jon Hall05b2b432014-10-08 19:53:25 -040052 for key in self.options:
53 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080054 self.home = self.options[ 'home' ]
Jon Hall05b2b432014-10-08 19:53:25 -040055 break
Jon Hall274b6642015-02-17 11:57:17 -080056 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070057 self.home = "~/onos"
Jon Hall21270ac2015-02-16 17:59:55 -080058
kelvin8ec71442015-01-15 16:57:00 -080059 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070060
61 for key in self.options:
62 if key == "nodes":
63 # Maximum number of ONOS nodes to run
64 self.maxNodes = int( self.options[ 'nodes' ] )
65 break
66 self.maxNodes = None
67
68
69 # Grabs all OC environment variables
70 self.onosIps = {} # Dictionary of all possible ONOS ip
71
72 try:
73 if self.maxNodes:
74 main.log.info( self.name + ": Creating cluster data with " +
75 str( self.maxNodes ) + " maximum number" +
76 " of nodes" )
77
78 for i in range( self.maxNodes ):
79 envString = "OC" + str( i + 1 )
80 self.onosIps[ envString ] = os.getenv( envString )
81
82 if not self.onosIps:
83 main.log.info( "Could not read any environment variable"
84 + " please load a cell file with all" +
85 " onos IP" )
86 else:
87 main.log.info( self.name + ": Found " +
88 str( self.onosIps.values() ) +
89 " ONOS IPs" )
90
91 except KeyError:
92 main.log.info( "Invalid environment variable" )
93 except Exception as inst:
94 main.log.error( "Uncaught exception: " + str( inst ) )
95
96 try:
97 if os.getenv( str( self.ip_address ) ) != None:
98 self.ip_address = os.getenv( str( self.ip_address ) )
99 else:
100 main.log.info( self.name +
101 ": Trying to connect to " +
102 self.ip_address )
103
104 except KeyError:
105 main.log.info( "Invalid host name," +
106 " connecting to local host instead" )
107 self.ip_address = 'localhost'
108 except Exception as inst:
109 main.log.error( "Uncaught exception: " + str( inst ) )
110
kelvin8ec71442015-01-15 16:57:00 -0800111 self.handle = super( OnosDriver, self ).connect(
112 user_name=self.user_name,
kelvin-onlab08679eb2015-01-21 16:11:48 -0800113 ip_address=self.ip_address,
kelvin-onlabd3b64892015-01-20 13:26:24 -0800114 port=self.port,
115 pwd=self.pwd,
116 home=self.home )
Jon Hall05b2b432014-10-08 19:53:25 -0400117
kelvin8ec71442015-01-15 16:57:00 -0800118 self.handle.sendline( "cd " + self.home )
119 self.handle.expect( "\$" )
kelvin-onlaba4074292015-07-09 15:19:49 -0700120
Jon Hall05b2b432014-10-08 19:53:25 -0400121 if self.handle:
122 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800123 else:
124 main.log.info( "NO ONOS HANDLE" )
Jon Hall05b2b432014-10-08 19:53:25 -0400125 return main.FALSE
kelvin-onlaba4074292015-07-09 15:19:49 -0700126
Jon Hall05b2b432014-10-08 19:53:25 -0400127 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800128 main.log.error( self.name + ": EOF exception found" )
129 main.log.error( self.name + ": " + self.handle.before )
Jon Hall05b2b432014-10-08 19:53:25 -0400130 main.cleanup()
131 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800132 except Exception:
133 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall05b2b432014-10-08 19:53:25 -0400134 main.cleanup()
135 main.exit()
136
kelvin8ec71442015-01-15 16:57:00 -0800137 def disconnect( self ):
138 """
Jon Hall05b2b432014-10-08 19:53:25 -0400139 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800140 """
Jon Halld61331b2015-02-17 16:35:47 -0800141 response = main.TRUE
Jon Hall05b2b432014-10-08 19:53:25 -0400142 try:
Jon Hall61282e32015-03-19 11:34:11 -0700143 if self.handle:
144 self.handle.sendline( "" )
145 self.handle.expect( "\$" )
146 self.handle.sendline( "exit" )
147 self.handle.expect( "closed" )
Jon Hall05b2b432014-10-08 19:53:25 -0400148 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800149 main.log.error( self.name + ": EOF exception found" )
150 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700151 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700152 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700153 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800154 except Exception:
155 main.log.exception( self.name + ": Connection failed to the host" )
Jon Hall05b2b432014-10-08 19:53:25 -0400156 response = main.FALSE
157 return response
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400158
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400159 def getEpochMs( self ):
160 """
161 Returns milliseconds since epoch
162
163 When checking multiple nodes in a for loop,
164 around a hundred milliseconds of difference (ascending) is
165 generally acceptable due to calltime of the function.
166 Few seconds, however, is not and it means clocks
167 are off sync.
168 """
169 try:
170 self.handle.sendline( 'date +%s.%N' )
171 self.handle.expect( 'date \+\%s\.\%N' )
172 self.handle.expect( '\$' )
173 epochMs = self.handle.before
174 return epochMs
175 except Exception:
176 main.log.exception( 'Uncaught exception getting epoch time' )
177 main.cleanup()
178 main.exit()
179
pingping-lin57a56ce2015-05-20 16:43:48 -0700180 def onosPackage( self, opTimeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800181 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400182 Produce a self-contained tar.gz file that can be deployed
kelvin8ec71442015-01-15 16:57:00 -0800183 and executed on any platform with Java 7 JRE.
184 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400185 try:
kelvin8ec71442015-01-15 16:57:00 -0800186 self.handle.sendline( "onos-package" )
187 self.handle.expect( "onos-package" )
pingping-lin57a56ce2015-05-20 16:43:48 -0700188 self.handle.expect( "tar.gz", opTimeout )
kelvin8ec71442015-01-15 16:57:00 -0800189 handle = str( self.handle.before )
190 main.log.info( "onos-package command returned: " +
191 handle )
192 # As long as the sendline does not time out,
193 # return true. However, be careful to interpret
194 # the results of the onos-package command return
andrewonlab0748d2a2014-10-09 13:24:17 -0400195 return main.TRUE
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400196
andrewonlab7735d852014-10-09 13:02:47 -0400197 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800198 main.log.error( self.name + ": EOF exception found" )
199 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800200 except Exception:
201 main.log.exception( "Failed to package ONOS" )
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400202 main.cleanup()
203 main.exit()
204
kelvin-onlabd3b64892015-01-20 13:26:24 -0800205 def onosBuild( self ):
kelvin8ec71442015-01-15 16:57:00 -0800206 """
andrewonlab8790abb2014-11-06 13:51:54 -0500207 Use the pre defined script to build onos via mvn
kelvin8ec71442015-01-15 16:57:00 -0800208 """
andrewonlab8790abb2014-11-06 13:51:54 -0500209 try:
kelvin8ec71442015-01-15 16:57:00 -0800210 self.handle.sendline( "onos-build" )
211 self.handle.expect( "onos-build" )
212 i = self.handle.expect( [
kelvin-onlabd3b64892015-01-20 13:26:24 -0800213 "BUILD SUCCESS",
214 "ERROR",
215 "BUILD FAILED" ],
216 timeout=120 )
kelvin8ec71442015-01-15 16:57:00 -0800217 handle = str( self.handle.before )
andrewonlab8790abb2014-11-06 13:51:54 -0500218
kelvin8ec71442015-01-15 16:57:00 -0800219 main.log.info( "onos-build command returned: " +
220 handle )
andrewonlab8790abb2014-11-06 13:51:54 -0500221
222 if i == 0:
223 return main.TRUE
224 else:
225 return handle
226
227 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800228 main.log.error( self.name + ": EOF exception found" )
229 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800230 except Exception:
231 main.log.exception( "Failed to build ONOS" )
andrewonlab8790abb2014-11-06 13:51:54 -0500232 main.cleanup()
233 main.exit()
234
shahshreya9f531fe2015-06-10 12:03:51 -0700235 def cleanInstall( self, skipTest=False, mciTimeout=600 ):
kelvin8ec71442015-01-15 16:57:00 -0800236 """
237 Runs mvn clean install in the root of the ONOS directory.
238 This will clean all ONOS artifacts then compile each module
shahshreya9f531fe2015-06-10 12:03:51 -0700239 Optional:
240 skipTest - Does "-DskipTests -Dcheckstyle.skip -U -T 1C" which
241 skip the test. This will make the building faster.
242 Disregarding the credibility of the build
kelvin8ec71442015-01-15 16:57:00 -0800243 Returns: main.TRUE on success
Jon Hallde9d9aa2014-10-08 20:36:02 -0400244 On Failure, exits the test
kelvin8ec71442015-01-15 16:57:00 -0800245 """
Jon Hallde9d9aa2014-10-08 20:36:02 -0400246 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800247 main.log.info( "Running 'mvn clean install' on " +
248 str( self.name ) +
kelvin8ec71442015-01-15 16:57:00 -0800249 ". This may take some time." )
250 self.handle.sendline( "cd " + self.home )
251 self.handle.expect( "\$" )
Jon Hallea7818b2014-10-09 14:30:59 -0400252
kelvin8ec71442015-01-15 16:57:00 -0800253 self.handle.sendline( "" )
254 self.handle.expect( "\$" )
shahshreya9f531fe2015-06-10 12:03:51 -0700255
256 if not skipTest:
257 self.handle.sendline( "mvn clean install" )
258 self.handle.expect( "mvn clean install" )
259 else:
260 self.handle.sendline( "mvn clean install -DskipTests" +
261 " -Dcheckstyle.skip -U -T 1C" )
262 self.handle.expect( "mvn clean install -DskipTests" +
263 " -Dcheckstyle.skip -U -T 1C" )
kelvin8ec71442015-01-15 16:57:00 -0800264 while True:
265 i = self.handle.expect( [
Jon Hall274b6642015-02-17 11:57:17 -0800266 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
Jon Hallefbd9792015-03-05 16:11:36 -0800267 'Runtime\sEnvironment\sto\scontinue',
Jon Hallde9d9aa2014-10-08 20:36:02 -0400268 'BUILD\sFAILURE',
269 'BUILD\sSUCCESS',
Jon Halle94919c2015-03-23 11:42:57 -0700270 'onos\$', #TODO: fix this to be more generic?
Jon Hallde9d9aa2014-10-08 20:36:02 -0400271 'ONOS\$',
pingping-lin57a56ce2015-05-20 16:43:48 -0700272 pexpect.TIMEOUT ], mciTimeout )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400273 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800274 main.log.error( self.name + ":There is insufficient memory \
275 for the Java Runtime Environment to continue." )
276 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400277 main.cleanup()
278 main.exit()
279 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800280 main.log.error( self.name + ": Build failure!" )
281 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400282 main.cleanup()
283 main.exit()
284 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800285 main.log.info( self.name + ": Build success!" )
Jon Halle94919c2015-03-23 11:42:57 -0700286 elif i == 3 or i == 4:
kelvin8ec71442015-01-15 16:57:00 -0800287 main.log.info( self.name + ": Build complete" )
288 # Print the build time
Jon Hallf8ef52c2014-10-09 19:37:33 -0400289 for line in self.handle.before.splitlines():
290 if "Total time:" in line:
kelvin8ec71442015-01-15 16:57:00 -0800291 main.log.info( line )
292 self.handle.sendline( "" )
293 self.handle.expect( "\$", timeout=60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400294 return main.TRUE
Jon Halle94919c2015-03-23 11:42:57 -0700295 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800296 main.log.error(
297 self.name +
298 ": mvn clean install TIMEOUT!" )
299 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400300 main.cleanup()
301 main.exit()
302 else:
Jon Hall274b6642015-02-17 11:57:17 -0800303 main.log.error( self.name + ": unexpected response from " +
Jon Hallefbd9792015-03-05 16:11:36 -0800304 "mvn clean install" )
kelvin8ec71442015-01-15 16:57:00 -0800305 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400306 main.cleanup()
307 main.exit()
308 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800309 main.log.error( self.name + ": EOF exception found" )
310 main.log.error( self.name + ": " + self.handle.before )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400311 main.cleanup()
312 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800313 except Exception:
314 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400315 main.cleanup()
316 main.exit()
Jon Hallacabffd2014-10-09 12:36:53 -0400317
Jon Hall61282e32015-03-19 11:34:11 -0700318 def gitPull( self, comp1="", fastForward=True ):
kelvin8ec71442015-01-15 16:57:00 -0800319 """
Jon Hallacabffd2014-10-09 12:36:53 -0400320 Assumes that "git pull" works without login
Jon Hall47a93fb2015-01-06 16:46:06 -0800321
Jon Hall61282e32015-03-19 11:34:11 -0700322 If the fastForward boolean is set to true, only git pulls that can
323 be fast forwarded will be performed. IE if you have not local commits
324 in your branch.
325
Jon Hallacabffd2014-10-09 12:36:53 -0400326 This function will perform a git pull on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800327 If used as gitPull( "NODE" ) it will do git pull + NODE. This is
Jon Hallacabffd2014-10-09 12:36:53 -0400328 for the purpose of pulling from other nodes if necessary.
329
Jon Hall47a93fb2015-01-06 16:46:06 -0800330 Otherwise, this function will perform a git pull in the
Jon Hallacabffd2014-10-09 12:36:53 -0400331 ONOS repository. If it has any problems, it will return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -0800332 If it successfully does a gitPull, it will return a 1 ( main.TRUE )
Shreya Shahee15f6c2014-10-28 18:12:30 -0400333 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400334
kelvin8ec71442015-01-15 16:57:00 -0800335 """
Jon Hallacabffd2014-10-09 12:36:53 -0400336 try:
kelvin8ec71442015-01-15 16:57:00 -0800337 # main.log.info( self.name + ": Stopping ONOS" )
338 # self.stop()
339 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800340 self.handle.expect( self.home + "\$" )
Jon Hall61282e32015-03-19 11:34:11 -0700341 cmd = "git pull"
342 if comp1 != "":
343 cmd += ' ' + comp1
344 if fastForward:
345 cmd += ' ' + " --ff-only"
346 self.handle.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800347 i = self.handle.expect(
348 [
349 'fatal',
350 'Username\sfor\s(.*):\s',
351 '\sfile(s*) changed,\s',
352 'Already up-to-date',
353 'Aborting',
354 'You\sare\snot\scurrently\son\sa\sbranch',
Jon Hall274b6642015-02-17 11:57:17 -0800355 'You asked me to pull without telling me which branch you',
356 'Pull is not possible because you have unmerged files',
Jon Hall61282e32015-03-19 11:34:11 -0700357 'Please enter a commit message to explain why this merge',
358 'Found a swap file by the name',
359 'Please, commit your changes before you can merge.',
kelvin-onlabd3b64892015-01-20 13:26:24 -0800360 pexpect.TIMEOUT ],
361 timeout=300 )
kelvin8ec71442015-01-15 16:57:00 -0800362 # debug
kelvin-onlabd3b64892015-01-20 13:26:24 -0800363 # main.log.report( self.name +": DEBUG: \n"+
364 # "git pull response: " +
365 # str( self.handle.before ) + str( self.handle.after ) )
kelvin8ec71442015-01-15 16:57:00 -0800366 if i == 0:
Jon Hall61282e32015-03-19 11:34:11 -0700367 main.log.error( self.name + ": Git pull had some issue" )
368 output = self.handle.after
369 self.handle.expect( '\$' )
370 output += self.handle.before
371 main.log.warn( output )
Jon Hallacabffd2014-10-09 12:36:53 -0400372 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800373 elif i == 1:
374 main.log.error(
375 self.name +
376 ": Git Pull Asking for username. " )
Jon Hallacabffd2014-10-09 12:36:53 -0400377 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800378 elif i == 2:
379 main.log.info(
380 self.name +
381 ": Git Pull - pulling repository now" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800382 self.handle.expect( self.home + "\$", 120 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800383 # So that only when git pull is done, we do mvn clean compile
384 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800385 elif i == 3:
386 main.log.info( self.name + ": Git Pull - Already up to date" )
Jon Hall47a93fb2015-01-06 16:46:06 -0800387 return i
kelvin8ec71442015-01-15 16:57:00 -0800388 elif i == 4:
389 main.log.info(
390 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800391 ": Git Pull - Aborting..." +
392 "Are there conflicting git files?" )
Jon Hallacabffd2014-10-09 12:36:53 -0400393 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800394 elif i == 5:
395 main.log.info(
396 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800397 ": Git Pull - You are not currently " +
398 "on a branch so git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400399 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800400 elif i == 6:
401 main.log.info(
402 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800403 ": Git Pull - You have not configured an upstream " +
404 "branch to pull from. Git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400405 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800406 elif i == 7:
407 main.log.info(
408 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800409 ": Git Pull - Pull is not possible because " +
410 "you have unmerged files." )
Jon Hallacabffd2014-10-09 12:36:53 -0400411 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800412 elif i == 8:
Jon Hall61282e32015-03-19 11:34:11 -0700413 # NOTE: abandoning test since we can't reliably handle this
414 # there could be different default text editors and we
415 # also don't know if we actually want to make the commit
416 main.log.error( "Git pull resulted in a merge commit message" +
417 ". Exiting test!" )
418 main.cleanup()
419 main.exit()
420 elif i == 9: # Merge commit message but swap file exists
421 main.log.error( "Git pull resulted in a merge commit message" +
422 " but a swap file exists." )
423 try:
424 self.handle.send( 'A' ) # Abort
425 self.handle.expect( "\$" )
426 return main.ERROR
427 except Exception:
428 main.log.exception( "Couldn't exit editor prompt!")
429 main.cleanup()
430 main.exit()
431 elif i == 10: # In the middle of a merge commit
432 main.log.error( "Git branch is in the middle of a merge. " )
433 main.log.warn( self.handle.before + self.handle.after )
434 return main.ERROR
435 elif i == 11:
kelvin8ec71442015-01-15 16:57:00 -0800436 main.log.error( self.name + ": Git Pull - TIMEOUT" )
437 main.log.error(
438 self.name + " Response was: " + str(
439 self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400440 return main.ERROR
441 else:
kelvin8ec71442015-01-15 16:57:00 -0800442 main.log.error(
443 self.name +
444 ": Git Pull - Unexpected response, check for pull errors" )
Jon Hallacabffd2014-10-09 12:36:53 -0400445 return main.ERROR
446 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800447 main.log.error( self.name + ": EOF exception found" )
448 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400449 main.cleanup()
450 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800451 except Exception:
452 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400453 main.cleanup()
454 main.exit()
455
kelvin-onlabd3b64892015-01-20 13:26:24 -0800456 def gitCheckout( self, branch="master" ):
kelvin8ec71442015-01-15 16:57:00 -0800457 """
Jon Hallacabffd2014-10-09 12:36:53 -0400458 Assumes that "git pull" works without login
kelvin8ec71442015-01-15 16:57:00 -0800459
Jon Hallacabffd2014-10-09 12:36:53 -0400460 This function will perform a git git checkout on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800461 If used as gitCheckout( "branch" ) it will do git checkout
462 of the "branch".
Jon Hallacabffd2014-10-09 12:36:53 -0400463
464 Otherwise, this function will perform a git checkout of the master
kelvin8ec71442015-01-15 16:57:00 -0800465 branch of the ONOS repository. If it has any problems, it will return
466 main.ERROR.
467 If the branch was already the specified branch, or the git checkout was
Jon Hallacabffd2014-10-09 12:36:53 -0400468 successful then the function will return main.TRUE.
469
kelvin8ec71442015-01-15 16:57:00 -0800470 """
Jon Hallacabffd2014-10-09 12:36:53 -0400471 try:
kelvin8ec71442015-01-15 16:57:00 -0800472 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800473 self.handle.expect( self.home + "\$" )
Jon Hall274b6642015-02-17 11:57:17 -0800474 main.log.info( self.name +
475 ": Checking out git branch/ref: " + branch + "..." )
kelvin8ec71442015-01-15 16:57:00 -0800476 cmd = "git checkout " + branch
477 self.handle.sendline( cmd )
478 self.handle.expect( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800479 i = self.handle.expect(
Jon Hall274b6642015-02-17 11:57:17 -0800480 [ 'fatal',
Jon Hall61282e32015-03-19 11:34:11 -0700481 'Username for (.*): ',
482 'Already on \'',
Jon Hall7a8354f2015-06-10 15:37:00 -0700483 'Switched to (a new )?branch \'' + str( branch ),
Jon Hall274b6642015-02-17 11:57:17 -0800484 pexpect.TIMEOUT,
485 'error: Your local changes to the following files' +
Jon Hallefbd9792015-03-05 16:11:36 -0800486 'would be overwritten by checkout:',
Jon Hall274b6642015-02-17 11:57:17 -0800487 'error: you need to resolve your current index first',
488 "You are in 'detached HEAD' state.",
489 "HEAD is now at " ],
kelvin-onlabd3b64892015-01-20 13:26:24 -0800490 timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -0800491 if i == 0:
492 main.log.error(
493 self.name +
494 ": Git checkout had some issue..." )
495 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400496 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800497 elif i == 1:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800498 main.log.error(
499 self.name +
500 ": Git checkout asking for username." +
501 " Please configure your local git repository to be able " +
502 "to access your remote repository passwordlessly" )
Jon Hall274b6642015-02-17 11:57:17 -0800503 # TODO add support for authenticating
Jon Hallacabffd2014-10-09 12:36:53 -0400504 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800505 elif i == 2:
506 main.log.info(
507 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800508 ": Git Checkout %s : Already on this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800509 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800510 # main.log.info( "DEBUG: after checkout cmd = "+
511 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400512 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800513 elif i == 3:
514 main.log.info(
515 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800516 ": Git checkout %s - Switched to 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 == 4:
522 main.log.error( self.name + ": Git Checkout- TIMEOUT" )
523 main.log.error(
Jon Hall274b6642015-02-17 11:57:17 -0800524 self.name + " Response was: " + str( self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400525 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800526 elif i == 5:
527 self.handle.expect( "Aborting" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800528 main.log.error(
529 self.name +
530 ": Git checkout error: \n" +
Jon Hall274b6642015-02-17 11:57:17 -0800531 "Your local changes to the following files would" +
532 " be overwritten by checkout:" +
533 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800534 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500535 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800536 elif i == 6:
Jon Hall274b6642015-02-17 11:57:17 -0800537 main.log.error(
538 self.name +
539 ": Git checkout error: \n" +
540 "You need to resolve your current index first:" +
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
Jon Hall274b6642015-02-17 11:57:17 -0800544 elif i == 7:
545 main.log.info(
546 self.name +
547 ": Git checkout " + str( branch ) +
548 " - You are in 'detached HEAD' state. HEAD is now at " +
549 str( branch ) )
550 self.handle.expect( self.home + "\$" )
551 return main.TRUE
552 elif i == 8: # Already in detached HEAD on the specified commit
553 main.log.info(
554 self.name +
555 ": Git Checkout %s : Already on commit" % branch )
556 self.handle.expect( self.home + "\$" )
557 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400558 else:
kelvin8ec71442015-01-15 16:57:00 -0800559 main.log.error(
560 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800561 ": Git Checkout - Unexpected response, " +
562 "check for pull errors" )
kelvin8ec71442015-01-15 16:57:00 -0800563 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400564 return main.ERROR
565
566 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800567 main.log.error( self.name + ": EOF exception found" )
568 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400569 main.cleanup()
570 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800571 except Exception:
572 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400573 main.cleanup()
574 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400575
pingping-lin6d23d9e2015-02-02 16:54:24 -0800576 def getBranchName( self ):
pingping-linf30cf272015-05-29 15:54:07 -0700577 main.log.info( "self.home = " )
578 main.log.info( self.home )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800579 self.handle.sendline( "cd " + self.home )
pingping-lin9bf3d8f2015-05-29 16:05:28 -0700580 self.handle.expect( self.home + "\$" )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800581 self.handle.sendline( "git name-rev --name-only HEAD" )
582 self.handle.expect( "git name-rev --name-only HEAD" )
583 self.handle.expect( "\$" )
584
585 lines = self.handle.before.splitlines()
586 if lines[1] == "master":
587 return "master"
588 elif lines[1] == "onos-1.0":
589 return "onos-1.0"
590 else:
591 main.log.info( lines[1] )
592 return "unexpected ONOS branch for SDN-IP test"
593
kelvin-onlabd3b64892015-01-20 13:26:24 -0800594 def getVersion( self, report=False ):
kelvin8ec71442015-01-15 16:57:00 -0800595 """
Jon Hall274b6642015-02-17 11:57:17 -0800596 Writes the COMMIT number to the report to be parsed
Jon Hallefbd9792015-03-05 16:11:36 -0800597 by Jenkins data collector.
kelvin8ec71442015-01-15 16:57:00 -0800598 """
Jon Hall45ec0922014-10-10 19:33:49 -0400599 try:
kelvin8ec71442015-01-15 16:57:00 -0800600 self.handle.sendline( "" )
601 self.handle.expect( "\$" )
602 self.handle.sendline(
603 "cd " +
604 self.home +
Jon Hall274b6642015-02-17 11:57:17 -0800605 "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " +
606 " \"commit\" --color=never" )
kelvin8ec71442015-01-15 16:57:00 -0800607 # NOTE: for some reason there are backspaces inserted in this
608 # phrase when run from Jenkins on some tests
609 self.handle.expect( "never" )
610 self.handle.expect( "\$" )
611 response = ( self.name + ": \n" + str(
612 self.handle.before + self.handle.after ) )
613 self.handle.sendline( "cd " + self.home )
614 self.handle.expect( "\$" )
615 lines = response.splitlines()
Jon Hall45ec0922014-10-10 19:33:49 -0400616 for line in lines:
Jon Hallfd191202014-11-07 18:36:09 -0500617 print line
618 if report:
pingping-lin763ee042015-05-20 17:45:30 -0700619 main.log.wiki( "<blockquote>" )
kelvin8ec71442015-01-15 16:57:00 -0800620 for line in lines[ 2:-1 ]:
621 # Bracket replacement is for Wiki-compliant
622 # formatting. '<' or '>' are interpreted
623 # as xml specific tags that cause errors
624 line = line.replace( "<", "[" )
625 line = line.replace( ">", "]" )
pingping-lin763ee042015-05-20 17:45:30 -0700626 #main.log.wiki( "\t" + line )
627 main.log.wiki( line + "<br /> " )
628 main.log.summary( line )
629 main.log.wiki( "</blockquote>" )
630 main.log.summary("\n")
kelvin8ec71442015-01-15 16:57:00 -0800631 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400632 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800633 main.log.error( self.name + ": EOF exception found" )
634 main.log.error( self.name + ": " + self.handle.before )
Jon Hall45ec0922014-10-10 19:33:49 -0400635 main.cleanup()
636 main.exit()
Jon Hall368769f2014-11-19 15:43:35 -0800637 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800638 main.log.error( self.name + ": TIMEOUT exception found" )
639 main.log.error( self.name + ": " + self.handle.before )
Jon Hall368769f2014-11-19 15:43:35 -0800640 main.cleanup()
641 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800642 except Exception:
643 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall45ec0922014-10-10 19:33:49 -0400644 main.cleanup()
645 main.exit()
646
kelvin-onlabd3b64892015-01-20 13:26:24 -0800647 def createCellFile( self, benchIp, fileName, mnIpAddrs,
kelvin-onlaba4074292015-07-09 15:19:49 -0700648 appString, onosIpAddrs ):
kelvin8ec71442015-01-15 16:57:00 -0800649 """
andrewonlab94282092014-10-10 13:00:11 -0400650 Creates a cell file based on arguments
651 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800652 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400653 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800654 * File name of the cell file ( fileName )
655 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800656 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400657 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800658 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400659 - Must be passed in as last arguments
kelvin8ec71442015-01-15 16:57:00 -0800660
andrewonlab94282092014-10-10 13:00:11 -0400661 NOTE: Assumes cells are located at:
662 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800663 """
664 # Variable initialization
Jon Hallf57a5ef2015-07-07 17:56:16 -0700665 cellDirectory = os.environ["ONOS_ROOT"] + "/tools/test/cells/"
kelvin8ec71442015-01-15 16:57:00 -0800666 # We want to create the cell file in the dependencies directory
667 # of TestON first, then copy over to ONOS bench
kelvin-onlabd3b64892015-01-20 13:26:24 -0800668 tempDirectory = "/tmp/"
kelvin8ec71442015-01-15 16:57:00 -0800669 # Create the cell file in the directory for writing ( w+ )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800670 cellFile = open( tempDirectory + fileName, 'w+' )
kelvin8ec71442015-01-15 16:57:00 -0800671
cameron@onlab.us75900962015-03-30 13:22:49 -0700672 # App string is hardcoded environment variables
kelvin8ec71442015-01-15 16:57:00 -0800673 # That you may wish to use by default on startup.
cameron@onlab.us75900962015-03-30 13:22:49 -0700674 # Note that you may not want certain apps listed
kelvin8ec71442015-01-15 16:57:00 -0800675 # on here.
cameron@onlab.us75900962015-03-30 13:22:49 -0700676 appString = "export ONOS_APPS=" + appString
kelvin-onlabd3b64892015-01-20 13:26:24 -0800677 mnString = "export OCN="
kelvin-onlabf70fd542015-05-07 18:41:40 -0700678 if mnIpAddrs == "":
679 mnString = ""
kelvin-onlabd3b64892015-01-20 13:26:24 -0800680 onosString = "export OC"
681 tempCount = 1
kelvin8ec71442015-01-15 16:57:00 -0800682
kelvin-onlabd3b64892015-01-20 13:26:24 -0800683 # Create ONOSNIC ip address prefix
kelvin-onlaba4074292015-07-09 15:19:49 -0700684 tempOnosIp = str( onosIpAddrs[ 0 ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800685 tempList = []
686 tempList = tempOnosIp.split( "." )
kelvin8ec71442015-01-15 16:57:00 -0800687 # Omit last element of list to format for NIC
kelvin-onlabd3b64892015-01-20 13:26:24 -0800688 tempList = tempList[ :-1 ]
kelvin8ec71442015-01-15 16:57:00 -0800689 # Structure the nic string ip
kelvin-onlabd3b64892015-01-20 13:26:24 -0800690 nicAddr = ".".join( tempList ) + ".*"
691 onosNicString = "export ONOS_NIC=" + nicAddr
andrewonlab94282092014-10-10 13:00:11 -0400692
693 try:
kelvin8ec71442015-01-15 16:57:00 -0800694 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800695 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400696
kelvin-onlabd3b64892015-01-20 13:26:24 -0800697 for arg in onosIpAddrs:
698 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800699 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400700 # export OC1="10.128.20.11"
701 # export OC2="10.128.20.12"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800702 cellFile.write( onosString + str( tempCount ) +
703 "=" + "\"" + arg + "\"" + "\n" )
704 tempCount = tempCount + 1
kelvin8ec71442015-01-15 16:57:00 -0800705
kelvin-onlabd3b64892015-01-20 13:26:24 -0800706 cellFile.write( mnString + "\"" + mnIpAddrs + "\"" + "\n" )
cameron@onlab.us75900962015-03-30 13:22:49 -0700707 cellFile.write( appString + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800708 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400709
kelvin8ec71442015-01-15 16:57:00 -0800710 # We use os.system to send the command to TestON cluster
711 # to account for the case in which TestON is not located
712 # on the same cluster as the ONOS bench
713 # Note that even if TestON is located on the same cluster
714 # as ONOS bench, you must setup passwordless ssh
715 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800716 os.system( "scp " + tempDirectory + fileName +
717 " admin@" + benchIp + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400718
andrewonlab2a6c9342014-10-16 13:40:15 -0400719 return main.TRUE
720
andrewonlab94282092014-10-10 13:00:11 -0400721 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800722 main.log.error( self.name + ": EOF exception found" )
723 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -0400724 main.cleanup()
725 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800726 except Exception:
727 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -0400728 main.cleanup()
729 main.exit()
730
kelvin-onlabd3b64892015-01-20 13:26:24 -0800731 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800732 """
andrewonlab95ca1462014-10-09 14:04:24 -0400733 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800734 """
Hari Krishna03f530e2015-07-10 17:28:27 -0700735 import re
andrewonlab95ca1462014-10-09 14:04:24 -0400736 try:
737 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800738 main.log.error( "Must define cellname" )
andrewonlab95ca1462014-10-09 14:04:24 -0400739 main.cleanup()
740 main.exit()
741 else:
kelvin8ec71442015-01-15 16:57:00 -0800742 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800743 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800744 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400745 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800746 self.handle.expect(str(cellname))
kelvin-onlabd3b64892015-01-20 13:26:24 -0800747 handleBefore = self.handle.before
748 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800749 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800750 self.handle.sendline("")
751 self.handle.expect("\$")
kelvin-onlabd3b64892015-01-20 13:26:24 -0800752 handleMore = self.handle.before
andrewonlab95ca1462014-10-09 14:04:24 -0400753
Hari Krishna03f530e2015-07-10 17:28:27 -0700754 cell_result = handleBefore + handleAfter + handleMore
755 print cell_result
756 if( re.search( "No such cell", cell_result ) ):
757 main.log.error( "Cell call returned: " + handleBefore +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800758 handleAfter + handleMore )
Hari Krishna03f530e2015-07-10 17:28:27 -0700759 main.cleanup()
760 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400761 return main.TRUE
762
763 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800764 main.log.error( self.name + ": EOF exception found" )
765 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ca1462014-10-09 14:04:24 -0400766 main.cleanup()
767 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800768 except Exception:
769 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ca1462014-10-09 14:04:24 -0400770 main.cleanup()
771 main.exit()
772
kelvin-onlabd3b64892015-01-20 13:26:24 -0800773 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800774 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400775 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800776 """
777 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400778
andrewonlabc03bf6c2014-10-09 14:56:18 -0400779 try:
kelvin8ec71442015-01-15 16:57:00 -0800780 # Clean handle by sending empty and expecting $
781 self.handle.sendline( "" )
782 self.handle.expect( "\$" )
783 self.handle.sendline( "onos-verify-cell" )
784 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800785 handleBefore = self.handle.before
786 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800787 # Get the rest of the handle
788 self.handle.sendline( "" )
789 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800790 handleMore = self.handle.before
andrewonlabc03bf6c2014-10-09 14:56:18 -0400791
kelvin-onlabd3b64892015-01-20 13:26:24 -0800792 main.log.info( "Verify cell returned: " + handleBefore +
793 handleAfter + handleMore )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400794
795 return main.TRUE
Jon Halla5cb6172015-02-23 09:28:28 -0800796 except pexpect.ExceptionPexpect as e:
797 main.log.error( self.name + ": Pexpect exception found of type " +
798 str( type( e ) ) )
799 main.log.error ( e.get_trace() )
kelvin8ec71442015-01-15 16:57:00 -0800800 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400801 main.cleanup()
802 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800803 except Exception:
804 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400805 main.cleanup()
806 main.exit()
807
jenkins1e99e7b2015-04-02 18:15:39 -0700808 def onosCfgSet( self, ONOSIp, configName, configParam ):
809 """
810 Uses 'onos <node-ip> cfg set' to change a parameter value of an
811 application.
812
813 ex)
814 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
jenkins1e99e7b2015-04-02 18:15:39 -0700815 ONOSIp = '10.0.0.1'
816 configName = 'org.onosproject.myapp'
817 configParam = 'appSetting 1'
jenkins1e99e7b2015-04-02 18:15:39 -0700818 """
cameron@onlab.us78b89652015-07-08 15:21:03 -0700819 for i in range(5):
820 try:
821 cfgStr = ( "onos "+str(ONOSIp)+" cfg set "+
822 str(configName) + " " +
823 str(configParam)
824 )
jenkins1e99e7b2015-04-02 18:15:39 -0700825
cameron@onlab.us78b89652015-07-08 15:21:03 -0700826 self.handle.sendline( "" )
827 self.handle.expect( ":~" )
828 self.handle.sendline( cfgStr )
829 self.handle.expect("cfg set")
830 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700831
cameron@onlab.us78b89652015-07-08 15:21:03 -0700832 paramValue = configParam.split(" ")[1]
833 paramName = configParam.split(" ")[0]
834
835 checkStr = ( "onos " + str(ONOSIp) + """ cfg get " """ + str(configName) + " " + paramName + """ " """)
jenkins1e99e7b2015-04-02 18:15:39 -0700836
cameron@onlab.us78b89652015-07-08 15:21:03 -0700837 self.handle.sendline( checkStr )
838 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700839
cameron@onlab.us78b89652015-07-08 15:21:03 -0700840 if "value=" + paramValue + "," in self.handle.before:
841 main.log.info("cfg " + configName + " successfully set to " + configParam)
842 return main.TRUE
843
844 except pexpect.ExceptionPexpect as e:
845 main.log.error( self.name + ": Pexpect exception found of type " +
846 str( type( e ) ) )
847 main.log.error ( e.get_trace() )
848 main.log.error( self.name + ": " + self.handle.before )
849 main.cleanup()
850 main.exit()
851 except Exception:
852 main.log.exception( self.name + ": Uncaught exception!" )
853 main.cleanup()
854 main.exit()
855
856 time.sleep(5)
857
858 main.log.error("CFG SET FAILURE: " + configName + " " + configParam )
859 main.ONOSbench.handle.sendline("onos $OC1 cfg get")
860 main.ONOSbench.handle.expect("\$")
861 print main.ONOSbench.handle.before
862 main.ONOSbench.logReport( ONOSIp, ["ERROR","WARN","EXCEPT"], "d")
863 return main.FALSE
864
865
kelvin-onlabd3b64892015-01-20 13:26:24 -0800866 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800867 """
andrewonlab05e362f2014-10-10 00:40:57 -0400868 Uses 'onos' command to send various ONOS CLI arguments.
869 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800870 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400871 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800872
873 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400874 CLI commands for ONOS. Try to use this function first
875 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800876 function.
877 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400878 by starting onos, and typing in 'onos' to enter the
879 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800880 available commands.
881 """
andrewonlab05e362f2014-10-10 00:40:57 -0400882 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800883 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800884 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400885 return main.FALSE
886 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800887 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400888 return main.FALSE
889
kelvin8ec71442015-01-15 16:57:00 -0800890 cmdstr = str( cmdstr )
891 self.handle.sendline( "" )
892 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400893
kelvin-onlabd3b64892015-01-20 13:26:24 -0800894 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800895 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400896
kelvin-onlabd3b64892015-01-20 13:26:24 -0800897 handleBefore = self.handle.before
Shreya Shaha73aaad2014-10-27 18:03:09 -0400898 print "handle_before = ", self.handle.before
kelvin-onlabd3b64892015-01-20 13:26:24 -0800899 # handleAfter = str( self.handle.after )
Jon Hall47a93fb2015-01-06 16:46:06 -0800900
kelvin8ec71442015-01-15 16:57:00 -0800901 # self.handle.sendline( "" )
902 # self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800903 # handleMore = str( self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400904
kelvin8ec71442015-01-15 16:57:00 -0800905 main.log.info( "Command sent successfully" )
andrewonlab05e362f2014-10-10 00:40:57 -0400906
kelvin8ec71442015-01-15 16:57:00 -0800907 # Obtain return handle that consists of result from
908 # the onos command. The string may need to be
909 # configured further.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800910 # returnString = handleBefore + handleAfter
911 returnString = handleBefore
912 print "return_string = ", returnString
913 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400914
915 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800916 main.log.error( self.name + ": EOF exception found" )
917 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400918 main.cleanup()
919 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800920 except Exception:
921 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab05e362f2014-10-10 00:40:57 -0400922 main.cleanup()
923 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400924
kelvin-onlabd3b64892015-01-20 13:26:24 -0800925 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800926 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400927 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800928 If -f option is provided, it also forces an uninstall.
929 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400930 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800931 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400932 files to certain onos nodes
933
934 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800935 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400936 try:
andrewonlab114768a2014-11-14 12:44:44 -0500937 if options:
kelvin8ec71442015-01-15 16:57:00 -0800938 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500939 else:
kelvin8ec71442015-01-15 16:57:00 -0800940 self.handle.sendline( "onos-install " + node )
941 self.handle.expect( "onos-install " )
942 # NOTE: this timeout may need to change depending on the network
943 # and size of ONOS
944 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800945 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800946 "ONOS\sis\salready\sinstalled",
947 pexpect.TIMEOUT ], timeout=60 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400948
Jon Hall7993bfc2014-10-09 16:30:14 -0400949 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800950 main.log.warn( "Network is unreachable" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400951 return main.FALSE
952 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800953 main.log.info(
954 "ONOS was installed on " +
955 node +
956 " and started" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400957 return main.TRUE
andrewonlabd9a73a72014-11-14 17:28:21 -0500958 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800959 main.log.info( "ONOS is already installed on " + node )
andrewonlabd9a73a72014-11-14 17:28:21 -0500960 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800961 elif i == 3:
962 main.log.info(
963 "Installation of ONOS on " +
964 node +
965 " timed out" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400966 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400967
968 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800969 main.log.error( self.name + ": EOF exception found" )
970 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400971 main.cleanup()
972 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800973 except Exception:
974 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400975 main.cleanup()
976 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400977
kelvin-onlabd3b64892015-01-20 13:26:24 -0800978 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800979 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400980 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400981 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800982 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400983 try:
kelvin8ec71442015-01-15 16:57:00 -0800984 self.handle.sendline( "" )
985 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800986 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800987 " start" )
988 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -0400989 "Job\sis\salready\srunning",
990 "start/running",
991 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800992 pexpect.TIMEOUT ], timeout=120 )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400993
994 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800995 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400996 return main.TRUE
997 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800998 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400999 return main.TRUE
1000 else:
kelvin8ec71442015-01-15 16:57:00 -08001001 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001002 main.cleanup()
1003 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001004 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001005 main.log.error( self.name + ": EOF exception found" )
1006 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001007 main.cleanup()
1008 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001009 except Exception:
1010 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001011 main.cleanup()
1012 main.exit()
1013
kelvin-onlabd3b64892015-01-20 13:26:24 -08001014 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001015 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001016 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001017 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001018 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001019 try:
kelvin8ec71442015-01-15 16:57:00 -08001020 self.handle.sendline( "" )
1021 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001022 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001023 " stop" )
1024 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -04001025 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -07001026 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -04001027 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -08001028 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2b30bd32014-10-09 16:48:55 -04001029
1030 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001031 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001032 return main.TRUE
1033 elif i == 1:
Jon Hall65844a32015-03-09 19:09:37 -07001034 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001035 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -04001036 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -07001037 elif i == 2:
1038 main.log.warn( "ONOS wasn't running" )
1039 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -04001040 else:
kelvin8ec71442015-01-15 16:57:00 -08001041 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001042 return main.FALSE
1043
1044 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001045 main.log.error( self.name + ": EOF exception found" )
1046 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -04001047 main.cleanup()
1048 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001049 except Exception:
1050 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001051 main.cleanup()
1052 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001053
kelvin-onlabd3b64892015-01-20 13:26:24 -08001054 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -08001055 """
andrewonlabc8d47972014-10-09 16:52:36 -04001056 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -08001057 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -04001058 if needed
kelvin8ec71442015-01-15 16:57:00 -08001059 """
andrewonlabc8d47972014-10-09 16:52:36 -04001060 try:
kelvin8ec71442015-01-15 16:57:00 -08001061 self.handle.sendline( "" )
pingping-lin763ee042015-05-20 17:45:30 -07001062 self.handle.expect( "\$", timeout=60 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001063 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001064 self.handle.expect( "\$" )
andrewonlabc8d47972014-10-09 16:52:36 -04001065
kelvin-onlabd3b64892015-01-20 13:26:24 -08001066 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
andrewonlab9dfd2082014-11-13 17:44:03 -05001067
kelvin8ec71442015-01-15 16:57:00 -08001068 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -04001069 return main.TRUE
1070
pingping-lin763ee042015-05-20 17:45:30 -07001071 except pexpect.TIMEOUT:
1072 main.log.exception( self.name + ": Timeout in onosUninstall" )
1073 return main.FALSE
andrewonlabc8d47972014-10-09 16:52:36 -04001074 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001075 main.log.error( self.name + ": EOF exception found" )
1076 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -04001077 main.cleanup()
1078 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001079 except Exception:
1080 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc8d47972014-10-09 16:52:36 -04001081 main.cleanup()
1082 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -04001083
kelvin-onlabd3b64892015-01-20 13:26:24 -08001084 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001085 """
andrewonlabaedc8332014-12-04 12:43:03 -05001086 Issues the command 'onos-die <node-ip>'
1087 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -08001088 """
andrewonlabaedc8332014-12-04 12:43:03 -05001089 try:
kelvin8ec71442015-01-15 16:57:00 -08001090 self.handle.sendline( "" )
1091 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001092 cmdStr = "onos-kill " + str( nodeIp )
1093 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001094 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -05001095 "Killing\sONOS",
1096 "ONOS\sprocess\sis\snot\srunning",
kelvin8ec71442015-01-15 16:57:00 -08001097 pexpect.TIMEOUT ], timeout=20 )
andrewonlabaedc8332014-12-04 12:43:03 -05001098 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001099 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001100 " was killed and stopped" )
andrewonlabaedc8332014-12-04 12:43:03 -05001101 return main.TRUE
1102 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001103 main.log.info( "ONOS process was not running" )
andrewonlabaedc8332014-12-04 12:43:03 -05001104 return main.FALSE
1105 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001106 main.log.error( self.name + ": EOF exception found" )
1107 main.log.error( self.name + ": " + self.handle.before )
andrewonlabaedc8332014-12-04 12:43:03 -05001108 main.cleanup()
1109 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001110 except Exception:
1111 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabaedc8332014-12-04 12:43:03 -05001112 main.cleanup()
1113 main.exit()
1114
kelvin-onlabd3b64892015-01-20 13:26:24 -08001115 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001116 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001117 Calls the command: 'onos-kill [<node-ip>]'
1118 "Remotely, and unceremoniously kills the ONOS instance running on
1119 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001120 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001121 try:
kelvin8ec71442015-01-15 16:57:00 -08001122 self.handle.sendline( "" )
1123 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001124 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001125 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -04001126 "\$",
1127 "No\sroute\sto\shost",
1128 "password:",
kelvin8ec71442015-01-15 16:57:00 -08001129 pexpect.TIMEOUT ], timeout=20 )
1130
andrewonlabe8e56fd2014-10-09 17:12:44 -04001131 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001132 main.log.info(
1133 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001135 return main.TRUE
1136 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001137 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001138 return main.FALSE
1139 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001140 main.log.info(
1141 "Passwordless login for host: " +
1142 str( nodeIp ) +
1143 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001144 return main.FALSE
1145 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001146 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001147 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001148
andrewonlabe8e56fd2014-10-09 17:12:44 -04001149 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001150 main.log.error( self.name + ": EOF exception found" )
1151 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001152 main.cleanup()
1153 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001154 except Exception:
1155 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001156 main.cleanup()
1157 main.exit()
1158
kelvin-onlabd3b64892015-01-20 13:26:24 -08001159 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001160 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001161 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001162 a cleaner environment.
1163
andrewonlab19fbdca2014-11-14 12:55:59 -05001164 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001165 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001166 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001167 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001168 try:
kelvin8ec71442015-01-15 16:57:00 -08001169 self.handle.sendline( "" )
1170 self.handle.expect( "\$" )
1171 self.handle.sendline( "onos-remove-raft-logs" )
1172 # Sometimes this command hangs
1173 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1174 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001175 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001176 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1177 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001178 if i == 1:
1179 return main.FALSE
shahshreya957feaa2015-03-23 16:08:29 -07001180 #self.handle.sendline( "" )
1181 #self.handle.expect( "\$" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001182 return main.TRUE
1183
1184 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001185 main.log.error( self.name + ": EOF exception found" )
1186 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -05001187 main.cleanup()
1188 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001189 except Exception:
1190 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001191 main.cleanup()
1192 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -05001193
kelvin-onlabd3b64892015-01-20 13:26:24 -08001194 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001195 """
1196 Calls the command 'onos-start-network [ <mininet-topo> ]
1197 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001198 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001199 cell."
andrewonlab94282092014-10-10 13:00:11 -04001200 * Specify mininet topology file name for mntopo
1201 * Topo files should be placed at:
1202 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001203
andrewonlab94282092014-10-10 13:00:11 -04001204 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001205 """
andrewonlab94282092014-10-10 13:00:11 -04001206 try:
1207 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001208 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001209 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001210
kelvin8ec71442015-01-15 16:57:00 -08001211 mntopo = str( mntopo )
1212 self.handle.sendline( "" )
1213 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -04001214
kelvin8ec71442015-01-15 16:57:00 -08001215 self.handle.sendline( "onos-start-network " + mntopo )
1216 self.handle.expect( "mininet>" )
1217 main.log.info( "Network started, entered mininet prompt" )
1218
1219 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001220
1221 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001222 main.log.error( self.name + ": EOF exception found" )
1223 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -04001224 main.cleanup()
1225 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001226 except Exception:
1227 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -04001228 main.cleanup()
1229 main.exit()
1230
Cameron Franke9c94fb02015-01-21 10:20:20 -08001231 def isup(self, node = "", timeout = 120):
kelvin8ec71442015-01-15 16:57:00 -08001232 """
1233 Run's onos-wait-for-start which only returns once ONOS is at run
Cameron Franke9c94fb02015-01-21 10:20:20 -08001234 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001235
Jon Hall7993bfc2014-10-09 16:30:14 -04001236 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001237 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001238 try:
Cameron Franke9c94fb02015-01-21 10:20:20 -08001239 self.handle.sendline("onos-wait-for-start " + node )
1240 self.handle.expect("onos-wait-for-start")
kelvin8ec71442015-01-15 16:57:00 -08001241 # NOTE: this timeout is arbitrary"
Cameron Franke9c94fb02015-01-21 10:20:20 -08001242 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001243 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001244 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001245 return main.TRUE
1246 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001247 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001248 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001249 main.log.error( "ONOS has not started yet" )
1250 self.handle.send( "\x03" ) # Control-C
1251 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001252 return main.FALSE
1253 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001254 main.log.error( self.name + ": EOF exception found" )
1255 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -04001256 main.cleanup()
1257 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001258 except Exception:
1259 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001260 main.cleanup()
1261 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001262
kelvin-onlabd3b64892015-01-20 13:26:24 -08001263 def pushTestIntentsShell(
1264 self,
1265 dpidSrc,
1266 dpidDst,
1267 numIntents,
1268 dirFile,
1269 onosIp,
1270 numMult="",
1271 appId="",
1272 report=True,
1273 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001274 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001275 Description:
kelvin8ec71442015-01-15 16:57:00 -08001276 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001277 better parallelize the results than the CLI
1278 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001279 * dpidSrc: specify source dpid
1280 * dpidDst: specify destination dpid
1281 * numIntents: specify number of intents to push
1282 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001283 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001284 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001285 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001286 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001287 """
1288 try:
1289 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001290 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001291 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001292 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001293 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001294 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001295
kelvin-onlabd3b64892015-01-20 13:26:24 -08001296 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1297 if not numMult:
1298 addIntents = addDpid + " " + str( numIntents )
1299 elif numMult:
1300 addIntents = addDpid + " " + str( numIntents ) + " " +\
1301 str( numMult )
1302 if appId:
1303 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001304 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001305 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001306
andrewonlabaedc8332014-12-04 12:43:03 -05001307 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001308 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001309 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001310 sendCmd = addApp + " &"
1311 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001312
kelvin-onlabd3b64892015-01-20 13:26:24 -08001313 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001314
1315 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001316 main.log.error( self.name + ": EOF exception found" )
1317 main.log.error( self.name + ": " + self.handle.before )
andrewonlabb66dfa12014-12-02 15:51:10 -05001318 main.cleanup()
1319 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001320 except Exception:
1321 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001322 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001323 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001324
kelvin-onlabd3b64892015-01-20 13:26:24 -08001325 def getTopology( self, topologyOutput ):
kelvin8ec71442015-01-15 16:57:00 -08001326 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001327 Definition:
1328 Loads a json topology output
1329 Return:
1330 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -08001331 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001332 import json
Jon Hall77f53ce2014-10-13 18:02:06 -04001333 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001334 # either onos:topology or 'topology' will work in CLI
1335 topology = json.loads(topologyOutput)
1336 print topology
Jon Hall77f53ce2014-10-13 18:02:06 -04001337 return topology
1338 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001339 main.log.error( self.name + ": EOF exception found" )
1340 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001341 main.cleanup()
1342 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001343 except Exception:
1344 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001345 main.cleanup()
1346 main.exit()
1347
kelvin-onlabd3b64892015-01-20 13:26:24 -08001348 def checkStatus(
1349 self,
1350 topologyResult,
1351 numoswitch,
1352 numolink,
1353 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001354 """
Jon Hallefbd9792015-03-05 16:11:36 -08001355 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001356 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001357 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08001358
Jon Hall77f53ce2014-10-13 18:02:06 -04001359 Params: ip = ip used for the onos cli
1360 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001361 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001362 logLevel = level to log to.
1363 Currently accepts 'info', 'warn' and 'report'
Jon Hall77f53ce2014-10-13 18:02:06 -04001364
1365
kelvin-onlabd3b64892015-01-20 13:26:24 -08001366 logLevel can
Jon Hall77f53ce2014-10-13 18:02:06 -04001367
Jon Hallefbd9792015-03-05 16:11:36 -08001368 Returns: main.TRUE if the number of switches and links are correct,
1369 main.FALSE if the number of switches and links is incorrect,
Jon Hall77f53ce2014-10-13 18:02:06 -04001370 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001371 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001372 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001373 topology = self.getTopology( topologyResult )
Jon Hall77f53ce2014-10-13 18:02:06 -04001374 if topology == {}:
1375 return main.ERROR
1376 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001377 # Is the number of switches is what we expected
shahshreya234a1682015-05-27 15:41:56 -07001378 devices = topology.get( 'devices', False )
1379 links = topology.get( 'links', False )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001380 if not devices or not links:
Jon Hall77f53ce2014-10-13 18:02:06 -04001381 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001382 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001383 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001384 linkCheck = ( int( links ) == int( numolink ) )
Jon Hallefbd9792015-03-05 16:11:36 -08001385 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08001386 # We expected the correct numbers
Jon Hall77f53ce2014-10-13 18:02:06 -04001387 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001388 + "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001389 result = main.TRUE
1390 else:
1391 output = output + \
Jon Hall274b6642015-02-17 11:57:17 -08001392 "The number of links and switches does not match " + \
1393 "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001394 result = main.FALSE
Jon Hallefbd9792015-03-05 16:11:36 -08001395 output = output + "\n ONOS sees %i devices" % int( devices )
1396 output = output + " (%i expected) " % int( numoswitch )
Jon Hall274b6642015-02-17 11:57:17 -08001397 output = output + "and %i links " % int( links )
1398 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001399 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001400 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001401 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001402 main.log.warn( output )
Jon Hall77f53ce2014-10-13 18:02:06 -04001403 else:
kelvin8ec71442015-01-15 16:57:00 -08001404 main.log.info( output )
1405 return result
Jon Hall77f53ce2014-10-13 18:02:06 -04001406 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001407 main.log.error( self.name + ": EOF exception found" )
1408 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001409 main.cleanup()
1410 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001411 except Exception:
1412 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001413 main.cleanup()
1414 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001415
kelvin-onlabd3b64892015-01-20 13:26:24 -08001416 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001417 """
andrewonlab970399c2014-11-07 13:09:32 -05001418 Capture all packet activity and store in specified
1419 directory/file
1420
1421 Required:
1422 * interface: interface to capture
1423 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001424 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001425 try:
1426 self.handle.sendline( "" )
1427 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001428
Jon Hallfebb1c72015-03-05 13:30:09 -08001429 self.handle.sendline( "tshark -i " + str( interface ) +
1430 " -t e -w " + str( dirFile ) + " &" )
1431 self.handle.sendline( "\r" )
1432 self.handle.expect( "Capturing on" )
1433 self.handle.sendline( "\r" )
1434 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001435
Jon Hallfebb1c72015-03-05 13:30:09 -08001436 main.log.info( "Tshark started capturing files on " +
1437 str( interface ) + " and saving to directory: " +
1438 str( dirFile ) )
1439 except pexpect.EOF:
1440 main.log.error( self.name + ": EOF exception found" )
1441 main.log.error( self.name + ": " + self.handle.before )
1442 main.cleanup()
1443 main.exit()
1444 except Exception:
1445 main.log.exception( self.name + ": Uncaught exception!" )
1446 main.cleanup()
1447 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001448
kelvin-onlabd3b64892015-01-20 13:26:24 -08001449 def runOnosTopoCfg( self, instanceName, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001450 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001451 On ONOS bench, run this command:
Jon Halle94919c2015-03-23 11:42:57 -07001452 {ONOS_HOME}/tools/test/bin/onos-topo-cfg $OC1 filename
kelvin-onlabd3b64892015-01-20 13:26:24 -08001453 which starts the rest and copies
1454 the json file to the onos instance
kelvin8ec71442015-01-15 16:57:00 -08001455 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001456 try:
kelvin8ec71442015-01-15 16:57:00 -08001457 self.handle.sendline( "" )
1458 self.handle.expect( "\$" )
Jon Halle94919c2015-03-23 11:42:57 -07001459 self.handle.sendline( "cd " + self.home + "/tools/test/bin" )
kelvin8ec71442015-01-15 16:57:00 -08001460 self.handle.expect( "/bin$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001461 cmd = "./onos-topo-cfg " + instanceName + " " + jsonFile
shahshreyae6c7cf42014-11-26 16:39:01 -08001462 print "cmd = ", cmd
kelvin8ec71442015-01-15 16:57:00 -08001463 self.handle.sendline( cmd )
1464 self.handle.expect( "\$" )
1465 self.handle.sendline( "cd ~" )
1466 self.handle.expect( "\$" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001467 return main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -08001468 except pexpect.EOF:
1469 main.log.error( self.name + ": EOF exception found" )
1470 main.log.error( self.name + ": " + self.handle.before )
1471 main.cleanup()
1472 main.exit()
1473 except Exception:
1474 main.log.exception( self.name + ": Uncaught exception!" )
1475 main.cleanup()
1476 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001477
jenkins1e99e7b2015-04-02 18:15:39 -07001478 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001479 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001480 Required:
kelvin8ec71442015-01-15 16:57:00 -08001481 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001482 * directory to store results
1483 Optional:
1484 * interface - default: eth0
jenkins1e99e7b2015-04-02 18:15:39 -07001485 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001486 Description:
1487 Uses tshark command to grep specific group of packets
1488 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001489 The timestamp is hardcoded to be in epoch
1490 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001491 try:
1492 self.handle.sendline( "" )
1493 self.handle.expect( "\$" )
1494 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001495 if grepOptions:
1496 grepStr = "grep "+str(grepOptions)
1497 else:
1498 grepStr = "grep"
1499
Jon Hallfebb1c72015-03-05 13:30:09 -08001500 self.handle.sendline(
1501 "tshark -i " +
1502 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001503 " -t e | " +
1504 grepStr + " --line-buffered \"" +
Jon Hallfebb1c72015-03-05 13:30:09 -08001505 str(grep) +
1506 "\" >" +
1507 directory +
1508 " &" )
1509 self.handle.sendline( "\r" )
1510 self.handle.expect( "Capturing on" )
1511 self.handle.sendline( "\r" )
1512 self.handle.expect( "\$" )
1513 except pexpect.EOF:
1514 main.log.error( self.name + ": EOF exception found" )
1515 main.log.error( self.name + ": " + self.handle.before )
1516 main.cleanup()
1517 main.exit()
1518 except Exception:
1519 main.log.exception( self.name + ": Uncaught exception!" )
1520 main.cleanup()
1521 main.exit()
1522
kelvin-onlabd3b64892015-01-20 13:26:24 -08001523 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001524 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001525 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001526 """
1527 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001528 try:
1529 self.execute( cmd="sudo rm /tmp/wireshark*" )
1530 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001531 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1532 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001533 self.handle.sendline( "" )
1534 main.log.info( "Tshark stopped" )
1535 except pexpect.EOF:
1536 main.log.error( self.name + ": EOF exception found" )
1537 main.log.error( self.name + ": " + self.handle.before )
1538 main.cleanup()
1539 main.exit()
1540 except Exception:
1541 main.log.exception( self.name + ": Uncaught exception!" )
1542 main.cleanup()
1543 main.exit()
1544
kelvin8ec71442015-01-15 16:57:00 -08001545 def ptpd( self, args ):
1546 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001547 Initiate ptp with user-specified args.
1548 Required:
1549 * args: specify string of args after command
1550 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001551 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001552 try:
kelvin8ec71442015-01-15 16:57:00 -08001553 self.handle.sendline( "sudo ptpd " + str( args ) )
1554 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001555 "Multiple",
1556 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001557 "\$" ] )
1558 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001559
andrewonlab0c38a4a2014-10-28 18:35:35 -04001560 if i == 0:
1561 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001562 main.log.info( "ptpd returned an error: " +
1563 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001564 return handle
1565 elif i == 1:
1566 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001567 main.log.error( "ptpd returned an error: " +
1568 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001569 return handle
1570 else:
1571 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001572
andrewonlab0c38a4a2014-10-28 18:35:35 -04001573 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001574 main.log.error( self.name + ": EOF exception found" )
1575 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001576 main.cleanup()
1577 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001578 except Exception:
1579 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001580 main.cleanup()
1581 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001582
kelvin-onlabd3b64892015-01-20 13:26:24 -08001583 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001584 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001585 """
1586 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001587 Current implementation of ONOS deletes its karaf
1588 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001589 you may want to use this function to capture
1590 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001591 Localtime will be attached to the filename
1592
1593 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001594 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001595 copy.
kelvin8ec71442015-01-15 16:57:00 -08001596 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001597 For copying multiple files, leave copyFileName
1598 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001599 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001600 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001601 ex ) /tmp/
1602 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001603 * copyFileName: If you want to rename the log
1604 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001605 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001606 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001607 try:
kelvin8ec71442015-01-15 16:57:00 -08001608 localtime = time.strftime( '%x %X' )
1609 localtime = localtime.replace( "/", "" )
1610 localtime = localtime.replace( " ", "_" )
1611 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001612 if destDir[ -1: ] != "/":
1613 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001614
kelvin-onlabd3b64892015-01-20 13:26:24 -08001615 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001616 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1617 str( destDir ) + str( copyFileName ) +
1618 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001619 self.handle.expect( "cp" )
1620 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001621 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001622 self.handle.sendline( "cp " + str( logToCopy ) +
1623 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001624 self.handle.expect( "cp" )
1625 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001626
kelvin8ec71442015-01-15 16:57:00 -08001627 return self.handle.before
1628
1629 except pexpect.EOF:
1630 main.log.error( "Copying files failed" )
1631 main.log.error( self.name + ": EOF exception found" )
1632 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001633 except Exception:
1634 main.log.exception( "Copying files failed" )
1635
Jon Hall16b72c42015-05-20 10:23:36 -07001636 def checkLogs( self, onosIp, restart=False):
kelvin8ec71442015-01-15 16:57:00 -08001637 """
Jon Hall94fd0472014-12-08 11:52:42 -08001638 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001639 If restart is True, use the old version of onos-check-logs which
1640 does not print the full stacktrace, but shows the entire log file,
1641 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001642 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001643 """
Jon Hall94fd0472014-12-08 11:52:42 -08001644 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001645 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001646 if restart:
1647 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001648 self.handle.sendline( cmd )
1649 self.handle.expect( cmd )
1650 self.handle.expect( "\$" )
Jon Hall94fd0472014-12-08 11:52:42 -08001651 response = self.handle.before
1652 return response
1653 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001654 main.log.error( "Lost ssh connection" )
1655 main.log.error( self.name + ": EOF exception found" )
1656 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001657 except Exception:
1658 main.log.exception( self.name + ": Uncaught exception!" )
1659 main.cleanup()
1660 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001661
kelvin-onlabd3b64892015-01-20 13:26:24 -08001662 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001663 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001664 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001665 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001666 try:
kelvin8ec71442015-01-15 16:57:00 -08001667 self.handle.sendline( "" )
1668 self.handle.expect( "\$" )
1669 self.handle.sendline( "onos-service " + str( node ) +
1670 " status" )
1671 i = self.handle.expect( [
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001672 "start/running",
1673 "stop/waiting",
kelvin8ec71442015-01-15 16:57:00 -08001674 pexpect.TIMEOUT ], timeout=120 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001675
1676 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001677 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001678 return main.TRUE
1679 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001680 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001681 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001682 main.cleanup()
1683 main.exit()
1684 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001685 main.log.error( self.name + ": EOF exception found" )
1686 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001687 main.cleanup()
1688 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001689 except Exception:
1690 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001691 main.cleanup()
1692 main.exit()
Jon Hall21270ac2015-02-16 17:59:55 -08001693
Jon Hall63604932015-02-26 17:09:50 -08001694 def setIpTables( self, ip, port='', action='add', packet_type='',
1695 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001696 """
Jon Hall21270ac2015-02-16 17:59:55 -08001697 Description:
1698 add or remove iptables rule to DROP (default) packets from
1699 specific IP and PORT
1700 Usage:
1701 * specify action ('add' or 'remove')
1702 when removing, pass in the same argument as you would add. It will
1703 delete that specific rule.
1704 * specify the ip to block
1705 * specify the destination port to block (defaults to all ports)
1706 * optional packet type to block (default tcp)
1707 * optional iptables rule (default DROP)
1708 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001709 * States boolean toggles adding all supported tcp states to the
1710 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001711 Returns:
1712 main.TRUE on success or
1713 main.FALSE if given invalid input or
1714 main.ERROR if there is an error in response from iptables
1715 WARNING:
1716 * This function uses root privilege iptables command which may result
1717 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001718 """
Jon Hall21270ac2015-02-16 17:59:55 -08001719 import time
1720
1721 # NOTE*********
1722 # The strict checking methods of this driver function is intentional
1723 # to discourage any misuse or error of iptables, which can cause
1724 # severe network errors
1725 # *************
1726
1727 # NOTE: Sleep needed to give some time for rule to be added and
1728 # registered to the instance. If you are calling this function
1729 # multiple times this sleep will prevent any errors.
1730 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001731 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001732 try:
1733 # input validation
1734 action_type = action.lower()
1735 rule = rule.upper()
1736 direction = direction.upper()
1737 if action_type != 'add' and action_type != 'remove':
1738 main.log.error( "Invalid action type. Use 'add' or "
1739 "'remove' table rule" )
1740 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1741 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1742 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1743 "'ACCEPT' or 'LOG' only." )
1744 if direction != 'INPUT' and direction != 'OUTPUT':
1745 # NOTE currently only supports rules INPUT and OUPTUT
1746 main.log.error( "Invalid rule. Valid directions are"
1747 " 'OUTPUT' or 'INPUT'" )
1748 return main.FALSE
1749 return main.FALSE
1750 return main.FALSE
1751 if action_type == 'add':
1752 # -A is the 'append' action of iptables
1753 actionFlag = '-A'
1754 elif action_type == 'remove':
1755 # -D is the 'delete' rule of iptables
1756 actionFlag = '-D'
1757 self.handle.sendline( "" )
1758 self.handle.expect( "\$" )
1759 cmd = "sudo iptables " + actionFlag + " " +\
1760 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001761 " -s " + str( ip )
Jon Hall63604932015-02-26 17:09:50 -08001762 # " -p " + str( packet_type ) +\
1763 if packet_type:
1764 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001765 if port:
1766 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001767 if states:
1768 cmd += " -m state --state="
1769 #FIXME- Allow user to configure which states to block
1770 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001771 cmd += " -j " + str( rule )
1772
1773 self.handle.sendline( cmd )
1774 self.handle.expect( "\$" )
1775 main.log.warn( self.handle.before )
1776
1777 info_string = "On " + str( self.name )
1778 info_string += " " + str( action_type )
1779 info_string += " iptable rule [ "
1780 info_string += " IP: " + str( ip )
1781 info_string += " Port: " + str( port )
1782 info_string += " Rule: " + str( rule )
1783 info_string += " Direction: " + str( direction ) + " ]"
1784 main.log.info( info_string )
1785 return main.TRUE
1786 except pexpect.TIMEOUT:
1787 main.log.exception( self.name + ": Timeout exception in "
1788 "setIpTables function" )
1789 return main.ERROR
1790 except pexpect.EOF:
1791 main.log.error( self.name + ": EOF exception found" )
1792 main.log.error( self.name + ": " + self.handle.before )
1793 main.cleanup()
1794 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001795 except Exception:
1796 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall21270ac2015-02-16 17:59:55 -08001797 main.cleanup()
1798 main.exit()
1799
Jon Hall0468b042015-02-19 19:08:21 -08001800 def detailed_status(self, log_filename):
Jon Hallefbd9792015-03-05 16:11:36 -08001801 """
Jon Hall0468b042015-02-19 19:08:21 -08001802 This method is used by STS to check the status of the controller
1803 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001804 """
Jon Hall0468b042015-02-19 19:08:21 -08001805 import re
1806 try:
1807 self.handle.sendline( "" )
1808 self.handle.expect( "\$" )
1809 self.handle.sendline( "cd " + self.home )
1810 self.handle.expect( "\$" )
1811 self.handle.sendline( "service onos status" )
1812 self.handle.expect( "\$" )
1813 response = self.handle.before
1814 if re.search( "onos start/running", response ):
1815 # onos start/running, process 10457
1816 return 'RUNNING'
1817 # FIXME: Implement this case
1818 # elif re.search( pattern, response ):
1819 # return 'STARTING'
1820 elif re.search( "onos stop/", response ):
1821 # onos stop/waiting
1822 # FIXME handle this differently?: onos stop/pre-stop
1823 return 'STOPPED'
1824 # FIXME: Implement this case
1825 # elif re.search( pattern, response ):
1826 # return 'FROZEN'
1827 else:
1828 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001829 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001830 main.log.warn( response )
1831 return 'ERROR', "Unknown response: %s" % response
1832 except pexpect.TIMEOUT:
1833 main.log.exception( self.name + ": Timeout exception in "
1834 "setIpTables function" )
1835 return 'ERROR', "Pexpect Timeout"
1836 except pexpect.EOF:
1837 main.log.error( self.name + ": EOF exception found" )
1838 main.log.error( self.name + ": " + self.handle.before )
1839 main.cleanup()
1840 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001841 except Exception:
1842 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall0468b042015-02-19 19:08:21 -08001843 main.cleanup()
1844 main.exit()
1845
andrew@onlab.us3b087132015-03-11 15:00:08 -07001846 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1847 '''
1848 Create/formats the LinkGraph.cfg file based on arguments
1849 -only creates a linear topology and connects islands
1850 -evenly distributes devices
1851 -must be called by ONOSbench
1852
1853 ONOSIpList - list of all of the node IPs to be used
1854
1855 deviceCount - number of switches to be assigned
1856 '''
1857 main.log.step("Creating link graph configuration file." )
1858 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
1859 tempFile = "/tmp/linkGraph.cfg"
1860
1861 linkGraph = open(tempFile, 'w+')
1862 linkGraph.write("# NullLinkProvider topology description (config file).\n")
1863 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
1864 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
1865
1866 clusterCount = len(ONOSIpList)
1867
1868 if type(deviceCount) is int or type(deviceCount) is str:
1869 deviceCount = int(deviceCount)
1870 switchList = [0]*(clusterCount+1)
1871 baselineSwitchCount = deviceCount/clusterCount
1872
1873 for node in range(1, clusterCount + 1):
1874 switchList[node] = baselineSwitchCount
1875
1876 for node in range(1, (deviceCount%clusterCount)+1):
1877 switchList[node] += 1
1878
1879 if type(deviceCount) is list:
1880 main.log.info("Using provided device distribution")
1881 switchList = [0]
1882 for i in deviceCount:
1883 switchList.append(int(i))
1884
1885 tempList = ['0']
1886 tempList.extend(ONOSIpList)
1887 ONOSIpList = tempList
1888
1889 myPort = 6
1890 lastSwitch = 0
1891 for node in range(1, clusterCount+1):
1892 if switchList[node] == 0:
1893 continue
1894
1895 linkGraph.write("graph " + ONOSIpList[node] + " {\n")
1896
1897 if node > 1:
1898 #connect to last device on previous node
1899 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
1900 linkGraph.write(line)
1901
1902 lastSwitch = 0
1903 for switch in range (0, switchList[node]-1):
1904 line = ""
1905 line = ("\t" + str(switch) + ":" + str(myPort))
1906 line += " -- "
1907 line += (str(switch+1) + ":" + str(myPort-1) + "\n")
1908 linkGraph.write(line)
1909 lastSwitch = switch+1
1910 lastIp = ONOSIpList[node]
1911
1912 #lastSwitch += 1
1913 if node < (clusterCount):
1914 #connect to first device on the next node
1915 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
1916 linkGraph.write(line)
1917
1918 linkGraph.write("}\n")
1919 linkGraph.close()
1920
1921 #SCP
1922 os.system( "scp " + tempFile + " admin@" + benchIp + ":" + linkGraphPath)
1923 main.log.info("linkGraph.cfg creation complete")
1924
cameron@onlab.us75900962015-03-30 13:22:49 -07001925 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001926
1927 '''
andrew@onlab.us3b087132015-03-11 15:00:08 -07001928 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
cameron@onlab.us75900962015-03-30 13:22:49 -07001929 deviceCount = number of switches to distribute, or list of values to use as custom distribution
1930 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 -07001931 '''
1932
cameron@onlab.us75900962015-03-30 13:22:49 -07001933 main.log.step("Configuring Null Device Provider" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07001934 clusterCount = len(ONOSIpList)
1935
cameron@onlab.us75900962015-03-30 13:22:49 -07001936 try:
1937
1938 if type(deviceCount) is int or type(deviceCount) is str:
1939 main.log.step("Creating device distribution")
1940 deviceCount = int(deviceCount)
1941 switchList = [0]*(clusterCount+1)
1942 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001943
cameron@onlab.us75900962015-03-30 13:22:49 -07001944 for node in range(1, clusterCount + 1):
1945 switchList[node] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001946
cameron@onlab.us75900962015-03-30 13:22:49 -07001947 for node in range(1, (deviceCount%clusterCount)+1):
1948 switchList[node] += 1
1949
1950 if type(deviceCount) is list:
1951 main.log.info("Using provided device distribution")
1952
1953 if len(deviceCount) == clusterCount:
1954 switchList = ['0']
1955 switchList.extend(deviceCount)
1956
1957 if len(deviceCount) == (clusterCount + 1):
1958 if deviceCount[0] == '0' or deviceCount[0] == 0:
1959 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001960
cameron@onlab.us75900962015-03-30 13:22:49 -07001961 assert len(switchList) == (clusterCount + 1)
1962
1963 except AssertionError:
1964 main.log.error( "Bad device/Ip list match")
1965 except TypeError:
1966 main.log.exception( self.name + ": Object not as expected" )
1967 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07001968 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001969 main.log.exception( self.name + ": Uncaught exception!" )
1970 main.cleanup()
1971 main.exit()
1972
andrew@onlab.us3b087132015-03-11 15:00:08 -07001973
1974 ONOSIp = [0]
1975 ONOSIp.extend(ONOSIpList)
1976
1977 devicesString = "devConfigs = "
1978 for node in range(1, len(ONOSIp)):
1979 devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
1980 if node < clusterCount:
1981 devicesString += (",")
cameron@onlab.us75900962015-03-30 13:22:49 -07001982
1983 try:
1984 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
1985 self.handle.expect(":~")
1986 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) )
1987 self.handle.expect(":~")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001988
cameron@onlab.us75900962015-03-30 13:22:49 -07001989 for i in range(10):
1990 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider")
1991 self.handle.expect(":~")
1992 verification = self.handle.before
1993 if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification:
1994 break
1995 else:
1996 time.sleep(1)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001997
cameron@onlab.us2cc8bf12015-04-02 14:12:30 -07001998 assert ("value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification
cameron@onlab.us75900962015-03-30 13:22:49 -07001999
2000 except AssertionError:
2001 main.log.error("Incorrect Config settings: " + verification)
Jon Hall77ba41c2015-04-06 10:25:40 -07002002 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002003 main.log.exception( self.name + ": Uncaught exception!" )
2004 main.cleanup()
2005 main.exit()
2006
cameron@onlab.usc80a8c82015-04-15 14:57:37 -07002007 def configNullLink( self,fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0):
andrew@onlab.us3b087132015-03-11 15:00:08 -07002008 '''
cameron@onlab.us75900962015-03-30 13:22:49 -07002009 fileName default is currently the same as the default on ONOS, specify alternate file if
2010 you want to use a different topology file than linkGraph.cfg
andrew@onlab.us3b087132015-03-11 15:00:08 -07002011 '''
2012
andrew@onlab.us3b087132015-03-11 15:00:08 -07002013
cameron@onlab.us75900962015-03-30 13:22:49 -07002014 try:
2015 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str(eventRate))
2016 self.handle.expect(":~")
2017 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
2018 self.handle.expect(":~")
2019
2020 for i in range(10):
2021 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider")
2022 self.handle.expect(":~")
2023 verification = self.handle.before
2024 if (" value=" + str(eventRate)) in verification and (" value=" + fileName) in verification:
2025 break
2026 else:
2027 time.sleep(1)
2028
2029 assert ("value=" + str(eventRate)) in verification and (" value=" + fileName) in verification
2030
2031 except pexpect.EOF:
2032 main.log.error( self.name + ": EOF exception found" )
2033 main.log.error( self.name + ": " + self.handle.before )
2034 main.cleanup()
2035 main.exit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002036 except AssertionError:
2037 main.log.info("Settings did not post to ONOS")
2038 main.log.error(varification)
Jon Hall77ba41c2015-04-06 10:25:40 -07002039 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002040 main.log.exception( self.name + ": Uncaught exception!" )
2041 main.log.error(varification)
2042 main.cleanup()
2043 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07002044
kelvin-onlaba4074292015-07-09 15:19:49 -07002045 def getOnosIps( self ):
2046 """
2047 Get all onos IPs stored in
2048 """
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002049
kelvin-onlaba4074292015-07-09 15:19:49 -07002050 return sorted( self.onosIps.values() )
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002051
kelvin-onlaba4074292015-07-09 15:19:49 -07002052 def logReport( self, nodeIp, searchTerms, outputMode="s" ):
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002053 '''
2054 - accepts either a list or a string for "searchTerms" these
2055 terms will be searched for in the log and have their
2056 instances counted
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002057
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002058 - nodeIp is the ip of the node whos log is to be scanned
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002059
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002060 - output modes:
2061 "s" - Simple. Quiet output mode that just prints
cameron@onlab.us2e166212015-05-19 14:28:25 -07002062 the occurences of each search term
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002063
cameron@onlab.us2e166212015-05-19 14:28:25 -07002064 "d" - Detailed. Prints number of occurences as well as the entire
2065 line for each of the last 5 occurences
2066
2067 - returns total of the number of instances of all search terms
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002068 '''
2069 main.log.info("========================== Log Report ===========================\n")
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002070
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002071 if type(searchTerms) is str:
2072 searchTerms = [searchTerms]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002073
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002074 logLines = [ [" "] for i in range(len(searchTerms)) ]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002075
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002076 for term in range(len(searchTerms)):
2077 logLines[term][0] = searchTerms[term]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002078
cameron@onlab.us2e166212015-05-19 14:28:25 -07002079 totalHits = 0
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002080 for term in range(len(searchTerms)):
2081 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep " + searchTerms[term]
2082 self.handle.sendline(cmd)
2083 self.handle.expect(":~")
2084 before = (self.handle.before).splitlines()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002085
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002086 count = [searchTerms[term],0]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002087
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002088 for line in before:
2089 if searchTerms[term] in line and "grep" not in line:
2090 count[1] += 1
2091 if before.index(line) > ( len(before) - 7 ):
2092 logLines[term].append(line)
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002093
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002094 main.log.info( str(count[0]) + ": " + str(count[1]) )
2095 if term == len(searchTerms)-1:
2096 print("\n")
cameron@onlab.us2e166212015-05-19 14:28:25 -07002097 totalHits += int(count[1])
2098
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002099 if outputMode != "s" and outputMode != "S":
2100 outputString = ""
2101 for i in logLines:
2102 outputString = i[0] + ": \n"
2103 for x in range(1,len(i)):
2104 outputString += ( i[x] + "\n" )
2105
2106 if outputString != (i[0] + ": \n"):
2107 main.log.info(outputString)
2108
2109 main.log.info("================================================================\n")
cameron@onlab.us2e166212015-05-19 14:28:25 -07002110 return totalHits
pingping-lin763ee042015-05-20 17:45:30 -07002111
Hari Krishnaade11a72015-07-01 17:06:46 -07002112 def getOnosIPfromCell(self):
2113 '''
2114 Returns the ONOS node names and their IP addresses as defined in the cell and applied to shell environment
Hari Krishnaa25104c2015-07-09 22:34:01 -07002115 Example output return: ['10.128.40.41','10.128.40.42','10.128.40.43']. This will work even if the Mininet is
2116 not part of the cell definition and also if there are multiple mininets, just by using static hostname
2117 in TOPO file.
2118 '''
Hari Krishnaade11a72015-07-01 17:06:46 -07002119 import re
2120 try:
2121 # Clean handle by sending empty and expecting $
2122 self.handle.sendline( "" )
2123 self.handle.expect( "\$" )
2124 self.handle.sendline( "cell" )
2125 self.handle.expect( "\$" )
2126 handleBefore = self.handle.before
2127 handleAfter = self.handle.after
2128 # Get the rest of the handle
2129 self.handle.sendline( "" )
2130 self.handle.expect( "\$" )
2131 handleMore = self.handle.before
2132 ipList = []
2133 cellOutput = handleBefore + handleAfter + handleMore
2134 cellOutput = cellOutput.replace("\r\r","")
2135 cellOutput = cellOutput.splitlines()
2136 for i in range( len(cellOutput) ):
2137 if( re.match( "OC", cellOutput[i] ) ):
2138 if( re.match( "OCI", cellOutput[i] ) or re.match( "OCN", cellOutput[i] ) ):
2139 continue
2140 else:
2141 onosIP = cellOutput[i].split("=")
Hari Krishnac195f3b2015-07-08 20:02:24 -07002142 ipList.append(onosIP[1])
Hari Krishnaade11a72015-07-01 17:06:46 -07002143 return ipList
2144 except pexpect.ExceptionPexpect as e:
2145 main.log.error( self.name + ": Pexpect exception found of type " +
2146 str( type( e ) ) )
2147 main.log.error ( e.get_trace() )
2148 main.log.error( self.name + ": " + self.handle.before )
2149 main.cleanup()
2150 main.exit()
2151 except Exception:
2152 main.log.exception( self.name + ": Uncaught exception!" )
2153 main.cleanup()
2154 main.exit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002155
2156 def copyMininetFile( self, fileName, localPath, userName, ip,
2157 mnPath='~/mininet/custom/', timeout = 60 ):
2158 """
2159 Description:
2160 Copy mininet topology file from dependency folder in the test folder
2161 and paste it to the mininet machine's mininet/custom folder
2162 Required:
2163 fileName - Name of the topology file to copy
2164 localPath - File path of the mininet topology file
2165 userName - User name of the mininet machine to send the file to
2166 ip - Ip address of the mininet machine
2167 Optional:
2168 mnPath - of the mininet directory to send the file to
2169 Return:
2170 Return main.TRUE if successfully copied the file otherwise
2171 return main.FALSE
2172 """
2173
2174 try:
2175 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2176 str( ip ) + ":" + mnPath + fileName
2177
2178 self.handle.sendline( "" )
2179 self.handle.expect( "\$" )
2180
2181 main.log.info( self.name + ": Execute: " + cmd )
2182
2183 self.handle.sendline( cmd )
2184
2185 i = self.handle.expect( [ 'No such file',
2186 "100%",
2187 pexpect.TIMEOUT ] )
2188
2189 if i == 0:
2190 main.log.error( self.name + ": File " + fileName +
2191 " does not exist!" )
2192 return main.FALSE
2193
2194 if i == 1:
2195 main.log.info( self.name + ": File " + fileName +
2196 " has been copied!" )
2197 self.handle.sendline( "" )
2198 self.handle.expect( "\$" )
2199 return main.TRUE
2200
2201 except pexpect.EOF:
2202 main.log.error( self.name + ": EOF exception found" )
2203 main.log.error( self.name + ": " + self.handle.before )
2204 main.cleanup()
2205 main.exit()
2206 except pexpect.TIMEOUT:
2207 main.log.error( self.name + ": TIMEOUT exception found" )
2208 main.log.error( self.name + ": " + self.handle.before )
2209 main.cleanup()
2210 main.exit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002211
2212 def jvmSet(self, memory=8):
2213
2214 import os
2215
2216 homeDir = os.path.expanduser('~')
2217 filename = "/onos/tools/package/bin/onos-service"
2218
2219 serviceConfig = open(homeDir + filename, 'w+')
2220 serviceConfig.write("#!/bin/bash\n ")
2221 serviceConfig.write("#------------------------------------- \n ")
2222 serviceConfig.write("# Starts ONOS Apache Karaf container\n ")
2223 serviceConfig.write("#------------------------------------- \n ")
2224 serviceConfig.write("#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n ")
2225 serviceConfig.write("""export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str(memory) + "G -Xmx" + str(memory) + """G}" \n """)
2226 serviceConfig.write("[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n")
2227 serviceConfig.write("""${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """)
2228 serviceConfig.close()
2229
2230 def createDBFile(self, testData):
2231
2232 filename = main.TEST + "DB"
2233 DBString = ""
2234
2235 for item in testData:
2236 if type(item) is string:
2237 item = "'" + item + "'"
2238 if testData.index(item) < len(testData-1):
2239 item += ","
2240 DBString += str(item)
2241
2242 DBFile = open(filename, "a")
2243 DBFile.write(DBString)
2244 DBFile.close()
2245
2246 def verifySummary(self, ONOSIp,*deviceCount):
2247
2248 self.handle.sendline("onos " + ONOSIp + " summary")
2249 self.handle.expect(":~")
2250
2251 summaryStr = self.handle.before
2252 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2253
2254 #passed = "SCC(s)=1" in summaryStr
2255 #if deviceCount:
2256 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
2257
2258
2259 if "SCC(s)=1," in summaryStr:
2260 passed = True
2261 print("Summary is verifed")
2262 else:
2263 print("Summary failed")
2264
2265 if deviceCount:
2266 print" ============================="
2267 checkStr = "devices=" + str(deviceCount[0]) + ","
2268 print "Checkstr: " + checkStr
2269 if checkStr not in summaryStr:
2270 passed = False
2271 print("Device count failed")
2272 else:
2273 print "device count verified"
2274
2275 return passed