From e6894960f4584b5dd1cdf57ab5a20ca22594bcc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Fern=C3=A1ndez=20Casta=C3=B1o?= Date: Tue, 6 Apr 2021 14:58:57 +0200 Subject: [PATCH] Include URLHttpClientIOException on URLBlobContainerRetriesTests testReadBlobWithReadTimeouts (#71318) 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 --- .../url/URLBlobContainerRetriesTests.java | 14 ++++++++++++++ .../AbstractBlobContainerRetriesTestCase.java | 8 ++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/modules/repository-url/src/test/java/org/elasticsearch/common/blobstore/url/URLBlobContainerRetriesTests.java b/modules/repository-url/src/test/java/org/elasticsearch/common/blobstore/url/URLBlobContainerRetriesTests.java index 12841ea586bd2..538b148b30bce 100644 --- a/modules/repository-url/src/test/java/org/elasticsearch/common/blobstore/url/URLBlobContainerRetriesTests.java +++ b/modules/repository-url/src/test/java/org/elasticsearch/common/blobstore/url/URLBlobContainerRetriesTests.java @@ -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; @@ -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; @@ -56,6 +62,14 @@ protected Class unresponsiveExceptionType() { return URLHttpClientIOException.class; } + @Override + protected Matcher 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, diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/AbstractBlobContainerRetriesTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/AbstractBlobContainerRetriesTestCase.java index 730bc1aa284e2..a63a633b95add 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/AbstractBlobContainerRetriesTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/AbstractBlobContainerRetriesTestCase.java @@ -79,6 +79,11 @@ protected abstract BlobContainer createBlobContainer(@Nullable Integer maxRetrie @Nullable Boolean disableChunkedEncoding, @Nullable ByteSizeValue bufferSize); + protected org.hamcrest.Matcher 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); @@ -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")));