summaryrefslogtreecommitdiffstats
path: root/lldb/packages/Python/lldbsuite/test/result_formatter.py
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/packages/Python/lldbsuite/test/result_formatter.py')
-rw-r--r--lldb/packages/Python/lldbsuite/test/result_formatter.py85
1 files changed, 77 insertions, 8 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/result_formatter.py b/lldb/packages/Python/lldbsuite/test/result_formatter.py
index cf0a6cf6b31..ff77c1411ba 100644
--- a/lldb/packages/Python/lldbsuite/test/result_formatter.py
+++ b/lldb/packages/Python/lldbsuite/test/result_formatter.py
@@ -28,6 +28,7 @@ import six
from six.moves import cPickle
# LLDB modules
+from . import configuration
# Ignore method count on DTOs.
@@ -165,7 +166,8 @@ class EventBuilder(object):
RESULT_TYPES = set([
TYPE_JOB_RESULT,
- TYPE_TEST_RESULT])
+ TYPE_TEST_RESULT
+ ])
# Test/Job Status Tags
STATUS_EXCEPTIONAL_EXIT = "exceptional_exit"
@@ -178,6 +180,16 @@ class EventBuilder(object):
STATUS_ERROR = "error"
STATUS_TIMEOUT = "timeout"
+ """Test methods or jobs with a status matching any of these
+ status values will cause a testrun failure, unless
+ the test methods rerun and do not trigger an issue when rerun."""
+ TESTRUN_ERROR_STATUS_VALUES = set([
+ STATUS_ERROR,
+ STATUS_EXCEPTIONAL_EXIT,
+ STATUS_FAILURE,
+ STATUS_TIMEOUT
+ ])
+
@staticmethod
def _get_test_name_info(test):
"""Returns (test-class-name, test-method-name) from a test case instance.
@@ -655,6 +667,61 @@ class ResultsFormatter(object):
# timeout test status for this.
self.expected_timeouts_by_basename = set()
+ # Keep track of rerun-eligible tests.
+ # This is a set that contains tests saved as:
+ # {test_filename}:{test_class}:{test_name}
+ self.rerun_eligible_tests = set()
+
+ # A dictionary of test files that had a failing
+ # test, in the format of:
+ # key = test path, value = array of test methods that need rerun
+ self.tests_for_rerun = {}
+
+ @classmethod
+ def _make_rerun_eligibility_key(cls, test_result_event):
+ if test_result_event is None:
+ return None
+ component_count = 0
+ if "test_filename" in test_result_event:
+ key = test_result_event["test_filename"]
+ component_count += 1
+ if "test_class" in test_result_event:
+ if component_count > 0:
+ key += "."
+ key += test_result_event["test_class"]
+ component_count += 1
+ if "test_name" in test_result_event:
+ if component_count > 0:
+ key += "."
+ key += test_result_event["test_name"]
+ component_count += 1
+ return key
+
+ def _mark_test_for_rerun_eligibility(self, test_result_event):
+ key = self._make_rerun_eligibility_key(test_result_event)
+ if key is not None:
+ self.rerun_eligible_tests.add(key)
+ else:
+ sys.stderr.write(
+ "\nerror: test marked for re-run eligibility but "
+ "failed to create key.\n")
+
+ def _maybe_add_test_to_rerun_list(self, result_event):
+ key = self._make_rerun_eligibility_key(result_event)
+ if key is not None:
+ if key in self.rerun_eligible_tests or configuration.rerun_all_issues:
+ test_filename = result_event.get("test_filename", None)
+ if test_filename is not None:
+ test_name = result_event.get("test_name", None)
+ if not test_filename in self.tests_for_rerun:
+ self.tests_for_rerun[test_filename] = []
+ if test_name is not None:
+ self.tests_for_rerun[test_filename].append(test_name)
+ else:
+ sys.stderr.write(
+ "\nerror: couldn't add testrun-failing test to rerun "
+ "list because no eligibility key could be created.\n")
+
def _maybe_remap_job_result_event(self, test_event):
"""Remaps timeout/exceptional exit job results to last test method running.
@@ -684,13 +751,6 @@ class ResultsFormatter(object):
if start_key not in test_event:
test_event[start_key] = start_value
- # Always take the value of test_filename from test_start,
- # as it was gathered by class introspections. Job status
- # has less refined info available to it, so might be missing
- # path info.
- if "test_filename" in test_start:
- test_event["test_filename"] = test_start["test_filename"]
-
def _maybe_remap_expected_timeout(self, event):
if event is None:
return
@@ -749,12 +809,21 @@ class ResultsFormatter(object):
worker_index = test_event.get("worker_index", None)
if worker_index is not None:
self.started_tests_by_worker.pop(worker_index, None)
+
+ if status in EventBuilder.TESTRUN_ERROR_STATUS_VALUES:
+ # A test/job status value in any of those status values
+ # causes a testrun failure. If such a test fails, check
+ # whether it can be rerun. If it can be rerun, add it
+ # to the rerun job.
+ self._maybe_add_test_to_rerun_list(test_event)
elif event_type == EventBuilder.TYPE_TEST_START:
# Keep track of the most recent test start event
# for the related worker.
worker_index = test_event.get("worker_index", None)
if worker_index is not None:
self.started_tests_by_worker[worker_index] = test_event
+ elif event_type == EventBuilder.TYPE_MARK_TEST_RERUN_ELIGIBLE:
+ self._mark_test_for_rerun_eligibility(test_event)
def set_expected_timeouts_by_basename(self, basenames):
"""Specifies a list of test file basenames that are allowed to timeout
OpenPOWER on IntegriCloud