]>
git.proxmox.com Git - rustc.git/blob - src/llvm/utils/lit/lit/Test.py
2 from xml
.sax
.saxutils
import escape
3 from json
import JSONEncoder
7 class ResultCode(object):
8 """Test result codes."""
10 # We override __new__ and __getnewargs__ to ensure that pickling still
11 # provides unique ResultCode objects in any particular instance.
13 def __new__(cls
, name
, isFailure
):
14 res
= cls
._instances
.get(name
)
16 cls
._instances
[name
] = res
= super(ResultCode
, cls
).__new
__(cls
)
18 def __getnewargs__(self
):
19 return (self
.name
, self
.isFailure
)
21 def __init__(self
, name
, isFailure
):
23 self
.isFailure
= isFailure
26 return '%s%r' % (self
.__class
__.__name
__,
27 (self
.name
, self
.isFailure
))
29 PASS
= ResultCode('PASS', False)
30 XFAIL
= ResultCode('XFAIL', False)
31 FAIL
= ResultCode('FAIL', True)
32 XPASS
= ResultCode('XPASS', True)
33 UNRESOLVED
= ResultCode('UNRESOLVED', True)
34 UNSUPPORTED
= ResultCode('UNSUPPORTED', False)
38 class MetricValue(object):
43 Convert this metric to a string suitable for displaying as part of the
46 raise RuntimeError("abstract method")
50 todata() -> json-serializable data
52 Convert this metric to content suitable for serializing in the JSON test
55 raise RuntimeError("abstract method")
57 class IntMetricValue(MetricValue
):
58 def __init__(self
, value
):
62 return str(self
.value
)
67 class RealMetricValue(MetricValue
):
68 def __init__(self
, value
):
72 return '%.4f' % self
.value
77 class JSONMetricValue(MetricValue
):
79 JSONMetricValue is used for types that are representable in the output
80 but that are otherwise uninterpreted.
82 def __init__(self
, value
):
83 # Ensure the value is a serializable by trying to encode it.
84 # WARNING: The value may change before it is encoded again, and may
85 # not be encodable after the change.
94 return str(self
.value
)
99 def toMetricValue(value
):
100 if isinstance(value
, MetricValue
):
102 elif isinstance(value
, int) or isinstance(value
, long):
103 return IntMetricValue(value
)
104 elif isinstance(value
, float):
105 return RealMetricValue(value
)
107 # Try to create a JSONMetricValue and let the constructor throw
108 # if value is not a valid type.
109 return JSONMetricValue(value
)
114 class Result(object):
115 """Wrapper for the results of executing an individual test."""
117 def __init__(self
, code
, output
='', elapsed
=None):
122 # The wall timing to execute the test, if timing.
123 self
.elapsed
= elapsed
124 # The metrics reported by this test.
127 def addMetric(self
, name
, value
):
129 addMetric(name, value)
131 Attach a test metric to the test result, with the given name and list of
132 values. It is an error to attempt to attach the metrics with the same
135 Each value must be an instance of a MetricValue subclass.
137 if name
in self
.metrics
:
138 raise ValueError("result already includes metrics for %r" % (
140 if not isinstance(value
, MetricValue
):
141 raise TypeError("unexpected metric value: %r" % (value
,))
142 self
.metrics
[name
] = value
147 """TestSuite - Information on a group of tests.
149 A test suite groups together a set of logically related tests.
152 def __init__(self
, name
, source_root
, exec_root
, config
):
154 self
.source_root
= source_root
155 self
.exec_root
= exec_root
156 # The test suite configuration.
159 def getSourcePath(self
, components
):
160 return os
.path
.join(self
.source_root
, *components
)
162 def getExecPath(self
, components
):
163 return os
.path
.join(self
.exec_root
, *components
)
166 """Test - Information on a single test instance."""
168 def __init__(self
, suite
, path_in_suite
, config
, file_path
= None):
170 self
.path_in_suite
= path_in_suite
172 self
.file_path
= file_path
173 # A list of conditions under which this test is expected to fail. These
174 # can optionally be provided by test format handlers, and will be
175 # honored when the test result is supplied.
177 # The test result, once complete.
180 def setResult(self
, result
):
181 if self
.result
is not None:
182 raise ArgumentError("test result already set")
183 if not isinstance(result
, Result
):
184 raise ArgumentError("unexpected result type")
188 # Apply the XFAIL handling to resolve the result exit code.
189 if self
.isExpectedToFail():
190 if self
.result
.code
== PASS
:
191 self
.result
.code
= XPASS
192 elif self
.result
.code
== FAIL
:
193 self
.result
.code
= XFAIL
195 def getFullName(self
):
196 return self
.suite
.config
.name
+ ' :: ' + '/'.join(self
.path_in_suite
)
198 def getFilePath(self
):
200 return self
.file_path
201 return self
.getSourcePath()
203 def getSourcePath(self
):
204 return self
.suite
.getSourcePath(self
.path_in_suite
)
206 def getExecPath(self
):
207 return self
.suite
.getExecPath(self
.path_in_suite
)
209 def isExpectedToFail(self
):
211 isExpectedToFail() -> bool
213 Check whether this test is expected to fail in the current
214 configuration. This check relies on the test xfails property which by
215 some test formats may not be computed until the test has first been
219 # Check if any of the xfails match an available feature or the target.
220 for item
in self
.xfails
:
221 # If this is the wildcard, it always fails.
225 # If this is an exact match for one of the features, it fails.
226 if item
in self
.config
.available_features
:
229 # If this is a part of the target triple, it fails.
230 if item
in self
.suite
.config
.target_triple
:
236 def getJUnitXML(self
):
237 test_name
= self
.path_in_suite
[-1]
238 test_path
= self
.path_in_suite
[:-1]
239 safe_test_path
= [x
.replace(".","_") for x
in test_path
]
240 safe_name
= self
.suite
.name
.replace(".","-")
243 class_name
= safe_name
+ "." + "/".join(safe_test_path
)
245 class_name
= safe_name
+ "." + safe_name
247 xml
= "<testcase classname='" + class_name
+ "' name='" + \
249 xml
+= " time='%.2f'" % (self
.result
.elapsed
,)
250 if self
.result
.code
.isFailure
:
251 xml
+= ">\n\t<failure >\n" + escape(self
.result
.output
)
252 xml
+= "\n\t</failure>\n</testcase>"