async def connect(port, baudrate, application, use_thread=True): if use_thread: application = ThreadsafeProxy(application, asyncio.get_event_loop()) thread = EventLoopThread() await thread.start() protocol, connection_done = await thread.run_coroutine_threadsafe( _connect(port, baudrate, application)) connection_done.add_done_callback(lambda _: thread.force_stop()) else: protocol, _ = await _connect(port, baudrate, application) return protocol
async def thread(): thread = EventLoopThread() await thread.start() thread.loop.call_soon_threadsafe(thread.loop.set_exception_handler, ExceptionCollector()) yield thread thread.force_stop() if thread.thread_complete is not None: await asyncio.wait_for(thread.thread_complete, 1) [t.join(1) for t in threading.enumerate() if "bellows" in t.name] threads = [t for t in threading.enumerate() if "bellows" in t.name] assert len(threads) == 0
async def test_thread_start(monkeypatch): current_loop = asyncio.get_event_loop() loopmock = mock.MagicMock() monkeypatch.setattr(asyncio, "new_event_loop", lambda: loopmock) monkeypatch.setattr(asyncio, "set_event_loop", lambda loop: None) def mockrun(task): future = asyncio.run_coroutine_threadsafe(task, loop=current_loop) return future.result(1) loopmock.run_until_complete.side_effect = mockrun thread = EventLoopThread() thread_complete = await thread.start() await thread_complete assert loopmock.run_until_complete.call_count == 1 assert loopmock.run_forever.call_count == 1 assert loopmock.close.call_count == 1