Skip to content

Commit

Permalink
Include URLHttpClientIOException on URLBlobContainerRetriesTests test…
Browse files Browse the repository at this point in the history
…ReadBlobWithReadTimeouts (#71344)

In some scenarios where the read timeout is too tight it's possible
that the http request times out before the response headers have
been received, in that case an URLHttpClientIOException is thrown.
This commit adds that exception type to the expected set of read timeout
exceptions.

Closes #70931
Backport of #71318
  • Loading branch information
fcofdez authored Apr 6, 2021
1 parent e2544d0 commit 6735350
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

package org.elasticsearch.common.blobstore.url;

import org.apache.http.ConnectionClosedException;
import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.blobstore.BlobContainer;
import org.elasticsearch.common.blobstore.BlobPath;
Expand All @@ -19,14 +20,19 @@
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.repositories.blobstore.AbstractBlobContainerRetriesTestCase;
import org.hamcrest.Matcher;
import org.junit.AfterClass;
import org.junit.BeforeClass;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;

import static org.hamcrest.Matchers.either;
import static org.hamcrest.Matchers.instanceOf;

@SuppressForbidden(reason = "use a http server")
public class URLBlobContainerRetriesTests extends AbstractBlobContainerRetriesTestCase {
private static URLHttpClient.Factory factory;
Expand Down Expand Up @@ -57,6 +63,14 @@ protected Class<? extends Exception> unresponsiveExceptionType() {
return URLHttpClientIOException.class;
}

@Override
protected Matcher<Object> readTimeoutExceptionMatcher() {
// If the timeout is too tight it's possible that an URLHttpClientIOException is thrown as that
// exception is thrown before reading data from the response body.
return either(instanceOf(SocketTimeoutException.class)).or(instanceOf(ConnectionClosedException.class))
.or(instanceOf(RuntimeException.class)).or(instanceOf(URLHttpClientIOException.class));
}

@Override
protected BlobContainer createBlobContainer(Integer maxRetries,
TimeValue readTimeout,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ protected abstract BlobContainer createBlobContainer(@Nullable Integer maxRetrie
@Nullable Boolean disableChunkedEncoding,
@Nullable ByteSizeValue bufferSize);

protected org.hamcrest.Matcher<Object> readTimeoutExceptionMatcher() {
return either(instanceOf(SocketTimeoutException.class)).or(instanceOf(ConnectionClosedException.class))
.or(instanceOf(RuntimeException.class));
}

public void testReadNonexistentBlobThrowsNoSuchFileException() {
final BlobContainer blobContainer = createBlobContainer(between(1, 5), null, null, null);
final long position = randomLongBetween(0, MAX_RANGE_VAL);
Expand Down Expand Up @@ -236,8 +241,7 @@ public void testReadBlobWithReadTimeouts() {
Streams.readFully(stream);
}
});
assertThat(exception, either(instanceOf(SocketTimeoutException.class)).or(instanceOf(ConnectionClosedException.class))
.or(instanceOf(RuntimeException.class)));
assertThat(exception, readTimeoutExceptionMatcher());
assertThat(exception.getMessage().toLowerCase(Locale.ROOT), either(containsString("read timed out")).or(
containsString("premature end of chunk coded message body: closing chunk expected")).or(containsString("Read timed out"))
.or(containsString("unexpected end of file from server")));
Expand Down

0 comments on commit 6735350

Please sign in to comment.