Skip to content

Commit 835ebcf

Browse files
authored
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 6afd042) Signed-off-by: Andrei Dan <[email protected]>
1 parent ae186a6 commit 835ebcf

File tree

6 files changed

+468
-437
lines changed

6 files changed

+468
-437
lines changed

x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/TimeSeriesRestDriver.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
import static org.elasticsearch.test.ESTestCase.randomAlphaOfLengthBetween;
4747
import static org.elasticsearch.test.ESTestCase.randomBoolean;
4848
import static org.elasticsearch.test.rest.ESRestTestCase.ensureGreen;
49+
import static org.hamcrest.Matchers.anyOf;
50+
import static org.hamcrest.Matchers.equalTo;
51+
import static org.junit.Assert.assertThat;
4952

5053
/**
5154
* This class provides the operational REST functions needed to control an ILM time series lifecycle.
@@ -104,6 +107,17 @@ public static void indexDocument(RestClient client, String indexAbstractionName,
104107
logger.info(response.getStatusLine());
105108
}
106109

110+
public static void index(RestClient client, String index, String id, Object... fields) throws IOException {
111+
XContentBuilder document = jsonBuilder().startObject();
112+
for (int i = 0; i < fields.length; i += 2) {
113+
document.field((String) fields[i], fields[i + 1]);
114+
}
115+
document.endObject();
116+
final Request request = new Request("POST", "/" + index + "/_doc/" + id);
117+
request.setJsonEntity(Strings.toString(document));
118+
assertThat(client.performRequest(request).getStatusLine().getStatusCode(), anyOf(equalTo(200), equalTo(201)));
119+
}
120+
107121
public static void createNewSingletonPolicy(RestClient client, String policyName, String phaseName, LifecycleAction action)
108122
throws IOException {
109123
createNewSingletonPolicy(client, policyName, phaseName, action, TimeValue.ZERO);
@@ -228,6 +242,14 @@ public static void createIndexWithSettings(RestClient client, String index, Stri
228242
ensureGreen(index);
229243
}
230244

245+
public static void createIndexWithSettings(RestClient client, String index, Settings.Builder settings) throws IOException {
246+
Request request = new Request("PUT", "/" + index);
247+
request.setJsonEntity("{\n \"settings\": " + Strings.toString(settings.build()) + "}");
248+
client.performRequest(request);
249+
// wait for the shards to initialize
250+
ensureGreen(index);
251+
}
252+
231253
@SuppressWarnings("unchecked")
232254
public static Integer getNumberOfSegments(RestClient client, String index) throws IOException {
233255
Response response = client.performRequest(new Request("GET", index + "/_segments"));
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
package org.elasticsearch.xpack.ilm;
8+
9+
import org.apache.http.entity.ContentType;
10+
import org.apache.http.entity.StringEntity;
11+
import org.apache.logging.log4j.LogManager;
12+
import org.apache.logging.log4j.Logger;
13+
import org.elasticsearch.client.Request;
14+
import org.elasticsearch.cluster.metadata.IndexMetadata;
15+
import org.elasticsearch.common.Strings;
16+
import org.elasticsearch.common.settings.Settings;
17+
import org.elasticsearch.common.unit.TimeValue;
18+
import org.elasticsearch.common.xcontent.XContentBuilder;
19+
import org.elasticsearch.test.rest.ESRestTestCase;
20+
import org.elasticsearch.xpack.core.ilm.DeleteAction;
21+
import org.elasticsearch.xpack.core.ilm.LifecycleAction;
22+
import org.elasticsearch.xpack.core.ilm.LifecyclePolicy;
23+
import org.elasticsearch.xpack.core.ilm.LifecycleSettings;
24+
import org.elasticsearch.xpack.core.ilm.Phase;
25+
import org.elasticsearch.xpack.core.ilm.RolloverAction;
26+
import org.elasticsearch.xpack.core.ilm.ShrinkAction;
27+
import org.junit.Before;
28+
29+
import java.util.HashMap;
30+
import java.util.Locale;
31+
import java.util.Map;
32+
33+
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
34+
import static org.elasticsearch.xpack.TimeSeriesRestDriver.createFullPolicy;
35+
import static org.elasticsearch.xpack.TimeSeriesRestDriver.createIndexWithSettings;
36+
import static org.elasticsearch.xpack.TimeSeriesRestDriver.createNewSingletonPolicy;
37+
import static org.elasticsearch.xpack.TimeSeriesRestDriver.explain;
38+
import static org.elasticsearch.xpack.TimeSeriesRestDriver.explainIndex;
39+
import static org.hamcrest.Matchers.allOf;
40+
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
41+
import static org.hamcrest.Matchers.hasKey;
42+
import static org.hamcrest.Matchers.is;
43+
import static org.hamcrest.Matchers.not;
44+
import static org.hamcrest.Matchers.notNullValue;
45+
import static org.hamcrest.Matchers.nullValue;
46+
47+
public class ExplainLifecycleIT extends ESRestTestCase {
48+
private static final Logger logger = LogManager.getLogger(ExplainLifecycleIT.class);
49+
private static final String FAILED_STEP_RETRY_COUNT_FIELD = "failed_step_retry_count";
50+
private static final String IS_AUTO_RETRYABLE_ERROR_FIELD = "is_auto_retryable_error";
51+
52+
private String policy;
53+
private String index;
54+
private String alias;
55+
56+
@Before
57+
public void refreshIndex() {
58+
index = "index-" + randomAlphaOfLength(10).toLowerCase(Locale.ROOT);
59+
policy = "policy-" + randomAlphaOfLength(5);
60+
alias = "alias-" + randomAlphaOfLength(5);
61+
}
62+
63+
public void testExplainFilters() throws Exception {
64+
String goodIndex = index + "-good-000001";
65+
String errorIndex = index + "-error";
66+
String nonexistantPolicyIndex = index + "-nonexistant-policy";
67+
String unmanagedIndex = index + "-unmanaged";
68+
69+
createFullPolicy(client(), policy, TimeValue.ZERO);
70+
71+
{
72+
// Create a "shrink-only-policy"
73+
Map<String, LifecycleAction> warmActions = new HashMap<>();
74+
warmActions.put(ShrinkAction.NAME, new ShrinkAction(17));
75+
Map<String, Phase> phases = new HashMap<>();
76+
phases.put("warm", new Phase("warm", TimeValue.ZERO, warmActions));
77+
LifecyclePolicy lifecyclePolicy = new LifecyclePolicy("shrink-only-policy", phases);
78+
// PUT policy
79+
XContentBuilder builder = jsonBuilder();
80+
lifecyclePolicy.toXContent(builder, null);
81+
final StringEntity entity = new StringEntity(
82+
"{ \"policy\":" + Strings.toString(builder) + "}", ContentType.APPLICATION_JSON);
83+
Request request = new Request("PUT", "_ilm/policy/shrink-only-policy");
84+
request.setEntity(entity);
85+
assertOK(client().performRequest(request));
86+
}
87+
88+
createIndexWithSettings(client(), goodIndex, alias, Settings.builder()
89+
.put(RolloverAction.LIFECYCLE_ROLLOVER_ALIAS, alias)
90+
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
91+
.put(LifecycleSettings.LIFECYCLE_NAME, policy)
92+
);
93+
createIndexWithSettings(client(), errorIndex, Settings.builder()
94+
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
95+
.put(LifecycleSettings.LIFECYCLE_NAME, "shrink-only-policy")
96+
);
97+
createIndexWithSettings(client(), nonexistantPolicyIndex, Settings.builder()
98+
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
99+
.put(LifecycleSettings.LIFECYCLE_NAME, randomValueOtherThan(policy, () -> randomAlphaOfLengthBetween(3, 10))));
100+
createIndexWithSettings(client(), unmanagedIndex, Settings.builder()
101+
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0));
102+
103+
assertBusy(() -> {
104+
Map<String, Map<String, Object>> explainResponse = explain(client(), index + "*", false, false);
105+
assertNotNull(explainResponse);
106+
assertThat(explainResponse,
107+
allOf(hasKey(goodIndex), hasKey(errorIndex), hasKey(nonexistantPolicyIndex), hasKey(unmanagedIndex)));
108+
109+
Map<String, Map<String, Object>> onlyManagedResponse = explain(client(), index + "*", false, true);
110+
assertNotNull(onlyManagedResponse);
111+
assertThat(onlyManagedResponse, allOf(hasKey(goodIndex), hasKey(errorIndex), hasKey(nonexistantPolicyIndex)));
112+
assertThat(onlyManagedResponse, not(hasKey(unmanagedIndex)));
113+
114+
Map<String, Map<String, Object>> onlyErrorsResponse = explain(client(), index + "*", true, true);
115+
assertNotNull(onlyErrorsResponse);
116+
assertThat(onlyErrorsResponse, allOf(hasKey(errorIndex), hasKey(nonexistantPolicyIndex)));
117+
assertThat(onlyErrorsResponse, allOf(not(hasKey(goodIndex)), not(hasKey(unmanagedIndex))));
118+
});
119+
}
120+
121+
public void testExplainIndexContainsAutomaticRetriesInformation() throws Exception {
122+
createFullPolicy(client(), policy, TimeValue.ZERO);
123+
124+
// create index without alias so the rollover action fails and is retried
125+
createIndexWithSettings(client(), index, Settings.builder()
126+
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
127+
.put(LifecycleSettings.LIFECYCLE_NAME, policy)
128+
);
129+
130+
assertBusy(() -> {
131+
Map<String, Object> explainIndex = explainIndex(client(), index);
132+
assertThat((Integer) explainIndex.get(FAILED_STEP_RETRY_COUNT_FIELD), greaterThanOrEqualTo(1));
133+
assertThat(explainIndex.get(IS_AUTO_RETRYABLE_ERROR_FIELD), is(true));
134+
});
135+
}
136+
137+
@SuppressWarnings("unchecked")
138+
public void testExplainIndicesWildcard() throws Exception {
139+
createNewSingletonPolicy(client(), policy, "delete", new DeleteAction(), TimeValue.timeValueDays(100));
140+
String firstIndex = this.index + "-first";
141+
String secondIndex = this.index + "-second";
142+
String unmanagedIndex = this.index + "-unmanaged";
143+
String indexWithMissingPolicy = this.index + "-missing_policy";
144+
createIndexWithSettings(client(), firstIndex, alias + firstIndex, Settings.builder()
145+
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
146+
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
147+
.put(LifecycleSettings.LIFECYCLE_NAME, policy));
148+
createIndexWithSettings(client(), secondIndex, alias + secondIndex, Settings.builder()
149+
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
150+
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
151+
.put(LifecycleSettings.LIFECYCLE_NAME, policy));
152+
createIndexWithSettings(client(), unmanagedIndex, alias + unmanagedIndex, Settings.builder()
153+
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
154+
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0));
155+
String missingPolicyName = "missing_policy_";
156+
createIndexWithSettings(client(), indexWithMissingPolicy, alias + indexWithMissingPolicy, Settings.builder()
157+
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
158+
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
159+
.put(LifecycleSettings.LIFECYCLE_NAME, missingPolicyName));
160+
161+
assertBusy(() -> {
162+
Map<String, Map<String, Object>> explain = explain(client(), this.index + "*", false, false);
163+
assertManagedIndex(explain.get(firstIndex));
164+
assertManagedIndex(explain.get(secondIndex));
165+
assertUnmanagedIndex(explain.get(unmanagedIndex));
166+
167+
Map<String, Object> explainIndexWithMissingPolicy = explain.get(indexWithMissingPolicy);
168+
assertThat(explainIndexWithMissingPolicy.get("managed"), is(true));
169+
assertThat(explainIndexWithMissingPolicy.get("policy"), is(missingPolicyName));
170+
assertThat(explainIndexWithMissingPolicy.get("phase"), is(nullValue()));
171+
assertThat(explainIndexWithMissingPolicy.get("action"), is(nullValue()));
172+
assertThat(explainIndexWithMissingPolicy.get("step"), is(nullValue()));
173+
assertThat(explainIndexWithMissingPolicy.get("age"), is(nullValue()));
174+
assertThat(explainIndexWithMissingPolicy.get("failed_step"), is(nullValue()));
175+
Map<String, Object> stepInfo = (Map<String, Object>) explainIndexWithMissingPolicy.get("step_info");
176+
assertThat(stepInfo, is(notNullValue()));
177+
assertThat(stepInfo.get("reason"), is("policy [missing_policy_] does not exist"));
178+
});
179+
}
180+
181+
private void assertUnmanagedIndex(Map<String, Object> explainIndexMap) {
182+
assertThat(explainIndexMap.get("managed"), is(false));
183+
assertThat(explainIndexMap.get("policy"), is(nullValue()));
184+
assertThat(explainIndexMap.get("phase"), is(nullValue()));
185+
assertThat(explainIndexMap.get("action"), is(nullValue()));
186+
assertThat(explainIndexMap.get("step"), is(nullValue()));
187+
assertThat(explainIndexMap.get("age"), is(nullValue()));
188+
assertThat(explainIndexMap.get("failed_step"), is(nullValue()));
189+
assertThat(explainIndexMap.get("step_info"), is(nullValue()));
190+
}
191+
192+
private void assertManagedIndex(Map<String, Object> explainIndexMap) {
193+
assertThat(explainIndexMap.get("managed"), is(true));
194+
assertThat(explainIndexMap.get("policy"), is(policy));
195+
assertThat(explainIndexMap.get("phase"), is("new"));
196+
assertThat(explainIndexMap.get("action"), is("complete"));
197+
assertThat(explainIndexMap.get("step"), is("complete"));
198+
assertThat(explainIndexMap.get("phase_time_millis"), is(notNullValue()));
199+
assertThat(explainIndexMap.get("age"), is(notNullValue()));
200+
assertThat(explainIndexMap.get("phase_execution"), is(notNullValue()));
201+
assertThat(explainIndexMap.get("failed_step"), is(nullValue()));
202+
assertThat(explainIndexMap.get("step_info"), is(nullValue()));
203+
}
204+
205+
}

0 commit comments

Comments
 (0)