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

Side by Side Diff: tools/test.py

Issue 4081: Various test-related changes. (Closed)
Patch Set: Created 12 years, 2 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
« no previous file with comments | « test/mjsunit/bugs/bug-87.js ('k') | 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/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
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
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
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
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
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
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
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())
OLDNEW
« no previous file with comments | « test/mjsunit/bugs/bug-87.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698