diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2021-10-07 17:00:28 +0200 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2021-10-07 17:05:04 +0200 |
commit | e8f2842df4e486af6b31e2ffbc1d5569b8d26850 (patch) | |
tree | b4aa7928ebf4ab6dc85f039325138857a24b4eaa /container-search | |
parent | 6cd3e5387169803041c5628178181ee15e7b929c (diff) |
- Use the default threadpool for federation.
- Move test classes into the same package as the code to avoid making test only methods public.
- Deprecate old AsyncExecution.search/fill methods and let them run in its own thread.
There should be no external usage of this class.
Diffstat (limited to 'container-search')
-rw-r--r-- | container-search/src/main/java/com/yahoo/search/federation/FederationSearcher.java | 41 | ||||
-rw-r--r-- | container-search/src/main/java/com/yahoo/search/searchchain/AsyncExecution.java | 73 | ||||
-rw-r--r-- | container-search/src/test/java/com/yahoo/prelude/searcher/test/BlendingSearcherTestCase.java | 20 | ||||
-rw-r--r-- | container-search/src/test/java/com/yahoo/search/federation/AddHitsWithRelevanceSearcher.java (renamed from container-search/src/test/java/com/yahoo/search/federation/test/AddHitsWithRelevanceSearcher.java) | 4 | ||||
-rw-r--r-- | container-search/src/test/java/com/yahoo/search/federation/BlockingSearcher.java (renamed from container-search/src/test/java/com/yahoo/search/federation/test/BlockingSearcher.java) | 4 | ||||
-rw-r--r-- | container-search/src/test/java/com/yahoo/search/federation/DuplicateSourceTestCase.java (renamed from container-search/src/test/java/com/yahoo/search/federation/test/DuplicateSourceTestCase.java) | 3 | ||||
-rw-r--r-- | container-search/src/test/java/com/yahoo/search/federation/FederationResultTest.java | 3 | ||||
-rw-r--r-- | container-search/src/test/java/com/yahoo/search/federation/FederationSearcherTest.java (renamed from container-search/src/test/java/com/yahoo/search/federation/test/FederationSearcherTest.java) | 80 | ||||
-rw-r--r-- | container-search/src/test/java/com/yahoo/search/federation/FederationSearcherTestCase.java (renamed from container-search/src/test/java/com/yahoo/search/federation/test/FederationSearcherTestCase.java) | 46 | ||||
-rw-r--r-- | container-search/src/test/java/com/yahoo/search/federation/FederationTester.java (renamed from container-search/src/test/java/com/yahoo/search/federation/test/FederationTester.java) | 10 | ||||
-rw-r--r-- | container-search/src/test/java/com/yahoo/search/federation/HitCountTestCase.java (renamed from container-search/src/test/java/com/yahoo/search/federation/test/HitCountTestCase.java) | 34 | ||||
-rw-r--r-- | container-search/src/test/java/com/yahoo/search/federation/SetHitCountsSearcher.java (renamed from container-search/src/test/java/com/yahoo/search/federation/test/SetHitCountsSearcher.java) | 2 | ||||
-rw-r--r-- | container-search/src/test/java/com/yahoo/search/query/context/test/ConcurrentTraceTestCase.java | 56 | ||||
-rw-r--r-- | container-search/src/test/java/com/yahoo/search/searchchain/AsyncExecutionOfOneChainTestCase.java (renamed from container-search/src/test/java/com/yahoo/search/searchchain/test/AsyncExecutionOfOneChainTestCase.java) | 20 | ||||
-rw-r--r-- | container-search/src/test/java/com/yahoo/search/searchchain/AsyncExecutionTestCase.java (renamed from container-search/src/test/java/com/yahoo/search/searchchain/test/AsyncExecutionTestCase.java) | 43 | ||||
-rw-r--r-- | container-search/src/test/java/com/yahoo/search/searchchain/VespaAsyncSearcherTest.java (renamed from container-search/src/test/java/com/yahoo/search/searchchain/test/VespaAsyncSearcherTest.java) | 34 |
16 files changed, 253 insertions, 220 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/federation/FederationSearcher.java b/container-search/src/main/java/com/yahoo/search/federation/FederationSearcher.java index 4cff1802949..4b9d469d90d 100644 --- a/container-search/src/main/java/com/yahoo/search/federation/FederationSearcher.java +++ b/container-search/src/main/java/com/yahoo/search/federation/FederationSearcher.java @@ -11,6 +11,7 @@ import com.yahoo.component.chain.dependencies.After; import com.yahoo.component.chain.dependencies.Provides; import com.yahoo.component.provider.ComponentRegistry; import com.yahoo.concurrent.CopyOnWriteHashMap; +import com.yahoo.concurrent.InThreadExecutorService; import com.yahoo.errorhandling.Results; import com.yahoo.errorhandling.Results.Builder; import com.yahoo.prelude.IndexFacts; @@ -53,6 +54,7 @@ import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; @@ -71,15 +73,14 @@ import static com.yahoo.search.federation.StrictContractsConfig.PropagateSourceP @After("*") public class FederationSearcher extends ForkingSearcher { - public static final String FEDERATION = "Federation"; - private static final Logger log = Logger.getLogger(FederationSearcher.class.getName()); /** The name of the query property containing the source name added to the query to each source by this */ public final static CompoundName SOURCENAME = new CompoundName("sourceName"); public final static CompoundName PROVIDERNAME = new CompoundName("providerName"); - /** Logging field name constants */ + public static final String FEDERATION = "Federation"; public static final String LOG_COUNT_PREFIX = "count_"; + private static final List<CompoundName> queryAndHits = ImmutableList.of(Query.OFFSET, Query.HITS); private final SearchChainResolver searchChainResolver; private final PropagateSourceProperties.Enum propagateSourceProperties; @@ -88,39 +89,45 @@ public class FederationSearcher extends ForkingSearcher { private final boolean strictSearchchain; private final TargetSelector<?> targetSelector; - private final Clock clock = Clock.systemUTC(); + private final Executor executor; + - private static final List<CompoundName> queryAndHits = ImmutableList.of(Query.OFFSET, Query.HITS); @Inject public FederationSearcher(FederationConfig config, StrictContractsConfig strict, - ComponentRegistry<TargetSelector> targetSelectors) { + ComponentRegistry<TargetSelector> targetSelectors, Executor executor) { this(createResolver(config), strict.searchchains(), strict.propagateSourceProperties(), - resolveSelector(config.targetSelector(), targetSelectors)); + resolveSelector(config.targetSelector(), targetSelectors), executor); } - private static TargetSelector resolveSelector(String selectorId, - ComponentRegistry<TargetSelector> targetSelectors) { - if (selectorId.isEmpty()) return null; - return checkNotNull(targetSelectors.getComponent(selectorId), - "Missing target selector with id '" + selectorId + "'"); + // for testing + FederationSearcher(ComponentId id, SearchChainResolver searchChainResolver, Executor executor) { + this(searchChainResolver, false, PropagateSourceProperties.EVERY, null, executor); } - // for testing public FederationSearcher(ComponentId id, SearchChainResolver searchChainResolver) { - this(searchChainResolver, false, PropagateSourceProperties.EVERY, null); + this(id, searchChainResolver, new InThreadExecutorService()); } private FederationSearcher(SearchChainResolver searchChainResolver, boolean strictSearchchain, PropagateSourceProperties.Enum propagateSourceProperties, - TargetSelector targetSelector) { + TargetSelector targetSelector, + Executor executor) { this.searchChainResolver = searchChainResolver; sourceRefResolver = new SourceRefResolver(searchChainResolver); this.strictSearchchain = strictSearchchain; this.propagateSourceProperties = propagateSourceProperties; this.targetSelector = targetSelector; + this.executor = executor; + } + + private static TargetSelector resolveSelector(String selectorId, + ComponentRegistry<TargetSelector> targetSelectors) { + if (selectorId.isEmpty()) return null; + return checkNotNull(targetSelectors.getComponent(selectorId), + "Missing target selector with id '" + selectorId + "'"); } private static SearchChainResolver createResolver(FederationConfig config) { @@ -248,7 +255,7 @@ public class FederationSearcher extends ForkingSearcher { if (timeout <= 0) return new FutureResult(() -> new Result(query, ErrorMessage.createTimeout("Timed out before federation")), execution, query); Query clonedQuery = cloneFederationQuery(query, window, timeout, target); - return new AsyncExecution(target.getChain(), execution).search(clonedQuery); + return new AsyncExecution(target.getChain(), execution).search(clonedQuery, executor); } private Query cloneFederationQuery(Query query, Window window, long timeout, Target target) { @@ -439,7 +446,7 @@ public class FederationSearcher extends ForkingSearcher { propagateErrors(resultToFill, result); } else { AsyncExecution asyncFill = new AsyncExecution(chainExecution); - futureFilledResults.add(new Pair<>(resultToFill, asyncFill.fill(resultToFill, summaryClass))); + futureFilledResults.add(new Pair<>(resultToFill, asyncFill.fill(resultToFill, summaryClass, executor))); } } } diff --git a/container-search/src/main/java/com/yahoo/search/searchchain/AsyncExecution.java b/container-search/src/main/java/com/yahoo/search/searchchain/AsyncExecution.java index edd3202d63a..c1d8972bae4 100644 --- a/container-search/src/main/java/com/yahoo/search/searchchain/AsyncExecution.java +++ b/container-search/src/main/java/com/yahoo/search/searchchain/AsyncExecution.java @@ -2,7 +2,7 @@ package com.yahoo.search.searchchain; import com.yahoo.component.chain.Chain; -import com.yahoo.concurrent.ThreadFactoryFactory; +import com.yahoo.concurrent.InThreadExecutorService; import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.Searcher; @@ -10,7 +10,14 @@ import com.yahoo.search.Searcher; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.concurrent.*; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; /** * Provides asynchronous execution of searchchains. @@ -42,22 +49,9 @@ import java.util.concurrent.*; * @see com.yahoo.search.searchchain.Execution * @author Arne Bergene Fossaa */ +//TODO Make package private as this is intended for use with FederationSearcher only. public class AsyncExecution { - private static final ThreadFactory threadFactory = ThreadFactoryFactory.getThreadFactory("search"); - - private static final Executor executorMain = createExecutor(); - - private static Executor createExecutor() { - ThreadPoolExecutor executor = new ThreadPoolExecutor(100, 8192, 1L, TimeUnit.SECONDS, - new SynchronousQueue<>(false), threadFactory); - // Prestart needed, if not all threads will be created by the fist N tasks and hence they might also - // get the dreaded thread locals initialized even if they will never run. - // That counters what we we want to achieve with the Q that will prefer thread locality. - executor.prestartAllCoreThreads(); - return executor; - } - /** The execution this executes */ private final Execution execution; @@ -117,20 +111,24 @@ public class AsyncExecution { * * @see com.yahoo.search.searchchain.Execution */ + public FutureResult search(Query query, Executor executor) { + return getFutureResult(executor, () -> execution.search(query), query); + } + @Deprecated public FutureResult search(Query query) { - return getFutureResult(() -> execution.search(query), query); + return search(query, new InThreadExecutorService()); } - public FutureResult searchAndFill(Query query) { - return getFutureResult(() -> { + public FutureResult searchAndFill(Query query, Executor executor) { + return getFutureResult(executor, () -> { Result result = execution.search(query); execution.fill(result, query.getPresentation().getSummary()); return result; }, query); } - - private static Executor getExecutor() { - return executorMain; + @Deprecated + public FutureResult searchAndFill(Query query) { + return searchAndFill(query, new InThreadExecutorService()); } /** @@ -138,35 +136,38 @@ public class AsyncExecution { * * @see com.yahoo.search.searchchain.Execution */ - public FutureResult fill(Result result, String summaryClass) { - return getFutureResult(() -> { + public FutureResult fill(Result result, String summaryClass, Executor executor) { + return getFutureResult(executor, () -> { execution.fill(result, summaryClass); return result; }, result.getQuery()); - + } + @Deprecated + public FutureResult fill(Result result, String summaryClass) { + return fill(result, summaryClass, new InThreadExecutorService()); } - private static <T> Future<T> getFuture(Callable<T> callable) { + private static <T> Future<T> getFuture(Executor executor, Callable<T> callable) { FutureTask<T> future = new FutureTask<>(callable); try { - getExecutor().execute(future); + executor.execute(future); } catch (RejectedExecutionException e) { future.run(); } return future; } - private static Future<Void> runTask(Runnable runnable) { - return getFuture(() -> { + private static Future<Void> runTask(Executor executor, Runnable runnable) { + return getFuture(executor, () -> { runnable.run(); return null; }); } - private FutureResult getFutureResult(Callable<Result> callable, Query query) { + private FutureResult getFutureResult(Executor executor, Callable<Result> callable, Query query) { FutureResult future = new FutureResult(callable, execution, query); try { - getExecutor().execute(future); + executor.execute(future); } catch (RejectedExecutionException e) { future.run(); } @@ -181,13 +182,13 @@ public class AsyncExecution { * @return the list of results in the same order as returned from the task * collection */ - public static List<Result> waitForAll(Collection<FutureResult> tasks, long timeoutMs) { + static List<Result> waitForAll(Collection<FutureResult> tasks, long timeoutMs, Executor executor) { // Copy the list in case it is modified while we are waiting List<FutureResult> workingTasks = new ArrayList<>(tasks); try { - runTask(() -> { + runTask(executor, () -> { for (FutureResult task : workingTasks) - task.get(); + task.get(timeoutMs, TimeUnit.MILLISECONDS); }).get(timeoutMs, TimeUnit.MILLISECONDS); } catch (TimeoutException | InterruptedException | ExecutionException e) { // Handle timeouts below @@ -205,5 +206,9 @@ public class AsyncExecution { } return results; } + @Deprecated + public static List<Result> waitForAll(Collection<FutureResult> tasks, long timeoutMs) { + return waitForAll(tasks, timeoutMs, new InThreadExecutorService()); + } } diff --git a/container-search/src/test/java/com/yahoo/prelude/searcher/test/BlendingSearcherTestCase.java b/container-search/src/test/java/com/yahoo/prelude/searcher/test/BlendingSearcherTestCase.java index cf0758a5c47..69d66c6341f 100644 --- a/container-search/src/test/java/com/yahoo/prelude/searcher/test/BlendingSearcherTestCase.java +++ b/container-search/src/test/java/com/yahoo/prelude/searcher/test/BlendingSearcherTestCase.java @@ -6,6 +6,8 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import com.yahoo.component.ComponentId; import com.yahoo.component.chain.Chain; @@ -27,6 +29,8 @@ import com.yahoo.search.searchchain.Execution; import com.yahoo.search.searchchain.SearchChain; import com.yahoo.search.searchchain.SearchChainRegistry; import com.yahoo.search.searchchain.testutil.DocumentSourceSearcher; +import org.junit.After; +import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; @@ -45,7 +49,19 @@ public class BlendingSearcherTestCase { private static final double delta = 0.00000001; - public static class BlendingSearcherWrapper extends Searcher { + private ExecutorService executor; + + @Before + public void setUp() throws Exception { + executor = Executors.newFixedThreadPool(16); + } + + @After + public void tearDown() { + assertEquals(0, executor.shutdownNow().size()); + } + + public class BlendingSearcherWrapper extends Searcher { private SearchChain blendingChain; private final FederationConfig.Builder builder = new FederationConfig.Builder(); @@ -111,7 +127,7 @@ public class BlendingSearcherTestCase { StrictContractsConfig contracts = new StrictContractsConfig.Builder().build(); FederationSearcher fedSearcher = - new FederationSearcher(new FederationConfig(builder), contracts, new ComponentRegistry<>()); + new FederationSearcher(new FederationConfig(builder), contracts, new ComponentRegistry<>(), executor); BlendingSearcher blendingSearcher = new BlendingSearcher(blendingField); blendingChain = new SearchChain(ComponentId.createAnonymousComponentId("blendingChain"), blendingSearcher, fedSearcher); return true; diff --git a/container-search/src/test/java/com/yahoo/search/federation/test/AddHitsWithRelevanceSearcher.java b/container-search/src/test/java/com/yahoo/search/federation/AddHitsWithRelevanceSearcher.java index 9c885a1632b..e4eada1968d 100644 --- a/container-search/src/test/java/com/yahoo/search/federation/test/AddHitsWithRelevanceSearcher.java +++ b/container-search/src/test/java/com/yahoo/search/federation/AddHitsWithRelevanceSearcher.java @@ -1,5 +1,5 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.search.federation.test; +package com.yahoo.search.federation; import com.yahoo.search.Query; import com.yahoo.search.Result; @@ -10,7 +10,7 @@ import com.yahoo.search.searchchain.Execution; /** * @author Tony Vaagenes */ -public class AddHitsWithRelevanceSearcher extends Searcher { +class AddHitsWithRelevanceSearcher extends Searcher { public static final int numHitsAdded = 5; private final String chainName; diff --git a/container-search/src/test/java/com/yahoo/search/federation/test/BlockingSearcher.java b/container-search/src/test/java/com/yahoo/search/federation/BlockingSearcher.java index fd2ae7fad61..f06ab5b7fdc 100644 --- a/container-search/src/test/java/com/yahoo/search/federation/test/BlockingSearcher.java +++ b/container-search/src/test/java/com/yahoo/search/federation/BlockingSearcher.java @@ -1,5 +1,5 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.search.federation.test; +package com.yahoo.search.federation; import com.yahoo.search.Query; import com.yahoo.search.Result; @@ -9,7 +9,7 @@ import com.yahoo.search.searchchain.Execution; /** * @author Tony Vaagenes */ -public class BlockingSearcher extends Searcher { +class BlockingSearcher extends Searcher { @Override public synchronized Result search(Query query, Execution execution) { diff --git a/container-search/src/test/java/com/yahoo/search/federation/test/DuplicateSourceTestCase.java b/container-search/src/test/java/com/yahoo/search/federation/DuplicateSourceTestCase.java index c8a1007f366..da25baacd51 100644 --- a/container-search/src/test/java/com/yahoo/search/federation/test/DuplicateSourceTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/federation/DuplicateSourceTestCase.java @@ -1,5 +1,5 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.search.federation.test; +package com.yahoo.search.federation; import com.google.common.collect.ImmutableList; import com.yahoo.component.ComponentId; @@ -9,7 +9,6 @@ import com.yahoo.prelude.IndexModel; import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.Searcher; -import com.yahoo.search.federation.FederationSearcher; import com.yahoo.search.federation.sourceref.SearchChainResolver; import com.yahoo.search.searchchain.Execution; import com.yahoo.search.searchchain.SearchChainRegistry; diff --git a/container-search/src/test/java/com/yahoo/search/federation/FederationResultTest.java b/container-search/src/test/java/com/yahoo/search/federation/FederationResultTest.java index 3cd9e4a6408..a17104f888d 100644 --- a/container-search/src/test/java/com/yahoo/search/federation/FederationResultTest.java +++ b/container-search/src/test/java/com/yahoo/search/federation/FederationResultTest.java @@ -19,6 +19,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** @@ -57,7 +58,7 @@ public class FederationResultTest { if (expectedTimeoutNames.contains(targetResult.target.getId().toString())) assertTrue(targetResult.target.getId() + " timed out", timedOut(result)); else - assertTrue(targetResult.target.getId() + " did not time out", ! timedOut(result)); + assertFalse(targetResult.target.getId() + " did not time out", timedOut(result)); } } diff --git a/container-search/src/test/java/com/yahoo/search/federation/test/FederationSearcherTest.java b/container-search/src/test/java/com/yahoo/search/federation/FederationSearcherTest.java index b42500ee4f5..7651849a519 100644 --- a/container-search/src/test/java/com/yahoo/search/federation/test/FederationSearcherTest.java +++ b/container-search/src/test/java/com/yahoo/search/federation/FederationSearcherTest.java @@ -1,5 +1,5 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.search.federation.test; +package com.yahoo.search.federation; import com.yahoo.component.ComponentId; import com.yahoo.component.chain.Chain; @@ -10,12 +10,8 @@ import com.yahoo.processing.execution.chain.ChainRegistry; import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.Searcher; -import com.yahoo.search.federation.FederationConfig; -import com.yahoo.search.federation.FederationSearcher; -import com.yahoo.search.federation.TimeoutException; import com.yahoo.search.federation.selection.FederationTarget; import com.yahoo.search.federation.selection.TargetSelector; -import com.yahoo.search.federation.StrictContractsConfig; import com.yahoo.search.result.ErrorHit; import com.yahoo.search.result.ErrorMessage; import com.yahoo.search.result.Hit; @@ -24,18 +20,21 @@ import com.yahoo.search.searchchain.Execution; import com.yahoo.search.searchchain.Execution.Context; import com.yahoo.search.searchchain.model.federation.FederationOptions; +import org.junit.After; +import org.junit.Before; import org.junit.Test; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.Iterator; import java.util.List; -import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; /** * @author Tony Vaagenes @@ -44,6 +43,18 @@ public class FederationSearcherTest { private static final String hasBeenFilled = "hasBeenFilled"; + private ExecutorService executor; + + @Before + public void setUp() throws Exception { + executor = Executors.newFixedThreadPool(16); + } + + @After + public void tearDown() { + assertEquals(0, executor.shutdownNow().size()); + } + @Test public void require_that_hits_are_not_automatically_filled() { Result result = federationToSingleAddHitSearcher().search(); @@ -58,7 +69,7 @@ public class FederationSearcherTest { @Test public void require_that_hits_can_be_filled_when_moved() { - FederationTester tester = new FederationTester(); + FederationTester tester = new FederationTester(executor); tester.addSearchChain("chain1", new AddHitSearcher()); tester.addSearchChain("chain2", new AddHitSearcher()); @@ -86,7 +97,7 @@ public class FederationSearcherTest { @Test public void require_that_hits_can_be_filled_for_multiple_chains_and_queries() { - FederationTester tester = new FederationTester(); + FederationTester tester = new FederationTester(executor); tester.addSearchChain("chain1", new AddHitSearcher()); tester.addSearchChain("chain2", new ModifyQueryAndAddHitSearcher("modified1")); tester.addSearchChain("chain3", new ModifyQueryAndAddHitSearcher("modified2")); @@ -100,7 +111,7 @@ public class FederationSearcherTest { @Test public void require_that_hits_that_time_out_in_fill_are_removed() { - FederationTester tester = new FederationTester(); + FederationTester tester = new FederationTester(executor); tester.addSearchChain("chain1", new AddHitSearcher()); tester.addSearchChain("chain2", new TimeoutInFillSearcher()); @@ -118,7 +129,7 @@ public class FederationSearcherTest { public void require_that_optional_search_chains_does_not_delay_federation() { BlockingSearcher blockingSearcher = new BlockingSearcher(); - FederationTester tester = new FederationTester(); + FederationTester tester = new FederationTester(executor); tester.addSearchChain("chain1", new AddHitSearcher()); tester.addOptionalSearchChain("chain2", blockingSearcher); @@ -147,7 +158,7 @@ public class FederationSearcherTest { @Test public void require_that_calling_a_single_slow_source_with_long_timeout_does_not_delay_federation() { - FederationTester tester = new FederationTester(); + FederationTester tester = new FederationTester(executor); tester.addSearchChain("chain1", new FederationOptions().setUseByDefault(true).setRequestTimeoutInMilliseconds(3600 * 1000), new BlockingSearcher() ); @@ -177,14 +188,14 @@ public class FederationSearcherTest { FederationSearcher searcher = new FederationSearcher( new FederationConfig(new FederationConfig.Builder().targetSelector(targetSelectorId.toString())), new StrictContractsConfig(new StrictContractsConfig.Builder()), - targetSelectors); + targetSelectors, executor); Query query = new Query(); query.setTimeout(20000); Result result = new Execution(searcher, Context.createContextStub()).search(query); HitGroup myChainGroup = (HitGroup) result.hits().get(0); - assertThat(myChainGroup.getId(), is(new URI("source:myChain"))); - assertThat(myChainGroup.get(0).getId(), is(new URI("myHit"))); + assertEquals(myChainGroup.getId(), new URI("source:myChain")); + assertEquals(myChainGroup.get(0).getId(), new URI("myHit")); } @Test @@ -196,7 +207,7 @@ public class FederationSearcherTest { FederationSearcher searcher = new FederationSearcher( new FederationConfig(new FederationConfig.Builder().targetSelector(targetSelectorId.toString())), new StrictContractsConfig(new StrictContractsConfig.Builder()), - targetSelectors); + targetSelectors, executor); Query query = new Query(); query.setTimeout(20000); @@ -206,11 +217,11 @@ public class FederationSearcherTest { Hit hit1 = hitsIterator.next(); Hit hit2 = hitsIterator.next(); - assertThat(hit1.getSource(), is("chain1")); - assertThat(hit2.getSource(), is("chain2")); + assertEquals(hit1.getSource(), "chain1"); + assertEquals(hit2.getSource(), "chain2"); - assertThat(hit1.getField("data"), is("modifyTargetQuery:custom-data:1")); - assertThat(hit2.getField("data"), is("modifyTargetQuery:custom-data:2")); + assertEquals(hit1.getField("data"), "modifyTargetQuery:custom-data:1"); + assertEquals(hit2.getField("data"), "modifyTargetQuery:custom-data:2"); } private Hit getFirstHit(Hit hitGroup) { @@ -220,15 +231,6 @@ public class FederationSearcherTest { throw new IllegalArgumentException("Expected HitGroup"); } - private List<Hit> getNonErrorHits(Result result) { - List<Hit> nonErrorHits = new ArrayList<>(); - for (Hit hit : result.hits()) { - if (!(hit instanceof ErrorHit)) - nonErrorHits.add(hit); - } - - return nonErrorHits; - } private static void assertFilled(Hit hit) { if (hit.isMeta()) return; assertTrue((Boolean)hit.getField(hasBeenFilled)); @@ -239,7 +241,7 @@ public class FederationSearcherTest { } private FederationTester federationToSingleAddHitSearcher() { - FederationTester tester = new FederationTester(); + FederationTester tester = new FederationTester(executor); tester.addSearchChain("chain1", new AddHitSearcher()); return tester; } @@ -326,8 +328,8 @@ public class FederationSearcherTest { @Override public Collection<FederationTarget<String>> getTargets(Query query, ChainRegistry<Searcher> searcherChainRegistry) { - return Arrays.asList( - new FederationTarget<>(new Chain<>("myChain", Collections.<Searcher>emptyList()), new FederationOptions(), "hello")); + return List.of( + new FederationTarget<>(new Chain<>("myChain", List.of()), new FederationOptions(), "hello")); } @Override @@ -339,13 +341,13 @@ public class FederationSearcherTest { @Override public void modifyTargetResult(FederationTarget<String> target, Result result) { checkTarget(target); - assertThat(result.getQuery().properties().getString(keyName), is("called")); + assertEquals(result.getQuery().properties().getString(keyName), "called"); result.hits().add(new Hit("myHit")); } private void checkTarget(FederationTarget<String> target) { - assertThat(target.getCustomData(), is("hello")); - assertThat(target.getChain().getId(), is(ComponentId.fromString("myChain"))); + assertEquals(target.getCustomData(), "hello"); + assertEquals(target.getChain().getId(), ComponentId.fromString("myChain")); } } @@ -359,7 +361,7 @@ public class FederationSearcherTest { } private FederationTarget<String> createTarget(int number) { - return new FederationTarget<>(new Chain<>("chain" + number, Collections.<Searcher>emptyList()), + return new FederationTarget<>(new Chain<>("chain" + number, List.of()), new FederationOptions(), "custom-data:" + number); } diff --git a/container-search/src/test/java/com/yahoo/search/federation/test/FederationSearcherTestCase.java b/container-search/src/test/java/com/yahoo/search/federation/FederationSearcherTestCase.java index 33198b4496e..65640cc94f0 100644 --- a/container-search/src/test/java/com/yahoo/search/federation/test/FederationSearcherTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/federation/FederationSearcherTestCase.java @@ -1,5 +1,5 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.search.federation.test; +package com.yahoo.search.federation; import com.yahoo.component.ComponentId; import com.yahoo.component.chain.Chain; @@ -7,13 +7,8 @@ import com.yahoo.component.provider.ComponentRegistry; import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.Searcher; -import com.yahoo.search.federation.FederationConfig; -import com.yahoo.search.federation.FederationSearcher; -import com.yahoo.search.federation.StrictContractsConfig; -import com.yahoo.search.federation.selection.TargetSelector; import com.yahoo.search.federation.sourceref.SearchChainResolver; import com.yahoo.search.query.profile.QueryProfile; -import com.yahoo.search.query.profile.QueryProfileRegistry; import com.yahoo.search.result.ErrorMessage; import com.yahoo.search.result.Hit; import com.yahoo.search.result.HitGroup; @@ -29,10 +24,17 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; -import static org.junit.Assert.*; import static com.yahoo.search.federation.StrictContractsConfig.PropagateSourceProperties; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; /** * Test for federation searcher. The searcher is also tested in @@ -40,7 +42,6 @@ import static com.yahoo.search.federation.StrictContractsConfig.PropagateSourceP * * @author Arne Bergene Fossaa */ -@SuppressWarnings("deprecation") public class FederationSearcherTestCase { static final String SOURCE1 = "source1"; @@ -63,17 +64,20 @@ public class FederationSearcherTestCase { private FederationConfig.Builder builder; private SearchChainRegistry chainRegistry; + private ExecutorService executor; @Before public void setUp() throws Exception { builder = new FederationConfig.Builder(); chainRegistry = new SearchChainRegistry(); + executor = Executors.newFixedThreadPool(16); } @After public void tearDown() { builder = null; chainRegistry = null; + assertEquals(0, executor.shutdownNow().size()); } private void addChained(Searcher searcher, String sourceName) { @@ -103,7 +107,7 @@ public class FederationSearcherTestCase { } private Searcher buildFederation(StrictContractsConfig contracts) throws RuntimeException { - return new FederationSearcher(new FederationConfig(builder), contracts, new ComponentRegistry<>()); + return new FederationSearcher(new FederationConfig(builder), contracts, new ComponentRegistry<>(), executor); } private SearchChain createSearchChain(ComponentId chainId,Searcher searcher) { @@ -161,12 +165,12 @@ public class FederationSearcherTestCase { }, SOURCE2); - Chain<Searcher> mainChain = new Chain<>("default", + return new Chain<>("default", new FederationSearcher(new FederationConfig(builder), new StrictContractsConfig( new StrictContractsConfig.Builder().searchchains(strictContracts)), - new ComponentRegistry<>())); - return mainChain; + new ComponentRegistry<>(), + executor)); } @Test @@ -208,7 +212,7 @@ public class FederationSearcherTestCase { assertEquals("source:mySource2", result.hits().get(1).getId().stringValue()); assertEquals("nalle", result.hits().get(0).getQuery().getPresentation().getSummary()); assertNull(result.hits().get(1).getQuery().getPresentation().getSummary()); - assertEquals(null, result.hits().get(0).getQuery().properties().get("custom")); + assertNull(result.hits().get(0).getQuery().properties().get("custom")); } @Test @@ -219,8 +223,8 @@ public class FederationSearcherTestCase { assertEquals("source:mySource2", result.hits().get(1).getId().stringValue()); assertEquals("nalle", result.hits().get(0).getQuery().getPresentation().getSummary()); assertEquals("foo", result.hits().get(0).getQuery().properties().get("customSourceProperty")); - assertEquals(null, result.hits().get(1).getQuery().properties().get("customSourceProperty")); - assertEquals(null, result.hits().get(0).getQuery().properties().get("custom.source.property")); + assertNull(result.hits().get(1).getQuery().properties().get("customSourceProperty")); + assertNull(result.hits().get(0).getQuery().properties().get("custom.source.property")); assertEquals("bar", result.hits().get(1).getQuery().properties().get("custom.source.property")); assertEquals(13, result.hits().get(0).getQuery().properties().get("hits")); assertEquals(1, result.hits().get(0).getQuery().properties().get("offset")); @@ -347,12 +351,12 @@ public class FederationSearcherTestCase { ComponentId provider1 = new ComponentId("provider1"); ComponentId provider2 = new ComponentId("provider2"); ComponentId news = new ComponentId("news"); - builder.addSearchChain(provider1, options, Collections.<String> emptyList()); - builder.addSearchChain(provider2, options, Collections.<String> emptyList()); - builder.addSourceForProvider(news, provider1, provider1, true, options, Collections.<String> emptyList()); - builder.addSourceForProvider(news, provider2, provider2, false, options, Collections.<String> emptyList()); + builder.addSearchChain(provider1, options, List.of()); + builder.addSearchChain(provider2, options, List.of()); + builder.addSourceForProvider(news, provider1, provider1, true, options, List.of()); + builder.addSourceForProvider(news, provider2, provider2, false, options, List.of()); - return new FederationSearcher(new ComponentId("federation"), builder.build()); + return new FederationSearcher(new ComponentId("federation"), builder.build(), executor); } private static class MockProvider extends Searcher { diff --git a/container-search/src/test/java/com/yahoo/search/federation/test/FederationTester.java b/container-search/src/test/java/com/yahoo/search/federation/FederationTester.java index 393529781b2..433fe557b24 100644 --- a/container-search/src/test/java/com/yahoo/search/federation/test/FederationTester.java +++ b/container-search/src/test/java/com/yahoo/search/federation/FederationTester.java @@ -1,18 +1,18 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.search.federation.test; +package com.yahoo.search.federation; import com.yahoo.component.ComponentId; import com.yahoo.component.chain.Chain; import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.Searcher; -import com.yahoo.search.federation.FederationSearcher; import com.yahoo.search.federation.sourceref.SearchChainResolver; import com.yahoo.search.searchchain.Execution; import com.yahoo.search.searchchain.SearchChainRegistry; import com.yahoo.search.searchchain.model.federation.FederationOptions; import java.util.Collections; +import java.util.concurrent.Executor; /** * @author Tony Vaagenes @@ -23,7 +23,11 @@ class FederationTester { private final SearchChainRegistry registry = new SearchChainRegistry(); private Execution execution; + private final Executor executor; + FederationTester(Executor executor) { + this.executor = executor; + } void addSearchChain(String id, Searcher... searchers) { addSearchChain(id, federationOptions(), searchers); } @@ -47,7 +51,7 @@ class FederationTester { } FederationSearcher buildFederationSearcher() { - return new FederationSearcher(ComponentId.fromString("federation"), builder.build()); + return new FederationSearcher(ComponentId.fromString("federation"), builder.build(), executor); } public Result search() { diff --git a/container-search/src/test/java/com/yahoo/search/federation/test/HitCountTestCase.java b/container-search/src/test/java/com/yahoo/search/federation/HitCountTestCase.java index 74eb7992a38..163263b7640 100644 --- a/container-search/src/test/java/com/yahoo/search/federation/test/HitCountTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/federation/HitCountTestCase.java @@ -1,31 +1,45 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.search.federation.test; +package com.yahoo.search.federation; import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.result.Hit; import com.yahoo.search.result.HitGroup; +import org.junit.After; +import org.junit.Before; import org.junit.Test; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; -import static org.hamcrest.core.Is.is; -import static org.hamcrest.core.StringStartsWith.startsWith; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; /** * @author Tony Vaagenes */ public class HitCountTestCase { + private ExecutorService executor; + + @Before + public void setUp() throws Exception { + executor = Executors.newFixedThreadPool(16); + } + + @After + public void tearDown() { + assertEquals(0, executor.shutdownNow().size()); + } + @Test public void require_that_offset_and_hits_are_adjusted_when_federating() { final int chain1RelevanceMultiplier = 1; final int chain2RelevanceMultiplier = 10; - FederationTester tester = new FederationTester(); + FederationTester tester = new FederationTester(executor); tester.addSearchChain("chain1", new AddHitsWithRelevanceSearcher("chain1", chain1RelevanceMultiplier)); tester.addSearchChain("chain2", new AddHitsWithRelevanceSearcher("chain2", chain2RelevanceMultiplier)); @@ -47,14 +61,14 @@ public class HitCountTestCase { final long chain2TotalHitCount = 7; final long chain2DeepHitCount = 11; - FederationTester tester = new FederationTester(); + FederationTester tester = new FederationTester(executor); tester.addSearchChain("chain1", new SetHitCountsSearcher(chain1TotalHitCount, chain1DeepHitCount)); tester.addSearchChain("chain2", new SetHitCountsSearcher(chain2TotalHitCount, chain2DeepHitCount)); Result result = tester.searchAndFill(); - assertThat(result.getTotalHitCount(), is(chain1TotalHitCount + chain2TotalHitCount)); - assertThat(result.getDeepHitCount(), is(chain1DeepHitCount + chain2DeepHitCount)); + assertEquals(result.getTotalHitCount(), chain1TotalHitCount + chain2TotalHitCount); + assertEquals(result.getDeepHitCount(), chain1DeepHitCount + chain2DeepHitCount); } @Test @@ -65,7 +79,7 @@ public class HitCountTestCase { final long chain2TotalHitCount = 11; final long chain2DeepHitCount = 15; - FederationTester tester = new FederationTester(); + FederationTester tester = new FederationTester(executor); tester.addSearchChain("chain1", new SetHitCountsSearcher(chain1TotalHitCount, chain1DeepHitCount)); @@ -110,7 +124,7 @@ public class HitCountTestCase { private void assertAllHitsFrom(String chainName, HitGroup flattenedHits) { for (Hit hit : flattenedHits) { - assertThat(hit.getId().toString(), startsWith(chainName)); + assertTrue(hit.getId().toString().startsWith(chainName)); } } diff --git a/container-search/src/test/java/com/yahoo/search/federation/test/SetHitCountsSearcher.java b/container-search/src/test/java/com/yahoo/search/federation/SetHitCountsSearcher.java index 36b5e7efa37..fe299fbeb95 100644 --- a/container-search/src/test/java/com/yahoo/search/federation/test/SetHitCountsSearcher.java +++ b/container-search/src/test/java/com/yahoo/search/federation/SetHitCountsSearcher.java @@ -1,5 +1,5 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.search.federation.test; +package com.yahoo.search.federation; import com.yahoo.search.Query; import com.yahoo.search.Result; diff --git a/container-search/src/test/java/com/yahoo/search/query/context/test/ConcurrentTraceTestCase.java b/container-search/src/test/java/com/yahoo/search/query/context/test/ConcurrentTraceTestCase.java deleted file mode 100644 index c8aac27da1d..00000000000 --- a/container-search/src/test/java/com/yahoo/search/query/context/test/ConcurrentTraceTestCase.java +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.search.query.context.test; - -import java.util.ArrayList; -import java.util.List; - -import com.yahoo.component.chain.Chain; - -import com.yahoo.search.Query; -import com.yahoo.search.Result; -import com.yahoo.search.Searcher; -import com.yahoo.search.searchchain.AsyncExecution; -import com.yahoo.search.searchchain.Execution; -import com.yahoo.search.searchchain.FutureResult; - -/** - * Checks it's OK adding more traces to an instance which is being rendered. - * - * @author <a href="arnebef@yahoo-inc.com">Arne Bergene Fossaa</a> - */ -@SuppressWarnings("deprecation") -public class ConcurrentTraceTestCase { - class TraceSearcher extends Searcher { - - @Override - public Result search(Query query, Execution execution) { - for(int i = 0;i<1000;i++) { - query.trace("Trace", false, 1); - try { - Thread.sleep(1); - } catch (InterruptedException e) { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - } - return execution.search(query); - } - } - - class AsyncSearcher extends Searcher { - - @Override - public Result search(Query query, Execution execution) { - Chain<Searcher> chain = new Chain<>(new TraceSearcher()); - - Result result = new Result(query); - List<FutureResult> futures = new ArrayList<>(); - for(int i = 0; i < 100; i++) { - futures.add(new AsyncExecution(chain, execution).searchAndFill(query)); - } - AsyncExecution.waitForAll(futures, 10); - return result; - } - - } - -} diff --git a/container-search/src/test/java/com/yahoo/search/searchchain/test/AsyncExecutionOfOneChainTestCase.java b/container-search/src/test/java/com/yahoo/search/searchchain/AsyncExecutionOfOneChainTestCase.java index 11491a86948..74d74e96b05 100644 --- a/container-search/src/test/java/com/yahoo/search/searchchain/test/AsyncExecutionOfOneChainTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/searchchain/AsyncExecutionOfOneChainTestCase.java @@ -1,5 +1,5 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.search.searchchain.test; +package com.yahoo.search.searchchain; import com.yahoo.component.chain.Chain; import com.yahoo.search.Query; @@ -7,14 +7,14 @@ import com.yahoo.search.Result; import com.yahoo.search.Searcher; import com.yahoo.search.result.Hit; import com.yahoo.search.result.HitGroup; -import com.yahoo.search.searchchain.AsyncExecution; -import com.yahoo.search.searchchain.Execution; -import com.yahoo.search.searchchain.FutureResult; import org.junit.Test; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; import static org.junit.Assert.assertEquals; @@ -29,8 +29,9 @@ public class AsyncExecutionOfOneChainTestCase { /** Tests having a result with some slow source data which should pass directly to rendering */ @Test public void testParallelExecutionOfOneChain() { + ExecutorService executor = Executors.newFixedThreadPool(16); // Setup - Chain<Searcher> mainChain=new Chain<>(new ParallelExecutor(),new ResultProcessor(),new RegularProvider()); + Chain<Searcher> mainChain=new Chain<>(new ParallelExecutor(executor),new ResultProcessor(),new RegularProvider()); // Execute Result result=new Execution(mainChain, Execution.Context.createContextStub()).search(new Query()); @@ -43,23 +44,26 @@ public class AsyncExecutionOfOneChainTestCase { assertEquals(0.5, result.hits().get("thread-0:hit-1").getRelevance().getScore(), delta); assertEquals(0.5, result.hits().get("thread-1:hit-1").getRelevance().getScore(), delta); assertEquals(0.5, result.hits().get("thread-2:hit-1").getRelevance().getScore(), delta); + assertEquals(0, executor.shutdownNow().size()); } - private class ParallelExecutor extends Searcher { + private static class ParallelExecutor extends Searcher { /** The number of parallel executions */ private static final int parallelism = 2; + private final Executor executor; + ParallelExecutor(Executor executor) { this.executor = executor; } @Override public Result search(Query query, Execution execution) { List<FutureResult> futureResults = new ArrayList<>(parallelism); for (int i = 0; i < parallelism; i++) - futureResults.add(new AsyncExecution(execution).search(query.clone())); + futureResults.add(new AsyncExecution(execution).search(query.clone(), executor)); Result mainResult = execution.search(query); // Add hits from other threads - AsyncExecution.waitForAll(futureResults,query.getTimeLeft()); + AsyncExecution.waitForAll(futureResults,query.getTimeLeft(), executor); for (FutureResult futureResult : futureResults) { Result result = futureResult.get(); mainResult.mergeWith(result); diff --git a/container-search/src/test/java/com/yahoo/search/searchchain/test/AsyncExecutionTestCase.java b/container-search/src/test/java/com/yahoo/search/searchchain/AsyncExecutionTestCase.java index ad7125a2e90..ec1c78437b6 100644 --- a/container-search/src/test/java/com/yahoo/search/searchchain/test/AsyncExecutionTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/searchchain/AsyncExecutionTestCase.java @@ -1,5 +1,5 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.search.searchchain.test; +package com.yahoo.search.searchchain; import com.yahoo.component.ComponentId; import com.yahoo.component.chain.Chain; @@ -7,14 +7,15 @@ import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.Searcher; import com.yahoo.search.result.Hit; -import com.yahoo.search.searchchain.AsyncExecution; -import com.yahoo.search.searchchain.Execution; -import com.yahoo.search.searchchain.FutureResult; +import org.junit.After; +import org.junit.Before; import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import static org.junit.Assert.assertEquals; @@ -29,7 +30,19 @@ import static org.junit.Assert.assertTrue; */ public class AsyncExecutionTestCase { - public class WaitingSearcher extends Searcher { + private ExecutorService executor; + + @Before + public void setUp() throws Exception { + executor = Executors.newFixedThreadPool(16); + } + + @After + public void tearDown() { + assertEquals(0, executor.shutdownNow().size()); + } + + public static class WaitingSearcher extends Searcher { int waittime; private WaitingSearcher(String id,int waittime) { @@ -49,7 +62,7 @@ public class AsyncExecutionTestCase { } } - public class SimpleSearcher extends Searcher { + public static class SimpleSearcher extends Searcher { public Result search(Query query,Execution execution) { return execution.search(query); @@ -66,10 +79,10 @@ public class AsyncExecutionTestCase { Chain<Searcher> searchChain = new Chain<>(new ComponentId("chain"), searchList); AsyncExecution asyncExecution = new AsyncExecution(searchChain, Execution.Context.createContextStub()); - FutureResult future = asyncExecution.search(new Query("?hits=0")); + FutureResult future = asyncExecution.search(new Query("?hits=0"), executor); Result result = future.get(0, TimeUnit.MILLISECONDS); - assertTrue(result.hits().getError() != null); + assertNotNull(result.hits().getError()); } @Test @@ -85,11 +98,11 @@ public class AsyncExecutionTestCase { Arrays.asList(new Searcher[]{new SimpleSearcher()}) ); - FutureResult slowFuture = new AsyncExecution(slowChain, Execution.Context.createContextStub()).search(new Query("?hits=0")); - FutureResult fastFuture = new AsyncExecution(fastChain, Execution.Context.createContextStub()).search(new Query("?hits=0")); + FutureResult slowFuture = new AsyncExecution(slowChain, Execution.Context.createContextStub()).search(new Query("?hits=0"), executor); + FutureResult fastFuture = new AsyncExecution(fastChain, Execution.Context.createContextStub()).search(new Query("?hits=0"), executor); fastFuture.get(); - FutureResult reslist[] = new FutureResult[]{slowFuture,fastFuture}; - List<Result> results = AsyncExecution.waitForAll(Arrays.asList(reslist),0); + FutureResult [] reslist = new FutureResult[]{slowFuture,fastFuture}; + List<Result> results = AsyncExecution.waitForAll(Arrays.asList(reslist),0, executor); //assertTrue(slowFuture.isCancelled()); assertTrue(fastFuture.isDone() && !fastFuture.isCancelled()); @@ -122,11 +135,11 @@ public class AsyncExecutionTestCase { public void testAsyncThroughSync() { Query query=new Query("?query=test"); Searcher searcher=new ResultProducingSearcher(); - FutureResult futureResult=new AsyncExecution(new Execution(searcher, Execution.Context.createContextStub())).search(query); + FutureResult futureResult=new AsyncExecution(new Execution(searcher, Execution.Context.createContextStub())).search(query, executor); List<FutureResult> futureResultList=new ArrayList<>(); futureResultList.add(futureResult); - AsyncExecution.waitForAll(futureResultList,1000); + AsyncExecution.waitForAll(futureResultList,1000, executor); Result result=futureResult.get(); assertEquals(1,result.hits().size()); @@ -161,7 +174,7 @@ public class AsyncExecutionTestCase { }); Execution execution = new Execution(chain, Execution.Context.createContextStub()); AsyncExecution async = new AsyncExecution(execution); - FutureResult future = async.searchAndFill(new Query()); + FutureResult future = async.searchAndFill(new Query(), executor); future.get(1, TimeUnit.MILLISECONDS); } diff --git a/container-search/src/test/java/com/yahoo/search/searchchain/test/VespaAsyncSearcherTest.java b/container-search/src/test/java/com/yahoo/search/searchchain/VespaAsyncSearcherTest.java index 57f066400d6..0b893020a16 100644 --- a/container-search/src/test/java/com/yahoo/search/searchchain/test/VespaAsyncSearcherTest.java +++ b/container-search/src/test/java/com/yahoo/search/searchchain/VespaAsyncSearcherTest.java @@ -1,17 +1,22 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.search.searchchain.test; +package com.yahoo.search.searchchain; import com.yahoo.component.chain.Chain; +import com.yahoo.concurrent.InThreadExecutorService; import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.Searcher; -import com.yahoo.search.searchchain.AsyncExecution; -import com.yahoo.search.searchchain.Execution; -import com.yahoo.search.searchchain.FutureResult; +import org.junit.After; +import org.junit.Before; import org.junit.Test; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import static org.junit.Assert.assertEquals; /** * Tests async execution of search chains. @@ -21,18 +26,33 @@ import java.util.List; */ public class VespaAsyncSearcherTest { + private ExecutorService executor; + + @Before + public void setUp() throws Exception { + executor = Executors.newFixedThreadPool(16); + } + + @After + public void tearDown() { + assertEquals(0, executor.shutdownNow().size()); + } + private static class FirstSearcher extends Searcher { + private final Executor executor; + FirstSearcher(Executor executor) { this.executor = executor;} + @Override public Result search(Query query, Execution execution) { int count = 10; List<FutureResult> futures = new ArrayList<>(count); for (int i = 0; i < count; i++) { Query subQuery = query.clone(); - FutureResult future = new AsyncExecution(execution).search(subQuery); + FutureResult future = new AsyncExecution(execution).search(subQuery, executor); futures.add(future); } - AsyncExecution.waitForAll(futures, 10 * 60 * 1000); + AsyncExecution.waitForAll(futures, 10 * 60 * 1000, new InThreadExecutorService()); Result combinedResult = new Result(query); for (FutureResult resultFuture : futures) { Result result = resultFuture.get(); @@ -55,7 +75,7 @@ public class VespaAsyncSearcherTest { @Test public void testAsyncExecution() { - Chain<Searcher> chain = new Chain<>(new FirstSearcher(), new SecondSearcher()); + Chain<Searcher> chain = new Chain<>(new FirstSearcher(executor), new SecondSearcher()); Execution execution = new Execution(chain, Execution.Context.createContextStub(null)); Query query = new Query(); execution.search(query); |