Skip to content

Commit

Permalink
* Regression test
Browse files Browse the repository at this point in the history
  • Loading branch information
Joshuaalbert committed Jan 28, 2024
1 parent 3f01881 commit 7d4b4c6
Showing 1 changed file with 43 additions and 0 deletions.
43 changes: 43 additions & 0 deletions fair_async_rlock/tests/test_fair_async_rlock.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,3 +609,46 @@ async def task4():
# Task 4 should not deadlock. It should be able to acquire the locks
await asyncio.wait([t4], timeout=1)
assert task4_acquired.is_set()

@pytest.mark.asyncio
async def test_gh17_regression():
lock = FairAsyncRLock()

# Use events to control the order of execution
task1_aquired = asyncio.Event()
# task1_released = asyncio.Event()
task2_acquired = asyncio.Event()

async def task1():
async with lock:
# tell task 2 to acquire lock
task1_aquired.set()
# but sleep long enough to make sure task 2 waits on lock before we release this one.
await asyncio.sleep(0.1)
# task1_released.set()

async def task2():
await task1_aquired.wait()
async with lock:
task2_acquired.set()
# hold this for long enough to allow task3 to release first in a race condition
# in which task3 beats task2 to ownership and then releases only to find
# task2 has set ownership, giving a foreign lock assert scenario
await asyncio.sleep(0.2)

async def task3():
# NB: we achieve this race condition with sleep(0.1)
# awaiting task1_released does not give it the edge
await asyncio.sleep(0.1)
# await task1_released.wait()
async with lock:
# if task 3 were to get an immediate lock (beating task3 to ownership), then waiting
# for this means we don't release until just after task2
# has clobbered over our ownership.
await task2_acquired.wait()

t1 = asyncio.create_task(task1())
t2 = asyncio.create_task(task2())
t3 = asyncio.create_task(task3())

await asyncio.gather(t1, t2, t3)

0 comments on commit 7d4b4c6

Please sign in to comment.