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

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

Issue 10225010: Complete perf data posting. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 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 optparse 8 import optparse
9 import os 9 import os
10 from os.path import dirname, abspath 10 from os.path import dirname, abspath
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 parser.add_option('--suites', '-s', dest='suites', help='Run the specified ' 170 parser.add_option('--suites', '-s', dest='suites', help='Run the specified '
171 'comma-separated test suites from set: %s' % \ 171 'comma-separated test suites from set: %s' % \
172 ','.join(TestBuilder.available_suite_names()), 172 ','.join(TestBuilder.available_suite_names()),
173 action='store', default=None) 173 action='store', default=None)
174 parser.add_option('--forever', '-f', dest='continuous', help='Run this scri' 174 parser.add_option('--forever', '-f', dest='continuous', help='Run this scri'
175 'pt forever, always checking for the next svn checkin', 175 'pt forever, always checking for the next svn checkin',
176 action='store_true', default=False) 176 action='store_true', default=False)
177 parser.add_option('--nobuild', '-n', dest='no_build', action='store_true', 177 parser.add_option('--nobuild', '-n', dest='no_build', action='store_true',
178 help='Do not sync with the repository and do not ' 178 help='Do not sync with the repository and do not '
179 'rebuild.', default=False) 179 'rebuild.', default=False)
180 parser.add_option('--upload', '-u', dest='upload', action='store_true', 180 parser.add_option('--noupload', '-u', dest='no_upload', action='store_true',
181 help='Post the results of the run.', default=False) 181 help='Do not post the results of the run.', default=False)
182 parser.add_option('--notest', '-t', dest='no_test', action='store_true',
183 help='Do not run the tests.', default=False)
182 parser.add_option('--verbose', '-v', dest='verbose', help='Print extra ' 184 parser.add_option('--verbose', '-v', dest='verbose', help='Print extra '
183 'debug output', action='store_true', default=False) 185 'debug output', action='store_true', default=False)
184 186
185 args, ignored = parser.parse_args() 187 args, ignored = parser.parse_args()
186 188
187 if not args.suites: 189 if not args.suites:
188 suites = TestBuilder.available_suite_names() 190 suites = TestBuilder.available_suite_names()
189 else: 191 else:
190 suites = [] 192 suites = []
191 suitelist = args.suites.split(',') 193 suitelist = args.suites.split(',')
192 for name in suitelist: 194 for name in suitelist:
193 if name in TestBuilder.available_suite_names(): 195 if name in TestBuilder.available_suite_names():
194 suites.append(name) 196 suites.append(name)
195 else: 197 else:
196 print ('Error: Invalid suite %s not in ' % name) + \ 198 print ('Error: Invalid suite %s not in ' % name) + \
197 '%s' % ','.join(TestBuilder.available_suite_names()) 199 '%s' % ','.join(TestBuilder.available_suite_names())
198 sys.exit(1) 200 sys.exit(1)
199 self.suite_names = suites 201 self.suite_names = suites
200 self.no_build = args.no_build 202 self.no_build = args.no_build
201 self.upload = args.upload 203 self.no_upload = args.no_upload
204 self.no_test = args.no_test
202 self.verbose = args.verbose 205 self.verbose = args.verbose
203 return args.continuous 206 return args.continuous
204 207
205 def run_test_sequence(self): 208 def run_test_sequence(self):
206 """Run the set of commands to (possibly) build, run, and graph the results 209 """Run the set of commands to (possibly) build, run, and graph the results
207 of our tests. 210 of our tests.
208 211
209 Args: 212 Args:
210 suite_names: The "display name" the user enters to specify which 213 suite_names: The "display name" the user enters to specify which
211 benchmark(s) to run. 214 benchmark(s) to run.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 269
267 def run(self): 270 def run(self):
268 """Run the benchmarks/tests from the command line and plot the 271 """Run the benchmarks/tests from the command line and plot the
269 results. 272 results.
270 """ 273 """
271 for visitor in [self.tester, self.file_processor]: 274 for visitor in [self.tester, self.file_processor]:
272 visitor.prepare() 275 visitor.prepare()
273 276
274 os.chdir(DART_INSTALL_LOCATION) 277 os.chdir(DART_INSTALL_LOCATION)
275 self.test_runner.ensure_output_directory(self.result_folder_name) 278 self.test_runner.ensure_output_directory(self.result_folder_name)
276 self.tester.run_tests() 279 if not self.test_runner.no_test:
280 self.tester.run_tests()
277 281
278 os.chdir(os.path.join('tools', 'testing', 'perf_testing')) 282 os.chdir(os.path.join('tools', 'testing', 'perf_testing'))
279 283
280 # TODO(efortuna): Remove trace files once uploaded. This will happen in a
281 # future CL.
282 files = os.listdir(self.result_folder_name) 284 files = os.listdir(self.result_folder_name)
283 for afile in files: 285 for afile in files:
284 if not afile.startswith('.'): 286 if not afile.startswith('.'):
285 self.file_processor.process_file(afile) 287 if self.file_processor.process_file(afile):
288 os.remove(os.path.join(self.result_folder_name, afile))
286 289
287 290
288 class Tester(object): 291 class Tester(object):
289 """The base level visitor class that runs tests. It contains convenience 292 """The base level visitor class that runs tests. It contains convenience
290 methods that many Tester objects use. Any class that would like to be a 293 methods that many Tester objects use. Any class that would like to be a
291 TesterVisitor must implement the run_tests() method.""" 294 TesterVisitor must implement the run_tests() method."""
292 295
293 def __init__(self, test): 296 def __init__(self, test):
294 self.test = test 297 self.test = test
295 298
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 os.getcwd(), 'internal', 'browserBenchmarks', 461 os.getcwd(), 'internal', 'browserBenchmarks',
459 'benchmark_page_%s.html' % version) 462 'benchmark_page_%s.html' % version)
460 self.test.test_runner.run_cmd( 463 self.test.test_runner.run_cmd(
461 ['python', os.path.join('tools', 'testing', 'run_selenium.py'), 464 ['python', os.path.join('tools', 'testing', 'run_selenium.py'),
462 '--out', file_path, '--browser', browser, 465 '--out', file_path, '--browser', browser,
463 '--timeout', '600', '--mode', 'perf'], self.test.trace_file, 466 '--timeout', '600', '--mode', 'perf'], self.test.trace_file,
464 append=True) 467 append=True)
465 468
466 class CommonBrowserFileProcessor(Processor): 469 class CommonBrowserFileProcessor(Processor):
467 def process_file(self, afile): 470 def process_file(self, afile):
468 """Comb through the html to find the performance results.""" 471 """Comb through the html to find the performance results.
472 Returns: True if we successfullly posted our data to storage."""
469 os.chdir(os.path.join(DART_INSTALL_LOCATION, 'tools', 473 os.chdir(os.path.join(DART_INSTALL_LOCATION, 'tools',
470 'testing', 'perf_testing')) 474 'testing', 'perf_testing'))
475 if self.test.test_runner.no_upload:
476 return
471 parts = afile.split('-') 477 parts = afile.split('-')
472 browser = parts[2] 478 browser = parts[2]
473 version = parts[3] 479 version = parts[3]
474 f = open(os.path.join(self.test.result_folder_name, afile)) 480 f = open(os.path.join(self.test.result_folder_name, afile))
475 lines = f.readlines() 481 lines = f.readlines()
476 line = '' 482 line = ''
477 i = 0 483 i = 0
478 revision_num = 0 484 revision_num = 0
479 while '<div id="results">' not in line and i < len(lines): 485 while '<div id="results">' not in line and i < len(lines):
480 if 'Revision' in line: 486 if 'Revision' in line:
481 revision_num = int(line.split()[1].strip('"')) 487 revision_num = int(line.split()[1].strip('"'))
482 line = lines[i] 488 line = lines[i]
483 i += 1 489 i += 1
484 490
485 if i >= len(lines) or revision_num == 0: 491 if i >= len(lines) or revision_num == 0:
486 # Then this run did not complete. Ignore this tracefile. 492 # Then this run did not complete. Ignore this tracefile.
487 return 493 return
488 494
489 line = lines[i] 495 line = lines[i]
490 i += 1 496 i += 1
491 results = [] 497 results = []
492 if line.find('<br>') > -1: 498 if line.find('<br>') > -1:
493 results = line.split('<br>') 499 results = line.split('<br>')
494 else: 500 else:
495 results = line.split('<br />') 501 results = line.split('<br />')
502 upload_success = True
496 for result in results: 503 for result in results:
497 name_and_score = result.split(':') 504 name_and_score = result.split(':')
498 if len(name_and_score) < 2: 505 if len(name_and_score) < 2:
499 break 506 break
500 name = name_and_score[0].strip() 507 name = name_and_score[0].strip()
501 score = name_and_score[1].strip() 508 score = name_and_score[1].strip()
502 if version == 'js' or version == 'v8': 509 if version == 'js' or version == 'v8':
503 version = 'js' 510 version = 'js'
504 if self.test.test_runner.upload: 511 upload_success = upload_success and self.report_results(
505 self.report_results(name, score, browser, version, revision_num, 512 name, score, browser, version, revision_num, self.SCORE)
506 self.SCORE)
507 513
508 f.close() 514 f.close()
515 return upload_success
509 516
510 517
511 class DromaeoTester(Tester): 518 class DromaeoTester(Tester):
512 DROMAEO_BENCHMARKS = { 519 DROMAEO_BENCHMARKS = {
513 'attr': ('attributes', [ 520 'attr': ('attributes', [
514 'getAttribute', 521 'getAttribute',
515 'element.property', 522 'element.property',
516 'setAttribute', 523 'setAttribute',
517 'element.property = value']), 524 'element.property = value']),
518 'modify': ('modify', [ 525 'modify': ('modify', [
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 def get_dromaeo_url_query(browser, version): 641 def get_dromaeo_url_query(browser, version):
635 if browser == 'dartium': 642 if browser == 'dartium':
636 version = version.replace('frog', 'dart') 643 version = version.replace('frog', 'dart')
637 version = version.replace('_','&') 644 version = version.replace('_','&')
638 tags = DromaeoTester.get_valid_dromaeo_tags() 645 tags = DromaeoTester.get_valid_dromaeo_tags()
639 return '|'.join([ '%s&%s' % (version, tag) for tag in tags]) 646 return '|'.join([ '%s&%s' % (version, tag) for tag in tags])
640 647
641 648
642 class DromaeoFileProcessor(Processor): 649 class DromaeoFileProcessor(Processor):
643 def process_file(self, afile): 650 def process_file(self, afile):
644 """Comb through the html to find the performance results.""" 651 """Comb through the html to find the performance results.
652 Returns: True if we successfullly posted our data to storage."""
653 if self.test.test_runner.no_upload:
654 return
645 parts = afile.split('-') 655 parts = afile.split('-')
646 browser = parts[2] 656 browser = parts[2]
647 version = parts[3] 657 version = parts[3]
648 658
649 f = open(os.path.join(self.test.result_folder_name, afile)) 659 f = open(os.path.join(self.test.result_folder_name, afile))
650 lines = f.readlines() 660 lines = f.readlines()
651 i = 0 661 i = 0
652 revision_num = 0 662 revision_num = 0
653 revision_pattern = r'Revision: (\d+)' 663 revision_pattern = r'Revision: (\d+)'
654 suite_pattern = r'<div class="result-item done">(.+?)</ol></div>' 664 suite_pattern = r'<div class="result-item done">(.+?)</ol></div>'
655 result_pattern = r'<b>(.+?)</b>(.+?)<small> runs/s(.+)' 665 result_pattern = r'<b>(.+?)</b>(.+?)<small> runs/s(.+)'
656 666
667 upload_success = True
657 for line in lines: 668 for line in lines:
658 rev = re.match(revision_pattern, line.strip()) 669 rev = re.match(revision_pattern, line.strip())
659 if rev: 670 if rev:
660 revision_num = int(rev.group(1)) 671 revision_num = int(rev.group(1))
661 continue 672 continue
662 673
663 suite_results = re.findall(suite_pattern, line) 674 suite_results = re.findall(suite_pattern, line)
664 if suite_results: 675 if suite_results:
665 for suite_result in suite_results: 676 for suite_result in suite_results:
666 results = re.findall(r'<li>(.*?)</li>', suite_result) 677 results = re.findall(r'<li>(.*?)</li>', suite_result)
667 if results: 678 if results:
668 for result in results: 679 for result in results:
669 r = re.match(result_pattern, result) 680 r = re.match(result_pattern, result)
670 name = DromaeoTester.legalize_filename(r.group(1).strip(':')) 681 name = DromaeoTester.legalize_filename(r.group(1).strip(':'))
671 score = float(r.group(2)) 682 score = float(r.group(2))
672 if self.test.test_runner.upload: 683 upload_success = upload_success and self.report_results(
673 self.report_results(name, score, browser, version, 684 name, score, browser, version, revision_num, self.SCORE)
674 revision_num, self.SCORE)
675 685
676 f.close() 686 f.close()
687 return upload_success
677 688
678 689
679 class DromaeoSizeTest(Test): 690 class DromaeoSizeTest(Test):
680 """Run tests to determine the compiled file output size of Dromaeo.""" 691 """Run tests to determine the compiled file output size of Dromaeo."""
681 def __init__(self, test_runner): 692 def __init__(self, test_runner):
682 super(DromaeoSizeTest, self).__init__( 693 super(DromaeoSizeTest, self).__init__(
683 self.name(), 694 self.name(),
684 ['browser'], ['dart', 'frog_dom', 'frog_html', 'frog_htmlidiomatic'], 695 ['browser'], ['dart', 'frog_dom', 'frog_html', 'frog_htmlidiomatic'],
685 DromaeoTester.DROMAEO_BENCHMARKS.keys(), test_runner, 696 DromaeoTester.DROMAEO_BENCHMARKS.keys(), test_runner,
686 self.DromaeoSizeTester(self), 697 self.DromaeoSizeTester(self),
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 ['echo', 'Size (%s, %s): %s' % (variant, 'sum', 763 ['echo', 'Size (%s, %s): %s' % (variant, 'sum',
753 total_size[variant])], 764 total_size[variant])],
754 self.test.trace_file, append=True) 765 self.test.trace_file, append=True)
755 766
756 767
757 class DromaeoSizeProcessor(Processor): 768 class DromaeoSizeProcessor(Processor):
758 def process_file(self, afile): 769 def process_file(self, afile):
759 """Pull all the relevant information out of a given tracefile. 770 """Pull all the relevant information out of a given tracefile.
760 771
761 Args: 772 Args:
762 afile: is the filename string we will be processing.""" 773 afile: is the filename string we will be processing.
774 Returns: True if we successfullly posted our data to storage."""
763 os.chdir(os.path.join(DART_INSTALL_LOCATION, 'tools', 775 os.chdir(os.path.join(DART_INSTALL_LOCATION, 'tools',
764 'testing', 'perf_testing')) 776 'testing', 'perf_testing'))
777 if self.test.test_runner.no_upload:
778 return
765 f = open(os.path.join(self.test.result_folder_name, afile)) 779 f = open(os.path.join(self.test.result_folder_name, afile))
766 tabulate_data = False 780 tabulate_data = False
767 revision_num = 0 781 revision_num = 0
768 revision_pattern = r'Revision: (\d+)' 782 revision_pattern = r'Revision: (\d+)'
769 result_pattern = r'Size \((\w+), ([a-zA-Z0-9-]+)\): (\d+)' 783 result_pattern = r'Size \((\w+), ([a-zA-Z0-9-]+)\): (\d+)'
770 784
785 upload_success = True
771 for line in f.readlines(): 786 for line in f.readlines():
772 rev = re.match(revision_pattern, line.strip()) 787 rev = re.match(revision_pattern, line.strip())
773 if rev: 788 if rev:
774 revision_num = int(rev.group(1)) 789 revision_num = int(rev.group(1))
775 continue 790 continue
776 791
777 result = re.match(result_pattern, line.strip()) 792 result = re.match(result_pattern, line.strip())
778 if result: 793 if result:
779 variant = result.group(1) 794 variant = result.group(1)
780 metric = result.group(2) 795 metric = result.group(2)
781 num = result.group(3) 796 num = result.group(3)
782 if num.find('.') == -1: 797 if num.find('.') == -1:
783 num = int(num) 798 num = int(num)
784 else: 799 else:
785 num = float(num) 800 num = float(num)
786 if self.test.test_runner.upload: 801 upload_success = upload_success and self.report_results(
787 self.report_results(metric, num, 'browser', variant, revision_num, 802 metric, num, 'browser', variant, revision_num, self.CODE_SIZE)
788 self.CODE_SIZE)
789 803
790 f.close() 804 f.close()
805 return upload_success
791 806
792 807
793 class CompileTimeAndSizeTest(Test): 808 class CompileTimeAndSizeTest(Test):
794 """Run tests to determine how long frogc takes to compile, and the compiled 809 """Run tests to determine how long frogc takes to compile, and the compiled
795 file output size of some benchmarking files.""" 810 file output size of some benchmarking files."""
796 def __init__(self, test_runner): 811 def __init__(self, test_runner):
797 """Reference to the test_runner object that notifies us when to begin 812 """Reference to the test_runner object that notifies us when to begin
798 testing.""" 813 testing."""
799 super(CompileTimeAndSizeTest, self).__init__( 814 super(CompileTimeAndSizeTest, self).__init__(
800 self.name(), ['commandline'], ['frog'], ['swarm', 'total'], 815 self.name(), ['commandline'], ['frog'], ['swarm', 'total'],
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 871
857 os.chdir('..') 872 os.chdir('..')
858 873
859 874
860 class CompileProcessor(Processor): 875 class CompileProcessor(Processor):
861 876
862 def process_file(self, afile): 877 def process_file(self, afile):
863 """Pull all the relevant information out of a given tracefile. 878 """Pull all the relevant information out of a given tracefile.
864 879
865 Args: 880 Args:
866 afile: is the filename string we will be processing.""" 881 afile: is the filename string we will be processing.
882 Returns: True if we successfullly posted our data to storage."""
867 os.chdir(os.path.join(DART_INSTALL_LOCATION, 'tools', 883 os.chdir(os.path.join(DART_INSTALL_LOCATION, 'tools',
868 'testing', 'perf_testing')) 884 'testing', 'perf_testing'))
885 if self.test.test_runner.no_upload:
886 return
869 f = open(os.path.join(self.test.result_folder_name, afile)) 887 f = open(os.path.join(self.test.result_folder_name, afile))
870 tabulate_data = False 888 tabulate_data = False
871 revision_num = 0 889 revision_num = 0
890 upload_success = True
872 for line in f.readlines(): 891 for line in f.readlines():
873 tokens = line.split() 892 tokens = line.split()
874 if 'Revision' in line: 893 if 'Revision' in line:
875 revision_num = int(line.split()[1]) 894 revision_num = int(line.split()[1])
876 else: 895 else:
877 for metric in self.test.values_list: 896 for metric in self.test.values_list:
878 if metric in line: 897 if metric in line:
879 num = tokens[0] 898 num = tokens[0]
880 if num.find('.') == -1: 899 if num.find('.') == -1:
881 num = int(num) 900 num = int(num)
882 else: 901 else:
883 num = float(num) 902 num = float(num)
884 score_type = self.CODE_SIZE 903 score_type = self.CODE_SIZE
885 if 'Compiling' in metric or 'Bootstrapping' in metric: 904 if 'Compiling' in metric or 'Bootstrapping' in metric:
886 score_type = self.COMPILE_TIME 905 score_type = self.COMPILE_TIME
887 if self.test.test_runner.upload: 906 upload_success = upload_success and self.report_results(
888 self.report_results(metric, num, 'commandline', 'frog', 907 metric, num, 'commandline', 'frog', revision_num, score_type)
889 revision_num, score_type)
890 908
891 f.close() 909 f.close()
910 return upload_success
892 911
893 912
894 class TestBuilder(object): 913 class TestBuilder(object):
895 """Construct the desired test object.""" 914 """Construct the desired test object."""
896 available_suites = dict((suite.name(), suite) for suite in [ 915 available_suites = dict((suite.name(), suite) for suite in [
897 CompileTimeAndSizeTest, CommonBrowserTest, DromaeoTest, DromaeoSizeTest]) 916 CompileTimeAndSizeTest, CommonBrowserTest, DromaeoTest, DromaeoSizeTest])
898 917
899 @staticmethod 918 @staticmethod
900 def make_test(test_name, test_runner): 919 def make_test(test_name, test_runner):
901 return TestBuilder.available_suites[test_name](test_runner) 920 return TestBuilder.available_suites[test_name](test_runner)
(...skipping 10 matching lines...) Expand all
912 while True: 931 while True:
913 if runner.has_new_code(): 932 if runner.has_new_code():
914 runner.run_test_sequence() 933 runner.run_test_sequence()
915 else: 934 else:
916 time.sleep(200) 935 time.sleep(200)
917 else: 936 else:
918 runner.run_test_sequence() 937 runner.run_test_sequence()
919 938
920 if __name__ == '__main__': 939 if __name__ == '__main__':
921 main() 940 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