Пример #1
0
def test_reader_recursion(loop):

    rwlock = RWLock(loop=loop)
    N = 5
    locked = []
    nlocked = []

    @asyncio.coroutine
    def f():
        yield from rwlock.reader_lock.acquire()
        try:
            yield from rwlock.reader_lock.acquire()
            try:
                locked.append(1)
                yield from _wait(loop=loop)
                nlocked.append(len(locked))
                yield from _wait(loop=loop)
                locked.pop(-1)
            finally:
                rwlock.reader_lock.release()
        finally:
            rwlock.reader_lock.release()

    yield from Bunch(f, N, loop=loop).wait_for_finished()
    assert max(nlocked) > 1
Пример #2
0
async def test_writer_success_with_statement(loop):
    # Verify that a writer can get access
    rwlock = RWLock()
    N = 5
    reads = 0
    writes = 0

    async def r():
        # read until we achive write successes
        nonlocal reads, writes
        while writes < 2:
            # print("current pre-reads", reads)
            async with rwlock.reader_lock:
                reads += 1
                # print("current reads", reads)

    async def w():
        nonlocal reads, writes
        while reads == 0:
            await _wait()

        for _ in range(2):
            await _wait()

            # print("current pre-writes", reads)
            async with rwlock.writer_lock:
                writes += 1

    b1 = Bunch(r, N)
    b2 = Bunch(w, 1)

    await b1.wait_for_finished()
    await b2.wait_for_finished()
    assert writes == 2
Пример #3
0
def test_get_write_then_read_and_write_again(loop):
    rwlock = RWLock(loop=loop)
    rl = rwlock.reader
    wl = rwlock.writer

    f = create_future(loop)
    writes = []

    @asyncio.coroutine
    def get_write_lock():
        yield from f
        with should_fail(.1, loop):
            with (yield from wl):
                assert wl.locked
                writes.append('should not be here')

    ensure_future(get_write_lock(), loop=loop)

    with (yield from wl):
        assert wl.locked

        with (yield from rl):
            f.set_result(None)
            yield from asyncio.sleep(0.12, loop=loop)
            # second task can not append to writes
            assert writes == []
            assert rl.locked
Пример #4
0
async def test_writers_deadlock(loop):
    rwlock = RWLock()
    rl = rwlock.reader
    wl = rwlock.writer

    # Scenario:
    # - task A (this) acquires read lock
    # - task B,C wait for write lock
    #
    # A releases the lock and, in the same loop interation,
    # task B gets cancelled (eg: by timeout);
    # B gets cancelled without waking up next waiter -- deadlock;
    #
    # See asyncio.Lock deadlock issue:
    #   https://github.com/python/cpython/pull/1031
    async def coro():
        async with wl:
            assert wl.locked
            await asyncio.sleep(0.2, loop)

    async with rl:
        assert rl.locked
        task_b = ensure_future(coro())
        task_c = ensure_future(coro())
        await asyncio.sleep(0.1, loop)
    # cancel lock waiter right after release
    task_b.cancel()
    assert not rl.locked

    # wait task_c to complete
    await asyncio.sleep(0.3, loop)
    assert task_c.done()
    assert not rl.locked
    assert not wl.locked
Пример #5
0
async def test_get_write_then_read_and_write_again(loop):
    rwlock = RWLock()
    rl = rwlock.reader
    wl = rwlock.writer

    f = loop.create_future()
    writes = []

    async def get_write_lock():
        await f
        with should_fail(0.1, loop):
            async with wl:
                assert wl.locked
                writes.append('should not be here')

    ensure_future(get_write_lock())

    async with wl:
        assert wl.locked

        async with rl:
            f.set_result(None)
            await asyncio.sleep(0.12)
            # second task can not append to writes
            assert writes == []
            assert rl.locked
Пример #6
0
async def test_get_write_then_read(loop):
    rwlock = RWLock()

    rl = rwlock.reader
    wl = rwlock.writer
    async with wl:
        assert wl.locked
        assert not rl.locked

        async with rl:
            assert wl.locked
            assert rl.locked
