# Path: tests/log_handler.py
# class PykkaTestLogHandler(logging.Handler):
#     def __init__(self, *args, **kwargs):
#         self.lock = threading.RLock()
#         with self.lock:
#             self.events = collections.defaultdict(threading.Event)
#             self.messages = {}
#             self.reset()
#         logging.Handler.__init__(self, *args, **kwargs)
# 
#     def emit(self, record):
#         with self.lock:
#             level = record.levelname.lower()
#             self.messages[level].append(record)
#             self.events[level].set()
# 
#     def reset(self):
#         with self.lock:
#             for level in ("debug", "info", "warning", "error", "critical"):
#                 self.events[level].clear()
#                 self.messages[level] = []
# 
#     def wait_for_message(self, level, num_messages=1, timeout=5):
#         """Wait until at least ``num_messages`` log messages have been emitted
#         to the given log level."""
#         deadline = time.time() + timeout
#         while time.time() < deadline:
#             with self.lock:
#                 if len(self.messages[level]) >= num_messages:
#                     return
#                 self.events[level].clear()
#             self.events[level].wait(1)
#         raise Exception(f"Timeout: Waited {timeout:d}s for log message")


import logging
import threading
import time
import pytest
from collections import namedtuple
from pykka import ActorRegistry, ThreadingActor, ThreadingFuture
from tests.log_handler import PykkaTestLogHandler
        def __init__(self, events):
            super().__init__()
            self.events = events

        def on_start(self):
            self.stop()

        def on_stop(self):
            try:
                raise RuntimeError("on_stop failure")
            finally:
                self.events.on_stop_was_called.set()

    return LateFailingActor


@pytest.fixture(scope="module")
def failing_on_failure_actor_class(runtime):
    class FailingOnFailureActor(runtime.actor_class):
        def __init__(self, events):
            super().__init__()
            self.events = events

        def on_receive(self, message):
            if message.get("command") == "raise exception":
                raise Exception("on_receive failure")
            else:
                super().on_receive(message)

        def on_failure(self, *args):

# Path: tests/log_handler.py
# class PykkaTestLogHandler(logging.Handler):
#     def __init__(self, *args, **kwargs):
#         self.lock = threading.RLock()
#         with self.lock:
#             self.events = collections.defaultdict(threading.Event)
#             self.messages = {}
#             self.reset()
#         logging.Handler.__init__(self, *args, **kwargs)
# 
#     def emit(self, record):
#         with self.lock:
#             level = record.levelname.lower()
#             self.messages[level].append(record)
#             self.events[level].set()
# 
#     def reset(self):
#         with self.lock:
#             for level in ("debug", "info", "warning", "error", "critical"):
#                 self.events[level].clear()
#                 self.messages[level] = []
# 
#     def wait_for_message(self, level, num_messages=1, timeout=5):
#         """Wait until at least ``num_messages`` log messages have been emitted
#         to the given log level."""
#         deadline = time.time() + timeout
#         while time.time() < deadline:
#             with self.lock:
#                 if len(self.messages[level]) >= num_messages:
#                     return
#                 self.events[level].clear()
#             self.events[level].wait(1)
#         raise Exception(f"Timeout: Waited {timeout:d}s for log message")


# Path: tests/conftest.py
import logging
import threading
import time
import pytest
from collections import namedtuple
from pykka import ActorRegistry, ThreadingActor, ThreadingFuture
from tests.log_handler import PykkaTestLogHandler

        def __init__(self, events):
            super().__init__()
            self.events = events

        def on_start(self):
            self.stop()

        def on_stop(self):
            try:
                raise RuntimeError("on_stop failure")
            finally:
                self.events.on_stop_was_called.set()

    return LateFailingActor


@pytest.fixture(scope="module")
def failing_on_failure_actor_class(runtime):
    class FailingOnFailureActor(runtime.actor_class):
        def __init__(self, events):
            super().__init__()
            self.events = events

        def on_receive(self, message):
            if message.get("command") == "raise exception":
                raise Exception("on_receive failure")
            else:
                super().on_receive(message)

        def on_failure(self, *args):

            try: