|
13 | 13 | import com.sun.net.httpserver.HttpHandler; |
14 | 14 |
|
15 | 15 | import org.elasticsearch.cluster.node.DiscoveryNode; |
| 16 | +import org.elasticsearch.common.Randomness; |
16 | 17 | import org.elasticsearch.common.blobstore.BlobContainer; |
17 | 18 | import org.elasticsearch.common.blobstore.BlobPath; |
18 | 19 | import org.elasticsearch.common.blobstore.OperationPurpose; |
| 20 | +import org.elasticsearch.common.bytes.BytesArray; |
19 | 21 | import org.elasticsearch.common.bytes.BytesReference; |
20 | 22 | import org.elasticsearch.core.SuppressForbidden; |
21 | 23 | import org.elasticsearch.plugins.PluginsService; |
|
31 | 33 | import java.io.IOException; |
32 | 34 | import java.nio.ByteBuffer; |
33 | 35 | import java.nio.charset.StandardCharsets; |
| 36 | +import java.util.ArrayList; |
34 | 37 | import java.util.List; |
35 | 38 | import java.util.Map; |
36 | 39 | import java.util.Queue; |
|
43 | 46 | import java.util.stream.IntStream; |
44 | 47 |
|
45 | 48 | import static org.elasticsearch.repositories.azure.AbstractAzureServerTestCase.randomBlobContent; |
| 49 | +import static org.elasticsearch.repositories.blobstore.BlobStoreTestUtil.randomPurpose; |
46 | 50 | import static org.hamcrest.Matchers.greaterThanOrEqualTo; |
47 | 51 | import static org.hamcrest.Matchers.hasSize; |
48 | 52 | import static org.hamcrest.Matchers.lessThanOrEqualTo; |
@@ -225,6 +229,34 @@ public void testRequestTimeIsAccurate() throws IOException { |
225 | 229 | assertThat(recordedRequestTime, lessThanOrEqualTo(elapsedTimeMillis)); |
226 | 230 | } |
227 | 231 |
|
| 232 | + public void testBatchDeleteFailure() throws IOException { |
| 233 | + final String repository = createRepository(randomRepositoryName()); |
| 234 | + final String dataNodeName = internalCluster().getNodeNameThat(DiscoveryNode::canContainData); |
| 235 | + final BlobContainer container = getBlobContainer(dataNodeName, repository); |
| 236 | + |
| 237 | + final List<String> blobsToDelete = new ArrayList<>(); |
| 238 | + for (int i = 0; i < 10; i++) { |
| 239 | + byte[] bytes = randomBytes(randomInt(100)); |
| 240 | + String blobName = "index-" + randomAlphaOfLength(10); |
| 241 | + container.writeBlob(randomPurpose(), blobName, new BytesArray(bytes), false); |
| 242 | + blobsToDelete.add(blobName); |
| 243 | + } |
| 244 | + Randomness.shuffle(blobsToDelete); |
| 245 | + clearMetrics(dataNodeName); |
| 246 | + |
| 247 | + // Exhaust the retries |
| 248 | + IntStream.range(0, MAX_RETRIES + 1).forEach(i -> requestHandlers.offer(new FixedRequestHandler(RestStatus.INTERNAL_SERVER_ERROR))); |
| 249 | + |
| 250 | + final OperationPurpose deletePurpose = randomPurpose(); |
| 251 | + assertThrows(IOException.class, () -> container.deleteBlobsIgnoringIfNotExists(deletePurpose, blobsToDelete.iterator())); |
| 252 | + |
| 253 | + metricsAsserter(dataNodeName, deletePurpose, AzureBlobStore.Operation.BLOB_BATCH, repository).expectMetrics() |
| 254 | + .withRequests(MAX_RETRIES + 1) |
| 255 | + .withExceptions(MAX_RETRIES + 1) |
| 256 | + .withThrottles(0) |
| 257 | + .forResult(MetricsAsserter.Result.Exception); |
| 258 | + } |
| 259 | + |
228 | 260 | private void clearMetrics(String discoveryNode) { |
229 | 261 | internalCluster().getInstance(PluginsService.class, discoveryNode) |
230 | 262 | .filterPlugins(TestTelemetryPlugin.class) |
|
0 commit comments