DATAGEODE-102 - Add support for enforcing Lucene Index creation before Region creation.
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright 2018 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.config.support;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.shiro.util.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.data.gemfire.RegionFactoryBean;
|
||||
import org.springframework.data.gemfire.test.mock.context.GemFireMockObjectsApplicationContextInitializer;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link LuceneIndexRegionBeanFactoryPostProcessor}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.springframework.data.gemfire.config.support.LuceneIndexRegionBeanFactoryPostProcessor
|
||||
* @since 2.1.0
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration(initializers = GemFireMockObjectsApplicationContextInitializer.class)
|
||||
public class LuceneIndexRegionBeanFactoryPostProcessorIntegrationTests {
|
||||
|
||||
private static final List<String> beanNames = new CopyOnWriteArrayList<>();
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private BeanDefinition getBeanDefinition(String beanName) {
|
||||
|
||||
return Optional.ofNullable(this.applicationContext)
|
||||
.filter(it -> it instanceof AbstractApplicationContext)
|
||||
.map(it -> (AbstractApplicationContext) it)
|
||||
.map(it -> it.getBeanFactory())
|
||||
.map(beanFactory -> beanFactory.getBeanDefinition(beanName))
|
||||
.orElse(null);
|
||||
}
|
||||
@Test
|
||||
public void regionLuceneIndexAndDiskStoreBeanDependenciesAreCorrect() {
|
||||
|
||||
BeanDefinition mockDiskStore = getBeanDefinition("MockDiskStore");
|
||||
|
||||
assertThat(mockDiskStore).isNotNull();
|
||||
assertThat(nullSafeArray(mockDiskStore.getDependsOn(), String.class))
|
||||
.doesNotContain("BookTitleLuceneIndex", "ContractDescriptionLuceneIndex");
|
||||
|
||||
BeanDefinition bookTitleLuceneIndex = getBeanDefinition("BookTitleLuceneIndex");
|
||||
|
||||
assertThat(bookTitleLuceneIndex).isNotNull();
|
||||
assertThat(nullSafeArray(bookTitleLuceneIndex.getDependsOn(), String.class))
|
||||
.doesNotContain("Books", "BookTitleLuceneIndex", "ContractDescriptionLuceneIndex");
|
||||
|
||||
BeanDefinition contractDescriptionLuceneIndex = getBeanDefinition("ContractDescriptionLuceneIndex");
|
||||
|
||||
assertThat(contractDescriptionLuceneIndex).isNotNull();
|
||||
assertThat(nullSafeArray(contractDescriptionLuceneIndex.getDependsOn(), String.class))
|
||||
.doesNotContain("Contracts", "BookTitleLuceneIndex", "ContractDescriptionLuceneIndex");
|
||||
|
||||
BeanDefinition booksRegion = getBeanDefinition("Books");
|
||||
|
||||
assertThat(booksRegion).isNotNull();
|
||||
assertThat(booksRegion.getDependsOn()).contains("BookTitleLuceneIndex");
|
||||
assertThat(booksRegion.getDependsOn()).doesNotContain("ContractDescriptionLuceneIndex");
|
||||
|
||||
BeanDefinition contractsRegion = getBeanDefinition("Contracts");
|
||||
|
||||
assertThat(contractsRegion).isNotNull();
|
||||
assertThat(contractsRegion.getDependsOn()).contains("ContractDescriptionLuceneIndex");
|
||||
assertThat(contractsRegion.getDependsOn()).doesNotContain("BookTitleLuceneIndex");
|
||||
|
||||
BeanDefinition peopleRegion = getBeanDefinition("People");
|
||||
|
||||
assertThat(peopleRegion).isNotNull();
|
||||
assertThat(nullSafeArray(peopleRegion.getDependsOn(), String.class))
|
||||
.doesNotContain("BookTitleLuceneIndex", "ContractDescriptionLucenenIndex");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void gemfireBeanProcessingOrderIsCorrect() {
|
||||
assertThat(beanNames.indexOf("BookTitleLuceneIndex")).isLessThan(beanNames.indexOf("Books"));
|
||||
assertThat(beanNames.indexOf("ContractDescriptionLuceneIndex")).isLessThan(beanNames.indexOf("Contracts"));
|
||||
}
|
||||
|
||||
static class BeanProcessingOrderRecordingBeanPostProcessor implements BeanPostProcessor {
|
||||
|
||||
@Nullable @Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (isRegionBean(bean)) {
|
||||
|
||||
Assert.isTrue(!"Books".equals(beanName) || beanNames.contains("BookTitleLuceneIndex"),
|
||||
"Expected [BookTitleLuceneIndex] to already exist");
|
||||
|
||||
Assert.isTrue(!"Contracts".equals(beanName) || beanNames.contains("ContractDescriptionLuceneIndex"),
|
||||
"Expected [ContractDescriptionLuceneIndex] to already exist");
|
||||
}
|
||||
|
||||
if (!beanNames.contains(beanName)) {
|
||||
beanNames.add(beanName);
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
private boolean isRegionBean(Object bean) {
|
||||
return bean instanceof Region || bean instanceof RegionFactoryBean;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ 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.nullSafeMap;
|
||||
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;
|
||||
@@ -55,6 +56,7 @@ import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
@@ -97,6 +99,13 @@ import org.apache.geode.cache.client.Pool;
|
||||
import org.apache.geode.cache.client.PoolFactory;
|
||||
import org.apache.geode.cache.control.ResourceManager;
|
||||
import org.apache.geode.cache.execute.RegionFunctionContext;
|
||||
import org.apache.geode.cache.lucene.LuceneIndex;
|
||||
import org.apache.geode.cache.lucene.LuceneIndexFactory;
|
||||
import org.apache.geode.cache.lucene.LuceneQuery;
|
||||
import org.apache.geode.cache.lucene.LuceneQueryFactory;
|
||||
import org.apache.geode.cache.lucene.LuceneQueryProvider;
|
||||
import org.apache.geode.cache.lucene.LuceneSerializer;
|
||||
import org.apache.geode.cache.lucene.LuceneService;
|
||||
import org.apache.geode.cache.query.CqAttributes;
|
||||
import org.apache.geode.cache.query.CqQuery;
|
||||
import org.apache.geode.cache.query.Index;
|
||||
@@ -118,6 +127,7 @@ import org.apache.geode.distributed.DistributedMember;
|
||||
import org.apache.geode.distributed.DistributedSystem;
|
||||
import org.apache.geode.internal.concurrent.ConcurrentHashSet;
|
||||
import org.apache.geode.pdx.PdxSerializer;
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.data.gemfire.IndexType;
|
||||
@@ -277,6 +287,20 @@ public abstract class GemFireMockObjectsSupport extends MockObjectsSupport {
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> T doSafeOperation(ExceptionThrowingOperation<T> operation) {
|
||||
return doSafeOperation(operation, null);
|
||||
}
|
||||
|
||||
private static <T> T doSafeOperation(ExceptionThrowingOperation<T> operation, T defaultValue) {
|
||||
|
||||
try {
|
||||
return operation.doExceptionThrowingOperation();
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the given {@link Region} is a root {@link Region}.
|
||||
*
|
||||
@@ -400,6 +424,19 @@ public abstract class GemFireMockObjectsSupport extends MockObjectsSupport {
|
||||
newIllegalStateException("RegionAttributes with ID [%s] cannot be found", regionAttributesId));
|
||||
}
|
||||
|
||||
private static <T> T rethrowAsRuntimeException(ExceptionThrowingOperation<T> operation) {
|
||||
|
||||
try {
|
||||
return operation.doExceptionThrowingOperation();
|
||||
}
|
||||
catch (RuntimeException cause) {
|
||||
throw cause;
|
||||
}
|
||||
catch (Exception cause) {
|
||||
throw new RuntimeException(cause);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given {@link String Region name} into a proper {@link Region#getName() Region name}.
|
||||
*
|
||||
@@ -1772,6 +1809,204 @@ public abstract class GemFireMockObjectsSupport extends MockObjectsSupport {
|
||||
return mock(IndexStatistics.class, mockObjectIdentifier(name));
|
||||
}
|
||||
|
||||
public static LuceneIndexFactory mockLuceneIndexFactory() {
|
||||
return mockLuceneIndexFactory(null);
|
||||
}
|
||||
|
||||
private static LuceneIndexFactory mockLuceneIndexFactory(Map<LuceneIndexKey, LuceneIndex> luceneIndexes) {
|
||||
|
||||
LuceneIndexFactory mockLuceneIndexFactory = mock(LuceneIndexFactory.class);
|
||||
|
||||
AtomicReference<LuceneSerializer> luceneSerializerReference = new AtomicReference<>(null);
|
||||
|
||||
Map<String, Analyzer> fieldAnalyzers = new ConcurrentHashMap<>();
|
||||
|
||||
Set<String> fields = new CopyOnWriteArraySet<>();
|
||||
|
||||
when(mockLuceneIndexFactory.addField(anyString())).thenAnswer(invocation -> {
|
||||
|
||||
String fieldName = invocation.getArgument(0);
|
||||
|
||||
fields.add(fieldName);
|
||||
|
||||
return mockLuceneIndexFactory;
|
||||
});
|
||||
|
||||
when(mockLuceneIndexFactory.addField(anyString(), any(Analyzer.class))).thenAnswer(invocation -> {
|
||||
|
||||
String fieldName = invocation.getArgument(0);
|
||||
Analyzer analyzer = invocation.getArgument(1);
|
||||
|
||||
fieldAnalyzers.put(fieldName, analyzer);
|
||||
|
||||
return mockLuceneIndexFactory;
|
||||
});
|
||||
|
||||
when(mockLuceneIndexFactory.setFields(ArgumentMatchers.<String[]>any())).thenAnswer(invocation -> {
|
||||
|
||||
Object[] fieldsArgument = invocation.getArguments();
|
||||
|
||||
fields.clear();
|
||||
|
||||
Arrays.stream(nullSafeArray(fieldsArgument, Object.class))
|
||||
.filter(field -> field instanceof String)
|
||||
.map(String::valueOf)
|
||||
.forEach(fields::add);
|
||||
|
||||
return mockLuceneIndexFactory;
|
||||
});
|
||||
|
||||
when(mockLuceneIndexFactory.setFields(any(Map.class))).thenAnswer(invocation -> {
|
||||
|
||||
Map<String, Analyzer> fieldAnalyzersArgument = invocation.getArgument(0);
|
||||
|
||||
fieldAnalyzers.clear();
|
||||
fieldAnalyzers.putAll(nullSafeMap(fieldAnalyzers));
|
||||
|
||||
return mockLuceneIndexFactory;
|
||||
});
|
||||
|
||||
when(mockLuceneIndexFactory.setLuceneSerializer(any(LuceneSerializer.class))).thenAnswer(invocation -> {
|
||||
|
||||
Optional.ofNullable(invocation.<LuceneSerializer>getArgument(0))
|
||||
.map(luceneSerializer -> {
|
||||
luceneSerializerReference.set(luceneSerializer);
|
||||
return luceneSerializer;
|
||||
})
|
||||
.orElseGet(() -> {
|
||||
luceneSerializerReference.set(null);
|
||||
return null;
|
||||
});
|
||||
|
||||
return mockLuceneIndexFactory;
|
||||
});
|
||||
|
||||
doAnswer(invocation -> {
|
||||
|
||||
String indexName = invocation.getArgument(0);
|
||||
String regionPath = invocation.getArgument(1);
|
||||
|
||||
LuceneIndexKey key = LuceneIndexKey.of(indexName, regionPath);
|
||||
|
||||
LuceneIndex mockLuceneIndex = mock(LuceneIndex.class, key.toString());
|
||||
|
||||
when(mockLuceneIndex.getFieldAnalyzers()).thenReturn(Collections.unmodifiableMap(fieldAnalyzers));
|
||||
when(mockLuceneIndex.getFieldNames()).thenAnswer(in -> fields.toArray(new String[fields.size()]));
|
||||
when(mockLuceneIndex.getLuceneSerializer()).thenAnswer(in -> luceneSerializerReference.get());
|
||||
when(mockLuceneIndex.getName()).thenReturn(indexName);
|
||||
when(mockLuceneIndex.getRegionPath()).thenReturn(regionPath);
|
||||
|
||||
Optional.ofNullable(luceneIndexes).ifPresent(it -> it.put(key, mockLuceneIndex));
|
||||
|
||||
return null;
|
||||
|
||||
}).when(mockLuceneIndexFactory).create(anyString(), anyString());
|
||||
|
||||
return mockLuceneIndexFactory;
|
||||
}
|
||||
|
||||
public static LuceneQueryFactory mockLuceneQueryFactory() {
|
||||
|
||||
LuceneQueryFactory mockLuceneQueryFactory = mock(LuceneQueryFactory.class);
|
||||
|
||||
AtomicInteger limit = new AtomicInteger(LuceneQueryFactory.DEFAULT_LIMIT);
|
||||
AtomicInteger pageSize = new AtomicInteger(LuceneQueryFactory.DEFAULT_PAGESIZE);
|
||||
|
||||
when(mockLuceneQueryFactory.setLimit(anyInt())).thenAnswer(invocation -> {
|
||||
limit.set(invocation.getArgument(0));
|
||||
return mockLuceneQueryFactory;
|
||||
});
|
||||
|
||||
when(mockLuceneQueryFactory.setPageSize(anyInt())).thenAnswer(invocation -> {
|
||||
pageSize.set(invocation.getArgument(0));
|
||||
return mockLuceneQueryFactory;
|
||||
});
|
||||
|
||||
when(mockLuceneQueryFactory.create(anyString(), anyString(), any(LuceneQueryProvider.class)))
|
||||
.thenAnswer(invocation -> mockLuceneQuery(limit.get(), pageSize.get()));
|
||||
|
||||
when(mockLuceneQueryFactory.create(anyString(), anyString(), anyString(), anyString()))
|
||||
.thenAnswer(invocation -> mockLuceneQuery(limit.get(), pageSize.get()));
|
||||
|
||||
return mockLuceneQueryFactory;
|
||||
}
|
||||
|
||||
private static LuceneQuery mockLuceneQuery(int limit, int pageSize) {
|
||||
|
||||
LuceneQuery mockLuceneQuery = mock(LuceneQuery.class);
|
||||
|
||||
when(mockLuceneQuery.getLimit()).thenReturn(limit);
|
||||
when(mockLuceneQuery.getPageSize()).thenReturn(pageSize);
|
||||
|
||||
doSafeOperation(() -> when(mockLuceneQuery.findKeys())
|
||||
.thenReturn(Collections.emptySet()), Collections.emptySet());
|
||||
|
||||
rethrowAsRuntimeException(() -> when(mockLuceneQuery.findPages())
|
||||
.thenThrow(newUnsupportedOperationException("Operation Not Supported!")));
|
||||
|
||||
doSafeOperation(() -> when(mockLuceneQuery.findResults())
|
||||
.thenReturn(Collections.emptyList()), Collections.emptyList());
|
||||
|
||||
doSafeOperation(() -> when(mockLuceneQuery.findValues())
|
||||
.thenReturn(Collections.emptyList()), Collections.emptyList());
|
||||
|
||||
return mockLuceneQuery;
|
||||
}
|
||||
|
||||
public static LuceneService mockLuceneService(Cache mockCache) {
|
||||
|
||||
LuceneService mockLuceneService = mock(LuceneService.class);
|
||||
|
||||
Map<LuceneIndexKey, LuceneIndex> luceneIndexes = new ConcurrentHashMap<>();
|
||||
|
||||
when(mockLuceneService.createIndexFactory())
|
||||
.thenAnswer(invocation -> mockLuceneIndexFactory(luceneIndexes));
|
||||
|
||||
when(mockLuceneService.createLuceneQueryFactory())
|
||||
.thenAnswer(invocation -> mockLuceneQueryFactory());
|
||||
|
||||
doAnswer(invocation -> {
|
||||
|
||||
String indexName = invocation.getArgument(0);
|
||||
String regionName = invocation .getArgument(1);
|
||||
|
||||
luceneIndexes.remove(LuceneIndexKey.of(indexName, regionName));
|
||||
|
||||
return null;
|
||||
|
||||
}).when(mockLuceneService).destroyIndex(anyString(), anyString());
|
||||
|
||||
doAnswer(invocation -> {
|
||||
|
||||
String regionPath = invocation.getArgument(0);
|
||||
|
||||
luceneIndexes.keySet().stream().filter(key -> key.getRegionPath().equals(regionPath))
|
||||
.collect(Collectors.toSet()).forEach(key -> luceneIndexes.remove(key));
|
||||
|
||||
return null;
|
||||
|
||||
}).when(mockLuceneService).destroyIndexes(anyString());
|
||||
|
||||
when(mockLuceneService.getAllIndexes()).thenAnswer(invocation ->
|
||||
Collections.unmodifiableCollection(luceneIndexes.values()));
|
||||
|
||||
when(mockLuceneService.getCache()).thenReturn(mockCache);
|
||||
|
||||
when(mockLuceneService.getIndex(anyString(), anyString())).thenAnswer(invocation -> {
|
||||
|
||||
String indexName = invocation.getArgument(0);
|
||||
String regionPath = invocation.getArgument(1);
|
||||
|
||||
return luceneIndexes.get(LuceneIndexKey.of(indexName, regionPath));
|
||||
});
|
||||
|
||||
doSafeOperation(() ->
|
||||
when(mockLuceneService.waitUntilFlushed(anyString(), anyString(), anyLong(), any(TimeUnit.class)))
|
||||
.thenReturn(true));
|
||||
|
||||
return mockLuceneService;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <K, V> Region<K, V> mockRegion(RegionService regionService, String name,
|
||||
RegionAttributes<K, V> regionAttributes) {
|
||||
@@ -2550,7 +2785,78 @@ public abstract class GemFireMockObjectsSupport extends MockObjectsSupport {
|
||||
return clientCacheFactorySpy;
|
||||
}
|
||||
|
||||
protected interface ExceptionThrowingOperation<T> {
|
||||
T doExceptionThrowingOperation() throws Exception;
|
||||
}
|
||||
|
||||
protected interface IoExceptionThrowingOperation {
|
||||
void doIo() throws IOException;
|
||||
}
|
||||
|
||||
public static class LuceneIndexKey {
|
||||
|
||||
private final String indexName;
|
||||
private final String regionPath;
|
||||
|
||||
public static LuceneIndexKey of(String indexName, Region<?, ?> region) {
|
||||
|
||||
Assert.notNull(region, "Region is required");
|
||||
|
||||
return of(indexName, region.getFullPath());
|
||||
}
|
||||
|
||||
public static LuceneIndexKey of(String indexName, String regionPath) {
|
||||
return new LuceneIndexKey(indexName, regionPath);
|
||||
}
|
||||
|
||||
private LuceneIndexKey(String indexName, String regionPath) {
|
||||
|
||||
Assert.hasText(indexName, String.format("LuceneIndex name [%s] is required", indexName));
|
||||
Assert.hasText(regionPath, String.format("Region path [%s] is required", regionPath));
|
||||
|
||||
this.indexName = indexName;
|
||||
this.regionPath = regionPath;
|
||||
}
|
||||
|
||||
protected String getIndexName() {
|
||||
return this.indexName;
|
||||
}
|
||||
|
||||
protected String getRegionPath() {
|
||||
return this.regionPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof LuceneIndexKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LuceneIndexKey that = (LuceneIndexKey) obj;
|
||||
|
||||
return this.getIndexName().equals(that.getIndexName())
|
||||
&& this.getRegionPath().equals(that.getRegionPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int hashValue = 17;
|
||||
|
||||
hashValue = 37 * hashValue + getIndexName().hashCode();
|
||||
hashValue = 37 * hashValue + getRegionPath().hashCode();
|
||||
|
||||
return hashValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%1$s.%2$s", getRegionPath(), getIndexName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,12 @@
|
||||
package org.springframework.data.gemfire.util;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -27,6 +31,7 @@ import static org.springframework.data.gemfire.util.ArrayUtils.asArray;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newRuntimeException;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -35,6 +40,7 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.PropertyValue;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
|
||||
@@ -61,10 +67,12 @@ public class SpringUtilsUnitTests {
|
||||
|
||||
when(mockBeanDefinition.getDependsOn()).thenReturn(asArray("testBeanNameOne", "testBeanNameTwo"));
|
||||
|
||||
assertThat(SpringUtils.addDependsOn(mockBeanDefinition, "testBeanNameThree")).isSameAs(mockBeanDefinition);
|
||||
assertThat(SpringUtils.addDependsOn(mockBeanDefinition, "testBeanNameThree"))
|
||||
.isSameAs(mockBeanDefinition);
|
||||
|
||||
verify(mockBeanDefinition, times(1)).getDependsOn();
|
||||
verify(mockBeanDefinition, times(1)).setDependsOn("testBeanNameOne", "testBeanNameTwo", "testBeanNameThree");
|
||||
verify(mockBeanDefinition, times(1))
|
||||
.setDependsOn("testBeanNameOne", "testBeanNameTwo", "testBeanNameThree");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -72,7 +80,8 @@ public class SpringUtilsUnitTests {
|
||||
|
||||
when(mockBeanDefinition.getDependsOn()).thenReturn(null);
|
||||
|
||||
assertThat(SpringUtils.addDependsOn(mockBeanDefinition, "testBeanName")).isSameAs(mockBeanDefinition);
|
||||
assertThat(SpringUtils.addDependsOn(mockBeanDefinition, "testBeanName"))
|
||||
.isSameAs(mockBeanDefinition);
|
||||
|
||||
verify(mockBeanDefinition, times(1)).getDependsOn();
|
||||
verify(mockBeanDefinition, times(1)).setDependsOn("testBeanName");
|
||||
@@ -91,6 +100,69 @@ public class SpringUtilsUnitTests {
|
||||
.setDependsOn("testBeanNameOne", "testBeanNameTwo", "testBeanNameThree", "testBeanNameFour");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPropertyValueForExistingPropertyHavingValueReturnsValue() {
|
||||
|
||||
MutablePropertyValues propertyValues =
|
||||
new MutablePropertyValues(Collections.singletonMap("testProperty", "testValue"));
|
||||
|
||||
when(mockBeanDefinition.getPropertyValues()).thenReturn(propertyValues);
|
||||
|
||||
assertThat(SpringUtils.getPropertyValue(mockBeanDefinition, "testProperty").orElse(null))
|
||||
.isEqualTo("testValue");
|
||||
|
||||
verify(mockBeanDefinition, times(1)).getPropertyValues();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPropertyValueForExistingPropertyHavingNullValueReturnsNull() {
|
||||
|
||||
MutablePropertyValues testPropertyValues = spy(new MutablePropertyValues());
|
||||
|
||||
PropertyValue testPropertyValue = spy(new PropertyValue("testProperty", null));
|
||||
|
||||
when(mockBeanDefinition.getPropertyValues()).thenReturn(testPropertyValues);
|
||||
doReturn(testPropertyValue).when(testPropertyValues).getPropertyValue(anyString());
|
||||
|
||||
assertThat(SpringUtils.getPropertyValue(mockBeanDefinition, "testProperty").orElse(null))
|
||||
.isNull();
|
||||
|
||||
verify(mockBeanDefinition, times(1)).getPropertyValues();
|
||||
verify(testPropertyValues, times(1)).getPropertyValue(eq("testProperty"));
|
||||
verify(testPropertyValue, times(1)).getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPropertyValueForNonExistingPropertyReturnsNull() {
|
||||
|
||||
MutablePropertyValues testPropertyValues = spy(new MutablePropertyValues());
|
||||
|
||||
when(mockBeanDefinition.getPropertyValues()).thenReturn(testPropertyValues);
|
||||
|
||||
assertThat(SpringUtils.getPropertyValue(mockBeanDefinition, "testProperty").orElse(null))
|
||||
.isNull();
|
||||
|
||||
verify(mockBeanDefinition, times(1)).getPropertyValues();
|
||||
verify(testPropertyValues, times(1)).getPropertyValue(eq("testProperty"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPropertyValueWithNullPropertyValuesReturnsNull() {
|
||||
|
||||
when(mockBeanDefinition.getPropertyValues()).thenReturn(null);
|
||||
|
||||
assertThat(SpringUtils.getPropertyValue(mockBeanDefinition, "testProperty").orElse(null))
|
||||
.isNull();
|
||||
|
||||
verify(mockBeanDefinition, times(1)).getPropertyValues();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPropertyValueWithNullBeanDefinitionReturnsNull() {
|
||||
assertThat(SpringUtils.getPropertyValue(null, "testProperty").orElse(null))
|
||||
.isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("all")
|
||||
public void setBeanDefinitionPropertyReference() {
|
||||
@@ -135,6 +207,7 @@ public class SpringUtilsUnitTests {
|
||||
|
||||
@Test
|
||||
public void defaultIfEmptyReturnsValue() {
|
||||
|
||||
assertThat(SpringUtils.defaultIfEmpty("test", "DEFAULT")).isEqualTo("test");
|
||||
assertThat(SpringUtils.defaultIfEmpty("abc123", "DEFAULT")).isEqualTo("abc123");
|
||||
assertThat(SpringUtils.defaultIfEmpty("123", "DEFAULT")).isEqualTo("123");
|
||||
@@ -147,6 +220,7 @@ public class SpringUtilsUnitTests {
|
||||
|
||||
@Test
|
||||
public void defaultIfEmptyReturnsDefault() {
|
||||
|
||||
assertThat(SpringUtils.defaultIfEmpty(" ", "DEFAULT")).isEqualTo("DEFAULT");
|
||||
assertThat(SpringUtils.defaultIfEmpty("", "DEFAULT")).isEqualTo("DEFAULT");
|
||||
assertThat(SpringUtils.defaultIfEmpty(null, "DEFAULT")).isEqualTo("DEFAULT");
|
||||
@@ -154,6 +228,7 @@ public class SpringUtilsUnitTests {
|
||||
|
||||
@Test
|
||||
public void defaultIfNullReturnsValue() {
|
||||
|
||||
assertThat(SpringUtils.defaultIfNull(true, false)).isTrue();
|
||||
assertThat(SpringUtils.defaultIfNull('x', 'A')).isEqualTo('x');
|
||||
assertThat(SpringUtils.defaultIfNull(1, 2)).isEqualTo(1);
|
||||
@@ -163,6 +238,7 @@ public class SpringUtilsUnitTests {
|
||||
|
||||
@Test
|
||||
public void defaultIfNullReturnsDefault() {
|
||||
|
||||
assertThat(SpringUtils.defaultIfNull(null, false)).isFalse();
|
||||
assertThat(SpringUtils.defaultIfNull(null, 'A')).isEqualTo('A');
|
||||
assertThat(SpringUtils.defaultIfNull(null, 2)).isEqualTo(2);
|
||||
@@ -173,6 +249,7 @@ public class SpringUtilsUnitTests {
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void defaultIfNullWithSupplierReturnsValue() {
|
||||
|
||||
Supplier<String> mockSupplier = mock(Supplier.class);
|
||||
|
||||
assertThat(SpringUtils.defaultIfNull("value", mockSupplier)).isEqualTo("value");
|
||||
@@ -183,6 +260,7 @@ public class SpringUtilsUnitTests {
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void defaultIfNullWithSupplierReturnsSupplierValue() {
|
||||
|
||||
Supplier<String> mockSupplier = mock(Supplier.class);
|
||||
|
||||
when(mockSupplier.get()).thenReturn("supplier");
|
||||
@@ -199,6 +277,7 @@ public class SpringUtilsUnitTests {
|
||||
|
||||
@Test
|
||||
public void equalsIgnoreNullIsTrue() {
|
||||
|
||||
assertThat(SpringUtils.equalsIgnoreNull(null, null)).isTrue();
|
||||
assertThat(SpringUtils.equalsIgnoreNull(true, true)).isTrue();
|
||||
assertThat(SpringUtils.equalsIgnoreNull('x', 'x')).isTrue();
|
||||
@@ -210,6 +289,7 @@ public class SpringUtilsUnitTests {
|
||||
|
||||
@Test
|
||||
public void equalsIgnoreNullIsFalse() {
|
||||
|
||||
assertThat(SpringUtils.equalsIgnoreNull(null, "null")).isFalse();
|
||||
assertThat(SpringUtils.equalsIgnoreNull(true, false)).isFalse();
|
||||
assertThat(SpringUtils.equalsIgnoreNull('x', 'X')).isFalse();
|
||||
|
||||
Reference in New Issue
Block a user