summaryrefslogtreecommitdiff
path: root/buildscripts/resmokelib/testing
diff options
context:
space:
mode:
authorRobert Guo <robert.guo@mongodb.com>2021-06-15 17:51:01 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-06-16 16:08:23 +0000
commit796a9f1504ea088bca412b8af787b735943245cf (patch)
treed7af48782eb4494338ee50c689a74b6207f58930 /buildscripts/resmokelib/testing
parentc73b1c09eb5ce2053577abac0a4ba360e3845de8 (diff)
downloadmongo-796a9f1504ea088bca412b8af787b735943245cf.tar.gz
SERVER-57439 add unittest task with undodb recordings to ! RHEL 8
Diffstat (limited to 'buildscripts/resmokelib/testing')
-rw-r--r--buildscripts/resmokelib/testing/testcases/cpp_unittest.py24
-rw-r--r--buildscripts/resmokelib/testing/testcases/interface.py16
-rw-r--r--buildscripts/resmokelib/testing/testcases/jstest.py15
3 files changed, 48 insertions, 7 deletions
diff --git a/buildscripts/resmokelib/testing/testcases/cpp_unittest.py b/buildscripts/resmokelib/testing/testcases/cpp_unittest.py
index 08b4a7e0cbd..9162bce16c9 100644
--- a/buildscripts/resmokelib/testing/testcases/cpp_unittest.py
+++ b/buildscripts/resmokelib/testing/testcases/cpp_unittest.py
@@ -1,5 +1,7 @@
"""The unittest.TestCase for C++ unit tests."""
+import os
+from buildscripts.resmokelib import config
from buildscripts.resmokelib import core
from buildscripts.resmokelib import utils
from buildscripts.resmokelib.testing.testcases import interface
@@ -18,6 +20,28 @@ class CPPUnitTestCase(interface.ProcessTestCase):
self.program_executable = program_executable
self.program_options = utils.default_if_none(program_options, {}).copy()
+ def run_test(self):
+ """Run the test."""
+ try:
+ super().run_test()
+ except self.failureException:
+ if config.UNDO_RECORDER_PATH:
+ # Record the list of failed tests so we can upload them to the Evergreen task.
+ # Non-recorded tests rely on the core dump content to identify the test binaries.
+ with open("failed_recorded_tests.txt", 'a') as failure_list:
+ failure_list.write(self.program_executable)
+ failure_list.write("\n")
+ self.logger.exception(
+ "*** Failed test run was recorded. ***\n"
+ "For instructions on using the recording instead of core dumps, see\n"
+ "https://wiki.corp.mongodb.com/display/COREENG/Time+Travel+Debugging+in+MongoDB\n"
+ "For questions or bug reports, please reach our in #server-testing")
+
+ # Archive any available recordings if there's any failure. It's possible a problem
+ # with the recorder will cause no recordings to be generated.
+ self._cull_recordings(os.path.basename(self.program_executable))
+ raise
+
def _make_process(self):
self.program_options["job_num"] = self.fixture.job_num
self.program_options["test_id"] = self._id
diff --git a/buildscripts/resmokelib/testing/testcases/interface.py b/buildscripts/resmokelib/testing/testcases/interface.py
index 474ddb2ae01..67733e74737 100644
--- a/buildscripts/resmokelib/testing/testcases/interface.py
+++ b/buildscripts/resmokelib/testing/testcases/interface.py
@@ -2,12 +2,13 @@
This is used to perform the actual test case.
"""
-
+import glob
import os
import os.path
import unittest
import uuid
+from buildscripts.resmokelib import config
from buildscripts.resmokelib import logging
from buildscripts.resmokelib.utils import registry
@@ -116,8 +117,8 @@ class ProcessTestCase(TestCase): # pylint: disable=abstract-method
def run_test(self):
"""Run the test."""
try:
- shell = self._make_process()
- self._execute(shell)
+ proc = self._make_process()
+ self._execute(proc)
except self.failureException:
raise
except:
@@ -145,3 +146,12 @@ class ProcessTestCase(TestCase): # pylint: disable=abstract-method
def _make_process(self):
"""Return a new Process instance that could be used to run the test or log the command."""
raise NotImplementedError("_make_process must be implemented by TestCase subclasses")
+
+ def _cull_recordings(self, program_executable):
+ """Move recordings if test fails so it doesn't get deleted."""
+ # Only store my recordings. Concurrent processes may generate their own recordings that we
+ # should ignore. There's a problem with duplicate program names under different directories
+ # But that should be rare and there's no harm in having more recordings stored.
+ for recording in glob.glob(program_executable + "*.undo"):
+ self.logger.info("Keeping recording %s", recording)
+ os.rename(recording, recording + '.tokeep')
diff --git a/buildscripts/resmokelib/testing/testcases/jstest.py b/buildscripts/resmokelib/testing/testcases/jstest.py
index b2ab85df514..f6ae1033e94 100644
--- a/buildscripts/resmokelib/testing/testcases/jstest.py
+++ b/buildscripts/resmokelib/testing/testcases/jstest.py
@@ -230,10 +230,17 @@ class JSTestCase(interface.ProcessTestCase):
def run_test(self):
"""Execute the test."""
- if self.num_clients == 1:
- self._run_single_copy()
- else:
- self._run_multiple_copies()
+ try:
+ if self.num_clients == 1:
+ self._run_single_copy()
+ else:
+ self._run_multiple_copies()
+ except:
+ # Archive any available recordings if there's any failure. It's possible a problem
+ # with the recorder will cause no recordings to be generated. There will also be
+ # recordings of other processes, we keep them to avoid complicating this code.
+ self._cull_recordings("mongo")
+ raise
def _raise_if_unsafe_exit(self, return_code):
"""Determine if a return code represents and unsafe exit."""