| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright 2008 the V8 project authors. All rights reserved. | 3 # Copyright 2008 the V8 project authors. All rights reserved. |
| 4 # Redistribution and use in source and binary forms, with or without | 4 # Redistribution and use in source and binary forms, with or without |
| 5 # modification, are permitted provided that the following conditions are | 5 # modification, are permitted provided that the following conditions are |
| 6 # met: | 6 # met: |
| 7 # | 7 # |
| 8 # * Redistributions of source code must retain the above copyright | 8 # * Redistributions of source code must retain the above copyright |
| 9 # notice, this list of conditions and the following disclaimer. | 9 # notice, this list of conditions and the following disclaimer. |
| 10 # * Redistributions in binary form must reproduce the above | 10 # * Redistributions in binary form must reproduce the above |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 | 29 |
| 30 import imp | 30 import imp |
| 31 import optparse | 31 import optparse |
| 32 import os | 32 import os |
| 33 from os.path import join, dirname, abspath, basename | 33 from os.path import join, dirname, abspath, basename, isdir |
| 34 import platform | 34 import platform |
| 35 import re | 35 import re |
| 36 import signal | 36 import signal |
| 37 import subprocess | 37 import subprocess |
| 38 import sys | 38 import sys |
| 39 import tempfile | 39 import tempfile |
| 40 import time | 40 import time |
| 41 import utils | 41 import utils |
| 42 | 42 |
| 43 | 43 |
| 44 VERBOSE = False | 44 VERBOSE = False |
| 45 | 45 |
| 46 | 46 |
| 47 # --------------------------------------------- | 47 # --------------------------------------------- |
| 48 # --- P r o g r e s s I n d i c a t o r s --- | 48 # --- P r o g r e s s I n d i c a t o r s --- |
| 49 # --------------------------------------------- | 49 # --------------------------------------------- |
| 50 | 50 |
| 51 | 51 |
| 52 class ProgressIndicator(object): | 52 class ProgressIndicator(object): |
| 53 | 53 |
| 54 def __init__(self, cases): | 54 def __init__(self, cases): |
| 55 self.cases = cases | 55 self.cases = cases |
| 56 self.succeeded = 0 | 56 self.succeeded = 0 |
| 57 self.failed = 0 | 57 self.failed = 0 |
| 58 self.remaining = len(self.cases) | 58 self.remaining = len(self.cases) |
| 59 self.total = len(self.cases) | 59 self.total = len(self.cases) |
| 60 self.failed_tests = [ ] | 60 self.failed_tests = [ ] |
| 61 | 61 |
| 62 def PrintFailureHeader(self, test): |
| 63 if test.IsNegative(): |
| 64 negative_marker = '[negative] ' |
| 65 else: |
| 66 negative_marker = '' |
| 67 print "=== %(label)s %(negative)s===" % { |
| 68 'label': test.GetLabel(), |
| 69 'negative': negative_marker |
| 70 } |
| 71 print "Path: %s" % "/".join(test.path) |
| 72 |
| 62 def Run(self): | 73 def Run(self): |
| 63 self.Starting() | 74 self.Starting() |
| 64 for test in self.cases: | 75 for test in self.cases: |
| 65 case = test.case | 76 case = test.case |
| 66 self.AboutToRun(case) | 77 self.AboutToRun(case) |
| 67 output = case.Run() | 78 output = case.Run() |
| 68 if output.UnexpectedOutput(): | 79 if output.UnexpectedOutput(): |
| 69 self.failed += 1 | 80 self.failed += 1 |
| 70 self.failed_tests.append(output) | 81 self.failed_tests.append(output) |
| 71 else: | 82 else: |
| (...skipping 17 matching lines...) Expand all Loading... |
| 89 | 100 |
| 90 | 101 |
| 91 class SimpleProgressIndicator(ProgressIndicator): | 102 class SimpleProgressIndicator(ProgressIndicator): |
| 92 | 103 |
| 93 def Starting(self): | 104 def Starting(self): |
| 94 print 'Running %i tests' % len(self.cases) | 105 print 'Running %i tests' % len(self.cases) |
| 95 | 106 |
| 96 def Done(self): | 107 def Done(self): |
| 97 print | 108 print |
| 98 for failed in self.failed_tests: | 109 for failed in self.failed_tests: |
| 99 print "=== %s (%s) ===" % (failed.test.GetLabel(), "/".join(failed.test.pa
th)) | 110 self.PrintFailureHeader(failed.test) |
| 100 if failed.output.stderr: | 111 if failed.output.stderr: |
| 101 print "--- stderr ---" | 112 print "--- stderr ---" |
| 102 print failed.output.stderr.strip() | 113 print failed.output.stderr.strip() |
| 103 if failed.output.stdout: | 114 if failed.output.stdout: |
| 104 print "--- stdout ---" | 115 print "--- stdout ---" |
| 105 print failed.output.stdout.strip() | 116 print failed.output.stdout.strip() |
| 106 print "Command: %s" % EscapeCommand(failed.command) | 117 print "Command: %s" % EscapeCommand(failed.command) |
| 107 if len(self.failed_tests) == 0: | 118 if len(self.failed_tests) == 0: |
| 108 print "===" | 119 print "===" |
| 109 print "=== All tests succeeded" | 120 print "=== All tests succeeded" |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 pass | 168 pass |
| 158 | 169 |
| 159 def Done(self): | 170 def Done(self): |
| 160 self.PrintProgress('Done') | 171 self.PrintProgress('Done') |
| 161 | 172 |
| 162 def AboutToRun(self, case): | 173 def AboutToRun(self, case): |
| 163 self.PrintProgress(case.GetLabel()) | 174 self.PrintProgress(case.GetLabel()) |
| 164 | 175 |
| 165 def HasRun(self, output): | 176 def HasRun(self, output): |
| 166 if output.UnexpectedOutput(): | 177 if output.UnexpectedOutput(): |
| 167 print "=== %s (%s) ===" % (output.test.GetLabel(), "/".join(output.test.pa
th)) | 178 self.ClearLine(self.last_status_length) |
| 179 self.PrintFailureHeader(output.test) |
| 168 print "Command: %s" % EscapeCommand(output.command) | 180 print "Command: %s" % EscapeCommand(output.command) |
| 169 stdout = output.output.stdout.strip() | 181 stdout = output.output.stdout.strip() |
| 170 if len(stdout): | 182 if len(stdout): |
| 171 print self.templates['stdout'] % stdout | 183 print self.templates['stdout'] % stdout |
| 172 stderr = output.output.stderr.strip() | 184 stderr = output.output.stderr.strip() |
| 173 if len(stderr): | 185 if len(stderr): |
| 174 print self.templates['stderr'] % stderr | 186 print self.templates['stderr'] % stderr |
| 175 | 187 |
| 176 def Truncate(self, str, length): | 188 def Truncate(self, str, length): |
| 177 if length and (len(str) > (length - 3)): | 189 if length and (len(str) > (length - 3)): |
| (...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 | 833 |
| 822 def __init__(self, sections, defs): | 834 def __init__(self, sections, defs): |
| 823 self.sections = sections | 835 self.sections = sections |
| 824 self.defs = defs | 836 self.defs = defs |
| 825 | 837 |
| 826 def ClassifyTests(self, cases, env): | 838 def ClassifyTests(self, cases, env): |
| 827 sections = [s for s in self.sections if s.condition.Evaluate(env, self.defs)
] | 839 sections = [s for s in self.sections if s.condition.Evaluate(env, self.defs)
] |
| 828 all_rules = reduce(list.__add__, [s.rules for s in sections], []) | 840 all_rules = reduce(list.__add__, [s.rules for s in sections], []) |
| 829 unused_rules = set(all_rules) | 841 unused_rules = set(all_rules) |
| 830 result = [ ] | 842 result = [ ] |
| 843 all_outcomes = set([]) |
| 831 for case in cases: | 844 for case in cases: |
| 832 matches = [ r for r in all_rules if r.Contains(case.path) ] | 845 matches = [ r for r in all_rules if r.Contains(case.path) ] |
| 833 outcomes = set([]) | 846 outcomes = set([]) |
| 834 for rule in matches: | 847 for rule in matches: |
| 835 outcomes = outcomes.union(rule.GetOutcomes(env, self.defs)) | 848 outcomes = outcomes.union(rule.GetOutcomes(env, self.defs)) |
| 836 unused_rules.discard(rule) | 849 unused_rules.discard(rule) |
| 837 if not outcomes: | 850 if not outcomes: |
| 838 outcomes = [PASS] | 851 outcomes = [PASS] |
| 839 case.outcomes = outcomes | 852 case.outcomes = outcomes |
| 853 all_outcomes = all_outcomes.union(outcomes) |
| 840 result.append(ClassifiedTest(case, outcomes)) | 854 result.append(ClassifiedTest(case, outcomes)) |
| 841 return (result, list(unused_rules)) | 855 return (result, list(unused_rules), all_outcomes) |
| 842 | 856 |
| 843 | 857 |
| 844 class Section(object): | 858 class Section(object): |
| 845 """A section of the configuration file. Sections are enabled or | 859 """A section of the configuration file. Sections are enabled or |
| 846 disabled prior to running the tests, based on their conditions""" | 860 disabled prior to running the tests, based on their conditions""" |
| 847 | 861 |
| 848 def __init__(self, condition): | 862 def __init__(self, condition): |
| 849 self.condition = condition | 863 self.condition = condition |
| 850 self.rules = [ ] | 864 self.rules = [ ] |
| 851 | 865 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 948 default=[], action="append") | 962 default=[], action="append") |
| 949 result.add_option("-t", "--timeout", help="Timeout in seconds", | 963 result.add_option("-t", "--timeout", help="Timeout in seconds", |
| 950 default=60, type="int") | 964 default=60, type="int") |
| 951 result.add_option("--arch", help='The architecture to run tests for', | 965 result.add_option("--arch", help='The architecture to run tests for', |
| 952 default='none') | 966 default='none') |
| 953 result.add_option("--simulator", help="Run tests with architecture simulator", | 967 result.add_option("--simulator", help="Run tests with architecture simulator", |
| 954 default='none') | 968 default='none') |
| 955 result.add_option("--special-command", default=None) | 969 result.add_option("--special-command", default=None) |
| 956 result.add_option("--cat", help="Print the source of the tests", | 970 result.add_option("--cat", help="Print the source of the tests", |
| 957 default=False, action="store_true") | 971 default=False, action="store_true") |
| 972 result.add_option("--warn-unused", help="Report unused rules", |
| 973 default=False, action="store_true") |
| 958 return result | 974 return result |
| 959 | 975 |
| 960 | 976 |
| 961 def ProcessOptions(options): | 977 def ProcessOptions(options): |
| 962 global VERBOSE | 978 global VERBOSE |
| 963 VERBOSE = options.verbose | 979 VERBOSE = options.verbose |
| 964 options.mode = options.mode.split(',') | 980 options.mode = options.mode.split(',') |
| 965 for mode in options.mode: | 981 for mode in options.mode: |
| 966 if not mode in ['debug', 'release']: | 982 if not mode in ['debug', 'release']: |
| 967 print "Unknown mode %s" % mode | 983 print "Unknown mode %s" % mode |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1040 prefix = value[:pos].split() | 1056 prefix = value[:pos].split() |
| 1041 suffix = value[pos+1:].split() | 1057 suffix = value[pos+1:].split() |
| 1042 def ExpandCommand(args): | 1058 def ExpandCommand(args): |
| 1043 return prefix + args + suffix | 1059 return prefix + args + suffix |
| 1044 return ExpandCommand | 1060 return ExpandCommand |
| 1045 | 1061 |
| 1046 | 1062 |
| 1047 BUILT_IN_TESTS = ['mjsunit', 'cctest'] | 1063 BUILT_IN_TESTS = ['mjsunit', 'cctest'] |
| 1048 | 1064 |
| 1049 | 1065 |
| 1066 def GetSuites(test_root): |
| 1067 return [ f for f in os.listdir(test_root) if isdir(join(test_root, f)) ] |
| 1068 |
| 1069 |
| 1050 def Main(): | 1070 def Main(): |
| 1051 parser = BuildOptions() | 1071 parser = BuildOptions() |
| 1052 (options, args) = parser.parse_args() | 1072 (options, args) = parser.parse_args() |
| 1053 if not ProcessOptions(options): | 1073 if not ProcessOptions(options): |
| 1054 parser.print_help() | 1074 parser.print_help() |
| 1055 return 1 | 1075 return 1 |
| 1056 | 1076 |
| 1057 workspace = abspath(join(dirname(sys.argv[0]), '..')) | 1077 workspace = abspath(join(dirname(sys.argv[0]), '..')) |
| 1058 repositories = [TestRepository(join(workspace, 'test', name)) for name in BUIL
T_IN_TESTS] | 1078 suites = GetSuites(join(workspace, 'test')) |
| 1079 repositories = [TestRepository(join(workspace, 'test', name)) for name in suit
es] |
| 1059 repositories += [TestRepository(a) for a in options.suite] | 1080 repositories += [TestRepository(a) for a in options.suite] |
| 1060 | 1081 |
| 1061 root = LiteralTestSuite(repositories) | 1082 root = LiteralTestSuite(repositories) |
| 1062 if len(args) == 0: | 1083 if len(args) == 0: |
| 1063 paths = [SplitPath(t) for t in BUILT_IN_TESTS] | 1084 paths = [SplitPath(t) for t in BUILT_IN_TESTS] |
| 1064 else: | 1085 else: |
| 1065 paths = [ ] | 1086 paths = [ ] |
| 1066 for arg in args: | 1087 for arg in args: |
| 1067 path = SplitPath(arg) | 1088 path = SplitPath(arg) |
| 1068 paths.append(path) | 1089 paths.append(path) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1085 # Get status for tests | 1106 # Get status for tests |
| 1086 sections = [ ] | 1107 sections = [ ] |
| 1087 defs = { } | 1108 defs = { } |
| 1088 root.GetTestStatus(context, sections, defs) | 1109 root.GetTestStatus(context, sections, defs) |
| 1089 config = Configuration(sections, defs) | 1110 config = Configuration(sections, defs) |
| 1090 | 1111 |
| 1091 # List the tests | 1112 # List the tests |
| 1092 all_cases = [ ] | 1113 all_cases = [ ] |
| 1093 all_unused = [ ] | 1114 all_unused = [ ] |
| 1094 unclassified_tests = [ ] | 1115 unclassified_tests = [ ] |
| 1116 globally_unused_rules = None |
| 1095 for path in paths: | 1117 for path in paths: |
| 1096 for mode in options.mode: | 1118 for mode in options.mode: |
| 1097 env = { | 1119 env = { |
| 1098 'mode': mode, | 1120 'mode': mode, |
| 1099 'system': platform.system().lower(), | 1121 'system': platform.system().lower(), |
| 1100 'arch': options.arch | 1122 'arch': options.arch |
| 1101 } | 1123 } |
| 1102 test_list = root.ListTests([], path, context, mode) | 1124 test_list = root.ListTests([], path, context, mode) |
| 1103 unclassified_tests += test_list | 1125 unclassified_tests += test_list |
| 1104 (cases, unused_rules) = config.ClassifyTests(test_list, env) | 1126 (cases, unused_rules, all_outcomes) = config.ClassifyTests(test_list, env) |
| 1127 if globally_unused_rules is None: |
| 1128 globally_unused_rules = set(unused_rules) |
| 1129 else: |
| 1130 globally_unused_rules = globally_unused_rules.intersection(unused_rules) |
| 1105 all_cases += cases | 1131 all_cases += cases |
| 1106 all_unused.append(unused_rules) | 1132 all_unused.append(unused_rules) |
| 1107 | 1133 |
| 1108 if options.cat: | 1134 if options.cat: |
| 1109 visited = set() | 1135 visited = set() |
| 1110 for test in unclassified_tests: | 1136 for test in unclassified_tests: |
| 1111 key = tuple(test.path) | 1137 key = tuple(test.path) |
| 1112 if key in visited: | 1138 if key in visited: |
| 1113 continue | 1139 continue |
| 1114 visited.add(key) | 1140 visited.add(key) |
| 1115 print "--- begin source: %s ---" % test.GetLabel() | 1141 print "--- begin source: %s ---" % test.GetLabel() |
| 1116 source = test.GetSource().strip() | 1142 source = test.GetSource().strip() |
| 1117 print source | 1143 print source |
| 1118 print "--- end source: %s ---" % test.GetLabel() | 1144 print "--- end source: %s ---" % test.GetLabel() |
| 1119 return 0 | 1145 return 0 |
| 1120 | 1146 |
| 1121 # for rule in unused_rules: | 1147 if options.warn_unused: |
| 1122 # print "Rule for '%s' was not used." % '/'.join([str(s) for s in rule.path]) | 1148 for rule in globally_unused_rules: |
| 1149 print "Rule for '%s' was not used." % '/'.join([str(s) for s in rule.path]
) |
| 1123 | 1150 |
| 1124 if options.report: | 1151 if options.report: |
| 1125 PrintReport(all_cases) | 1152 PrintReport(all_cases) |
| 1126 | 1153 |
| 1127 if len(all_cases) == 0: | 1154 if len(all_cases) == 0: |
| 1128 print "No tests to run." | 1155 print "No tests to run." |
| 1129 return 0 | 1156 return 0 |
| 1130 else: | 1157 else: |
| 1131 try: | 1158 try: |
| 1132 if RunTestCases(all_cases, options.progress): | 1159 if RunTestCases(all_cases, options.progress): |
| 1133 return 0 | 1160 return 0 |
| 1134 else: | 1161 else: |
| 1135 return 1 | 1162 return 1 |
| 1136 except KeyboardInterrupt: | 1163 except KeyboardInterrupt: |
| 1137 print "Interrupted" | 1164 print "Interrupted" |
| 1138 return 1 | 1165 return 1 |
| 1139 | 1166 |
| 1140 | 1167 |
| 1141 if __name__ == '__main__': | 1168 if __name__ == '__main__': |
| 1142 sys.exit(Main()) | 1169 sys.exit(Main()) |
| OLD | NEW |