|
8 | 8 |
|
9 | 9 | package org.elasticsearch.action.admin.indices.create; |
10 | 10 |
|
| 11 | +import io.netty.handler.codec.http.HttpMethod; |
| 12 | + |
11 | 13 | import org.elasticsearch.action.ActionListener; |
12 | 14 | import org.elasticsearch.action.ActionRequestBuilder; |
13 | 15 | import org.elasticsearch.action.UnavailableShardsException; |
14 | 16 | import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse; |
15 | 17 | import org.elasticsearch.action.admin.indices.alias.Alias; |
16 | 18 | import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse; |
| 19 | +import org.elasticsearch.action.support.ActionTestUtils; |
17 | 20 | import org.elasticsearch.action.support.ActiveShardCount; |
18 | 21 | import org.elasticsearch.action.support.IndicesOptions; |
| 22 | +import org.elasticsearch.action.support.PlainActionFuture; |
19 | 23 | import org.elasticsearch.action.support.master.AcknowledgedResponse; |
| 24 | +import org.elasticsearch.client.Response; |
20 | 25 | import org.elasticsearch.cluster.ClusterState; |
21 | 26 | import org.elasticsearch.cluster.metadata.IndexMetadata; |
22 | 27 | import org.elasticsearch.cluster.metadata.MappingMetadata; |
23 | 28 | import org.elasticsearch.cluster.metadata.Metadata; |
| 29 | +import org.elasticsearch.cluster.service.ClusterService; |
| 30 | +import org.elasticsearch.common.Priority; |
24 | 31 | import org.elasticsearch.common.settings.Settings; |
| 32 | +import org.elasticsearch.common.util.concurrent.FutureUtils; |
25 | 33 | import org.elasticsearch.core.TimeValue; |
26 | 34 | import org.elasticsearch.index.IndexNotFoundException; |
27 | 35 | import org.elasticsearch.index.IndexService; |
|
31 | 39 | import org.elasticsearch.test.ESIntegTestCase; |
32 | 40 | import org.elasticsearch.test.ESIntegTestCase.ClusterScope; |
33 | 41 | import org.elasticsearch.test.ESIntegTestCase.Scope; |
| 42 | +import org.elasticsearch.test.rest.ESRestTestCase; |
34 | 43 | import org.elasticsearch.xcontent.XContentFactory; |
35 | 44 |
|
| 45 | +import java.io.IOException; |
36 | 46 | import java.util.Map; |
37 | 47 | import java.util.concurrent.CountDownLatch; |
| 48 | +import java.util.concurrent.CyclicBarrier; |
| 49 | +import java.util.concurrent.TimeUnit; |
38 | 50 | import java.util.concurrent.atomic.AtomicInteger; |
39 | 51 | import java.util.function.BiFunction; |
40 | 52 |
|
| 53 | +import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_NUMBER_OF_REPLICAS; |
41 | 54 | import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_WAIT_FOR_ACTIVE_SHARDS; |
| 55 | +import static org.elasticsearch.common.xcontent.support.XContentMapValues.extractValue; |
42 | 56 | import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; |
43 | 57 | import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked; |
44 | 58 | import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailuresAndResponse; |
| 59 | +import static org.elasticsearch.test.rest.ESRestTestCase.entityAsMap; |
45 | 60 | import static org.hamcrest.Matchers.allOf; |
46 | 61 | import static org.hamcrest.Matchers.equalTo; |
47 | 62 | import static org.hamcrest.Matchers.greaterThanOrEqualTo; |
|
53 | 68 | @ClusterScope(scope = Scope.TEST) |
54 | 69 | public class CreateIndexIT extends ESIntegTestCase { |
55 | 70 |
|
| 71 | + @Override |
| 72 | + protected boolean addMockHttpTransport() { |
| 73 | + return false; // expose HTTP requests |
| 74 | + } |
| 75 | + |
56 | 76 | public void testCreationDateGivenFails() { |
57 | 77 | try { |
58 | 78 | prepareCreate("test").setSettings(Settings.builder().put(IndexMetadata.SETTING_CREATION_DATE, 4L)).get(); |
@@ -370,4 +390,38 @@ public void testIndexNameInResponse() { |
370 | 390 | assertEquals("Should have index name in response", "foo", response.index()); |
371 | 391 | } |
372 | 392 |
|
| 393 | + public void testInfiniteAckTimeout() throws IOException { |
| 394 | + final var clusterService = internalCluster().getInstance(ClusterService.class); |
| 395 | + final var barrier = new CyclicBarrier(2); |
| 396 | + clusterService.getClusterApplierService().runOnApplierThread("block for test", Priority.NORMAL, cs -> { |
| 397 | + safeAwait(barrier); |
| 398 | + safeAwait(barrier); |
| 399 | + }, ActionListener.noop()); |
| 400 | + |
| 401 | + safeAwait(barrier); |
| 402 | + |
| 403 | + final var request = ESRestTestCase.newXContentRequest( |
| 404 | + HttpMethod.PUT, |
| 405 | + "testindex", |
| 406 | + (builder, params) -> builder.startObject("settings") |
| 407 | + .field(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1) |
| 408 | + .field(SETTING_NUMBER_OF_REPLICAS, internalCluster().numDataNodes() - 1) |
| 409 | + .endObject() |
| 410 | + ); |
| 411 | + request.addParameter("timeout", "-1"); |
| 412 | + final var responseFuture = new PlainActionFuture<Response>(); |
| 413 | + getRestClient().performRequestAsync(request, ActionTestUtils.wrapAsRestResponseListener(responseFuture)); |
| 414 | + |
| 415 | + if (randomBoolean()) { |
| 416 | + safeSleep(scaledRandomIntBetween(1, 100)); |
| 417 | + } |
| 418 | + |
| 419 | + assertFalse(responseFuture.isDone()); |
| 420 | + safeAwait(barrier); |
| 421 | + |
| 422 | + final var response = FutureUtils.get(responseFuture, 10, TimeUnit.SECONDS); |
| 423 | + assertEquals(200, response.getStatusLine().getStatusCode()); |
| 424 | + assertTrue((boolean) extractValue("acknowledged", entityAsMap(response))); |
| 425 | + } |
| 426 | + |
373 | 427 | } |
0 commit comments