diff options
Diffstat (limited to 'buildscripts/resmokelib/testing/hooks/background_job.py')
-rw-r--r-- | buildscripts/resmokelib/testing/hooks/background_job.py | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/buildscripts/resmokelib/testing/hooks/background_job.py b/buildscripts/resmokelib/testing/hooks/background_job.py index b01196ba462..d239df4f6eb 100644 --- a/buildscripts/resmokelib/testing/hooks/background_job.py +++ b/buildscripts/resmokelib/testing/hooks/background_job.py @@ -3,6 +3,7 @@ import sys import threading +from buildscripts.resmokelib import errors from buildscripts.resmokelib.testing.hooks import jsfile @@ -98,3 +99,63 @@ class _ContinuousDynamicJSTestCase(jsfile.DynamicJSTestCase): last one. This method returns without waiting for the current execution to finish. """ self._should_stop.set() + + +class BackgroundRepeatedJsHook(jsfile.JSHook): + """A hook to run a js file on repeat in the background.""" + + IS_BACKGROUND = True + + def __init__(self, hook_logger, fixture, js_filename, description, thread_name, + shell_options=None): + """Initialize BackgroundRepeatedJsHook.""" + super().__init__(hook_logger, fixture, js_filename, description, + shell_options=shell_options) + self._background_job = None + self._thread_name = thread_name + + def before_suite(self, test_report): + """Start the background thread.""" + self._background_job = _BackgroundJob(self._thread_name) + self.logger.info("Starting background thread: {}.".format(self._thread_name)) + self._background_job.start() + + def after_suite(self, test_report, teardown_flag=None): + """Signal the background thread to exit, and wait until it does.""" + if self._background_job is None: + return + + self.logger.info("Stopping background thread: {}.".format(self._thread_name)) + self._background_job.stop() + + def before_test(self, test, test_report): + """Instruct the background thread to run while 'test' is also running.""" + if self._background_job is None: + return + + hook_test_case = _ContinuousDynamicJSTestCase.create_before_test( + test.logger, test, self, self._js_filename, self._shell_options) + hook_test_case.configure(self.fixture) + + self.logger.info("Resuming background thread: {}.".format(self._thread_name)) + self._background_job.resume(hook_test_case, test_report) + + def after_test(self, test, test_report): # noqa: D205,D400 + """Instruct the background thread to stop running now that 'test' has finished running.""" + if self._background_job is None: + return + + self.logger.info("Pausing background thread: {}.".format(self._thread_name)) + self._background_job.pause() + + if self._background_job.exc_info is not None: + if isinstance(self._background_job.exc_info[1], errors.TestFailure): + # If the mongo shell process running the JavaScript file exited with a non-zero + # return code, then we raise an errors.ServerFailure exception to cause resmoke.py's + # test execution to stop. + raise errors.ServerFailure(self._background_job.exc_info[1].args[0]) + else: + self.logger.error( + "Encountered an error inside background thread {}.".format(self._thread_name), + exc_info=self._background_job.exc_info) + raise self._background_job.exc_info[1] |