OLD | NEW |
| (Empty) |
1 # Copyright 2012 the V8 project authors. All rights reserved. | |
2 # Redistribution and use in source and binary forms, with or without | |
3 # modification, are permitted provided that the following conditions are | |
4 # met: | |
5 # | |
6 # * Redistributions of source code must retain the above copyright | |
7 # notice, this list of conditions and the following disclaimer. | |
8 # * Redistributions in binary form must reproduce the above | |
9 # copyright notice, this list of conditions and the following | |
10 # disclaimer in the documentation and/or other materials provided | |
11 # with the distribution. | |
12 # * Neither the name of Google Inc. nor the names of its | |
13 # contributors may be used to endorse or promote products derived | |
14 # from this software without specific prior written permission. | |
15 # | |
16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
17 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
18 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
19 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
20 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 | |
28 | |
29 import imp | |
30 import os | |
31 | |
32 from . import statusfile | |
33 | |
34 class TestSuite(object): | |
35 | |
36 @staticmethod | |
37 def LoadTestSuite(root): | |
38 name = root.split(os.path.sep)[-1] | |
39 f = None | |
40 try: | |
41 (f, pathname, description) = imp.find_module("testcfg", [root]) | |
42 module = imp.load_module("testcfg", f, pathname, description) | |
43 suite = module.GetSuite(name, root) | |
44 finally: | |
45 if f: | |
46 f.close() | |
47 return suite | |
48 | |
49 def __init__(self, name, root): | |
50 self.name = name # string | |
51 self.root = root # string containing path | |
52 self.tests = None # list of TestCase objects | |
53 self.rules = None # dictionary mapping test path to list of outcomes | |
54 self.wildcards = None # dictionary mapping test paths to list of outcomes | |
55 self.total_duration = None # float, assigned on demand | |
56 | |
57 def shell(self): | |
58 return "d8" | |
59 | |
60 def suffix(self): | |
61 return ".js" | |
62 | |
63 def status_file(self): | |
64 return "%s/%s.status" % (self.root, self.name) | |
65 | |
66 # Used in the status file and for stdout printing. | |
67 def CommonTestName(self, testcase): | |
68 return testcase.path | |
69 | |
70 def ListTests(self, context): | |
71 raise NotImplementedError | |
72 | |
73 def VariantFlags(self): | |
74 return None | |
75 | |
76 def DownloadData(self): | |
77 pass | |
78 | |
79 def ReadStatusFile(self, variables): | |
80 (self.rules, self.wildcards) = \ | |
81 statusfile.ReadStatusFile(self.status_file(), variables) | |
82 | |
83 def ReadTestCases(self, context): | |
84 self.tests = self.ListTests(context) | |
85 | |
86 def FilterTestCasesByStatus(self, warn_unused_rules): | |
87 filtered = [] | |
88 used_rules = set() | |
89 for t in self.tests: | |
90 testname = self.CommonTestName(t) | |
91 if testname in self.rules: | |
92 used_rules.add(testname) | |
93 outcomes = self.rules[testname] | |
94 t.outcomes = outcomes # Even for skipped tests, as the TestCase | |
95 # object stays around and PrintReport() uses it. | |
96 if statusfile.DoSkip(outcomes): | |
97 continue # Don't add skipped tests to |filtered|. | |
98 if len(self.wildcards) != 0: | |
99 skip = False | |
100 for rule in self.wildcards: | |
101 assert rule[-1] == '*' | |
102 if testname.startswith(rule[:-1]): | |
103 used_rules.add(rule) | |
104 outcomes = self.wildcards[rule] | |
105 t.outcomes = outcomes | |
106 if statusfile.DoSkip(outcomes): | |
107 skip = True | |
108 break # "for rule in self.wildcards" | |
109 if skip: continue # "for t in self.tests" | |
110 filtered.append(t) | |
111 self.tests = filtered | |
112 | |
113 if not warn_unused_rules: | |
114 return | |
115 | |
116 for rule in self.rules: | |
117 if rule not in used_rules: | |
118 print("Unused rule: %s -> %s" % (rule, self.rules[rule])) | |
119 for rule in self.wildcards: | |
120 if rule not in used_rules: | |
121 print("Unused rule: %s -> %s" % (rule, self.wildcards[rule])) | |
122 | |
123 def FilterTestCasesByArgs(self, args): | |
124 filtered = [] | |
125 filtered_args = [] | |
126 for a in args: | |
127 argpath = a.split(os.path.sep) | |
128 if argpath[0] != self.name: | |
129 continue | |
130 if len(argpath) == 1 or (len(argpath) == 2 and argpath[1] == '*'): | |
131 return # Don't filter, run all tests in this suite. | |
132 path = os.path.sep.join(argpath[1:]) | |
133 if path[-1] == '*': | |
134 path = path[:-1] | |
135 filtered_args.append(path) | |
136 for t in self.tests: | |
137 for a in filtered_args: | |
138 if t.path.startswith(a): | |
139 filtered.append(t) | |
140 break | |
141 self.tests = filtered | |
142 | |
143 def GetFlagsForTestCase(self, testcase, context): | |
144 raise NotImplementedError | |
145 | |
146 def GetSourceForTest(self, testcase): | |
147 return "(no source available)" | |
148 | |
149 def IsFailureOutput(self, output, testpath): | |
150 return output.exit_code != 0 | |
151 | |
152 def IsNegativeTest(self, testcase): | |
153 return False | |
154 | |
155 def HasFailed(self, testcase): | |
156 execution_failed = self.IsFailureOutput(testcase.output, testcase.path) | |
157 if self.IsNegativeTest(testcase): | |
158 return not execution_failed | |
159 else: | |
160 return execution_failed | |
161 | |
162 def HasUnexpectedOutput(self, testcase): | |
163 if testcase.output.HasCrashed(): | |
164 outcome = statusfile.CRASH | |
165 elif testcase.output.HasTimedOut(): | |
166 outcome = statusfile.TIMEOUT | |
167 elif self.HasFailed(testcase): | |
168 outcome = statusfile.FAIL | |
169 else: | |
170 outcome = statusfile.PASS | |
171 if not testcase.outcomes: | |
172 return outcome != statusfile.PASS | |
173 return not outcome in testcase.outcomes | |
174 | |
175 def StripOutputForTransmit(self, testcase): | |
176 if not self.HasUnexpectedOutput(testcase): | |
177 testcase.output.stdout = "" | |
178 testcase.output.stderr = "" | |
179 | |
180 def CalculateTotalDuration(self): | |
181 self.total_duration = 0.0 | |
182 for t in self.tests: | |
183 self.total_duration += t.duration | |
184 return self.total_duration | |
OLD | NEW |