Convert flaky yml tests to EsRestTestCases (#63634) (#64581)

The yml "Test Invalid Move To Step With Invalid Next Step" worked based on
assuming the current step is a particular one. As we can't control the
timing of ILM and we can't busy assert in yml test, this converts the
test to a java test and makes use of `assertBusy`

This converts the explain lifecycle yml tests that depende on ILM having run
at least once to a java integration test that makes use of `assertBusy`.

(cherry picked from commit 6afd0422ed5ff0e3a2e5661f0e6d192bdad9af4f)
Signed-off-by: Andrei Dan <andrei.dan@elastic.co>
This commit is contained in:
Andrei Dan 2020-11-04 12:39:26 +00:00 committed by GitHub
parent ae186a6214
commit 835ebcfff2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 468 additions and 437 deletions

View File

@ -46,6 +46,9 @@ import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.test.ESTestCase.randomAlphaOfLengthBetween;
import static org.elasticsearch.test.ESTestCase.randomBoolean;
import static org.elasticsearch.test.rest.ESRestTestCase.ensureGreen;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
/**
* This class provides the operational REST functions needed to control an ILM time series lifecycle.
@ -104,6 +107,17 @@ public final class TimeSeriesRestDriver {
logger.info(response.getStatusLine());
}
public static void index(RestClient client, String index, String id, Object... fields) throws IOException {
XContentBuilder document = jsonBuilder().startObject();
for (int i = 0; i < fields.length; i += 2) {
document.field((String) fields[i], fields[i + 1]);
}
document.endObject();
final Request request = new Request("POST", "/" + index + "/_doc/" + id);
request.setJsonEntity(Strings.toString(document));
assertThat(client.performRequest(request).getStatusLine().getStatusCode(), anyOf(equalTo(200), equalTo(201)));
}
public static void createNewSingletonPolicy(RestClient client, String policyName, String phaseName, LifecycleAction action)
throws IOException {
createNewSingletonPolicy(client, policyName, phaseName, action, TimeValue.ZERO);
@ -228,6 +242,14 @@ public final class TimeSeriesRestDriver {
ensureGreen(index);
}
public static void createIndexWithSettings(RestClient client, String index, Settings.Builder settings) throws IOException {
Request request = new Request("PUT", "/" + index);
request.setJsonEntity("{\n \"settings\": " + Strings.toString(settings.build()) + "}");
client.performRequest(request);
// wait for the shards to initialize
ensureGreen(index);
}
@SuppressWarnings("unchecked")
public static Integer getNumberOfSegments(RestClient client, String index) throws IOException {
Response response = client.performRequest(new Request("GET", index + "/_segments"));

View File

@ -0,0 +1,205 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.ilm;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.client.Request;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.test.rest.ESRestTestCase;
import org.elasticsearch.xpack.core.ilm.DeleteAction;
import org.elasticsearch.xpack.core.ilm.LifecycleAction;
import org.elasticsearch.xpack.core.ilm.LifecyclePolicy;
import org.elasticsearch.xpack.core.ilm.LifecycleSettings;
import org.elasticsearch.xpack.core.ilm.Phase;
import org.elasticsearch.xpack.core.ilm.RolloverAction;
import org.elasticsearch.xpack.core.ilm.ShrinkAction;
import org.junit.Before;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.createFullPolicy;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.createIndexWithSettings;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.createNewSingletonPolicy;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.explain;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.explainIndex;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
public class ExplainLifecycleIT extends ESRestTestCase {
private static final Logger logger = LogManager.getLogger(ExplainLifecycleIT.class);
private static final String FAILED_STEP_RETRY_COUNT_FIELD = "failed_step_retry_count";
private static final String IS_AUTO_RETRYABLE_ERROR_FIELD = "is_auto_retryable_error";
private String policy;
private String index;
private String alias;
@Before
public void refreshIndex() {
index = "index-" + randomAlphaOfLength(10).toLowerCase(Locale.ROOT);
policy = "policy-" + randomAlphaOfLength(5);
alias = "alias-" + randomAlphaOfLength(5);
}
public void testExplainFilters() throws Exception {
String goodIndex = index + "-good-000001";
String errorIndex = index + "-error";
String nonexistantPolicyIndex = index + "-nonexistant-policy";
String unmanagedIndex = index + "-unmanaged";
createFullPolicy(client(), policy, TimeValue.ZERO);
{
// Create a "shrink-only-policy"
Map<String, LifecycleAction> warmActions = new HashMap<>();
warmActions.put(ShrinkAction.NAME, new ShrinkAction(17));
Map<String, Phase> phases = new HashMap<>();
phases.put("warm", new Phase("warm", TimeValue.ZERO, warmActions));
LifecyclePolicy lifecyclePolicy = new LifecyclePolicy("shrink-only-policy", phases);
// PUT policy
XContentBuilder builder = jsonBuilder();
lifecyclePolicy.toXContent(builder, null);
final StringEntity entity = new StringEntity(
"{ \"policy\":" + Strings.toString(builder) + "}", ContentType.APPLICATION_JSON);
Request request = new Request("PUT", "_ilm/policy/shrink-only-policy");
request.setEntity(entity);
assertOK(client().performRequest(request));
}
createIndexWithSettings(client(), goodIndex, alias, Settings.builder()
.put(RolloverAction.LIFECYCLE_ROLLOVER_ALIAS, alias)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put(LifecycleSettings.LIFECYCLE_NAME, policy)
);
createIndexWithSettings(client(), errorIndex, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put(LifecycleSettings.LIFECYCLE_NAME, "shrink-only-policy")
);
createIndexWithSettings(client(), nonexistantPolicyIndex, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put(LifecycleSettings.LIFECYCLE_NAME, randomValueOtherThan(policy, () -> randomAlphaOfLengthBetween(3, 10))));
createIndexWithSettings(client(), unmanagedIndex, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0));
assertBusy(() -> {
Map<String, Map<String, Object>> explainResponse = explain(client(), index + "*", false, false);
assertNotNull(explainResponse);
assertThat(explainResponse,
allOf(hasKey(goodIndex), hasKey(errorIndex), hasKey(nonexistantPolicyIndex), hasKey(unmanagedIndex)));
Map<String, Map<String, Object>> onlyManagedResponse = explain(client(), index + "*", false, true);
assertNotNull(onlyManagedResponse);
assertThat(onlyManagedResponse, allOf(hasKey(goodIndex), hasKey(errorIndex), hasKey(nonexistantPolicyIndex)));
assertThat(onlyManagedResponse, not(hasKey(unmanagedIndex)));
Map<String, Map<String, Object>> onlyErrorsResponse = explain(client(), index + "*", true, true);
assertNotNull(onlyErrorsResponse);
assertThat(onlyErrorsResponse, allOf(hasKey(errorIndex), hasKey(nonexistantPolicyIndex)));
assertThat(onlyErrorsResponse, allOf(not(hasKey(goodIndex)), not(hasKey(unmanagedIndex))));
});
}
public void testExplainIndexContainsAutomaticRetriesInformation() throws Exception {
createFullPolicy(client(), policy, TimeValue.ZERO);
// create index without alias so the rollover action fails and is retried
createIndexWithSettings(client(), index, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put(LifecycleSettings.LIFECYCLE_NAME, policy)
);
assertBusy(() -> {
Map<String, Object> explainIndex = explainIndex(client(), index);
assertThat((Integer) explainIndex.get(FAILED_STEP_RETRY_COUNT_FIELD), greaterThanOrEqualTo(1));
assertThat(explainIndex.get(IS_AUTO_RETRYABLE_ERROR_FIELD), is(true));
});
}
@SuppressWarnings("unchecked")
public void testExplainIndicesWildcard() throws Exception {
createNewSingletonPolicy(client(), policy, "delete", new DeleteAction(), TimeValue.timeValueDays(100));
String firstIndex = this.index + "-first";
String secondIndex = this.index + "-second";
String unmanagedIndex = this.index + "-unmanaged";
String indexWithMissingPolicy = this.index + "-missing_policy";
createIndexWithSettings(client(), firstIndex, alias + firstIndex, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put(LifecycleSettings.LIFECYCLE_NAME, policy));
createIndexWithSettings(client(), secondIndex, alias + secondIndex, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put(LifecycleSettings.LIFECYCLE_NAME, policy));
createIndexWithSettings(client(), unmanagedIndex, alias + unmanagedIndex, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0));
String missingPolicyName = "missing_policy_";
createIndexWithSettings(client(), indexWithMissingPolicy, alias + indexWithMissingPolicy, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put(LifecycleSettings.LIFECYCLE_NAME, missingPolicyName));
assertBusy(() -> {
Map<String, Map<String, Object>> explain = explain(client(), this.index + "*", false, false);
assertManagedIndex(explain.get(firstIndex));
assertManagedIndex(explain.get(secondIndex));
assertUnmanagedIndex(explain.get(unmanagedIndex));
Map<String, Object> explainIndexWithMissingPolicy = explain.get(indexWithMissingPolicy);
assertThat(explainIndexWithMissingPolicy.get("managed"), is(true));
assertThat(explainIndexWithMissingPolicy.get("policy"), is(missingPolicyName));
assertThat(explainIndexWithMissingPolicy.get("phase"), is(nullValue()));
assertThat(explainIndexWithMissingPolicy.get("action"), is(nullValue()));
assertThat(explainIndexWithMissingPolicy.get("step"), is(nullValue()));
assertThat(explainIndexWithMissingPolicy.get("age"), is(nullValue()));
assertThat(explainIndexWithMissingPolicy.get("failed_step"), is(nullValue()));
Map<String, Object> stepInfo = (Map<String, Object>) explainIndexWithMissingPolicy.get("step_info");
assertThat(stepInfo, is(notNullValue()));
assertThat(stepInfo.get("reason"), is("policy [missing_policy_] does not exist"));
});
}
private void assertUnmanagedIndex(Map<String, Object> explainIndexMap) {
assertThat(explainIndexMap.get("managed"), is(false));
assertThat(explainIndexMap.get("policy"), is(nullValue()));
assertThat(explainIndexMap.get("phase"), is(nullValue()));
assertThat(explainIndexMap.get("action"), is(nullValue()));
assertThat(explainIndexMap.get("step"), is(nullValue()));
assertThat(explainIndexMap.get("age"), is(nullValue()));
assertThat(explainIndexMap.get("failed_step"), is(nullValue()));
assertThat(explainIndexMap.get("step_info"), is(nullValue()));
}
private void assertManagedIndex(Map<String, Object> explainIndexMap) {
assertThat(explainIndexMap.get("managed"), is(true));
assertThat(explainIndexMap.get("policy"), is(policy));
assertThat(explainIndexMap.get("phase"), is("new"));
assertThat(explainIndexMap.get("action"), is("complete"));
assertThat(explainIndexMap.get("step"), is("complete"));
assertThat(explainIndexMap.get("phase_time_millis"), is(notNullValue()));
assertThat(explainIndexMap.get("age"), is(notNullValue()));
assertThat(explainIndexMap.get("phase_execution"), is(notNullValue()));
assertThat(explainIndexMap.get("failed_step"), is(nullValue()));
assertThat(explainIndexMap.get("step_info"), is(nullValue()));
}
}

View File

@ -13,7 +13,6 @@ import org.apache.logging.log4j.Logger;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.common.CheckedRunnable;
import org.elasticsearch.common.Nullable;
@ -47,7 +46,6 @@ import org.elasticsearch.xpack.core.ilm.SetSingleNodeAllocateStep;
import org.elasticsearch.xpack.core.ilm.ShrinkAction;
import org.elasticsearch.xpack.core.ilm.ShrinkStep;
import org.elasticsearch.xpack.core.ilm.Step;
import org.elasticsearch.xpack.core.ilm.Step.StepKey;
import org.elasticsearch.xpack.core.ilm.UpdateRolloverLifecycleDateStep;
import org.elasticsearch.xpack.core.ilm.WaitForActiveShardsStep;
import org.elasticsearch.xpack.core.ilm.WaitForRolloverReadyStep;
@ -70,19 +68,17 @@ import static org.elasticsearch.xpack.TimeSeriesRestDriver.createFullPolicy;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.createIndexWithSettings;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.createNewSingletonPolicy;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.createSnapshotRepo;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.explain;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.explainIndex;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.getNumberOfSegments;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.getOnlyIndexSettings;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.getStepKeyForIndex;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.index;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.indexDocument;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.rolloverMaxOneDocCondition;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
@ -90,7 +86,6 @@ import static org.hamcrest.Matchers.nullValue;
public class TimeSeriesLifecycleActionsIT extends ESRestTestCase {
private static final Logger logger = LogManager.getLogger(TimeSeriesLifecycleActionsIT.class);
private static final String FAILED_STEP_RETRY_COUNT_FIELD = "failed_step_retry_count";
private static final String IS_AUTO_RETRYABLE_ERROR_FIELD = "is_auto_retryable_error";
private String index;
private String policy;
@ -141,84 +136,6 @@ public class TimeSeriesLifecycleActionsIT extends ESRestTestCase {
assertBusy(() -> assertFalse(indexExists(shrunkenOriginalIndex)));
}
public void testMoveToAllocateStep() throws Exception {
String originalIndex = index + "-000001";
createIndexWithSettings(client(), originalIndex, alias, Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 4)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put("index.routing.allocation.include._name", "javaRestTest-0")
.put(RolloverAction.LIFECYCLE_ROLLOVER_ALIAS, "alias"));
// create policy
createFullPolicy(client(), policy, TimeValue.timeValueHours(10));
// update policy on index
updatePolicy(originalIndex, policy);
// move to a step
Request moveToStepRequest = new Request("POST", "_ilm/move/" + originalIndex);
assertBusy(() -> assertTrue(getStepKeyForIndex(client(), originalIndex).equals(new StepKey("new", "complete", "complete"))));
moveToStepRequest.setJsonEntity("{\n" +
" \"current_step\": {\n" +
" \"phase\": \"new\",\n" +
" \"action\": \"complete\",\n" +
" \"name\": \"complete\"\n" +
" },\n" +
" \"next_step\": {\n" +
" \"phase\": \"cold\",\n" +
" \"action\": \"allocate\",\n" +
" \"name\": \"allocate\"\n" +
" }\n" +
"}");
client().performRequest(moveToStepRequest);
assertBusy(() -> assertFalse(indexExists(originalIndex)));
}
public void testMoveToRolloverStep() throws Exception {
String originalIndex = index + "-000001";
String shrunkenOriginalIndex = ShrinkAction.SHRUNKEN_INDEX_PREFIX + originalIndex;
String secondIndex = index + "-000002";
createIndexWithSettings(client(), originalIndex, alias, Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 4)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put("index.routing.allocation.include._name", "javaRestTest-0")
.put(RolloverAction.LIFECYCLE_ROLLOVER_ALIAS, alias));
createFullPolicy(client(), policy, TimeValue.timeValueHours(10));
// update policy on index
updatePolicy(originalIndex, policy);
// move to a step
Request moveToStepRequest = new Request("POST", "_ilm/move/" + originalIndex);
// index document to trigger rollover
index(client(), originalIndex, "_id", "foo", "bar");
logger.info(getStepKeyForIndex(client(), originalIndex));
moveToStepRequest.setJsonEntity("{\n" +
" \"current_step\": {\n" +
" \"phase\": \"new\",\n" +
" \"action\": \"complete\",\n" +
" \"name\": \"complete\"\n" +
" },\n" +
" \"next_step\": {\n" +
" \"phase\": \"hot\",\n" +
" \"action\": \"rollover\",\n" +
" \"name\": \"attempt-rollover\"\n" +
" }\n" +
"}");
client().performRequest(moveToStepRequest);
/*
* These asserts are in the order that they should be satisfied in, in
* order to maximize the time for all operations to complete.
* An "out of order" assert here may result in this test occasionally
* timing out and failing inappropriately.
*/
// asserts that rollover was called
assertBusy(() -> assertTrue(indexExists(secondIndex)));
// asserts that shrink deleted the original index
assertBusy(() -> assertFalse(indexExists(originalIndex)), 30, TimeUnit.SECONDS);
// asserts that the delete phase completed for the managed shrunken index
assertBusy(() -> assertFalse(indexExists(shrunkenOriginalIndex)));
}
public void testRetryFailedDeleteAction() throws Exception {
createNewSingletonPolicy(client(), policy, "delete", new DeleteAction());
createIndexWithSettings(client(), index, alias, Settings.builder()
@ -888,16 +805,16 @@ public class TimeSeriesLifecycleActionsIT extends ESRestTestCase {
policy = otherPolicy;
createNewSingletonPolicy(client(), policy, "delete", new DeleteAction(), TimeValue.timeValueHours(13));
createIndexWithSettingsNoAlias(managedIndex1, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1,10))
createIndexWithSettings(client(), managedIndex1, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1, 10))
.put(LifecycleSettings.LIFECYCLE_NAME_SETTING.getKey(), originalPolicy));
createIndexWithSettingsNoAlias(managedIndex2, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1,10))
createIndexWithSettings(client(), managedIndex2, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1, 10))
.put(LifecycleSettings.LIFECYCLE_NAME_SETTING.getKey(), originalPolicy));
createIndexWithSettingsNoAlias(unmanagedIndex, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1,10)));
createIndexWithSettingsNoAlias(managedByOtherPolicyIndex, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1,10))
createIndexWithSettings(client(), unmanagedIndex, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1, 10)));
createIndexWithSettings(client(), managedByOtherPolicyIndex, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1, 10))
.put(LifecycleSettings.LIFECYCLE_NAME_SETTING.getKey(), otherPolicy));
Request deleteRequest = new Request("DELETE", "_ilm/policy/" + originalPolicy);
@ -951,80 +868,6 @@ public class TimeSeriesLifecycleActionsIT extends ESRestTestCase {
assertBusy(() -> assertThat(getStepKeyForIndex(client(), originalIndex), equalTo(PhaseCompleteStep.finalStep("hot").getKey())));
}
public void testMoveToInjectedStep() throws Exception {
String shrunkenIndex = ShrinkAction.SHRUNKEN_INDEX_PREFIX + index;
createNewSingletonPolicy(client(), policy, "warm", new ShrinkAction(1), TimeValue.timeValueHours(12));
createIndexWithSettings(client(), index, alias, Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 3)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put(LifecycleSettings.LIFECYCLE_NAME, policy)
.put(RolloverAction.LIFECYCLE_ROLLOVER_ALIAS, alias));
assertBusy(() -> assertThat(getStepKeyForIndex(client(), index), equalTo(new StepKey("new", "complete", "complete"))));
// Move to a step from the injected unfollow action
Request moveToStepRequest = new Request("POST", "_ilm/move/" + index);
moveToStepRequest.setJsonEntity("{\n" +
" \"current_step\": { \n" +
" \"phase\": \"new\",\n" +
" \"action\": \"complete\",\n" +
" \"name\": \"complete\"\n" +
" },\n" +
" \"next_step\": { \n" +
" \"phase\": \"warm\",\n" +
" \"action\": \"unfollow\",\n" +
" \"name\": \"wait-for-indexing-complete\"\n" +
" }\n" +
"}");
// If we get an OK on this request we have successfully moved to the injected step
assertOK(client().performRequest(moveToStepRequest));
// Make sure we actually move on to and execute the shrink action
assertBusy(() -> {
assertTrue(indexExists(shrunkenIndex));
assertTrue(aliasExists(shrunkenIndex, index));
assertThat(getStepKeyForIndex(client(), shrunkenIndex), equalTo(PhaseCompleteStep.finalStep("warm").getKey()));
}, 30, TimeUnit.SECONDS);
}
@AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/53612")
public void testMoveToStepRereadsPolicy() throws Exception {
createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, TimeValue.timeValueHours(1), null), TimeValue.ZERO);
createIndexWithSettings(client(), "test-1", alias, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put(LifecycleSettings.LIFECYCLE_NAME, policy)
.put(RolloverAction.LIFECYCLE_ROLLOVER_ALIAS, alias),
true);
assertBusy(() -> assertThat(getStepKeyForIndex(client(), "test-1"),
equalTo(new StepKey("hot", "rollover", "check-rollover-ready"))));
createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, TimeValue.timeValueSeconds(1), null), TimeValue.ZERO);
// Move to the same step, which should re-read the policy
Request moveToStepRequest = new Request("POST", "_ilm/move/test-1");
moveToStepRequest.setJsonEntity("{\n" +
" \"current_step\": { \n" +
" \"phase\": \"hot\",\n" +
" \"action\": \"rollover\",\n" +
" \"name\": \"check-rollover-ready\"\n" +
" },\n" +
" \"next_step\": { \n" +
" \"phase\": \"hot\",\n" +
" \"action\": \"rollover\",\n" +
" \"name\": \"check-rollover-ready\"\n" +
" }\n" +
"}");
assertOK(client().performRequest(moveToStepRequest));
// Make sure we actually rolled over
assertBusy(() -> {
indexExists("test-000002");
});
}
public void testCanStopILMWithPolicyUsingNonexistentPolicy() throws Exception {
createIndexWithSettings(client(), index, alias, Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
@ -1047,80 +890,6 @@ public class TimeSeriesLifecycleActionsIT extends ESRestTestCase {
assertOK(client().performRequest(startILMReqest));
}
public void testExplainFilters() throws Exception {
String goodIndex = index + "-good-000001";
String errorIndex = index + "-error";
String nonexistantPolicyIndex = index + "-nonexistant-policy";
String unmanagedIndex = index + "-unmanaged";
createFullPolicy(client(), policy, TimeValue.ZERO);
{
// Create a "shrink-only-policy"
Map<String, LifecycleAction> warmActions = new HashMap<>();
warmActions.put(ShrinkAction.NAME, new ShrinkAction(17));
Map<String, Phase> phases = new HashMap<>();
phases.put("warm", new Phase("warm", TimeValue.ZERO, warmActions));
LifecyclePolicy lifecyclePolicy = new LifecyclePolicy("shrink-only-policy", phases);
// PUT policy
XContentBuilder builder = jsonBuilder();
lifecyclePolicy.toXContent(builder, null);
final StringEntity entity = new StringEntity(
"{ \"policy\":" + Strings.toString(builder) + "}", ContentType.APPLICATION_JSON);
Request request = new Request("PUT", "_ilm/policy/shrink-only-policy");
request.setEntity(entity);
assertOK(client().performRequest(request));
}
createIndexWithSettings(client(), goodIndex, alias, Settings.builder()
.put(RolloverAction.LIFECYCLE_ROLLOVER_ALIAS, alias)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put(LifecycleSettings.LIFECYCLE_NAME, policy)
);
createIndexWithSettingsNoAlias(errorIndex, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put(LifecycleSettings.LIFECYCLE_NAME, "shrink-only-policy")
);
createIndexWithSettingsNoAlias(nonexistantPolicyIndex, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put(LifecycleSettings.LIFECYCLE_NAME, randomValueOtherThan(policy, () -> randomAlphaOfLengthBetween(3,10))));
createIndexWithSettingsNoAlias(unmanagedIndex, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0));
assertBusy(() -> {
Map<String, Map<String, Object>> explainResponse = explain(client(), index + "*", false, false);
assertNotNull(explainResponse);
assertThat(explainResponse,
allOf(hasKey(goodIndex), hasKey(errorIndex), hasKey(nonexistantPolicyIndex), hasKey(unmanagedIndex)));
Map<String, Map<String, Object>> onlyManagedResponse = explain(client(), index + "*", false, true);
assertNotNull(onlyManagedResponse);
assertThat(onlyManagedResponse, allOf(hasKey(goodIndex), hasKey(errorIndex), hasKey(nonexistantPolicyIndex)));
assertThat(onlyManagedResponse, not(hasKey(unmanagedIndex)));
Map<String, Map<String, Object>> onlyErrorsResponse = explain(client(), index + "*", true, true);
assertNotNull(onlyErrorsResponse);
assertThat(onlyErrorsResponse, allOf(hasKey(errorIndex), hasKey(nonexistantPolicyIndex)));
assertThat(onlyErrorsResponse, allOf(not(hasKey(goodIndex)), not(hasKey(unmanagedIndex))));
});
}
public void testExplainIndexContainsAutomaticRetriesInformation() throws Exception {
createFullPolicy(client(), policy, TimeValue.ZERO);
// create index without alias so the rollover action fails and is retried
createIndexWithSettingsNoAlias(index, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put(LifecycleSettings.LIFECYCLE_NAME, policy)
);
assertBusy(() -> {
Map<String, Object> explainIndex = explainIndex(client(), index);
assertThat((Integer) explainIndex.get(FAILED_STEP_RETRY_COUNT_FIELD), greaterThanOrEqualTo(1));
assertThat(explainIndex.get(IS_AUTO_RETRYABLE_ERROR_FIELD), is(true));
});
}
public void testILMRolloverRetriesOnReadOnlyBlock() throws Exception {
String firstIndex = index + "-000001";
@ -1744,26 +1513,6 @@ public class TimeSeriesLifecycleActionsIT extends ESRestTestCase {
assertEquals(WaitForRolloverReadyStep.NAME, stepKey.getName());
}
private void createIndexWithSettingsNoAlias(String index, Settings.Builder settings) throws IOException {
Request request = new Request("PUT", "/" + index);
request.setJsonEntity("{\n \"settings\": " + Strings.toString(settings.build())
+ "}");
client().performRequest(request);
// wait for the shards to initialize
ensureGreen(index);
}
private static void index(RestClient client, String index, String id, Object... fields) throws IOException {
XContentBuilder document = jsonBuilder().startObject();
for (int i = 0; i < fields.length; i += 2) {
document.field((String) fields[i], fields[i + 1]);
}
document.endObject();
final Request request = new Request("POST", "/" + index + "/_doc/" + id);
request.setJsonEntity(Strings.toString(document));
assertOK(client.performRequest(request));
}
@Nullable
private String getFailedStepForIndex(String indexName) throws IOException {
Map<String, Object> indexResponse = explainIndex(client(), indexName);

View File

@ -0,0 +1,232 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.ilm;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.test.rest.ESRestTestCase;
import org.elasticsearch.xpack.core.ilm.DeleteAction;
import org.elasticsearch.xpack.core.ilm.LifecycleSettings;
import org.elasticsearch.xpack.core.ilm.PhaseCompleteStep;
import org.elasticsearch.xpack.core.ilm.RolloverAction;
import org.elasticsearch.xpack.core.ilm.ShrinkAction;
import org.elasticsearch.xpack.core.ilm.Step.StepKey;
import org.junit.Before;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.createFullPolicy;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.createIndexWithSettings;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.createNewSingletonPolicy;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.getStepKeyForIndex;
import static org.elasticsearch.xpack.TimeSeriesRestDriver.index;
import static org.hamcrest.Matchers.containsStringIgnoringCase;
import static org.hamcrest.Matchers.equalTo;
public class TimeseriesMoveToStepIT extends ESRestTestCase {
private static final Logger logger = LogManager.getLogger(TimeseriesMoveToStepIT.class);
private String policy;
private String index;
private String alias;
@Before
public void refreshIndex() {
index = "index-" + randomAlphaOfLength(10).toLowerCase(Locale.ROOT);
policy = "policy-" + randomAlphaOfLength(5);
alias = "alias-" + randomAlphaOfLength(5);
}
public void testMoveToAllocateStep() throws Exception {
String originalIndex = index + "-000001";
// create policy
createFullPolicy(client(), policy, TimeValue.timeValueHours(10));
createIndexWithSettings(client(), originalIndex, alias, Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 4)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put("index.routing.allocation.include._name", "javaRestTest-0")
.put(LifecycleSettings.LIFECYCLE_NAME, policy)
.put(RolloverAction.LIFECYCLE_ROLLOVER_ALIAS, "alias"));
// move to a step
Request moveToStepRequest = new Request("POST", "_ilm/move/" + originalIndex);
assertBusy(() -> assertTrue(getStepKeyForIndex(client(), originalIndex).equals(new StepKey("new", "complete", "complete"))));
moveToStepRequest.setJsonEntity("{\n" +
" \"current_step\": {\n" +
" \"phase\": \"new\",\n" +
" \"action\": \"complete\",\n" +
" \"name\": \"complete\"\n" +
" },\n" +
" \"next_step\": {\n" +
" \"phase\": \"cold\",\n" +
" \"action\": \"allocate\",\n" +
" \"name\": \"allocate\"\n" +
" }\n" +
"}");
client().performRequest(moveToStepRequest);
assertBusy(() -> assertFalse(indexExists(originalIndex)));
}
public void testMoveToRolloverStep() throws Exception {
String originalIndex = index + "-000001";
String shrunkenOriginalIndex = ShrinkAction.SHRUNKEN_INDEX_PREFIX + originalIndex;
String secondIndex = index + "-000002";
createFullPolicy(client(), policy, TimeValue.timeValueHours(10));
createIndexWithSettings(client(), originalIndex, alias, Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 4)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put("index.routing.allocation.include._name", "javaRestTest-0")
.put(LifecycleSettings.LIFECYCLE_NAME, policy)
.put(RolloverAction.LIFECYCLE_ROLLOVER_ALIAS, alias));
// move to a step
Request moveToStepRequest = new Request("POST", "_ilm/move/" + originalIndex);
// index document to trigger rollover
index(client(), originalIndex, "_id", "foo", "bar");
logger.info(getStepKeyForIndex(client(), originalIndex));
moveToStepRequest.setJsonEntity("{\n" +
" \"current_step\": {\n" +
" \"phase\": \"new\",\n" +
" \"action\": \"complete\",\n" +
" \"name\": \"complete\"\n" +
" },\n" +
" \"next_step\": {\n" +
" \"phase\": \"hot\",\n" +
" \"action\": \"rollover\",\n" +
" \"name\": \"attempt-rollover\"\n" +
" }\n" +
"}");
client().performRequest(moveToStepRequest);
/*
* These asserts are in the order that they should be satisfied in, in
* order to maximize the time for all operations to complete.
* An "out of order" assert here may result in this test occasionally
* timing out and failing inappropriately.
*/
// asserts that rollover was called
assertBusy(() -> assertTrue(indexExists(secondIndex)));
// asserts that shrink deleted the original index
assertBusy(() -> assertFalse(indexExists(originalIndex)), 30, TimeUnit.SECONDS);
// asserts that the delete phase completed for the managed shrunken index
assertBusy(() -> assertFalse(indexExists(shrunkenOriginalIndex)));
}
public void testMoveToInjectedStep() throws Exception {
String shrunkenIndex = ShrinkAction.SHRUNKEN_INDEX_PREFIX + index;
createNewSingletonPolicy(client(), policy, "warm", new ShrinkAction(1), TimeValue.timeValueHours(12));
createIndexWithSettings(client(), index, alias, Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 3)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put(LifecycleSettings.LIFECYCLE_NAME, policy)
.put(RolloverAction.LIFECYCLE_ROLLOVER_ALIAS, alias));
assertBusy(() -> assertThat(getStepKeyForIndex(client(), index), equalTo(new StepKey("new", "complete", "complete"))));
// Move to a step from the injected unfollow action
Request moveToStepRequest = new Request("POST", "_ilm/move/" + index);
moveToStepRequest.setJsonEntity("{\n" +
" \"current_step\": { \n" +
" \"phase\": \"new\",\n" +
" \"action\": \"complete\",\n" +
" \"name\": \"complete\"\n" +
" },\n" +
" \"next_step\": { \n" +
" \"phase\": \"warm\",\n" +
" \"action\": \"unfollow\",\n" +
" \"name\": \"wait-for-indexing-complete\"\n" +
" }\n" +
"}");
// If we get an OK on this request we have successfully moved to the injected step
assertOK(client().performRequest(moveToStepRequest));
// Make sure we actually move on to and execute the shrink action
assertBusy(() -> {
assertTrue(indexExists(shrunkenIndex));
assertTrue(aliasExists(shrunkenIndex, index));
assertThat(getStepKeyForIndex(client(), shrunkenIndex), equalTo(PhaseCompleteStep.finalStep("warm").getKey()));
}, 30, TimeUnit.SECONDS);
}
@AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/53612")
public void testMoveToStepRereadsPolicy() throws Exception {
createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, TimeValue.timeValueHours(1), null), TimeValue.ZERO);
createIndexWithSettings(client(), "test-1", alias, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put(LifecycleSettings.LIFECYCLE_NAME, policy)
.put(RolloverAction.LIFECYCLE_ROLLOVER_ALIAS, alias),
true);
assertBusy(() -> assertThat(getStepKeyForIndex(client(), "test-1"),
equalTo(new StepKey("hot", "rollover", "check-rollover-ready"))));
createNewSingletonPolicy(client(), policy, "hot", new RolloverAction(null, TimeValue.timeValueSeconds(1), null), TimeValue.ZERO);
// Move to the same step, which should re-read the policy
Request moveToStepRequest = new Request("POST", "_ilm/move/test-1");
moveToStepRequest.setJsonEntity("{\n" +
" \"current_step\": { \n" +
" \"phase\": \"hot\",\n" +
" \"action\": \"rollover\",\n" +
" \"name\": \"check-rollover-ready\"\n" +
" },\n" +
" \"next_step\": { \n" +
" \"phase\": \"hot\",\n" +
" \"action\": \"rollover\",\n" +
" \"name\": \"check-rollover-ready\"\n" +
" }\n" +
"}");
assertOK(client().performRequest(moveToStepRequest));
// Make sure we actually rolled over
assertBusy(() -> {
indexExists("test-000002");
});
}
public void testMoveToStepWithInvalidNextStep() throws Exception {
createNewSingletonPolicy(client(), policy, "delete", new DeleteAction(), TimeValue.timeValueDays(100));
createIndexWithSettings(client(), index, alias, Settings.builder()
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
.put(LifecycleSettings.LIFECYCLE_NAME, policy));
// move to a step
Request moveToStepRequest = new Request("POST", "_ilm/move/" + index);
moveToStepRequest.setJsonEntity("{\n" +
" \"current_step\": {\n" +
" \"phase\": \"new\",\n" +
" \"action\": \"complete\",\n" +
" \"name\": \"complete\"\n" +
" },\n" +
" \"next_step\": {\n" +
" \"phase\": \"hot\",\n" +
" \"action\": \"rollover\",\n" +
" \"name\": \"attempt-rollover\"\n" +
" }\n" +
"}");
assertBusy(() -> {
ResponseException exception =
expectThrows(ResponseException.class, () -> client().performRequest(moveToStepRequest));
String responseEntityAsString = EntityUtils.toString(exception.getResponse().getEntity());
String expectedErrorMessage = "step [{\\\"phase\\\":\\\"hot\\\",\\\"action\\\":\\\"rollover\\\",\\\"name\\\":" +
"\\\"attempt-rollover\\\"}] for index [" + index + "] with policy [" + policy + "] does not exist";
assertThat(responseEntityAsString, containsStringIgnoringCase(expectedErrorMessage));
});
}
}

