/*
* Copyright 2016 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.search.lucene;
import static org.assertj.core.api.Java6Assertions.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.doReturn;
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.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.lucene.LuceneIndex;
import org.apache.geode.cache.lucene.LuceneService;
import org.apache.lucene.analysis.Analyzer;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
/**
* Unit tests for {@link LuceneIndexFactoryBean}.
*
* @author John Blum
* @see org.junit.Rule
* @see org.junit.Test
* @see org.junit.runner.RunWith
* @see org.mockito.Mock
* @see org.mockito.Mockito
* @see org.mockito.Spy
* @see org.mockito.junit.MockitoJUnitRunner
* @see org.springframework.data.gemfire.search.lucene.LuceneIndexFactoryBean
* @since 1.1.0
*/
@RunWith(MockitoJUnitRunner.class)
public class LuceneIndexFactoryBeanUnitTests {
@Rule
public ExpectedException exception = ExpectedException.none();
@Mock
private Analyzer mockAnalyzer;
@Mock
private BeanFactory mockBeanFactory;
@Mock
private GemFireCache mockCache;
@Mock
private LuceneIndex mockLuceneIndex;
@Mock
private LuceneService mockLuceneService;
@Mock
private Region<Object, Object> mockRegion;
private LuceneIndexFactoryBean factoryBean;
@Before
public void setup() {
factoryBean = spy(new LuceneIndexFactoryBean());
}
@Test
public void afterPropertiesSetResolvesCacheLuceneServiceRegionPathAndCreatesLuceneIndex() throws Exception {
doReturn(mockCache).when(factoryBean).resolveCache();
doReturn(mockLuceneService).when(factoryBean).resolveLuceneService();
doReturn("/Example").when(factoryBean).resolveRegionPath();
doReturn(mockLuceneIndex).when(factoryBean).createIndex(eq("ExampleIndex"), eq("/Example"));
factoryBean.setIndexName("ExampleIndex");
assertThat(factoryBean.getIndexName()).isEqualTo("ExampleIndex");
factoryBean.afterPropertiesSet();
assertThat(factoryBean.getObject()).isEqualTo(mockLuceneIndex);
verify(factoryBean, times(1)).resolveCache();
verify(factoryBean, times(1)).resolveLuceneService();
verify(factoryBean, times(1)).resolveRegionPath();
verify(factoryBean, times(1))
.createIndex(eq("ExampleIndex"), eq("/Example"));
}
@Test
public void afterPropertiesSetThrowsIllegalStateExceptionIndexNameNotSet() throws Exception {
exception.expect(IllegalStateException.class);
exception.expectCause(is(nullValue(Throwable.class)));
exception.expectMessage("indexName was not properly initialized");
factoryBean.afterPropertiesSet();
}
@Test
public void createIndexWithAllFields() {
factoryBean.setLuceneService(mockLuceneService);
when(mockLuceneService.getIndex(eq("ExampleIndex"), eq("/Example"))).thenReturn(mockLuceneIndex);
assertThat(factoryBean.getFieldAnalyzers()).isEmpty();
assertThat(factoryBean.getFields()).isEmpty();
assertThat(factoryBean.getLuceneService()).isSameAs(mockLuceneService);
assertThat(factoryBean.createIndex("ExampleIndex", "/Example")).isEqualTo(mockLuceneIndex);
verify(mockLuceneService, times(1))
.createIndex(eq("ExampleIndex"), eq("/Example"), eq(LuceneService.REGION_VALUE_FIELD));
verify(mockLuceneService, times(1))
.getIndex(eq("ExampleIndex"), eq("/Example"));
}
@Test
public void createIndexWithFieldAnalyzers() {
Map<String, Analyzer> fieldAnalyzers = Collections.singletonMap("fieldOne", mockAnalyzer);
factoryBean.setFieldAnalyzers(fieldAnalyzers);
factoryBean.setLuceneService(mockLuceneService);
when(mockLuceneService.getIndex(eq("ExampleIndex"), eq("/Example"))).thenReturn(mockLuceneIndex);
assertThat(factoryBean.getFieldAnalyzers()).isEqualTo(fieldAnalyzers);
assertThat(factoryBean.getFields()).isEmpty();
assertThat(factoryBean.getLuceneService()).isSameAs(mockLuceneService);
assertThat(factoryBean.createIndex("ExampleIndex", "/Example")).isEqualTo(mockLuceneIndex);
verify(mockLuceneService, times(1))
.createIndex(eq("ExampleIndex"), eq("/Example"), eq(fieldAnalyzers));
verify(mockLuceneService, times(1))
.getIndex(eq("ExampleIndex"), eq("/Example"));
}
@Test
public void createIndexWithTargetedFields() {
factoryBean.setFields("fieldOne", "fieldTwo");
factoryBean.setLuceneService(mockLuceneService);
when(mockLuceneService.getIndex(eq("ExampleIndex"), eq("/Example"))).thenReturn(mockLuceneIndex);
assertThat(factoryBean.getFieldAnalyzers()).isEmpty();
assertThat(factoryBean.getFields()).containsAll(Arrays.asList("fieldOne", "fieldTwo"));
assertThat(factoryBean.getLuceneService()).isSameAs(mockLuceneService);
assertThat(factoryBean.createIndex("ExampleIndex", "/Example")).isEqualTo(mockLuceneIndex);
verify(mockLuceneService, times(1))
.createIndex(eq("ExampleIndex"), eq("/Example"), eq("fieldOne"), eq("fieldTwo"));
verify(mockLuceneService, times(1))
.getIndex(eq("ExampleIndex"), eq("/Example"));
}
@Test
@SuppressWarnings("deprecation")
public void destroyIsSuccessful() throws Exception {
factoryBean.setDestroy(true);
factoryBean.setLuceneService(mockLuceneService);
assertThat(factoryBean.isDestroy()).isTrue();
assertThat(factoryBean.getLuceneService()).isSameAs(mockLuceneService);
doReturn(mockLuceneIndex).when(factoryBean).getObject();
factoryBean.destroy();
verify(factoryBean, times(1)).getObject();
verify(mockLuceneService, times(1)).destroyIndex(eq(mockLuceneIndex));
}
@Test
@SuppressWarnings("deprecation")
public void destroyDoesNothingWhenDestroyIsFalse() throws Exception {
factoryBean.setDestroy(false);
factoryBean.setLuceneService(mockLuceneService);
assertThat(factoryBean.isDestroy()).isFalse();
assertThat(factoryBean.getLuceneService()).isSameAs(mockLuceneService);
doReturn(mockLuceneIndex).when(factoryBean).getObject();
factoryBean.destroy();
verify(factoryBean, times(1)).getObject();
verify(mockLuceneService, never()).destroyIndex(any(LuceneIndex.class));
}
@Test
@SuppressWarnings("deprecation")
public void destroyDoesNothingWhenLuceneIndexIsNull() throws Exception {
factoryBean.setDestroy(true);
factoryBean.setLuceneService(mockLuceneService);
assertThat(factoryBean.isDestroy()).isTrue();
assertThat(factoryBean.getLuceneService()).isSameAs(mockLuceneService);
doReturn(null).when(factoryBean).getObject();
factoryBean.destroy();
verify(factoryBean, times(1)).getObject();
verify(mockLuceneService, never()).destroyIndex(isNull(LuceneIndex.class));
}
@Test
public void isLuceneIndexDestroyableReturnsTrue() {
factoryBean.setDestroy(true);
assertThat(factoryBean.isDestroy()).isTrue();
assertThat(factoryBean.isLuceneIndexDestroyable(mockLuceneIndex)).isTrue();
}
@Test
public void isLuceneIndexDestroyableWhenDestroyIsFalseReturnsFalse() {
factoryBean.setDestroy(false);
assertThat(factoryBean.isDestroy()).isFalse();
assertThat(factoryBean.isLuceneIndexDestroyable(mockLuceneIndex)).isFalse();
}
@Test
public void isLuceneIndexDestroyableWhenLuceneIndexIsNullReturnsFalse() {
factoryBean.setDestroy(true);
assertThat(factoryBean.isDestroy()).isTrue();
assertThat(factoryBean.isLuceneIndexDestroyable(null)).isFalse();
}
@Test
public void getObjectReturnsLuceneIndexFromLuceneService() throws Exception {
factoryBean.setCache(mockCache);
factoryBean.setIndexName("ExampleIndex");
factoryBean.setLuceneService(mockLuceneService);
factoryBean.setRegionPath("/Example");
when(mockLuceneService.getIndex(eq("ExampleIndex"), eq("/Example"))).thenReturn(mockLuceneIndex);
assertThat(factoryBean.getCache()).isSameAs(mockCache);
assertThat(factoryBean.getIndexName()).isEqualTo("ExampleIndex");
assertThat(factoryBean.getLuceneService()).isSameAs(mockLuceneService);
assertThat(factoryBean.getRegionPath()).isEqualTo("/Example");
assertThat(factoryBean.getObject()).isEqualTo(mockLuceneIndex);
verify(mockLuceneService, times(1))
.getIndex(eq("ExampleIndex"), eq("/Example"));
}
@Test
public void getObjectReturnsExistingLuceneIndex() throws Exception {
factoryBean.setLuceneIndex(mockLuceneIndex);
factoryBean.setLuceneService(mockLuceneService);
assertThat(factoryBean.getObject()).isSameAs(mockLuceneIndex);
verify(mockLuceneService, never()).getIndex(anyString(), anyString());
}
@Test
public void getObjectReturnsNullWhenLuceneServiceIsNull() throws Exception {
factoryBean.setCache(mockCache);
factoryBean.setRegionPath("/Example");
doReturn(null).when(factoryBean).resolveLuceneService(eq(mockCache));
assertThat(factoryBean.getCache()).isSameAs(mockCache);
assertThat(factoryBean.getLuceneService()).isNull();
assertThat(factoryBean.getRegionPath()).isEqualTo("/Example");
assertThat(factoryBean.getObject()).isNull();
verify(factoryBean, times(1)).resolveLuceneService();
verify(factoryBean, times(1)).resolveLuceneService(eq(mockCache));
}
@Test
public void getObjectTypeBeforeInitialization() {
assertThat(factoryBean.getObjectType()).isEqualTo(LuceneIndex.class);
}
@Test
public void getObjectTypeAfterInitialization() {
assertThat(factoryBean.setLuceneIndex(mockLuceneIndex).getObjectType()).isEqualTo(mockLuceneIndex.getClass());
}
@Test
public void isSingletonReturnsTrue() {
assertThat(factoryBean.isSingleton()).isTrue();
}
@Test
public void resolveCacheReturnsConfiguredCache() {
factoryBean.setCache(mockCache);
assertThat(factoryBean.getCache()).isSameAs(mockCache);
assertThat(factoryBean.resolveCache()).isSameAs(mockCache);
}
@Test
public void resolveFieldsReturnsGivenFields() {
List<String> expectedFields = Arrays.asList("fieldOne", "fieldTwo");
assertThat(factoryBean.resolveFields(expectedFields)).isSameAs(expectedFields);
}
@Test
public void resolveFieldsWithEmptyListReturnsAllFields() {
assertThat(factoryBean.resolveFields(Collections.emptyList()))
.isEqualTo(Collections.singletonList(LuceneService.REGION_VALUE_FIELD));
}
@Test
public void resolveFieldsWithNullReturnsAllFields() {
assertThat(factoryBean.resolveFields(null))
.isEqualTo(Collections.singletonList(LuceneService.REGION_VALUE_FIELD));
}
@Test
public void resolveLuceneServiceReturnsConfiguredLuceneService() {
factoryBean.setBeanFactory(mockBeanFactory);
factoryBean.setCache(mockCache);
factoryBean.setLuceneService(mockLuceneService);
assertThat(factoryBean.getBeanFactory()).isSameAs(mockBeanFactory);
assertThat(factoryBean.getCache()).isSameAs(mockCache);
assertThat(factoryBean.getLuceneService()).isSameAs(mockLuceneService);
assertThat(factoryBean.resolveLuceneService()).isSameAs(mockLuceneService);
verifyZeroInteractions(mockBeanFactory);
verifyZeroInteractions(mockCache);
verify(factoryBean, never()).resolveLuceneService(any(GemFireCache.class));
}
@Test
public void resolveLuceneServiceFromBeanFactory() {
factoryBean.setBeanFactory(mockBeanFactory);
factoryBean.setCache(mockCache);
when(mockBeanFactory.getBean(eq(LuceneService.class))).thenReturn(mockLuceneService);
assertThat(factoryBean.getBeanFactory()).isSameAs(mockBeanFactory);
assertThat(factoryBean.getCache()).isSameAs(mockCache);
assertThat(factoryBean.getLuceneService()).isNull();
assertThat(factoryBean.resolveLuceneService()).isSameAs(mockLuceneService);
verify(mockBeanFactory, times(1)).getBean(eq(LuceneService.class));
verifyZeroInteractions(mockCache);
verify(factoryBean, never()).resolveLuceneService(any(GemFireCache.class));
}
@Test
public void resolveLuceneServiceFromGemFireCache() {
factoryBean.setCache(mockCache);
doReturn(mockLuceneService).when(factoryBean).resolveLuceneService(eq(mockCache));
assertThat(factoryBean.getBeanFactory()).isNull();
assertThat(factoryBean.getCache()).isSameAs(mockCache);
assertThat(factoryBean.getLuceneService()).isNull();
assertThat(factoryBean.resolveLuceneService()).isSameAs(mockLuceneService);
verifyZeroInteractions(mockCache);
verify(factoryBean, times(1)).resolveLuceneService(eq(mockCache));
}
@Test
@SuppressWarnings("unchecked")
public void resolveLuceneServiceFromGemFireCacheWithBeanFactoryThrowinBeansException() {
factoryBean.setBeanFactory(mockBeanFactory);
factoryBean.setCache(mockCache);
when(mockBeanFactory.getBean(any(Class.class))).thenThrow(new NoSuchBeanDefinitionException("test"));
doReturn(mockLuceneService).when(factoryBean).resolveLuceneService(eq(mockCache));
assertThat(factoryBean.getBeanFactory()).isSameAs(mockBeanFactory);
assertThat(factoryBean.getCache()).isSameAs(mockCache);
assertThat(factoryBean.getLuceneService()).isNull();
assertThat(factoryBean.resolveLuceneService()).isSameAs(mockLuceneService);
verify(mockBeanFactory, times(1)).getBean(eq(LuceneService.class));
verifyZeroInteractions(mockCache);
verify(factoryBean, times(1)).resolveLuceneService(eq(mockCache));
}
@Test
public void resolveLuceneServiceThrowsIllegalArgumentExceptionWhenGemFireCacheIsNotConfigured() {
exception.expect(IllegalArgumentException.class);
exception.expectCause(is(nullValue(Throwable.class)));
exception.expectMessage("A reference to the GemFireCache was not properly configured");
factoryBean.resolveLuceneService(null);
}
@Test
@SuppressWarnings("all")
public void resolveRegionReturnsConfiguredRegion() {
factoryBean.setRegion(mockRegion);
assertThat(factoryBean.resolveRegion()).isSameAs(mockRegion);
verify(factoryBean, times(1)).getRegion();
verify(factoryBean, never()).resolveCache();
verify(factoryBean, never()).getRegionPath();
}
@Test
@SuppressWarnings("all")
public void resolveRegionReturnsRegionFromCache() {
factoryBean.setRegionPath("/Example");
doReturn(mockCache).when(factoryBean).resolveCache();
when(mockCache.getRegion(eq("/Example"))).thenReturn(mockRegion);
assertThat(factoryBean.resolveRegion()).isEqualTo(mockRegion);
verify(factoryBean, times(1)).getRegion();
verify(factoryBean, times(1)).resolveCache();
verify(factoryBean, times(1)).getRegionPath();
verify(mockCache, times(1)).getRegion(eq("/Example"));
}
@Test
@SuppressWarnings("all")
public void resolveRegionReturnsNullWhenCacheNotConfigured() {
factoryBean.setRegionPath("/Example");
doReturn(null).when(factoryBean).resolveCache();
assertThat(factoryBean.resolveRegion()).isNull();
verify(factoryBean, times(1)).getRegion();
verify(factoryBean, times(1)).resolveCache();
verify(factoryBean, times(1)).getRegionPath();
}
@Test
@SuppressWarnings("all")
public void resolveRegionReturnsNullWhenRegionPathNotConfigured() {
factoryBean.setCache(mockCache);
factoryBean.setRegionPath(" ");
assertThat(factoryBean.resolveRegion()).isNull();
verify(factoryBean, times(1)).getRegion();
verify(factoryBean, times(1)).resolveCache();
verify(factoryBean, times(1)).getRegionPath();
verify(mockCache, never()).getRegion(anyString());
}
@Test
@SuppressWarnings("all")
public void resolveRegionPathReturnsConfiguredRegionPath() {
factoryBean.setRegionPath("/Example");
doReturn(null).when(factoryBean).resolveRegion();
assertThat(factoryBean.resolveRegionPath()).isEqualTo("/Example");
verify(factoryBean, times(1)).resolveRegion();
verify(factoryBean, times(1)).getRegionPath();
}
@Test
@SuppressWarnings("all")
public void resolveRegionPathReturnsRegionFullPath() {
doReturn(mockRegion).when(factoryBean).resolveRegion();
when(mockRegion.getFullPath()).thenReturn("/Example");
assertThat(factoryBean.resolveRegionPath()).isEqualTo("/Example");
verify(factoryBean, times(1)).resolveRegion();
verify(factoryBean, never()).getRegionPath();
verify(mockRegion, times(1)).getFullPath();
}
@Test
@SuppressWarnings("all")
public void resolveRegionPathThrowsIllegalStateException() {
doReturn(null).when(factoryBean).resolveRegion();
factoryBean.setRegionPath(null);
try {
exception.expect(IllegalStateException.class);
exception.expectCause(is(nullValue(Throwable.class)));
exception.expectMessage("Either Region or regionPath must be specified");
factoryBean.resolveRegionPath();
}
finally {
verify(factoryBean, times(1)).resolveRegion();
verify(factoryBean, times(1)).getRegionPath();
}
}
@Test
public void setAndGetFieldAnalyzers() {
Map<String, Analyzer> fieldAnalyzers = factoryBean.getFieldAnalyzers();
assertThat(fieldAnalyzers).isNotNull();
assertThat(fieldAnalyzers).isEmpty();
fieldAnalyzers = Collections.singletonMap("mockField", mockAnalyzer);
factoryBean.setFieldAnalyzers(fieldAnalyzers);
assertThat(factoryBean.getFieldAnalyzers()).isEqualTo(fieldAnalyzers);
factoryBean.setFieldAnalyzers(null);
fieldAnalyzers = factoryBean.getFieldAnalyzers();
assertThat(fieldAnalyzers).isNotNull();
assertThat(fieldAnalyzers).isEmpty();
}
@Test
public void setAndGetFields() {
List<String> fields = factoryBean.getFields();
assertThat(fields).isNotNull();
assertThat(fields).isEmpty();
factoryBean.setFields(Arrays.asList("fieldOne", "fieldTwo"));
assertThat(factoryBean.getFields()).containsAll(Arrays.asList("fieldOne", "fieldTwo"));
factoryBean.setFields((String[]) null);
fields = factoryBean.getFields();
assertThat(fields).isNotNull();
assertThat(fields).isEmpty();
}
@Test
public void setAndGetIndexName() {
factoryBean.setBeanName("IndexOne");
assertThat(factoryBean.getIndexName()).isEqualTo("IndexOne");
factoryBean.setIndexName("IndexTwo");
assertThat(factoryBean.getIndexName()).isEqualTo("IndexTwo");
factoryBean.setIndexName(null);
}
@Test
public void getUninitializedIndexName() {
exception.expect(IllegalStateException.class);
exception.expectCause(is(nullValue(Throwable.class)));
exception.expectMessage("indexName was not properly initialized");
factoryBean.getIndexName();
}
@Test
public void factoryBeanInitializationIsSuccessful() {
factoryBean.setCache(mockCache);
factoryBean.setDestroy(true);
factoryBean.setFieldAnalyzers(Collections.singletonMap("fieldThree", mockAnalyzer));
factoryBean.setFields("fieldOne", "fieldTwo");
factoryBean.setIndexName("TestIndex");
factoryBean.setLuceneService(mockLuceneService);
factoryBean.setRegion(mockRegion);
factoryBean.setRegionPath("/Grandparent/Parent/Child");
assertThat(factoryBean.getCache()).isSameAs(mockCache);
assertThat(factoryBean.isDestroy()).isTrue();
assertThat(factoryBean.getFieldAnalyzers()).isEqualTo(Collections.singletonMap("fieldThree", mockAnalyzer));
assertThat(factoryBean.getFields()).containsAll(Arrays.asList("fieldOne", "fieldTwo"));
assertThat(factoryBean.getIndexName()).isEqualTo("TestIndex");
assertThat(factoryBean.getLuceneService()).isSameAs(mockLuceneService);
assertThat(factoryBean.getRegion()).isSameAs(mockRegion);
assertThat(factoryBean.getRegionPath()).isEqualTo("/Grandparent/Parent/Child");
}
}