diff options
| author | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-11 15:07:35 -0300 |
|---|---|---|
| committer | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-11 15:07:35 -0300 |
| commit | 4cb8841196d0625dfa3825aa326f071cd27c7b8b (patch) | |
| tree | 1682a647d4463397c119183369ae6f750d5fdcff /buildscripts/resmokelib/testing/report.py | |
| parent | aa03c6362cbaa767638e6eed9b031d86dd2643d1 (diff) | |
| parent | 8f0827553e09872941945a093b647a4211a9db7f (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.py | 89 |
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 |
