summaryrefslogtreecommitdiffstats
path: root/vespa-http-client/src/test/java
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@oath.com>2018-04-03 17:37:17 +0200
committerBjørn Christian Seime <bjorncs@oath.com>2018-04-03 17:37:17 +0200
commit2f45e213261e98a272a171b6fb5d07cf77496f33 (patch)
tree98f12ffd9157f6e1519c23fcc74da22b4d1267c9 /vespa-http-client/src/test/java
parent81b0d89f8e9b788da56c9cea3b5cabb3d00c42dc (diff)
Add reporting of endpoint errors to FeedClient.ResultCallback
Extend the ResultCallback interface with the method onEndpointException which users may implement to observe endpoint failures.
Diffstat (limited to 'vespa-http-client/src/test/java')
-rw-r--r--vespa-http-client/src/test/java/com/yahoo/vespa/http/client/core/communication/IOThreadTest.java73
1 files changed, 73 insertions, 0 deletions
diff --git a/vespa-http-client/src/test/java/com/yahoo/vespa/http/client/core/communication/IOThreadTest.java b/vespa-http-client/src/test/java/com/yahoo/vespa/http/client/core/communication/IOThreadTest.java
index a894aa5af1d..f2a63895fd4 100644
--- a/vespa-http-client/src/test/java/com/yahoo/vespa/http/client/core/communication/IOThreadTest.java
+++ b/vespa-http-client/src/test/java/com/yahoo/vespa/http/client/core/communication/IOThreadTest.java
@@ -1,27 +1,41 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.http.client.core.communication;
+import com.yahoo.vespa.http.client.FeedConnectException;
+import com.yahoo.vespa.http.client.FeedEndpointException;
+import com.yahoo.vespa.http.client.FeedProtocolException;
import com.yahoo.vespa.http.client.Result;
import com.yahoo.vespa.http.client.V3HttpAPITest;
+import com.yahoo.vespa.http.client.config.Endpoint;
import com.yahoo.vespa.http.client.core.Document;
import com.yahoo.vespa.http.client.core.EndpointResult;
+import com.yahoo.vespa.http.client.core.ServerResponseException;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
public class IOThreadTest {
+
+ private static final Endpoint ENDPOINT = Endpoint.create("myhost");
+
final EndpointResultQueue endpointResultQueue = mock(EndpointResultQueue.class);
final ApacheGatewayConnection apacheGatewayConnection = mock(ApacheGatewayConnection.class);
final String exceptionMessage = "SOME EXCEPTION FOO";
@@ -34,6 +48,10 @@ public class IOThreadTest {
V3HttpAPITest.documents.get(1).getContents(), null /* context */);
DocumentQueue documentQueue = new DocumentQueue(4);
+ public IOThreadTest() {
+ when(apacheGatewayConnection.getEndpoint()).thenReturn(ENDPOINT);
+ }
+
/**
* Set up mock so that it can handle both failDocument() and resultReceived().
* @param expectedDocIdFail on failure, this has to be the doc id, or the mock will fail.
@@ -124,4 +142,59 @@ public class IOThreadTest {
assert (latch.await(120, TimeUnit.SECONDS));
}
}
+
+ @Test
+ public void requireThatEndpointProtocolExceptionsArePropagated()
+ throws IOException, ServerResponseException, InterruptedException, TimeoutException, ExecutionException {
+ when(apacheGatewayConnection.connect()).thenReturn(true);
+ int errorCode = 403;
+ String errorMessage = "Not authorized";
+ doThrow(new ServerResponseException(errorCode, errorMessage)).when(apacheGatewayConnection).handshake();
+ Future<FeedEndpointException> futureException = endpointErrorCapturer(endpointResultQueue);
+
+ try (IOThread ioThread = new IOThread(
+ endpointResultQueue, apacheGatewayConnection, 0, 0, 10, 10L, documentQueue, 0)) {
+ ioThread.post(doc1);
+ FeedEndpointException reportedException = futureException.get(120, TimeUnit.SECONDS);
+ assertThat(reportedException, instanceOf(FeedProtocolException.class));
+ FeedProtocolException actualException = (FeedProtocolException) reportedException;
+ assertThat(actualException.getHttpStatusCode(), equalTo(errorCode));
+ assertThat(actualException.getHttpResponseMessage(), equalTo(errorMessage));
+ assertThat(actualException.getEndpoint(), equalTo(ENDPOINT));
+ assertThat(actualException.getMessage(), equalTo("Endpoint 'myhost:4080' returned an error on handshake: 403 - Not authorized"));
+ }
+ }
+
+ @Test
+ public void requireThatEndpointConnectExceptionsArePropagated()
+ throws IOException, ServerResponseException, InterruptedException, TimeoutException, ExecutionException {
+ when(apacheGatewayConnection.connect()).thenReturn(true);
+ String errorMessage = "generic error message";
+ IOException cause = new IOException(errorMessage);
+ doThrow(cause).when(apacheGatewayConnection).handshake();
+ Future<FeedEndpointException> futureException = endpointErrorCapturer(endpointResultQueue);
+
+ try (IOThread ioThread = new IOThread(
+ endpointResultQueue, apacheGatewayConnection, 0, 0, 10, 10L, documentQueue, 0)) {
+ ioThread.post(doc1);
+ FeedEndpointException reportedException = futureException.get(120, TimeUnit.SECONDS);
+ assertThat(reportedException, instanceOf(FeedConnectException.class));
+ FeedConnectException actualException = (FeedConnectException) reportedException;
+ assertThat(actualException.getCause(), equalTo(cause));
+ assertThat(actualException.getEndpoint(), equalTo(ENDPOINT));
+ assertThat(actualException.getMessage(), equalTo("Handshake to endpoint 'myhost:4080' failed: generic error message"));
+ }
+ }
+
+ private static Future<FeedEndpointException> endpointErrorCapturer(EndpointResultQueue endpointResultQueue) {
+ CompletableFuture<FeedEndpointException> futureResult = new CompletableFuture<>();
+ doAnswer(invocation -> {
+ if (futureResult.isDone()) return null;
+ FeedEndpointException reportedException = (FeedEndpointException) invocation.getArguments()[0];
+ futureResult.complete(reportedException);
+ return null;
+ }).when(endpointResultQueue).onEndpointError(any());
+ return futureResult;
+ }
+
}