View File

@ -61,30 +61,6 @@ teardown:
ilm.get_lifecycle:
policy: "my_moveable_timeseries_lifecycle"
---
"Test Basic Move To Step":
- do:
ilm.move_to_step:
index: "my_index"
body:
current_step:
phase: "new"
action: "complete"
name: "complete"
next_step:
phase: "completed"
action: "completed"
name: "completed"
- do:
ilm.explain_lifecycle:
index: "my_index"
- match: { indices.my_index.policy: "my_moveable_timeseries_lifecycle" }
- match: { indices.my_index.step: "completed" }
- match: { indices.my_index.action: "completed" }
- match: { indices.my_index.phase: "completed" }
---
"Test Invalid Move To Step With Incorrect Current Step":
@ -105,33 +81,6 @@ teardown:
- match: { error.root_cause.0.reason: "index [my_index] is not on current step [{\"phase\":\"warm\",\"action\":\"forcemerge\",\"name\":\"forcemerge\"}], currently: [{\"phase\":\"new\",\"action\":\"complete\",\"name\":\"complete\"}]" }
- do:
ilm.explain_lifecycle:
index: "my_index"
- match: { indices.my_index.policy: "my_moveable_timeseries_lifecycle" }
- match: { indices.my_index.step: "complete" }
- match: { indices.my_index.action: "complete" }
- match: { indices.my_index.phase: "new" }
---
"Test Invalid Move To Step With Invalid Next Step":
- do:
catch: bad_request
ilm.move_to_step:
index: "my_index"
body:
current_step:
phase: "new"
action: "complete"
name: "complete"
next_step:
phase: "invalid"
action: "invalid"
name: "invalid"
- match: { error.root_cause.0.type: "illegal_argument_exception" }
- match: { error.root_cause.0.reason: "step [{\"phase\":\"invalid\",\"action\":\"invalid\",\"name\":\"invalid\"}] for index [my_index] with policy [my_moveable_timeseries_lifecycle] does not exist" }
- do:
ilm.explain_lifecycle:
index: "my_index"

