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

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

Issue 10095016: Add Dartium to browser_perf tests (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments Created 8 years, 8 months 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 getpass 8 import getpass
9 import math 9 import math
10 try: 10 try:
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 self.values_dict[platform] = dict() 336 self.values_dict[platform] = dict()
337 for f in variants: 337 for f in variants:
338 self.revision_dict[platform][f] = dict() 338 self.revision_dict[platform][f] = dict()
339 self.values_dict[platform][f] = dict() 339 self.values_dict[platform][f] = dict()
340 for val in values_list: 340 for val in values_list:
341 self.revision_dict[platform][f][val] = [] 341 self.revision_dict[platform][f][val] = []
342 self.values_dict[platform][f][val] = [] 342 self.values_dict[platform][f][val] = []
343 for extra_metric in extra_metrics: 343 for extra_metric in extra_metrics:
344 self.revision_dict[platform][f][extra_metric] = [] 344 self.revision_dict[platform][f][extra_metric] = []
345 self.values_dict[platform][f][extra_metric] = [] 345 self.values_dict[platform][f][extra_metric] = []
346 346
347 def is_valid_combination(self, platform, variant):
348 """Check whether data should be captured for this platform/variant
349 combination.
350 """
351 return True
352
347 def run(self, graph_only): 353 def run(self, graph_only):
348 """Run the benchmarks/tests from the command line and plot the 354 """Run the benchmarks/tests from the command line and plot the
349 results. 355 results.
350 356
351 Args: 357 Args:
352 graph_only: True if we should just graph the results instead of also 358 graph_only: True if we should just graph the results instead of also
353 running tests.""" 359 running tests."""
354 for visitor in [self.tester, self.file_processor, self.grapher]: 360 for visitor in [self.tester, self.file_processor, self.grapher]:
355 visitor.prepare() 361 visitor.prepare()
356 362
(...skipping 22 matching lines...) Expand all
379 methods that many Tester objects use. Any class that would like to be a 385 methods that many Tester objects use. Any class that would like to be a
380 TesterVisitor must implement the run_tests() method.""" 386 TesterVisitor must implement the run_tests() method."""
381 387
382 def __init__(self, test): 388 def __init__(self, test):
383 self.test = test 389 self.test = test
384 390
385 def prepare(self): 391 def prepare(self):
386 """Perform any initial setup required before the test is run.""" 392 """Perform any initial setup required before the test is run."""
387 pass 393 pass
388 394
389 def add_svn_revision_to_trace(self, outfile): 395 def add_svn_revision_to_trace(self, outfile, browser = None):
390 """Add the svn version number to the provided tracefile.""" 396 """Add the svn version number to the provided tracefile."""
391 def search_for_revision(svn_info_command): 397 def search_for_revision(svn_info_command):
392 p = subprocess.Popen(svn_info_command, stdout = subprocess.PIPE, 398 p = subprocess.Popen(svn_info_command, stdout = subprocess.PIPE,
393 stderr = subprocess.STDOUT, shell = 399 stderr = subprocess.STDOUT, shell =
394 self.test.test_runner.has_shell) 400 self.test.test_runner.has_shell)
395 output, _ = p.communicate() 401 output, _ = p.communicate()
396 for line in output.split('\n'): 402 for line in output.split('\n'):
397 if 'Revision' in line: 403 if 'Revision' in line:
398 self.test.test_runner.run_cmd(['echo', line.strip()], outfile) 404 self.test.test_runner.run_cmd(['echo', line.strip()], outfile)
399 return True 405 return True
400 return False 406 return False
401 407
402 if not search_for_revision(['svn', 'info']): 408 def get_dartium_revision():
409 version_file_name = os.path.join(DART_INSTALL_LOCATION, 'client', 'tests',
410 'dartium', 'LAST_VERSION')
411 version_file = open(version_file_name, 'r')
412 version = version_file.read().split('.')[-2]
413 version_file.close()
414 return version
415
416 if browser and browser == 'dartium':
417 revision = get_dartium_revision()
418 self.test.test_runner.run_cmd(['echo', 'Revision: ' + revision], outfile)
419 elif not search_for_revision(['svn', 'info']):
403 if not search_for_revision(['git', 'svn', 'info']): 420 if not search_for_revision(['git', 'svn', 'info']):
404 self.test.test_runner.run_cmd(['echo', 'Revision: unknown'], outfile) 421 self.test.test_runner.run_cmd(['echo', 'Revision: unknown'], outfile)
405 422
406 423
407 class Processor(object): 424 class Processor(object):
408 """The base level vistor class that processes tests. It contains convenience 425 """The base level vistor class that processes tests. It contains convenience
409 methods that many File Processor objects use. Any class that would like to be 426 methods that many File Processor objects use. Any class that would like to be
410 a ProcessorVisitor must implement the process_file() method.""" 427 a ProcessorVisitor must implement the process_file() method."""
411 428
412 def __init__(self, test): 429 def __init__(self, test):
413 self.test = test 430 self.test = test
414 431
415 def prepare(self): 432 def prepare(self):
416 """Perform any initial setup required before the test is run.""" 433 """Perform any initial setup required before the test is run."""
417 pass 434 pass
418 435
419 def calculate_geometric_mean(self, platform, variant, svn_revision): 436 def calculate_geometric_mean(self, platform, variant, svn_revision):
420 """Calculate the aggregate geometric mean for JS and frog benchmark sets, 437 """Calculate the aggregate geometric mean for JS and frog benchmark sets,
421 given two benchmark dictionaries.""" 438 given two benchmark dictionaries."""
422 geo_mean = 0 439 geo_mean = 0
423 for benchmark in self.test.values_list: 440 # TODO(vsm): Suppress graphing this combination altogether. For
424 geo_mean += math.log(self.test.values_dict[platform][variant][benchmark][ 441 # now, we feed a geomean of 0.
425 len(self.test.values_dict[platform][variant][benchmark]) - 1]) 442 if self.test.is_valid_combination(platform, variant):
443 for benchmark in self.test.values_list:
444 geo_mean += math.log(
445 self.test.values_dict[platform][variant][benchmark][
446 len(self.test.values_dict[platform][variant][benchmark]) - 1])
426 447
427 self.test.values_dict[platform][variant]['Geo-Mean'] += \ 448 self.test.values_dict[platform][variant]['Geo-Mean'] += \
428 [math.pow(math.e, geo_mean / len(self.test.values_list))] 449 [math.pow(math.e, geo_mean / len(self.test.values_list))]
429 self.test.revision_dict[platform][variant]['Geo-Mean'] += [svn_revision] 450 self.test.revision_dict[platform][variant]['Geo-Mean'] += [svn_revision]
430 451
431 452
432 class Grapher(object): 453 class Grapher(object):
433 """The base level visitor class that generates graphs for data. It contains 454 """The base level visitor class that generates graphs for data. It contains
434 convenience methods that many Grapher objects use. Any class that would like 455 convenience methods that many Grapher objects use. Any class that would like
435 to be a GrapherVisitor must implement the plot_results() method.""" 456 to be a GrapherVisitor must implement the plot_results() method."""
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 def plot_avg_perf(self, png_filename): 580 def plot_avg_perf(self, png_filename):
560 """Generate a plot that shows the performance changes of the geomentric 581 """Generate a plot that shows the performance changes of the geomentric
561 mean of JS and frog benchmark performance over svn history.""" 582 mean of JS and frog benchmark performance over svn history."""
562 (title, y_axis, size_x, size_y, loc, filename) = \ 583 (title, y_axis, size_x, size_y, loc, filename) = \
563 ('Geometric Mean of benchmark %s performance on %s ' % 584 ('Geometric Mean of benchmark %s performance on %s ' %
564 (self.test.platform_type, utils.GuessOS()), 'Speed (bigger = better)', 585 (self.test.platform_type, utils.GuessOS()), 'Speed (bigger = better)',
565 16, 5, 'lower left', 'avg'+png_filename) 586 16, 5, 'lower left', 'avg'+png_filename)
566 clear_axis = True 587 clear_axis = True
567 for platform in self.test.platform_list: 588 for platform in self.test.platform_list:
568 for version in self.test.versions: 589 for version in self.test.versions:
569 for metric in self.test.extra_metrics: 590 if self.test.is_valid_combination(platform, version):
570 self.style_and_save_perf_plot(title, y_axis, size_x, size_y, loc, 591 for metric in self.test.extra_metrics:
571 filename, [platform], [version], 592 self.style_and_save_perf_plot(title, y_axis, size_x, size_y, loc,
572 [metric], clear_axis) 593 filename, [platform], [version],
573 clear_axis = False 594 [metric], clear_axis)
595 clear_axis = False
574 596
575 def plot_results(self, png_filename): 597 def plot_results(self, png_filename):
576 self.plot_all_perf(png_filename) 598 self.plot_all_perf(png_filename)
577 self.plot_avg_perf('2' + png_filename) 599 self.plot_avg_perf('2' + png_filename)
578 600
579 601
580 class CommonCommandLineTest(RuntimePerformanceTest): 602 class CommonCommandLineTest(RuntimePerformanceTest):
581 """Run the basic performance tests (Benchpress, some V8 benchmarks) from the 603 """Run the basic performance tests (Benchpress, some V8 benchmarks) from the
582 command line.""" 604 command line."""
583 605
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 [revision_num] 671 [revision_num]
650 self.test.values_dict['commandline']['frog'][benchmark] += \ 672 self.test.values_dict['commandline']['frog'][benchmark] += \
651 [frog_value] 673 [frog_value]
652 f.close() 674 f.close()
653 675
654 self.calculate_geometric_mean('commandline', 'frog', revision_num) 676 self.calculate_geometric_mean('commandline', 'frog', revision_num)
655 self.calculate_geometric_mean('commandline', 'js', revision_num) 677 self.calculate_geometric_mean('commandline', 'js', revision_num)
656 678
657 679
658 class BrowserTester(Tester): 680 class BrowserTester(Tester):
659 # TODO(vsm): Add Dartium.
660 @staticmethod 681 @staticmethod
661 def get_browsers(): 682 def get_browsers():
662 browsers = ['ff', 'chrome'] 683 browsers = ['dartium', 'ff', 'chrome']
684 has_shell = False
663 if platform.system() == 'Darwin': 685 if platform.system() == 'Darwin':
664 browsers += ['safari'] 686 browsers += ['safari']
665 if platform.system() == 'Windows': 687 if platform.system() == 'Windows':
666 browsers += ['ie'] 688 browsers += ['ie']
689 has_shell = True
690 if 'dartium' in browsers:
691 # Fetch it if necessary.
692 get_dartium = ['python',
693 os.path.join(DART_INSTALL_LOCATION, 'tools', 'get_drt.py'),
694 '--dartium']
695 # TODO(vsm): It's inconvenient that run_cmd isn't in scope here.
696 # Perhaps there is a better place to put that or this.
697 subprocess.Popen(get_dartium, shell=has_shell)
667 return browsers 698 return browsers
668 699
669 700
670 class CommonBrowserTest(RuntimePerformanceTest): 701 class CommonBrowserTest(RuntimePerformanceTest):
671 """Runs this basic performance tests (Benchpress, some V8 benchmarks) in the 702 """Runs this basic performance tests (Benchpress, some V8 benchmarks) in the
672 browser.""" 703 browser."""
673 704
674 def __init__(self, test_runner): 705 def __init__(self, test_runner):
675 """Args: 706 """Args:
676 test_runner: Reference to the object that notifies us when to run.""" 707 test_runner: Reference to the object that notifies us when to run."""
(...skipping 18 matching lines...) Expand all
695 class CommonBrowserTester(BrowserTester): 726 class CommonBrowserTester(BrowserTester):
696 def run_tests(self): 727 def run_tests(self):
697 """Run a performance test in the browser.""" 728 """Run a performance test in the browser."""
698 os.chdir('frog') 729 os.chdir('frog')
699 self.test.test_runner.run_cmd(['python', os.path.join('benchmarks', 730 self.test.test_runner.run_cmd(['python', os.path.join('benchmarks',
700 'make_web_benchmarks.py')]) 731 'make_web_benchmarks.py')])
701 os.chdir('..') 732 os.chdir('..')
702 733
703 for browser in BrowserTester.get_browsers(): 734 for browser in BrowserTester.get_browsers():
704 for version in self.test.versions: 735 for version in self.test.versions:
736 if not self.test.is_valid_combination(browser, version):
737 continue
705 self.test.trace_file = os.path.join( 738 self.test.trace_file = os.path.join(
706 'tools', 'testing', 'perf_testing', self.test.result_folder_name, 739 'tools', 'testing', 'perf_testing', self.test.result_folder_name,
707 'perf-%s-%s-%s' % (self.test.cur_time, browser, version)) 740 'perf-%s-%s-%s' % (self.test.cur_time, browser, version))
708 self.add_svn_revision_to_trace(self.test.trace_file) 741 self.add_svn_revision_to_trace(self.test.trace_file, browser)
709 file_path = os.path.join( 742 file_path = os.path.join(
710 os.getcwd(), 'internal', 'browserBenchmarks', 743 os.getcwd(), 'internal', 'browserBenchmarks',
711 'benchmark_page_%s.html' % version) 744 'benchmark_page_%s.html' % version)
712 self.test.test_runner.run_cmd( 745 self.test.test_runner.run_cmd(
713 ['python', os.path.join('tools', 'testing', 'run_selenium.py'), 746 ['python', os.path.join('tools', 'testing', 'run_selenium.py'),
714 '--out', file_path, '--browser', browser, 747 '--out', file_path, '--browser', browser,
715 '--timeout', '600', '--mode', 'perf'], self.test.trace_file, 748 '--timeout', '600', '--mode', 'perf'], self.test.trace_file,
716 append=True) 749 append=True)
717 750
718 class CommonBrowserFileProcessor(Processor): 751 class CommonBrowserFileProcessor(Processor):
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
839 self.name(), BrowserTester.get_browsers(), 'browser', 872 self.name(), BrowserTester.get_browsers(), 'browser',
840 DromaeoTester.get_dromaeo_versions(), 873 DromaeoTester.get_dromaeo_versions(),
841 DromaeoTester.get_dromaeo_benchmarks(), test_runner, 874 DromaeoTester.get_dromaeo_benchmarks(), test_runner,
842 self.DromaeoPerfTester(self), 875 self.DromaeoPerfTester(self),
843 self.DromaeoFileProcessor(self)) 876 self.DromaeoFileProcessor(self))
844 877
845 @staticmethod 878 @staticmethod
846 def name(): 879 def name():
847 return 'dromaeo' 880 return 'dromaeo'
848 881
882 def is_valid_combination(self, browser, version):
883 # TODO(vsm): This avoids a bug in 32-bit Chrome (dartium)
884 # running JS dromaeo.
885 if browser == 'dartium' and version == 'js':
886 return False
887 return True
888
849 class DromaeoPerfTester(DromaeoTester): 889 class DromaeoPerfTester(DromaeoTester):
850 def run_tests(self): 890 def run_tests(self):
851 """Run dromaeo in the browser.""" 891 """Run dromaeo in the browser."""
852 892
853 # Build tests. 893 # Build tests.
854 dromaeo_path = os.path.join('samples', 'third_party', 'dromaeo') 894 dromaeo_path = os.path.join('samples', 'third_party', 'dromaeo')
855 current_path = os.getcwd() 895 current_path = os.getcwd()
856 os.chdir(dromaeo_path) 896 os.chdir(dromaeo_path)
857 self.test.test_runner.run_cmd(['python', 'generate_frog_tests.py']) 897 self.test.test_runner.run_cmd(['python', 'generate_frog_tests.py'])
858 os.chdir(current_path) 898 os.chdir(current_path)
859 899
860 versions = DromaeoTester.get_dromaeo_versions() 900 versions = DromaeoTester.get_dromaeo_versions()
861 901
862 for browser in BrowserTester.get_browsers(): 902 for browser in BrowserTester.get_browsers():
863 for version_name in versions: 903 for version_name in versions:
904 if not self.test.is_valid_combination(browser, version):
905 continue
864 version = DromaeoTest.DromaeoPerfTester.get_dromaeo_url_query( 906 version = DromaeoTest.DromaeoPerfTester.get_dromaeo_url_query(
865 version_name) 907 browser, version_name)
866 self.test.trace_file = os.path.join( 908 self.test.trace_file = os.path.join(
867 'tools', 'testing', 'perf_testing', self.test.result_folder_name, 909 'tools', 'testing', 'perf_testing', self.test.result_folder_name,
868 'dromaeo-%s-%s-%s' % (self.test.cur_time, browser, version_name)) 910 'dromaeo-%s-%s-%s' % (self.test.cur_time, browser, version_name))
869 self.add_svn_revision_to_trace(self.test.trace_file) 911 self.add_svn_revision_to_trace(self.test.trace_file, browser)
870 file_path = '"%s"' % os.path.join(os.getcwd(), dromaeo_path, 912 file_path = '"%s"' % os.path.join(os.getcwd(), dromaeo_path,
871 'index-js.html?%s' % version) 913 'index-js.html?%s' % version)
872 self.test.test_runner.run_cmd( 914 self.test.test_runner.run_cmd(
873 ['python', os.path.join('tools', 'testing', 'run_selenium.py'), 915 ['python', os.path.join('tools', 'testing', 'run_selenium.py'),
874 '--out', file_path, '--browser', browser, 916 '--out', file_path, '--browser', browser,
875 '--timeout', '600', '--mode', 'dromaeo'], self.test.trace_file, 917 '--timeout', '600', '--mode', 'dromaeo'], self.test.trace_file,
876 append=True) 918 append=True)
877 919
878 @staticmethod 920 @staticmethod
879 def get_dromaeo_url_query(version): 921 def get_dromaeo_url_query(browser, version):
922 if browser == 'dartium':
923 version = version.replace('frog', 'dart')
880 version = version.replace('_','&') 924 version = version.replace('_','&')
881 tags = DromaeoTester.get_valid_dromaeo_tags() 925 tags = DromaeoTester.get_valid_dromaeo_tags()
882 return '|'.join([ '%s&%s' % (version, tag) for tag in tags]) 926 return '|'.join([ '%s&%s' % (version, tag) for tag in tags])
883 927
884 928
885 class DromaeoFileProcessor(Processor): 929 class DromaeoFileProcessor(Processor):
886 def process_file(self, afile): 930 def process_file(self, afile):
887 """Comb through the html to find the performance results.""" 931 """Comb through the html to find the performance results."""
888 parts = afile.split('-') 932 parts = afile.split('-')
889 browser = parts[2] 933 browser = parts[2]
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
1221 while True: 1265 while True:
1222 if runner.has_new_code(): 1266 if runner.has_new_code():
1223 runner.run_test_sequence() 1267 runner.run_test_sequence()
1224 else: 1268 else:
1225 time.sleep(200) 1269 time.sleep(200)
1226 else: 1270 else:
1227 runner.run_test_sequence() 1271 runner.run_test_sequence()
1228 1272
1229 if __name__ == '__main__': 1273 if __name__ == '__main__':
1230 main() 1274 main()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698