async def test_task_done(self): q = self.q_class() for i in range(100): q.put_nowait(i) accumulator = 0 # Two workers get items from the queue and call task_done after each. # Join the queue and assert all items have been processed. running = True async def worker(): nonlocal accumulator while running: item = await q.get() accumulator += item q.task_done() async with asyncio.TaskGroup() as tg: tasks = [tg.create_task(worker()) for index in range(2)] await q.join() self.assertEqual(sum(range(100)), accumulator) # close running generators running = False for i in range(len(tasks)): q.put_nowait(0)
async def _test_repr_or_str(self, fn, expect_id): """Test Queue's repr or str. fn is repr or str. expect_id is True if we expect the Queue's id to appear in fn(Queue()). """ q = asyncio.Queue() self.assertTrue(fn(q).startswith('<Queue'), fn(q)) id_is_present = hex(id(q)) in fn(q) self.assertEqual(expect_id, id_is_present) # getters q = asyncio.Queue() async with asyncio.TaskGroup() as tg: # Start a task that waits to get. getter = tg.create_task(q.get()) # Let it start waiting. await asyncio.sleep(0) self.assertTrue('_getters[1]' in fn(q)) # resume q.get coroutine to finish generator q.put_nowait(0) self.assertEqual(0, await getter) # putters q = asyncio.Queue(maxsize=1) async with asyncio.TaskGroup() as tg: q.put_nowait(1) # Start a task that waits to put. putter = tg.create_task(q.put(2)) # Let it start waiting. await asyncio.sleep(0) self.assertTrue('_putters[1]' in fn(q)) # resume q.put coroutine to finish generator q.get_nowait() self.assertTrue(putter.done()) q = asyncio.Queue() q.put_nowait(1) self.assertTrue('_queue=[1]' in fn(q))
async def test_why_are_getters_waiting(self): async def consumer(queue, num_expected): for _ in range(num_expected): await queue.get() async def producer(queue, num_items): for i in range(num_items): await queue.put(i) producer_num_items = 5 q = asyncio.Queue(1) async with asyncio.TaskGroup() as tg: tg.create_task(producer(q, producer_num_items)) tg.create_task(consumer(q, producer_num_items))
async def test_why_are_putters_waiting(self): queue = asyncio.Queue(2) async def putter(item): await queue.put(item) async def getter(): await asyncio.sleep(0) num = queue.qsize() for _ in range(num): queue.get_nowait() async with asyncio.TaskGroup() as tg: tg.create_task(getter()) tg.create_task(putter(0)) tg.create_task(putter(1)) tg.create_task(putter(2)) tg.create_task(putter(3))
async def test_get_cancel_drop_many_pending_readers(self): q = asyncio.Queue() async with asyncio.TaskGroup() as tg: reader1 = tg.create_task(q.get()) reader2 = tg.create_task(q.get()) reader3 = tg.create_task(q.get()) await asyncio.sleep(0) q.put_nowait(1) q.put_nowait(2) reader1.cancel() with self.assertRaises(asyncio.CancelledError): await reader1 await reader3 # It is undefined in which order concurrent readers receive results. self.assertEqual({reader2.result(), reader3.result()}, {1, 2})
async def test_acquire_fifo_order(self): sem = asyncio.Semaphore(1) result = [] async def coro(tag): await sem.acquire() result.append(f'{tag}_1') await asyncio.sleep(0.01) sem.release() await sem.acquire() result.append(f'{tag}_2') await asyncio.sleep(0.01) sem.release() async with asyncio.TaskGroup() as tg: tg.create_task(coro('c1')) tg.create_task(coro('c2')) tg.create_task(coro('c3')) self.assertEqual(['c1_1', 'c2_1', 'c3_1', 'c1_2', 'c2_2', 'c3_2'], result)