add more force-merge related steps and tests
The force-merge is an a TODO state due to the unresolved issue around best_compression. - updated ReadOnlyStep with tests - implemented an update to the ForceMergeAction - added UpdateBestCompressionSettingsStep - added tests for SegmentCountStep
This commit is contained in:
parent
06e969b430
commit
f5b23df349
|
@ -5,39 +5,20 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack.core.indexlifecycle;
|
||||
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.ActionResponse;
|
||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequestBuilder;
|
||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeResponse;
|
||||
import org.elasticsearch.action.admin.indices.segments.IndicesSegmentResponse;
|
||||
import org.elasticsearch.action.admin.indices.segments.IndicesSegmentsRequest;
|
||||
import org.elasticsearch.action.admin.indices.segments.IndicesSegmentsRequestBuilder;
|
||||
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.LongSupplier;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
/**
|
||||
* A {@link LifecycleAction} which force-merges the index.
|
||||
|
@ -45,42 +26,53 @@ import java.util.stream.StreamSupport;
|
|||
public class ForceMergeAction implements LifecycleAction {
|
||||
public static final String NAME = "forcemerge";
|
||||
public static final ParseField MAX_NUM_SEGMENTS_FIELD = new ParseField("max_num_segments");
|
||||
public static final ParseField BEST_COMPRESSION_FIELD = new ParseField("best_compression");
|
||||
|
||||
private static final ConstructingObjectParser<ForceMergeAction, Void> PARSER = new ConstructingObjectParser<>(NAME,
|
||||
false, a -> {
|
||||
int maxNumSegments = (Integer) a[0];
|
||||
return new ForceMergeAction(maxNumSegments);
|
||||
boolean bestCompression = (Boolean) a[1];
|
||||
return new ForceMergeAction(maxNumSegments, bestCompression);
|
||||
});
|
||||
|
||||
static {
|
||||
PARSER.declareInt(ConstructingObjectParser.constructorArg(), MAX_NUM_SEGMENTS_FIELD);
|
||||
PARSER.declareBoolean(ConstructingObjectParser.optionalConstructorArg(), BEST_COMPRESSION_FIELD);
|
||||
}
|
||||
|
||||
private final Integer maxNumSegments;
|
||||
private final int maxNumSegments;
|
||||
private final boolean bestCompression;
|
||||
|
||||
public static ForceMergeAction parse(XContentParser parser) {
|
||||
return PARSER.apply(parser, null);
|
||||
}
|
||||
|
||||
public ForceMergeAction(int maxNumSegments) {
|
||||
public ForceMergeAction(int maxNumSegments, boolean bestCompression) {
|
||||
if (maxNumSegments <= 0) {
|
||||
throw new IllegalArgumentException("[" + MAX_NUM_SEGMENTS_FIELD.getPreferredName()
|
||||
+ "] must be a positive integer");
|
||||
}
|
||||
this.maxNumSegments = maxNumSegments;
|
||||
this.bestCompression = bestCompression;
|
||||
}
|
||||
|
||||
public ForceMergeAction(StreamInput in) throws IOException {
|
||||
this.maxNumSegments = in.readVInt();
|
||||
this.bestCompression = in.readBoolean();
|
||||
}
|
||||
|
||||
public int getMaxNumSegments() {
|
||||
return maxNumSegments;
|
||||
}
|
||||
|
||||
public boolean isBestCompression() {
|
||||
return bestCompression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
out.writeVInt(maxNumSegments);
|
||||
out.writeBoolean(bestCompression);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -92,34 +84,28 @@ public class ForceMergeAction implements LifecycleAction {
|
|||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
builder.field(MAX_NUM_SEGMENTS_FIELD.getPreferredName(), maxNumSegments);
|
||||
builder.field(BEST_COMPRESSION_FIELD.getPreferredName(), bestCompression);
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Step> toSteps(Client client, String phase, Step.StepKey nextStepKey) {
|
||||
|
||||
// ClientStep<IndicesSegmentsRequestBuilder, IndicesSegmentResponse> segmentCount = new ClientStep<>( "segment_count",
|
||||
// NAME, phase, index.getName(),
|
||||
// client.admin().indices().prepareSegments(index.getName()),
|
||||
// currentState -> false, response -> {
|
||||
// // check if has too many segments
|
||||
// return StreamSupport.stream(response.getIndices().get(index.getName()).spliterator(), false)
|
||||
// .anyMatch(iss -> Arrays.stream(iss.getShards()).anyMatch(p -> p.getSegments().size() > maxNumSegments));
|
||||
// });
|
||||
//
|
||||
// ClientStep forceMerge = new ClientStep<ForceMergeRequestBuilder, ForceMergeResponse>( "force_merge",
|
||||
// NAME, phase, index.getName(),
|
||||
// client.admin().indices().prepareForceMerge(index.getName()).setMaxNumSegments(maxNumSegments),
|
||||
// currentState -> false, response -> RestStatus.OK.equals(response.getStatus()));
|
||||
// just forceMerge... then wait to see whether segmentCount matches condition
|
||||
|
||||
return Arrays.asList();
|
||||
StepKey updateCompressionKey = new StepKey(phase, NAME, UpdateBestCompressionSettingsStep.NAME);
|
||||
StepKey forceMergeKey = new StepKey(phase, NAME, ForceMergeStep.NAME);
|
||||
StepKey countKey = new StepKey(phase, NAME, SegmentCountStep.NAME);
|
||||
ForceMergeStep forceMergeStep = new ForceMergeStep(forceMergeKey, countKey, client, maxNumSegments);
|
||||
SegmentCountStep segmentCountStep = new SegmentCountStep(countKey, nextStepKey, client, maxNumSegments, bestCompression);
|
||||
if (bestCompression) {
|
||||
UpdateBestCompressionSettingsStep updateBestCompression = new UpdateBestCompressionSettingsStep(updateCompressionKey, forceMergeKey);
|
||||
return Arrays.asList(updateBestCompression, forceMergeStep, segmentCountStep);
|
||||
}
|
||||
return Arrays.asList(forceMergeStep, segmentCountStep);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(maxNumSegments);
|
||||
return Objects.hash(maxNumSegments, bestCompression);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -131,7 +117,8 @@ public class ForceMergeAction implements LifecycleAction {
|
|||
return false;
|
||||
}
|
||||
ForceMergeAction other = (ForceMergeAction) obj;
|
||||
return Objects.equals(maxNumSegments, other.maxNumSegments);
|
||||
return Objects.equals(maxNumSegments, other.maxNumSegments)
|
||||
&& Objects.equals(bestCompression, other.bestCompression);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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.core.indexlifecycle;
|
||||
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
|
||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ForceMergeStep extends AsyncActionStep {
|
||||
public static final String NAME = "forcemerge";
|
||||
private final int maxNumSegments;
|
||||
|
||||
public ForceMergeStep(StepKey key, StepKey nextStepKey, Client client, int maxNumSegments) {
|
||||
super(key, nextStepKey, client);
|
||||
this.maxNumSegments = maxNumSegments;
|
||||
}
|
||||
|
||||
public int getMaxNumSegments() {
|
||||
return maxNumSegments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performAction(Index index, Listener listener) {
|
||||
ForceMergeRequest request = new ForceMergeRequest();
|
||||
request.maxNumSegments(maxNumSegments);
|
||||
getClient().admin().indices()
|
||||
.forceMerge(request, ActionListener.wrap(response -> listener.onResponse(true),
|
||||
listener::onFailure));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), maxNumSegments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ForceMergeStep other = (ForceMergeStep) obj;
|
||||
return super.equals(obj) &&
|
||||
Objects.equals(maxNumSegments, other.maxNumSegments);
|
||||
}
|
||||
}
|
|
@ -10,12 +10,14 @@ import org.elasticsearch.common.Strings;
|
|||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A {@link LifecycleAction} which force-merges the index.
|
||||
|
@ -24,8 +26,7 @@ public class ReadOnlyAction implements LifecycleAction {
|
|||
public static final String NAME = "readonly";
|
||||
public static final ReadOnlyAction INSTANCE = new ReadOnlyAction();
|
||||
|
||||
private static final ConstructingObjectParser<ReadOnlyAction, Void> PARSER = new ConstructingObjectParser<>(NAME,
|
||||
false, a -> new ReadOnlyAction());
|
||||
private static final ObjectParser<ReadOnlyAction, Void> PARSER = new ObjectParser<>(NAME, false, ReadOnlyAction::new);
|
||||
|
||||
public static ReadOnlyAction parse(XContentParser parser) {
|
||||
return PARSER.apply(parser, null);
|
||||
|
@ -55,10 +56,26 @@ public class ReadOnlyAction implements LifecycleAction {
|
|||
|
||||
@Override
|
||||
public List<Step> toSteps(Client client, String phase, Step.StepKey nextStepKey) {
|
||||
Step.StepKey key = new Step.StepKey(phase, NAME, "readonly-step");
|
||||
Step.StepKey key = new Step.StepKey(phase, NAME, ReadOnlyStep.NAME);
|
||||
return Collections.singletonList(new ReadOnlyStep(key, nextStepKey));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ReadOnlyAction.class.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (obj.getClass() != getClass()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Strings.toString(this);
|
||||
|
|
|
@ -11,7 +11,10 @@ import org.elasticsearch.cluster.metadata.MetaData;
|
|||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.Index;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ReadOnlyStep extends ClusterStateActionStep {
|
||||
public static final String NAME = "read-only";
|
||||
|
||||
ReadOnlyStep(StepKey key, StepKey nextStepKey) {
|
||||
super(key, nextStepKey);
|
||||
|
|
|
@ -5,27 +5,77 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack.core.indexlifecycle;
|
||||
|
||||
import org.apache.lucene.codecs.lucene50.Lucene50StoredFieldsFormat;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.admin.indices.segments.IndicesSegmentsRequest;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.index.Index;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
/**
|
||||
* This {@link Step} evaluates whether force_merge was successful
|
||||
*/
|
||||
public class SegmentCountStep extends AsyncWaitStep {
|
||||
public static final String NAME = "segment-count";
|
||||
|
||||
private final int maxNumSegments;
|
||||
private final boolean bestCompression;
|
||||
|
||||
public SegmentCountStep(StepKey key, StepKey nextStepKey, Client client, int maxNumSegments) {
|
||||
public SegmentCountStep(StepKey key, StepKey nextStepKey, Client client, int maxNumSegments, boolean bestCompression) {
|
||||
super(key, nextStepKey, client);
|
||||
this.maxNumSegments = maxNumSegments;
|
||||
this.bestCompression = bestCompression;
|
||||
}
|
||||
|
||||
public int getMaxNumSegments() {
|
||||
return maxNumSegments;
|
||||
}
|
||||
|
||||
public boolean isBestCompression() {
|
||||
return bestCompression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evaluateCondition(Index index, Listener listener) {
|
||||
getClient().admin().indices().prepareSegments(index.getName()).execute(ActionListener.wrap(response -> {
|
||||
getClient().admin().indices().segments(new IndicesSegmentsRequest(index.getName()), ActionListener.wrap(response -> {
|
||||
listener.onResponse(StreamSupport.stream(response.getIndices().get(index.getName()).spliterator(), false)
|
||||
.anyMatch(iss -> Arrays.stream(iss.getShards()).anyMatch(p -> p.getSegments().size() > maxNumSegments)));
|
||||
.anyMatch(iss -> Arrays.stream(iss.getShards()).anyMatch(p -> {
|
||||
boolean hasRightAmountOfSegments = p.getSegments().size() <= maxNumSegments;
|
||||
if (bestCompression) {
|
||||
// // TODO(talevy): discuss
|
||||
// boolean allUsingCorrectCompression = p.getSegments().stream().anyMatch(s ->
|
||||
// Lucene50StoredFieldsFormat.Mode.BEST_COMPRESSION.equals(
|
||||
// Lucene50StoredFieldsFormat.Mode.BEST_COMPRESSION.toString().equals(
|
||||
// s.getAttributes().get(Lucene50StoredFieldsFormat.MODE_KEY)))
|
||||
// );
|
||||
boolean allUsingCorrectCompression = true;
|
||||
return hasRightAmountOfSegments && allUsingCorrectCompression;
|
||||
} else {
|
||||
return hasRightAmountOfSegments;
|
||||
}
|
||||
})));
|
||||
}, listener::onFailure));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), maxNumSegments, bestCompression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SegmentCountStep other = (SegmentCountStep) obj;
|
||||
return super.equals(obj)
|
||||
&& Objects.equals(maxNumSegments, other.maxNumSegments)
|
||||
&& Objects.equals(bestCompression, other.bestCompression);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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.core.indexlifecycle;
|
||||
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.codec.CodecService;
|
||||
import org.elasticsearch.index.engine.EngineConfig;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class UpdateBestCompressionSettingsStep extends ClusterStateActionStep {
|
||||
public static final String NAME = "update-best-compression";
|
||||
|
||||
public UpdateBestCompressionSettingsStep(StepKey key, StepKey nextStepKey) {
|
||||
super(key, nextStepKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClusterState performAction(Index index, ClusterState clusterState) {
|
||||
IndexMetaData idxMeta = clusterState.metaData().index(index);
|
||||
if (idxMeta == null) {
|
||||
return clusterState;
|
||||
}
|
||||
Settings.Builder newSettings = Settings.builder()
|
||||
.put(EngineConfig.INDEX_CODEC_SETTING.getKey(), CodecService.BEST_COMPRESSION_CODEC);
|
||||
|
||||
return ClusterState.builder(clusterState)
|
||||
.metaData(MetaData.builder(clusterState.metaData())
|
||||
.updateSettings(newSettings.build(), index.getName())).build();
|
||||
}
|
||||
}
|
|
@ -91,7 +91,6 @@ public class DeleteStepTests extends ESTestCase {
|
|||
assertEquals(1, request.indices().length);
|
||||
assertEquals(index.getName(), request.indices()[0]);
|
||||
listener.onFailure(exception);
|
||||
;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,63 +5,43 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack.core.indexlifecycle;
|
||||
|
||||
import org.apache.lucene.util.SetOnce;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeResponse;
|
||||
import org.elasticsearch.action.admin.indices.segments.IndexSegments;
|
||||
import org.elasticsearch.action.admin.indices.segments.IndexShardSegments;
|
||||
import org.elasticsearch.action.admin.indices.segments.IndicesSegmentResponse;
|
||||
import org.elasticsearch.action.admin.indices.segments.ShardSegments;
|
||||
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsResponse;
|
||||
import org.elasticsearch.client.AdminClient;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.client.IndicesAdminClient;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
||||
import org.elasticsearch.common.io.stream.Writeable.Reader;
|
||||
import org.elasticsearch.common.xcontent.DeprecationHandler;
|
||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.engine.Segment;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
import org.elasticsearch.test.AbstractSerializingTestCase;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mockito;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Spliterator;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.mockito.Matchers.any;
|
||||
|
||||
public class ForceMergeActionTests extends AbstractSerializingTestCase<ForceMergeAction> {
|
||||
|
||||
@Override
|
||||
protected ForceMergeAction doParseInstance(XContentParser parser) throws IOException {
|
||||
protected ForceMergeAction doParseInstance(XContentParser parser) {
|
||||
return ForceMergeAction.parse(parser);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ForceMergeAction createTestInstance() {
|
||||
return new ForceMergeAction(randomIntBetween(1, 100));
|
||||
return new ForceMergeAction(randomIntBetween(1, 100), randomBoolean());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ForceMergeAction mutateInstance(ForceMergeAction instance) {
|
||||
return new ForceMergeAction(instance.getMaxNumSegments() + randomIntBetween(1, 10));
|
||||
int maxNumSegments = instance.getMaxNumSegments();
|
||||
boolean bestCompression = instance.isBestCompression();
|
||||
if (randomBoolean()) {
|
||||
maxNumSegments = maxNumSegments + randomIntBetween(1, 10);
|
||||
} else {
|
||||
bestCompression = !bestCompression;
|
||||
}
|
||||
return new ForceMergeAction(maxNumSegments, bestCompression);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,336 +58,30 @@ public class ForceMergeActionTests extends AbstractSerializingTestCase<ForceMerg
|
|||
}
|
||||
|
||||
public void testInvalidNegativeSegmentNumber() {
|
||||
Exception r = expectThrows(IllegalArgumentException.class, () -> new ForceMergeAction(randomIntBetween(-10, 0)));
|
||||
Exception r = expectThrows(IllegalArgumentException.class, () -> new ForceMergeAction(randomIntBetween(-10, 0), false));
|
||||
assertThat(r.getMessage(), equalTo("[max_num_segments] must be a positive integer"));
|
||||
}
|
||||
|
||||
// public void testExecuteSuccessfully() throws Exception {
|
||||
// Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
|
||||
//
|
||||
// ClusterService clusterService = Mockito.mock(ClusterService.class);
|
||||
// IndexMetaData indexMetadata = IndexMetaData.builder(index.getName())
|
||||
// .settings(settings(Version.CURRENT))
|
||||
// .numberOfShards(randomIntBetween(1, 5)).numberOfReplicas(randomIntBetween(0, 5)).build();
|
||||
// ImmutableOpenMap.Builder<String, IndexMetaData> indices = ImmutableOpenMap.<String, IndexMetaData> builder().fPut(index.getName(),
|
||||
// indexMetadata);
|
||||
// ClusterState clusterState = ClusterState.builder(ClusterState.EMPTY_STATE).metaData(MetaData.builder().indices(indices.build()))
|
||||
// .build();
|
||||
// Mockito.when(clusterService.state()).thenReturn(clusterState);
|
||||
// Client client = Mockito.mock(Client.class);
|
||||
// AdminClient adminClient = Mockito.mock(AdminClient.class);
|
||||
// IndicesAdminClient indicesClient = Mockito.mock(IndicesAdminClient.class);
|
||||
// UpdateSettingsResponse updateSettingsResponse = Mockito.mock(UpdateSettingsResponse.class);
|
||||
// IndicesSegmentResponse indicesSegmentResponse = Mockito.mock(IndicesSegmentResponse.class);
|
||||
// IndexSegments indexSegments = Mockito.mock(IndexSegments.class);
|
||||
// IndexShardSegments indexShardSegments = Mockito.mock(IndexShardSegments.class);
|
||||
// Map<Integer, IndexShardSegments> indexShards = Collections.singletonMap(0, indexShardSegments);
|
||||
// ShardSegments shardSegmentsOne = Mockito.mock(ShardSegments.class);
|
||||
// ShardSegments[] shardSegmentsArray = new ShardSegments[] { shardSegmentsOne };
|
||||
// Spliterator<IndexShardSegments> iss = indexShards.values().spliterator();
|
||||
// List<Segment> segments = Arrays.asList(null, null);
|
||||
// ForceMergeResponse forceMergeResponse = Mockito.mock(ForceMergeResponse.class);
|
||||
// Mockito.when(forceMergeResponse.getStatus()).thenReturn(RestStatus.OK);
|
||||
// Mockito.when(indicesSegmentResponse.getStatus()).thenReturn(RestStatus.OK);
|
||||
// Mockito.when(indicesSegmentResponse.getIndices()).thenReturn(Collections.singletonMap(index.getName(), indexSegments));
|
||||
// Mockito.when(indexSegments.spliterator()).thenReturn(iss);
|
||||
// Mockito.when(indexShardSegments.getShards()).thenReturn(shardSegmentsArray);
|
||||
// Mockito.when(shardSegmentsOne.getSegments()).thenReturn(segments);
|
||||
// int maxNumSegments = 1;
|
||||
//
|
||||
// Mockito.when(client.admin()).thenReturn(adminClient);
|
||||
// Mockito.when(adminClient.indices()).thenReturn(indicesClient);
|
||||
//
|
||||
// Mockito.doAnswer(invocationOnMock -> {
|
||||
// @SuppressWarnings("unchecked")
|
||||
// ActionListener<IndicesSegmentResponse> listener = (ActionListener<IndicesSegmentResponse>) invocationOnMock.getArguments()[1];
|
||||
// listener.onResponse(indicesSegmentResponse);
|
||||
// return null;
|
||||
// }).when(indicesClient).segments(any(), any());
|
||||
//
|
||||
// Mockito.doAnswer(invocationOnMock -> {
|
||||
// @SuppressWarnings("unchecked")
|
||||
// ActionListener<UpdateSettingsResponse> listener = (ActionListener<UpdateSettingsResponse>) invocationOnMock.getArguments()[1];
|
||||
// listener.onResponse(updateSettingsResponse);
|
||||
// return null;
|
||||
// }).when(indicesClient).updateSettings(any(), any());
|
||||
//
|
||||
// Mockito.doAnswer(invocationOnMock -> {
|
||||
// ForceMergeRequest request = (ForceMergeRequest) invocationOnMock.getArguments()[0];
|
||||
// assertThat(request.maxNumSegments(), equalTo(maxNumSegments));
|
||||
// @SuppressWarnings("unchecked")
|
||||
// ActionListener<ForceMergeResponse> listener = (ActionListener<ForceMergeResponse>) invocationOnMock.getArguments()[1];
|
||||
// listener.onResponse(forceMergeResponse);
|
||||
// return null;
|
||||
// }).when(indicesClient).forceMerge(any(), any());
|
||||
//
|
||||
// SetOnce<Boolean> actionCompleted = new SetOnce<>();
|
||||
// ForceMergeAction action = new ForceMergeAction(maxNumSegments);
|
||||
// action.execute(index, client, clusterService, new Listener() {
|
||||
//
|
||||
// @Override
|
||||
// public void onSuccess(boolean completed) {
|
||||
// actionCompleted.set(completed);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onFailure(Exception e) {
|
||||
// throw new AssertionError("Unexpected method call", e);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// assertEquals(true, actionCompleted.get());
|
||||
//
|
||||
// Mockito.verify(client, Mockito.atLeast(1)).admin();
|
||||
// Mockito.verify(adminClient, Mockito.atLeast(1)).indices();
|
||||
// Mockito.verify(indicesClient, Mockito.atLeast(1)).segments(any(), any());
|
||||
// Mockito.verify(indicesClient, Mockito.atLeast(1)).updateSettings(any(), any());
|
||||
// Mockito.verify(indicesClient, Mockito.atLeast(1)).forceMerge(any(), any());
|
||||
// Mockito.verify(clusterService, Mockito.atLeast(1)).state();
|
||||
// }
|
||||
//
|
||||
// public void testExecuteWhenReadOnlyAlready() {
|
||||
// Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
|
||||
// boolean isReadOnlyAlready = true;
|
||||
//
|
||||
// ClusterService clusterService = Mockito.mock(ClusterService.class);
|
||||
// IndexMetaData indexMetadata = IndexMetaData.builder(index.getName())
|
||||
// .settings(settings(Version.CURRENT).put(IndexMetaData.SETTING_BLOCKS_WRITE, isReadOnlyAlready))
|
||||
// .numberOfShards(randomIntBetween(1, 5)).numberOfReplicas(randomIntBetween(0, 5)).build();
|
||||
// ImmutableOpenMap.Builder<String, IndexMetaData> indices = ImmutableOpenMap.<String, IndexMetaData> builder().fPut(index.getName(),
|
||||
// indexMetadata);
|
||||
// ClusterState clusterState = ClusterState.builder(ClusterState.EMPTY_STATE).metaData(MetaData.builder().indices(indices.build()))
|
||||
// .build();
|
||||
// Mockito.when(clusterService.state()).thenReturn(clusterState);
|
||||
//
|
||||
// Client client = Mockito.mock(Client.class);
|
||||
// AdminClient adminClient = Mockito.mock(AdminClient.class);
|
||||
// IndicesAdminClient indicesClient = Mockito.mock(IndicesAdminClient.class);
|
||||
// IndicesSegmentResponse indicesSegmentResponse = Mockito.mock(IndicesSegmentResponse.class);
|
||||
// IndexSegments indexSegments = Mockito.mock(IndexSegments.class);
|
||||
// IndexShardSegments indexShardSegments = Mockito.mock(IndexShardSegments.class);
|
||||
// Map<Integer, IndexShardSegments> indexShards = Collections.singletonMap(0, indexShardSegments);
|
||||
// ShardSegments shardSegmentsOne = Mockito.mock(ShardSegments.class);
|
||||
// ShardSegments[] shardSegmentsArray = new ShardSegments[] { shardSegmentsOne };
|
||||
// Spliterator<IndexShardSegments> iss = indexShards.values().spliterator();
|
||||
// List<Segment> segments = Arrays.asList(null, null);
|
||||
//
|
||||
// Mockito.when(indicesSegmentResponse.getStatus()).thenReturn(RestStatus.OK);
|
||||
// Mockito.when(indicesSegmentResponse.getIndices()).thenReturn(Collections.singletonMap(index.getName(), indexSegments));
|
||||
// Mockito.when(indexSegments.spliterator()).thenReturn(iss);
|
||||
// Mockito.when(indexShardSegments.getShards()).thenReturn(shardSegmentsArray);
|
||||
// Mockito.when(shardSegmentsOne.getSegments()).thenReturn(segments);
|
||||
// int maxNumSegments = Integer.MAX_VALUE;
|
||||
//
|
||||
// Mockito.when(client.admin()).thenReturn(adminClient);
|
||||
// Mockito.when(adminClient.indices()).thenReturn(indicesClient);
|
||||
//
|
||||
//
|
||||
// Mockito.doAnswer(invocationOnMock -> {
|
||||
// @SuppressWarnings("unchecked")
|
||||
// ActionListener<IndicesSegmentResponse> listener = (ActionListener<IndicesSegmentResponse>) invocationOnMock.getArguments()[1];
|
||||
// listener.onResponse(indicesSegmentResponse);
|
||||
// return null;
|
||||
// }).when(indicesClient).segments(any(), any());
|
||||
//
|
||||
//
|
||||
// SetOnce<Boolean> actionCompleted = new SetOnce<>();
|
||||
// ForceMergeAction action = new ForceMergeAction(maxNumSegments);
|
||||
// action.execute(index, client, clusterService, new Listener() {
|
||||
//
|
||||
// @Override
|
||||
// public void onSuccess(boolean completed) {
|
||||
// actionCompleted.set(completed);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onFailure(Exception e) {
|
||||
// throw new AssertionError("Unexpected method call", e);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// assertEquals(null, actionCompleted.get());
|
||||
//
|
||||
// InOrder inOrder = Mockito.inOrder(clusterService, client, adminClient, indicesClient);
|
||||
// inOrder.verify(clusterService).state();
|
||||
// inOrder.verify(client).admin();
|
||||
// inOrder.verify(adminClient).indices();
|
||||
// inOrder.verify(indicesClient).segments(any(), any());
|
||||
// inOrder.verify(indicesClient).updateSettings(any(), any());
|
||||
// Mockito.verify(indicesClient, Mockito.never()).forceMerge(any(), any());
|
||||
// }
|
||||
//
|
||||
// public void testExecuteWithNoNeedToForceMerge() {
|
||||
// Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
|
||||
// boolean isReadOnlyAlready = false;
|
||||
//
|
||||
// ClusterService clusterService = Mockito.mock(ClusterService.class);
|
||||
// IndexMetaData indexMetadata = IndexMetaData.builder(index.getName())
|
||||
// .settings(settings(Version.CURRENT).put(IndexMetaData.SETTING_BLOCKS_WRITE, isReadOnlyAlready))
|
||||
// .numberOfShards(randomIntBetween(1, 5)).numberOfReplicas(randomIntBetween(0, 5)).build();
|
||||
// ImmutableOpenMap.Builder<String, IndexMetaData> indices = ImmutableOpenMap.<String, IndexMetaData> builder().fPut(index.getName(),
|
||||
// indexMetadata);
|
||||
// ClusterState clusterState = ClusterState.builder(ClusterState.EMPTY_STATE).metaData(MetaData.builder().indices(indices.build()))
|
||||
// .build();
|
||||
// Mockito.when(clusterService.state()).thenReturn(clusterState);
|
||||
//
|
||||
// Client client = Mockito.mock(Client.class);
|
||||
// AdminClient adminClient = Mockito.mock(AdminClient.class);
|
||||
// IndicesAdminClient indicesClient = Mockito.mock(IndicesAdminClient.class);
|
||||
// IndicesSegmentResponse indicesSegmentResponse = Mockito.mock(IndicesSegmentResponse.class);
|
||||
// IndexSegments indexSegments = Mockito.mock(IndexSegments.class);
|
||||
// IndexShardSegments indexShardSegments = Mockito.mock(IndexShardSegments.class);
|
||||
// Map<Integer, IndexShardSegments> indexShards = Collections.singletonMap(0, indexShardSegments);
|
||||
// ShardSegments shardSegmentsOne = Mockito.mock(ShardSegments.class);
|
||||
// ShardSegments[] shardSegmentsArray = new ShardSegments[] { shardSegmentsOne };
|
||||
// Spliterator<IndexShardSegments> iss = indexShards.values().spliterator();
|
||||
// List<Segment> segments = Arrays.asList(null, null);
|
||||
//
|
||||
// Mockito.when(indicesSegmentResponse.getStatus()).thenReturn(RestStatus.OK);
|
||||
// Mockito.when(indicesSegmentResponse.getIndices()).thenReturn(Collections.singletonMap(index.getName(), indexSegments));
|
||||
// Mockito.when(indexSegments.spliterator()).thenReturn(iss);
|
||||
// Mockito.when(indexShardSegments.getShards()).thenReturn(shardSegmentsArray);
|
||||
// Mockito.when(shardSegmentsOne.getSegments()).thenReturn(segments);
|
||||
// int maxNumSegments = Integer.MAX_VALUE;
|
||||
//
|
||||
// Mockito.when(client.admin()).thenReturn(adminClient);
|
||||
// Mockito.when(adminClient.indices()).thenReturn(indicesClient);
|
||||
//
|
||||
//
|
||||
// Mockito.doAnswer(invocationOnMock -> {
|
||||
// @SuppressWarnings("unchecked")
|
||||
// ActionListener<IndicesSegmentResponse> listener = (ActionListener<IndicesSegmentResponse>) invocationOnMock.getArguments()[1];
|
||||
// listener.onResponse(indicesSegmentResponse);
|
||||
// return null;
|
||||
// }).when(indicesClient).segments(any(), any());
|
||||
//
|
||||
//
|
||||
// SetOnce<Boolean> actionCompleted = new SetOnce<>();
|
||||
// ForceMergeAction action = new ForceMergeAction(maxNumSegments);
|
||||
// action.execute(index, client, clusterService, new Listener() {
|
||||
//
|
||||
// @Override
|
||||
// public void onSuccess(boolean completed) {
|
||||
// actionCompleted.set(completed);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onFailure(Exception e) {
|
||||
// throw new AssertionError("Unexpected method call", e);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// assertEquals(true, actionCompleted.get());
|
||||
//
|
||||
// InOrder inOrder = Mockito.inOrder(clusterService, client, adminClient, indicesClient);
|
||||
// inOrder.verify(clusterService).state();
|
||||
// inOrder.verify(client).admin();
|
||||
// inOrder.verify(adminClient).indices();
|
||||
// inOrder.verify(indicesClient).segments(any(), any());
|
||||
// Mockito.verify(indicesClient, Mockito.never()).updateSettings(any(), any());
|
||||
// Mockito.verify(indicesClient, Mockito.never()).forceMerge(any(), any());
|
||||
// }
|
||||
//
|
||||
// public void testCheckSegmentsNeedsMerging() {
|
||||
// Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
|
||||
// Client client = Mockito.mock(Client.class);
|
||||
// AdminClient adminClient = Mockito.mock(AdminClient.class);
|
||||
// IndicesAdminClient indicesClient = Mockito.mock(IndicesAdminClient.class);
|
||||
// IndicesSegmentResponse indicesSegmentResponse = Mockito.mock(IndicesSegmentResponse.class);
|
||||
// IndexSegments indexSegments = Mockito.mock(IndexSegments.class);
|
||||
// IndexShardSegments indexShardSegments = Mockito.mock(IndexShardSegments.class);
|
||||
// Map<Integer, IndexShardSegments> indexShards = Collections.singletonMap(0, indexShardSegments);
|
||||
// ShardSegments shardSegmentsOne = Mockito.mock(ShardSegments.class);
|
||||
// ShardSegments[] shardSegmentsArray = new ShardSegments[] { shardSegmentsOne };
|
||||
// Spliterator<IndexShardSegments> iss = indexShards.values().spliterator();
|
||||
// List<Segment> segments = Arrays.asList(null, null);
|
||||
// Mockito.when(indicesSegmentResponse.getStatus()).thenReturn(RestStatus.OK);
|
||||
// Mockito.when(indicesSegmentResponse.getIndices()).thenReturn(Collections.singletonMap(index.getName(), indexSegments));
|
||||
// Mockito.when(indexSegments.spliterator()).thenReturn(iss);
|
||||
// Mockito.when(indexShardSegments.getShards()).thenReturn(shardSegmentsArray);
|
||||
// Mockito.when(shardSegmentsOne.getSegments()).thenReturn(segments);
|
||||
// int maxNumSegments = 1;
|
||||
//
|
||||
// Mockito.when(client.admin()).thenReturn(adminClient);
|
||||
// Mockito.when(adminClient.indices()).thenReturn(indicesClient);
|
||||
//
|
||||
// Mockito.doAnswer(invocationOnMock -> {
|
||||
// @SuppressWarnings("unchecked")
|
||||
// ActionListener<IndicesSegmentResponse> listener = (ActionListener<IndicesSegmentResponse>) invocationOnMock.getArguments()[1];
|
||||
// listener.onResponse(indicesSegmentResponse);
|
||||
// return null;
|
||||
// }).when(indicesClient).segments(any(), any());
|
||||
//
|
||||
// SetOnce<Boolean> nextActionCalled = new SetOnce<>();
|
||||
// ForceMergeAction action = new ForceMergeAction(maxNumSegments);
|
||||
// action.checkSegments(index, client, new Listener() {
|
||||
//
|
||||
// @Override
|
||||
// public void onSuccess(boolean completed) {
|
||||
// throw new AssertionError("Unexpected method call to onSuccess");
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onFailure(Exception e) {
|
||||
// throw new AssertionError("Unexpected method call", e);
|
||||
// }
|
||||
// }, r -> nextActionCalled.set(true), r2 -> {throw new AssertionError("unexpected call to action");});
|
||||
//
|
||||
// assertEquals(true, nextActionCalled.get());
|
||||
// Mockito.verify(client, Mockito.only()).admin();
|
||||
// Mockito.verify(adminClient, Mockito.only()).indices();
|
||||
// Mockito.verify(indicesClient, Mockito.only()).segments(any(), any());
|
||||
// }
|
||||
//
|
||||
// public void testCheckSegmentsNoNeedToMerge() {
|
||||
// Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
|
||||
// Client client = Mockito.mock(Client.class);
|
||||
// AdminClient adminClient = Mockito.mock(AdminClient.class);
|
||||
// IndicesAdminClient indicesClient = Mockito.mock(IndicesAdminClient.class);
|
||||
// IndicesSegmentResponse indicesSegmentResponse = Mockito.mock(IndicesSegmentResponse.class);
|
||||
// IndexSegments indexSegments = Mockito.mock(IndexSegments.class);
|
||||
// IndexShardSegments indexShardSegments = Mockito.mock(IndexShardSegments.class);
|
||||
// Map<Integer, IndexShardSegments> indexShards = Collections.singletonMap(0, indexShardSegments);
|
||||
// ShardSegments shardSegmentsOne = Mockito.mock(ShardSegments.class);
|
||||
// ShardSegments[] shardSegmentsArray = new ShardSegments[] { shardSegmentsOne };
|
||||
// Spliterator<IndexShardSegments> iss = indexShards.values().spliterator();
|
||||
// List<Segment> segments = Arrays.asList(null, null);
|
||||
// Mockito.when(indicesSegmentResponse.getStatus()).thenReturn(RestStatus.OK);
|
||||
// Mockito.when(indicesSegmentResponse.getIndices()).thenReturn(Collections.singletonMap(index.getName(), indexSegments));
|
||||
// Mockito.when(indexSegments.spliterator()).thenReturn(iss);
|
||||
// Mockito.when(indexShardSegments.getShards()).thenReturn(shardSegmentsArray);
|
||||
// Mockito.when(shardSegmentsOne.getSegments()).thenReturn(segments);
|
||||
// int maxNumSegments = randomIntBetween(2, Integer.MAX_VALUE);
|
||||
//
|
||||
// Mockito.when(client.admin()).thenReturn(adminClient);
|
||||
// Mockito.when(adminClient.indices()).thenReturn(indicesClient);
|
||||
//
|
||||
// Mockito.doAnswer(invocationOnMock -> {
|
||||
// @SuppressWarnings("unchecked")
|
||||
// ActionListener<IndicesSegmentResponse> listener = (ActionListener<IndicesSegmentResponse>) invocationOnMock.getArguments()[1];
|
||||
// listener.onResponse(indicesSegmentResponse);
|
||||
// return null;
|
||||
// }).when(indicesClient).segments(any(), any());
|
||||
//
|
||||
// SetOnce<Boolean> skipActionCalled = new SetOnce<>();
|
||||
// ForceMergeAction action = new ForceMergeAction(maxNumSegments);
|
||||
// action.checkSegments(index, client, new Listener() {
|
||||
//
|
||||
// @Override
|
||||
// public void onSuccess(boolean completed) {
|
||||
// throw new AssertionError("Unexpected method call to onSuccess");
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onFailure(Exception e) {
|
||||
// throw new AssertionError("Unexpected method call", e);
|
||||
// }
|
||||
// }, r -> { throw new AssertionError("next action should not be called"); },
|
||||
// r2 -> skipActionCalled.set(true));
|
||||
//
|
||||
// assertTrue(skipActionCalled.get());
|
||||
// Mockito.verify(client, Mockito.only()).admin();
|
||||
// Mockito.verify(adminClient, Mockito.only()).indices();
|
||||
// Mockito.verify(indicesClient, Mockito.only()).segments(any(), any());
|
||||
// }
|
||||
public void testToSteps() {
|
||||
ForceMergeAction instance = createTestInstance();
|
||||
String phase = randomAlphaOfLength(5);
|
||||
StepKey nextStepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
List<Step> steps = instance.toSteps(null, phase, nextStepKey);
|
||||
assertNotNull(steps);
|
||||
int segmentCountIndex = 1;
|
||||
if (instance.isBestCompression()) {
|
||||
assertEquals(3, steps.size());
|
||||
UpdateBestCompressionSettingsStep firstStep = (UpdateBestCompressionSettingsStep) steps.get(0);
|
||||
assertThat(firstStep.getKey(), equalTo(new StepKey(phase, ForceMergeAction.NAME, UpdateBestCompressionSettingsStep.NAME)));
|
||||
segmentCountIndex = 2;
|
||||
} else {
|
||||
assertEquals(2, steps.size());
|
||||
}
|
||||
ForceMergeStep firstStep = (ForceMergeStep) steps.get(0);
|
||||
SegmentCountStep secondStep = (SegmentCountStep) steps.get(segmentCountIndex);
|
||||
assertThat(firstStep.getKey(), equalTo(new StepKey(phase, ForceMergeAction.NAME, ForceMergeStep.NAME)));
|
||||
assertThat(firstStep.getNextStepKey(), equalTo(secondStep.getKey()));
|
||||
assertThat(secondStep.getKey(), equalTo(new StepKey(phase, ForceMergeAction.NAME, SegmentCountStep.NAME)));
|
||||
assertThat(secondStep.getNextStepKey(), equalTo(nextStepKey));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* 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.core.indexlifecycle;
|
||||
|
||||
|
||||
import org.apache.lucene.util.SetOnce;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
|
||||
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
|
||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeRequest;
|
||||
import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeResponse;
|
||||
import org.elasticsearch.client.AdminClient;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.client.IndicesAdminClient;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.test.EqualsHashCodeTestUtils;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
||||
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class ForceMergeStepTests extends ESTestCase {
|
||||
|
||||
public ForceMergeStep createRandomInstance() {
|
||||
Step.StepKey stepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
StepKey nextStepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
int maxNumSegments = randomIntBetween(1, 10);
|
||||
|
||||
return new ForceMergeStep(stepKey, nextStepKey, null, maxNumSegments);
|
||||
}
|
||||
|
||||
public ForceMergeStep mutateInstance(ForceMergeStep instance) {
|
||||
StepKey key = instance.getKey();
|
||||
StepKey nextKey = instance.getNextStepKey();
|
||||
int maxNumSegments = instance.getMaxNumSegments();
|
||||
|
||||
switch (between(0, 2)) {
|
||||
case 0:
|
||||
key = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5));
|
||||
break;
|
||||
case 1:
|
||||
nextKey = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5));
|
||||
break;
|
||||
case 2:
|
||||
maxNumSegments += 1;
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError("Illegal randomisation branch");
|
||||
}
|
||||
|
||||
return new ForceMergeStep(key, nextKey, null, maxNumSegments);
|
||||
}
|
||||
|
||||
|
||||
public void testHashcodeAndEquals() {
|
||||
EqualsHashCodeTestUtils.checkEqualsAndHashCode(createRandomInstance(),
|
||||
instance -> new ForceMergeStep(instance.getKey(), instance.getNextStepKey(),
|
||||
null, instance.getMaxNumSegments()), this::mutateInstance);
|
||||
}
|
||||
|
||||
public void testPerformActionComplete() {
|
||||
Step.StepKey stepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
StepKey nextStepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
int maxNumSegments = randomIntBetween(1, 10);
|
||||
Client client = mock(Client.class);
|
||||
AdminClient adminClient = mock(AdminClient.class);
|
||||
IndicesAdminClient indicesClient = mock(IndicesAdminClient.class);
|
||||
when(client.admin()).thenReturn(adminClient);
|
||||
when(adminClient.indices()).thenReturn(indicesClient);
|
||||
ForceMergeResponse forceMergeResponse = Mockito.mock(ForceMergeResponse.class);
|
||||
Mockito.when(forceMergeResponse.getStatus()).thenReturn(RestStatus.OK);
|
||||
Mockito.doAnswer(invocationOnMock -> {
|
||||
@SuppressWarnings("unchecked")
|
||||
ForceMergeRequest request = (ForceMergeRequest) invocationOnMock.getArguments()[0];
|
||||
assertThat(request.maxNumSegments(), equalTo(maxNumSegments));
|
||||
@SuppressWarnings("unchecked")
|
||||
ActionListener<ForceMergeResponse> listener = (ActionListener<ForceMergeResponse>) invocationOnMock.getArguments()[1];
|
||||
listener.onResponse(forceMergeResponse);
|
||||
return null;
|
||||
}).when(indicesClient).forceMerge(any(), any());
|
||||
|
||||
ForceMergeStep step = new ForceMergeStep(stepKey, nextStepKey, client, maxNumSegments);
|
||||
Index index = new Index(randomAlphaOfLength(5), randomAlphaOfLength(5));
|
||||
SetOnce<Boolean> completed = new SetOnce<>();
|
||||
step.performAction(index, new AsyncActionStep.Listener() {
|
||||
@Override
|
||||
public void onResponse(boolean complete) {
|
||||
completed.set(complete);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
throw new AssertionError("unexpected method call", e);
|
||||
}
|
||||
});
|
||||
assertThat(completed.get(), equalTo(true));
|
||||
}
|
||||
|
||||
public void testPerformActionThrowsException() {
|
||||
Exception exception = new RuntimeException("error");
|
||||
Step.StepKey stepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
StepKey nextStepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
int maxNumSegments = randomIntBetween(1, 10);
|
||||
Client client = mock(Client.class);
|
||||
AdminClient adminClient = mock(AdminClient.class);
|
||||
IndicesAdminClient indicesClient = mock(IndicesAdminClient.class);
|
||||
when(client.admin()).thenReturn(adminClient);
|
||||
when(adminClient.indices()).thenReturn(indicesClient);
|
||||
ForceMergeResponse forceMergeResponse = Mockito.mock(ForceMergeResponse.class);
|
||||
Mockito.when(forceMergeResponse.getStatus()).thenReturn(RestStatus.OK);
|
||||
Mockito.doAnswer(invocationOnMock -> {
|
||||
@SuppressWarnings("unchecked")
|
||||
ForceMergeRequest request = (ForceMergeRequest) invocationOnMock.getArguments()[0];
|
||||
assertThat(request.maxNumSegments(), equalTo(maxNumSegments));
|
||||
@SuppressWarnings("unchecked")
|
||||
ActionListener<ForceMergeResponse> listener = (ActionListener<ForceMergeResponse>) invocationOnMock.getArguments()[1];
|
||||
listener.onFailure(exception);
|
||||
return null;
|
||||
}).when(indicesClient).forceMerge(any(), any());
|
||||
|
||||
ForceMergeStep step = new ForceMergeStep(stepKey, nextStepKey, client, maxNumSegments);
|
||||
Index index = new Index(randomAlphaOfLength(5), randomAlphaOfLength(5));
|
||||
SetOnce<Boolean> exceptionThrown = new SetOnce<>();
|
||||
step.performAction(index, new AsyncActionStep.Listener() {
|
||||
@Override
|
||||
public void onResponse(boolean complete) {
|
||||
throw new AssertionError("unexpected method call");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
assertEquals(exception, e);
|
||||
exceptionThrown.set(true);
|
||||
}
|
||||
});
|
||||
assertThat(exceptionThrown.get(), equalTo(true));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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.core.indexlifecycle;
|
||||
|
||||
import org.elasticsearch.common.io.stream.Writeable.Reader;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.test.AbstractSerializingTestCase;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
public class ReadOnlyActionTests extends AbstractSerializingTestCase<ReadOnlyAction> {
|
||||
|
||||
@Override
|
||||
protected ReadOnlyAction doParseInstance(XContentParser parser) {
|
||||
return ReadOnlyAction.parse(parser);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReadOnlyAction createTestInstance() {
|
||||
return new ReadOnlyAction();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Reader<ReadOnlyAction> instanceReader() {
|
||||
return ReadOnlyAction::new;
|
||||
}
|
||||
|
||||
public void testToSteps() {
|
||||
ReadOnlyAction action = createTestInstance();
|
||||
String phase = randomAlphaOfLengthBetween(1, 10);
|
||||
StepKey nextStepKey = new StepKey(randomAlphaOfLengthBetween(1, 10), randomAlphaOfLengthBetween(1, 10),
|
||||
randomAlphaOfLengthBetween(1, 10));
|
||||
List<Step> steps = action.toSteps(null, phase, nextStepKey);
|
||||
assertNotNull(steps);
|
||||
assertEquals(1, steps.size());
|
||||
StepKey expectedFirstStepKey = new StepKey(phase, ReadOnlyAction.NAME, ReadOnlyStep.NAME);
|
||||
ReadOnlyStep firstStep = (ReadOnlyStep) steps.get(0);
|
||||
assertThat(firstStep.getKey(), equalTo(expectedFirstStepKey));
|
||||
assertThat(firstStep.getNextStepKey(), equalTo(nextStepKey));
|
||||
}
|
||||
|
||||
}
|
|
@ -14,11 +14,24 @@ import org.elasticsearch.cluster.metadata.MetaData;
|
|||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.test.EqualsHashCodeTestUtils;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
public class ReadOnlyStepTests extends ESTestCase {
|
||||
|
||||
public ReadOnlyStep createRandomInstance() {
|
||||
StepKey stepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
StepKey nextStepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
|
||||
return new ReadOnlyStep(stepKey, nextStepKey);
|
||||
}
|
||||
public void testHashcodeAndEquals() {
|
||||
EqualsHashCodeTestUtils.checkEqualsAndHashCode(createRandomInstance(),
|
||||
instance -> new ReadOnlyStep(instance.getKey(), instance.getNextStepKey()));
|
||||
}
|
||||
|
||||
public void testPerformAction() {
|
||||
Settings.Builder indexSettingsBuilder = settings(Version.CURRENT);
|
||||
if (randomBoolean()) {
|
||||
|
|
|
@ -5,11 +5,224 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack.core.indexlifecycle;
|
||||
|
||||
import org.apache.lucene.util.SetOnce;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.admin.indices.segments.IndexSegments;
|
||||
import org.elasticsearch.action.admin.indices.segments.IndexShardSegments;
|
||||
import org.elasticsearch.action.admin.indices.segments.IndicesSegmentResponse;
|
||||
import org.elasticsearch.action.admin.indices.segments.ShardSegments;
|
||||
import org.elasticsearch.client.AdminClient;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.client.IndicesAdminClient;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.engine.Segment;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
import org.elasticsearch.test.EqualsHashCodeTestUtils;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
||||
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Spliterator;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.mockito.Matchers.any;
|
||||
|
||||
public class SegmentCountStepTests extends ESTestCase {
|
||||
|
||||
public void test() {
|
||||
public SegmentCountStep createRandomInstance() {
|
||||
Step.StepKey stepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
StepKey nextStepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
int maxNumSegments = randomIntBetween(1, 10);
|
||||
boolean bestCompression = randomBoolean();
|
||||
|
||||
return new SegmentCountStep(stepKey, nextStepKey, null, maxNumSegments, bestCompression);
|
||||
}
|
||||
|
||||
public SegmentCountStep mutateInstance(SegmentCountStep instance) {
|
||||
StepKey key = instance.getKey();
|
||||
StepKey nextKey = instance.getNextStepKey();
|
||||
int maxNumSegments = instance.getMaxNumSegments();
|
||||
boolean bestCompression = instance.isBestCompression();
|
||||
|
||||
switch (between(0, 3)) {
|
||||
case 0:
|
||||
key = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5));
|
||||
break;
|
||||
case 1:
|
||||
nextKey = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5));
|
||||
break;
|
||||
case 2:
|
||||
maxNumSegments += 1;
|
||||
break;
|
||||
case 3:
|
||||
bestCompression = !bestCompression;
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError("Illegal randomisation branch");
|
||||
}
|
||||
|
||||
return new SegmentCountStep(key, nextKey, null, maxNumSegments, bestCompression);
|
||||
}
|
||||
|
||||
|
||||
public void testHashcodeAndEquals() {
|
||||
EqualsHashCodeTestUtils.checkEqualsAndHashCode(createRandomInstance(),
|
||||
instance -> new SegmentCountStep(instance.getKey(), instance.getNextStepKey(),
|
||||
null, instance.getMaxNumSegments(), instance.isBestCompression()), this::mutateInstance);
|
||||
}
|
||||
|
||||
public void testIsConditionMet() {
|
||||
int maxNumSegments = randomIntBetween(3, 10);
|
||||
Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
|
||||
Client client = Mockito.mock(Client.class);
|
||||
AdminClient adminClient = Mockito.mock(AdminClient.class);
|
||||
IndicesAdminClient indicesClient = Mockito.mock(IndicesAdminClient.class);
|
||||
IndicesSegmentResponse indicesSegmentResponse = Mockito.mock(IndicesSegmentResponse.class);
|
||||
IndexSegments indexSegments = Mockito.mock(IndexSegments.class);
|
||||
IndexShardSegments indexShardSegments = Mockito.mock(IndexShardSegments.class);
|
||||
Map<Integer, IndexShardSegments> indexShards = Collections.singletonMap(0, indexShardSegments);
|
||||
ShardSegments shardSegmentsOne = Mockito.mock(ShardSegments.class);
|
||||
ShardSegments[] shardSegmentsArray = new ShardSegments[] { shardSegmentsOne };
|
||||
Spliterator<IndexShardSegments> iss = indexShards.values().spliterator();
|
||||
List<Segment> segments = new ArrayList<>();
|
||||
for (int i = 0; i < maxNumSegments - randomIntBetween(0, 3); i++) {
|
||||
segments.add(null);
|
||||
}
|
||||
Mockito.when(indicesSegmentResponse.getStatus()).thenReturn(RestStatus.OK);
|
||||
Mockito.when(indicesSegmentResponse.getIndices()).thenReturn(Collections.singletonMap(index.getName(), indexSegments));
|
||||
Mockito.when(indexSegments.spliterator()).thenReturn(iss);
|
||||
Mockito.when(indexShardSegments.getShards()).thenReturn(shardSegmentsArray);
|
||||
Mockito.when(shardSegmentsOne.getSegments()).thenReturn(segments);
|
||||
|
||||
Mockito.when(client.admin()).thenReturn(adminClient);
|
||||
Mockito.when(adminClient.indices()).thenReturn(indicesClient);
|
||||
|
||||
Step.StepKey stepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
StepKey nextStepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
boolean bestCompression = randomBoolean();
|
||||
|
||||
Mockito.doAnswer(invocationOnMock -> {
|
||||
@SuppressWarnings("unchecked")
|
||||
ActionListener<IndicesSegmentResponse> listener = (ActionListener<IndicesSegmentResponse>) invocationOnMock.getArguments()[1];
|
||||
listener.onResponse(indicesSegmentResponse);
|
||||
return null;
|
||||
}).when(indicesClient).segments(any(), any());
|
||||
|
||||
SetOnce<Boolean> conditionMetResult = new SetOnce<>();
|
||||
|
||||
SegmentCountStep step = new SegmentCountStep(stepKey, nextStepKey, client, maxNumSegments, bestCompression);
|
||||
step.evaluateCondition(index, new AsyncWaitStep.Listener() {
|
||||
@Override
|
||||
public void onResponse(boolean conditionMet) {
|
||||
conditionMetResult.set(conditionMet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
throw new AssertionError("unexpected method call");
|
||||
}
|
||||
});
|
||||
|
||||
assertTrue(conditionMetResult.get());
|
||||
}
|
||||
|
||||
public void testIsConditionFails() {
|
||||
int maxNumSegments = randomIntBetween(3, 10);
|
||||
Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
|
||||
Client client = Mockito.mock(Client.class);
|
||||
AdminClient adminClient = Mockito.mock(AdminClient.class);
|
||||
IndicesAdminClient indicesClient = Mockito.mock(IndicesAdminClient.class);
|
||||
IndicesSegmentResponse indicesSegmentResponse = Mockito.mock(IndicesSegmentResponse.class);
|
||||
IndexSegments indexSegments = Mockito.mock(IndexSegments.class);
|
||||
IndexShardSegments indexShardSegments = Mockito.mock(IndexShardSegments.class);
|
||||
Map<Integer, IndexShardSegments> indexShards = Collections.singletonMap(0, indexShardSegments);
|
||||
ShardSegments shardSegmentsOne = Mockito.mock(ShardSegments.class);
|
||||
ShardSegments[] shardSegmentsArray = new ShardSegments[] { shardSegmentsOne };
|
||||
Spliterator<IndexShardSegments> iss = indexShards.values().spliterator();
|
||||
List<Segment> segments = new ArrayList<>();
|
||||
for (int i = 0; i < maxNumSegments + randomIntBetween(1, 3); i++) {
|
||||
segments.add(null);
|
||||
}
|
||||
Mockito.when(indicesSegmentResponse.getStatus()).thenReturn(RestStatus.OK);
|
||||
Mockito.when(indicesSegmentResponse.getIndices()).thenReturn(Collections.singletonMap(index.getName(), indexSegments));
|
||||
Mockito.when(indexSegments.spliterator()).thenReturn(iss);
|
||||
Mockito.when(indexShardSegments.getShards()).thenReturn(shardSegmentsArray);
|
||||
Mockito.when(shardSegmentsOne.getSegments()).thenReturn(segments);
|
||||
|
||||
Mockito.when(client.admin()).thenReturn(adminClient);
|
||||
Mockito.when(adminClient.indices()).thenReturn(indicesClient);
|
||||
|
||||
Step.StepKey stepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
StepKey nextStepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
boolean bestCompression = randomBoolean();
|
||||
|
||||
Mockito.doAnswer(invocationOnMock -> {
|
||||
@SuppressWarnings("unchecked")
|
||||
ActionListener<IndicesSegmentResponse> listener = (ActionListener<IndicesSegmentResponse>) invocationOnMock.getArguments()[1];
|
||||
listener.onResponse(indicesSegmentResponse);
|
||||
return null;
|
||||
}).when(indicesClient).segments(any(), any());
|
||||
|
||||
SetOnce<Boolean> conditionMetResult = new SetOnce<>();
|
||||
|
||||
SegmentCountStep step = new SegmentCountStep(stepKey, nextStepKey, client, maxNumSegments, bestCompression);
|
||||
step.evaluateCondition(index, new AsyncWaitStep.Listener() {
|
||||
@Override
|
||||
public void onResponse(boolean conditionMet) {
|
||||
conditionMetResult.set(conditionMet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
throw new AssertionError("unexpected method call");
|
||||
}
|
||||
});
|
||||
|
||||
assertFalse(conditionMetResult.get());
|
||||
}
|
||||
|
||||
public void testThrowsException() {
|
||||
Exception exception = new RuntimeException("error");
|
||||
Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
|
||||
Client client = Mockito.mock(Client.class);
|
||||
AdminClient adminClient = Mockito.mock(AdminClient.class);
|
||||
IndicesAdminClient indicesClient = Mockito.mock(IndicesAdminClient.class);
|
||||
Mockito.when(client.admin()).thenReturn(adminClient);
|
||||
Mockito.when(adminClient.indices()).thenReturn(indicesClient);
|
||||
|
||||
Step.StepKey stepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
StepKey nextStepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
int maxNumSegments = randomIntBetween(3, 10);
|
||||
boolean bestCompression = randomBoolean();
|
||||
|
||||
Mockito.doAnswer(invocationOnMock -> {
|
||||
@SuppressWarnings("unchecked")
|
||||
ActionListener<IndicesSegmentResponse> listener = (ActionListener<IndicesSegmentResponse>) invocationOnMock.getArguments()[1];
|
||||
listener.onFailure(exception);
|
||||
return null;
|
||||
}).when(indicesClient).segments(any(), any());
|
||||
|
||||
SetOnce<Boolean> exceptionThrown = new SetOnce<>();
|
||||
|
||||
SegmentCountStep step = new SegmentCountStep(stepKey, nextStepKey, client, maxNumSegments, bestCompression);
|
||||
step.evaluateCondition(index, new AsyncWaitStep.Listener() {
|
||||
@Override
|
||||
public void onResponse(boolean conditionMet) {
|
||||
throw new AssertionError("unexpected method call");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
assertThat(e, equalTo(exception));
|
||||
exceptionThrown.set(true);
|
||||
}
|
||||
});
|
||||
|
||||
assertTrue(exceptionThrown.get());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public class TimeseriesLifecycleTypeTests extends ESTestCase {
|
|||
|
||||
private static final AllocateAction TEST_ALLOCATE_ACTION = new AllocateAction(Collections.singletonMap("node", "node1"),null, null);
|
||||
private static final DeleteAction TEST_DELETE_ACTION = new DeleteAction();
|
||||
private static final ForceMergeAction TEST_FORCE_MERGE_ACTION = new ForceMergeAction(1);
|
||||
private static final ForceMergeAction TEST_FORCE_MERGE_ACTION = new ForceMergeAction(1, true);
|
||||
private static final ReplicasAction TEST_REPLICAS_ACTION = new ReplicasAction(1);
|
||||
private static final RolloverAction TEST_ROLLOVER_ACTION = new RolloverAction("", new ByteSizeValue(1), null, null);
|
||||
private static final ShrinkAction TEST_SHRINK_ACTION = new ShrinkAction(1);
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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.core.indexlifecycle;
|
||||
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cluster.ClusterName;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.codec.CodecService;
|
||||
import org.elasticsearch.index.engine.EngineConfig;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.test.EqualsHashCodeTestUtils;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
|
||||
|
||||
public class UpdateBestCompressionSettingsStepTests extends ESTestCase {
|
||||
|
||||
public UpdateBestCompressionSettingsStep createRandomInstance() {
|
||||
StepKey stepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
StepKey nextStepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
|
||||
|
||||
return new UpdateBestCompressionSettingsStep(stepKey, nextStepKey);
|
||||
}
|
||||
|
||||
|
||||
public void testHashcodeAndEquals() {
|
||||
EqualsHashCodeTestUtils.checkEqualsAndHashCode(createRandomInstance(),
|
||||
instance -> new UpdateBestCompressionSettingsStep(instance.getKey(), instance.getNextStepKey()));
|
||||
}
|
||||
|
||||
public void testPerformAction() {
|
||||
IndexMetaData indexMetadata = IndexMetaData.builder(randomAlphaOfLength(5))
|
||||
.settings(settings(Version.CURRENT))
|
||||
.numberOfShards(1)
|
||||
.numberOfReplicas(0).build();
|
||||
MetaData metaData = MetaData.builder()
|
||||
.persistentSettings(settings(Version.CURRENT).build())
|
||||
.put(IndexMetaData.builder(indexMetadata))
|
||||
.build();
|
||||
Index index = indexMetadata.getIndex();
|
||||
ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT).metaData(metaData).build();
|
||||
|
||||
UpdateBestCompressionSettingsStep step = createRandomInstance();
|
||||
ClusterState newState = step.performAction(index, clusterState);
|
||||
assertNotSame(clusterState, newState);
|
||||
IndexMetaData newIndexMetadata = newState.metaData().index(index);
|
||||
assertNotNull(newIndexMetadata);
|
||||
assertNotSame(indexMetadata, newIndexMetadata);
|
||||
assertTrue(EngineConfig.INDEX_CODEC_SETTING.exists(newIndexMetadata.getSettings()));
|
||||
assertTrue(CodecService.BEST_COMPRESSION_CODEC.equals(
|
||||
newIndexMetadata.getSettings().get(EngineConfig.INDEX_CODEC_SETTING.getKey())));
|
||||
}
|
||||
|
||||
public void testPerformActionNoIndex() {
|
||||
MetaData metaData = MetaData.builder().persistentSettings(settings(Version.CURRENT).build()).build();
|
||||
Index index = new Index("invalid_index", "invalid_index_id");
|
||||
ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT).metaData(metaData).build();
|
||||
|
||||
UpdateBestCompressionSettingsStep step = createRandomInstance();
|
||||
ClusterState newState = step.performAction(index, clusterState);
|
||||
assertSame(clusterState, newState);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue