Ejemplo n.º 1
0
def test_minmax_size() -> None:
    """Check that resources are destroyed when the pool overflows.

    Given:
        - a resource pool initialized with a min and a max poolsize and a dealloc function
    When:
        - more resources than the max poolsize are acquired
        - and the resources are all put back into the pool
    Then:
        - the surplus resources will be reset using the dealloc function
    """
    pool = ResourcePool(alloc=R, dealloc=R.close, minsize=1, maxsize=2)
    a, b, c = pool.pop(), pool.pop(), pool.pop()
    pool.push(a)
    pool.push(b)
    pool.push(c)

    sleep(1)  # wait for pool's gc thread

    assert len(R.deallocated) == 2
    assert a in R.deallocated
    assert not a.alive
    assert b in R.deallocated
    assert not b.alive
    assert c.alive
Ejemplo n.º 2
0
def test_provide_additional_resource() -> None:
    """Resources are actually reused after returning."""
    allocate = MagicMock()
    allocate.side_effect = R.create(4)
    pool = ResourcePool(alloc=allocate)

    resources = [pool.pop() for _ in range(3)]

    R.set(100)
    pool.push(R())

    resources.append(pool.pop())
    resources.append(pool.pop())

    allocate.assert_has_calls([call(), call(), call(), call()])
    assert resources == [0, 1, 2, 100, 3]
Ejemplo n.º 3
0
def test_no_resources() -> None:
    """Test exception raised when there are no resources available.

    Given:
        - a default-initialized resource pool
        - there are no resources currently available in the pool
        - and the pool has no way of creating a new
          resource (i. e., `alloc` was not given on construction)
    When:
        - client code attempts to get a resurce without giving
          the `timeout` argument
    Then:
        - an exception of type `ResourcePoolEmpty` will be raised
    """
    pool = ResourcePool()

    with pytest.raises(ResourcePoolEmpty):
        pool.pop()
Ejemplo n.º 4
0
def test_maxage_minsize() -> None:
    """Test maxage parameter with minimum size."""
    size = 5
    pool = ResourcePool(alloc=now, maxage=1, minsize=1)

    resources = [pool.pop() for _ in range(size)]
    assert len(pool) == 0

    for r in resources:
        sleep(0.1)
        pool.push(r)

    assert len(pool) == size
    sleep(2)
    assert len(pool) == 1
    expected = max(resources)
    actual = pool.pop()
    assert actual == expected
Ejemplo n.º 5
0
def test_max_size_no_overflow() -> None:
    """Check that resources are not destroyed unless the pool overflows.

    Given:
        - a resource pool initialized with a max poolsize and a dealloc function
    When:
        - the maxsize amount of resources are allocated
        - and the resources are all put back into the pool
    Then:
        - no resources will be reset using the dealloc function
    """
    pool = ResourcePool(alloc=R, dealloc=R.close, minsize=0, maxsize=2)
    a, b = pool.pop(), pool.pop()
    pool.push(a)
    pool.push(b)

    sleep(1)  # wait for pool's gc thread
    assert len(R.deallocated) == 0
    assert a.alive
    assert b.alive
Ejemplo n.º 6
0
def test_maxage() -> None:
    """Test maxage parameter."""
    size = 5
    pool = ResourcePool(alloc=now, maxage=1)

    resources = [pool.pop() for _ in range(size)]
    for r in resources:
        pool.push(r)

    assert len(pool) == size
    sleep(1.1)
    assert len(pool) == 0
Ejemplo n.º 7
0
def test_no_resources_with_timeout() -> None:
    """Test exception raised with a timeout when there are no resources available.

    Given:
        - a default-initialized resource pool
        - there are no resources currently available in the pool
        - and the pool has no way of creating a new
          resource (i. e., `alloc` was not given on construction)
    When:
        - client code attempts to get a resurce with a timeout
    Then:
        - an exception of type `ResourcePoolEmpty` will be raised
        - the exception will be raised after the timeout period
    """
    pool = ResourcePool()
    timeout = 1

    start = now()
    with pytest.raises(ResourcePoolEmpty):
        pool.pop(timeout=timeout)

    duration = now() - start
    assert duration == pytest.approx(timeout, abs=1e-2)
Ejemplo n.º 8
0
def test_call_allocator() -> None:
    """Allocator is called without arguments.

    Given:
        - a resource pool with an `alloc` function, enabling
          creation of new resources
    When:
        - client code attempts to get a resurce
    Then:
        - the allocation method had been called
    """
    pool = ResourcePool(alloc=R)

    resource = pool.pop()

    assert resource == 0
Ejemplo n.º 9
0
def test_reuse() -> None:
    """Resources are actually reused after returning."""
    allocate = MagicMock()
    allocate.side_effect = [1, 2, 3, 4]
    pool = ResourcePool(alloc=allocate)

    resources = []
    for _ in range(3):
        with pool() as r:
            resources.append(r)

    pool.push(100)

    resources.append(pool.pop())
    for _ in range(2):
        with pool() as r:
            resources.append(r)

    allocate.assert_called_once()
    assert resources == [1, 1, 1, 100, 1, 1]