Пример #1
0
def test_shutdown_blocking_awaits_running_callbacks():
    called_with = []
    at_least_one_called = threading.Event()
    at_least_one_completed = threading.Event()

    def callback(message):
        called_with.append(message)  # appends are thread-safe
        at_least_one_called.set()
        time.sleep(1.0)
        at_least_one_completed.set()

    executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
    scheduler_ = scheduler.ThreadScheduler(executor=executor)

    scheduler_.schedule(callback, "message_1")
    scheduler_.schedule(callback, "message_2")

    at_least_one_called.wait()
    dropped = scheduler_.shutdown(await_msg_callbacks=True)

    assert len(called_with) == 1
    assert called_with[0] in {"message_1", "message_2"}

    # The work items that have not been started yet should still be dropped.
    assert len(dropped) == 1
    assert dropped[0] in {"message_1", "message_2"}
    assert dropped[0] != called_with[0]  # the dropped message was not the processed one

    err_msg = "Shutdown did not wait for the already running callbacks to complete."
    assert at_least_one_completed.is_set(), err_msg
Пример #2
0
def test_shutdown_nonblocking_by_default():
    called_with = []
    at_least_one_called = threading.Event()
    at_least_one_completed = threading.Event()

    def callback(message):
        called_with.append(message)  # appends are thread-safe
        at_least_one_called.set()
        time.sleep(1.0)
        at_least_one_completed.set()

    executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
    scheduler_ = scheduler.ThreadScheduler(executor=executor)

    scheduler_.schedule(callback, "message_1")
    scheduler_.schedule(callback, "message_2")

    at_least_one_called.wait()
    dropped = scheduler_.shutdown()

    assert len(called_with) == 1
    assert called_with[0] in {"message_1", "message_2"}

    assert len(dropped) == 1
    assert dropped[0] in {"message_1", "message_2"}
    assert dropped[0] != called_with[0]  # the dropped message was not the processed one

    err_msg = (
        "Shutdown should not have waited "
        "for the already running callbacks to complete."
    )
    assert not at_least_one_completed.is_set(), err_msg
Пример #3
0
def test_schedule_executes_submitted_items():
    called_with = []
    callback_done_twice = threading.Barrier(
        3)  # 3 == 2x callback + 1x main thread

    def callback(*args, **kwargs):
        called_with.append((args, kwargs))  # appends are thread-safe
        callback_done_twice.wait()

    scheduler_ = scheduler.ThreadScheduler()

    scheduler_.schedule(callback, "arg1", kwarg1="meep")
    scheduler_.schedule(callback, "arg2", kwarg2="boop")

    callback_done_twice.wait(timeout=3.0)
    result = scheduler_.shutdown()

    assert result == []  # no scheduled items dropped

    expected_calls = [(("arg1", ), {
        "kwarg1": "meep"
    }), (("arg2", ), {
        "kwarg2": "boop"
    })]
    assert sorted(called_with) == expected_calls
Пример #4
0
def test_shutdown_handles_executor_queue_sentinels():
    at_least_one_called = threading.Event()

    def callback(_):
        at_least_one_called.set()
        time.sleep(1.0)

    executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
    scheduler_ = scheduler.ThreadScheduler(executor=executor)

    scheduler_.schedule(callback, "message_1")
    scheduler_.schedule(callback, "message_2")
    scheduler_.schedule(callback, "message_3")

    # Simulate executor shutdown from another thread.
    executor._work_queue.put(None)
    executor._work_queue.put(None)

    at_least_one_called.wait()
    dropped = scheduler_.shutdown(await_msg_callbacks=True)

    assert len(set(dropped)) == 2  # Also test for item uniqueness.
    for msg in dropped:
        assert msg is not None
        assert msg.startswith("message_")
def test_schedule():
    called_with = []
    called = threading.Event()

    def callback(*args, **kwargs):
        called_with.append((args, kwargs))
        called.set()

    scheduler_ = scheduler.ThreadScheduler()

    scheduler_.schedule(callback, "arg1", kwarg1="meep")

    called.wait()
    scheduler_.shutdown()

    assert called_with == [(("arg1",), {"kwarg1": "meep"})]
Пример #6
0
def test_schedule_after_executor_shutdown_warning():
    def callback(*args, **kwargs):
        pass

    scheduler_ = scheduler.ThreadScheduler()

    scheduler_.schedule(callback, "arg1", kwarg1="meep")
    scheduler_._executor.shutdown()

    with warnings.catch_warnings(record=True) as warned:
        scheduler_.schedule(callback, "arg2", kwarg2="boop")

    assert len(warned) == 1
    assert issubclass(warned[0].category, RuntimeWarning)
    warning_msg = str(warned[0].message)
    assert "after executor shutdown" in warning_msg
def test_constructor_options():
    scheduler_ = scheduler.ThreadScheduler(executor=mock.sentinel.executor)

    assert scheduler_._executor == mock.sentinel.executor
def test_constructor_defaults():
    scheduler_ = scheduler.ThreadScheduler()

    assert isinstance(scheduler_.queue, queue.Queue)
    assert isinstance(scheduler_._executor, concurrent.futures.Executor)