[test] Move getting outcomes to the statusfile
Bug: v8:6917 Change-Id: I175fa426546f2f3775a35f1094dfb19e06b2185d Reviewed-on: https://chromium-review.googlesource.com/832394 Commit-Queue: Michał Majewski <majeski@google.com> Reviewed-by: Michael Achenbach <machenbach@chromium.org> Cr-Commit-Position: refs/heads/master@{#50203}
This commit is contained in:
parent
e0c4321479
commit
4695e97905
@ -70,11 +70,70 @@ for var in ALL_VARIANTS:
|
|||||||
class StatusFile(object):
|
class StatusFile(object):
|
||||||
def __init__(self, path, variables):
|
def __init__(self, path, variables):
|
||||||
"""
|
"""
|
||||||
rules: {variant: {test name: [rule]}}
|
_rules: {variant: {test name: [rule]}}
|
||||||
prefix_rules: {variant: {test name prefix: [rule]}}
|
_prefix_rules: {variant: {test name prefix: [rule]}}
|
||||||
"""
|
"""
|
||||||
with open(path) as f:
|
with open(path) as f:
|
||||||
self.rules, self.prefix_rules = ReadStatusFile(f.read(), variables)
|
self._rules, self._prefix_rules = ReadStatusFile(f.read(), variables)
|
||||||
|
|
||||||
|
def get_outcomes(self, testname, variant=None):
|
||||||
|
"""Merges variant dependent and independent rules."""
|
||||||
|
outcomes = frozenset()
|
||||||
|
|
||||||
|
for key in set([variant or '', '']):
|
||||||
|
rules = self._rules.get(key, {})
|
||||||
|
prefix_rules = self._prefix_rules.get(key, {})
|
||||||
|
|
||||||
|
if testname in rules:
|
||||||
|
outcomes |= rules[testname]
|
||||||
|
|
||||||
|
for prefix in prefix_rules:
|
||||||
|
if testname.startswith(prefix):
|
||||||
|
outcomes |= prefix_rules[prefix]
|
||||||
|
|
||||||
|
return outcomes
|
||||||
|
|
||||||
|
def warn_unused_rules(self, tests, check_variant_rules=False):
|
||||||
|
"""Finds and prints unused rules in status file.
|
||||||
|
|
||||||
|
Rule X is unused when it doesn't apply to any tests, which can also mean
|
||||||
|
that all matching tests were skipped by another rule before evaluating X.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tests: list of pairs (testname, variant)
|
||||||
|
check_variant_rules: if set variant dependent rules are checked
|
||||||
|
"""
|
||||||
|
|
||||||
|
if check_variant_rules:
|
||||||
|
variants = list(ALL_VARIANTS)
|
||||||
|
else:
|
||||||
|
variants = ['']
|
||||||
|
used_rules = set()
|
||||||
|
|
||||||
|
for testname, variant in tests:
|
||||||
|
variant = variant or ''
|
||||||
|
|
||||||
|
if testname in self._rules.get(variant, {}):
|
||||||
|
used_rules.add((testname, variant))
|
||||||
|
if SKIP in self._rules[variant][testname]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for prefix in self._prefix_rules.get(variant, {}):
|
||||||
|
if testname.startswith(prefix):
|
||||||
|
used_rules.add((prefix, variant))
|
||||||
|
if SKIP in self._prefix_rules[variant][prefix]:
|
||||||
|
break
|
||||||
|
|
||||||
|
for variant in variants:
|
||||||
|
for rule, value in (
|
||||||
|
list(self._rules.get(variant, {}).iteritems()) +
|
||||||
|
list(self._prefix_rules.get(variant, {}).iteritems())):
|
||||||
|
if (rule, variant) not in used_rules:
|
||||||
|
if variant == '':
|
||||||
|
variant_desc = 'variant independent'
|
||||||
|
else:
|
||||||
|
variant_desc = 'variant: %s' % variant
|
||||||
|
print 'Unused rule: %s -> %s (%s)' % (rule, value, variant_desc)
|
||||||
|
|
||||||
|
|
||||||
def _JoinsPassAndFail(outcomes1, outcomes2):
|
def _JoinsPassAndFail(outcomes1, outcomes2):
|
||||||
|
@ -146,46 +146,6 @@ class TestSuite(object):
|
|||||||
|
|
||||||
self.tests = filter(_compliant, self.tests)
|
self.tests = filter(_compliant, self.tests)
|
||||||
|
|
||||||
def WarnUnusedRules(self, check_variant_rules=False):
|
|
||||||
"""Finds and prints unused rules in status file.
|
|
||||||
|
|
||||||
Rule X is unused when it doesn't apply to any tests, which can also mean
|
|
||||||
that all matching tests were skipped by another rule before evaluating X.
|
|
||||||
|
|
||||||
Status file has to be loaded before using this function.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if check_variant_rules:
|
|
||||||
variants = list(ALL_VARIANTS)
|
|
||||||
else:
|
|
||||||
variants = ['']
|
|
||||||
used_rules = set()
|
|
||||||
|
|
||||||
for test in self.tests:
|
|
||||||
variant = test.variant or ""
|
|
||||||
|
|
||||||
if test.name in self.statusfile.rules.get(variant, {}):
|
|
||||||
used_rules.add((test.name, variant))
|
|
||||||
if statusfile.SKIP in self.statusfile.rules[variant][test.name]:
|
|
||||||
continue
|
|
||||||
|
|
||||||
for prefix in self.statusfile.prefix_rules.get(variant, {}):
|
|
||||||
if test.name.startswith(prefix):
|
|
||||||
used_rules.add((prefix, variant))
|
|
||||||
if statusfile.SKIP in self.statusfile.prefix_rules[variant][prefix]:
|
|
||||||
break
|
|
||||||
|
|
||||||
for variant in variants:
|
|
||||||
for rule, value in (
|
|
||||||
list(self.statusfile.rules.get(variant, {}).iteritems()) +
|
|
||||||
list(self.statusfile.prefix_rules.get(variant, {}).iteritems())):
|
|
||||||
if (rule, variant) not in used_rules:
|
|
||||||
if variant == '':
|
|
||||||
variant_desc = 'variant independent'
|
|
||||||
else:
|
|
||||||
variant_desc = 'variant: %s' % variant
|
|
||||||
print('Unused rule: %s -> %s (%s)' % (rule, value, variant_desc))
|
|
||||||
|
|
||||||
def FilterTestCasesByArgs(self, args):
|
def FilterTestCasesByArgs(self, args):
|
||||||
"""Filter test cases based on command-line arguments.
|
"""Filter test cases based on command-line arguments.
|
||||||
|
|
||||||
@ -211,33 +171,6 @@ class TestSuite(object):
|
|||||||
break
|
break
|
||||||
self.tests = filtered
|
self.tests = filtered
|
||||||
|
|
||||||
def GetStatusFileOutcomes(self, testname, variant=None):
|
|
||||||
"""Gets outcomes from status file.
|
|
||||||
|
|
||||||
Merges variant dependent and independent rules. Status file has to be loaded
|
|
||||||
before using this function.
|
|
||||||
"""
|
|
||||||
|
|
||||||
variant = variant or ''
|
|
||||||
|
|
||||||
# Load statusfile to get outcomes for the first time.
|
|
||||||
assert(self.statusfile is not None)
|
|
||||||
|
|
||||||
outcomes = frozenset()
|
|
||||||
|
|
||||||
for key in set([variant, '']):
|
|
||||||
rules = self.statusfile.rules.get(key, {})
|
|
||||||
prefix_rules = self.statusfile.prefix_rules.get(key, {})
|
|
||||||
|
|
||||||
if testname in rules:
|
|
||||||
outcomes |= rules[testname]
|
|
||||||
|
|
||||||
for prefix in prefix_rules:
|
|
||||||
if testname.startswith(prefix):
|
|
||||||
outcomes |= prefix_rules[prefix]
|
|
||||||
|
|
||||||
return outcomes
|
|
||||||
|
|
||||||
def IsFailureOutput(self, testcase, output):
|
def IsFailureOutput(self, testcase, output):
|
||||||
return output.exit_code != 0
|
return output.exit_code != 0
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ class TestCase(object):
|
|||||||
def not_flag(outcome):
|
def not_flag(outcome):
|
||||||
return not is_flag(outcome)
|
return not is_flag(outcome)
|
||||||
|
|
||||||
outcomes = self.suite.GetStatusFileOutcomes(self.name, self.variant)
|
outcomes = self.suite.statusfile.get_outcomes(self.name, self.variant)
|
||||||
self.statusfile_outcomes = filter(not_flag, outcomes)
|
self.statusfile_outcomes = filter(not_flag, outcomes)
|
||||||
self._statusfile_flags = filter(is_flag, outcomes)
|
self._statusfile_flags = filter(is_flag, outcomes)
|
||||||
self.expected_outcomes = (
|
self.expected_outcomes = (
|
||||||
|
@ -422,7 +422,8 @@ class StandardTestRunner(base_runner.BaseTestRunner):
|
|||||||
# First filtering by status applying the generic rules (tests without
|
# First filtering by status applying the generic rules (tests without
|
||||||
# variants)
|
# variants)
|
||||||
if options.warn_unused:
|
if options.warn_unused:
|
||||||
s.WarnUnusedRules(check_variant_rules=False)
|
tests = [(t.name, t.variant) for t in s.tests]
|
||||||
|
s.statusfile.warn_unused_rules(tests, check_variant_rules=False)
|
||||||
s.FilterTestCasesByStatus(options.slow_tests, options.pass_fail_tests)
|
s.FilterTestCasesByStatus(options.slow_tests, options.pass_fail_tests)
|
||||||
|
|
||||||
if options.cat:
|
if options.cat:
|
||||||
@ -454,7 +455,8 @@ class StandardTestRunner(base_runner.BaseTestRunner):
|
|||||||
|
|
||||||
# Second filtering by status applying also the variant-dependent rules.
|
# Second filtering by status applying also the variant-dependent rules.
|
||||||
if options.warn_unused:
|
if options.warn_unused:
|
||||||
s.WarnUnusedRules(check_variant_rules=True)
|
tests = [(t.name, t.variant) for t in s.tests]
|
||||||
|
s.statusfile.warn_unused_rules(tests, check_variant_rules=True)
|
||||||
s.FilterTestCasesByStatus(options.slow_tests, options.pass_fail_tests)
|
s.FilterTestCasesByStatus(options.slow_tests, options.pass_fail_tests)
|
||||||
s.tests = self._shard_tests(s.tests, options)
|
s.tests = self._shard_tests(s.tests, options)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user