| OLD | NEW |
| 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 from matplotlib.font_manager import FontProperties |
| 10 import matplotlib.pyplot as plt | 10 import matplotlib.pyplot as plt |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 '..', '..', '..') | 30 '..', '..', '..') |
| 31 V8_MEAN = 'V8 Mean' | 31 V8_MEAN = 'V8 Mean' |
| 32 FROG_MEAN = 'frog Mean' | 32 FROG_MEAN = 'frog Mean' |
| 33 COMMAND_LINE = 'commandline' | 33 COMMAND_LINE = 'commandline' |
| 34 V8 = 'v8' | 34 V8 = 'v8' |
| 35 FROG = 'frog' | 35 FROG = 'frog' |
| 36 V8_AND_FROG = [V8, FROG] | 36 V8_AND_FROG = [V8, FROG] |
| 37 CORRECTNESS = 'Percent passing' | 37 CORRECTNESS = 'Percent passing' |
| 38 COLORS = ['blue', 'green', 'red', 'cyan', 'magenta', 'black'] | 38 COLORS = ['blue', 'green', 'red', 'cyan', 'magenta', 'black'] |
| 39 GRAPH_OUT_DIR = 'graphs' | 39 GRAPH_OUT_DIR = 'graphs' |
| 40 |
| 41 BROWSER_PERF = 'browser-perf' |
| 42 TIME_SIZE = 'code-time-size' |
| 43 CL_PERF = 'cl-results' |
| 44 BROWSER_CORRECTNESS = 'browser-correctness' |
| 45 |
| 40 SLEEP_TIME = 200 | 46 SLEEP_TIME = 200 |
| 41 VERBOSE = False | 47 VERBOSE = False |
| 42 HAS_SHELL = False | 48 HAS_SHELL = False |
| 43 if platform.system() == 'Windows': | 49 if platform.system() == 'Windows': |
| 44 # On Windows, shell must be true to get the correct environment variables. | 50 # On Windows, shell must be true to get the correct environment variables. |
| 45 HAS_SHELL = True | 51 HAS_SHELL = True |
| 46 | 52 |
| 47 """First, some utility methods.""" | 53 """First, some utility methods.""" |
| 48 | 54 |
| 49 def run_cmd(cmd_list, outfile=None, append=False): | 55 def run_cmd(cmd_list, outfile=None, append=False): |
| 50 """Run the specified command and print out any output to stdout. | 56 """Run the specified command and print out any output to stdout. |
| 57 |
| 51 Args: | 58 Args: |
| 52 cmd_list a list of strings that make up the command to run | 59 cmd_list: a list of strings that make up the command to run |
| 53 outfile a string indicating the name of the file that we should write stdout | 60 outfile: a string indicating the name of the file that we should write |
| 54 to | 61 stdout to |
| 55 append True if we want to append to the file instead of overwriting it""" | 62 append: True if we want to append to the file instead of overwriting it""" |
| 56 if VERBOSE: | 63 if VERBOSE: |
| 57 print ' '.join(cmd_list) | 64 print ' '.join(cmd_list) |
| 58 out = subprocess.PIPE | 65 out = subprocess.PIPE |
| 59 if outfile: | 66 if outfile: |
| 60 mode = 'w' | 67 mode = 'w' |
| 61 if append: | 68 if append: |
| 62 mode = 'a' | 69 mode = 'a' |
| 63 out = open(outfile, mode) | 70 out = open(outfile, mode) |
| 64 p = subprocess.Popen(cmd_list, stdout = out, stderr = subprocess.PIPE, | 71 p = subprocess.Popen(cmd_list, stdout = out, stderr = subprocess.PIPE, |
| 65 shell=HAS_SHELL) | 72 shell=HAS_SHELL) |
| 66 output, not_used = p.communicate(); | 73 output, not_used = p.communicate(); |
| 67 if output: | 74 if output: |
| 68 print output | 75 print output |
| 69 return output | 76 return output |
| 70 | 77 |
| 71 def time_cmd(cmd): | 78 def time_cmd(cmd): |
| 72 """Determine the amount of (real) time it takes to execute a given command.""" | 79 """Determine the amount of (real) time it takes to execute a given command.""" |
| 73 start = time.time() | 80 start = time.time() |
| 74 run_cmd(cmd) | 81 run_cmd(cmd) |
| 75 return time.time() - start | 82 return time.time() - start |
| 76 | 83 |
| 77 def sync_and_build(): | 84 def sync_and_build(): |
| 78 """Make sure we have the latest version of of the repo, and build it. We | 85 """Make sure we have the latest version of of the repo, and build it. We |
| 79 begin and end standing in DART_INSTALL_LOCATION. | 86 begin and end standing in DART_INSTALL_LOCATION. |
| 87 |
| 80 Returns: | 88 Returns: |
| 81 err_code = 1 if there was a problem building.""" | 89 err_code = 1 if there was a problem building.""" |
| 82 os.chdir(DART_INSTALL_LOCATION) | 90 os.chdir(DART_INSTALL_LOCATION) |
| 83 #Revert our newly built minfrog to prevent conflicts when we update | 91 #Revert our newly built minfrog to prevent conflicts when we update |
| 84 run_cmd(['svn', 'revert', os.path.join(os.getcwd(), 'frog', 'minfrog')]) | 92 run_cmd(['svn', 'revert', os.path.join(os.getcwd(), 'frog', 'minfrog')]) |
| 85 | 93 |
| 86 run_cmd(['gclient', 'sync']) | 94 run_cmd(['gclient', 'sync']) |
| 87 # TODO(efortuna): building the sdk locally is a band-aid until all build | 95 # TODO(efortuna): building the sdk locally is a band-aid until all build |
| 88 # platform SDKs are hosted in Google storage. Pull from https://sandbox. | 96 # platform SDKs are hosted in Google storage. Pull from https://sandbox. |
| 89 # google.com/storage/?arg=dart-dump-render-tree#dart-dump-render-tree%2Fsdk | 97 # google.com/storage/?arg=dart-dump-render-tree#dart-dump-render-tree%2Fsdk |
| (...skipping 10 matching lines...) Expand all Loading... |
| 100 if 'BUILD FAILED' in lines: | 108 if 'BUILD FAILED' in lines: |
| 101 # Someone checked in a broken build! Just stop trying to make it work | 109 # Someone checked in a broken build! Just stop trying to make it work |
| 102 # and wait to try again. | 110 # and wait to try again. |
| 103 print 'Broken Build' | 111 print 'Broken Build' |
| 104 return 1 | 112 return 1 |
| 105 return 0 | 113 return 0 |
| 106 | 114 |
| 107 def ensure_output_directory(dir_name): | 115 def ensure_output_directory(dir_name): |
| 108 """Test that the listed directory name exists, and if not, create one for | 116 """Test that the listed directory name exists, and if not, create one for |
| 109 our output to be placed. | 117 our output to be placed. |
| 118 |
| 110 Args: | 119 Args: |
| 111 dir_name the directory we will create if it does not exist.""" | 120 dir_name: the directory we will create if it does not exist.""" |
| 112 dir_path = os.path.join(DART_INSTALL_LOCATION, 'tools', 'testing', | 121 dir_path = os.path.join(DART_INSTALL_LOCATION, 'tools', 'testing', |
| 113 'perf_testing', dir_name) | 122 'perf_testing', dir_name) |
| 114 if not os.path.exists(dir_path): | 123 if not os.path.exists(dir_path): |
| 115 os.mkdir(dir_path) | 124 os.mkdir(dir_path) |
| 116 print 'Creating output directory ', dir_path | 125 print 'Creating output directory ', dir_path |
| 117 | 126 |
| 118 def has_new_code(): | 127 def has_new_code(): |
| 119 """Tests if there are any newer versions of files on the server.""" | 128 """Tests if there are any newer versions of files on the server.""" |
| 120 os.chdir(DART_INSTALL_LOCATION) | 129 os.chdir(DART_INSTALL_LOCATION) |
| 121 results = run_cmd(['svn', 'st', '-u']) | 130 results = run_cmd(['svn', 'st', '-u']) |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 self.values_dict[platform][V8][V8_MEAN] = [] | 215 self.values_dict[platform][V8][V8_MEAN] = [] |
| 207 if FROG in v8_and_or_frog_list: | 216 if FROG in v8_and_or_frog_list: |
| 208 self.revision_dict[platform][FROG][FROG_MEAN] = [] | 217 self.revision_dict[platform][FROG][FROG_MEAN] = [] |
| 209 self.values_dict[platform][FROG][FROG_MEAN] = [] | 218 self.values_dict[platform][FROG][FROG_MEAN] = [] |
| 210 | 219 |
| 211 def get_color(self): | 220 def get_color(self): |
| 212 color = COLORS[self.color_index] | 221 color = COLORS[self.color_index] |
| 213 self.color_index = (self.color_index + 1) % len(COLORS) | 222 self.color_index = (self.color_index + 1) % len(COLORS) |
| 214 return color | 223 return color |
| 215 | 224 |
| 216 def syle_and_save_perf_plot(self, chart_title, y_axis_label, size_x, size_y, | 225 def style_and_save_perf_plot(self, chart_title, y_axis_label, size_x, size_y, |
| 217 legend_loc, filename, platform_list, v8_and_or_frog_list, values_list, | 226 legend_loc, filename, platform_list, v8_and_or_frog_list, values_list, |
| 218 should_clear_axes=True): | 227 should_clear_axes=True): |
| 219 """Sets style preferences for chart boilerplate that is consistent across | 228 """Sets style preferences for chart boilerplate that is consistent across |
| 220 all charts, and saves the chart as a png. | 229 all charts, and saves the chart as a png. |
| 230 |
| 221 Args: | 231 Args: |
| 222 size_x the size of the printed chart, in inches, in the horizontal | 232 size_x: the size of the printed chart, in inches, in the horizontal |
| 223 direction | 233 direction |
| 224 size_y the size of the printed chart, in inches in the vertical direction | 234 size_y: the size of the printed chart, in inches in the vertical direction |
| 225 legend_loc the location of the legend in on the chart. See suitable | 235 legend_loc: the location of the legend in on the chart. See suitable |
| 226 arguments for the loc argument in matplotlib | 236 arguments for the loc argument in matplotlib |
| 227 filename the filename that we want to save the resulting chart as | 237 filename: the filename that we want to save the resulting chart as |
| 228 platform_list a list containing the platform(s) that our data has been run | 238 platform_list: a list containing the platform(s) that our data has been |
| 229 on. (command line, firefox, chrome, etc) | 239 run on. (command line, firefox, chrome, etc) |
| 230 values_list a list containing the type of data we will be graphing | 240 values_list: a list containing the type of data we will be graphing |
| 231 (performance, percentage passing, etc) | 241 (performance, percentage passing, etc) |
| 232 should_clear_axes True if we want to create a fresh graph, instead of | 242 should_clear_axes: True if we want to create a fresh graph, instead of |
| 233 plotting additional lines on the current graph.""" | 243 plotting additional lines on the current graph.""" |
| 234 if should_clear_axes: | 244 if should_clear_axes: |
| 235 plt.cla() # cla = clear current axes | 245 plt.cla() # cla = clear current axes |
| 236 for platform in platform_list: | 246 for platform in platform_list: |
| 237 for f in v8_and_or_frog_list: | 247 for f in v8_and_or_frog_list: |
| 238 for val in values_list: | 248 for val in values_list: |
| 239 plt.plot(self.revision_dict[platform][f][val], | 249 plt.plot(self.revision_dict[platform][f][val], |
| 240 self.values_dict[platform][f][val], | 250 self.values_dict[platform][f][val], |
| 241 color=self.get_color(), label='%s-%s-%s' % (platform, f, val)) | 251 color=self.get_color(), label='%s-%s-%s' % (platform, f, val)) |
| 242 | 252 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 # TODO(efortuna): You will want to make this only use a subset of the files | 332 # TODO(efortuna): You will want to make this only use a subset of the files |
| 323 # eventually. | 333 # eventually. |
| 324 files = os.listdir(self.result_folder_name) | 334 files = os.listdir(self.result_folder_name) |
| 325 | 335 |
| 326 for afile in files: | 336 for afile in files: |
| 327 if not afile.startswith('.'): | 337 if not afile.startswith('.'): |
| 328 self.process_file(afile) | 338 self.process_file(afile) |
| 329 | 339 |
| 330 self.plot_results('%s.png' % self.result_folder_name) | 340 self.plot_results('%s.png' % self.result_folder_name) |
| 331 | 341 |
| 332 class PerformanceTestRunner(TestRunner): | 342 class PerformanceTest(TestRunner): |
| 333 """Super class for all performance testing.""" | 343 """Super class for all performance testing.""" |
| 334 def __init__(self, result_folder_name, platform_list, platform_type): | 344 def __init__(self, result_folder_name, platform_list, platform_type): |
| 335 super(PerformanceTestRunner, self).__init__(result_folder_name, | 345 super(PerformanceTest, self).__init__(result_folder_name, |
| 336 platform_list, get_versions(), get_benchmarks()) | 346 platform_list, get_versions(), get_benchmarks()) |
| 337 self.platform_list = platform_list | 347 self.platform_list = platform_list |
| 338 self.platform_type = platform_type | 348 self.platform_type = platform_type |
| 339 | 349 |
| 340 def plot_all_perf(self, png_filename): | 350 def plot_all_perf(self, png_filename): |
| 341 """Create a plot that shows the performance changes of individual benchmarks | 351 """Create a plot that shows the performance changes of individual benchmarks |
| 342 run by V8 and generated by frog, over svn history.""" | 352 run by V8 and generated by frog, over svn history.""" |
| 343 for benchmark in get_benchmarks(): | 353 for benchmark in get_benchmarks(): |
| 344 self.syle_and_save_perf_plot( | 354 self.style_and_save_perf_plot( |
| 345 'Performance of %s over time on the %s' % (benchmark, | 355 'Performance of %s over time on the %s' % (benchmark, |
| 346 self.platform_type), 'Speed (bigger = better)', 16, 14, 'lower left', | 356 self.platform_type), 'Speed (bigger = better)', 16, 14, 'lower left', |
| 347 benchmark + png_filename, self.platform_list, get_versions(), | 357 benchmark + png_filename, self.platform_list, get_versions(), |
| 348 [benchmark]) | 358 [benchmark]) |
| 349 | 359 |
| 350 def plot_avg_perf(self, png_filename): | 360 def plot_avg_perf(self, png_filename): |
| 351 """Generate a plot that shows the performance changes of the geomentric mean | 361 """Generate a plot that shows the performance changes of the geomentric mean |
| 352 of V8 and frog benchmark performance over svn history.""" | 362 of V8 and frog benchmark performance over svn history.""" |
| 353 (title, y_axis, size_x, size_y, loc, filename) = \ | 363 (title, y_axis, size_x, size_y, loc, filename) = \ |
| 354 ('Geometric Mean of benchmark %s performance' % self.platform_type, | 364 ('Geometric Mean of benchmark %s performance' % self.platform_type, |
| 355 'Speed (bigger = better)', 16, 5, 'center', 'avg'+png_filename) | 365 'Speed (bigger = better)', 16, 5, 'center', 'avg'+png_filename) |
| 356 clear_axis = True | 366 clear_axis = True |
| 357 for platform in self.platform_list: | 367 for platform in self.platform_list: |
| 358 self.syle_and_save_perf_plot(title, y_axis, size_x, size_y, loc, filename,
| 368 self.style_and_save_perf_plot(title, y_axis, size_x, size_y, loc, |
| 359 [platform], [V8], [V8_MEAN], clear_axis) | 369 filename, [platform], [V8], [V8_MEAN], clear_axis) |
| 360 clear_axis = False | 370 clear_axis = False |
| 361 self.syle_and_save_perf_plot(title, y_axis, size_x, size_y, loc, filename,
| 371 self.style_and_save_perf_plot(title, y_axis, size_x, size_y, loc, |
| 362 [platform], [FROG], [FROG_MEAN], clear_axis) | 372 filename, [platform], [FROG], [FROG_MEAN], clear_axis) |
| 363 | 373 |
| 364 def plot_results(self, png_filename): | 374 def plot_results(self, png_filename): |
| 365 self.plot_all_perf(png_filename) | 375 self.plot_all_perf(png_filename) |
| 366 self.plot_avg_perf('2' + png_filename) | 376 self.plot_avg_perf('2' + png_filename) |
| 367 | 377 |
| 368 | 378 |
| 369 class CommandLinePerformanceTestRunner(PerformanceTestRunner): | 379 class CommandLinePerformanceTest(PerformanceTest): |
| 370 """Run performance tests from the command line.""" | 380 """Run performance tests from the command line.""" |
| 371 | 381 |
| 372 def __init__(self, result_folder_name): | 382 def __init__(self, result_folder_name): |
| 373 super(CommandLinePerformanceTestRunner, self).__init__(result_folder_name, | 383 super(CommandLinePerformanceTest, self).__init__(result_folder_name, |
| 374 [COMMAND_LINE], 'command line') | 384 [COMMAND_LINE], 'command line') |
| 375 | 385 |
| 376 def process_file(self, afile): | 386 def process_file(self, afile): |
| 377 """Pull all the relevant information out of a given tracefile. | 387 """Pull all the relevant information out of a given tracefile. |
| 378 | 388 |
| 379 Args: | 389 Args: |
| 380 afile is the filename string we will be processing.""" | 390 afile is the filename string we will be processing.""" |
| 381 f = open(os.path.join(self.result_folder_name, afile)) | 391 f = open(os.path.join(self.result_folder_name, afile)) |
| 382 tabulate_data = False | 392 tabulate_data = False |
| 383 revision_num = 0 | 393 revision_num = 0 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 410 def run_tests(self): | 420 def run_tests(self): |
| 411 """Run a performance test on our updated system.""" | 421 """Run a performance test on our updated system.""" |
| 412 os.chdir('frog') | 422 os.chdir('frog') |
| 413 self.trace_file = os.path.join('..', 'tools', 'testing', 'perf_testing', | 423 self.trace_file = os.path.join('..', 'tools', 'testing', 'perf_testing', |
| 414 self.result_folder_name, 'result' + self.cur_time) | 424 self.result_folder_name, 'result' + self.cur_time) |
| 415 run_cmd(['python', os.path.join('benchmarks', 'perf_tests.py')], | 425 run_cmd(['python', os.path.join('benchmarks', 'perf_tests.py')], |
| 416 self.trace_file) | 426 self.trace_file) |
| 417 os.chdir('..') | 427 os.chdir('..') |
| 418 | 428 |
| 419 | 429 |
| 420 class BrowserPerformanceTestRunner(PerformanceTestRunner): | 430 class BrowserPerformanceTest(PerformanceTest): |
| 421 """Runs performance tests, in the browser.""" | 431 """Runs performance tests, in the browser.""" |
| 422 | 432 |
| 423 def __init__(self, result_folder_name): | 433 def __init__(self, result_folder_name): |
| 424 super(BrowserPerformanceTestRunner, self).__init__( | 434 super(BrowserPerformanceTest, self).__init__( |
| 425 result_folder_name, get_browsers(), 'browser') | 435 result_folder_name, get_browsers(), 'browser') |
| 426 | 436 |
| 427 def run_tests(self): | 437 def run_tests(self): |
| 428 """Run a performance test in the browser.""" | 438 """Run a performance test in the browser.""" |
| 429 | 439 |
| 430 os.chdir('frog') | 440 os.chdir('frog') |
| 431 run_cmd(['python', os.path.join('benchmarks', 'make_web_benchmarks.py')]) | 441 run_cmd(['python', os.path.join('benchmarks', 'make_web_benchmarks.py')]) |
| 432 os.chdir('..') | 442 os.chdir('..') |
| 433 | 443 |
| 434 for browser in get_browsers(): | 444 for browser in get_browsers(): |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 | 495 |
| 486 f.close() | 496 f.close() |
| 487 self.calculate_geometric_mean(browser, version, revision_num) | 497 self.calculate_geometric_mean(browser, version, revision_num) |
| 488 | 498 |
| 489 def write_html(self, delimiter, rev_nums, label_1, dict_1, label_2, dict_2, | 499 def write_html(self, delimiter, rev_nums, label_1, dict_1, label_2, dict_2, |
| 490 cleanFile=False): | 500 cleanFile=False): |
| 491 #TODO(efortuna) | 501 #TODO(efortuna) |
| 492 pass | 502 pass |
| 493 | 503 |
| 494 | 504 |
| 495 class BrowserCorrectnessTestRunner(TestRunner): | 505 class BrowserCorrectnessTest(TestRunner): |
| 496 def __init__(self, test_type, result_folder_name): | 506 def __init__(self, test_type, result_folder_name): |
| 497 super(BrowserCorrectnessTestRunner, self).__init__(result_folder_name, | 507 super(BrowserCorrectnessTest, self).__init__(result_folder_name, |
| 498 get_browsers(), [FROG], [CORRECTNESS]) | 508 get_browsers(), [FROG], [CORRECTNESS]) |
| 499 self.test_type = test_type | 509 self.test_type = test_type |
| 500 | 510 |
| 501 def run_tests(self): | 511 def run_tests(self): |
| 502 """run a test of the latest svn revision.""" | 512 """Run a test of the latest svn revision.""" |
| 503 system = get_os_directory() | 513 system = get_os_directory() |
| 504 suffix = '' | 514 suffix = '' |
| 505 if platform.system() == 'Windows': | 515 if platform.system() == 'Windows': |
| 506 suffix = '.exe' | 516 suffix = '.exe' |
| 507 for browser in get_browsers(): | 517 for browser in get_browsers(): |
| 508 current_file = 'correctness%s-%s' % (self.cur_time, browser) | 518 current_file = 'correctness%s-%s' % (self.cur_time, browser) |
| 509 self.trace_file = os.path.join('tools', 'testing', | 519 self.trace_file = os.path.join('tools', 'testing', |
| 510 'perf_testing', self.result_folder_name, current_file) | 520 'perf_testing', self.result_folder_name, current_file) |
| 511 self.add_svn_revision_to_trace(self.trace_file) | 521 self.add_svn_revision_to_trace(self.trace_file) |
| 512 dart_sdk = os.path.join(os.getcwd(), utils.GetBuildRoot(utils.GuessOS(), | 522 dart_sdk = os.path.join(os.getcwd(), utils.GetBuildRoot(utils.GuessOS(), |
| 513 'release', 'ia32'), 'dart-sdk') | 523 'release', 'ia32'), 'dart-sdk') |
| 514 run_cmd([os.path.join('.', 'tools', 'testing', 'bin', system, | 524 run_cmd([os.path.join('.', 'tools', 'testing', 'bin', system, |
| 515 'dart' + suffix), os.path.join('tools', 'test.dart'), | 525 'dart' + suffix), os.path.join('tools', 'test.dart'), |
| 516 '--component=webdriver', | 526 '--component=webdriver', |
| 517 '--browser=%s' % browser, '--frog=%s' % os.path.join(dart_sdk, 'bin', | 527 '--browser=%s' % browser, '--frog=%s' % os.path.join(dart_sdk, 'bin', |
| 518 'frogc'), '--froglib=%s' % os.path.join(dart_sdk, 'lib'), '--report', | 528 'frogc'), '--froglib=%s' % os.path.join(dart_sdk, 'lib'), '--report', |
| 519 '--timeout=20', '--progress=color', '--mode=release', '-j1', | 529 '--timeout=20', '--progress=color', '--mode=release', '-j1', |
| 520 self.test_type], self.trace_file, append=True) | 530 self.test_type], self.trace_file, append=True) |
| 521 | 531 |
| 522 def process_file(self, afile): | 532 def process_file(self, afile): |
| 523 """Given a trace file, extract all the relevant information out of it to | 533 """Given a trace file, extract all the relevant information out of it to |
| 524 determine the number of correctly passing tests. | 534 determine the number of correctly passing tests. |
| 525 | 535 |
| 526 Arguments: | 536 Arguments: |
| 527 afile the filename string""" | 537 afile: the filename string""" |
| 528 browser = afile.rpartition('-')[2] | 538 browser = afile.rpartition('-')[2] |
| 529 f = open(os.path.join(self.result_folder_name, afile)) | 539 f = open(os.path.join(self.result_folder_name, afile)) |
| 530 revision_num = 0 | 540 revision_num = 0 |
| 531 lines = f.readlines() | 541 lines = f.readlines() |
| 532 total_tests = 0 | 542 total_tests = 0 |
| 533 num_failed = 0 | 543 num_failed = 0 |
| 534 expect_fail = 0 | 544 expect_fail = 0 |
| 535 for line in lines: | 545 for line in lines: |
| 536 if 'Total:' in line: | 546 if 'Total:' in line: |
| 537 total_tests = int(line.split()[1]) | 547 total_tests = int(line.split('Total: ')[1].split()[0]) |
| 538 if 'will be skipped' in line: | 548 if 'will be skipped' in line: |
| 539 total_tests -= int(line.split()[1]) | 549 total_tests -= int(line.split()[1]) |
| 540 if 'we should fix' in line: | 550 if 'we should fix' in line: |
| 541 expect_fail += int(line.split()[1]) | 551 expect_fail += int(line.split()[1]) |
| 542 if 'Revision' in line: | 552 if 'Revision' in line: |
| 543 revision_num = int(line.split()[1]) | 553 revision_num = int(line.split()[1]) |
| 544 if '--- TIMEOUT ---' in line or 'FAIL:' in line or 'PASS' in line: | 554 if '--- TIMEOUT ---' in line or 'FAIL:' in line or 'PASS' in line: |
| 545 # (A printed out 'PASS' indicates we incorrectly passed a negative | 555 # (A printed out 'PASS' indicates we incorrectly passed a negative |
| 546 # test.) | 556 # test.) |
| 547 num_failed += 1 | 557 num_failed += 1 |
| 548 | 558 |
| 549 self.revision_dict[browser][FROG][CORRECTNESS] += [revision_num] | 559 self.revision_dict[browser][FROG][CORRECTNESS] += [revision_num] |
| 550 self.values_dict[browser][FROG][CORRECTNESS] += [100.0 * | 560 self.values_dict[browser][FROG][CORRECTNESS] += [100.0 * |
| 551 (((float)(total_tests - (expect_fail + num_failed))) /total_tests)] | 561 (((float)(total_tests - (expect_fail + num_failed))) /total_tests)] |
| 552 f.close() | 562 f.close() |
| 553 | 563 |
| 554 def plot_results(self, png_filename): | 564 def plot_results(self, png_filename): |
| 555 first_time = True | 565 first_time = True |
| 556 for browser in get_browsers(): | 566 for browser in get_browsers(): |
| 557 self.syle_and_save_perf_plot('Percentage of language tests passing in ' | 567 self.style_and_save_perf_plot('Percentage of language tests passing in ' |
| 558 'different browsers', '% of tests passed', 8, 8, 'lower left', | 568 'different browsers', '% of tests passed', 8, 8, 'lower left', |
| 559 png_filename, [browser], [FROG], [CORRECTNESS], first_time) | 569 png_filename, [browser], [FROG], [CORRECTNESS], first_time) |
| 560 first_time = False | 570 first_time = False |
| 561 | 571 |
| 562 | 572 |
| 563 class CompileTimeAndSizeTestRunner(TestRunner): | 573 class CompileTimeAndSizeTest(TestRunner): |
| 564 """Run tests to determine how long minfrog takes to compile, and the compiled | 574 """Run tests to determine how long minfrog takes to compile, and the compiled |
| 565 file output size of some benchmarking files.""" | 575 file output size of some benchmarking files.""" |
| 566 def __init__(self, result_folder_name): | 576 def __init__(self, result_folder_name): |
| 567 super(CompileTimeAndSizeTestRunner, self).__init__(result_folder_name, | 577 super(CompileTimeAndSizeTest, self).__init__(result_folder_name, |
| 568 [COMMAND_LINE], [FROG], ['Compiling on Dart VM', 'Bootstrapping', | 578 [COMMAND_LINE], [FROG], ['Compiling on Dart VM', 'Bootstrapping', |
| 569 'minfrog', 'swarm', 'total']) | 579 'minfrog', 'swarm', 'total']) |
| 570 self.failure_threshold = {'Compiling on Dart VM' : 1, 'Bootstrapping' : .5, | 580 self.failure_threshold = {'Compiling on Dart VM' : 1, 'Bootstrapping' : .5, |
| 571 'minfrog' : 100, 'swarm' : 100, 'total' : 100} | 581 'minfrog' : 100, 'swarm' : 100, 'total' : 100} |
| 572 | 582 |
| 573 def run_tests(self): | 583 def run_tests(self): |
| 574 os.chdir('frog') | 584 os.chdir('frog') |
| 575 self.trace_file = os.path.join('..', 'tools', 'testing', 'perf_testing', | 585 self.trace_file = os.path.join('..', 'tools', 'testing', 'perf_testing', |
| 576 self.result_folder_name, self.result_folder_name + self.cur_time) | 586 self.result_folder_name, self.result_folder_name + self.cur_time) |
| 577 | 587 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 | 623 |
| 614 run_cmd(['echo', '%d Generated checked swarm size' % swarm_size], | 624 run_cmd(['echo', '%d Generated checked swarm size' % swarm_size], |
| 615 self.trace_file, append=True) | 625 self.trace_file, append=True) |
| 616 | 626 |
| 617 run_cmd(['echo', '%d Generated checked total size' % total_size], | 627 run_cmd(['echo', '%d Generated checked total size' % total_size], |
| 618 self.trace_file, append=True) | 628 self.trace_file, append=True) |
| 619 os.chdir('..') | 629 os.chdir('..') |
| 620 | 630 |
| 621 def process_file(self, afile): | 631 def process_file(self, afile): |
| 622 """Pull all the relevant information out of a given tracefile. | 632 """Pull all the relevant information out of a given tracefile. |
| 633 |
| 623 Args: | 634 Args: |
| 624 afile is the filename string we will be processing.""" | 635 afile: is the filename string we will be processing.""" |
| 625 f = open(os.path.join(self.result_folder_name, afile)) | 636 f = open(os.path.join(self.result_folder_name, afile)) |
| 626 tabulate_data = False | 637 tabulate_data = False |
| 627 revision_num = 0 | 638 revision_num = 0 |
| 628 for line in f.readlines(): | 639 for line in f.readlines(): |
| 629 tokens = line.split() | 640 tokens = line.split() |
| 630 if 'Revision' in line: | 641 if 'Revision' in line: |
| 631 revision_num = int(line.split()[1]) | 642 revision_num = int(line.split()[1]) |
| 632 else: | 643 else: |
| 633 for metric in self.values_list: | 644 for metric in self.values_list: |
| 634 if metric in line: | 645 if metric in line: |
| 635 num = tokens[0] | 646 num = tokens[0] |
| 636 if num.find('.') == -1: | 647 if num.find('.') == -1: |
| 637 num = int(num) | 648 num = int(num) |
| 638 else: | 649 else: |
| 639 num = float(num) | 650 num = float(num) |
| 640 self.values_dict[COMMAND_LINE][FROG][metric] += [num] | 651 self.values_dict[COMMAND_LINE][FROG][metric] += [num] |
| 641 self.revision_dict[COMMAND_LINE][FROG][metric] += [revision_num] | 652 self.revision_dict[COMMAND_LINE][FROG][metric] += [revision_num] |
| 642 | 653 |
| 643 if revision_num != 0: | 654 if revision_num != 0: |
| 644 for metric in self.values_list: | 655 for metric in self.values_list: |
| 645 self.revision_dict[COMMAND_LINE][FROG][metric].pop() | 656 self.revision_dict[COMMAND_LINE][FROG][metric].pop() |
| 646 self.revision_dict[COMMAND_LINE][FROG][metric] += [revision_num] | 657 self.revision_dict[COMMAND_LINE][FROG][metric] += [revision_num] |
| 647 # Fill 0 if compilation failed. | 658 # Fill in 0 if compilation failed. |
| 648 if self.values_dict[COMMAND_LINE][FROG][metric][-1] < \ | 659 if self.values_dict[COMMAND_LINE][FROG][metric][-1] < \ |
| 649 self.failure_threshold[metric]: | 660 self.failure_threshold[metric]: |
| 650 self.values_dict[COMMAND_LINE][FROG][metric] += [0] | 661 self.values_dict[COMMAND_LINE][FROG][metric] += [0] |
| 651 self.revision_dict[COMMAND_LINE][FROG][metric] += [revision_num] | 662 self.revision_dict[COMMAND_LINE][FROG][metric] += [revision_num] |
| 652 | 663 |
| 653 f.close() | 664 f.close() |
| 654 | 665 |
| 655 def plot_results(self, png_filename): | 666 def plot_results(self, png_filename): |
| 656 self.syle_and_save_perf_plot('Compiled minfrog Sizes', | 667 self.style_and_save_perf_plot('Compiled minfrog Sizes', |
| 657 'Size (in bytes)', 10, 10, 'center', png_filename, [COMMAND_LINE], | 668 'Size (in bytes)', 10, 10, 'center', png_filename, [COMMAND_LINE], |
| 658 [FROG], ['swarm', 'total', 'minfrog']) | 669 [FROG], ['swarm', 'total', 'minfrog']) |
| 659 self.write_html('bar', self.revision_dict[COMMAND_LINE][FROG]['minfrog'], | 670 self.write_html('bar', self.revision_dict[COMMAND_LINE][FROG]['minfrog'], |
| 660 'minfrog size', self.values_dict[COMMAND_LINE][FROG]['minfrog'], '', []) | 671 'minfrog size', self.values_dict[COMMAND_LINE][FROG]['minfrog'], '', []) |
| 661 | 672 |
| 662 self.syle_and_save_perf_plot('Time to compile and bootstrap', | 673 self.style_and_save_perf_plot('Time to compile and bootstrap', |
| 663 'Seconds', 10, 10, 'center', '2' + png_filename, [COMMAND_LINE], [FROG], | 674 'Seconds', 10, 10, 'center', '2' + png_filename, [COMMAND_LINE], [FROG], |
| 664 ['Bootstrapping', 'Compiling on Dart VM']) | 675 ['Bootstrapping', 'Compiling on Dart VM']) |
| 665 self.write_html('baz', | 676 self.write_html('baz', |
| 666 self.revision_dict[COMMAND_LINE][FROG]['Bootstrapping'], | 677 self.revision_dict[COMMAND_LINE][FROG]['Bootstrapping'], |
| 667 'Bootstrapping', self.values_dict[COMMAND_LINE][FROG]['Bootstrapping'], | 678 'Bootstrapping', self.values_dict[COMMAND_LINE][FROG]['Bootstrapping'], |
| 668 'Compiling on Dart VM', | 679 'Compiling on Dart VM', |
| 669 self.values_dict[COMMAND_LINE][FROG]['Compiling on Dart VM']) | 680 self.values_dict[COMMAND_LINE][FROG]['Compiling on Dart VM']) |
| 670 | 681 |
| 671 | 682 |
| 672 def parse_args(): | 683 def parse_args(): |
| (...skipping 21 matching lines...) Expand all Loading... |
| 694 args.cl = args.size = args.language = args.perf = True | 705 args.cl = args.size = args.language = args.perf = True |
| 695 return (args.cl, args.size, args.language, args.perf, args.continuous, | 706 return (args.cl, args.size, args.language, args.perf, args.continuous, |
| 696 args.verbose) | 707 args.verbose) |
| 697 | 708 |
| 698 def run_test_sequence(cl, size, language, perf): | 709 def run_test_sequence(cl, size, language, perf): |
| 699 # The buildbot already builds and syncs to a specific revision. Don't fight | 710 # The buildbot already builds and syncs to a specific revision. Don't fight |
| 700 # with it or replicate work. | 711 # with it or replicate work. |
| 701 if sync_and_build() == 1: | 712 if sync_and_build() == 1: |
| 702 return # The build is broken. | 713 return # The build is broken. |
| 703 if cl: | 714 if cl: |
| 704 CommandLinePerformanceTestRunner('cl-results').run() | 715 CommandLinePerformanceTest(CL_PERF).run() |
| 705 if size: | 716 if size: |
| 706 CompileTimeAndSizeTestRunner('code-time-size').run() | 717 CompileTimeAndSizeTest(TIME_SIZE).run() |
| 707 if language: | 718 if language: |
| 708 BrowserCorrectnessTestRunner('language', 'browser-correctness').run() | 719 BrowserCorrectnessTest('language', BROWSER_CORRECTNESS).run() |
| 709 if perf: | 720 if perf: |
| 710 BrowserPerformanceTestRunner('browser-perf').run() | 721 BrowserPerformanceTest(BROWSER_PERF).run() |
| 711 | 722 |
| 712 # TODO(efortuna): Temporarily disabled until you make a safe way to provide | 723 # TODO(efortuna): Temporarily disabled until you make a safe way to provide |
| 713 # your username/password for the uploading process. | 724 # your username/password for the uploading process. |
| 714 #upload_to_app_engine() | 725 #upload_to_app_engine() |
| 715 | 726 |
| 716 def main(): | 727 def main(): |
| 717 global VERBOSE | 728 global VERBOSE |
| 718 (cl, size, language, perf, continuous, verbose) = parse_args() | 729 (cl, size, language, perf, continuous, verbose) = parse_args() |
| 719 VERBOSE = verbose | 730 VERBOSE = verbose |
| 720 if continuous: | 731 if continuous: |
| 721 while True: | 732 while True: |
| 722 if has_new_code(): | 733 if has_new_code(): |
| 723 run_test_sequence(cl, size, language, perf) | 734 run_test_sequence(cl, size, language, perf) |
| 724 else: | 735 else: |
| 725 time.sleep(SLEEP_TIME) | 736 time.sleep(SLEEP_TIME) |
| 726 else: | 737 else: |
| 727 run_test_sequence(cl, size, language, perf) | 738 run_test_sequence(cl, size, language, perf) |
| 728 | 739 |
| 729 if __name__ == '__main__': | 740 if __name__ == '__main__': |
| 730 main() | 741 main() |
| 731 | 742 |
| OLD | NEW |