From d44464dee5b38d51f6d5748257c7963d422e948b Mon Sep 17 00:00:00 2001 From: John Blum Date: Wed, 1 Apr 2015 14:25:00 -0700 Subject: [PATCH] SGF-390 - Improve unit test coverage for the PoolFactoryBean class. --- .../data/gemfire/CacheFactoryBean.java | 11 +- .../client/ClientCacheFactoryBean.java | 5 +- .../data/gemfire/client/PoolFactoryBean.java | 75 +++--- .../data/gemfire/util/ArrayUtils.java | 136 +++++----- .../data/gemfire/util/CollectionUtils.java | 47 ++++ .../data/gemfire/CacheFactoryBeanTest.java | 14 - .../data/gemfire/RegionFactoryBeanTest.java | 2 +- .../gemfire/client/PoolFactoryBeanTest.java | 246 ++++++++++++++++++ .../data/gemfire/test/support/ArrayUtils.java | 16 +- .../gemfire/test/support/CollectionUtils.java | 4 +- .../data/gemfire/util/ArrayUtilsTest.java | 129 +++++++++ .../gemfire/util/CollectionUtilsTest.java | 56 ++++ 12 files changed, 610 insertions(+), 131 deletions(-) create mode 100644 src/main/java/org/springframework/data/gemfire/util/CollectionUtils.java create mode 100644 src/test/java/org/springframework/data/gemfire/client/PoolFactoryBeanTest.java create mode 100644 src/test/java/org/springframework/data/gemfire/util/ArrayUtilsTest.java create mode 100644 src/test/java/org/springframework/data/gemfire/util/CollectionUtilsTest.java diff --git a/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java b/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java index 2018c59e..b45559c3 100644 --- a/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java @@ -19,8 +19,6 @@ package org.springframework.data.gemfire; import java.io.File; import java.io.IOException; import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Properties; @@ -38,6 +36,7 @@ import org.springframework.beans.factory.InitializingBean; import org.springframework.core.io.Resource; import org.springframework.dao.DataAccessException; import org.springframework.dao.support.PersistenceExceptionTranslator; +import org.springframework.data.gemfire.util.CollectionUtils; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -487,7 +486,7 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, /* (non-Javadoc) */ private void registerTransactionListeners(Cache cache) { - for (TransactionListener transactionListener : nullSafeCollection(transactionListeners)) { + for (TransactionListener transactionListener : CollectionUtils.nullSafeCollection(transactionListeners)) { cache.getCacheTransactionManager().addListener(transactionListener); } } @@ -501,7 +500,7 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, /* (non-Javadoc) */ private void registerJndiDataSources() { - for (JndiDataSource jndiDataSource : nullSafeCollection(jndiDataSources)) { + for (JndiDataSource jndiDataSource : CollectionUtils.nullSafeCollection(jndiDataSources)) { String typeAttributeValue = jndiDataSource.getAttributes().get("type"); JndiDataSourceType jndiDataSourceType = JndiDataSourceType.valueOfIgnoreCase(typeAttributeValue); @@ -514,10 +513,6 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, } } - protected Collection nullSafeCollection(final Collection collection) { - return (collection != null ? collection : Collections.emptyList()); - } - @Override public void destroy() throws Exception { if (close) { diff --git a/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java b/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java index 259717f7..af6d41c9 100644 --- a/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java @@ -23,6 +23,7 @@ import java.util.Properties; import org.springframework.beans.factory.BeanInitializationException; import org.springframework.data.gemfire.CacheFactoryBean; import org.springframework.data.gemfire.config.GemfireConstants; +import org.springframework.data.gemfire.util.CollectionUtils; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -180,11 +181,11 @@ public class ClientCacheFactoryBean extends CacheFactoryBean { clientCacheFactory.setPoolSubscriptionRedundancy(pool.getSubscriptionRedundancy()); clientCacheFactory.setPoolThreadLocalConnections(pool.getThreadLocalConnections()); - for (InetSocketAddress socketAddress : nullSafeCollection(pool.getLocators())) { + for (InetSocketAddress socketAddress : CollectionUtils.nullSafeCollection(pool.getLocators())) { clientCacheFactory.addPoolLocator(socketAddress.getHostName(), socketAddress.getPort()); } - for (InetSocketAddress socketAddress : nullSafeCollection(pool.getServers())) { + for (InetSocketAddress socketAddress : CollectionUtils.nullSafeCollection(pool.getServers())) { clientCacheFactory.addPoolServer(socketAddress.getHostName(), socketAddress.getPort()); } } diff --git a/src/main/java/org/springframework/data/gemfire/client/PoolFactoryBean.java b/src/main/java/org/springframework/data/gemfire/client/PoolFactoryBean.java index 2a059335..2d3db542 100644 --- a/src/main/java/org/springframework/data/gemfire/client/PoolFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/client/PoolFactoryBean.java @@ -18,7 +18,6 @@ package org.springframework.data.gemfire.client; import java.net.InetSocketAddress; import java.util.Collection; -import java.util.Collections; import java.util.Properties; import org.apache.commons.logging.Log; @@ -29,8 +28,8 @@ import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; +import org.springframework.data.gemfire.util.CollectionUtils; import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import com.gemstone.gemfire.cache.client.Pool; @@ -59,7 +58,7 @@ public class PoolFactoryBean implements FactoryBean, InitializingBean, Dis private static final Log log = LogFactory.getLog(PoolFactoryBean.class); // indicates whether the Pool has been created internally (by this FactoryBean) or not - private volatile boolean internalPool = true; + private volatile boolean springBasedPool = true; private BeanFactory beanFactory; @@ -109,7 +108,7 @@ public class PoolFactoryBean implements FactoryBean, InitializingBean, Dis public void afterPropertiesSet() throws Exception { if (!StringUtils.hasText(name)) { - Assert.hasText(beanName, "The Pool name is required!"); + Assert.hasText(beanName, "Pool 'name' is required"); name = beanName; } @@ -121,7 +120,7 @@ public class PoolFactoryBean implements FactoryBean, InitializingBean, Dis log.debug(String.format("A Pool with name '%1$s' already exists; using existing Pool.", name)); } - internalPool = false; + springBasedPool = false; pool = existingPool; } else { @@ -130,12 +129,12 @@ public class PoolFactoryBean implements FactoryBean, InitializingBean, Dis } if (CollectionUtils.isEmpty(locators) && CollectionUtils.isEmpty(servers)) { - throw new IllegalArgumentException("At least one locator or server is required!"); + throw new IllegalArgumentException("at least one GemFire Locator or Server is required"); } - internalPool = true; + springBasedPool = true; - PoolFactory poolFactory = PoolManager.createFactory(); + PoolFactory poolFactory = createPoolFactory(); poolFactory.setFreeConnectionTimeout(freeConnectionTimeout); poolFactory.setIdleTimeout(idleTimeout); @@ -156,33 +155,41 @@ public class PoolFactoryBean implements FactoryBean, InitializingBean, Dis poolFactory.setSubscriptionRedundancy(subscriptionRedundancy); poolFactory.setThreadLocalConnections(threadLocalConnections); - for (InetSocketAddress connection : nullSafeCollection(locators)) { + for (InetSocketAddress connection : CollectionUtils.nullSafeCollection(locators)) { poolFactory.addLocator(connection.getHostName(), connection.getPort()); } - for (InetSocketAddress connection : nullSafeCollection(servers)) { + for (InetSocketAddress connection : CollectionUtils.nullSafeCollection(servers)) { poolFactory.addServer(connection.getHostName(), connection.getPort()); } - // eagerly initialize ClientCache (if needed) - if (InternalDistributedSystem.getAnyInstance() == null) { - doDistributedSystemConnect(resolveGemfireProperties()); - } + // eagerly initialize the GemFire DistributedSystem (if needed) + resolveDistributedSystem(); pool = poolFactory.create(name); } } - public void destroy() throws Exception { - if (internalPool && pool != null) { - if (!pool.isDestroyed()) { - pool.releaseThreadLocalConnection(); - pool.destroy(keepAlive); + /* (non-Javadoc) */ + protected PoolFactory createPoolFactory() { + return PoolManager.createFactory(); + } - if (log.isDebugEnabled()) { - log.debug(String.format("Destroyed Pool '%1$s'.", name)); - } - } + /* (non-Javadoc) */ + void resolveDistributedSystem() { + if (InternalDistributedSystem.getAnyInstance() == null) { + doDistributedSystemConnect(resolveGemfireProperties()); + } + } + + /* (non-Javadoc) */ + Properties resolveGemfireProperties() { + try { + ClientCacheFactoryBean clientCacheFactoryBean = beanFactory.getBean(ClientCacheFactoryBean.class); + return clientCacheFactoryBean.getProperties(); + } + catch (Exception ignore) { + return null; } } @@ -195,26 +202,22 @@ public class PoolFactoryBean implements FactoryBean, InitializingBean, Dis * @see com.gemstone.gemfire.distributed.DistributedSystem#connect(java.util.Properties) */ @SuppressWarnings("deprecation") - static void doDistributedSystemConnect(Properties properties) { + void doDistributedSystemConnect(Properties properties) { Properties gemfireProperties = (properties != null ? (Properties) properties.clone() : new Properties()); gemfireProperties.setProperty("locators", ""); gemfireProperties.setProperty("mcast-port", "0"); DistributedSystem.connect(gemfireProperties); } - /* (non-Javadoc) */ - private Collection nullSafeCollection(final Collection list) { - return (list != null ? list : Collections.emptyList()); - } + public void destroy() throws Exception { + if (springBasedPool && pool != null && !pool.isDestroyed()) { + pool.releaseThreadLocalConnection(); + pool.destroy(keepAlive); + pool = null; - /* (non-Javadoc) */ - private Properties resolveGemfireProperties() { - try { - ClientCacheFactoryBean clientCacheFactoryBean = beanFactory.getBean(ClientCacheFactoryBean.class); - return clientCacheFactoryBean.getProperties(); - } - catch (Exception ignore) { - return null; + if (log.isDebugEnabled()) { + log.debug(String.format("Destroyed Pool '%1$s'.", name)); + } } } diff --git a/src/main/java/org/springframework/data/gemfire/util/ArrayUtils.java b/src/main/java/org/springframework/data/gemfire/util/ArrayUtils.java index 1a08839b..efb5b31f 100644 --- a/src/main/java/org/springframework/data/gemfire/util/ArrayUtils.java +++ b/src/main/java/org/springframework/data/gemfire/util/ArrayUtils.java @@ -10,79 +10,99 @@ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ + package org.springframework.data.gemfire.util; +import java.lang.reflect.Array; + /** - * @author David Turanski + * The ArrayUtils class is a utility class for working with Object arrays. * + * @author David Turanski + * @author John Blum + * @see java.lang.reflect.Array */ - - public abstract class ArrayUtils { - /** - * Insert an element into an array. The element is inserted at the - * given position, all elements afterwards are moved to the right. - * - * @param originalArray array to insert into - * @param pos position at which to insert the element - * @param element element to add - * @return the new array - */ - public static Object[] insert(Object[] originalArray, int pos, Object element) { - Object[] newArray = (Object[]) java.lang.reflect.Array.newInstance( - originalArray.getClass().getComponentType(), originalArray.length + 1); + /** + * Insert an element into the given array at position (index). The element is inserted at the given position + * and all elements afterwards are moved to the right. + * + * @param originalArray the array in which to insert the element. + * @param position an integer index (position) at which to insert the element in the array. + * @param element the element to insert into the array. + * @return a new array with the element inserted at position. + * @see java.lang.System#arraycopy(Object, int, Object, int, int) + * @see java.lang.reflect.Array#newInstance(Class, int) + */ + public static Object[] insert(Object[] originalArray, int position, Object element) { + Object[] newArray = (Object[]) Array.newInstance(originalArray.getClass().getComponentType(), + originalArray.length + 1); - - // copy everything before the given position - if (pos > 0) { - System.arraycopy(originalArray, 0, newArray, 0, pos); // does not copy originalArray[pos], where we insert - } - // insert - newArray[pos] = element; + // copy all elements before the given position (here, position refers to the length, or number of elements + // to be copied, excluding the element at originalArray[position] + if (position > 0) { + System.arraycopy(originalArray, 0, newArray, 0, position); + } - // copy remaining elements - if (pos < originalArray.length) { - System.arraycopy(originalArray, pos, // originalArray[pos] first element copied - newArray, pos + 1, // newArray[pos + 1] first destination - originalArray.length - pos); // number of elements left - } + // insert + newArray[position] = element; - - return newArray; - } + // copy remaining elements from originalArray, starting at position, to new array + if (position < originalArray.length) { + System.arraycopy(originalArray, position, newArray, position + 1, originalArray.length - position); + } - /** - * Remove element from an array. The element is removed at the - * specified position, and all remaining elements are moved to the left. - * - * @param originalArray array to remove from - * @param pos position to remove - * @return the new array - */ - public static Object[] remove(Object[] originalArray, int pos) { - Object[] newArray = (Object[])java.lang.reflect.Array.newInstance( - originalArray.getClass().getComponentType(), originalArray.length - 1); + return newArray; + } - + /** + * Determines whether the given array is empty or not. + * + * @param array the array to evaluate for emptiness. + * @return a boolean value indicating whether the given array is empty. + * @see #length(Object...) + */ + public static boolean isEmpty(Object... array) { + return (length(array) == 0); + } - // Copy everything before - if (pos > 0) { - System.arraycopy(originalArray, 0, newArray, 0, pos); // originalArray[pos - 1] is last element copied - } + /** + * Null-safe operation to determine an array's length. + * + * @param array the array to determine it's length. + * @return the length of the given array or 0 if the array reference is null. + */ + public static int length(Object... array) { + return (array != null ? array.length : 0); + } - - // Copy everything after - if (pos < originalArray.length - 1) { - System.arraycopy(originalArray, pos + 1, // originalArray[pos + 1] is first element copied - newArray, pos, // first position to copy into - originalArray.length - 1 - pos); - } + /** + * Remove an element from the given array at position (index). The element is removed at the specified position + * and all remaining elements are shifted to the left. + * + * @param originalArray the array from which to remove the element. + * @param position the integer index (position) indicating the element to remove from the array. + * @return a new array with the element at position in the originalArray removed. + * @see java.lang.System#arraycopy(Object, int, Object, int, int) + * @see java.lang.reflect.Array#newInstance(Class, int) + */ + public static Object[] remove(Object[] originalArray, int position) { + Object[] newArray = (Object[]) Array.newInstance(originalArray.getClass().getComponentType(), + originalArray.length - 1); - - return newArray; - } + // copy all elements before position (here, position refers to the length, or number of elements to be copied + if (position > 0) { + System.arraycopy(originalArray, 0, newArray, 0, position); + } + + // copy remaining elements after position from the originalArray + if (position < originalArray.length - 1) { + System.arraycopy(originalArray, position + 1, newArray, position, originalArray.length - 1 - position); + } + + return newArray; + } - } diff --git a/src/main/java/org/springframework/data/gemfire/util/CollectionUtils.java b/src/main/java/org/springframework/data/gemfire/util/CollectionUtils.java new file mode 100644 index 00000000..8e38e5a2 --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/util/CollectionUtils.java @@ -0,0 +1,47 @@ +/* + * Copyright 2010-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire.util; + +import java.util.Collection; +import java.util.Collections; + +/** + * The CollectionUtils class is a utility class for working with Java Collections Framework and classes. + * + * @author John Blum + * @see java.util.Collection + * @see java.util.Collections + * @see org.springframework.util.CollectionUtils + * @since 1.7.0 + */ +@SuppressWarnings("unused") +public abstract class CollectionUtils extends org.springframework.util.CollectionUtils { + + /** + * A null-safe operation returning the original Collection is non-null or an empty Collection + * (implemented with List) if null. + * + * @param the element class type of the Collection. + * @param collection the Collection to evaluate for being null. + * @return the given Collection if not null, otherwise return an empty Collection (List). + * @see java.util.Collections#emptyList() + */ + public static Collection nullSafeCollection(final Collection collection) { + return (collection != null ? collection : Collections.emptyList()); + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/CacheFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/CacheFactoryBeanTest.java index f68a2249..de5e3a55 100644 --- a/src/test/java/org/springframework/data/gemfire/CacheFactoryBeanTest.java +++ b/src/test/java/org/springframework/data/gemfire/CacheFactoryBeanTest.java @@ -34,7 +34,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.InputStream; -import java.util.Collection; import java.util.Collections; import java.util.Properties; import java.util.concurrent.atomic.AtomicBoolean; @@ -387,19 +386,6 @@ public class CacheFactoryBeanTest { assertTrue(new CacheFactoryBean().isSingleton()); } - @Test - public void testNullSafeCollectionWithNonNullCollection() { - assertNotNull(new CacheFactoryBean().nullSafeCollection(Collections.emptyList())); - } - - @Test - public void testNullSafeCollectionWithNullCollection() { - Collection collection = new CacheFactoryBean().nullSafeCollection(null); - - assertNotNull(collection); - assertTrue(collection.isEmpty()); - } - @Test public void testDestroy() throws Exception { final Cache mockCache = mock(Cache.class, "GemFireCache"); diff --git a/src/test/java/org/springframework/data/gemfire/RegionFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/RegionFactoryBeanTest.java index d052d784..4f1e2b11 100644 --- a/src/test/java/org/springframework/data/gemfire/RegionFactoryBeanTest.java +++ b/src/test/java/org/springframework/data/gemfire/RegionFactoryBeanTest.java @@ -156,7 +156,7 @@ public class RegionFactoryBeanTest extends AbstractRegionFactoryBeanTest { protected RegionAttributes createMockRegionAttributes(final DataPolicy... dataPolicies) { RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); - when(mockRegionAttributes.getDataPolicy()).thenReturn(ArrayUtils.getFirst(DataPolicy.DEFAULT, dataPolicies)); + when(mockRegionAttributes.getDataPolicy()).thenReturn(ArrayUtils.getFirst(dataPolicies, DataPolicy.DEFAULT)); return mockRegionAttributes; } diff --git a/src/test/java/org/springframework/data/gemfire/client/PoolFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/client/PoolFactoryBeanTest.java new file mode 100644 index 00000000..9768023b --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/client/PoolFactoryBeanTest.java @@ -0,0 +1,246 @@ +/* + * Copyright 2010-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire.client; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.util.Collections; +import java.util.Properties; + +import org.junit.Test; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.data.gemfire.TestUtils; +import org.springframework.data.util.ReflectionUtils; + +import com.gemstone.gemfire.cache.client.Pool; +import com.gemstone.gemfire.cache.client.PoolFactory; + +/** + * The PoolFactoryBeanTest class is a test suite of test cases testing the contract and functionality + * of the PoolFactoryBean class. + * + * @author John Blum + * @see org.junit.Test + * @see org.mockito.Mockito + * @see org.springframework.data.gemfire.client.PoolFactoryBean + * @see com.gemstone.gemfire.cache.client.Pool + * @see com.gemstone.gemfire.cache.client.PoolFactory + * @since 1.7.0 + */ +public class PoolFactoryBeanTest { + + @Test + public void testGetObjectType() { + assertEquals(Pool.class, new PoolFactoryBean().getObjectType()); + } + + @Test + public void testIsSingleton() { + assertTrue(new PoolFactoryBean().isSingleton()); + } + + @Test + public void testAfterPropertiesSet() throws Exception { + BeanFactory mockBeanFactory = mock(BeanFactory.class, "MockSpringBeanFactory"); + final PoolFactory mockPoolFactory = mock(PoolFactory.class, "MockGemFirePoolFactory"); + Pool mockPool = mock(Pool.class, "GemFirePool"); + + final Properties gemfireProperties = new Properties(); + gemfireProperties.setProperty("name", "testAfterPropertiesSet"); + + ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean(); + clientCacheFactoryBean.setProperties(gemfireProperties); + + when(mockBeanFactory.getBean(eq(ClientCacheFactoryBean.class))).thenReturn(clientCacheFactoryBean); + when(mockPoolFactory.create(eq("GemFirePool"))).thenReturn(mockPool); + + PoolFactoryBean poolFactoryBean = new PoolFactoryBean() { + @Override protected PoolFactory createPoolFactory() { + return mockPoolFactory; + } + + @Override void doDistributedSystemConnect(Properties properties) { + assertSame(gemfireProperties, properties); + } + }; + + poolFactoryBean.setBeanFactory(mockBeanFactory); + poolFactoryBean.setBeanName("GemFirePool"); + poolFactoryBean.setName(null); + poolFactoryBean.setFreeConnectionTimeout(60000); + poolFactoryBean.setIdleTimeout(120000l); + poolFactoryBean.setKeepAlive(false); + poolFactoryBean.setLoadConditioningInterval(15000); + poolFactoryBean.setLocators(Collections.singletonList(new InetSocketAddress(InetAddress.getLocalHost(), 54321))); + poolFactoryBean.setMaxConnections(50); + poolFactoryBean.setMinConnections(5); + poolFactoryBean.setMultiUserAuthentication(false); + poolFactoryBean.setPingInterval(5000l); + poolFactoryBean.setPrSingleHopEnabled(true); + poolFactoryBean.setRetryAttempts(10); + poolFactoryBean.setServerGroup("TestServerGroup"); + poolFactoryBean.setServers(Collections.singletonList(new InetSocketAddress(InetAddress.getLocalHost(), 12345))); + poolFactoryBean.setSocketBufferSize(32768); + poolFactoryBean.setStatisticInterval(1000); + poolFactoryBean.setSubscriptionAckInterval(500); + poolFactoryBean.setSubscriptionMessageTrackingTimeout(20000); + poolFactoryBean.setSubscriptionRedundancy(2); + poolFactoryBean.setThreadLocalConnections(false); + poolFactoryBean.afterPropertiesSet(); + + assertSame(mockPool, poolFactoryBean.getObject()); + + verify(mockPoolFactory, times(1)).setFreeConnectionTimeout(eq(60000)); + verify(mockPoolFactory, times(1)).setIdleTimeout(eq(120000l)); + verify(mockPoolFactory, times(1)).setLoadConditioningInterval(eq(15000)); + verify(mockPoolFactory, times(1)).setMaxConnections(eq(50)); + verify(mockPoolFactory, times(1)).setMinConnections(eq(5)); + verify(mockPoolFactory, times(1)).setMultiuserAuthentication(eq(false)); + verify(mockPoolFactory, times(1)).setPingInterval(eq(5000l)); + verify(mockPoolFactory, times(1)).setPRSingleHopEnabled(eq(true)); + verify(mockPoolFactory, times(1)).setRetryAttempts(eq(10)); + verify(mockPoolFactory, times(1)).setServerGroup(eq("TestServerGroup")); + verify(mockPoolFactory, times(1)).setSocketBufferSize(eq(32768)); + verify(mockPoolFactory, times(1)).setStatisticInterval(eq(1000)); + verify(mockPoolFactory, times(1)).setSubscriptionAckInterval(eq(500)); + verify(mockPoolFactory, times(1)).setSubscriptionMessageTrackingTimeout(eq(20000)); + verify(mockPoolFactory, times(1)).setSubscriptionRedundancy(eq(2)); + verify(mockPoolFactory, times(1)).setThreadLocalConnections(eq(false)); + verify(mockPoolFactory, times(1)).addLocator(InetAddress.getLocalHost().getHostName(), 54321); + verify(mockPoolFactory, times(1)).addServer(InetAddress.getLocalHost().getHostName(), 12345); + verify(mockPoolFactory, times(1)).create(eq("GemFirePool")); + } + + @Test(expected = IllegalArgumentException.class) + public void testAfterPropertiesSetWithNoLocatorsServersSpecified() throws Exception { + try { + PoolFactoryBean poolFactoryBean = new PoolFactoryBean(); + + poolFactoryBean.setName("GemFirePool"); + poolFactoryBean.setLocators(null); + poolFactoryBean.setServers(Collections.emptyList()); + poolFactoryBean.afterPropertiesSet(); + } + catch (IllegalArgumentException expected) { + assertEquals("at least one GemFire Locator or Server is required", expected.getMessage()); + throw expected; + } + } + + @Test(expected = IllegalArgumentException.class) + public void testAfterPropertiesSetWithUnspecifiedName() throws Exception { + try { + PoolFactoryBean poolFactoryBean = new PoolFactoryBean(); + poolFactoryBean.setBeanName(null); + poolFactoryBean.setName(null); + poolFactoryBean.afterPropertiesSet(); + } + catch (IllegalArgumentException expected) { + assertEquals("Pool 'name' is required", expected.getMessage()); + throw expected; + } + } + + @Test + public void testResolveGemfireProperties() { + BeanFactory mockBeanFactory = mock(BeanFactory.class, "MockSpringBeanFactory"); + ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean(); + + when(mockBeanFactory.getBean(eq(ClientCacheFactoryBean.class))).thenReturn(clientCacheFactoryBean); + + Properties expectedGemfireProperties = new Properties(); + + expectedGemfireProperties.setProperty("name", "testResolveGemfireProperties"); + clientCacheFactoryBean.setProperties(expectedGemfireProperties); + + PoolFactoryBean poolFactoryBean = new PoolFactoryBean(); + + poolFactoryBean.setBeanFactory(mockBeanFactory); + + Properties resolvedGemfireProperties = poolFactoryBean.resolveGemfireProperties(); + + assertSame(expectedGemfireProperties, resolvedGemfireProperties); + } + + @Test + public void testResolveUnresolvableGemfireProperties() { + BeanFactory mockBeanFactory = mock(BeanFactory.class, "MockSpringBeanFactory"); + + when(mockBeanFactory.getBean(eq(ClientCacheFactoryBean.class))).thenThrow( + new NoSuchBeanDefinitionException("TEST")); + + PoolFactoryBean poolFactoryBean = new PoolFactoryBean(); + + poolFactoryBean.setBeanFactory(mockBeanFactory); + + assertNull(poolFactoryBean.resolveGemfireProperties()); + } + + @Test + public void testDestroy() throws Exception { + Pool mockPool = mock(Pool.class, "MockGemFirePool"); + + when(mockPool.isDestroyed()).thenReturn(false); + + PoolFactoryBean poolFactoryBean = new PoolFactoryBean(); + + poolFactoryBean.setPool(mockPool); + poolFactoryBean.destroy(); + + assertNull(TestUtils.readField("pool", poolFactoryBean)); + + verify(mockPool, times(1)).releaseThreadLocalConnection(); + verify(mockPool, times(1)).destroy(eq(false)); + } + + @Test + public void testDestroyNonSpringBasedPool() throws Exception { + Pool mockPool = mock(Pool.class, "MockGemFirePool"); + + PoolFactoryBean poolFactoryBean = new PoolFactoryBean(); + + ReflectionUtils.setField(PoolFactoryBean.class.getDeclaredField("springBasedPool"), poolFactoryBean, false); + poolFactoryBean.setPool(mockPool); + poolFactoryBean.destroy(); + + verify(mockPool, never()).isDestroyed(); + verify(mockPool, never()).releaseThreadLocalConnection(); + verify(mockPool, never()).destroy(any(Boolean.class)); + } + + @Test + public void testDestroyWithUninitializedPool() throws Exception { + PoolFactoryBean poolFactoryBean = new PoolFactoryBean(); + + poolFactoryBean.setPool(null); + poolFactoryBean.destroy(); + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/test/support/ArrayUtils.java b/src/test/java/org/springframework/data/gemfire/test/support/ArrayUtils.java index fce0b8a3..5d28a671 100644 --- a/src/test/java/org/springframework/data/gemfire/test/support/ArrayUtils.java +++ b/src/test/java/org/springframework/data/gemfire/test/support/ArrayUtils.java @@ -20,25 +20,19 @@ package org.springframework.data.gemfire.test.support; * ArrayUtils is a utility class for working with Java arrays. * * @author John Blum + * @see org.springframework.data.gemfire.util.ArrayUtils * @since 1.6.0 */ @SuppressWarnings("unused") -public class ArrayUtils { +// TODO replace with org.springframework.data.gemfire.util.ArrayUtils +public class ArrayUtils extends org.springframework.data.gemfire.util.ArrayUtils { public static T getFirst(T... array) { - return getFirst(null, array); + return getFirst(array, null); } - public static T getFirst(T defaultValue, T... array) { + public static T getFirst(T[] array, T defaultValue) { return (isEmpty(array) ? defaultValue : array[0]); } - public static boolean isEmpty(final Object... array) { - return (array == null || array.length == 0); - } - - public static int length(final Object... array) { - return (array != null ? array.length : 0); - } - } diff --git a/src/test/java/org/springframework/data/gemfire/test/support/CollectionUtils.java b/src/test/java/org/springframework/data/gemfire/test/support/CollectionUtils.java index 768c9251..ebd25151 100644 --- a/src/test/java/org/springframework/data/gemfire/test/support/CollectionUtils.java +++ b/src/test/java/org/springframework/data/gemfire/test/support/CollectionUtils.java @@ -27,10 +27,12 @@ import java.util.List; * @author John Blum * @see java.util.Collection * @see java.util.Collections + * @see org.springframework.data.gemfire.util.CollectionUtils * @since 1.5.0 */ @SuppressWarnings("unused") -public abstract class CollectionUtils { +// TODO replace with org.springframework.data.gemfire.util.CollectionUtils +public abstract class CollectionUtils extends org.springframework.data.gemfire.util.CollectionUtils { public static Iterable iterable(final Enumeration enumeration) { return new Iterable() { diff --git a/src/test/java/org/springframework/data/gemfire/util/ArrayUtilsTest.java b/src/test/java/org/springframework/data/gemfire/util/ArrayUtilsTest.java new file mode 100644 index 00000000..155760d8 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/util/ArrayUtilsTest.java @@ -0,0 +1,129 @@ +/* + * Copyright 2010-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; + +import org.junit.Test; + +/** + * The ArrayUtilsTest class is a test suite of test cases testing the contract and functionality + * of the ArrayUtils class. + * + * @author John Blum + * @see java.util.Arrays + * @see org.junit.Test + * @see org.springframework.data.gemfire.util.ArrayUtils + * @since 1.7.0 + */ +public class ArrayUtilsTest { + + @Test + public void testInsertBeginning() { + Object[] originalArray = { "testing", "tested" }; + Object[] newArray = ArrayUtils.insert(originalArray, 0, "test"); + + assertNotSame(originalArray, newArray); + assertFalse(Arrays.equals(originalArray, newArray)); + assertEquals("test", newArray[0]); + assertEquals("testing", newArray[1]); + assertEquals("tested", newArray[2]); + } + + @Test + public void testInsertMiddle() { + Object[] originalArray = { "test", "tested" }; + Object[] newArray = ArrayUtils.insert(originalArray, 1, "testing"); + + assertNotSame(originalArray, newArray); + assertFalse(Arrays.equals(originalArray, newArray)); + assertEquals("test", newArray[0]); + assertEquals("testing", newArray[1]); + assertEquals("tested", newArray[2]); + } + + @Test + public void testInsertEnd() { + Object[] originalArray = { "test", "testing" }; + Object[] newArray = ArrayUtils.insert(originalArray, 2, "tested"); + + assertNotSame(originalArray, newArray); + assertFalse(Arrays.equals(originalArray, newArray)); + assertEquals("test", newArray[0]); + assertEquals("testing", newArray[1]); + assertEquals("tested", newArray[2]); + } + + @Test + public void testIsEmpty() { + assertFalse(ArrayUtils.isEmpty("test", "testing", "tested")); + assertFalse(ArrayUtils.isEmpty("test")); + assertFalse(ArrayUtils.isEmpty("")); + assertFalse(ArrayUtils.isEmpty(null, null, null)); + assertTrue(ArrayUtils.isEmpty()); + assertTrue(ArrayUtils.isEmpty((Object[]) null)); + } + + @Test + public void testLength() { + assertEquals(3, ArrayUtils.length("test", "testing", "tested")); + assertEquals(1, ArrayUtils.length("test")); + assertEquals(1, ArrayUtils.length("")); + assertEquals(3, ArrayUtils.length(null, null, null)); + assertEquals(0, ArrayUtils.length()); + assertEquals(0, ArrayUtils.length((Object[]) null)); + } + + @Test + public void testRemoveBeginning() { + Object[] originalArray = { "test", "testing", "tested" }; + Object[] newArray = ArrayUtils.remove(originalArray, 0); + + assertNotSame(originalArray, newArray); + assertFalse(Arrays.equals(originalArray, newArray)); + assertEquals("testing", newArray[0]); + assertEquals("tested", newArray[1]); + } + + @Test + public void testRemoveMiddle() { + Object[] originalArray = { "test", "testing", "tested" }; + Object[] newArray = ArrayUtils.remove(originalArray, 1); + + assertNotSame(originalArray, newArray); + assertFalse(Arrays.equals(originalArray, newArray)); + assertEquals("test", newArray[0]); + assertEquals("tested", newArray[1]); + } + + @Test + public void testRemoveEnd() { + Object[] originalArray = { "test", "testing", "tested" }; + Object[] newArray = ArrayUtils.remove(originalArray, 2); + + assertNotSame(originalArray, newArray); + assertFalse(Arrays.equals(originalArray, newArray)); + assertEquals("test", newArray[0]); + assertEquals("testing", newArray[1]); + } + +} diff --git a/src/test/java/org/springframework/data/gemfire/util/CollectionUtilsTest.java b/src/test/java/org/springframework/data/gemfire/util/CollectionUtilsTest.java new file mode 100644 index 00000000..c10dc3dd --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/util/CollectionUtilsTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2010-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.gemfire.util; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +import java.util.Collection; +import java.util.List; + +import org.junit.Test; + +/** + * The CollectionUtilsTest class is a test suite of test cases testing the contract and functionality + * of the CollectionUtils class. + * + * @author John Blum + * @see java.util.Collection + * @see org.junit.Test + * @see org.mockito.Mockito + * @see org.springframework.data.gemfire.util.CollectionUtils + * @since 1.7.0 + */ +public class CollectionUtilsTest { + + @Test + public void testNullSafeCollectionWithNonNullCollection() { + List mockList = mock(List.class); + assertSame(mockList, CollectionUtils.nullSafeCollection(mockList)); + } + + @Test + public void testNullSafeCollectionWithNullCollection() { + Collection collection = CollectionUtils.nullSafeCollection(null); + + assertNotNull(collection); + assertTrue(collection.isEmpty()); + } + +}