public void TestBaseInvalidateObject()
        {
            try
            {
                pool = MakeEmptyPool(3);
            }
            catch (NotSupportedException)
            {
                return; // skip this test if unsupported
            }
            Object keya = MakeKey(0);

            Assert.AreEqual(0, pool.KeyedActiveCount(keya));
            Assert.AreEqual(0, pool.KeyedIdleCount(keya));
            Object obj0 = pool.BorrowObject(keya);
            Object obj1 = pool.BorrowObject(keya);

            Assert.AreEqual(2, pool.KeyedActiveCount(keya));
            Assert.AreEqual(0, pool.KeyedIdleCount(keya));
            pool.InvalidateObject(keya, obj0);
            Assert.AreEqual(1, pool.KeyedActiveCount(keya));
            Assert.AreEqual(0, pool.KeyedIdleCount(keya));
            pool.InvalidateObject(keya, obj1);
            Assert.AreEqual(0, pool.KeyedActiveCount(keya));
            Assert.AreEqual(0, pool.KeyedIdleCount(keya));
        }
        public void TestKPOFInvalidateObjectUsages()
        {
            FailingKeyedPoolableObjectFactory factory = new FailingKeyedPoolableObjectFactory();
            KeyedObjectPool <Object, Object>  pool;

            try
            {
                pool = MakeEmptyPool(factory);
            }
            catch (NotSupportedException)
            {
                return; // test not supported
            }
            List <MethodCall> expectedMethods = new ArrayList <MethodCall>();
            Object            obj;

            // Test correct behavior code paths

            obj = pool.BorrowObject(KEY);
            Clear(factory, expectedMethods);

            // invalidated object should be destroyed
            pool.InvalidateObject(KEY, obj);
            expectedMethods.Add(new MethodCall("destroyObject", KEY, obj));
            Assert.AreEqual(expectedMethods, factory.MethodCalls);

            // Test exception handling of InvalidateObject
            Reset(pool, factory, expectedMethods);
            obj = pool.BorrowObject(KEY);
            Clear(factory, expectedMethods);
            factory.DestroyObjectFail = true;
            try
            {
                pool.InvalidateObject(KEY, obj);
                Assert.Fail("Expecting destroy exception to propagate");
            }
            catch (MethodAccessException)
            {
                // Expected
            }
            Thread.Sleep(250);
            TestObjectPool.RemoveDestroyObjectCall(factory.MethodCalls);
            Assert.AreEqual(expectedMethods, factory.MethodCalls);
        }
        public void TestClosedPoolBehavior()
        {
            KeyedObjectPool <Object, Object> pool;

            try
            {
                pool = MakeEmptyPool(new InternalKeyedPoolableObjectFactory());
            }
            catch (NotSupportedException)
            {
                return; // test not supported
            }

            Object o1 = pool.BorrowObject(KEY);
            Object o2 = pool.BorrowObject(KEY);

            pool.Close();

            try
            {
                pool.AddObject(KEY);
                Assert.Fail("A Closed pool must throw an IllegalStateException when AddObject is called.");
            }
            catch (IllegalStateException)
            {
                // expected
            }

            try
            {
                pool.BorrowObject(KEY);
                Assert.Fail("A Closed pool must throw an IllegalStateException when BorrowObject is called.");
            }
            catch (IllegalStateException)
            {
                // expected
            }

            // The following should not throw exceptions just because the pool is Closed.
            Assert.AreEqual(0, pool.KeyedIdleCount(KEY), "A Closed pool shouldn't have any idle objects.");
            Assert.AreEqual(0, pool.IdleCount, "A Closed pool shouldn't have any idle objects.");
            int count = pool.ActiveCount;

            count = pool.KeyedActiveCount(KEY);
            count++;
            pool.ReturnObject(KEY, o1);
            Assert.AreEqual(0, pool.KeyedIdleCount(KEY), "ReturnObject should not add items back into the idle object pool for a Closed pool.");
            Assert.AreEqual(0, pool.IdleCount, "ReturnObject should not add items back into the idle object pool for a Closed pool.");
            pool.InvalidateObject(KEY, o2);
            pool.Clear(KEY);
            pool.Clear();
            pool.Close();
        }