summaryrefslogtreecommitdiff
path: root/deps/v8/tools/testrunner/local/testsuite.py
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/tools/testrunner/local/testsuite.py')
-rw-r--r--deps/v8/tools/testrunner/local/testsuite.py281
1 files changed, 172 insertions, 109 deletions
diff --git a/deps/v8/tools/testrunner/local/testsuite.py b/deps/v8/tools/testrunner/local/testsuite.py
index 3b8f956a7f..946e89a3fc 100644
--- a/deps/v8/tools/testrunner/local/testsuite.py
+++ b/deps/v8/tools/testrunner/local/testsuite.py
@@ -50,15 +50,17 @@ class VariantGenerator(object):
def FilterVariantsByTest(self, testcase):
result = self.all_variants
- if testcase.outcomes:
- if statusfile.OnlyStandardVariant(testcase.outcomes):
+ outcomes = testcase.suite.GetStatusFileOutcomes(testcase)
+ if outcomes:
+ if statusfile.OnlyStandardVariant(outcomes):
return self.standard_variant
- if statusfile.OnlyFastVariants(testcase.outcomes):
+ if statusfile.OnlyFastVariants(outcomes):
result = self.fast_variants
return result
def GetFlagSets(self, testcase, variant):
- if testcase.outcomes and statusfile.OnlyFastVariants(testcase.outcomes):
+ outcomes = testcase.suite.GetStatusFileOutcomes(testcase)
+ if outcomes and statusfile.OnlyFastVariants(outcomes):
return FAST_VARIANT_FLAGS[variant]
else:
return ALL_VARIANT_FLAGS[variant]
@@ -86,12 +88,11 @@ class TestSuite(object):
self.name = name # string
self.root = root # string containing path
self.tests = None # list of TestCase objects
- self.rules = None # dictionary mapping test path to list of outcomes
- self.wildcards = None # dictionary mapping test paths to list of outcomes
+ self.rules = None # {variant: {test name: [rule]}}
+ self.prefix_rules = None # {variant: {test name prefix: [rule]}}
self.total_duration = None # float, assigned on demand
- def shell(self):
- return "d8"
+ self._outcomes_cache = dict()
def suffix(self):
return ".js"
@@ -131,109 +132,104 @@ class TestSuite(object):
"""
pass
- def DownloadData(self):
- pass
-
def ReadStatusFile(self, variables):
with open(self.status_file()) as f:
- self.rules, self.wildcards = (
+ self.rules, self.prefix_rules = (
statusfile.ReadStatusFile(f.read(), variables))
def ReadTestCases(self, context):
self.tests = self.ListTests(context)
- @staticmethod
- def _FilterSlow(slow, mode):
- return (mode == "run" and not slow) or (mode == "skip" and slow)
+ def GetStatusfileFlags(self, test):
+ """Gets runtime flags from a status file.
- @staticmethod
- def _FilterPassFail(pass_fail, mode):
- return (mode == "run" and not pass_fail) or (mode == "skip" and pass_fail)
-
- def FilterTestCasesByStatus(self, warn_unused_rules,
- slow_tests="dontcare",
- pass_fail_tests="dontcare",
- variants=False):
-
- # Use only variants-dependent rules and wildcards when filtering
- # respective test cases and generic rules when filtering generic test
- # cases.
- if not variants:
- rules = self.rules[""]
- wildcards = self.wildcards[""]
- else:
- # We set rules and wildcards to a variant-specific version for each test
- # below.
- rules = {}
- wildcards = {}
+ Every outcome that starts with "--" is a flag. Status file has to be loaded
+ before using this function.
+ """
+ flags = []
+ for outcome in self.GetStatusFileOutcomes(test):
+ if outcome.startswith('--'):
+ flags.append(outcome)
+ return flags
- filtered = []
+ def FilterTestCasesByStatus(self,
+ slow_tests_mode=None,
+ pass_fail_tests_mode=None):
+ """Filters tests by outcomes from status file.
+
+ Status file has to be loaded before using this function.
+
+ Args:
+ slow_tests_mode: What to do with slow tests.
+ pass_fail_tests_mode: What to do with pass or fail tests.
- # Remember used rules as tuples of (rule, variant), where variant is "" for
- # variant-independent rules.
+ Mode options:
+ None (default) - don't skip
+ "skip" - skip if slow/pass_fail
+ "run" - skip if not slow/pass_fail
+ """
+ def _skip_slow(is_slow, mode):
+ return (
+ (mode == 'run' and not is_slow) or
+ (mode == 'skip' and is_slow))
+
+ def _skip_pass_fail(pass_fail, mode):
+ return (
+ (mode == 'run' and not pass_fail) or
+ (mode == 'skip' and pass_fail))
+
+ def _compliant(test):
+ outcomes = self.GetStatusFileOutcomes(test)
+ if statusfile.DoSkip(outcomes):
+ return False
+ if _skip_slow(statusfile.IsSlow(outcomes), slow_tests_mode):
+ return False
+ if _skip_pass_fail(statusfile.IsPassOrFail(outcomes),
+ pass_fail_tests_mode):
+ return False
+ return True
+
+ 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 t in self.tests:
- slow = False
- pass_fail = False
testname = self.CommonTestName(t)
variant = t.variant or ""
- if variants:
- rules = self.rules[variant]
- wildcards = self.wildcards[variant]
- if testname in rules:
- used_rules.add((testname, variant))
- # Even for skipped tests, as the TestCase object stays around and
- # PrintReport() uses it.
- t.outcomes = t.outcomes | rules[testname]
- if statusfile.DoSkip(t.outcomes):
- continue # Don't add skipped tests to |filtered|.
- for outcome in t.outcomes:
- if outcome.startswith('Flags: '):
- t.flags += outcome[7:].split()
- slow = statusfile.IsSlow(t.outcomes)
- pass_fail = statusfile.IsPassOrFail(t.outcomes)
- skip = False
- for rule in wildcards:
- assert rule[-1] == '*'
- if testname.startswith(rule[:-1]):
- used_rules.add((rule, variant))
- t.outcomes = t.outcomes | wildcards[rule]
- if statusfile.DoSkip(t.outcomes):
- skip = True
- break # "for rule in wildcards"
- slow = slow or statusfile.IsSlow(t.outcomes)
- pass_fail = pass_fail or statusfile.IsPassOrFail(t.outcomes)
- if (skip
- or self._FilterSlow(slow, slow_tests)
- or self._FilterPassFail(pass_fail, pass_fail_tests)):
- continue # "for t in self.tests"
- filtered.append(t)
- self.tests = filtered
-
- if not warn_unused_rules:
- return
-
- if not variants:
- for rule in self.rules[""]:
- if (rule, "") not in used_rules:
- print("Unused rule: %s -> %s (variant independent)" % (
- rule, self.rules[""][rule]))
- for rule in self.wildcards[""]:
- if (rule, "") not in used_rules:
- print("Unused rule: %s -> %s (variant independent)" % (
- rule, self.wildcards[""][rule]))
- else:
- for variant in ALL_VARIANTS:
- for rule in self.rules[variant]:
- if (rule, variant) not in used_rules:
- print("Unused rule: %s -> %s (variant: %s)" % (
- rule, self.rules[variant][rule], variant))
- for rule in self.wildcards[variant]:
- if (rule, variant) not in used_rules:
- print("Unused rule: %s -> %s (variant: %s)" % (
- rule, self.wildcards[variant][rule], variant))
+ if testname in self.rules.get(variant, {}):
+ used_rules.add((testname, variant))
+ if statusfile.DoSkip(self.rules[variant][testname]):
+ continue
+
+ for prefix in self.prefix_rules.get(variant, {}):
+ if testname.startswith(prefix):
+ used_rules.add((prefix, variant))
+ if statusfile.DoSkip(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 FilterTestCasesByArgs(self, args):
"""Filter test cases based on command-line arguments.
@@ -260,7 +256,66 @@ class TestSuite(object):
break
self.tests = filtered
- def GetFlagsForTestCase(self, testcase, context):
+ def GetExpectedOutcomes(self, testcase):
+ """Gets expected outcomes from status file.
+
+ It differs from GetStatusFileOutcomes by selecting only outcomes that can
+ be result of test execution.
+ Status file has to be loaded before using this function.
+ """
+ outcomes = self.GetStatusFileOutcomes(testcase)
+
+ expected = []
+ if (statusfile.FAIL in outcomes or
+ statusfile.FAIL_OK in outcomes):
+ expected.append(statusfile.FAIL)
+
+ if statusfile.CRASH in outcomes:
+ expected.append(statusfile.CRASH)
+
+ if statusfile.PASS in outcomes:
+ expected.append(statusfile.PASS)
+
+ return expected or [statusfile.PASS]
+
+ def GetStatusFileOutcomes(self, testcase):
+ """Gets outcomes from status file.
+
+ Merges variant dependent and independent rules. Status file has to be loaded
+ before using this function.
+ """
+ variant = testcase.variant or ''
+ testname = self.CommonTestName(testcase)
+ cache_key = '%s$%s' % (testname, variant)
+
+ if cache_key not in self._outcomes_cache:
+ # Load statusfile to get outcomes for the first time.
+ assert(self.rules is not None)
+ assert(self.prefix_rules is not None)
+
+ outcomes = frozenset()
+
+ for key in set([variant, '']):
+ 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]
+
+ self._outcomes_cache[cache_key] = outcomes
+
+ return self._outcomes_cache[cache_key]
+
+ def GetShellForTestCase(self, testcase):
+ """Returns shell to be executed for this test case."""
+ return 'd8'
+
+ def GetParametersForTestCase(self, testcase, context):
+ """Returns a tuple of (files, flags, env) for this test case."""
raise NotImplementedError
def GetSourceForTest(self, testcase):
@@ -290,8 +345,7 @@ class TestSuite(object):
return statusfile.PASS
def HasUnexpectedOutput(self, testcase):
- outcome = self.GetOutcome(testcase)
- return not outcome in (testcase.outcomes or [statusfile.PASS])
+ return self.GetOutcome(testcase) not in self.GetExpectedOutcomes(testcase)
def StripOutputForTransmit(self, testcase):
if not self.HasUnexpectedOutput(testcase):
@@ -315,18 +369,24 @@ class GoogleTestSuite(TestSuite):
super(GoogleTestSuite, self).__init__(name, root)
def ListTests(self, context):
- shell = os.path.abspath(os.path.join(context.shell_dir, self.shell()))
+ shell = os.path.abspath(
+ os.path.join(context.shell_dir, self.GetShellForTestCase(None)))
if utils.IsWindows():
shell += ".exe"
output = None
for i in xrange(3): # Try 3 times in case of errors.
- output = commands.Execute(context.command_prefix +
- [shell, "--gtest_list_tests"] +
- context.extra_flags)
+ cmd = (
+ context.command_prefix +
+ [shell, "--gtest_list_tests"] +
+ context.extra_flags
+ )
+ output = commands.Execute(cmd)
if output.exit_code == 0:
break
- print "Test executable failed to list the tests (try %d).\n\nStdout:" % i
+ print "Test executable failed to list the tests (try %d).\n\nCmd:" % i
+ print ' '.join(cmd)
+ print "\nStdout:"
print output.stdout
print "\nStderr:"
print output.stderr
@@ -346,14 +406,17 @@ class GoogleTestSuite(TestSuite):
tests.sort(key=lambda t: t.path)
return tests
- def GetFlagsForTestCase(self, testcase, context):
- return (testcase.flags + ["--gtest_filter=" + testcase.path] +
- ["--gtest_random_seed=%s" % context.random_seed] +
- ["--gtest_print_time=0"] +
- context.mode_flags)
+ def GetParametersForTestCase(self, testcase, context):
+ flags = (
+ testcase.flags +
+ ["--gtest_filter=" + testcase.path] +
+ ["--gtest_random_seed=%s" % context.random_seed] +
+ ["--gtest_print_time=0"] +
+ context.mode_flags)
+ return [], flags, {}
def _VariantGeneratorFactory(self):
return StandardVariantGenerator
- def shell(self):
+ def GetShellForTestCase(self, testcase):
return self.name