Adds some unit tests

This commit is contained in:
Colin Goodheart-Smithe 2017-11-23 12:44:12 +00:00
parent f571dc3000
commit db502bef6d
8 changed files with 349 additions and 3 deletions

View File

@ -9,6 +9,7 @@ import org.apache.logging.log4j.Logger;
import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse; import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.client.Client; import org.elasticsearch.client.Client;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.logging.ESLoggerFactory; import org.elasticsearch.common.logging.ESLoggerFactory;
@ -66,4 +67,25 @@ public class DeleteAction extends LifecycleAction {
}); });
} }
@Override
public int hashCode() {
return 1;
}
@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);
}
} }

View File

@ -13,6 +13,7 @@ import org.elasticsearch.cluster.NamedDiff;
import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.metadata.MetaData.Custom; import org.elasticsearch.cluster.metadata.MetaData.Custom;
import org.elasticsearch.common.ParseField; import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
@ -23,7 +24,9 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
@ -35,7 +38,7 @@ public class IndexLifecycleMetadata implements MetaData.Custom {
public static final IndexLifecycleMetadata EMPTY_METADATA = new IndexLifecycleMetadata(Collections.emptySortedMap(), 3); public static final IndexLifecycleMetadata EMPTY_METADATA = new IndexLifecycleMetadata(Collections.emptySortedMap(), 3);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static final ConstructingObjectParser<IndexLifecycleMetadata, NamedXContentRegistry> PARSER = new ConstructingObjectParser<>( public static final ConstructingObjectParser<IndexLifecycleMetadata, NamedXContentRegistry> PARSER = new ConstructingObjectParser<>(
TYPE, a -> new IndexLifecycleMetadata((SortedMap<String, LifecyclePolicy>) a[0], (long) a[1])); TYPE, a -> new IndexLifecycleMetadata(convertListToMapValues((List<LifecyclePolicy>) a[0]), (long) a[1]));
static { static {
PARSER.declareNamedObjects(ConstructingObjectParser.constructorArg(), (p, c, n) -> LifecyclePolicy.parse(p, new Tuple<>(n, c)), PARSER.declareNamedObjects(ConstructingObjectParser.constructorArg(), (p, c, n) -> LifecyclePolicy.parse(p, new Tuple<>(n, c)),
v -> { v -> {
@ -92,6 +95,14 @@ public class IndexLifecycleMetadata implements MetaData.Custom {
return builder; return builder;
} }
private static SortedMap<String, LifecyclePolicy> convertListToMapValues(List<LifecyclePolicy> list) {
SortedMap<String, LifecyclePolicy> map = new TreeMap<>();
for (LifecyclePolicy policy : list) {
map.put(policy.getName(), policy);
}
return map;
}
@Override @Override
public Version getMinimalSupportedVersion() { public Version getMinimalSupportedVersion() {
return Version.V_7_0_0_alpha1; return Version.V_7_0_0_alpha1;
@ -107,6 +118,29 @@ public class IndexLifecycleMetadata implements MetaData.Custom {
return MetaData.ALL_CONTEXTS; return MetaData.ALL_CONTEXTS;
} }
@Override
public int hashCode() {
return Objects.hash(policies, pollInterval);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj.getClass() != getClass()) {
return false;
}
IndexLifecycleMetadata other = (IndexLifecycleMetadata) obj;
return Objects.equals(policies, other.policies) &&
Objects.equals(pollInterval, other.pollInterval);
}
@Override
public String toString() {
return Strings.toString(this, true, true);
}
public static class IndexLifecycleMetadataDiff implements NamedDiff<MetaData.Custom> { public static class IndexLifecycleMetadataDiff implements NamedDiff<MetaData.Custom> {
final Diff<Map<String, LifecyclePolicy>> policies; final Diff<Map<String, LifecyclePolicy>> policies;

View File

@ -27,6 +27,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Objects;
public class LifecyclePolicy extends AbstractDiffable<LifecyclePolicy> implements ToXContentObject, Writeable { public class LifecyclePolicy extends AbstractDiffable<LifecyclePolicy> implements ToXContentObject, Writeable {
private static final Logger logger = ESLoggerFactory.getLogger(LifecyclePolicy.class); private static final Logger logger = ESLoggerFactory.getLogger(LifecyclePolicy.class);
@ -78,7 +79,6 @@ public class LifecyclePolicy extends AbstractDiffable<LifecyclePolicy> implement
@Override @Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(); builder.startObject();
builder.array(PHASES_FIELD.getPreferredName(), phases);
builder.startObject(PHASES_FIELD.getPreferredName()); builder.startObject(PHASES_FIELD.getPreferredName());
for (Phase phase : phases) { for (Phase phase : phases) {
builder.field(phase.getName(), phase); builder.field(phase.getName(), phase);
@ -155,4 +155,26 @@ public class LifecyclePolicy extends AbstractDiffable<LifecyclePolicy> implement
currentPhase.execute(idxMeta, client); currentPhase.execute(idxMeta, client);
} }
} }
@Override
public int hashCode() {
return Objects.hash(name, phases);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj.getClass() != getClass()) {
return false;
}
LifecyclePolicy other = (LifecyclePolicy) obj;
return Objects.equals(name, other.name) && Objects.equals(phases, other.phases);
}
@Override
public String toString() {
return Strings.toString(this, true, true);
}
} }

View File

@ -28,6 +28,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Objects;
public class Phase implements ToXContentObject, Writeable { public class Phase implements ToXContentObject, Writeable {
public static final String PHASE_COMPLETED = "ACTIONS COMPLETED"; public static final String PHASE_COMPLETED = "ACTIONS COMPLETED";
@ -137,7 +138,7 @@ public class Phase implements ToXContentObject, Writeable {
@Override @Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(); builder.startObject();
builder.field(AFTER_FIELD.getPreferredName(), after); builder.field(AFTER_FIELD.getPreferredName(), after.seconds() + "s"); // Need a better way to get a parsable format out here
builder.startObject(ACTIONS_FIELD.getPreferredName()); builder.startObject(ACTIONS_FIELD.getPreferredName());
for (LifecycleAction action : actions) { for (LifecycleAction action : actions) {
builder.field(action.getWriteableName(), action); builder.field(action.getWriteableName(), action);
@ -147,4 +148,28 @@ public class Phase implements ToXContentObject, Writeable {
return builder; return builder;
} }
@Override
public int hashCode() {
return Objects.hash(name, after, actions);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj.getClass() != getClass()) {
return false;
}
Phase other = (Phase) obj;
return Objects.equals(name, other.name) &&
Objects.equals(after, other.after) &&
Objects.equals(actions, other.actions);
}
@Override
public String toString() {
return Strings.toString(this, true, true);
}
} }

View File

@ -0,0 +1,31 @@
/*
* 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.elasticsearch.common.io.stream.Writeable.Reader;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.test.AbstractSerializingTestCase;
import java.io.IOException;
public class DeleteActionTests extends AbstractSerializingTestCase<DeleteAction> {
@Override
protected DeleteAction doParseInstance(XContentParser parser) throws IOException {
return DeleteAction.parse(parser);
}
@Override
protected DeleteAction createTestInstance() {
return new DeleteAction();
}
@Override
protected Reader<DeleteAction> instanceReader() {
return DeleteAction::new;
}
}

View File

@ -0,0 +1,77 @@
/*
* 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.elasticsearch.common.ParseField;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.io.stream.Writeable.Reader;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.test.AbstractSerializingTestCase;
import org.junit.Before;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
public class IndexLifecycleMetadataTests extends AbstractSerializingTestCase<IndexLifecycleMetadata> {
private NamedXContentRegistry registry;
@Before
public void setup() {
List<NamedXContentRegistry.Entry> entries = Arrays
.asList(new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(DeleteAction.NAME), DeleteAction::parse));
registry = new NamedXContentRegistry(entries);
}
@Override
protected IndexLifecycleMetadata createTestInstance() {
int numPolicies = 1; // randomInt(5);
SortedMap<String, LifecyclePolicy> policies = new TreeMap<>();
for (int i = 0; i < numPolicies; i++) {
int numberPhases = randomInt(5);
List<Phase> phases = new ArrayList<>(numberPhases);
for (int j = 0; j < numberPhases; j++) {
TimeValue after = TimeValue.parseTimeValue(randomTimeValue(0, 1000000000, "s", "m", "h", "d"), "test_after");
List<LifecycleAction> actions = new ArrayList<>();
if (randomBoolean()) {
actions.add(new DeleteAction());
}
phases.add(new Phase(randomAlphaOfLength(10), after, actions));
}
String policyName = randomAlphaOfLength(10);
policies.put(policyName, new LifecyclePolicy(policyName, phases));
}
long pollInterval = randomNonNegativeLong();
return new IndexLifecycleMetadata(policies, pollInterval);
}
@Override
protected String[] getShuffleFieldsExceptions() {
return new String[] { "phases" }; // NOCOMMIT this needs to be temporary since we should not rely on the order of the JSON map
}
@Override
protected IndexLifecycleMetadata doParseInstance(XContentParser parser) throws IOException {
return IndexLifecycleMetadata.PARSER.apply(parser, registry);
}
@Override
protected Reader<IndexLifecycleMetadata> instanceReader() {
return IndexLifecycleMetadata::new;
}
protected NamedWriteableRegistry getNamedWriteableRegistry() {
return new NamedWriteableRegistry(
Arrays.asList(new NamedWriteableRegistry.Entry(LifecycleAction.class, DeleteAction.NAME, DeleteAction::new)));
}
}

View File

@ -0,0 +1,72 @@
/*
* 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.elasticsearch.common.ParseField;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.io.stream.Writeable.Reader;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.test.AbstractSerializingTestCase;
import org.junit.Before;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class LifecyclePolicyTests extends AbstractSerializingTestCase<LifecyclePolicy> {
private NamedXContentRegistry registry;
private String lifecycleName;
@Before
public void setup() {
List<NamedXContentRegistry.Entry> entries = Arrays
.asList(new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(DeleteAction.NAME), DeleteAction::parse));
registry = new NamedXContentRegistry(entries);
lifecycleName = randomAlphaOfLength(20); // NOCOMMIT we need to randomise the lifecycle name rather
// than use the same name for all instances
}
@Override
protected LifecyclePolicy createTestInstance() {
int numberPhases = randomInt(5);
List<Phase> phases = new ArrayList<>(numberPhases);
for (int i = 0; i < numberPhases; i++) {
TimeValue after = TimeValue.parseTimeValue(randomTimeValue(0, 1000000000, "s", "m", "h", "d"), "test_after");
List<LifecycleAction> actions = new ArrayList<>();
if (randomBoolean()) {
actions.add(new DeleteAction());
}
phases.add(new Phase(randomAlphaOfLength(10), after, actions));
}
return new LifecyclePolicy(lifecycleName, phases);
}
@Override
protected String[] getShuffleFieldsExceptions() {
return new String[] { "phases" }; // NOCOMMIT this needs to be temporary since we should not rely on the order of the JSON map
}
@Override
protected LifecyclePolicy doParseInstance(XContentParser parser) throws IOException {
return LifecyclePolicy.parse(parser, new Tuple<>(lifecycleName, registry));
}
@Override
protected Reader<LifecyclePolicy> instanceReader() {
return LifecyclePolicy::new;
}
protected NamedWriteableRegistry getNamedWriteableRegistry() {
return new NamedWriteableRegistry(
Arrays.asList(new NamedWriteableRegistry.Entry(LifecycleAction.class, DeleteAction.NAME, DeleteAction::new)));
}
}

View File

@ -0,0 +1,63 @@
/*
* 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.elasticsearch.common.ParseField;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.io.stream.Writeable.Reader;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.test.AbstractSerializingTestCase;
import org.junit.Before;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class PhaseTests extends AbstractSerializingTestCase<Phase> {
private NamedXContentRegistry registry;
private String phaseName;
@Before
public void setup() {
List<NamedXContentRegistry.Entry> entries = Arrays
.asList(new NamedXContentRegistry.Entry(LifecycleAction.class, new ParseField(DeleteAction.NAME), DeleteAction::parse));
registry = new NamedXContentRegistry(entries);
phaseName = randomAlphaOfLength(20); // NOCOMMIT we need to randomise the phase name rather
// than use the same name for all instances
}
@Override
protected Phase createTestInstance() {
TimeValue after = TimeValue.parseTimeValue(randomTimeValue(0, 1000000000, "s", "m", "h", "d"), "test_after");
List<LifecycleAction> actions = new ArrayList<>();
if (randomBoolean()) {
actions.add(new DeleteAction());
}
return new Phase(phaseName, after, actions);
}
@Override
protected Phase doParseInstance(XContentParser parser) throws IOException {
return Phase.parse(parser, new Tuple<>(phaseName, registry));
}
@Override
protected Reader<Phase> instanceReader() {
return Phase::new;
}
protected NamedWriteableRegistry getNamedWriteableRegistry() {
return new NamedWriteableRegistry(Arrays
.asList(new NamedWriteableRegistry.Entry(LifecycleAction.class, DeleteAction.NAME, DeleteAction::new)));
}
}