Revert "[test] Move has unexpected output to outproc."
This reverts commit 71605b3ea4
.
Reason for revert: Seems to break static-initializers step:
https://build.chromium.org/p/client.v8/builders/V8%20Linux64/builds/22156
Original change's description:
> [test] Move has unexpected output to outproc.
>
> Expected outcomes optimized to serialize [PASS] as None.
>
> Keeping expected outcomes inside output processors should be
> optimized in the future. Few possible optimizations:
> - separate classes for tests that are expected to PASS - done as
> an example in mozilla test suite.
> - cache output processors inside testcase.
> - share output processors between copies of the same test - needs
> some updates to the create_variant to update outproc only if
> expected outcomes changed.
>
> Bug: v8:6917
> Change-Id: Ie73f1dcdf17fdfc65bce27228f818b1dd1e420c9
> Reviewed-on: https://chromium-review.googlesource.com/843025
> Commit-Queue: Michael Achenbach <machenbach@chromium.org>
> Reviewed-by: Michael Achenbach <machenbach@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#50347}
TBR=machenbach@chromium.org,sergiyb@chromium.org,majeski@google.com
Change-Id: Ice1f3aee0a26f7f38996459d38fd6e0bd964113d
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:6917
Reviewed-on: https://chromium-review.googlesource.com/849572
Reviewed-by: Bill Budge <bbudge@chromium.org>
Commit-Queue: Bill Budge <bbudge@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50348}
This commit is contained in:
parent
71605b3ea4
commit
1685b5d27a
@ -42,6 +42,8 @@ class TestCase(testcase.TestCase):
|
||||
super(TestCase, self).__init__(*args, **kwargs)
|
||||
|
||||
self._source_flags = self._parse_source_flags()
|
||||
self._outproc = outproc.ExpectedOutProc(
|
||||
os.path.join(self.suite.root, self.path) + EXPECTED_SUFFIX)
|
||||
|
||||
def _get_files_params(self, ctx):
|
||||
return [
|
||||
@ -60,9 +62,7 @@ class TestCase(testcase.TestCase):
|
||||
|
||||
@property
|
||||
def output_proc(self):
|
||||
return outproc.ExpectedOutProc(
|
||||
self.expected_outcomes,
|
||||
os.path.join(self.suite.root, self.path) + EXPECTED_SUFFIX)
|
||||
return self._outproc
|
||||
|
||||
|
||||
def GetSuite(name, root):
|
||||
|
@ -71,6 +71,8 @@ class TestCase(testcase.TestCase):
|
||||
source = self.get_source()
|
||||
self._source_files = self._parse_source_files(source)
|
||||
self._source_flags = self._parse_source_flags(source)
|
||||
self._outproc = OutProc(os.path.join(self.suite.root, self.path),
|
||||
self._expected_fail())
|
||||
|
||||
def _parse_source_files(self, source):
|
||||
files = []
|
||||
@ -103,14 +105,11 @@ class TestCase(testcase.TestCase):
|
||||
|
||||
@property
|
||||
def output_proc(self):
|
||||
return OutProc(self.expected_outcomes,
|
||||
os.path.join(self.suite.root, self.path),
|
||||
self._expected_fail())
|
||||
return self._outproc
|
||||
|
||||
|
||||
class OutProc(outproc.OutProc):
|
||||
def __init__(self, expected_outcomes, basepath, expected_fail):
|
||||
super(OutProc, self).__init__(expected_outcomes)
|
||||
def __init__(self, basepath, expected_fail):
|
||||
self._basepath = basepath
|
||||
self._expected_fail = expected_fail
|
||||
|
||||
|
@ -17,7 +17,8 @@ class TestSuite(testsuite.TestSuite):
|
||||
super(TestSuite, self).__init__(*args, **kwargs)
|
||||
|
||||
v8_path = os.path.dirname(os.path.dirname(os.path.abspath(self.root)))
|
||||
self.expected_path = os.path.join(v8_path, 'tools', 'v8heapconst.py')
|
||||
expected_path = os.path.join(v8_path, 'tools', 'v8heapconst.py')
|
||||
self.out_proc = OutProc(expected_path)
|
||||
|
||||
def ListTests(self, context):
|
||||
test = self._create_test(SHELL)
|
||||
@ -42,12 +43,11 @@ class TestCase(testcase.TestCase):
|
||||
|
||||
@property
|
||||
def output_proc(self):
|
||||
return OutProc(self.expected_outcomes, self.suite.expected_path)
|
||||
return self.suite.out_proc
|
||||
|
||||
|
||||
class OutProc(outproc.OutProc):
|
||||
def __init__(self, expected_outcomes, expected_path):
|
||||
super(OutProc, self).__init__(expected_outcomes)
|
||||
def __init__(self, expected_path):
|
||||
self._expected_path = expected_path
|
||||
|
||||
def _is_failure_output(self, output):
|
||||
|
@ -108,38 +108,27 @@ class TestCase(testcase.TestCase):
|
||||
|
||||
@property
|
||||
def output_proc(self):
|
||||
if not self.expected_outcomes:
|
||||
if self.path.endswith('-n'):
|
||||
return MOZILLA_PASS_NEGATIVE
|
||||
return MOZILLA_PASS_DEFAULT
|
||||
if self.path.endswith('-n'):
|
||||
return NegOutProc(self.expected_outcomes)
|
||||
return OutProc(self.expected_outcomes)
|
||||
|
||||
|
||||
def _is_failure_output(self, output):
|
||||
return (
|
||||
output.exit_code != 0 or
|
||||
'FAILED!' in output.stdout
|
||||
)
|
||||
return MOZILLA_NEGATIVE
|
||||
return MOZILLA_DEFAULT
|
||||
|
||||
|
||||
class OutProc(outproc.OutProc):
|
||||
"""Optimized for positive tests."""
|
||||
OutProc._is_failure_output = _is_failure_output
|
||||
def _is_failure_output(self, output):
|
||||
return (
|
||||
output.exit_code != 0 or
|
||||
'FAILED!' in output.stdout
|
||||
)
|
||||
|
||||
|
||||
class PassOutProc(outproc.PassOutProc):
|
||||
"""Optimized for positive tests expected to PASS."""
|
||||
PassOutProc._is_failure_output = _is_failure_output
|
||||
class NegativeOutProc(OutProc):
|
||||
@property
|
||||
def negative(self):
|
||||
return True
|
||||
|
||||
|
||||
NegOutProc = outproc.negative(OutProc)
|
||||
NegPassOutProc = outproc.negative(PassOutProc)
|
||||
|
||||
|
||||
MOZILLA_PASS_DEFAULT = PassOutProc()
|
||||
MOZILLA_PASS_NEGATIVE = NegPassOutProc()
|
||||
MOZILLA_DEFAULT = OutProc()
|
||||
MOZILLA_NEGATIVE = NegativeOutProc()
|
||||
|
||||
|
||||
def GetSuite(name, root):
|
||||
|
@ -200,11 +200,16 @@ class TestCase(testcase.TestCase):
|
||||
|
||||
source = self.get_source()
|
||||
self.test_record = self.suite.parse_test_record(source, self.path)
|
||||
self._expected_exception = (
|
||||
|
||||
expected_exception = (
|
||||
self.test_record
|
||||
.get('negative', {})
|
||||
.get('type', None)
|
||||
)
|
||||
if expected_exception is None:
|
||||
self._outproc = NO_EXCEPTION
|
||||
else:
|
||||
self._outproc = OutProc(expected_exception)
|
||||
|
||||
def _get_files_params(self, ctx):
|
||||
return (
|
||||
@ -245,23 +250,18 @@ class TestCase(testcase.TestCase):
|
||||
|
||||
@property
|
||||
def output_proc(self):
|
||||
if self._expected_exception is not None:
|
||||
return ExceptionOutProc(self.expected_outcomes, self._expected_exception)
|
||||
if self.expected_outcomes == outproc.OUTCOMES_PASS:
|
||||
return PASS_NO_EXCEPTION
|
||||
return NoExceptionOutProc(self.expected_outcomes)
|
||||
return self._outproc
|
||||
|
||||
|
||||
class ExceptionOutProc(outproc.OutProc):
|
||||
"""Output processor for tests with expected exception."""
|
||||
def __init__(self, expected_outcomes, expected_exception=None):
|
||||
super(ExceptionOutProc, self).__init__(expected_outcomes)
|
||||
class OutProc(outproc.OutProc):
|
||||
def __init__(self, expected_exception=None):
|
||||
self._expected_exception = expected_exception
|
||||
|
||||
def _is_failure_output(self, output):
|
||||
if output.exit_code != 0:
|
||||
return True
|
||||
if self._expected_exception != self._parse_exception(output.stdout):
|
||||
if (self._expected_exception and
|
||||
self._expected_exception != self._parse_exception(output.stdout)):
|
||||
return True
|
||||
return 'FAILED!' in output.stdout
|
||||
|
||||
@ -276,27 +276,7 @@ class ExceptionOutProc(outproc.OutProc):
|
||||
return None
|
||||
|
||||
|
||||
def _is_failure_output(self, output):
|
||||
return (
|
||||
output.exit_code != 0 or
|
||||
'FAILED!' in output.stdout
|
||||
)
|
||||
|
||||
|
||||
class NoExceptionOutProc(outproc.OutProc):
|
||||
"""Output processor optimized for tests without expected exception."""
|
||||
NoExceptionOutProc._is_failure_output = _is_failure_output
|
||||
|
||||
|
||||
class PassNoExceptionOutProc(outproc.PassOutProc):
|
||||
"""
|
||||
Output processor optimized for tests expected to PASS without expected
|
||||
exception.
|
||||
"""
|
||||
PassNoExceptionOutProc._is_failure_output = _is_failure_output
|
||||
|
||||
|
||||
PASS_NO_EXCEPTION = PassNoExceptionOutProc()
|
||||
NO_EXCEPTION = OutProc()
|
||||
|
||||
|
||||
def GetSuite(name, root):
|
||||
|
@ -68,6 +68,8 @@ class TestCase(testcase.TestCase):
|
||||
source = self.get_source()
|
||||
self._source_files = self._parse_source_files(source)
|
||||
self._source_flags = self._parse_source_flags(source)
|
||||
self._outproc = OutProc(
|
||||
os.path.join(self.suite.root, self.path) + '-expected.txt')
|
||||
|
||||
def _parse_source_files(self, source):
|
||||
files_list = [] # List of file names to append to command arguments.
|
||||
@ -104,9 +106,7 @@ class TestCase(testcase.TestCase):
|
||||
|
||||
@property
|
||||
def output_proc(self):
|
||||
return OutProc(
|
||||
self.expected_outcomes,
|
||||
os.path.join(self.suite.root, self.path) + '-expected.txt')
|
||||
return self._outproc
|
||||
|
||||
|
||||
class OutProc(outproc.ExpectedOutProc):
|
||||
|
@ -183,7 +183,7 @@ class TestSuite(object):
|
||||
not test.output_proc.negative and
|
||||
statusfile.FAIL not in test.expected_outcomes
|
||||
)
|
||||
return test.output_proc.has_unexpected_output(output)
|
||||
return test.output_proc.get_outcome(output) not in test.expected_outcomes
|
||||
|
||||
def _create_test(self, path, **kwargs):
|
||||
test = self._test_class()(self, path, self._path_to_name(path), **kwargs)
|
||||
|
@ -7,14 +7,7 @@ import itertools
|
||||
from ..local import statusfile
|
||||
|
||||
|
||||
OUTCOMES_PASS = [statusfile.PASS]
|
||||
OUTCOMES_FAIL = [statusfile.FAIL]
|
||||
|
||||
|
||||
class BaseOutProc(object):
|
||||
def has_unexpected_output(self, output):
|
||||
return self.get_outcome(output) not in self.expected_outcomes
|
||||
|
||||
class OutProc(object):
|
||||
def get_outcome(self, output):
|
||||
if output.HasCrashed():
|
||||
return statusfile.CRASH
|
||||
@ -38,65 +31,12 @@ class BaseOutProc(object):
|
||||
def negative(self):
|
||||
return False
|
||||
|
||||
@property
|
||||
def expected_outcomes(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
def negative(cls):
|
||||
class Neg(cls):
|
||||
@property
|
||||
def negative(self):
|
||||
return True
|
||||
return Neg
|
||||
|
||||
|
||||
class PassOutProc(BaseOutProc):
|
||||
"""Output processor optimized for positive tests expected to PASS."""
|
||||
def has_unexpected_output(self, output):
|
||||
return self.get_outcome(output) != statusfile.PASS
|
||||
|
||||
@property
|
||||
def expected_outcomes(self):
|
||||
return OUTCOMES_PASS
|
||||
|
||||
|
||||
class OutProc(BaseOutProc):
|
||||
"""Output processor optimized for positive tests with expected outcomes
|
||||
different than a single PASS.
|
||||
"""
|
||||
def __init__(self, expected_outcomes):
|
||||
self._expected_outcomes = expected_outcomes
|
||||
|
||||
@property
|
||||
def expected_outcomes(self):
|
||||
return self._expected_outcomes
|
||||
|
||||
# TODO(majeski): Inherit from PassOutProc in case of OUTCOMES_PASS and remove
|
||||
# custom get/set state.
|
||||
def __getstate__(self):
|
||||
d = self.__dict__
|
||||
if self._expected_outcomes is OUTCOMES_PASS:
|
||||
d = d.copy()
|
||||
del d['_expected_outcomes']
|
||||
return d
|
||||
|
||||
def __setstate__(self, d):
|
||||
if '_expected_outcomes' not in d:
|
||||
d['_expected_outcomes'] = OUTCOMES_PASS
|
||||
self.__dict__.update(d)
|
||||
|
||||
|
||||
# TODO(majeski): Override __reduce__ to make it deserialize as one instance.
|
||||
DEFAULT = PassOutProc()
|
||||
DEFAULT = OutProc()
|
||||
|
||||
|
||||
class ExpectedOutProc(OutProc):
|
||||
"""Output processor that has is_failure_output depending on comparing the
|
||||
output with the expected output.
|
||||
"""
|
||||
def __init__(self, expected_outcomes, expected_filename):
|
||||
super(ExpectedOutProc, self).__init__(expected_outcomes)
|
||||
def __init__(self, expected_filename):
|
||||
self._expected_filename = expected_filename
|
||||
|
||||
def _is_failure_output(self, output):
|
||||
|
@ -38,7 +38,6 @@ from ..local import utils
|
||||
FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
|
||||
|
||||
|
||||
|
||||
class TestCase(object):
|
||||
def __init__(self, suite, path, name):
|
||||
self.suite = suite # TestSuite object
|
||||
@ -54,7 +53,7 @@ class TestCase(object):
|
||||
self.cmd = None
|
||||
|
||||
self._statusfile_outcomes = None
|
||||
self._expected_outcomes = None # optimization: None == [statusfile.PASS]
|
||||
self.expected_outcomes = None
|
||||
self._statusfile_flags = None
|
||||
self._prepare_outcomes()
|
||||
|
||||
@ -89,7 +88,7 @@ class TestCase(object):
|
||||
def _parse_status_file_outcomes(self, outcomes):
|
||||
if (statusfile.FAIL_SLOPPY in outcomes and
|
||||
'--use-strict' not in self.variant_flags):
|
||||
return outproc.OUTCOMES_FAIL
|
||||
return [statusfile.FAIL]
|
||||
|
||||
expected_outcomes = []
|
||||
if (statusfile.FAIL in outcomes or
|
||||
@ -97,16 +96,9 @@ class TestCase(object):
|
||||
expected_outcomes.append(statusfile.FAIL)
|
||||
if statusfile.CRASH in outcomes:
|
||||
expected_outcomes.append(statusfile.CRASH)
|
||||
|
||||
# Do not add PASS if there is nothing else. Empty outcomes are converted to
|
||||
# the global [PASS].
|
||||
if expected_outcomes and statusfile.PASS in outcomes:
|
||||
if statusfile.PASS in outcomes:
|
||||
expected_outcomes.append(statusfile.PASS)
|
||||
|
||||
# Avoid creating multiple instances of a list with a single FAIL.
|
||||
if expected_outcomes == outproc.OUTCOMES_FAIL:
|
||||
return outproc.OUTCOMES_FAIL
|
||||
return expected_outcomes or outproc.OUTCOMES_PASS
|
||||
return expected_outcomes or [statusfile.PASS]
|
||||
|
||||
@property
|
||||
def do_skip(self):
|
||||
@ -247,9 +239,7 @@ class TestCase(object):
|
||||
|
||||
@property
|
||||
def output_proc(self):
|
||||
if self.expected_outcomes is outproc.OUTCOMES_PASS:
|
||||
return outproc.DEFAULT
|
||||
return outproc.OutProc(self.expected_outcomes)
|
||||
return outproc.DEFAULT
|
||||
|
||||
def __cmp__(self, other):
|
||||
# Make sure that test cases are sorted correctly if sorted without
|
||||
|
Loading…
Reference in New Issue
Block a user