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 for rule in self.wildcards: |
| 100 assert rule[-1] == '*' |
| 101 if testname.startswith(rule[:-1]): |
| 102 used_rules.add(rule) |
| 103 outcomes = self.wildcards[rule] |
| 104 if statusfile.DoSkip(outcomes): |
| 105 continue |
| 106 t.outcomes = outcomes |
| 107 filtered.append(t) |
| 108 self.tests = filtered |
| 109 |
| 110 if not warn_unused_rules: |
| 111 return |
| 112 |
| 113 for rule in self.rules: |
| 114 if rule not in used_rules: |
| 115 print("Unused rule: %s -> %s" % (rule, self.rules[rule])) |
| 116 for rule in self.wildcards: |
| 117 if rule not in used_rules: |
| 118 print("Unused rule: %s -> %s" % (rule, self.wildcards[rule])) |
| 119 |
| 120 def FilterTestCasesByArgs(self, args): |
| 121 filtered = [] |
| 122 filtered_args = [] |
| 123 for a in args: |
| 124 argpath = a.split(os.path.sep) |
| 125 if argpath[0] != self.name: |
| 126 continue |
| 127 if len(argpath) == 1 or (len(argpath) == 2 and argpath[1] == '*'): |
| 128 return # Don't filter, run all tests in this suite. |
| 129 path = os.path.sep.join(argpath[1:]) |
| 130 if path[-1] == '*': |
| 131 path = path[:-1] |
| 132 filtered_args.append(path) |
| 133 for t in self.tests: |
| 134 for a in filtered_args: |
| 135 if t.path.startswith(a): |
| 136 filtered.append(t) |
| 137 break |
| 138 self.tests = filtered |
| 139 |
| 140 def GetFlagsForTestCase(self, testcase, context): |
| 141 raise NotImplementedError |
| 142 |
| 143 def GetSourceForTest(self, testcase): |
| 144 return "(no source available)" |
| 145 |
| 146 def IsFailureOutput(self, output, testpath): |
| 147 return output.exit_code != 0 |
| 148 |
| 149 def IsNegativeTest(self, testcase): |
| 150 return False |
| 151 |
| 152 def HasFailed(self, testcase): |
| 153 execution_failed = self.IsFailureOutput(testcase.output, testcase.path) |
| 154 if self.IsNegativeTest(testcase): |
| 155 return not execution_failed |
| 156 else: |
| 157 return execution_failed |
| 158 |
| 159 def HasUnexpectedOutput(self, testcase): |
| 160 if testcase.output.HasCrashed(): |
| 161 outcome = statusfile.CRASH |
| 162 elif testcase.output.HasTimedOut(): |
| 163 outcome = statusfile.TIMEOUT |
| 164 elif self.HasFailed(testcase): |
| 165 outcome = statusfile.FAIL |
| 166 else: |
| 167 outcome = statusfile.PASS |
| 168 if not testcase.outcomes: |
| 169 return outcome != statusfile.PASS |
| 170 return not outcome in testcase.outcomes |
| 171 |
| 172 def StripOutputForTransmit(self, testcase): |
| 173 if not self.HasUnexpectedOutput(testcase): |
| 174 testcase.output.stdout = "" |
| 175 testcase.output.stderr = "" |
| 176 |
| 177 def CalculateTotalDuration(self): |
| 178 self.total_duration = 0.0 |
| 179 for t in self.tests: |
| 180 self.total_duration += t.duration |
| 181 return self.total_duration |
OLD | NEW |