Пример #1
0
def test_object_pool_count():
    def count(pool):
        counts = (pool.count(), pool.count_free(), pool.count_busy())
        return 'total=%d free=%d busy=%d' % counts

    pool = lets.ObjectPool(2, object)
    assert count(pool) == 'total=0 free=0 busy=0'

    a = pool.get(block=False)
    assert count(pool) == 'total=1 free=0 busy=1'

    b = pool.get(block=False)
    assert count(pool) == 'total=2 free=0 busy=2'

    with pytest.raises(gevent.Timeout):
        pool.get(block=False)
    assert count(pool) == 'total=2 free=0 busy=2'

    pool.release(a)
    assert count(pool) == 'total=2 free=1 busy=1'

    pool.release(a)  # again
    assert count(pool) == 'total=2 free=1 busy=1'

    pool.release(b)
    assert count(pool) == 'total=2 free=2 busy=0'

    pool.discard(a)
    assert count(pool) == 'total=1 free=1 busy=0'

    b2 = pool.get(block=False)
    assert b2 is b
    assert count(pool) == 'total=1 free=0 busy=1'

    pool.discard(b2)
    assert count(pool) == 'total=0 free=0 busy=0'

    sink_pool = lets.ObjectPool(1, object, discard_later=0.1)
    assert count(sink_pool) == 'total=0 free=0 busy=0'

    c = sink_pool.get(block=False)
    assert count(sink_pool) == 'total=1 free=0 busy=1'

    sink_pool.release(c)
    assert count(sink_pool) == 'total=1 free=1 busy=0'

    gevent.sleep(0.2)
    assert count(sink_pool) == 'total=0 free=0 busy=0'
Пример #2
0
def test_object_pool_discard_immediately():
    pool = lets.ObjectPool(None, object, discard_later=0)
    assert pool.count() == 0
    x = pool.get()
    assert pool.count() == 1
    pool.release(x)
    assert pool.count() == 0
Пример #3
0
def test_object_pool_clear():
    events = []
    pool = lets.ObjectPool(2, lambda: events.pop(), lambda e: e.set())
    # clear all
    _events = [Event(), Event()]
    events.extend(_events)
    with pool.reserve():
        with pool.reserve():
            pass
    assert pool.count() == 2
    assert [e.is_set() for e in _events] == [False, False]
    pool.clear()
    assert pool.count() == 0
    assert [e.is_set() for e in _events] == [True, True]
    # clear only available
    _events = [Event(), Event()]
    events.extend(_events)
    with pool.reserve():
        with pool.reserve():
            pass
        assert pool.count() == 2
        assert [e.is_set() for e in _events] == [False, False]
        pool.clear()
        assert pool.count() == 1
        assert [e.is_set() for e in _events] == [True, False]
        pool.clear()
        assert [e.is_set() for e in _events] == [True, False]
    pool.clear()
    assert pool.count() == 0
    assert [e.is_set() for e in _events] == [True, True]
Пример #4
0
def test_object_pool_context():
    pool = lets.ObjectPool(1, object)
    assert pool.available()
    with pool.reserve() as o:
        assert type(o) is object
        assert not pool.available()
    assert pool.available()
Пример #5
0
def test_object_pool():
    # getting object blocks
    pool = lets.ObjectPool(2, object)
    assert pool.available()
    assert pool.count() == 0
    o1 = pool.get()
    assert pool.available()
    assert pool.count() == 1
    o2 = pool.get()
    assert not pool.available()
    with pytest.raises(gevent.Timeout):
        pool.get(timeout=0.1)
    assert o1 is not o2
    assert pool.count() == 2
    # release and get again
    pool.release(o1)
    assert pool.available()
    o3 = pool.get()
    assert not pool.available()
    assert o1 is o3
    assert pool.count() == 2
    # discard
    pool.discard(o2)
    o4 = pool.get()
    assert not pool.available()
    assert o2 is not o4
    pool.discard(o4)
    assert pool.available()
Пример #6
0
def test_object_pool_wait_available():
    pool = lets.ObjectPool(1, object)
    o = pool.get()
    waiting_avaiable = gevent.spawn(pool.wait_available)
    waiting_avaiable.join(0.1)
    assert not waiting_avaiable.ready()
    pool.release(o)
    waiting_avaiable.join(0.1)
    assert waiting_avaiable.ready()
Пример #7
0
def test_object_pool_with_slow_behaviors():
    def slow():
        gevent.sleep(0.1)
        return object()
    pool = lets.ObjectPool(2, slow)
    def consume_obj_from_pool():
        with pool.reserve():
            gevent.sleep(0.1)
    gevent.joinall([gevent.spawn(consume_obj_from_pool) for x in range(10)])
    assert pool.count() == 2
Пример #8
0
def test_object_pool_deadlock():
    zero_div = lambda: 0 / 0
    pool = lets.ObjectPool(1, zero_div)

    with pytest.raises(ZeroDivisionError):
        pool.get()

    with pytest.raises(ZeroDivisionError):
        with gevent.Timeout(1, AssertionError('deadlock detected')):
            pool.get()
