Example #1
0
 def test_get_and_put_item_without_resetter(self):
     op = ObjectPool(_x_factory)
     x = op.get()
     uuid = x.uuid
     self.assertIsInstance(x, X)
     self.assertTrue(x.is_initialized)
     self.assertEqual(op.num_available_objects, 0)
     self.assertEqual(op.num_objects, 1)
     self.assertEqual(op.max_num_objects, 4)
     x.use()
     self.assertFalse(x.is_initialized)
     op.put(x)
     self.assertEqual(op.num_available_objects, 1)
     self.assertEqual(op.num_objects, 1)
     self.assertEqual(op.max_num_objects, 4)
     y = op.get()
     self.assertEqual(uuid, y.uuid)  # y is what x was
     self.assertIsInstance(y, X)
     self.assertFalse(y.is_initialized)
     self.assertEqual(op.num_available_objects, 0)
     self.assertEqual(op.num_objects, 1)
     self.assertEqual(op.max_num_objects, 4)
Example #2
0
class TestObjectPool(unittest.TestCase):
    def setUp(self):
        self._op = ObjectPool(construct=_x_factory, reset=_x_resetter)

    def test_pool_default_initialization(self):
        op = ObjectPool(_x_factory)
        self.assertEqual(op.num_objects, 0)
        self.assertEqual(op.num_available_objects, 0)
        self.assertEqual(op.max_num_objects, 4)

    def test_pool_initialization_with_reset_and_limit(self):
        op = ObjectPool(construct=_x_factory, reset=_x_resetter, limit=10)
        self.assertEqual(op.num_objects, 0)
        self.assertEqual(op.num_available_objects, 0)
        self.assertEqual(op.max_num_objects, 10)

    def test_get_and_put_item_without_resetter(self):
        op = ObjectPool(_x_factory)
        x = op.get()
        uuid = x.uuid
        self.assertIsInstance(x, X)
        self.assertTrue(x.is_initialized)
        self.assertEqual(op.num_available_objects, 0)
        self.assertEqual(op.num_objects, 1)
        self.assertEqual(op.max_num_objects, 4)
        x.use()
        self.assertFalse(x.is_initialized)
        op.put(x)
        self.assertEqual(op.num_available_objects, 1)
        self.assertEqual(op.num_objects, 1)
        self.assertEqual(op.max_num_objects, 4)
        y = op.get()
        self.assertEqual(uuid, y.uuid)  # y is what x was
        self.assertIsInstance(y, X)
        self.assertFalse(y.is_initialized)
        self.assertEqual(op.num_available_objects, 0)
        self.assertEqual(op.num_objects, 1)
        self.assertEqual(op.max_num_objects, 4)

    def test_get_and_put_item_with_resetter(self):
        x = self._op.get()
        uuid = x.uuid
        self.assertIsInstance(x, X)
        self.assertTrue(x.is_initialized)
        self.assertEqual(self._op.num_available_objects, 0)
        self.assertEqual(self._op.num_objects, 1)
        self.assertEqual(self._op.max_num_objects, 4)
        x.use()
        self.assertFalse(x.is_initialized)
        self._op.put(x)
        self.assertEqual(self._op.num_available_objects, 1)
        self.assertEqual(self._op.num_objects, 1)
        self.assertEqual(self._op.max_num_objects, 4)
        y = self._op.get()
        self.assertEqual(uuid, y.uuid)
        self.assertIsInstance(y, X)
        self.assertTrue(y.is_initialized)
        self.assertEqual(self._op.num_available_objects, 0)
        self.assertEqual(self._op.num_objects, 1)
        self.assertEqual(self._op.max_num_objects, 4)

    def test_get_max_num_objects(self):
        objects = []
        for i in range(self._op.max_num_objects):
            x = self._op.get()
            self.assertEqual(self._op.num_objects, i + 1)
            self.assertEqual(self._op.num_available_objects, 0)
            self.assertEqual(self._op.max_num_objects, 4)
            objects.append(x)

        for i, x in enumerate(objects):
            self._op.put(x)
            self.assertEqual(self._op.num_objects, 4)
            self.assertEqual(self._op.num_available_objects, i + 1)
            self.assertEqual(self._op.max_num_objects, 4)

    def test_block_when_pool_is_empty(self):
        def work(pool, duration):
            x = pool.get()
            x.use(duration)
            pool.put(x)

        # Use threads to exhaust the pool and hold on to the resources
        # for 2 seconds each
        threads = []
        for i in range(self._op.max_num_objects):
            t = Thread(target=work, args=(self._op, 2))
            threads.append(t)
            t.start()

        # Busy wait to make sure every thread has acquired its resource
        while (self._op.num_available_objects != 0):
            continue

        # Use main thread to try to acquire a resource, and measure time
        # it has to wait (which is around 2 seconds)
        start = time.time()
        x = self._op.get()
        wait_time = time.time() - start
        self.assertGreater(wait_time, 1.5)
        self.assertLess(wait_time, 2.5)
        self._op.put(x)

        for t in threads:
            t.join()

    def test_get_object_using_context_manager(self):

        with self._op.item() as x:
            self.assertTrue(x.is_initialized)
            x.use()
            self.assertFalse(x.is_initialized)
            self.assertEqual(self._op.num_available_objects, 0)
            self.assertEqual(self._op.num_objects, 1)

        self.assertEqual(self._op.num_available_objects, 1)
        self.assertEqual(self._op.num_objects, 1)
        y = self._op.get()
        self.assertTrue(y.is_initialized)
        self._op.put(y)

    def test_work_simulation(self):
        def work(duration):
            with self._op.item() as x:
                x.use(duration)

        work_items = [uniform(0, 0.1) for i in range(100)]

        # create some contention by having more threads than resources
        tp = ThreadPool(self._op.max_num_objects + 2)

        tp.map(work, work_items)
        self.assertEqual(self._op.num_objects, 4)
        self.assertEqual(self._op.num_available_objects, 4)

        # ensure all objects are in good state

        objects = []
        for i in range(self._op.max_num_objects):
            x = self._op.get()
            self.assertTrue(x.is_initialized)
            objects.append(x)

        self.assertEqual(self._op.num_available_objects, 0)
        self.assertEqual(len(objects), self._op.max_num_objects)