Пример #7
0
def test_get_write_then_read(loop):
    rwlock = RWLock(loop=loop)

    rl = rwlock.reader
    wl = rwlock.writer
    with (yield from wl):
        assert wl.locked
        assert not rl.locked

        with (yield from rl):
            assert wl.locked
            assert rl.locked
Пример #8
0
async def test_readers_writers(loop, fast_track):
    rwlock = RWLock(fast=fast_track)
    N = 5
    rlocked = []
    wlocked = []
    nlocked = []

    async def r():
        await rwlock.reader_lock.acquire()
        try:
            rlocked.append(1)
            await _wait()
            nlocked.append((len(rlocked), len(wlocked)))
            await _wait()
            rlocked.pop(-1)
        finally:
            rwlock.reader_lock.release()

    async def w():
        await rwlock.writer_lock.acquire()
        try:
            wlocked.append(1)
            await _wait()
            nlocked.append((len(rlocked), len(wlocked)))
            await _wait()
            wlocked.pop(-1)
        finally:
            rwlock.writer_lock.release()

    b1 = Bunch(r, N)
    b2 = Bunch(w, N)

    await asyncio.sleep(0.0001)

    await b1.wait_for_finished()
    await b2.wait_for_finished()

    (
        r,
        w,
    ) = zip(*nlocked)

    assert max(r) > 1
    assert max(w) == 1

    for r, w in nlocked:
        if w:
            assert r == 0
        if r:
            assert w == 0
Пример #9
0
def test_readers_writers(loop):
    rwlock = RWLock(loop=loop)
    N = 5
    rlocked = []
    wlocked = []
    nlocked = []

    @asyncio.coroutine
    def r():
        yield from rwlock.reader_lock.acquire()
        try:
            rlocked.append(1)
            yield from _wait(loop=loop)
            nlocked.append((len(rlocked), len(wlocked)))
            yield from _wait(loop=loop)
            rlocked.pop(-1)
        finally:
            rwlock.reader_lock.release()

    @asyncio.coroutine
    def w():
        yield from rwlock.writer_lock.acquire()
        try:
            wlocked.append(1)
            yield from _wait(loop=loop)
            nlocked.append((len(rlocked), len(wlocked)))
            yield from _wait(loop=loop)
            wlocked.pop(-1)
        finally:
            rwlock.writer_lock.release()

    b1 = Bunch(r, N, loop=loop)
    b2 = Bunch(w, N, loop=loop)

    yield from asyncio.sleep(0.0001, loop=loop)

    yield from b1.wait_for_finished()
    yield from b2.wait_for_finished()

    r, w, = zip(*nlocked)

    assert max(r) > 1
    assert max(w) == 1

    for r, w in nlocked:
        if w:
            assert r == 0
        if r:
            assert w == 0
Пример #10
0
def test_repr(loop):
    rwlock = RWLock(loop=loop)
    assert 'RWLock' in rwlock.__repr__()
    assert 'WriterLock: [unlocked' in rwlock.__repr__()
    assert 'ReaderLock: [unlocked' in rwlock.__repr__()

    # reader lock __repr__
    yield from rwlock.reader_lock.acquire()
    assert 'ReaderLock: [locked]' in rwlock.__repr__()
    rwlock.reader_lock.release()
    assert 'ReaderLock: [unlocked]' in rwlock.__repr__()

    # writer lock __repr__
    yield from rwlock.writer_lock.acquire()
    assert 'WriterLock: [locked]' in rwlock.__repr__()
    rwlock.writer_lock.release()
    assert 'WriterLock: [unlocked]' in rwlock.__repr__()
