(self)
| 817 | self.assertIs(err.exception, raised) |
| 818 | |
| 819 | async def test_cancelled_wakeup(self): |
| 820 | # Test that a task cancelled at the "same" time as it is woken |
| 821 | # up as part of a Condition.notify() does not result in a lost wakeup. |
| 822 | # This test simulates a cancel while the target task is awaiting initial |
| 823 | # wakeup on the wakeup queue. |
| 824 | condition = asyncio.Condition() |
| 825 | state = 0 |
| 826 | async def consumer(): |
| 827 | nonlocal state |
| 828 | async with condition: |
| 829 | while True: |
| 830 | await condition.wait_for(lambda: state != 0) |
| 831 | if state < 0: |
| 832 | return |
| 833 | state -= 1 |
| 834 | |
| 835 | # create two consumers |
| 836 | c = [asyncio.create_task(consumer()) for _ in range(2)] |
| 837 | # wait for them to settle |
| 838 | await asyncio.sleep(0) |
| 839 | async with condition: |
| 840 | # produce one item and wake up one |
| 841 | state += 1 |
| 842 | condition.notify(1) |
| 843 | |
| 844 | # Cancel it while it is awaiting to be run. |
| 845 | # This cancellation could come from the outside |
| 846 | c[0].cancel() |
| 847 | |
| 848 | # now wait for the item to be consumed |
| 849 | # if it doesn't means that our "notify" didn"t take hold. |
| 850 | # because it raced with a cancel() |
| 851 | try: |
| 852 | async with asyncio.timeout(0.01): |
| 853 | await condition.wait_for(lambda: state == 0) |
| 854 | except TimeoutError: |
| 855 | pass |
| 856 | self.assertEqual(state, 0) |
| 857 | |
| 858 | # clean up |
| 859 | state = -1 |
| 860 | condition.notify_all() |
| 861 | await c[1] |
| 862 | |
| 863 | async def test_cancelled_wakeup_relock(self): |
| 864 | # Test that a task cancelled at the "same" time as it is woken |
nothing calls this directly
no test coverage detected