def test_multithread(self):
        with ConnectionPool(connector,
                            DirectConnectionErrorHandler,
                            max_connection_pool_size=5,
                            connection_acquisition_timeout=10) as pool:
            address = ("127.0.0.1", 7687)
            releasing_event = Event()

            # We start 10 threads to compete connections from pool with size of 5
            threads = []
            for i in range(10):
                t = Thread(target=acquire_release_conn,
                           args=(pool, address, releasing_event))
                t.start()
                threads.append(t)

            # The pool size should be 5, all are in-use
            self.assert_pool_size(address, 5, 0, pool)
            # Now we allow thread to release connections they obtained from pool
            releasing_event.set()

            # wait for all threads to release connections back to pool
            for t in threads:
                t.join()
            # The pool size is still 5, but all are free
            self.assert_pool_size(address, 0, 5, pool)
 def test_max_conn_pool_size(self):
     with ConnectionPool(connector, DirectConnectionErrorHandler,
                         max_connection_pool_size=1, connection_acquisition_timeout=0) as pool:
         address = ("127.0.0.1", 7687)
         pool.acquire_direct(address)
         self.assertEqual(pool.in_use_connection_count(address), 1)
         with self.assertRaises(ClientError):
             pool.acquire_direct(address)
         self.assertEqual(pool.in_use_connection_count(address), 1)
 def setUp(self):
     self.pool = ConnectionPool(connector, DirectConnectionErrorHandler())
class ConnectionPoolTestCase(TestCase):
    def setUp(self):
        self.pool = ConnectionPool(connector, DirectConnectionErrorHandler())

    def tearDown(self):
        self.pool.close()

    def assert_pool_size(self,
                         address,
                         expected_active,
                         expected_inactive,
                         pool=None):
        if pool is None:
            pool = self.pool
        try:
            connections = pool.connections[address]
        except KeyError:
            assert 0 == expected_active
            assert 0 == expected_inactive
        else:
            assert len([c for c in connections if c.in_use]) == expected_active
            assert len([c for c in connections
                        if not c.in_use]) == expected_inactive

    def test_can_acquire(self):
        address = ("127.0.0.1", 7687)
        connection = self.pool.acquire_direct(address)
        assert connection.address == address
        self.assert_pool_size(address, 1, 0)

    def test_can_acquire_twice(self):
        address = ("127.0.0.1", 7687)
        connection_1 = self.pool.acquire_direct(address)
        connection_2 = self.pool.acquire_direct(address)
        assert connection_1.address == address
        assert connection_2.address == address
        assert connection_1 is not connection_2
        self.assert_pool_size(address, 2, 0)

    def test_can_acquire_two_addresses(self):
        address_1 = ("127.0.0.1", 7687)
        address_2 = ("127.0.0.1", 7474)
        connection_1 = self.pool.acquire_direct(address_1)
        connection_2 = self.pool.acquire_direct(address_2)
        assert connection_1.address == address_1
        assert connection_2.address == address_2
        self.assert_pool_size(address_1, 1, 0)
        self.assert_pool_size(address_2, 1, 0)

    def test_can_acquire_and_release(self):
        address = ("127.0.0.1", 7687)
        connection = self.pool.acquire_direct(address)
        self.assert_pool_size(address, 1, 0)
        self.pool.release(connection)
        self.assert_pool_size(address, 0, 1)

    def test_releasing_twice(self):
        address = ("127.0.0.1", 7687)
        connection = self.pool.acquire_direct(address)
        self.pool.release(connection)
        self.assert_pool_size(address, 0, 1)
        self.pool.release(connection)
        self.assert_pool_size(address, 0, 1)

    def test_cannot_acquire_after_close(self):
        with ConnectionPool(lambda a: QuickConnection(FakeSocket(a)),
                            DirectConnectionErrorHandler()) as pool:
            pool.close()
            with self.assertRaises(ServiceUnavailable):
                _ = pool.acquire_direct("X")

    def test_in_use_count(self):
        address = ("127.0.0.1", 7687)
        self.assertEqual(self.pool.in_use_connection_count(address), 0)
        connection = self.pool.acquire_direct(address)
        self.assertEqual(self.pool.in_use_connection_count(address), 1)
        self.pool.release(connection)
        self.assertEqual(self.pool.in_use_connection_count(address), 0)

    def test_max_conn_pool_size(self):
        with ConnectionPool(connector,
                            DirectConnectionErrorHandler,
                            max_connection_pool_size=1,
                            connection_acquisition_timeout=0) as pool:
            address = ("127.0.0.1", 7687)
            pool.acquire_direct(address)
            self.assertEqual(pool.in_use_connection_count(address), 1)
            with self.assertRaises(ClientError):
                pool.acquire_direct(address)
            self.assertEqual(pool.in_use_connection_count(address), 1)

    def test_multithread(self):
        with ConnectionPool(connector,
                            DirectConnectionErrorHandler,
                            max_connection_pool_size=5,
                            connection_acquisition_timeout=10) as pool:
            address = ("127.0.0.1", 7687)
            releasing_event = Event()

            # We start 10 threads to compete connections from pool with size of 5
            threads = []
            for i in range(10):
                t = Thread(target=acquire_release_conn,
                           args=(pool, address, releasing_event))
                t.start()
                threads.append(t)

            # The pool size should be 5, all are in-use
            self.assert_pool_size(address, 5, 0, pool)
            # Now we allow thread to release connections they obtained from pool
            releasing_event.set()

            # wait for all threads to release connections back to pool
            for t in threads:
                t.join()
            # The pool size is still 5, but all are free
            self.assert_pool_size(address, 0, 5, pool)
 def test_cannot_acquire_after_close(self):
     with ConnectionPool(lambda a: QuickConnection(FakeSocket(a)),
                         DirectConnectionErrorHandler()) as pool:
         pool.close()
         with self.assertRaises(ServiceUnavailable):
             _ = pool.acquire_direct("X")