mirror of https://github.com/mongodb/mongo
101 lines
3.4 KiB
Python
101 lines
3.4 KiB
Python
"""Background job utils. Helps run a JS file repeatedly while a test suite's tests run."""
|
|
|
|
import sys
|
|
import threading
|
|
|
|
from buildscripts.resmokelib.testing.hooks import jsfile
|
|
|
|
|
|
class _BackgroundJob(threading.Thread):
|
|
"""A thread for running a JS file while a test is running."""
|
|
|
|
def __init__(self, thread_name):
|
|
"""Initialize _BackgroundJob."""
|
|
threading.Thread.__init__(self, name=thread_name)
|
|
self.daemon = True
|
|
|
|
self._lock = threading.Lock()
|
|
self._cond = threading.Condition(self._lock)
|
|
|
|
self._should_stop = False
|
|
self._should_resume = False
|
|
self._is_idle = True
|
|
|
|
self._hook_test_case = None
|
|
self._test_report = None
|
|
self.exc_info = None
|
|
|
|
def run(self):
|
|
while True:
|
|
with self._lock:
|
|
while not self._should_resume:
|
|
self._cond.wait()
|
|
|
|
# We have the background thread set 'self._should_resume' back to false to ensure
|
|
# that 'self._hook_test_case.run_dynamic_test()' is only called once before the
|
|
# resume() method is called again.
|
|
self._should_resume = False
|
|
|
|
if self._should_stop:
|
|
break
|
|
|
|
# We are about to execute 'self._hook_test_case' so we mark the background thread as
|
|
# no longer being idle.
|
|
self._is_idle = False
|
|
|
|
try:
|
|
self._hook_test_case.run_dynamic_test(self._test_report)
|
|
except:
|
|
self.exc_info = sys.exc_info()
|
|
finally:
|
|
with self._lock:
|
|
self._is_idle = True
|
|
self._cond.notify_all()
|
|
|
|
def stop(self):
|
|
"""Signal the background thread to exit, and wait until it does."""
|
|
with self._lock:
|
|
self._should_stop = True
|
|
self.resume(hook_test_case=None, test_report=None)
|
|
self.join()
|
|
|
|
def pause(self): # noqa: D205,D400
|
|
"""
|
|
Signal the background thread that it should stop executing 'self._hook_test_case'.
|
|
|
|
Wait until the current execution has finished.
|
|
"""
|
|
self._hook_test_case.signal_stop_test()
|
|
with self._lock:
|
|
while not self._is_idle:
|
|
self._cond.wait()
|
|
|
|
def resume(self, hook_test_case, test_report):
|
|
"""Instruct the background thread to start executing 'hook_test_case'."""
|
|
self._hook_test_case = hook_test_case
|
|
self._test_report = test_report
|
|
self.exc_info = None
|
|
with self._lock:
|
|
self._should_resume = True
|
|
self._cond.notify_all()
|
|
|
|
|
|
class _ContinuousDynamicJSTestCase(jsfile.DynamicJSTestCase):
|
|
"""A dynamic TestCase that runs a JavaScript file repeatedly."""
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
"""Initialize _ContinuousDynamicJSTestCase."""
|
|
jsfile.DynamicJSTestCase.__init__(self, *args, **kwargs)
|
|
self._should_stop = threading.Event()
|
|
|
|
def run_test(self):
|
|
"""Execute the test repeatedly."""
|
|
while not self._should_stop.is_set():
|
|
jsfile.DynamicJSTestCase.run_test(self)
|
|
|
|
def signal_stop_test(self): # noqa: D205,D400
|
|
"""Indicate to the thread executing the run_test() method that the current execution is the
|
|
last one. This method returns without waiting for the current execution to finish.
|
|
"""
|
|
self._should_stop.set()
|