add Rest tests to index-lifecycle (#30159)
* add QA-style Rest tests to index-lifecycle This PR introduces a `qa` module within the index-lifecycle project. the idea is to have both complex policies tested, as well as policies with isolated/singular actions. So far, only tests with policies containing one action are implemented. Following Actions have implemented tests in this commit - AllocateAction - DeleteAction - ForceMergeAction - ReadOnlyAction - ReplicasAction tests to be added later - RolloverAction - ShrinkAction * respond to review and enable integTests * fix dependsOn fiasco * fix license * update to new proj structure * move to new integTest with x-pack-core as module * remove unused imports * update to use module instead of plugin
This commit is contained in:
parent
4e757fff21
commit
2814557679
|
@ -1,6 +1,7 @@
|
|||
evaluationDependsOn(xpackModule('core'))
|
||||
|
||||
apply plugin: 'elasticsearch.esplugin'
|
||||
|
||||
esplugin {
|
||||
name 'x-pack-index-lifecycle'
|
||||
description 'Elasticsearch Expanded Pack Plugin - Index Lifecycle'
|
||||
|
@ -11,16 +12,23 @@ esplugin {
|
|||
}
|
||||
archivesBaseName = 'x-pack-index-lifecycle'
|
||||
|
||||
// TODO: enable this once we have tests
|
||||
licenseHeaders.enabled = false
|
||||
|
||||
integTest.enabled = false
|
||||
|
||||
dependencies {
|
||||
compileOnly "org.elasticsearch.plugin:x-pack-core:${version}"
|
||||
testCompile project(path: xpackModule('core'), configuration: 'testArtifacts')
|
||||
}
|
||||
|
||||
integTestCluster {
|
||||
numNodes = 2
|
||||
clusterName = 'index-lifecycle'
|
||||
setting 'xpack.security.enabled', 'false'
|
||||
setting 'xpack.watcher.enabled', 'false'
|
||||
setting 'xpack.monitoring.enabled', 'false'
|
||||
setting 'xpack.ml.enabled', 'false'
|
||||
setting 'xpack.index_lifecycle.enabled', 'true'
|
||||
setting 'indices.lifecycle.poll_interval', '500ms'
|
||||
module project(xpackModule('core'))
|
||||
}
|
||||
|
||||
run {
|
||||
plugin xpackModule('core')
|
||||
}
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* 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.indexlifecycle;
|
||||
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
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.indexlifecycle.AllocateAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.DeleteAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.ForceMergeAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.LifecyclePolicy;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.LifecycleSettings;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.Phase;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.ReadOnlyAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.ReplicasAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.TerminalPolicyStep;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.TimeseriesLifecycleType;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
|
||||
public class TimeSeriesLifecycleActionsIT extends ESRestTestCase {
|
||||
private String index;
|
||||
private String policy;
|
||||
|
||||
@Before
|
||||
public void refreshIndex() {
|
||||
index = randomAlphaOfLength(10).toLowerCase(Locale.ROOT);
|
||||
policy = randomAlphaOfLength(5);
|
||||
}
|
||||
|
||||
public void testAllocate() throws Exception {
|
||||
createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 2)
|
||||
.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0));
|
||||
String allocateNodeName = "node-" + randomFrom(0, 1);
|
||||
AllocateAction allocateAction = new AllocateAction(null, null, singletonMap("_name", allocateNodeName));
|
||||
createNewSingletonPolicy("warm", allocateAction);
|
||||
updateIndexSettings(index, Settings.builder().put(LifecycleSettings.LIFECYCLE_NAME, policy));
|
||||
assertBusy(() -> {
|
||||
Map<String, Object> settings = getOnlyIndexSettings(index);
|
||||
assertThat(getStepKey(settings), equalTo(TerminalPolicyStep.KEY));
|
||||
});
|
||||
ensureGreen(index);
|
||||
}
|
||||
|
||||
public void testDelete() throws Exception {
|
||||
createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
|
||||
.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0));
|
||||
createNewSingletonPolicy("delete", new DeleteAction());
|
||||
updateIndexSettings(index, Settings.builder().put(LifecycleSettings.LIFECYCLE_NAME, policy));
|
||||
assertBusy(() -> assertFalse(indexExists(index)));
|
||||
}
|
||||
|
||||
public void testReadOnly() throws Exception {
|
||||
createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
|
||||
.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0));
|
||||
createNewSingletonPolicy("warm", new ReadOnlyAction());
|
||||
updateIndexSettings(index, Settings.builder().put(LifecycleSettings.LIFECYCLE_NAME, policy));
|
||||
assertBusy(() -> {
|
||||
Map<String, Object> settings = getOnlyIndexSettings(index);
|
||||
assertThat(getStepKey(settings), equalTo(TerminalPolicyStep.KEY));
|
||||
assertThat(settings.get(IndexMetaData.INDEX_BLOCKS_WRITE_SETTING.getKey()), equalTo("true"));
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testForceMergeAction() throws Exception {
|
||||
createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
|
||||
.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0));
|
||||
for (int i = 0; i < randomIntBetween(2, 10); i++) {
|
||||
client().performRequest("PUT", index + "/_doc/" + i, singletonMap("refresh", "true"),
|
||||
new StringEntity("{\"a\": \"test\"}", ContentType.APPLICATION_JSON));
|
||||
}
|
||||
|
||||
Supplier<Integer> numSegments = () -> {
|
||||
try {
|
||||
Map<String, Object> segmentResponse = getAsMap(index + "/_segments");
|
||||
segmentResponse = (Map<String, Object>) segmentResponse.get("indices");
|
||||
segmentResponse = (Map<String, Object>) segmentResponse.get(index);
|
||||
segmentResponse = (Map<String, Object>) segmentResponse.get("shards");
|
||||
List<Map<String, Object>> shards = (List<Map<String, Object>>) segmentResponse.get("0");
|
||||
return (Integer) shards.get(0).get("num_search_segments");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
assertThat(numSegments.get(), greaterThan(1));
|
||||
|
||||
createNewSingletonPolicy("warm", new ForceMergeAction(1, false));
|
||||
updateIndexSettings(index, Settings.builder().put(LifecycleSettings.LIFECYCLE_NAME, policy));
|
||||
|
||||
assertBusy(() -> {
|
||||
assertThat(getStepKey(getOnlyIndexSettings(index)), equalTo(TerminalPolicyStep.KEY));
|
||||
assertThat(numSegments.get(), equalTo(1));
|
||||
});
|
||||
}
|
||||
|
||||
public void testReplicasAction() throws Exception {
|
||||
int numShards = randomFrom(1, 5);
|
||||
int numReplicas = randomFrom(0, 1);
|
||||
int finalNumReplicas = (numReplicas + 1) % 2;
|
||||
createIndexWithSettings(index, Settings.builder().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, numShards)
|
||||
.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, numReplicas));
|
||||
createNewSingletonPolicy("warm", new ReplicasAction(finalNumReplicas));
|
||||
updateIndexSettings(index, Settings.builder().put(LifecycleSettings.LIFECYCLE_NAME, policy));
|
||||
|
||||
assertBusy(() -> {
|
||||
Map<String, Object> settings = getOnlyIndexSettings(index);
|
||||
assertThat(getStepKey(settings), equalTo(TerminalPolicyStep.KEY));
|
||||
assertThat(settings.get(IndexMetaData.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey()), equalTo(String.valueOf(finalNumReplicas)));
|
||||
});
|
||||
}
|
||||
|
||||
private void createNewSingletonPolicy(String phaseName, LifecycleAction action) throws IOException {
|
||||
Phase phase = new Phase(phaseName, TimeValue.ZERO, singletonMap(action.getWriteableName(), action));
|
||||
LifecyclePolicy lifecyclePolicy =
|
||||
new LifecyclePolicy(TimeseriesLifecycleType.INSTANCE, policy, singletonMap(phase.getName(), phase));
|
||||
XContentBuilder builder = jsonBuilder();
|
||||
lifecyclePolicy.toXContent(builder, null);
|
||||
final StringEntity entity = new StringEntity(
|
||||
"{ \"policy\":" + Strings.toString(builder) + "}", ContentType.APPLICATION_JSON);
|
||||
client().performRequest("PUT", "_xpack/index_lifecycle/" + policy, Collections.emptyMap(), entity);
|
||||
}
|
||||
|
||||
private void createIndexWithSettings(String index, Settings.Builder settings) throws IOException {
|
||||
// create the test-index index
|
||||
createIndex(index, settings.build());
|
||||
// wait for the shards to initialize
|
||||
ensureGreen(index);
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> getOnlyIndexSettings(String index) throws IOException {
|
||||
return (Map<String, Object>) ((Map<String, Object>) getIndexSettings(index).get(index)).get("settings");
|
||||
}
|
||||
|
||||
private StepKey getStepKey(Map<String, Object> settings) {
|
||||
String phase = (String) settings.get(LifecycleSettings.LIFECYCLE_PHASE);
|
||||
String action = (String) settings.get(LifecycleSettings.LIFECYCLE_ACTION);
|
||||
String step = (String) settings.get(LifecycleSettings.LIFECYCLE_STEP);
|
||||
return new StepKey(phase, action, step);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue