OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 | 2 |
3 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 3 # Copyright (c) 2012, 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 import optparse | 9 import optparse |
10 import os | 10 import os |
11 from os.path import dirname, abspath | 11 from os.path import dirname, abspath |
12 import pickle | 12 import pickle |
13 import platform | 13 import platform |
14 import random | 14 import random |
15 import re | 15 import re |
16 import shutil | 16 import shutil |
17 import stat | 17 import stat |
18 import subprocess | 18 import subprocess |
19 import sys | 19 import sys |
20 import time | 20 import time |
21 | 21 |
22 TOOLS_PATH = os.path.join(dirname(dirname(dirname(abspath(__file__))))) | 22 TOOLS_PATH = os.path.join(dirname(dirname(dirname(abspath(__file__))))) |
23 TOP_LEVEL_DIR = abspath(os.path.join(dirname(abspath(__file__)), '..', '..', | 23 TOP_LEVEL_DIR = abspath(os.path.join(dirname(abspath(__file__)), '..', '..', |
24 '..')) | 24 '..')) |
25 DART_REPO_LOC = abspath(os.path.join(dirname(abspath(__file__)), '..', '..', | 25 DART_REPO_LOC = abspath(os.path.join(dirname(abspath(__file__)), '..', '..', |
26 '..', '..', '..', | 26 '..', '..', '..', |
27 'dart_checkout_for_perf_testing', | 27 'dart_checkout_for_perf_testing', |
28 'dart')) | 28 'dart')) |
29 # How far back in time we want to test. | 29 # How far back in time we want to test. |
30 EARLIEST_REVISION = 6285 | 30 EARLIEST_REVISION = 33076 |
31 FIRST_CHROMEDRIVER = 7823 | |
32 sys.path.append(TOOLS_PATH) | 31 sys.path.append(TOOLS_PATH) |
33 sys.path.append(os.path.join(TOP_LEVEL_DIR, 'internal', 'tests')) | 32 sys.path.append(os.path.join(TOP_LEVEL_DIR, 'internal', 'tests')) |
34 import post_results | 33 import post_results |
35 import utils | 34 import utils |
36 | 35 |
37 """This script runs to track performance and size progress of | 36 """This script runs to track performance and size progress of |
38 different svn revisions. It tests to see if there a newer version of the code on | 37 different svn revisions. It tests to see if there a newer version of the code on |
39 the server, and will sync and run the performance tests if so.""" | 38 the server, and will sync and run the performance tests if so.""" |
40 class TestRunner(object): | 39 class TestRunner(object): |
41 | 40 |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 browsers += ['dartium'] | 619 browsers += ['dartium'] |
621 has_shell = False | 620 has_shell = False |
622 if platform.system() == 'Darwin': | 621 if platform.system() == 'Darwin': |
623 browsers += ['safari'] | 622 browsers += ['safari'] |
624 if platform.system() == 'Windows': | 623 if platform.system() == 'Windows': |
625 browsers += ['ie'] | 624 browsers += ['ie'] |
626 has_shell = True | 625 has_shell = True |
627 return browsers | 626 return browsers |
628 | 627 |
629 | 628 |
630 class CommonBrowserTest(RuntimePerformanceTest): | |
631 """Runs this basic performance tests (Benchpress, some V8 benchmarks) in the | |
632 browser.""" | |
633 | |
634 def __init__(self, test_runner): | |
635 """Args: | |
636 test_runner: Reference to the object that notifies us when to run.""" | |
637 super(CommonBrowserTest, self).__init__( | |
638 self.Name(), BrowserTester.GetBrowsers(False), | |
639 'browser', ['js', 'dart2js'], | |
640 self.GetStandaloneBenchmarks(), test_runner, | |
641 self.CommonBrowserTester(self), | |
642 self.CommonBrowserFileProcessor(self)) | |
643 | |
644 @staticmethod | |
645 def Name(): | |
646 return 'browser-perf' | |
647 | |
648 @staticmethod | |
649 def GetStandaloneBenchmarks(): | |
650 return ['Mandelbrot', 'DeltaBlue', 'Richards', 'NBody', 'BinaryTrees', | |
651 'Fannkuch', 'Meteor', 'BubbleSort', 'Fibonacci', 'Loop', 'Permute', | |
652 'Queens', 'QuickSort', 'Recurse', 'Sieve', 'Sum', 'Tak', 'Takl', 'Towers', | |
653 'TreeSort'] | |
654 | |
655 class CommonBrowserTester(BrowserTester): | |
656 def RunTests(self): | |
657 """Run a performance test in the browser.""" | |
658 os.chdir(DART_REPO_LOC) | |
659 self.test.test_runner.RunCmd([ | |
660 'python', os.path.join('internal', 'browserBenchmarks', | |
661 'make_web_benchmarks.py')]) | |
662 | |
663 for browser in self.test.platform_list: | |
664 for version in self.test.versions: | |
665 if not self.test.IsValidCombination(browser, version): | |
666 continue | |
667 self.test.trace_file = os.path.join(TOP_LEVEL_DIR, | |
668 'tools', 'testing', 'perf_testing', self.test.result_folder_name, | |
669 'perf-%s-%s-%s' % (self.test.cur_time, browser, version)) | |
670 self.AddSvnRevisionToTrace(self.test.trace_file, browser) | |
671 file_path = os.path.join( | |
672 os.getcwd(), 'internal', 'browserBenchmarks', 'V8vDart', | |
673 'V8vDart_page_%s.html' % version) | |
674 self.test.test_runner.RunCmd( | |
675 ['python', os.path.join('tools', 'testing', 'run_selenium.py'), | |
676 '--out', '"file:///%s"' % file_path, '--browser', browser, | |
677 '--timeout', '600', '--mode', 'perf'], self.test.trace_file, | |
678 append=True) | |
679 | |
680 class CommonBrowserFileProcessor(Processor): | |
681 | |
682 def ProcessFile(self, afile, should_post_file): | |
683 """Comb through the html to find the performance results. | |
684 Returns: True if we successfully posted our data to storage and/or we can | |
685 delete the trace file.""" | |
686 os.chdir(os.path.join(TOP_LEVEL_DIR, 'tools', | |
687 'testing', 'perf_testing')) | |
688 parts = afile.split('-') | |
689 browser = parts[2] | |
690 version = parts[3] | |
691 f = self.OpenTraceFile(afile, should_post_file) | |
692 lines = f.readlines() | |
693 line = '' | |
694 i = 0 | |
695 revision_num = 0 | |
696 while '<div id="results">' not in line and i < len(lines): | |
697 if 'Revision' in line: | |
698 revision_num = int(line.split()[1].strip('"')) | |
699 line = lines[i] | |
700 i += 1 | |
701 | |
702 if i >= len(lines) or revision_num == 0: | |
703 # Then this run did not complete. Ignore this tracefile. | |
704 return True | |
705 | |
706 line = lines[i] | |
707 i += 1 | |
708 results = [] | |
709 if line.find('<br>') > -1: | |
710 results = line.split('<br>') | |
711 else: | |
712 results = line.split('<br />') | |
713 if results == []: | |
714 return True | |
715 upload_success = True | |
716 for result in results: | |
717 name_and_score = result.split(':') | |
718 if len(name_and_score) < 2: | |
719 break | |
720 name = name_and_score[0].strip() | |
721 score = name_and_score[1].strip() | |
722 if version == 'js' or version == 'v8': | |
723 version = 'js' | |
724 bench_dict = self.test.values_dict[browser][version] | |
725 bench_dict[name] += [float(score)] | |
726 self.test.revision_dict[browser][version][name] += [revision_num] | |
727 if not self.test.test_runner.no_upload and should_post_file: | |
728 upload_success = upload_success and self.ReportResults( | |
729 name, score, browser, version, revision_num, | |
730 self.GetScoreType(name)) | |
731 else: | |
732 upload_success = False | |
733 | |
734 f.close() | |
735 self.CalculateGeometricMean(browser, version, revision_num) | |
736 return upload_success | |
737 | |
738 | |
739 class DromaeoTester(Tester): | 629 class DromaeoTester(Tester): |
740 DROMAEO_BENCHMARKS = { | 630 DROMAEO_BENCHMARKS = { |
741 'attr': ('attributes', [ | 631 'attr': ('attributes', [ |
742 'getAttribute', | 632 'getAttribute', |
743 'element.property', | 633 'element.property', |
744 'setAttribute', | 634 'setAttribute', |
745 'element.property = value']), | 635 'element.property = value']), |
746 'modify': ('modify', [ | 636 'modify': ('modify', [ |
747 'createElement', | 637 'createElement', |
748 'createTextNode', | 638 'createTextNode', |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
816 DromaeoTester.GetDromaeoVersions(), | 706 DromaeoTester.GetDromaeoVersions(), |
817 DromaeoTester.GetDromaeoBenchmarks(), test_runner, | 707 DromaeoTester.GetDromaeoBenchmarks(), test_runner, |
818 self.DromaeoPerfTester(self), | 708 self.DromaeoPerfTester(self), |
819 self.DromaeoFileProcessor(self)) | 709 self.DromaeoFileProcessor(self)) |
820 | 710 |
821 @staticmethod | 711 @staticmethod |
822 def Name(): | 712 def Name(): |
823 return 'dromaeo' | 713 return 'dromaeo' |
824 | 714 |
825 class DromaeoPerfTester(DromaeoTester): | 715 class DromaeoPerfTester(DromaeoTester): |
826 def MoveChromeDriverIfNeeded(self, browser): | |
827 """Move the appropriate version of ChromeDriver onto the path. | |
828 TODO(efortuna): This is a total hack because the latest version of Chrome | |
829 (Dartium builds) requires a different version of ChromeDriver, that is | |
830 incompatible with the release or beta Chrome and vice versa. Remove these | |
831 shenanigans once we're back to both versions of Chrome using the same | |
832 version of ChromeDriver. IMPORTANT NOTE: This assumes your chromedriver is | |
833 in the default location (inside depot_tools). | |
834 | |
835 Returns: True if we were successfully able to download a new version of | |
836 chromedriver and/or move the correct chromedriver into position. | |
837 """ | |
838 current_dir = os.getcwd() | |
839 self.test.test_runner.GetArchive('chromedriver') | |
840 path = os.environ['PATH'].split(os.pathsep) | |
841 orig_chromedriver_path = os.path.join(DART_REPO_LOC, 'tools', 'testing', | |
842 'orig-chromedriver') | |
843 dartium_chromedriver_path = os.path.join(DART_REPO_LOC, 'tools', | |
844 'testing', | |
845 'dartium-chromedriver') | |
846 extension = '' | |
847 if platform.system() == 'Windows': | |
848 extension = '.exe' | |
849 | |
850 def MoveChromedriver(depot_tools, copy_to_depot_tools_dir=True, | |
851 from_path=None): | |
852 if from_path: | |
853 from_dir = from_path + extension | |
854 else: | |
855 from_dir = os.path.join(orig_chromedriver_path, | |
856 'chromedriver' + extension) | |
857 to_dir = os.path.join(depot_tools, 'chromedriver' + extension) | |
858 if not copy_to_depot_tools_dir: | |
859 tmp = to_dir | |
860 to_dir = from_dir | |
861 from_dir = tmp | |
862 print >> sys.stderr, from_dir | |
863 print >> sys.stderr, to_dir | |
864 if not os.path.exists(os.path.dirname(to_dir)): | |
865 os.makedirs(os.path.dirname(to_dir)) | |
866 if not os.path.exists(os.path.dirname(from_dir)): | |
867 os.makedirs(os.path.dirname(from_dir)) | |
868 shutil.copyfile(from_dir, to_dir) | |
869 | |
870 for loc in path: | |
871 if 'depot_tools' in loc: | |
872 if browser == 'chrome': | |
873 if os.path.exists(orig_chromedriver_path): | |
874 MoveChromedriver(loc) | |
875 elif browser == 'dartium': | |
876 if (int(self.test.test_runner.current_revision_num) < | |
877 FIRST_CHROMEDRIVER): | |
878 # If we don't have a stashed different chromedriver just use | |
879 # the regular chromedriver. | |
880 if not os.path.exists(os.path.dirname(orig_chromedriver_path)): | |
881 os.makedirs(os.path.dirname(orig_chromedriver_path)) | |
882 self.test.test_runner.RunCmd([os.path.join( | |
883 TOP_LEVEL_DIR, 'tools', 'testing', 'webdriver_test_setup.py'), | |
884 '-f', '-p', '-s']) | |
885 elif not os.path.exists(dartium_chromedriver_path): | |
886 success, _, _ = self.test.test_runner.GetArchive('chromedriver') | |
887 if not success: | |
888 return False | |
889 # Move original chromedriver for storage. | |
890 if not os.path.exists(orig_chromedriver_path): | |
891 MoveChromedriver(loc, copy_to_depot_tools_dir=False) | |
892 if self.test.test_runner.current_revision_num >= FIRST_CHROMEDRIVER: | |
893 # Copy Dartium chromedriver into depot_tools | |
894 MoveChromedriver(loc, from_path=os.path.join( | |
895 dartium_chromedriver_path, 'chromedriver')) | |
896 os.chdir(current_dir) | |
897 return True | |
898 | |
899 def RunTests(self): | 716 def RunTests(self): |
900 """Run dromaeo in the browser.""" | 717 """Run dromaeo in the browser.""" |
901 success, _, _ = self.test.test_runner.GetArchive('dartium') | 718 success, _, _ = self.test.test_runner.GetArchive('dartium') |
902 if not success: | 719 if not success: |
903 # Unable to download dartium. Try later. | 720 # Unable to download dartium. Try later. |
904 return | 721 return |
905 | 722 |
906 # Build tests. | 723 # Build tests. |
907 dromaeo_path = os.path.join('samples', 'third_party', 'dromaeo') | 724 dromaeo_path = os.path.join('samples', 'third_party', 'dromaeo') |
908 current_path = os.getcwd() | 725 current_path = os.getcwd() |
909 os.chdir(dromaeo_path) | 726 os.chdir(dromaeo_path) |
910 if os.path.exists('generate_dart2js_tests.py'): | 727 stdout, _ = self.test.test_runner.RunCmd( |
911 stdout, _ = self.test.test_runner.RunCmd( | 728 ['python', 'generate_perf_and_dart2js_tests.py']) |
912 ['python', 'generate_dart2js_tests.py']) | |
913 else: | |
914 stdout, _ = self.test.test_runner.RunCmd( | |
915 ['python', 'generate_frog_tests.py']) | |
916 os.chdir(current_path) | 729 os.chdir(current_path) |
917 if 'Error: Compilation failed' in stdout: | 730 if 'Error: Compilation failed' in stdout: |
918 return | 731 return |
919 versions = DromaeoTester.GetDromaeoVersions() | 732 versions = DromaeoTester.GetDromaeoVersions() |
920 | 733 |
921 for browser in BrowserTester.GetBrowsers(): | 734 for browser in BrowserTester.GetBrowsers(): |
922 success = self.MoveChromeDriverIfNeeded(browser) | |
923 if not success: | |
924 return | |
925 for version_name in versions: | 735 for version_name in versions: |
926 if not self.test.IsValidCombination(browser, version_name): | 736 if not self.test.IsValidCombination(browser, version_name): |
927 continue | 737 continue |
928 version = DromaeoTest.DromaeoPerfTester.GetDromaeoUrlQuery( | 738 version = DromaeoTest.DromaeoPerfTester.GetDromaeoUrlQuery( |
929 browser, version_name) | 739 browser, version_name) |
930 self.test.trace_file = os.path.join(TOP_LEVEL_DIR, | 740 self.test.trace_file = os.path.join(TOP_LEVEL_DIR, |
931 'tools', 'testing', 'perf_testing', self.test.result_folder_name, | 741 'tools', 'testing', 'perf_testing', self.test.result_folder_name, |
932 'dromaeo-%s-%s-%s' % (self.test.cur_time, browser, version_name)) | 742 'dromaeo-%s-%s-%s' % (self.test.cur_time, browser, version_name)) |
933 self.AddSvnRevisionToTrace(self.test.trace_file, browser) | 743 self.AddSvnRevisionToTrace(self.test.trace_file, browser) |
934 file_path = os.path.join(os.getcwd(), dromaeo_path, | 744 url_path = '/'.join(['/root_dart', dromaeo_path, 'index%s.html?%s'% ( |
935 'index%s.html?%s' % ( | 745 '-dart' if version_name == 'dart_html' else '-js', |
936 '' if version_name == 'dart_html' else '-js', version)) | 746 version)]) |
| 747 |
| 748 # TODO(efortuna): Make this a separate function. We should do this |
| 749 # once per cycle. |
| 750 os.chdir(os.path.join(DART_REPO_LOC, 'tools', 'testing', 'dart', |
| 751 'browser_perf_testing')) |
| 752 self.test.test_runner.RunCmd([os.path.join(DART_REPO_LOC, |
| 753 utils.GetBuildRoot(utils.GuessOS(), 'release', 'ia32'), |
| 754 'dart-sdk', 'bin', 'pub'), 'install']) |
| 755 os.chdir(current_path) |
| 756 |
937 self.test.test_runner.RunCmd( | 757 self.test.test_runner.RunCmd( |
938 ['python', os.path.join('tools', 'testing', 'run_selenium.py'), | 758 [os.path.join(utils.GetBuildRoot( |
939 '--out', '"file:///%s"' % file_path, '--browser', browser, | 759 utils.GuessOS(), 'release', 'ia32'), 'dart-sdk', 'bin', 'dart'), |
940 '--timeout', '900', '--mode', 'dromaeo'], self.test.trace_file, | 760 '--package-root=%s' % os.path.join(DART_REPO_LOC, 'tools', |
| 761 'testing', 'dart', 'browser_perf_testing', 'packages'), |
| 762 os.path.join('tools', 'testing', 'dart', 'browser_perf_testing', |
| 763 'lib', 'browser_perf_testing.dart'), |
| 764 '--browser', browser, '--termination_test_file', |
| 765 '/root_dart/samples/third_party/dromaeo/dromaeo_end_condition.' |
| 766 'js', '--test_path', url_path], self.test.trace_file, |
941 append=True) | 767 append=True) |
942 # Put default Chromedriver back in. | |
943 self.MoveChromeDriverIfNeeded('chrome') | |
944 | 768 |
945 @staticmethod | 769 @staticmethod |
946 def GetDromaeoUrlQuery(browser, version): | 770 def GetDromaeoUrlQuery(browser, version): |
947 if browser == 'dartium': | |
948 version = version.replace('frog', 'dart') | |
949 version = version.replace('_','AND') | 771 version = version.replace('_','AND') |
950 tags = DromaeoTester.GetValidDromaeoTags() | 772 tags = DromaeoTester.GetValidDromaeoTags() |
951 return 'OR'.join([ '%sAND%s' % (version, tag) for tag in tags]) | 773 return 'OR'.join([ '%sAND%s' % (version, tag) for tag in tags]) |
952 | 774 |
953 | 775 |
954 class DromaeoFileProcessor(Processor): | 776 class DromaeoFileProcessor(Processor): |
955 def ProcessFile(self, afile, should_post_file): | 777 def ProcessFile(self, afile, should_post_file): |
956 """Comb through the html to find the performance results. | 778 """Comb through the html to find the performance results. |
957 Returns: True if we successfully posted our data to storage.""" | 779 Returns: True if we successfully posted our data to storage.""" |
958 parts = afile.split('-') | 780 parts = afile.split('-') |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
995 else: | 817 else: |
996 upload_success = False | 818 upload_success = False |
997 | 819 |
998 f.close() | 820 f.close() |
999 self.CalculateGeometricMean(browser, version, revision_num) | 821 self.CalculateGeometricMean(browser, version, revision_num) |
1000 return upload_success | 822 return upload_success |
1001 | 823 |
1002 class TestBuilder(object): | 824 class TestBuilder(object): |
1003 """Construct the desired test object.""" | 825 """Construct the desired test object.""" |
1004 available_suites = dict((suite.Name(), suite) for suite in [ | 826 available_suites = dict((suite.Name(), suite) for suite in [ |
1005 CommonBrowserTest, DromaeoTest]) | 827 DromaeoTest]) |
1006 | 828 |
1007 @staticmethod | 829 @staticmethod |
1008 def MakeTest(test_name, test_runner): | 830 def MakeTest(test_name, test_runner): |
1009 return TestBuilder.available_suites[test_name](test_runner) | 831 return TestBuilder.available_suites[test_name](test_runner) |
1010 | 832 |
1011 @staticmethod | 833 @staticmethod |
1012 def AvailableSuiteNames(): | 834 def AvailableSuiteNames(): |
1013 return TestBuilder.available_suites.keys() | 835 return TestBuilder.available_suites.keys() |
1014 | 836 |
1015 | 837 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1131 else: | 953 else: |
1132 if runner.backfill: | 954 if runner.backfill: |
1133 results_set = FillInBackHistory(results_set, runner) | 955 results_set = FillInBackHistory(results_set, runner) |
1134 else: | 956 else: |
1135 time.sleep(200) | 957 time.sleep(200) |
1136 else: | 958 else: |
1137 runner.RunTestSequence() | 959 runner.RunTestSequence() |
1138 | 960 |
1139 if __name__ == '__main__': | 961 if __name__ == '__main__': |
1140 main() | 962 main() |
OLD | NEW |