summaryrefslogtreecommitdiffstats
path: root/container-search/src/test/java/com/yahoo/search/federation
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2017-01-24 15:19:59 +0100
committerJon Bratseth <bratseth@yahoo-inc.com>2017-01-24 15:19:59 +0100
commit827b409663ae7a0137d2e1f4c8659fcb3b15a1e5 (patch)
tree7804a1e593e433c547d46d46cd0867ba579d9d46 /container-search/src/test/java/com/yahoo/search/federation
parent6329a23f586f3a418702e6b2ca683957bc0ca554 (diff)
Adaptive federation timeout
Diffstat (limited to 'container-search/src/test/java/com/yahoo/search/federation')
-rw-r--r--container-search/src/test/java/com/yahoo/search/federation/FederationResultTest.java146
-rw-r--r--container-search/src/test/java/com/yahoo/search/federation/FutureWaiterTest.java109
-rw-r--r--container-search/src/test/java/com/yahoo/search/federation/test/FederationSearcherTestCase.java2
-rw-r--r--container-search/src/test/java/com/yahoo/search/federation/test/FederationTester.java1
4 files changed, 148 insertions, 110 deletions
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
new file mode 100644
index 00000000000..eb17cf27db9
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/federation/FederationResultTest.java
@@ -0,0 +1,146 @@
+package com.yahoo.search.federation;
+
+import com.google.common.collect.ImmutableSet;
+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.result.ErrorMessage;
+import com.yahoo.search.searchchain.Execution;
+import com.yahoo.search.searchchain.FutureResult;
+import com.yahoo.search.searchchain.model.federation.FederationOptions;
+import org.junit.Test;
+
+import java.time.Clock;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author bratseth
+ */
+public class FederationResultTest {
+
+ private static final FederationSearcher.Target organic = new MockTarget("organic", 250);
+ private static final FederationSearcher.Target dsp1 = new MockTarget("dsp1", 120);
+ private static final FederationSearcher.Target dsp2 = new MockTarget("dsp2", 100);
+
+ private final Clock clock = Clock.systemUTC();
+
+ @Test
+ public void testFederationResult() {
+ assertTimeout(ImmutableSet.of(), 50, 100, 90);
+ assertTimeout(ImmutableSet.of(), 240, 200, 200);
+ assertTimeout(ImmutableSet.of("dsp1"), 130, 140, 110);
+ assertTimeout(ImmutableSet.of("organic"), 260, 80, 80);
+ assertTimeout(ImmutableSet.of("dsp2"), 100, 110, 115);
+ assertTimeout(ImmutableSet.of(), 100, 110, 105);
+ assertTimeout(ImmutableSet.of("dsp1", "dsp2"), 100, 130, 130);
+ assertTimeout(ImmutableSet.of("organic"), 260, 130, 130);
+ }
+
+ private void assertTimeout(Set<String> expectedTimeoutNames, int ... responseTimes) {
+ FederationResult.Builder builder = new FederationResult.Builder();
+ builder.add(organic, resultAfter(responseTimes[0]));
+ builder.add(dsp1, resultAfter(responseTimes[1]));
+ builder.add(dsp2, resultAfter(responseTimes[2]));
+ FederationResult federationResult = builder.build();
+ federationResult.waitForAll(50, clock);
+ assertEquals(3, federationResult.all().size());
+ for (FederationResult.TargetResult targetResult : federationResult.all()) {
+ Result result = targetResult.getOrTimeoutError();
+ 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));
+ }
+ }
+
+ private MockFutureResult resultAfter(int time) {
+ return new MockFutureResult(new Query(), time);
+ }
+
+ private boolean timedOut(Result result) {
+ ErrorMessage error = result.hits().getError();
+ if (error == null) return false;
+ return error.getCode() == ErrorMessage.timeoutCode;
+ }
+
+ private class MockFutureResult extends FutureResult {
+
+ private final int responseTime;
+ private final Query query;
+ private final long startTime;
+
+ MockFutureResult(Query query, int responseTime) {
+ super(() -> new Result(query), new Execution(Execution.Context.createContextStub()), query);
+ this.responseTime = responseTime;
+ this.query = query;
+ startTime = clock.millis();
+ }
+
+ @Override
+ public Result get() { throw new RuntimeException(); }
+
+ @Override
+ public Optional<Result> getIfAvailable(long timeout, TimeUnit timeunit) {
+ if (timeunit != TimeUnit.MILLISECONDS) throw new RuntimeException();
+
+ long elapsedTime = clock.millis() - startTime;
+ long leftUntilResponse = responseTime - elapsedTime;
+ if (leftUntilResponse > timeout) {
+ sleepUntil(timeout);
+ return Optional.empty();
+ }
+ else {
+ sleepUntil(leftUntilResponse);
+ return Optional.of(new Result(query));
+ }
+ }
+
+ private void sleepUntil(long time) {
+ if (time <= 0) return;
+ try {
+ Thread.sleep(time);
+ }
+ catch (InterruptedException e) {
+ }
+ }
+
+ @Override
+ public Query getQuery() {
+ return query;
+ }
+
+ }
+
+ private static class MockTarget extends FederationSearcher.Target {
+
+ private final Chain<Searcher> chain;
+ private final int timeout;
+
+ MockTarget(String id, int timeout) {
+ this.chain = new Chain<>(id);
+ this.timeout = timeout;
+ }
+
+ @Override
+ Chain<Searcher> getChain() { return chain; }
+
+ @Override
+ void modifyTargetQuery(Query query) { }
+
+ @Override
+ void modifyTargetResult(Result result) { }
+
+ @Override
+ public FederationOptions federationOptions() {
+ return new FederationOptions(false, timeout, true);
+ }
+
+ }
+
+}
diff --git a/container-search/src/test/java/com/yahoo/search/federation/FutureWaiterTest.java b/container-search/src/test/java/com/yahoo/search/federation/FutureWaiterTest.java
deleted file mode 100644
index 37969e12399..00000000000
--- a/container-search/src/test/java/com/yahoo/search/federation/FutureWaiterTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.search.federation;
-
-
-/**
- * @author tonytv
- */
-// TODO: Fix or remove!
-public class FutureWaiterTest {
-
-/*
-
- @MockClass(realClass = System.class)
- public static class MockSystem {
-
- private static long currentTime;
- private static boolean firstTime;
-
- private static final long startTime = 123;
-
- @Mock
- public static synchronized long currentTimeMillis() {
- if (firstTime) {
- firstTime = false;
- return startTime;
- }
- return currentTime;
- }
-
- static synchronized void setElapsedTime(long elapsedTime) {
- firstTime = true;
- currentTime = elapsedTime + startTime;
- }
- }
-
- @Mocked()
- FutureResult result1;
-
- @Mocked()
- FutureResult result2;
-
- @Mocked()
- FutureResult result3;
-
- @Mocked()
- FutureResult result4;
-
- @Before
- public void before() {
- Mockit.setUpMock(FutureWaiterTest.MockSystem.class);
- }
-
- @After
- public void after() {
- Mockit.tearDownMocks();
- }
-
- @Test
- public void require_time_to_wait_is_adjusted_for_elapsed_time() {
- MockSystem.setElapsedTime(300);
-
- FutureWaiter futureWaiter = new FutureWaiter();
- futureWaiter.add(result1, 350);
- futureWaiter.waitForFutures();
-
- new FullVerifications() {
- {
- result1.get(350 - 300, TimeUnit.MILLISECONDS);
- }
- };
- }
-
- @Test
- public void require_do_not_wait_for_expired_timeouts() {
- MockSystem.setElapsedTime(300);
-
- FutureWaiter futureWaiter = new FutureWaiter();
- futureWaiter.add(result1, 300);
- futureWaiter.add(result2, 290);
-
- futureWaiter.waitForFutures();
-
- new FullVerifications() {
- {}
- };
- }
-
- @Test
- public void require_wait_for_largest_timeout_first() throws InterruptedException {
- MockSystem.setElapsedTime(600);
-
- FutureWaiter futureWaiter = new FutureWaiter();
- futureWaiter.add(result1, 500);
- futureWaiter.add(result4, 800);
- futureWaiter.add(result2, 600);
- futureWaiter.add(result3, 700);
-
- futureWaiter.waitForFutures();
-
- new FullVerifications() {
- {
- result4.get(800 - 600, TimeUnit.MILLISECONDS);
- result3.get(700 - 600, TimeUnit.MILLISECONDS);
- }
- };
- }
-
- */
-}
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/test/FederationSearcherTestCase.java
index e4176bb6679..11fae387739 100644
--- a/container-search/src/test/java/com/yahoo/search/federation/test/FederationSearcherTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/federation/test/FederationSearcherTestCase.java
@@ -38,7 +38,7 @@ import static com.yahoo.search.federation.StrictContractsConfig.PropagateSourceP
* Test for federation searcher. The searcher is also tested in
* com.yahoo.prelude.searcher.test.BlendingSearcherTestCase.
*
- * @author <a href="mailto:arnebef@yahoo-inc.com">Arne Bergene Fossaa</a>
+ * @author Arne Bergene Fossaa
*/
@SuppressWarnings("deprecation")
public class FederationSearcherTestCase {
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/test/FederationTester.java
index 7b0451a01ba..7aa73c64d3a 100644
--- a/container-search/src/test/java/com/yahoo/search/federation/test/FederationTester.java
+++ b/container-search/src/test/java/com/yahoo/search/federation/test/FederationTester.java
@@ -18,6 +18,7 @@ import java.util.Collections;
* @author tonytv
*/
class FederationTester {
+
SearchChainResolver.Builder builder = new SearchChainResolver.Builder();
SearchChainRegistry registry = new SearchChainRegistry();