From 950a456c88785bb0ed08ba81194a0165c58be0b1 Mon Sep 17 00:00:00 2001 From: John Blum Date: Tue, 10 Apr 2018 13:24:18 -0700 Subject: [PATCH] Add mock object support for Region o.a.g.cache.AttributesMutator and o.a.g.cache.EvictionAttributesMutator. --- .../tests/mock/GemFireMockObjectsSupport.java | 187 +++++++++++++++++- .../MockClientCacheApplicationTest.java | 1 - 2 files changed, 185 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/springframework/data/gemfire/tests/mock/GemFireMockObjectsSupport.java b/src/main/java/org/springframework/data/gemfire/tests/mock/GemFireMockObjectsSupport.java index 898b370..81d9b11 100644 --- a/src/main/java/org/springframework/data/gemfire/tests/mock/GemFireMockObjectsSupport.java +++ b/src/main/java/org/springframework/data/gemfire/tests/mock/GemFireMockObjectsSupport.java @@ -30,6 +30,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray; +import static org.springframework.data.gemfire.util.CollectionUtils.asSet; import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeSet; import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.NOT_SUPPORTED; import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException; @@ -61,6 +62,7 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.stream.Collectors; +import org.apache.geode.cache.AttributesMutator; import org.apache.geode.cache.Cache; import org.apache.geode.cache.CacheFactory; import org.apache.geode.cache.CacheListener; @@ -71,6 +73,7 @@ import org.apache.geode.cache.DataPolicy; import org.apache.geode.cache.DiskStore; import org.apache.geode.cache.DiskStoreFactory; import org.apache.geode.cache.EvictionAttributes; +import org.apache.geode.cache.EvictionAttributesMutator; import org.apache.geode.cache.ExpirationAction; import org.apache.geode.cache.ExpirationAttributes; import org.apache.geode.cache.GemFireCache; @@ -121,6 +124,7 @@ import org.springframework.data.gemfire.IndexType; import org.springframework.data.gemfire.server.SubscriptionEvictionPolicy; import org.springframework.data.gemfire.tests.mock.support.MockObjectInvocationException; import org.springframework.data.gemfire.tests.util.FileSystemUtils; +import org.springframework.util.Assert; /** * The {@link GemFireMockObjectsSupport} class is an abstract base class encapsulating factory methods for creating @@ -157,7 +161,7 @@ import org.springframework.data.gemfire.tests.util.FileSystemUtils; * @see org.springframework.data.gemfire.tests.mock.MockObjectsSupport * @since 0.0.1 */ -@SuppressWarnings("unused") +@SuppressWarnings("all") public abstract class GemFireMockObjectsSupport extends MockObjectsSupport { private static final boolean DEFAULT_USE_SINGLETON_CACHE = false; @@ -1793,7 +1797,7 @@ public abstract class GemFireMockObjectsSupport extends MockObjectsSupport { Set> subRegions = new CopyOnWriteArraySet<>(); - when(mockRegion.getAttributes()).thenReturn(regionAttributes); + when(mockRegion.getAttributes()).thenAnswer(invocation -> mockRegionAttributes(mockRegion, regionAttributes)); when(mockRegion.getFullPath()).thenReturn(toRegionPath(name)); when(mockRegion.getName()).thenReturn(toRegionName(name)); when(mockRegion.getRegionService()).thenReturn(regionService); @@ -1832,6 +1836,185 @@ public abstract class GemFireMockObjectsSupport extends MockObjectsSupport { return rememberMockedRegion(mockRegion); } + @SuppressWarnings("all") + private static RegionAttributes mockRegionAttributes(Region mockRegion, + RegionAttributes baseRegionAttributes) { + + AttributesMutator mockAttributesMutator = mock(AttributesMutator.class); + + EvictionAttributesMutator mockEvictionAttributesMutator = mock(EvictionAttributesMutator.class); + + RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); + + when(mockRegion.getAttributesMutator()).thenReturn(mockAttributesMutator); + when(mockAttributesMutator.getEvictionAttributesMutator()).thenReturn(mockEvictionAttributesMutator); + when(mockAttributesMutator.getRegion()).thenReturn(mockRegion); + + AtomicInteger evictionMaximum = + new AtomicInteger(Optional.ofNullable(baseRegionAttributes.getEvictionAttributes()) + .map(EvictionAttributes::getMaximum) + .orElse(EvictionAttributes.DEFAULT_ENTRIES_MAXIMUM)); + + AtomicReference cloningEnabled = new AtomicReference<>(null); + + AtomicReference> cacheLoader = new AtomicReference<>(baseRegionAttributes.getCacheLoader()); + + AtomicReference> cacheWriter = new AtomicReference<>(baseRegionAttributes.getCacheWriter()); + + AtomicReference> customEntryIdleTimeout = + new AtomicReference<>(baseRegionAttributes.getCustomEntryIdleTimeout()); + + AtomicReference> customEntryTimeToLive = + new AtomicReference<>(baseRegionAttributes.getCustomEntryTimeToLive()); + + AtomicReference entryIdleTimeout = + new AtomicReference<>(baseRegionAttributes.getEntryIdleTimeout()); + + AtomicReference entryTimeToLive = + new AtomicReference<>(baseRegionAttributes.getEntryTimeToLive()); + + AtomicReference regionIdleTimeout = + new AtomicReference<>(baseRegionAttributes.getRegionIdleTimeout()); + + AtomicReference regionTimeToLive = + new AtomicReference<>(baseRegionAttributes.getRegionTimeToLive()); + + List asyncEventQueueIds = + new CopyOnWriteArrayList<>(nullSafeSet(baseRegionAttributes.getAsyncEventQueueIds())); + + List> cacheListeners = + new CopyOnWriteArrayList<>(nullSafeArray(baseRegionAttributes.getCacheListeners(), CacheListener.class)); + + List gatewaySenderIds = + new CopyOnWriteArrayList<>(nullSafeSet(baseRegionAttributes.getGatewaySenderIds())); + + // Mock AttributesMutator + doAnswer(newAdder(asyncEventQueueIds, null)) + .when(mockAttributesMutator).addAsyncEventQueueId(anyString()); + + doAnswer(newAdder(cacheListeners, null)) + .when(mockAttributesMutator).addCacheListener(any(CacheListener.class)); + + doAnswer(newAdder(gatewaySenderIds, null)). + when(mockAttributesMutator).addGatewaySenderId(anyString()); + + when(mockAttributesMutator.getCloningEnabled()).thenAnswer(newGetter(() -> + Optional.ofNullable(cloningEnabled.get()).orElseGet(baseRegionAttributes::getCloningEnabled))); + + doAnswer(invocation -> { + + CacheListener[] cacheListenersArgument = + nullSafeArray(invocation.getArgument(0), CacheListener.class); + + Arrays.stream(cacheListenersArgument).forEach(it -> + Assert.notNull(it, "The CacheListener[] must not contain null elements")); + + cacheListeners.forEach(CacheListener::close); + cacheListeners.addAll(Arrays.asList(cacheListenersArgument)); + + return null; + + }).when(mockAttributesMutator).initCacheListeners(any(CacheListener[].class)); + + + doAnswer(invocation -> asyncEventQueueIds.remove(invocation.getArgument(0))) + .when(mockAttributesMutator).removeAsyncEventQueueId(anyString()); + + doAnswer(invocation -> cacheListeners.remove(invocation.getArgument(0))) + .when(mockAttributesMutator).removeCacheListener(any(CacheListener.class)); + + doAnswer(invocation -> gatewaySenderIds.remove(invocation.getArgument(0))) + .when(mockAttributesMutator).removeGatewaySenderId(anyString()); + + doAnswer(newSetter(cacheLoader, baseRegionAttributes.getCacheLoader())) + .when(mockAttributesMutator).setCacheLoader(any(CacheLoader.class)); + + doAnswer(newSetter(cacheWriter, baseRegionAttributes.getCacheWriter())) + .when(mockAttributesMutator).setCacheWriter(any(CacheWriter.class)); + + doAnswer(newSetter(cloningEnabled, null)) + .when(mockAttributesMutator).setCloningEnabled(anyBoolean()); + + doAnswer(newSetter(customEntryIdleTimeout, baseRegionAttributes.getCustomEntryIdleTimeout())) + .when(mockAttributesMutator).setCustomEntryIdleTimeout(any(CustomExpiry.class)); + + doAnswer(newSetter(customEntryTimeToLive, baseRegionAttributes.getCustomEntryTimeToLive())) + .when(mockAttributesMutator).setCustomEntryTimeToLive(any(CustomExpiry.class)); + + doAnswer(newSetter(entryIdleTimeout, baseRegionAttributes.getEntryIdleTimeout())) + .when(mockAttributesMutator).setEntryIdleTimeout(any(ExpirationAttributes.class)); + + doAnswer(newSetter(entryTimeToLive, baseRegionAttributes.getEntryTimeToLive())) + .when(mockAttributesMutator).setEntryTimeToLive(any(ExpirationAttributes.class)); + + doAnswer(newSetter(regionIdleTimeout, baseRegionAttributes.getRegionIdleTimeout())) + .when(mockAttributesMutator).setRegionIdleTimeout(any(ExpirationAttributes.class)); + + doAnswer(newSetter(regionTimeToLive, baseRegionAttributes.getRegionTimeToLive())) + .when(mockAttributesMutator).setRegionTimeToLive(any(ExpirationAttributes.class)); + + // Mock EvictionAttributesMutator + doAnswer(newSetter(evictionMaximum, null)).when(mockEvictionAttributesMutator).setMaximum(anyInt()); + + // Mock RegionAttributes + when(mockRegionAttributes.getAsyncEventQueueIds()) + .thenAnswer(invocation -> asSet(asyncEventQueueIds.toArray(new String[asyncEventQueueIds.size()]))); + + when(mockRegionAttributes.getCacheListeners()) + .thenAnswer(invocation -> cacheListeners.toArray(new CacheListener[cacheListeners.size()])); + + when(mockRegionAttributes.getCacheLoader()).thenAnswer(newGetter(cacheLoader::get)); + when(mockRegionAttributes.getCacheWriter()).thenAnswer(newGetter(cacheWriter::get)); + when(mockRegionAttributes.getCloningEnabled()).thenAnswer(newGetter(cloningEnabled::get)); + when(mockRegionAttributes.getCompressor()).thenAnswer(newGetter(baseRegionAttributes::getCompressor)); + when(mockRegionAttributes.getConcurrencyChecksEnabled()).thenAnswer(newGetter(baseRegionAttributes::getConcurrencyChecksEnabled)); + when(mockRegionAttributes.getConcurrencyLevel()).thenAnswer(newGetter(baseRegionAttributes::getConcurrencyLevel)); + when(mockRegionAttributes.getCustomEntryIdleTimeout()).thenAnswer(newGetter(customEntryIdleTimeout::get)); + when(mockRegionAttributes.getCustomEntryTimeToLive()).thenAnswer(newGetter(customEntryTimeToLive::get)); + when(mockRegionAttributes.getDataPolicy()).thenAnswer(newGetter(baseRegionAttributes::getDataPolicy)); + when(mockRegionAttributes.getDiskStoreName()).thenAnswer(newGetter(baseRegionAttributes::getDiskStoreName)); + when(mockRegionAttributes.getEnableAsyncConflation()).thenAnswer(newGetter(baseRegionAttributes::getEnableAsyncConflation)); + when(mockRegionAttributes.getEnableSubscriptionConflation()).thenAnswer(newGetter(baseRegionAttributes::getEnableSubscriptionConflation)); + when(mockRegionAttributes.getEntryIdleTimeout()).thenAnswer(newGetter(entryIdleTimeout::get)); + when(mockRegionAttributes.getEntryTimeToLive()).thenAnswer(newGetter(entryTimeToLive::get)); + + when(mockRegionAttributes.getEvictionAttributes()).thenAnswer(invocation -> { + + EvictionAttributes mockEvictionAttibutes = mock(EvictionAttributes.class); + EvictionAttributes regionEvictionAttributes = baseRegionAttributes.getEvictionAttributes(); + + when(mockEvictionAttibutes.getAction()).thenAnswer(newGetter(regionEvictionAttributes::getAction)); + when(mockEvictionAttibutes.getAlgorithm()).thenAnswer(newGetter(regionEvictionAttributes::getAlgorithm)); + when(mockEvictionAttibutes.getMaximum()).thenAnswer(newGetter(evictionMaximum)); + when(mockEvictionAttibutes.getObjectSizer()).thenAnswer(newGetter(regionEvictionAttributes::getObjectSizer)); + + return mockEvictionAttibutes; + }); + + when(mockRegionAttributes.getGatewaySenderIds()) + .thenAnswer(invocation -> asSet(gatewaySenderIds.toArray(new String[gatewaySenderIds.size()]))); + + when(mockRegionAttributes.getIgnoreJTA()).thenAnswer(newGetter(baseRegionAttributes::getIgnoreJTA)); + when(mockRegionAttributes.getIndexMaintenanceSynchronous()).thenAnswer(newGetter(baseRegionAttributes::getIndexMaintenanceSynchronous)); + when(mockRegionAttributes.getInitialCapacity()).thenAnswer(newGetter(baseRegionAttributes::getInitialCapacity)); + when(mockRegionAttributes.getKeyConstraint()).thenAnswer(newGetter(baseRegionAttributes::getKeyConstraint)); + when(mockRegionAttributes.getLoadFactor()).thenAnswer(newGetter(baseRegionAttributes::getLoadFactor)); + when(mockRegionAttributes.getMulticastEnabled()).thenAnswer(newGetter(baseRegionAttributes::getMulticastEnabled)); + when(mockRegionAttributes.getOffHeap()).thenAnswer(newGetter(baseRegionAttributes::getOffHeap)); + when(mockRegionAttributes.getPartitionAttributes()).thenAnswer(newGetter(baseRegionAttributes::getPartitionAttributes)); + when(mockRegionAttributes.getPoolName()).thenAnswer(newGetter(baseRegionAttributes::getPoolName)); + when(mockRegionAttributes.getRegionIdleTimeout()).thenAnswer(newGetter(regionIdleTimeout::get)); + when(mockRegionAttributes.getRegionTimeToLive()).thenAnswer(newGetter(regionTimeToLive::get)); + when(mockRegionAttributes.getScope()).thenAnswer(newGetter(baseRegionAttributes::getScope)); + when(mockRegionAttributes.getStatisticsEnabled()).thenAnswer(newGetter(baseRegionAttributes::getStatisticsEnabled)); + when(mockRegionAttributes.getSubscriptionAttributes()).thenAnswer(newGetter(baseRegionAttributes::getSubscriptionAttributes)); + when(mockRegionAttributes.getValueConstraint()).thenAnswer(newGetter(baseRegionAttributes::getValueConstraint)); + when(mockRegionAttributes.isDiskSynchronous()).thenAnswer(newGetter(baseRegionAttributes::isDiskSynchronous)); + when(mockRegionAttributes.isLockGrantor()).thenAnswer(newGetter(baseRegionAttributes::isLockGrantor)); + + return mockRegionAttributes; + } + public static Region mockSubRegion(Region parent, String name, RegionAttributes regionAttributes) { diff --git a/src/test/java/org/springframework/data/gemfire/MockClientCacheApplicationTest.java b/src/test/java/org/springframework/data/gemfire/MockClientCacheApplicationTest.java index fe69653..57b6932 100644 --- a/src/test/java/org/springframework/data/gemfire/MockClientCacheApplicationTest.java +++ b/src/test/java/org/springframework/data/gemfire/MockClientCacheApplicationTest.java @@ -64,6 +64,5 @@ public class MockClientCacheApplicationTest { return exampleRegion; } - } }