Пример #11
0
async def test_repr(loop):
    rwlock = RWLock()
    assert 'RWLock' in rwlock.__repr__()
    assert 'WriterLock: [unlocked' in rwlock.__repr__()
    assert 'ReaderLock: [unlocked' in rwlock.__repr__()

    # reader lock __repr__
    await rwlock.reader_lock.acquire()
    assert 'ReaderLock: [locked]' in rwlock.__repr__()
    rwlock.reader_lock.release()
    assert 'ReaderLock: [unlocked]' in rwlock.__repr__()

    # writer lock __repr__
    await rwlock.writer_lock.acquire()
    assert 'WriterLock: [locked]' in rwlock.__repr__()
    rwlock.writer_lock.release()
    assert 'WriterLock: [unlocked]' in rwlock.__repr__()
Пример #12
0
async def test_writer_recursion_fail(loop):
    rwlock = RWLock()
    N = 5
    locked = []

    async def f():
        await rwlock.reader_lock.acquire()
        try:
            with pytest.raises(RuntimeError):
                await rwlock.writer_lock.acquire()
            locked.append(1)
        finally:
            rwlock.reader_lock.release()

    await Bunch(f, N).wait_for_finished()
    assert len(locked) == N
Пример #13
0
def test_writer_recursion_fail(loop):
    rwlock = RWLock(loop=loop)
    N = 5
    locked = []

    @asyncio.coroutine
    def f():
        yield from rwlock.reader_lock.acquire()
        try:
            with pytest.raises(RuntimeError):
                yield from rwlock.writer_lock.acquire()
            locked.append(1)
        finally:
            rwlock.reader_lock.release()

    yield from Bunch(f, N, loop=loop).wait_for_finished()
    assert len(locked) == N
Пример #14
0
async def test_canceled_inside_acquire(loop):
    rwlock = RWLock()
    rl = rwlock.reader

    async def coro(lock):
        async with lock:
            pass

    task = ensure_future(coro(rl))
    await asyncio.sleep(0)
    task.cancel()

    try:
        await task
    except asyncio.CancelledError:
        pass

    assert not rl.locked
Пример #15
0
def test_writer_success_fast(loop):
    # Verify that a writer can get access
    rwlock = RWLock(loop=loop, fast=True)
    N = 5
    reads = 0
    writes = 0

    @asyncio.coroutine
    def r():
        # read until we achive write successes
        nonlocal reads, writes
        while writes < 2:
            # print("current pre-reads", reads)
            yield from rwlock.reader_lock.acquire()
            try:
                reads += 1
                # print("current reads", reads)
                yield from asyncio.sleep(0, loop=loop)
            finally:
                rwlock.reader_lock.release()

    @asyncio.coroutine
    def w():
        nonlocal reads, writes
        while reads == 0:
            yield from _wait(loop=loop)

        for i in range(2):
            yield from _wait(loop=loop)

            # print("current pre-writes", reads)
            yield from rwlock.writer_lock.acquire()
            try:
                writes += 1
                # print("current writes", reads)
            finally:
                rwlock.writer_lock.release()

    b1 = Bunch(r, N, loop=loop)
    b2 = Bunch(w, 1, loop=loop)

    yield from b1.wait_for_finished()
    yield from b2.wait_for_finished()
    assert writes == 2
Пример #16
0
async def test_repr(loop):
    rwlock = RWLock(loop=loop)
    assert 'RWLock' in rwlock.__repr__()
    assert 'WriterLock: [unlocked' in rwlock.__repr__()
    assert 'ReaderLock: [unlocked' in rwlock.__repr__()

    # reader lock __repr__
    await rwlock.reader_lock.acquire()
    assert 'ReaderLock: [locked]' in rwlock.__repr__()
    rwlock.reader_lock.release()
    assert 'ReaderLock: [unlocked]' in rwlock.__repr__()

    # writer lock __repr__
    await rwlock.writer_lock.acquire()
    assert 'WriterLock: [locked]' in rwlock.__repr__()
    rwlock.writer_lock.release()
    assert 'WriterLock: [unlocked]' in rwlock.__repr__()
