The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / tools / testrunner / local / testsuite.py @ f230a1cf

History | View | Annotate | Download (6.47 KB)

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
from . import utils
34

    
35
class TestSuite(object):
36

    
37
  @staticmethod
38
  def LoadTestSuite(root):
39
    name = root.split(os.path.sep)[-1]
40
    f = None
41
    try:
42
      (f, pathname, description) = imp.find_module("testcfg", [root])
43
      module = imp.load_module("testcfg", f, pathname, description)
44
      suite = module.GetSuite(name, root)
45
    finally:
46
      if f:
47
        f.close()
48
    return suite
49

    
50
  def __init__(self, name, root):
51
    self.name = name  # string
52
    self.root = root  # string containing path
53
    self.tests = None  # list of TestCase objects
54
    self.rules = None  # dictionary mapping test path to list of outcomes
55
    self.wildcards = None  # dictionary mapping test paths to list of outcomes
56
    self.total_duration = None  # float, assigned on demand
57

    
58
  def shell(self):
59
    return "d8"
60

    
61
  def suffix(self):
62
    return ".js"
63

    
64
  def status_file(self):
65
    return "%s/%s.status" % (self.root, self.name)
66

    
67
  # Used in the status file and for stdout printing.
68
  def CommonTestName(self, testcase):
69
    if utils.IsWindows():
70
      return testcase.path.replace("\\", "/")
71
    else:
72
      return testcase.path
73

    
74
  def ListTests(self, context):
75
    raise NotImplementedError
76

    
77
  def VariantFlags(self, testcase, default_flags):
78
    if testcase.outcomes and statusfile.OnlyStandardVariant(testcase.outcomes):
79
      return [[]]
80
    return default_flags
81

    
82
  def DownloadData(self):
83
    pass
84

    
85
  def ReadStatusFile(self, variables):
86
    (self.rules, self.wildcards) = \
87
        statusfile.ReadStatusFile(self.status_file(), variables)
88

    
89
  def ReadTestCases(self, context):
90
    self.tests = self.ListTests(context)
91

    
92
  @staticmethod
93
  def _FilterFlaky(flaky, mode):
94
    return (mode == "run" and not flaky) or (mode == "skip" and flaky)
95

    
96
  def FilterTestCasesByStatus(self, warn_unused_rules, flaky_tests="dontcare"):
97
    filtered = []
98
    used_rules = set()
99
    for t in self.tests:
100
      flaky = False
101
      testname = self.CommonTestName(t)
102
      if testname in self.rules:
103
        used_rules.add(testname)
104
        # Even for skipped tests, as the TestCase object stays around and
105
        # PrintReport() uses it.
106
        t.outcomes = self.rules[testname]
107
        if statusfile.DoSkip(t.outcomes):
108
          continue  # Don't add skipped tests to |filtered|.
109
        flaky = statusfile.IsFlaky(t.outcomes)
110
      skip = False
111
      for rule in self.wildcards:
112
        assert rule[-1] == '*'
113
        if testname.startswith(rule[:-1]):
114
          used_rules.add(rule)
115
          t.outcomes = self.wildcards[rule]
116
          if statusfile.DoSkip(t.outcomes):
117
            skip = True
118
            break  # "for rule in self.wildcards"
119
          flaky = flaky or statusfile.IsFlaky(t.outcomes)
120
      if skip or self._FilterFlaky(flaky, flaky_tests):
121
        continue  # "for t in self.tests"
122
      filtered.append(t)
123
    self.tests = filtered
124

    
125
    if not warn_unused_rules:
126
      return
127

    
128
    for rule in self.rules:
129
      if rule not in used_rules:
130
        print("Unused rule: %s -> %s" % (rule, self.rules[rule]))
131
    for rule in self.wildcards:
132
      if rule not in used_rules:
133
        print("Unused rule: %s -> %s" % (rule, self.wildcards[rule]))
134

    
135
  def FilterTestCasesByArgs(self, args):
136
    filtered = []
137
    filtered_args = []
138
    for a in args:
139
      argpath = a.split(os.path.sep)
140
      if argpath[0] != self.name:
141
        continue
142
      if len(argpath) == 1 or (len(argpath) == 2 and argpath[1] == '*'):
143
        return  # Don't filter, run all tests in this suite.
144
      path = os.path.sep.join(argpath[1:])
145
      if path[-1] == '*':
146
        path = path[:-1]
147
      filtered_args.append(path)
148
    for t in self.tests:
149
      for a in filtered_args:
150
        if t.path.startswith(a):
151
          filtered.append(t)
152
          break
153
    self.tests = filtered
154

    
155
  def GetFlagsForTestCase(self, testcase, context):
156
    raise NotImplementedError
157

    
158
  def GetSourceForTest(self, testcase):
159
    return "(no source available)"
160

    
161
  def IsFailureOutput(self, output, testpath):
162
    return output.exit_code != 0
163

    
164
  def IsNegativeTest(self, testcase):
165
    return False
166

    
167
  def HasFailed(self, testcase):
168
    execution_failed = self.IsFailureOutput(testcase.output, testcase.path)
169
    if self.IsNegativeTest(testcase):
170
      return not execution_failed
171
    else:
172
      return execution_failed
173

    
174
  def HasUnexpectedOutput(self, testcase):
175
    if testcase.output.HasCrashed():
176
      outcome = statusfile.CRASH
177
    elif testcase.output.HasTimedOut():
178
      outcome = statusfile.TIMEOUT
179
    elif self.HasFailed(testcase):
180
      outcome = statusfile.FAIL
181
    else:
182
      outcome = statusfile.PASS
183
    if not testcase.outcomes:
184
      return outcome != statusfile.PASS
185
    return not outcome in testcase.outcomes
186

    
187
  def StripOutputForTransmit(self, testcase):
188
    if not self.HasUnexpectedOutput(testcase):
189
      testcase.output.stdout = ""
190
      testcase.output.stderr = ""
191

    
192
  def CalculateTotalDuration(self):
193
    self.total_duration = 0.0
194
    for t in self.tests:
195
      self.total_duration += t.duration
196
    return self.total_duration