Пример #9
0
def test_object_pool_as_just_factory():
    objects = set()

    def factory():
        obj = object()
        objects.add(obj)
        return obj

    def destroy(obj):
        objects.remove(obj)

    # Actually, ObjectPool with (size=None, discard_later=0) is not useful as
    # a pool.  get() always succeeds, release() always destroys the object.
    # The pool just looks like an object factory.
    pool = lets.ObjectPool(None, factory, destroy, discard_later=0)

    with pool.reserve() as a:
        assert a in objects

        with pool.reserve() as b:
            assert a in objects
            assert b in objects
            assert a is not b

            with pool.reserve() as c:
                assert a in objects
                assert b in objects
                assert c in objects
                assert a is not b
                assert a is not c
                assert b is not c

            assert a in objects
            assert b in objects
            assert c not in objects

        assert a in objects
        assert b not in objects
        assert c not in objects

    assert a not in objects
    assert b not in objects
    assert c not in objects
Пример #10
0
def test_object_pool_rotation():
    counter = [0]
    def f():
        counter[0] += 1
        return counter[0]
    pool = lets.ObjectPool(3, f)
    assert pool.get() == 1
    assert pool.get() == 2
    assert pool.get() == 3
    pool.release(1)
    pool.release(2)
    pool.release(3)
    assert pool.get() == 1
    pool.discard(2)
    assert pool.get() == 3
    assert pool.get() == 4
    pool.discard(1)
    pool.release(1)
    assert pool.get() == 5
    assert not pool.available()
Пример #11
0
def test_object_pool_discard_later():
    pool = lets.ObjectPool(1, object, discard_later=0.1)

    with pool.reserve() as a:
        pass
    with pool.reserve() as b:
        pass
    assert a is b

    assert pool.count() == 1
    gevent.sleep(0.2)
    assert pool.count() == 0

    with pool.reserve() as c:
        pass
    assert a is not c

    gevent.sleep(0.05)  # try to discard soon
    with pool.reserve() as d:
        gevent.sleep(0.2)  # but busy
    assert c is d
Пример #12
0
def test_object_pool_discard_later_cancel_when_get(count_greenlets):
    def slow_destroy(obj):
        gevent.sleep(1)

    pool = lets.ObjectPool(1, object, slow_destroy, discard_later=0.1)

    assert count_greenlets() == 0

    with pool.reserve() as a:
        pass

    # reserve discard() in 0.1 sec
    assert count_greenlets() == 1

    with pool.reserve() as b:
        # reserved discard() is canceled
        assert count_greenlets() == 0
        assert a is b

    # reserve discard() in 0.1 sec again
    assert count_greenlets() == 1
Пример #13
0
def test_object_pool_zero_size():
    objects = set()

    def factory():
        obj = object()
        objects.add(obj)
        return obj

    def destroy(obj):
        objects.remove(obj)

    pool = lets.ObjectPool(None, factory, destroy, discard_later=0)

    with pool.reserve() as a:
        assert a in objects

        with pool.reserve() as b:
            assert a in objects
            assert b in objects
            assert a is not b

            with pool.reserve() as c:
                assert a in objects
                assert b in objects
                assert c in objects
                assert a is not b
                assert a is not c
                assert b is not c

            assert a in objects
            assert b in objects
            assert c not in objects

        assert a in objects
        assert b not in objects
        assert c not in objects

    assert a not in objects
    assert b not in objects
    assert c not in objects
Пример #14
0
def test_object_pool_unlimited():
    # getting object blocks
    pool = lets.ObjectPool(None, object)
    assert pool.available()
    o1 = pool.get()
    assert pool.available()
    o2 = pool.get()
    assert pool.available()
    assert o1 is not o2
    assert pool.count() == 2
    # release and get again
    pool.release(o1)
    o3 = pool.get()
    assert o1 is o3
    o4 = pool.get()
    assert o4 is not o1
    assert o4 is not o2
    assert pool.count() == 3
    # discard
    pool.discard(o2)
    o5 = pool.get()
    assert o2 is not o5
Пример #15
0
def test_object_pool_discard_later_with_slow_destroy():
    destroy_started = Event()
    destroy_ended = Event()

    def slow_destroy(obj):
        destroy_started.set()
        gevent.sleep(10)
        destroy_ended.set()

    pool = lets.ObjectPool(1, object, slow_destroy, discard_later=0.1)

    with pool.reserve() as a:
        pass

    destroy_started.wait()
    assert destroy_started.is_set()
    with pool.reserve() as b:
        pass
    # 'a' is still being destroyed.
    assert not destroy_ended.is_set()

    # 'b' should not be destroying 'a'.
    assert a is not b
Пример #16
0
def test_object_pool_discard_later_with_destroy():
    objects = set()

    def factory():
        obj = object()
        objects.add(obj)
        return obj

    def destroy(obj):
        objects.remove(obj)

    pool = lets.ObjectPool(1, factory, destroy, discard_later=0.1)

    with pool.reserve() as a:
        pass
    with pool.reserve() as b:
        pass
    assert a is b
    assert a in objects

    assert pool.count() == 1
    gevent.sleep(0.2)
    assert pool.count() == 0
    assert a not in objects

    with pool.reserve() as c:
        pass
    assert a is not c
    assert a not in objects
    assert c in objects

    gevent.sleep(0.05)  # try to discard soon
    with pool.reserve() as d:
        gevent.sleep(0.2)  # but busy
    assert c is d
    assert c in objects
    assert len(objects) == 1