View File

@ -100,132 +100,6 @@ teardown:
ilm.get_lifecycle:
policy: "my_moveable_timeseries_lifecycle"
---
"Test Basic Lifecycle Explain":
- do:
ilm.explain_lifecycle:
index: "my_index"
- is_true: indices.my_index.managed
- match: { indices.my_index.index: "my_index" }
- match: { indices.my_index.policy: "my_moveable_timeseries_lifecycle" }
- match: { indices.my_index.phase: "new" }
- match: { indices.my_index.action: "complete" }
- match: { indices.my_index.step: "complete" }
- is_true: indices.my_index.phase_time_millis
- is_true: indices.my_index.age
- is_true: indices.my_index.phase_execution
- is_false: indices.my_index.failed_step
- is_false: indices.my_index.step_info
- is_false: indices.my_index2
- is_false: indices.another_index
- is_false: indices.unmanaged_index
- is_false: indices.index_with_policy_that_doesnt_exist
---
"Test Wildcard Index Lifecycle Explain":
- do:
ilm.explain_lifecycle:
index: "my_*"
- is_true: indices.my_index.managed
- match: { indices.my_index.index: "my_index" }
- match: { indices.my_index.policy: "my_moveable_timeseries_lifecycle" }
- match: { indices.my_index.phase: "new" }
- match: { indices.my_index.action: "complete" }
- match: { indices.my_index.step: "complete" }
- is_true: indices.my_index.phase_time_millis
- is_true: indices.my_index.age
- is_true: indices.my_index.phase_execution
- is_false: indices.my_index.failed_step
- is_false: indices.my_index.step_info
- is_true: indices.my_index2.managed
- match: { indices.my_index2.index: "my_index2" }
- match: { indices.my_index2.policy: "my_moveable_timeseries_lifecycle" }
- match: { indices.my_index2.phase: "new" }
- match: { indices.my_index2.action: "complete" }
- match: { indices.my_index2.step: "complete" }
- is_true: indices.my_index2.phase_time_millis
- is_true: indices.my_index2.age
- is_true: indices.my_index2.phase_execution
- is_false: indices.my_index2.failed_step
- is_false: indices.my_index2.step_info
- is_false: indices.another_index
- is_false: indices.unmanaged_index
- is_false: indices.index_with_policy_that_doesnt_exist
---
"Test All Indexes Lifecycle Explain":
- skip:
reason: https://github.com/elastic/elasticsearch/issues/47275
version: "6.7.0 - "
- do:
ilm.explain_lifecycle:
index: "*"
- is_true: indices.my_index.managed
- match: { indices.my_index.index: "my_index" }
- match: { indices.my_index.policy: "my_moveable_timeseries_lifecycle" }
- match: { indices.my_index.phase: "new" }
- match: { indices.my_index.action: "complete" }
- match: { indices.my_index.step: "complete" }
- is_true: indices.my_index.phase_time_millis
- is_true: indices.my_index.age
- is_true: indices.my_index.phase_execution
- is_false: indices.my_index.failed_step
- is_false: indices.my_index.step_info
- is_true: indices.my_index2.managed
- match: { indices.my_index2.index: "my_index2" }
- match: { indices.my_index2.policy: "my_moveable_timeseries_lifecycle" }
- match: { indices.my_index2.phase: "new" }
- match: { indices.my_index2.action: "complete" }
- match: { indices.my_index2.step: "complete" }
- is_true: indices.my_index2.phase_time_millis
- is_true: indices.my_index2.age
- is_true: indices.my_index2.phase_execution
- is_false: indices.my_index2.failed_step
- is_false: indices.my_index2.step_info
- is_true: indices.another_index.managed
- match: { indices.another_index.index: "another_index" }
- match: { indices.another_index.policy: "my_moveable_timeseries_lifecycle" }
- match: { indices.another_index.phase: "new" }
- match: { indices.another_index.action: "complete" }
- match: { indices.another_index.step: "complete" }
- is_true: indices.another_index.phase_time_millis
- is_true: indices.another_index.age
- is_true: indices.another_index.phase_execution
- is_false: indices.another_index.failed_step
- is_false: indices.another_index.step_info
- match: { indices.unmanaged_index.index: "unmanaged_index" }
- is_false: indices.unmanaged_index.managed
- is_false: indices.unmanaged_index.policy
- is_false: indices.unmanaged_index.phase
- is_false: indices.unmanaged_index.action
- is_false: indices.unmanaged_index.step
- is_false: indices.unmanaged.age
- is_false: indices.another_index.failed_step
- is_false: indices.another_index.step_info
- match: { indices.index_with_policy_that_doesnt_exist.index: "index_with_policy_that_doesnt_exist" }
- match: { indices.index_with_policy_that_doesnt_exist.policy: "a_policy_that_doesnt_exist" }
- match: { indices.index_with_policy_that_doesnt_exist.step_info.reason: "policy [a_policy_that_doesnt_exist] does not exist" }
- is_true: indices.index_with_policy_that_doesnt_exist.managed
- is_false: indices.index_with_policy_that_doesnt_exist.phase
- is_false: indices.index_with_policy_that_doesnt_exist.action
- is_false: indices.index_with_policy_that_doesnt_exist.step
- is_false: indices.index_with_policy_that_doesnt_exist.age
- is_false: indices.index_with_policy_that_doesnt_exist.failed_step
---
"Test Unmanaged Index Lifecycle Explain":