|
@@ -20,6 +20,7 @@ package org.apache.hadoop.fs.azurebfs;
|
|
|
|
|
|
import java.io.FileNotFoundException;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
|
|
+import java.net.SocketException;
|
|
import java.net.SocketTimeoutException;
|
|
import java.net.SocketTimeoutException;
|
|
import java.net.URL;
|
|
import java.net.URL;
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
@@ -42,6 +43,7 @@ import org.apache.hadoop.fs.LocatedFileStatus;
|
|
import org.apache.hadoop.fs.Path;
|
|
import org.apache.hadoop.fs.Path;
|
|
import org.apache.hadoop.fs.azurebfs.constants.FSOperationType;
|
|
import org.apache.hadoop.fs.azurebfs.constants.FSOperationType;
|
|
import org.apache.hadoop.fs.azurebfs.constants.HttpHeaderConfigurations;
|
|
import org.apache.hadoop.fs.azurebfs.constants.HttpHeaderConfigurations;
|
|
|
|
+import org.apache.hadoop.fs.azurebfs.contracts.exceptions.AbfsDriverException;
|
|
import org.apache.hadoop.fs.azurebfs.contracts.exceptions.AbfsRestOperationException;
|
|
import org.apache.hadoop.fs.azurebfs.contracts.exceptions.AbfsRestOperationException;
|
|
import org.apache.hadoop.fs.azurebfs.services.AbfsBlobClient;
|
|
import org.apache.hadoop.fs.azurebfs.services.AbfsBlobClient;
|
|
import org.apache.hadoop.fs.azurebfs.services.AbfsClientHandler;
|
|
import org.apache.hadoop.fs.azurebfs.services.AbfsClientHandler;
|
|
@@ -63,7 +65,10 @@ import static org.apache.hadoop.fs.azurebfs.constants.AbfsHttpConstants.ROOT_PAT
|
|
import static org.apache.hadoop.fs.azurebfs.constants.AbfsHttpConstants.TRUE;
|
|
import static org.apache.hadoop.fs.azurebfs.constants.AbfsHttpConstants.TRUE;
|
|
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.AZURE_LIST_MAX_RESULTS;
|
|
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.AZURE_LIST_MAX_RESULTS;
|
|
import static org.apache.hadoop.fs.azurebfs.constants.HttpHeaderConfigurations.X_MS_METADATA_PREFIX;
|
|
import static org.apache.hadoop.fs.azurebfs.constants.HttpHeaderConfigurations.X_MS_METADATA_PREFIX;
|
|
|
|
+import static org.apache.hadoop.fs.azurebfs.services.AbfsErrors.ERR_BLOB_LIST_PARSING;
|
|
import static org.apache.hadoop.fs.azurebfs.services.RenameAtomicity.SUFFIX;
|
|
import static org.apache.hadoop.fs.azurebfs.services.RenameAtomicity.SUFFIX;
|
|
|
|
+import static org.apache.hadoop.fs.azurebfs.services.RetryReasonConstants.CONNECTION_RESET_MESSAGE;
|
|
|
|
+import static org.apache.hadoop.fs.azurebfs.services.RetryReasonConstants.CONNECTION_TIMEOUT_ABBREVIATION;
|
|
import static org.apache.hadoop.fs.azurebfs.services.RetryReasonConstants.CONNECTION_TIMEOUT_JDK_MESSAGE;
|
|
import static org.apache.hadoop.fs.azurebfs.services.RetryReasonConstants.CONNECTION_TIMEOUT_JDK_MESSAGE;
|
|
import static org.apache.hadoop.fs.contract.ContractTestUtils.assertMkdirs;
|
|
import static org.apache.hadoop.fs.contract.ContractTestUtils.assertMkdirs;
|
|
import static org.apache.hadoop.fs.contract.ContractTestUtils.createFile;
|
|
import static org.apache.hadoop.fs.contract.ContractTestUtils.createFile;
|
|
@@ -130,7 +135,9 @@ public class ITestAzureBlobFileSystemListStatus extends
|
|
|
|
|
|
/**
|
|
/**
|
|
* Test to verify that each paginated call to ListBlobs uses a new tracing context.
|
|
* Test to verify that each paginated call to ListBlobs uses a new tracing context.
|
|
- * @throws Exception
|
|
|
|
|
|
+ * Test also verifies that the retry policy is called when a SocketTimeoutException
|
|
|
|
+ * Test also verifies that empty list with valid continuation token is handled.
|
|
|
|
+ * @throws Exception if there is an error or test assertions fails.
|
|
*/
|
|
*/
|
|
@Test
|
|
@Test
|
|
public void testListPathTracingContext() throws Exception {
|
|
public void testListPathTracingContext() throws Exception {
|
|
@@ -160,6 +167,10 @@ public class ITestAzureBlobFileSystemListStatus extends
|
|
List<FileStatus> fileStatuses = new ArrayList<>();
|
|
List<FileStatus> fileStatuses = new ArrayList<>();
|
|
spiedStore.listStatus(new Path("/"), "", fileStatuses, true, null, spiedTracingContext);
|
|
spiedStore.listStatus(new Path("/"), "", fileStatuses, true, null, spiedTracingContext);
|
|
|
|
|
|
|
|
+ // Assert that there were retries due to SocketTimeoutException
|
|
|
|
+ Mockito.verify(spiedClient, Mockito.times(1))
|
|
|
|
+ .getRetryPolicy(CONNECTION_TIMEOUT_ABBREVIATION);
|
|
|
|
+
|
|
// Assert that there were 2 paginated ListPath calls were made 1 and 2.
|
|
// Assert that there were 2 paginated ListPath calls were made 1 and 2.
|
|
// 1. Without continuation token
|
|
// 1. Without continuation token
|
|
Mockito.verify(spiedClient, times(1)).listPath(
|
|
Mockito.verify(spiedClient, times(1)).listPath(
|
|
@@ -176,6 +187,31 @@ public class ITestAzureBlobFileSystemListStatus extends
|
|
Mockito.verify(spiedTracingContext, times(0)).constructHeader(any(), any(), any());
|
|
Mockito.verify(spiedTracingContext, times(0)).constructHeader(any(), any(), any());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Test
|
|
|
|
+ public void testListPathParsingFailure() throws Exception {
|
|
|
|
+ assumeBlobServiceType();
|
|
|
|
+ AzureBlobFileSystem spiedFs = Mockito.spy(getFileSystem());
|
|
|
|
+ AzureBlobFileSystemStore spiedStore = Mockito.spy(spiedFs.getAbfsStore());
|
|
|
|
+ AbfsBlobClient spiedClient = Mockito.spy(spiedStore.getClientHandler()
|
|
|
|
+ .getBlobClient());
|
|
|
|
+ Mockito.doReturn(spiedStore).when(spiedFs).getAbfsStore();
|
|
|
|
+ Mockito.doReturn(spiedClient).when(spiedStore).getClient();
|
|
|
|
+
|
|
|
|
+ Mockito.doThrow(new SocketException(CONNECTION_RESET_MESSAGE)).when(spiedClient).filterDuplicateEntriesAndRenamePendingFiles(any(), any());
|
|
|
|
+ List<FileStatus> fileStatuses = new ArrayList<>();
|
|
|
|
+ AbfsDriverException ex = intercept(AbfsDriverException.class,
|
|
|
|
+ () -> {
|
|
|
|
+ spiedStore.listStatus(new Path("/"), "", fileStatuses,
|
|
|
|
+ true, null, getTestTracingContext(spiedFs, true));
|
|
|
|
+ });
|
|
|
|
+ Assertions.assertThat(ex.getStatusCode())
|
|
|
|
+ .describedAs("Expecting Network Error status code")
|
|
|
|
+ .isEqualTo(-1);
|
|
|
|
+ Assertions.assertThat(ex.getErrorMessage())
|
|
|
|
+ .describedAs("Expecting COPY_ABORTED error code")
|
|
|
|
+ .contains(ERR_BLOB_LIST_PARSING);
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Creates a file, verifies that listStatus returns it,
|
|
* Creates a file, verifies that listStatus returns it,
|
|
* even while the file is still open for writing.
|
|
* even while the file is still open for writing.
|