Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(251)

Side by Side Diff: tools/testing/perf_testing/create_graph.py

Issue 8775058: Tweaking perf testing script and adding smoketests to run on buildbot. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 3 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
4 # for details. All rights reserved. Use of this source code is governed by a 4 # for details. All rights reserved. Use of this source code is governed by a
5 # BSD-style license that can be found in the LICENSE file. 5 # BSD-style license that can be found in the LICENSE file.
6 6
7 import datetime 7 import datetime
8 import math 8 import math
9 from matplotlib.font_manager import FontProperties 9 try:
10 import matplotlib.pyplot as plt 10 from matplotlib.font_manager import FontProperties
11 import matplotlib.pyplot as plt
12 except ImportError:
13 print 'Warning: no matplotlib. ' + \
14 'Please ignore if you are running buildbot smoketests.'
15 import optparse
11 import os 16 import os
12 import platform 17 import platform
13 import shutil 18 import shutil
14 import subprocess 19 import subprocess
15 import time 20 import time
16 import traceback 21 import traceback
17 22
18 """This script runs to track performance and correctness progress of 23 """This script runs to track performance and correctness progress of
19 different svn revisions. It tests to see if there a newer version of the code on 24 different svn revisions. It tests to see if there a newer version of the code on
20 the server, and will sync and run the performance tests if so.""" 25 the server, and will sync and run the performance tests if so."""
21 26
22 DART_INSTALL_LOCATION = os.path.join(os.path.dirname(os.path.abspath(__file__)), 27 DART_INSTALL_LOCATION = os.path.join(os.path.dirname(os.path.abspath(__file__)),
23 '..', '..', '..') 28 '..', '..', '..')
24 V8_MEAN = 'V8 Mean' 29 V8_MEAN = 'V8 Mean'
25 FROG_MEAN = 'frog Mean' 30 FROG_MEAN = 'frog Mean'
26 COMMAND_LINE = 'commandline' 31 COMMAND_LINE = 'commandline'
27 V8 = 'v8' 32 V8 = 'v8'
28 FROG = 'frog' 33 FROG = 'frog'
29 V8_AND_FROG = [V8, FROG] 34 V8_AND_FROG = [V8, FROG]
30 CORRECTNESS = 'Percent passing' 35 CORRECTNESS = 'Percent passing'
31 BENCHMARKS = ['Mandelbrot', 'DeltaBlue', 'Richards', 'NBody', 36 BENCHMARKS = ['Mandelbrot', 'DeltaBlue', 'Richards', 'NBody',
32 'BinaryTrees', 'Fannkuch', 'Meteor', 'BubbleSort', 'Fibonacci', 37 'BinaryTrees', 'Fannkuch', 'Meteor', 'BubbleSort', 'Fibonacci',
33 'Loop', 'Permute', 'Queens', 'QuickSort', 'Recurse', 'Sieve', 'Sum', 38 'Loop', 'Permute', 'Queens', 'QuickSort', 'Recurse', 'Sieve', 'Sum',
34 'Tak', 'Takl', 'Towers', 'TreeSort'] 39 'Tak', 'Takl', 'Towers', 'TreeSort']
35 COLORS = ['blue', 'green', 'red', 'cyan', 'magenta', 'black'] 40 COLORS = ['blue', 'green', 'red', 'cyan', 'magenta', 'black']
36 GRAPH_OUT_DIR = 'graphs' 41 GRAPH_OUT_DIR = 'graphs'
42 SLEEP_TIME = 200
43 PERFBOT_MODE = False
37 44
38 """First, some utility methods.""" 45 """First, some utility methods."""
39 46
40 def RunCmd(string): 47 def RunCmd(cmd_list, outfile=None, append=False):
41 """Run the specified command and print out any output to stdout. 48 """Run the specified command and print out any output to stdout.
42 Args: 49 Args:
43 string the command to run""" 50 cmd_list a list of strings that make up the command to run
44 p = subprocess.Popen(string, stdout = subprocess.PIPE, 51 outfile a string indicating the name of the file that we should write stdout
45 stderr = subprocess.STDOUT, close_fds=True) 52 to
53 append True if we want to append to the file instead of overwriting it"""
54 print cmd_list
Siggi Cherem (dart-lang) 2011/12/02 21:33:43 for later - we could only print if you specify --v
55 out = subprocess.PIPE
56 if outfile:
57 mode = 'w'
58 if append:
59 mode = 'a'
60 out = open(outfile, mode)
61 p = subprocess.Popen(cmd_list, stdout = out,
62 stderr = subprocess.PIPE, close_fds=True)
46 output, not_used = p.communicate(); 63 output, not_used = p.communicate();
47 print output: 64 if output:
48 return lines 65 print output
66 return output
49 67
50 def TimeCmd(self, cmd): 68 def TimeCmd(cmd):
69 """Determine the amount of (real) time it takes to execute a given command."""
51 start = time.time() 70 start = time.time()
52 RunCmd(cmd) 71 RunCmd(cmd)
53 return time.time() - start 72 return time.time() - start
54 73
55 def SyncAndBuild(failed_once=False): 74 def SyncAndBuild(failed_once=False):
56 """Make sure we have the latest version of of the repo, and build it. We 75 """Make sure we have the latest version of of the repo, and build it. We
57 begin and end standing in DART_INSTALL_LOCATION. 76 begin and end standing in DART_INSTALL_LOCATION.
58 Args: 77 Args:
59 failed_once True if we have attempted to build this once before, and we've 78 failed_once True if we have attempted to build this once before, and we've
60 failed, indicating .""" 79 failed, indicating the build is broken."""
61 os.chdir(DART_INSTALL_LOCATION) 80 os.chdir(DART_INSTALL_LOCATION)
62 #Revert our newly built frogsh to prevent conflicts when we update 81 #Revert our newly built frogsh to prevent conflicts when we update
63 RunCmd('svn revert ' + os.path.join(os.getcwd(), 'frog', 'frogsh')) 82 RunCmd(['svn', 'revert', os.path.join(os.getcwd(), 'frog', 'frogsh')])
64 83
65 RunCmd('gclient sync') 84 RunCmd(['gclient', 'sync'])
66 lines = RunCmd('%s -m release' % os.path.join('.', 'tools', 'build.py')) 85 lines = RunCmd([os.path.join('.', 'tools', 'build.py'), '-m', 'release'])
67 os.chdir('frog') 86 os.chdir('frog')
68 lines += RunCmd('%s -m debug,release' % os.path.join('..', 'tools', 87 lines += RunCmd([os.path.join('..', 'tools', 'build.py'), '-m',
69 'build.py')) 88 'debug,release'])
70 os.chdir('..') 89 os.chdir('..')
71 90
72 for line in lines: 91 for line in lines:
73 if '** BUILD FAILED **' in lines: 92 if 'BUILD FAILED' in lines:
74 if TestRunner.failed_once: 93 if failed_once:
75 # Someone checked in a broken build! Just stop trying to make it work 94 # Someone checked in a broken build! Just stop trying to make it work
76 # and wait for the next hour to try again. 95 # and wait for the next hour to try again.
77 print 'Broken Build' 96 print 'Broken Build'
78 sys.exit(0) 97 sys.exit(0)
79 #Remove the xcode directory and attempt to build again. If it still 98 #Remove the xcode directory and attempt to build again. If it still
80 #fails, abort, and try again next hour. 99 #fails, abort, and try again next hour.
81 out_dir = 'out' 100 out_dir = 'out'
82 if platform.system() == 'Darwin': 101 if platform.system() == 'Darwin':
83 out_dir = 'xcodebuild' 102 out_dir = 'xcodebuild'
84 os.removedirs(os.getcwd() + os.path.join('dart', out_dir, 'Release_ia32')) 103 shutil.rmtree(os.path.join(os.getcwd(), out_dir, 'Release_ia32'))
85 os.removedirs(os.getcwd() + os.path.join('dart', 'frog', out_dir, 104 shutil.rmtree(os.path.join(os.getcwd(), 'frog', out_dir,
105 'Debug_ia32'))
106 shutil.rmtree(os.path.join(os.getcwd(), 'frog', out_dir,
86 'Release_ia32')) 107 'Release_ia32'))
87 os.removedirs(os.getcwd() + os.path.join('dart', 'frog', out_dir, 108 SyncAndBuild(True)
88 'Debug_ia32'))
89 TestRunner.failed_once = True
90 SyncAndBuild()
91 109
92 def EnsureOutputDirectory(dir_name): 110 def EnsureOutputDirectory(dir_name):
93 """Test that the listed directory name exists, and if not, create one for 111 """Test that the listed directory name exists, and if not, create one for
94 our output to be placed.""" 112 our output to be placed.
113 Args:
114 dir_name the directory we will create if it does not exist."""
95 dir_path = os.path.join(DART_INSTALL_LOCATION, 'tools', 'testing', 115 dir_path = os.path.join(DART_INSTALL_LOCATION, 'tools', 'testing',
96 'perf_testing', dir_name) 116 'perf_testing', dir_name)
97 if not os.path.exists(dir_path): 117 if not os.path.exists(dir_path):
98 os.mkdir(dir_path) 118 os.mkdir(dir_path)
99 print 'Creating output directory ', dir_path 119 print 'Creating output directory ', dir_path
100 120
101 def HasNewCode(): 121 def HasNewCode():
102 """Tests if there are any newer versions of files on the server.""" 122 """Tests if there are any newer versions of files on the server."""
103 os.chdir(DART_INSTALL_LOCATION) 123 os.chdir(DART_INSTALL_LOCATION)
104 results = RunCmd('svn st -u') 124 results = RunCmd(['svn', 'st', '-u'])
105 for line in results: 125 for line in results:
106 if '*' in line: 126 if '*' in line:
107 return True 127 return True
108 return False 128 return False
109 129
110 def GetBrowsers(): 130 def GetBrowsers():
131 if not PERFBOT_MODE:
132 # Only Firefox (and Chrome, but we have Dump Render Tree) works in Linux
133 return ['ff']
111 browsers = ['ff', 'chrome'] 134 browsers = ['ff', 'chrome']
112 if platform.system() == 'Windows': 135 if platform.system() == 'Windows':
113 browsers += ['ie'] 136 browsers += ['ie']
114 return browsers 137 return browsers
115 138
139 def GetVersions():
140 if not PERBOT_MODE:
141 return [FROG]
142 else:
143 return V8_AND_FROG
144
116 class TestRunner(object): 145 class TestRunner(object):
117 """The base clas to provide shared code for different tests we will run and 146 """The base clas to provide shared code for different tests we will run and
118 graph.""" 147 graph."""
119 148
120 def __init__(self, result_folder_name, platform_list, v8_and_or_frog_list, 149 def __init__(self, result_folder_name, platform_list, v8_and_or_frog_list,
121 values_list): 150 values_list):
122 """Args: 151 """Args:
123 result_folder_name the name of the folder where a tracefile of 152 result_folder_name the name of the folder where a tracefile of
124 performance results will be stored. 153 performance results will be stored.
125 platform_list a list containing the platform(s) that our data has been 154 platform_list a list containing the platform(s) that our data has been
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 fontP = FontProperties() 220 fontP = FontProperties()
192 fontP.set_size('small') 221 fontP.set_size('small')
193 plt.legend(loc=legend_loc, prop = fontP) 222 plt.legend(loc=legend_loc, prop = fontP)
194 223
195 fig = plt.gcf() 224 fig = plt.gcf()
196 fig.set_size_inches(size_x, size_y) 225 fig.set_size_inches(size_x, size_y)
197 fig.savefig(os.path.join(GRAPH_OUT_DIR, filename)) 226 fig.savefig(os.path.join(GRAPH_OUT_DIR, filename))
198 227
199 def AddSvnRevisionToTrace(self, outfile): 228 def AddSvnRevisionToTrace(self, outfile):
200 """Add the svn version number to the provided tracefile.""" 229 """Add the svn version number to the provided tracefile."""
201 p = subprocess.Popen('svn info ', stdout = subprocess.PIPE, 230 p = subprocess.Popen(['svn', 'info'], stdout = subprocess.PIPE,
202 stderr = subprocess.STDOUT, close_fds=True) 231 stderr = subprocess.STDOUT, close_fds=True)
203 output, not_used = p.communicate() 232 output, not_used = p.communicate()
204 for line in output.split('\n'): 233 for line in output.split('\n'):
205 if 'Revision' in line: 234 if 'Revision' in line:
206 RunCmd('echo "%s" > %s' % (line.strip(), outfile)) 235 RunCmd(['echo', line.strip()], outfile)
207 236
208 def WriteHtml(self, delimiter, rev_nums, label_1, dict_1, label_2, dict_2, 237 def WriteHtml(self, delimiter, rev_nums, label_1, dict_1, label_2, dict_2,
209 cleanFile=False): 238 cleanFile=False):
210 """Adds an html table to the webpage to display the data values. This method 239 """Adds an html table to the webpage to display the data values. This method
211 will be removed when we have a nicer way to display data values.""" 240 will be removed when we have a nicer way to display data values."""
212 #TODO(efortuna): fix this. 241 #TODO(efortuna): fix this.
213 return 242 return
214 #TODO(efortuna): Take this method out when have finalized where the data is 243 #TODO(efortuna): Take this method out when have finalized where the data is
215 # going to be displayed. 244 # going to be displayed.
216 f = '' 245 f = ''
(...skipping 30 matching lines...) Expand all
247 geo_mean += math.log(self.values_dict[platform][frog_or_v8][benchmark][ 276 geo_mean += math.log(self.values_dict[platform][frog_or_v8][benchmark][
248 len(self.values_dict[platform][frog_or_v8][benchmark]) - 1]) 277 len(self.values_dict[platform][frog_or_v8][benchmark]) - 1])
249 278
250 mean = V8_MEAN 279 mean = V8_MEAN
251 if frog_or_v8 == FROG: 280 if frog_or_v8 == FROG:
252 mean = FROG_MEAN 281 mean = FROG_MEAN
253 self.values_dict[platform][frog_or_v8][mean] += \ 282 self.values_dict[platform][frog_or_v8][mean] += \
254 [math.pow(math.e, geo_mean / len(BENCHMARKS))] 283 [math.pow(math.e, geo_mean / len(BENCHMARKS))]
255 self.revision_dict[platform][frog_or_v8][mean] += [svn_revision] 284 self.revision_dict[platform][frog_or_v8][mean] += [svn_revision]
256 285
286 def Cleanup(self):
287 pass
288
257 def Run(self): 289 def Run(self):
258 """Run the benchmarks/tests from the command line and plot the 290 """Run the benchmarks/tests from the command line and plot the
259 results.""" 291 results."""
260 plt.cla() # cla = clear current axes 292 plt.cla() # cla = clear current axes
261 os.chdir(DART_INSTALL_LOCATION) 293 os.chdir(DART_INSTALL_LOCATION)
262 EnsureOutputDirectory(self.result_folder_name) 294 EnsureOutputDirectory(self.result_folder_name)
263 EnsureOutputDirectory(GRAPH_OUT_DIR) 295 EnsureOutputDirectory(GRAPH_OUT_DIR)
264 self.RunTests() 296 self.RunTests()
265 os.chdir(os.path.join('tools', 'testing', 'perf_testing')) 297 os.chdir(os.path.join('tools', 'testing', 'perf_testing'))
266 298
267 # TODO(efortuna): You will want to make this only use a subset of the files 299 # TODO(efortuna): You will want to make this only use a subset of the files
268 # eventually. 300 # eventually.
269 files = os.listdir(self.result_folder_name) 301 files = os.listdir(self.result_folder_name)
270 302
271 for afile in files: 303 for afile in files:
272 if not afile.startswith('.'): 304 if not afile.startswith('.'):
273 self.ProcessFile(afile) 305 self.ProcessFile(afile)
274 self.PlotResults('%s.png' % self.result_folder_name) 306
307 if PERFBOT_MODE:
308 self.PlotResults('%s.png' % self.result_folder_name)
309 self.Cleanup();
275 310
276 class PerformanceTestRunner(TestRunner): 311 class PerformanceTestRunner(TestRunner):
277 """Super class for all performance testing.""" 312 """Super class for all performance testing."""
278 def __init__(self, result_folder_name, platform_list, platform_type): 313 def __init__(self, result_folder_name, platform_list, platform_type):
279 super(PerformanceTestRunner, self).__init__(result_folder_name, 314 super(PerformanceTestRunner, self).__init__(result_folder_name,
280 platform_list, V8_AND_FROG, BENCHMARKS) 315 platform_list, GetVersions(), BENCHMARKS)
281 self.platform_list = platform_list 316 self.platform_list = platform_list
282 self.platform_type = platform_type 317 self.platform_type = platform_type
283 318
284 def PlotAllPerf(self, png_filename): 319 def PlotAllPerf(self, png_filename):
285 """Create a plot that shows the performance changes of individual benchmarks 320 """Create a plot that shows the performance changes of individual benchmarks
286 run by V8 and generated by frog, over svn history.""" 321 run by V8 and generated by frog, over svn history."""
287 for benchmark in BENCHMARKS: 322 for benchmark in BENCHMARKS:
288 self.StyleAndSavePerfPlot( 323 self.StyleAndSavePerfPlot(
289 'Performance of %s over time on the %s' % (benchmark, 324 'Performance of %s over time on the %s' % (benchmark,
290 self.platform_type), 'Speed (bigger = better)', 16, 14, 'lower left', 325 self.platform_type), 'Speed (bigger = better)', 16, 14, 'lower left',
291 benchmark + png_filename, self.platform_list, V8_AND_FROG, 326 benchmark + png_filename, self.platform_list, GetVersions(),
292 [benchmark]) 327 [benchmark])
293 328
294 def PlotAvgPerf(self, png_filename): 329 def PlotAvgPerf(self, png_filename):
295 """Generate a plot that shows the performance changes of the geomentric mean 330 """Generate a plot that shows the performance changes of the geomentric mean
296 of V8 and frog benchmark performance over svn history.""" 331 of V8 and frog benchmark performance over svn history."""
297 (title, y_axis, size_x, size_y, loc, filename) = \ 332 (title, y_axis, size_x, size_y, loc, filename) = \
298 ('Geometric Mean of benchmark %s performance' % self.platform_type, 333 ('Geometric Mean of benchmark %s performance' % self.platform_type,
299 'Speed (bigger = better)', 16, 5, 'center', 'avg'+png_filename) 334 'Speed (bigger = better)', 16, 5, 'center', 'avg'+png_filename)
300 for platform in self.platform_list: 335 for platform in self.platform_list:
301 self.StyleAndSavePerfPlot(title, y_axis, size_x, size_y, loc, filename, 336 self.StyleAndSavePerfPlot(title, y_axis, size_x, size_y, loc, filename,
302 [platform], [V8], [V8_MEAN], True) 337 [platform], [V8], [V8_MEAN], True)
303 self.StyleAndSavePerfPlot(title, y_axis, size_x, size_y, loc, filename, 338 self.StyleAndSavePerfPlot(title, y_axis, size_x, size_y, loc, filename,
304 [platform], [FROG], [FROG_MEAN], False) 339 [platform], [FROG], [FROG_MEAN], False)
305 self.WriteHtml('table', 340 self.WriteHtml('table',
306 self.revision_dict[platform][V8], 341 self.revision_dict[platform][V8],
307 'V8 mean', self.values_dict[platform][V8][V8_MEAN], 342 'V8 mean', self.values_dict[platform][V8][V8_MEAN],
308 'Frog mean', self.values_dict[platform][FROG][FROG_MEAN], 343 'Frog mean', self.values_dict[platform][FROG][FROG_MEAN],
309 True) 344 True)
310 345
311 def PlotResults(self, png_filename): 346 def PlotResults(self, png_filename):
312 self.PlotAllPerf(png_filename) 347 self.PlotAllPerf(png_filename)
313 self.PlotAvgPerf('2' + png_filename) 348 self.PlotAvgPerf('2' + png_filename)
314 349
350
315 class CommandLinePerformanceTestRunner(PerformanceTestRunner): 351 class CommandLinePerformanceTestRunner(PerformanceTestRunner):
316 """Run performance tests from the command line.""" 352 """Run performance tests from the command line."""
317 353
318 def __init__(self, result_folder_name): 354 def __init__(self, result_folder_name):
319 super(CommandLinePerformanceTestRunner, self).__init__(result_folder_name, 355 super(CommandLinePerformanceTestRunner, self).__init__(result_folder_name,
320 [COMMAND_LINE], 'command line') 356 [COMMAND_LINE], 'command line')
321 357
322 def ProcessFile(self, afile): 358 def ProcessFile(self, afile):
323 """Pull all the relevant information out of a given tracefile. 359 """Pull all the relevant information out of a given tracefile.
324 360
(...skipping 24 matching lines...) Expand all
349 self.revision_dict[COMMAND_LINE][FROG][benchmark] += [revision_num] 385 self.revision_dict[COMMAND_LINE][FROG][benchmark] += [revision_num]
350 self.values_dict[COMMAND_LINE][FROG][benchmark] += [frog_value] 386 self.values_dict[COMMAND_LINE][FROG][benchmark] += [frog_value]
351 f.close() 387 f.close()
352 388
353 self.CalculateGeometricMean(COMMAND_LINE, FROG, revision_num) 389 self.CalculateGeometricMean(COMMAND_LINE, FROG, revision_num)
354 self.CalculateGeometricMean(COMMAND_LINE, V8, revision_num) 390 self.CalculateGeometricMean(COMMAND_LINE, V8, revision_num)
355 391
356 def RunTests(self): 392 def RunTests(self):
357 """Run a performance test on our updated system.""" 393 """Run a performance test on our updated system."""
358 os.chdir('frog') 394 os.chdir('frog')
359 file_path = os.path.join('..', 'tools', 'testing', 'perf_testing', 395 self.trace_file = os.path.join('..', 'tools', 'testing', 'perf_testing',
360 self.result_folder_name, 'result') 396 self.result_folder_name, 'result' + self.cur_time)
361 RunCmd('python %s > %s%s' % (os.path.join('benchmarks', 397 RunCmd(['python', os.path.join('benchmarks', 'perf_tests.py')],
362 'perf_tests.py'), file_path, self.cur_time)) 398 self.trace_file)
363 os.chdir('..') 399 os.chdir('..')
364 400
365 401
366 class BrowserPerformanceTestRunner(PerformanceTestRunner): 402 class BrowserPerformanceTestRunner(PerformanceTestRunner):
367 """Runs performance tests, in the browser.""" 403 """Runs performance tests, in the browser."""
368 404
369 def __init__(self, result_folder_name): 405 def __init__(self, result_folder_name):
370 super(BrowserPerformanceTestRunner, self).__init__( 406 super(BrowserPerformanceTestRunner, self).__init__(
371 result_folder_name, GetBrowsers(), 'browser') 407 result_folder_name, GetBrowsers(), 'browser')
372 408
373 def RunTests(self): 409 def RunTests(self):
374 """Run a performance test in the browser.""" 410 """Run a performance test in the browser."""
375 os.chdir('frog') 411 os.chdir('frog')
376 RunCmd('python benchmarks/make_web_benchmarks.py') 412 RunCmd(['python', os.path.join('benchmarks', 'make_web_benchmarks.py')])
377 os.chdir('..') 413 os.chdir('..')
378 414
379 for browser in GetBrowsers(): 415 for browser in GetBrowsers():
380 for version in V8_AND_FROG: 416 for version in GetVersions():
381 self.AddSvnRevisionToTrace(os.path.join('tools', 'testing', 417 self.trace_file = os.path.join('tools', 'testing', 'perf_testing',
382 'perf_testing', self.result_folder_name, 418 self.result_folder_name,
383 'perf-%s-%s-%s' % (self.cur_time, browser, version))) 419 'perf-%s-%s-%s' % (self.cur_time, browser, version))
384 RunCmd('python %s --out %s --browser %s --timeout 1000 --perf >> %s' % 420 self.AddSvnRevisionToTrace(self.trace_file)
385 (os.path.join('tools', 'testing', 'run_selenium.py'), 421 RunCmd(['python', os.path.join('tools', 'testing', 'run_selenium.py'),
386 os.path.join(os.getcwd(), 'internal', 'browserBenchmarks', 422 '--out', os.path.join(os.getcwd(), 'internal', 'browserBenchmarks',
387 'benchmark_page_%s.html' % version), 423 'benchmark_page_%s.html' % version), '--browser', browser,
388 browser, 424 '--timeout', '600', '--perf'], self.trace_file, append=True)
389 os.path.join('tools', 'testing', 'perf_testing',
390 self.result_folder_name, 'perf-%s-%s-%s' % (self.cur_time, browser,
391 version))))
392 425
393 def ProcessFile(self, afile): 426 def ProcessFile(self, afile):
394 """Comb through the html to find the performance results.""" 427 """Comb through the html to find the performance results."""
395 parts = afile.split('-') 428 parts = afile.split('-')
396 browser = parts[2] 429 browser = parts[2]
397 version = parts[3] 430 version = parts[3]
398 f = open(os.path.join(self.result_folder_name, afile)) 431 f = open(os.path.join(self.result_folder_name, afile))
399 lines = f.readlines() 432 lines = f.readlines()
400 line = '' 433 line = ''
401 i = 0 434 i = 0
(...skipping 29 matching lines...) Expand all
431 self.revision_dict[browser][version][name] += [revision_num] 464 self.revision_dict[browser][version][name] += [revision_num]
432 465
433 f.close() 466 f.close()
434 self.CalculateGeometricMean(browser, version, revision_num) 467 self.CalculateGeometricMean(browser, version, revision_num)
435 468
436 def WriteHtml(self, delimiter, rev_nums, label_1, dict_1, label_2, dict_2, 469 def WriteHtml(self, delimiter, rev_nums, label_1, dict_1, label_2, dict_2,
437 cleanFile=False): 470 cleanFile=False):
438 #TODO(efortuna) 471 #TODO(efortuna)
439 pass 472 pass
440 473
474
475 def Cleanup():
476 # Kill the zombie chromedriver processes.
477 RunCmd(['killall', 'chromedriver'])
478
479
441 class BrowserCorrectnessTestRunner(TestRunner): 480 class BrowserCorrectnessTestRunner(TestRunner):
442 def __init__(self, test_type, result_folder_name): 481 def __init__(self, test_type, result_folder_name):
443 super(BrowserCorrectnessTestRunner, self).__init__(result_folder_name, 482 super(BrowserCorrectnessTestRunner, self).__init__(result_folder_name,
444 GetBrowsers(), [FROG], [CORRECTNESS]) 483 GetBrowsers(), [FROG], [CORRECTNESS])
445 self.test_type = test_type 484 self.test_type = test_type
446 485
447 def RunTests(self): 486 def RunTests(self):
448 """Run a test of the latest svn revision.""" 487 """Run a test of the latest svn revision."""
449 for browser in GetBrowsers(): 488 for browser in GetBrowsers():
450 current_file = 'correctness%s-%s' % (self.cur_time, browser) 489 current_file = 'correctness%s-%s' % (self.cur_time, browser)
451 current_file_path = os.path.join('tools', 'testing', 490 self.trace_file = os.path.join('tools', 'testing',
452 'perf_testing', self.result_folder_name, current_file) 491 'perf_testing', self.result_folder_name, current_file)
453 self.AddSvnRevisionToTrace(current_file_path) 492 self.AddSvnRevisionToTrace(self.trace_file)
454 RunCmd(os.path.join('.', 'tools', 'test.py') + 493 RunCmd([os.path.join('.', 'tools', 'test.py'),
455 ' --component=webdriver --flag=%s --report --timeout=20 ' % browser + 494 '--component=webdriver', '--flag=%s' % browser, '--report',
456 '--progress=color --mode=release -j1 %s >>' % self.test_type + 495 '--timeout=20', '--progress=color', '--mode=release', '-j1',
457 current_file_path) 496 self.test_type], self.trace_file, append=True)
458 497
459 def ProcessFile(self, afile): 498 def ProcessFile(self, afile):
460 """Given a trace file, extract all the relevant information out of it to 499 """Given a trace file, extract all the relevant information out of it to
461 determine the number of correctly passing tests. 500 determine the number of correctly passing tests.
462 501
463 Arguments: 502 Arguments:
464 afile the filename string""" 503 afile the filename string"""
465 browser = afile.rpartition('-')[2] 504 browser = afile.rpartition('-')[2]
466 f = open(os.path.join(self.result_folder_name, afile)) 505 f = open(os.path.join(self.result_folder_name, afile))
467 revision_num = 0 506 revision_num = 0
(...skipping 21 matching lines...) Expand all
489 f.close() 528 f.close()
490 529
491 def PlotResults(self, png_filename): 530 def PlotResults(self, png_filename):
492 first_time = True 531 first_time = True
493 for browser in GetBrowsers(): 532 for browser in GetBrowsers():
494 self.StyleAndSavePerfPlot('Percentage of language tests passing in ' 533 self.StyleAndSavePerfPlot('Percentage of language tests passing in '
495 'different browsers', '% of tests passed', 8, 8, 'lower left', 534 'different browsers', '% of tests passed', 8, 8, 'lower left',
496 png_filename, [browser], [FROG], [CORRECTNESS], first_time) 535 png_filename, [browser], [FROG], [CORRECTNESS], first_time)
497 first_time = False 536 first_time = False
498 537
538 def Cleanup():
539 # Kill the zombie chromedriver processes.
540 RunCmd(['killall', 'chromedriver'])
499 541
500 class CompileTimeAndSizeTestRunner(TestRunner): 542 class CompileTimeAndSizeTestRunner(TestRunner):
501 """Run tests to determine how long frogsh takes to compile, and the compiled 543 """Run tests to determine how long frogsh takes to compile, and the compiled
502 file output size of some benchmarking files.""" 544 file output size of some benchmarking files."""
503 def __init__(self, result_folder_name): 545 def __init__(self, result_folder_name):
504 super(CompileTimeAndSizeTestRunner, self).__init__(result_folder_name, 546 super(CompileTimeAndSizeTestRunner, self).__init__(result_folder_name,
505 [COMMAND_LINE], [FROG], ['Compiling on Dart VM', 'Bootstrapping', 547 [COMMAND_LINE], [FROG], ['Compiling on Dart VM', 'Bootstrapping',
506 'frogsh', 'swarm', 'total']) 548 'frogsh', 'swarm', 'total'])
507 self.failure_threshold = {'Compiling on Dart VM' : 1, 'Bootstrapping' : .5, 549 self.failure_threshold = {'Compiling on Dart VM' : 1, 'Bootstrapping' : .5,
508 'frogsh' : 100, 'swarm' : 100, 'total' : 100} 550 'frogsh' : 100, 'swarm' : 100, 'total' : 100}
509 551
510 def RunTests(self): 552 def RunTests(self):
511 os.chdir('frog') 553 os.chdir('frog')
512 current_file_path = os.path.join('..', 'tools', 'testing', 'perf_testing', 554 self.trace_file = os.path.join('..', 'tools', 'testing', 'perf_testing',
513 self.result_folder_name, self.result_folder_name + self.cur_time) 555 self.result_folder_name, self.result_folder_name + self.cur_time)
514 556
515 self.AddSvnRevisionToTrace(current_file_path) 557 self.AddSvnRevisionToTrace(self.trace_file)
516 558
517 elapsed = TimeCmd(os.path.join('.', 'frog.py') + 559 elapsed = TimeCmd([os.path.join('.', 'frog.py'),
518 ' --vm_flags="--compile_all --enable_type_checks --enable_asserts" --' 560 '--vm_flags="--compile_all --enable_type_checks --enable_asserts"',
519 ' --compile_all --enable_type_checks --out=frogsh frog.dart') 561 '--', '--compile_all', '--enable_type_checks', '--out=frogsh',
520 RunCmd('echo "%f Compiling on Dart VM in checked mode in' % elapsed + 562 'frog.dart'])
521 ' seconds" >> %s' % current_file_path) 563 RunCmd(['echo', '%f Compiling on Dart VM in checked mode in seconds'
522 RunCmd('chmod +x frogsh') 564 % elapsed], self.trace_file, append=True)
523 elapsed = TimeCmd(os.path.join('.', 'frogsh') + ' --out=frogsh ' 565 elapsed = TimeCmd([os.path.join('.', 'frogsh'), '--out=frogsh',
524 '--enable_type_checks frog.dart --enable_type_checks ' + 566 '--enable_type_checks', 'frog.dart', '--enable_type_checks',
525 os.path.join('tests', 'hello.dart')) 567 os.path.join('tests', 'hello.dart')])
526 if elapsed < self.failure_threshold['Bootstrapping']: 568 if elapsed < self.failure_threshold['Bootstrapping']:
527 #frogsh didn't compile correctly. Stop testing now, because subsequent 569 #frogsh didn't compile correctly. Stop testing now, because subsequent
528 #numbers will be meaningless. 570 #numbers will be meaningless.
529 return 571 return
530 size = os.path.getsize('frogsh') 572 size = os.path.getsize('frogsh')
531 RunCmd('echo "%f Bootstrapping time in seconds in checked mode"' % 573 RunCmd(['echo', '%f Bootstrapping time in seconds in checked mode' %
532 elapsed + ' >> %s' % current_file_path) 574 elapsed], self.trace_file, append=True)
533 RunCmd('echo "%d Generated checked frogsh size "' % size + 575 RunCmd(['echo', '%d Generated checked frogsh size' % size],
534 ' >> %s' % current_file_path) 576 self.trace_file, append=True)
535 577
536 RunCmd(os.path.join('.', 'frogsh') + ' --out=swarm-result ' 578 RunCmd([os.path.join('.', 'frogsh'), ' --out=swarm-result ',
537 '--compile-only ' + os.path.join('..', 'client', 'samples', 'swarm', 579 '--compile-only', os.path.join('..', 'client', 'samples', 'swarm',
538 'swarm.dart')) 580 'swarm.dart')])
539 swarm_size = 0 581 swarm_size = 0
540 try: 582 try:
541 swarm_size = os.path.getsize('swarm-result') 583 swarm_size = os.path.getsize('swarm-result')
542 except OSError: 584 except OSError:
543 pass #If compilation failed, continue on running other tests. 585 pass #If compilation failed, continue on running other tests.
544 586
545 RunCmd(os.path.join('.', 'frogsh') + ' --out=total-result ' 587 RunCmd([os.path.join('.', 'frogsh'), '--out=total-result',
546 '--compile-only ' + os.path.join('..', 'client', 'samples', 'total', 588 '--compile-only', os.path.join('..', 'client', 'samples', 'total',
547 'src', 'Total.dart')) 589 'src', 'Total.dart')])
548 total_size = 0 590 total_size = 0
549 try: 591 try:
550 total_size = os.path.getsize('total-result') 592 total_size = os.path.getsize('total-result')
551 except OSError: 593 except OSError:
552 pass #If compilation failed, continue on running other tests. 594 pass #If compilation failed, continue on running other tests.
553 595
554 RunCmd('echo "%d Generated checked swarm size "' % swarm_size + 596 RunCmd(['echo', '%d Generated checked swarm size' % swarm_size],
555 ' >> %s' % current_file_path) 597 self.trace_file, append=True)
556 598
557 RunCmd('echo "%d Generated checked total size "' % total_size + 599 RunCmd(['echo', '%d Generated checked total size' % total_size],
558 ' >> %s' % current_file_path) 600 self.trace_file, append=True)
559 os.chdir('..') 601 os.chdir('..')
560 602
561 def ProcessFile(self, afile): 603 def ProcessFile(self, afile):
562 """Pull all the relevant information out of a given tracefile. 604 """Pull all the relevant information out of a given tracefile.
563 Args: 605 Args:
564 afile is the filename string we will be processing.""" 606 afile is the filename string we will be processing."""
565 f = open(os.path.join(self.result_folder_name, afile)) 607 f = open(os.path.join(self.result_folder_name, afile))
566 tabulate_data = False 608 tabulate_data = False
567 revision_num = 0 609 revision_num = 0
568 for line in f.readlines(): 610 for line in f.readlines():
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 'frogsh size', self.values_dict[COMMAND_LINE][FROG]['frogsh'], '', []) 642 'frogsh size', self.values_dict[COMMAND_LINE][FROG]['frogsh'], '', [])
601 643
602 self.StyleAndSavePerfPlot('Time to compile and bootstrap', 644 self.StyleAndSavePerfPlot('Time to compile and bootstrap',
603 'Seconds', 10, 10, 'center', '2' + png_filename, [COMMAND_LINE], [FROG], 645 'Seconds', 10, 10, 'center', '2' + png_filename, [COMMAND_LINE], [FROG],
604 ['Bootstrapping', 'Compiling on Dart VM']) 646 ['Bootstrapping', 'Compiling on Dart VM'])
605 self.WriteHtml('baz', 647 self.WriteHtml('baz',
606 self.revision_dict[COMMAND_LINE][FROG]['Bootstrapping'], 648 self.revision_dict[COMMAND_LINE][FROG]['Bootstrapping'],
607 'Bootstrapping', self.values_dict[COMMAND_LINE][FROG]['Bootstrapping'], 649 'Bootstrapping', self.values_dict[COMMAND_LINE][FROG]['Bootstrapping'],
608 'Compiling on Dart VM', 650 'Compiling on Dart VM',
609 self.values_dict[COMMAND_LINE][FROG]['Compiling on Dart VM']) 651 self.values_dict[COMMAND_LINE][FROG]['Compiling on Dart VM'])
610 652
653
654 def ParseArgs():
655 parser = optparse.OptionParser()
656 parser.add_option('--command-line', '-c', dest='cl',
657 help = 'Run the command line tests',
658 action = 'store_true', default = False)
659 parser.add_option('--size-time', '-s', dest = 'size',
660 help = 'Run the code size and timing tests',
661 action = 'store_true', default = False)
662 parser.add_option('--language', '-l', dest = 'language',
663 help = 'Run the language correctness tests',
664 action = 'store_true', default = False)
665 parser.add_option('--browser-perf', '-p', dest = 'perf',
666 help = 'Run the browser performance tests',
667 action = 'store_true', default = False)
668 parser.add_option('--forever', '-f', dest = 'continuous',
669 help = 'Run this script forever, always checking for the next svn '
670 'checkin', action = 'store_true', default = False)
671 parser.add_option('--perfbot', '-p', dest = 'perfbot',
672 help = "Run in perfbot mode. (Generate plots, and remove trace files)",
673 action = 'store_true', default = False)
674
675 args, ignored = parser.parse_args()
676 if not (args.cl or args.size or args.language or args.perf):
677 args.cl = args.size = args.language = args.perf = True
678 return (args.cl, args.size, args.language, args.perf, args.continuous,
679 args.perfbot)
680
681 def RunTestSequence(cl, size, language, perf):
682 if PERFBOT_MODE:
683 # The buildbot already builds and syncs to a specific revision. Don't fight
684 # with it or replicate work.
685 SyncAndBuild()
686 if cl:
687 CommandLinePerformanceTestRunner('cl-results').Run()
688 if size:
689 CompileTimeAndSizeTestRunner('code-time-size').Run()
690 if language:
691 BrowserCorrectnessTestRunner('language', 'browser-correctness').Run()
692 if perf:
693 BrowserPerformanceTestRunner('browser-perf').Run()
611 694
612 def main(): 695 def main():
613 if HasNewCode(): 696 (cl, size, language, perf, continuous, perfbot) = ParseArgs()
614 SyncAndBuild() 697 PERFBOT_MODE = perfbot
615 CommandLinePerformanceTestRunner('cl-results').Run() 698 if continuous:
616 CompileTimeAndSizeTestRunner('code-time-size').Run() 699 while True:
617 BrowserCorrectnessTestRunner('language', 'browser-correctness').Run() 700 if HasNewCode():
618 BrowserPerformanceTestRunner('browser-perf').Run() 701 RunTestSequence(cl, size, language, perf)
702 else:
703 time.sleep(SLEEP_TIME)
704 else:
705 RunTestSequence(cl, size, language, perf)
619 706
620 if __name__ == '__main__': 707 if __name__ == '__main__':
621 main() 708 main()
622 709
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698