Пример #17
0
async def test_write_read_lock_multiple_tasks(loop, fast_track):
    rwlock = RWLock(fast=fast_track)
    rl = rwlock.reader
    wl = rwlock.writer

    async def coro():
        async with rl:
            assert not wl.locked
            assert rl.locked
            await asyncio.sleep(0.2, loop)

    async with wl:
        assert wl.locked
        assert not rl.locked
        task = asyncio.Task(coro())
        await asyncio.sleep(0.1, loop)
    await task
    assert not rl.locked
    assert not wl.locked
Пример #18
0
async def test_many_readers(loop, fast_track):
    rwlock = RWLock(fast=fast_track)
    N = 5
    locked = []
    nlocked = []

    async def f():
        await rwlock.reader_lock.acquire()
        try:
            locked.append(1)
            await _wait()
            nlocked.append(len(locked))
            await _wait()
            locked.pop(-1)
        finally:
            rwlock.reader_lock.release()

    await Bunch(f, N).wait_for_finished()
    assert max(nlocked) > 1
Пример #19
0
async def test_writer_success_fast(loop):
    # Verify that a writer can get access
    rwlock = RWLock(fast=True)
    N = 5
    reads = 0
    writes = 0

    async def r():
        # read until we achive write successes
        nonlocal reads, writes
        while writes < 2:
            # print("current pre-reads", reads)
            await rwlock.reader_lock.acquire()
            try:
                reads += 1
                # print("current reads", reads)
                await asyncio.sleep(0)
            finally:
                rwlock.reader_lock.release()

    async def w():
        nonlocal reads, writes
        while reads == 0:
            await _wait()

        for _ in range(2):
            await _wait()

            # print("current pre-writes", reads)
            await rwlock.writer_lock.acquire()
            try:
                writes += 1
                # print("current writes", reads)
            finally:
                rwlock.writer_lock.release()

    b1 = Bunch(r, N)
    b2 = Bunch(w, 1)

    await b1.wait_for_finished()
    await b2.wait_for_finished()
    assert writes == 2
Пример #20
0
def test_write_read_lock_multiple_tasks(loop):
    rwlock = RWLock(loop=loop)
    rl = rwlock.reader
    wl = rwlock.writer

    @asyncio.coroutine
    def coro():
        with (yield from rl):
            assert not wl.locked
            assert rl.locked
            yield from asyncio.sleep(0.2, loop)

    with (yield from wl):
        assert wl.locked
        assert not rl.locked
        task = asyncio.Task(coro(), loop=loop)
        yield from asyncio.sleep(0.1, loop)
    yield from task
    assert not rl.locked
    assert not wl.locked
Пример #21
0
async def test_read_upgrade_write_release(loop):
    rwlock = RWLock()
    await rwlock.writer_lock.acquire()
    await rwlock.reader_lock.acquire()
    await rwlock.reader_lock.acquire()

    await rwlock.reader_lock.acquire()
    rwlock.reader_lock.release()

    assert rwlock.writer_lock.locked

    rwlock.writer_lock.release()
    assert not rwlock.writer_lock.locked

    assert rwlock.reader.locked

    with pytest.raises(RuntimeError):
        await rwlock.writer_lock.acquire()

    rwlock.reader_lock.release()
    rwlock.reader_lock.release()
Пример #22
0
async def test_race_multiple_writers(loop):
    seq = []

    async def write_wait(lock):
        async with lock.reader:
            await asyncio.sleep(0.1)
            seq.append('READ')
        async with lock.writer:
            seq.append('START1')
            await asyncio.sleep(0.1)
            seq.append('FIN1')

    async def write(lock):
        await asyncio.sleep(0)  # PY36 seems to run tasks in the wrong order.
        async with lock.writer:
            seq.append('START2')
            await asyncio.sleep(0.1)
            seq.append('FIN2')

    lock = RWLock(fast=True)
    await asyncio.gather(write_wait(lock), write(lock))
    assert seq == ['READ', 'START2', 'FIN2', 'START1', 'FIN1']
