summaryrefslogtreecommitdiff
path: root/buildscripts/resmokelib/testing/report.py
diff options
context:
space:
mode:
authorLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
committerLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
commit4cb8841196d0625dfa3825aa326f071cd27c7b8b (patch)
tree1682a647d4463397c119183369ae6f750d5fdcff /buildscripts/resmokelib/testing/report.py
parentaa03c6362cbaa767638e6eed9b031d86dd2643d1 (diff)
parent8f0827553e09872941945a093b647a4211a9db7f (diff)
Update upstream source from tag 'upstream/6.0.0'master
Update to upstream version '6.0.0' with Debian dir 5604a80ec1c96ca76f25f40d78e6ef855abec322
Diffstat (limited to 'buildscripts/resmokelib/testing/report.py')
-rw-r--r--buildscripts/resmokelib/testing/report.py89
1 files changed, 40 insertions, 49 deletions
diff --git a/buildscripts/resmokelib/testing/report.py b/buildscripts/resmokelib/testing/report.py
index e2655e8bf81..38fe409b656 100644
--- a/buildscripts/resmokelib/testing/report.py
+++ b/buildscripts/resmokelib/testing/report.py
@@ -4,14 +4,12 @@ This is used to support additional test status and timing information for the re
"""
import copy
-import os
import threading
import time
import unittest
from buildscripts.resmokelib import config as _config
from buildscripts.resmokelib import logging
-from buildscripts.resmokelib.testing.symbolizer_service import ResmokeSymbolizer
# pylint: disable=attribute-defined-outside-init
@@ -56,9 +54,7 @@ class TestReport(unittest.TestResult): # pylint: disable=too-many-instance-attr
for report in reports:
if not isinstance(report, TestReport):
- raise TypeError(
- f"reports must be a list of TestReport instances, current report is {type(report)}"
- )
+ raise TypeError("reports must be a list of TestReport instances")
with report._lock: # pylint: disable=protected-access
for test_info in report.test_infos:
@@ -110,7 +106,6 @@ class TestReport(unittest.TestResult): # pylint: disable=too-many-instance-attr
unittest.TestResult.startTest(self, test)
test_info = TestInfo(test.id(), test.test_name, test.dynamic)
- test_info.group_id = f"job{self.job_num}"
basename = test.basename()
command = test.as_command()
@@ -129,53 +124,40 @@ class TestReport(unittest.TestResult): # pylint: disable=too-many-instance-attr
test.basename(), command,
test.logger, self.job_num,
test.id(), self.job_logger)
- test_info.log_info = {
- "log_name": logging.loggers.get_evergreen_log_name(self.job_num, test.id()),
- "logs_to_merge": [logging.loggers.get_evergreen_log_name(self.job_num)],
- "rendering_type": "resmoke", "version": 0
- }
test_info.url_endpoint = url_endpoint
if self.logging_prefix is not None:
test_logger.info(self.logging_prefix)
# Set job_num in test.
test.job_num = self.job_num
+
test.override_logger(test_logger)
test_info.start_time = time.time()
def stopTest(self, test): # pylint: disable=invalid-name
"""Call after 'test' has run."""
- try:
- # check if there are stacktrace files, if so, invoke the symbolizer here.
- # log symbolized output to test.logger.info()
- symbolizer = ResmokeSymbolizer()
- symbolizer.symbolize_test_logs(test)
-
- unittest.TestResult.stopTest(self, test)
-
- with self._lock:
- test_info = self.find_test_info(test)
- test_info.end_time = time.time()
- test_status = "no failures detected" if test_info.status == "pass" else "failed"
-
- time_taken = test_info.end_time - test_info.start_time
- self.job_logger.info("%s ran in %0.2f seconds: %s.", test.basename(), time_taken,
- test_status)
-
- finally:
- # This is a failsafe. In the event that 'stopTest' fails,
- # any rogue logger handlers will be removed from this test.
- # If not cleaned up, these will trigger 'setup failures' --
- # indicated by exiting with LoggerRuntimeConfigError.EXIT_CODE.
- for handler in test.logger.handlers:
- # We ignore the cancellation token returned by close_later() since we always want the
- # logs to eventually get flushed.
- logging.flush.close_later(handler)
-
- # Restore the original logger for the test.
- test.reset_logger()
-
- def addError(self, test, err):
+ unittest.TestResult.stopTest(self, test)
+
+ with self._lock:
+ test_info = self.find_test_info(test)
+ test_info.end_time = time.time()
+ test_status = "no failures detected" if test_info.status == "pass" else "failed"
+
+ time_taken = test_info.end_time - test_info.start_time
+ self.job_logger.info("%s ran in %0.2f seconds: %s.", test.basename(), time_taken,
+ test_status)
+
+ # Asynchronously closes the buildlogger test handler to avoid having too many threads open
+ # on 32-bit systems.
+ for handler in test.logger.handlers:
+ # We ignore the cancellation token returned by close_later() since we always want the
+ # logs to eventually get flushed.
+ logging.flush.close_later(handler)
+
+ # Restore the original logger for the test.
+ test.reset_logger()
+
+ def addError(self, test, err): # pylint: disable=invalid-name
"""Call when a non-failureException was raised during the execution of 'test'."""
unittest.TestResult.addError(self, test, err)
@@ -219,7 +201,12 @@ class TestReport(unittest.TestResult): # pylint: disable=too-many-instance-attr
test_info = self.find_test_info(test)
test_info.status = "fail"
- test_info.evergreen_status = "fail"
+ if test_info.dynamic:
+ # Dynamic tests are used for data consistency checks, so the failures are never
+ # silenced.
+ test_info.evergreen_status = "fail"
+ else:
+ test_info.evergreen_status = self.suite_options.report_failure_status
test_info.return_code = test.return_code
def setFailure(self, test, return_code=1): # pylint: disable=invalid-name
@@ -231,7 +218,12 @@ class TestReport(unittest.TestResult): # pylint: disable=too-many-instance-attr
raise ValueError("stopTest was not called on %s" % (test.basename()))
test_info.status = "fail"
- test_info.evergreen_status = "fail"
+ if test_info.dynamic:
+ # Dynamic tests are used for data consistency checks, so the failures are never
+ # silenced.
+ test_info.evergreen_status = "fail"
+ else:
+ test_info.evergreen_status = self.suite_options.report_failure_status
test_info.return_code = return_code
# Recompute number of success, failures, and errors.
@@ -294,18 +286,19 @@ class TestReport(unittest.TestResult): # pylint: disable=too-many-instance-attr
for test_info in self.test_infos:
result = {
"test_file": test_info.test_file,
- "group_id": test_info.group_id,
"status": test_info.evergreen_status,
"exit_code": test_info.return_code,
"start": test_info.start_time,
"end": test_info.end_time,
"elapsed": test_info.end_time - test_info.start_time,
- "log_info": test_info.log_info,
}
if test_info.display_test_name is not None:
result["display_test_name"] = test_info.display_test_name
+ if test_info.group_id is not None:
+ result["group_id"] = test_info.group_id
+
if test_info.url_endpoint is not None:
result["url"] = test_info.url_endpoint
result["url_raw"] = test_info.url_endpoint + "?raw=1"
@@ -335,7 +328,6 @@ class TestReport(unittest.TestResult): # pylint: disable=too-many-instance-attr
test_info = TestInfo(test_file, test_file, is_dynamic)
test_info.display_test_name = result.get("display_test_name")
test_info.group_id = result.get("group_id")
- test_info.log_info = result.get("log_info")
test_info.url_endpoint = result.get("url")
test_info.status = result["status"]
test_info.evergreen_status = test_info.status
@@ -389,16 +381,15 @@ class TestInfo(object): # pylint: disable=too-many-instance-attributes
self.test_id = test_id
self.test_file = test_file
- self.group_id = None
self.display_test_name = None
self.dynamic = dynamic
+ self.group_id = None
self.start_time = None
self.end_time = None
self.status = None
self.evergreen_status = None
self.return_code = None
- self.log_info = None
self.url_endpoint = None