[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:
Michal Majewski 2017-12-19 15:32:59 +01:00 committed by Commit Bot
parent e0c4321479
commit 4695e97905
4 changed files with 67 additions and 73 deletions

View File

@ -70,11 +70,70 @@ for var in ALL_VARIANTS:
class StatusFile(object):
def __init__(self, path, variables):
"""
rules: {variant: {test name: [rule]}}
prefix_rules: {variant: {test name prefix: [rule]}}
_rules: {variant: {test name: [rule]}}
_prefix_rules: {variant: {test name prefix: [rule]}}
"""
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):

View File

@ -146,46 +146,6 @@ class TestSuite(object):
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):
"""Filter test cases based on command-line arguments.
@ -211,33 +171,6 @@ class TestSuite(object):
break
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):
return output.exit_code != 0

View File

@ -78,7 +78,7 @@ class TestCase(object):
def not_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_flags = filter(is_flag, outcomes)
self.expected_outcomes = (

View File

@ -422,7 +422,8 @@ class StandardTestRunner(base_runner.BaseTestRunner):
# First filtering by status applying the generic rules (tests without
# variants)
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)
if options.cat:
@ -454,7 +455,8 @@ class StandardTestRunner(base_runner.BaseTestRunner):
# Second filtering by status applying also the variant-dependent rules.
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.tests = self._shard_tests(s.tests, options)