Skip to content

Commit

Permalink
Convert flaky yml tests to EsRestTestCases (#63634)
Browse files Browse the repository at this point in the history
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`.
  • Loading branch information
andreidan committed Oct 27, 2020
1 parent 1a72a0d commit 6afd042
Show file tree
Hide file tree
Showing 6 changed files with 468 additions and 432 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
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.
Expand Down Expand Up @@ -104,6 +107,17 @@ public static void indexDocument(RestClient client, String indexAbstractionName,
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);
Expand Down Expand Up @@ -228,6 +242,14 @@ public static void createIndexWithSettings(RestClient client, String index, Stri
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"));
Expand Down
Original file line number Diff line number Diff line change
@@ -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()));
}

}

0 comments on commit 6afd042

Please sign in to comment.