test_build: exit rather than hanging on event handler exception

Event handlers decorated with @celery_app_task don't raise an exception -
they just log the exception, leaving the Moksha hub running. This meant
that any failures in test_build would result in the test suite hanging
rather than failing usefully.

We solve this by adding a new class EventTrap which acts as a context
manager. Any exceptions that occur in event handlers are set on the
current EventTrap, and the test_build tests re-raise the exception.
This commit is contained in:
Owen W. Taylor
2021-01-22 15:11:04 -05:00
parent 3a633967ec
commit 4ddd3c2637
2 changed files with 74 additions and 13 deletions

View File

@@ -83,6 +83,16 @@ def make_simple_stop_condition():
return stop_condition
def make_trapped_stop_condition(stop_condition):
def trapped_stop_condition(message):
if events.EventTrap.get_exception():
return True
return stop_condition(message)
return trapped_stop_condition
def main(initial_messages, stop_condition):
""" Run the consumer until some condition is met.
@@ -108,18 +118,25 @@ def main(initial_messages, stop_condition):
consumers = [module_build_service.scheduler.consumer.MBSConsumer]
# Note that the hub we kick off here cannot send any message. You
# should use fedmsg.publish(...) still for that.
moksha.hub.main(
# Pass in our config dict
options=config,
# Only run the specified consumers if any are so specified.
consumers=consumers,
# Do not run default producers.
producers=[],
# Tell moksha to quiet its logging.
framework=False,
)
# The events.EventTrap context handler allows us to detect exceptions
# in event handlers and re-raise them here so that tests fail usefully
# rather than just hang.
with events.EventTrap() as trap:
# Note that the hub we kick off here cannot send any message. You
# should use fedmsg.publish(...) still for that.
moksha.hub.main(
# Pass in our config dict
options=config,
# Only run the specified consumers if any are so specified.
consumers=consumers,
# Do not run default producers.
producers=[],
# Tell moksha to quiet its logging.
framework=False,
)
if trap.exception:
raise trap.exception
class FakeSCM(object):
@@ -388,9 +405,10 @@ def cleanup_moksha():
class BaseTestBuild:
def run_scheduler(self, msgs=None, stop_condition=None):
stop_condition = stop_condition or make_simple_stop_condition()
main(
msgs or [],
stop_condition or make_simple_stop_condition()
make_trapped_stop_condition(stop_condition)
)