GEODE-11: Fixing a class cast exception when LuceneFunction has an error LuceneFunction was using sendException to return exceptions to caller. But the behavior of sendException is actually to pass the exception to the addResult method, which is not what we want in this case.
Adding an integration test of the same. Changing LuceneFunctionJUnitTest to use mockito and changing the expectations of what LuceneFunction will do after an exception. Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/b3ef7913 Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/b3ef7913 Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/b3ef7913 Branch: refs/heads/feature/GEODE-1276 Commit: b3ef791346b248ea81b4da989ba7759c75c7d92d Parents: 0481732 Author: Dan Smith <upthewatersp...@apache.org> Authored: Mon May 2 14:54:07 2016 -0700 Committer: Dan Smith <upthewatersp...@apache.org> Committed: Tue May 3 16:41:37 2016 -0700 ---------------------------------------------------------------------- .../internal/distributed/CollectorManager.java | 3 +- .../internal/distributed/LuceneFunction.java | 31 +- .../distributed/TopEntriesCollectorManager.java | 2 +- .../TopEntriesFunctionCollector.java | 9 +- .../lucene/LuceneQueriesIntegrationTest.java | 88 ++++ .../distributed/LuceneFunctionJUnitTest.java | 406 ++++++------------- .../TopEntriesFunctionCollectorJUnitTest.java | 4 +- 7 files changed, 236 insertions(+), 307 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b3ef7913/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/CollectorManager.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/CollectorManager.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/CollectorManager.java index 45750d1..4d1d1c2 100644 --- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/CollectorManager.java +++ b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/CollectorManager.java @@ -49,7 +49,6 @@ public interface CollectorManager<C extends IndexResultCollector> { * Reduce the results of individual collectors into a meaningful result. This method must be called after collection * is finished on all provided collectors. * - * @throws IOException */ - C reduce(Collection<C> results) throws IOException; + C reduce(Collection<C> results); } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b3ef7913/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunction.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunction.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunction.java index 199b698..9567305 100644 --- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunction.java +++ b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunction.java @@ -29,6 +29,7 @@ import org.apache.lucene.search.Query; import com.gemstone.gemfire.cache.Region; import com.gemstone.gemfire.cache.execute.FunctionAdapter; import com.gemstone.gemfire.cache.execute.FunctionContext; +import com.gemstone.gemfire.cache.execute.FunctionException; import com.gemstone.gemfire.cache.execute.RegionFunctionContext; import com.gemstone.gemfire.cache.execute.ResultSender; import com.gemstone.gemfire.cache.lucene.LuceneQueryProvider; @@ -41,6 +42,7 @@ import com.gemstone.gemfire.cache.lucene.internal.repository.RepositoryManager; import com.gemstone.gemfire.cache.query.QueryException; import com.gemstone.gemfire.internal.InternalEntity; import com.gemstone.gemfire.internal.cache.BucketNotFoundException; +import com.gemstone.gemfire.internal.cache.execute.BucketMovedException; import com.gemstone.gemfire.internal.logging.LogService; /** @@ -63,14 +65,12 @@ public class LuceneFunction extends FunctionAdapter implements InternalEntity { LuceneFunctionContext<IndexResultCollector> searchContext = (LuceneFunctionContext) ctx.getArguments(); if (searchContext == null) { - resultSender.sendException(new IllegalArgumentException("Missing search context")); - return; + throw new IllegalArgumentException("Missing search context"); } LuceneQueryProvider queryProvider = searchContext.getQueryProvider(); if (queryProvider == null) { - resultSender.sendException(new IllegalArgumentException("Missing query provider")); - return; + throw new IllegalArgumentException("Missing query provider"); } LuceneService service = LuceneServiceProvider.get(region.getCache()); @@ -81,8 +81,8 @@ public class LuceneFunction extends FunctionAdapter implements InternalEntity { try { query = queryProvider.getQuery(index); } catch (QueryException e) { - resultSender.sendException(e); - return; + logger.warn("", e); + throw new FunctionException(e); } if (logger.isDebugEnabled()) { @@ -104,24 +104,11 @@ public class LuceneFunction extends FunctionAdapter implements InternalEntity { repo.query(query, resultLimit, collector); results.add(collector); } - } catch (IOException e) { - logger.warn("", e); - resultSender.sendException(e); - return; - } catch (BucketNotFoundException e) { - logger.warn("", e); - resultSender.sendException(e); - return; - } - - TopEntriesCollector mergedResult; - try { - mergedResult = (TopEntriesCollector) manager.reduce(results); + TopEntriesCollector mergedResult = (TopEntriesCollector) manager.reduce(results); resultSender.lastResult(mergedResult); - } catch (IOException e) { + } catch (IOException|BucketNotFoundException e) { logger.warn("", e); - resultSender.sendException(e); - return; + throw new FunctionException(e); } } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b3ef7913/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/TopEntriesCollectorManager.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/TopEntriesCollectorManager.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/TopEntriesCollectorManager.java index b19e104..cf6e420 100644 --- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/TopEntriesCollectorManager.java +++ b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/TopEntriesCollectorManager.java @@ -68,7 +68,7 @@ public class TopEntriesCollectorManager implements CollectorManager<TopEntriesCo } @Override - public TopEntriesCollector reduce(Collection<TopEntriesCollector> collectors) throws IOException { + public TopEntriesCollector reduce(Collection<TopEntriesCollector> collectors) { TopEntriesCollector mergedResult = new TopEntriesCollector(id, limit); if (collectors.isEmpty()) { return mergedResult; http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b3ef7913/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/TopEntriesFunctionCollector.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/TopEntriesFunctionCollector.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/TopEntriesFunctionCollector.java index 2e8f2dc..4a99bf8 100644 --- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/TopEntriesFunctionCollector.java +++ b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/distributed/TopEntriesFunctionCollector.java @@ -123,13 +123,8 @@ public class TopEntriesFunctionCollector implements ResultCollector<TopEntriesCo return mergedResults.getEntries(); } - try { - mergedResults = manager.reduce(subResults); - return mergedResults.getEntries(); - } catch (IOException e) { - logger.debug("Error while merging function execution results", e); - throw new FunctionException(e); - } + mergedResults = manager.reduce(subResults); + return mergedResults.getEntries(); } } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b3ef7913/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/LuceneQueriesIntegrationTest.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/LuceneQueriesIntegrationTest.java b/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/LuceneQueriesIntegrationTest.java new file mode 100644 index 0000000..9009e3d --- /dev/null +++ b/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/LuceneQueriesIntegrationTest.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 com.gemstone.gemfire.cache.lucene; + +import static org.hamcrest.Matchers.isA; +import static org.junit.Assert.*; + +import com.gemstone.gemfire.cache.Cache; +import com.gemstone.gemfire.cache.CacheFactory; +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.RegionShortcut; +import com.gemstone.gemfire.cache.execute.Function; +import com.gemstone.gemfire.cache.execute.FunctionException; +import com.gemstone.gemfire.cache.query.QueryException; +import com.gemstone.gemfire.test.junit.categories.IntegrationTest; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.ExpectedException; + +/** + * This class contains tests of lucene queries that can fit + */ +@Category(IntegrationTest.class) +public class LuceneQueriesIntegrationTest { + @Rule + public ExpectedException thrown = ExpectedException.none(); + private static final String INDEX_NAME = "index"; + protected static final String REGION_NAME = "index"; + Cache cache; + + @Before + public void createCache() { + cache = new CacheFactory() + .set("mcast-port", "0") + .set("locators", "") + .set("log-level", "warning").create(); + } + + @After + public void closeCache() { + cache.close(); + } + + @Test() + public void throwFunctionExceptionWhenGivenBadQuery() { + LuceneService luceneService = LuceneServiceProvider.get(cache); + luceneService.createIndex(INDEX_NAME, REGION_NAME, "text"); + Region region = cache.createRegionFactory(RegionShortcut.PARTITION) + .create(REGION_NAME); + + //Create a query that throws an exception + final LuceneQuery<Object, Object> query = luceneService.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, + index -> { + throw new QueryException("Bad query"); + }); + + + thrown.expect(FunctionException.class); + thrown.expectCause(isA(QueryException.class)); + try { + query.search(); + } catch(FunctionException e) { + assertEquals(QueryException.class, e.getCause().getClass()); + throw e; + } + + } + + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b3ef7913/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunctionJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunctionJUnitTest.java b/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunctionJUnitTest.java index 750ec0f..70ec434 100644 --- a/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunctionJUnitTest.java +++ b/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/LuceneFunctionJUnitTest.java @@ -19,27 +19,16 @@ package com.gemstone.gemfire.cache.lucene.internal.distributed; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.concurrent.atomic.AtomicReference; - -import org.apache.lucene.search.Query; -import org.jmock.Expectations; -import org.jmock.Mockery; -import org.jmock.api.Invocation; -import org.jmock.lib.action.CustomAction; -import org.jmock.lib.concurrent.Synchroniser; -import org.jmock.lib.legacy.ClassImposteriser; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.categories.Category; import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.execute.FunctionException; import com.gemstone.gemfire.cache.execute.ResultSender; import com.gemstone.gemfire.cache.lucene.LuceneQueryFactory; import com.gemstone.gemfire.cache.lucene.LuceneQueryProvider; @@ -55,9 +44,14 @@ import com.gemstone.gemfire.internal.cache.InternalCache; import com.gemstone.gemfire.internal.cache.execute.InternalRegionFunctionContext; import com.gemstone.gemfire.test.junit.categories.UnitTest; +import org.apache.lucene.search.Query; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.mockito.ArgumentCaptor; + @Category(UnitTest.class) public class LuceneFunctionJUnitTest { - Mockery mocker; String regionPath = "/region"; String indexName = "index"; @@ -87,275 +81,162 @@ public class LuceneFunctionJUnitTest { @Test public void testRepoQueryAndMerge() throws Exception { - final AtomicReference<TopEntriesCollector> result = new AtomicReference<>(); - mocker.checking(new Expectations() { - { - oneOf(mockContext).getDataSet(); - will(returnValue(mockRegion)); - oneOf(mockContext).getArguments(); - will(returnValue(searchArgs)); - - oneOf(mockRepoManager).getRepositories(mockContext); - will(returnValue(repos)); - - oneOf(mockContext).getResultSender(); - will(returnValue(mockResultSender)); - - oneOf(mockRepository1).query(with(query), with(equal(LuceneQueryFactory.DEFAULT_LIMIT)), with(any(IndexResultCollector.class))); - will(new CustomAction("streamSearchResults") { - @Override - public Object invoke(Invocation invocation) throws Throwable { - IndexResultCollector collector = (IndexResultCollector) invocation.getParameter(2); - collector.collect(r1_1.getKey(), r1_1.getScore()); - collector.collect(r1_2.getKey(), r1_2.getScore()); - collector.collect(r1_3.getKey(), r1_3.getScore()); - return null; - } - }); - - oneOf(mockRepository2).query(with(query), with(equal(LuceneQueryFactory.DEFAULT_LIMIT)), with(any(IndexResultCollector.class))); - will(new CustomAction("streamSearchResults") { - @Override - public Object invoke(Invocation invocation) throws Throwable { - IndexResultCollector collector = (IndexResultCollector) invocation.getParameter(2); - collector.collect(r2_1.getKey(), r2_1.getScore()); - collector.collect(r2_2.getKey(), r2_2.getScore()); - return null; - } - }); - - oneOf(mockResultSender).lastResult(with(any(TopEntriesCollector.class))); - will(new CustomAction("collectResult") { - @Override - public Object invoke(Invocation invocation) throws Throwable { - result.set((TopEntriesCollector) invocation.getParameter(0)); - return null; - } - }); - } - }); + when(mockContext.getDataSet()).thenReturn(mockRegion); + when(mockContext.getArguments()).thenReturn(searchArgs); + when(mockContext.<TopEntriesCollector>getResultSender()).thenReturn(mockResultSender); + when(mockRepoManager.getRepositories(eq(mockContext))).thenReturn(repos); + doAnswer(invocation -> { + IndexResultCollector collector = invocation.getArgumentAt(2, IndexResultCollector.class); + collector.collect(r1_1.getKey(), r1_1.getScore()); + collector.collect(r1_2.getKey(), r1_2.getScore()); + collector.collect(r1_3.getKey(), r1_3.getScore()); + return null; + }).when(mockRepository1).query(eq(query), eq(LuceneQueryFactory.DEFAULT_LIMIT), any(IndexResultCollector.class)); + + doAnswer(invocation -> { + IndexResultCollector collector = invocation.getArgumentAt(2, IndexResultCollector.class); + collector.collect(r2_1.getKey(), r2_1.getScore()); + collector.collect(r2_2.getKey(), r2_2.getScore()); + return null; + }).when(mockRepository2).query(eq(query), eq(LuceneQueryFactory.DEFAULT_LIMIT), any(IndexResultCollector.class)); LuceneFunction function = new LuceneFunction(); function.execute(mockContext); - List<EntryScore> hits = result.get().getEntries().getHits(); + + ArgumentCaptor<TopEntriesCollector> resultCaptor = ArgumentCaptor.forClass(TopEntriesCollector.class); + verify(mockResultSender).lastResult(resultCaptor.capture()); + TopEntriesCollector result = resultCaptor.getValue(); + + + List<EntryScore> hits = result.getEntries().getHits(); assertEquals(5, hits.size()); - TopEntriesJUnitTest.verifyResultOrder(result.get().getEntries().getHits(), r1_1, r2_1, r1_2, r2_2, r1_3); + TopEntriesJUnitTest.verifyResultOrder(result.getEntries().getHits(), r1_1, r2_1, r1_2, r2_2, r1_3); } @Test public void testResultLimitClause() throws Exception { - final AtomicReference<TopEntriesCollector> result = new AtomicReference<>(); searchArgs = new LuceneFunctionContext<IndexResultCollector>(queryProvider, "indexName", null, 3); + when(mockContext.getDataSet()).thenReturn(mockRegion); + when(mockContext.getArguments()).thenReturn(searchArgs); + when(mockContext.<TopEntriesCollector>getResultSender()).thenReturn(mockResultSender); + when(mockRepoManager.getRepositories(eq(mockContext))).thenReturn(repos); + + doAnswer(invocation -> { + IndexResultCollector collector = invocation.getArgumentAt(2, IndexResultCollector.class); + collector.collect(r1_1.getKey(), r1_1.getScore()); + collector.collect(r1_2.getKey(), r1_2.getScore()); + collector.collect(r1_3.getKey(), r1_3.getScore()); + return null; + }).when(mockRepository1).query(eq(query), eq(3), any(IndexResultCollector.class)); + + doAnswer(invocation -> { + IndexResultCollector collector = invocation.getArgumentAt(2, IndexResultCollector.class); + collector.collect(r2_1.getKey(), r2_1.getScore()); + collector.collect(r2_2.getKey(), r2_2.getScore()); + return null; + }).when(mockRepository2).query(eq(query), eq(3), any(IndexResultCollector.class)); - mocker.checking(new Expectations() { - { - oneOf(mockContext).getDataSet(); - will(returnValue(mockRegion)); - oneOf(mockContext).getArguments(); - will(returnValue(searchArgs)); - - oneOf(mockContext).getResultSender(); - will(returnValue(mockResultSender)); - - oneOf(mockRepoManager).getRepositories(mockContext); - will(returnValue(repos)); - - oneOf(mockRepository1).query(with(query), with(equal(3)), with(any(IndexResultCollector.class))); - will(new CustomAction("streamSearchResults") { - @Override - public Object invoke(Invocation invocation) throws Throwable { - IndexResultCollector collector = (IndexResultCollector) invocation.getParameter(2); - collector.collect(r1_1.getKey(), r1_1.getScore()); - collector.collect(r1_2.getKey(), r1_2.getScore()); - collector.collect(r1_3.getKey(), r1_3.getScore()); - return null; - } - }); - - oneOf(mockRepository2).query(with(query), with(equal(3)), with(any(IndexResultCollector.class))); - will(new CustomAction("streamSearchResults") { - @Override - public Object invoke(Invocation invocation) throws Throwable { - IndexResultCollector collector = (IndexResultCollector) invocation.getParameter(2); - collector.collect(r2_1.getKey(), r2_1.getScore()); - collector.collect(r2_2.getKey(), r2_2.getScore()); - return null; - } - }); - - oneOf(mockResultSender).lastResult(with(any(TopEntriesCollector.class))); - will(new CustomAction("collectResult") { - @Override - public Object invoke(Invocation invocation) throws Throwable { - result.set((TopEntriesCollector) invocation.getParameter(0)); - return null; - } - }); - } - }); LuceneFunction function = new LuceneFunction(); function.execute(mockContext); - List<EntryScore> hits = result.get().getEntries().getHits(); + + ArgumentCaptor<TopEntriesCollector> resultCaptor = ArgumentCaptor.forClass(TopEntriesCollector.class); + verify(mockResultSender).lastResult(resultCaptor.capture()); + TopEntriesCollector result = resultCaptor.getValue(); + + List<EntryScore> hits = result.getEntries().getHits(); assertEquals(3, hits.size()); - TopEntriesJUnitTest.verifyResultOrder(result.get().getEntries().getHits(), r1_1, r2_1, r1_2); + TopEntriesJUnitTest.verifyResultOrder(result.getEntries().getHits(), r1_1, r2_1, r1_2); } @Test public void injectCustomCollectorManager() throws Exception { - final CollectorManager mockManager = mocker.mock(CollectorManager.class); + final CollectorManager mockManager = mock(CollectorManager.class); searchArgs = new LuceneFunctionContext<IndexResultCollector>(queryProvider, "indexName", mockManager); - mocker.checking(new Expectations() { - { - oneOf(mockContext).getDataSet(); - will(returnValue(mockRegion)); - oneOf(mockContext).getArguments(); - will(returnValue(searchArgs)); - oneOf(mockContext).getResultSender(); - will(returnValue(mockResultSender)); - - oneOf(mockRepoManager).getRepositories(mockContext); - repos.remove(0); - will(returnValue(repos)); - - oneOf(mockManager).newCollector("repo2"); - will(returnValue(mockCollector)); - oneOf(mockManager).reduce(with(any(Collection.class))); - will(new CustomAction("reduce") { - @Override - public Object invoke(Invocation invocation) throws Throwable { - Collection<IndexResultCollector> collectors = (Collection<IndexResultCollector>) invocation.getParameter(0); - assertEquals(1, collectors.size()); - assertEquals(mockCollector, collectors.iterator().next()); - return new TopEntriesCollector(null); - } - }); - - oneOf(mockCollector).collect("key-2-1", .45f); - - oneOf(mockRepository2).query(with(query), with(equal(LuceneQueryFactory.DEFAULT_LIMIT)), with(any(IndexResultCollector.class))); - will(new CustomAction("streamSearchResults") { - @Override - public Object invoke(Invocation invocation) throws Throwable { - IndexResultCollector collector = (IndexResultCollector) invocation.getParameter(2); - collector.collect(r2_1.getKey(), r2_1.getScore()); - return null; - } - }); - - oneOf(mockResultSender).lastResult(with(any(TopEntriesCollector.class))); - } - }); + when(mockContext.getDataSet()).thenReturn(mockRegion); + when(mockContext.getArguments()).thenReturn(searchArgs); + when(mockContext.<TopEntriesCollector>getResultSender()).thenReturn(mockResultSender); + repos.remove(0); + when(mockRepoManager.getRepositories(eq(mockContext))).thenReturn(repos); + when(mockManager.newCollector(eq("repo2"))).thenReturn(mockCollector); + when(mockManager.reduce(any(Collection.class))).thenAnswer(invocation -> { + Collection<IndexResultCollector> collectors = invocation.getArgumentAt(0, Collection.class); + assertEquals(1, collectors.size()); + assertEquals(mockCollector, collectors.iterator().next()); + return new TopEntriesCollector(null); + + } ); + + doAnswer(invocation -> { + IndexResultCollector collector = invocation.getArgumentAt(2, IndexResultCollector.class); + collector.collect(r2_1.getKey(), r2_1.getScore()); + return null; + }).when(mockRepository2).query(eq(query), eq(LuceneQueryFactory.DEFAULT_LIMIT), any(IndexResultCollector.class)); + LuceneFunction function = new LuceneFunction(); function.execute(mockContext); + + verify(mockCollector).collect(eq("key-2-1"), eq(.45f)); + verify(mockResultSender).lastResult(any(TopEntriesCollector.class)); } - @Test + @Test(expected = FunctionException.class) public void testIndexRepoQueryFails() throws Exception { - mocker.checking(new Expectations() { - { - oneOf(mockContext).getDataSet(); - will(returnValue(mockRegion)); - oneOf(mockContext).getArguments(); - will(returnValue(searchArgs)); - - oneOf(mockRepoManager).getRepositories(mockContext); - will(returnValue(repos)); - - oneOf(mockContext).getResultSender(); - will(returnValue(mockResultSender)); - oneOf(mockResultSender).sendException(with(any(IOException.class))); - - oneOf(mockRepository1).query(with(query), with(equal(LuceneQueryFactory.DEFAULT_LIMIT)), with(any(IndexResultCollector.class))); - will(throwException(new IOException())); - } - }); + when(mockContext.getDataSet()).thenReturn(mockRegion); + when(mockContext.getArguments()).thenReturn(searchArgs); + when(mockContext.<TopEntriesCollector>getResultSender()).thenReturn(mockResultSender); + when(mockRepoManager.getRepositories(eq(mockContext))).thenReturn(repos); + doThrow(IOException.class).when(mockRepository1).query(eq(query), eq(LuceneQueryFactory.DEFAULT_LIMIT), any(IndexResultCollector.class)); LuceneFunction function = new LuceneFunction(); function.execute(mockContext); } - @Test + @Test(expected = FunctionException.class) public void testBucketNotFound() throws Exception { - mocker.checking(new Expectations() { - { - oneOf(mockContext).getDataSet(); - will(returnValue(mockRegion)); - oneOf(mockContext).getArguments(); - will(returnValue(searchArgs)); - - oneOf(mockRepoManager).getRepositories(mockContext); - will(throwException(new BucketNotFoundException(""))); - - oneOf(mockContext).getResultSender(); - will(returnValue(mockResultSender)); - oneOf(mockResultSender).sendException(with(any(BucketNotFoundException.class))); - } - }); - + when(mockContext.getDataSet()).thenReturn(mockRegion); + when(mockContext.getArguments()).thenReturn(searchArgs); + when(mockContext.<TopEntriesCollector>getResultSender()).thenReturn(mockResultSender); + when(mockRepoManager.getRepositories(eq(mockContext))).thenThrow(new BucketNotFoundException("")); LuceneFunction function = new LuceneFunction(); function.execute(mockContext); + + verify(mockResultSender).sendException(any(BucketNotFoundException.class)); } - @Test + @Test(expected = FunctionException.class) public void testReduceError() throws Exception { - final CollectorManager mockManager = mocker.mock(CollectorManager.class); + final CollectorManager mockManager = mock(CollectorManager.class); searchArgs = new LuceneFunctionContext<IndexResultCollector>(queryProvider, "indexName", mockManager); - mocker.checking(new Expectations() { - { - oneOf(mockContext).getDataSet(); - will(returnValue(mockRegion)); - oneOf(mockContext).getResultSender(); - will(returnValue(mockResultSender)); - oneOf(mockContext).getArguments(); - will(returnValue(searchArgs)); - - oneOf(mockManager).newCollector("repo1"); - will(returnValue(mockCollector)); - oneOf(mockManager).reduce(with(any(Collection.class))); - will(throwException(new IOException())); - - oneOf(mockRepoManager).getRepositories(mockContext); - repos.remove(1); - will(returnValue(repos)); - - oneOf(mockRepository1).query(query, LuceneQueryFactory.DEFAULT_LIMIT, mockCollector); - oneOf(mockResultSender).sendException(with(any(IOException.class))); - } - }); + + when(mockContext.getDataSet()).thenReturn(mockRegion); + when(mockContext.getArguments()).thenReturn(searchArgs); + when(mockContext.<TopEntriesCollector>getResultSender()).thenReturn(mockResultSender); + repos.remove(1); + when(mockRepoManager.getRepositories(eq(mockContext))).thenReturn(repos); + when(mockManager.newCollector(eq("repo1"))).thenReturn(mockCollector); + when(mockManager.reduce(any(Collection.class))).thenThrow(IOException.class); LuceneFunction function = new LuceneFunction(); function.execute(mockContext); } - @Test + @Test(expected = FunctionException.class) public void queryProviderErrorIsHandled() throws Exception { - queryProvider = mocker.mock(LuceneQueryProvider.class); + queryProvider = mock(LuceneQueryProvider.class); searchArgs = new LuceneFunctionContext<IndexResultCollector>(queryProvider, "indexName"); - mocker.checking(new Expectations() { - { - oneOf(mockContext).getDataSet(); - will(returnValue(mockRegion)); - oneOf(mockContext).getResultSender(); - will(returnValue(mockResultSender)); - oneOf(mockContext).getArguments(); - will(returnValue(searchArgs)); - - oneOf(queryProvider).getQuery(mockIndex); - will(throwException(new QueryException())); - - oneOf(mockResultSender).sendException(with(any(QueryException.class))); - } - }); - + when(mockContext.getDataSet()).thenReturn(mockRegion); + when(mockContext.getArguments()).thenReturn(searchArgs); + when(mockContext.<TopEntriesCollector>getResultSender()).thenReturn(mockResultSender); + when(queryProvider.getQuery(eq(mockIndex))).thenThrow(QueryException.class); LuceneFunction function = new LuceneFunction(); function.execute(mockContext); @@ -369,55 +250,34 @@ public class LuceneFunctionJUnitTest { @Before public void createMocksAndCommonObjects() throws Exception { - mocker = new Mockery() { - { - setImposteriser(ClassImposteriser.INSTANCE); - setThreadingPolicy(new Synchroniser()); - } - }; - - mockContext = mocker.mock(InternalRegionFunctionContext.class); - mockResultSender = mocker.mock(ResultSender.class); - mockRegion = mocker.mock(Region.class); - - mockRepoManager = mocker.mock(RepositoryManager.class); - mockRepository1 = mocker.mock(IndexRepository.class, "repo1"); - mockRepository2 = mocker.mock(IndexRepository.class, "repo2"); - mockCollector = mocker.mock(IndexResultCollector.class); + mockContext = mock(InternalRegionFunctionContext.class); + mockResultSender = mock(ResultSender.class); + mockRegion = mock(Region.class); + + mockRepoManager = mock(RepositoryManager.class); + mockRepository1 = mock(IndexRepository.class, "repo1"); + mockRepository2 = mock(IndexRepository.class, "repo2"); + mockCollector = mock(IndexResultCollector.class); repos = new ArrayList<IndexRepository>(); repos.add(mockRepository1); repos.add(mockRepository2); - mockIndex = mocker.mock(InternalLuceneIndex.class); - mockService = mocker.mock(InternalLuceneService.class); - mockCache = mocker.mock(InternalCache.class); + mockIndex = mock(InternalLuceneIndex.class); + mockService = mock(InternalLuceneService.class); + mockCache = mock(InternalCache.class); queryProvider = new StringQueryProvider("gemfire:lucene"); searchArgs = new LuceneFunctionContext<IndexResultCollector>(queryProvider, "indexName"); - - mocker.checking(new Expectations() {{ - allowing(mockRegion).getCache(); - will(returnValue(mockCache)); - allowing(mockRegion).getFullPath(); - will(returnValue(regionPath)); - allowing(mockCache).getService(InternalLuceneService.class); - will(returnValue(mockService)); - allowing(mockService).getIndex(with("indexName"), with(regionPath)); - will(returnValue(mockIndex)); - allowing(mockIndex).getRepositoryManager(); - will(returnValue(mockRepoManager)); - allowing(mockIndex).getFieldNames(); - will(returnValue(new String[] {"gemfire"})); - }}); - - query = queryProvider.getQuery(mockIndex); - } - @After - public void validateMock() { - mocker.assertIsSatisfied(); - mocker = null; + when(mockRegion.getCache()).thenReturn(mockCache); + when(mockRegion.getFullPath()).thenReturn(regionPath); + when(mockCache.getService(any())).thenReturn(mockService); + when(mockService.getIndex(eq("indexName"), eq(regionPath))).thenReturn(mockIndex); + when(mockIndex.getRepositoryManager()).thenReturn(mockRepoManager); + when(mockIndex.getFieldNames()).thenReturn(new String[] {"gemfire"}); + + query = queryProvider.getQuery(mockIndex); } } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b3ef7913/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/TopEntriesFunctionCollectorJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/TopEntriesFunctionCollectorJUnitTest.java b/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/TopEntriesFunctionCollectorJUnitTest.java index 4f93587..b7709bc 100644 --- a/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/TopEntriesFunctionCollectorJUnitTest.java +++ b/geode-lucene/src/test/java/com/gemstone/gemfire/cache/lucene/internal/distributed/TopEntriesFunctionCollectorJUnitTest.java @@ -287,10 +287,10 @@ public class TopEntriesFunctionCollectorJUnitTest { TopEntriesJUnitTest.verifyResultOrder(merged.getHits(), r2_1, r2_2); } - @Test(expected = FunctionException.class) + @Test(expected = RuntimeException.class) public void testExceptionDuringMerge() throws Exception { TopEntriesCollectorManager mockManager = mock(TopEntriesCollectorManager.class); - Mockito.doThrow(new IOException()).when(mockManager).reduce(any(Collection.class)); + Mockito.doThrow(new RuntimeException()).when(mockManager).reduce(any(Collection.class)); LuceneFunctionContext<TopEntriesCollector> context = new LuceneFunctionContext<>(null, null, mockManager); TopEntriesFunctionCollector collector = new TopEntriesFunctionCollector(context);