Пример #23
0
async def test_readers_cancel(loop):
    rwlock = RWLock()
    rl = rwlock.reader
    wl = rwlock.writer

    async def coro(lock):
        async with lock:
            assert lock.locked
            await asyncio.sleep(0.2, loop)

    async with wl:
        assert wl.locked
        task_b = ensure_future(coro(rl))
        task_c = ensure_future(coro(rl))
        await asyncio.sleep(0.1, loop)

    task_b.cancel()
    assert not wl.locked

    await task_c
    assert task_c.done()
    assert not rl.locked
    assert not wl.locked
Пример #24
0
async def test_writer_then_reader_recursion(loop, fast_track):
    rwlock = RWLock(loop=loop, fast=fast_track)
    N = 5
    locked = []
    nlocked = []

    async def f():
        await rwlock.writer_lock.acquire()
        try:
            await rwlock.reader_lock.acquire()
            try:
                locked.append(1)
                await _wait(loop=loop)
                nlocked.append(len(locked))
                await _wait(loop=loop)
                locked.pop(-1)
            finally:
                rwlock.reader_lock.release()
        finally:
            rwlock.writer_lock.release()

    await Bunch(f, N, loop=loop).wait_for_finished()
    assert max(nlocked) == 1
Пример #25
0
def test_readers_cancel(loop):
    rwlock = RWLock(loop=loop)
    rl = rwlock.reader
    wl = rwlock.writer

    @asyncio.coroutine
    def coro(lock):
        with (yield from lock):
            assert lock.locked
            yield from asyncio.sleep(0.2, loop)

    with (yield from wl):
        assert wl.locked
        task_b = ensure_future(coro(rl), loop=loop)
        task_c = ensure_future(coro(rl), loop=loop)
        yield from asyncio.sleep(0.1, loop)

    task_b.cancel()
    assert not wl.locked

    yield from task_c
    assert task_c.done()
    assert not rl.locked
    assert not wl.locked
Пример #26
0
def test_writer_success_with_statement(loop):
    # Verify that a writer can get access
    rwlock = RWLock(loop=loop)
    N = 5
    reads = 0
    writes = 0

    @asyncio.coroutine
    def r():
        # read until we achive write successes
        nonlocal reads, writes
        while writes < 2:
            # print("current pre-reads", reads)
            with (yield from rwlock.reader_lock):
                reads += 1
                # print("current reads", reads)

    @asyncio.coroutine
    def w():
        nonlocal reads, writes
        while reads == 0:
            yield from _wait(loop=loop)

        for i in range(2):
            yield from _wait(loop=loop)

            # print("current pre-writes", reads)
            with (yield from rwlock.writer_lock):
                writes += 1

    b1 = Bunch(r, N, loop=loop)
    b2 = Bunch(w, 1, loop=loop)

    yield from b1.wait_for_finished()
    yield from b2.wait_for_finished()
    assert writes == 2
Пример #27
0
def test_release_unlocked(loop):
    rwlock = RWLock(loop=loop)
    with pytest.raises(RuntimeError):
        rwlock.reader_lock.release()
Пример #28
0
def test_ctor_noloop_writer(loop):
    asyncio.set_event_loop(loop)
    rwlock = RWLock().writer_lock
    assert rwlock._lock._loop is loop
Пример #29
0
def test_ctor_loop_writer(loop):
    rwlock = RWLock(loop=loop).writer_lock
    assert rwlock._lock._loop is loop
Пример #30
0
def test_ctor_loop_reader(loop):
    rwlock = RWLock(loop=loop).reader_lock
    assert rwlock._lock._loop is loop
Пример #31
0
def test_write_locked(loop):
    rwlock = RWLock(loop=loop)
    assert not rwlock.writer_lock.locked
    with (yield from rwlock.writer_lock):
        assert rwlock.writer_lock.locked