let prelert metadata test extend from AbstractSerializingTestCase, so that we test the writable and xcontent serialization much better.

Original commit: elastic/x-pack-elasticsearch@de8609ad59
This commit is contained in:
Martijn van Groningen 2016-12-12 12:09:07 +01:00
parent f73d22b4b2
commit bad8a2beb5
3 changed files with 47 additions and 65 deletions

View File

@ -46,7 +46,7 @@ public class PrelertMetadata implements MetaData.Custom {
public static final PrelertMetadata PROTO = new PrelertMetadata(Collections.emptySortedMap(), Collections.emptySortedMap(), public static final PrelertMetadata PROTO = new PrelertMetadata(Collections.emptySortedMap(), Collections.emptySortedMap(),
Collections.emptySortedMap()); Collections.emptySortedMap());
private static final ObjectParser<Builder, ParseFieldMatcherSupplier> PRELERT_METADATA_PARSER = new ObjectParser<>("prelert_metadata", static final ObjectParser<Builder, ParseFieldMatcherSupplier> PRELERT_METADATA_PARSER = new ObjectParser<>("prelert_metadata",
Builder::new); Builder::new);
static { static {
@ -54,8 +54,6 @@ public class PrelertMetadata implements MetaData.Custom {
PRELERT_METADATA_PARSER.declareObjectArray(Builder::putAllocations, Allocation.PARSER, ALLOCATIONS_FIELD); PRELERT_METADATA_PARSER.declareObjectArray(Builder::putAllocations, Allocation.PARSER, ALLOCATIONS_FIELD);
} }
// NORELEASE: A few fields of job details change frequently and this needs to be stored elsewhere
// performance issue will occur if we don't change that
private final SortedMap<String, Job> jobs; private final SortedMap<String, Job> jobs;
private final SortedMap<String, Allocation> allocations; private final SortedMap<String, Allocation> allocations;
private final SortedMap<String, SchedulerStatus> schedulerStatuses; private final SortedMap<String, SchedulerStatus> schedulerStatuses;
@ -68,8 +66,6 @@ public class PrelertMetadata implements MetaData.Custom {
} }
public Map<String, Job> getJobs() { public Map<String, Job> getJobs() {
// NORELEASE jobs should be immutable or a job can be modified in the
// cluster state of a single node without a cluster state update
return jobs; return jobs;
} }

View File

@ -8,23 +8,20 @@ package org.elasticsearch.xpack.prelert.job.metadata;
import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.ElasticsearchStatusException;
import org.elasticsearch.ResourceAlreadyExistsException; import org.elasticsearch.ResourceAlreadyExistsException;
import org.elasticsearch.ResourceNotFoundException; import org.elasticsearch.ResourceNotFoundException;
import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.io.stream.InputStreamStreamInput; import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.io.stream.OutputStreamStreamOutput;
import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestStatus; import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.prelert.job.Job; import org.elasticsearch.xpack.prelert.job.Job;
import org.elasticsearch.xpack.prelert.job.JobStatus; import org.elasticsearch.xpack.prelert.job.JobStatus;
import org.elasticsearch.xpack.prelert.job.JobTests; import org.elasticsearch.xpack.prelert.job.JobTests;
import org.elasticsearch.xpack.prelert.job.SchedulerStatus; import org.elasticsearch.xpack.prelert.job.SchedulerStatus;
import org.elasticsearch.xpack.prelert.support.AbstractSerializingTestCase;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import static org.elasticsearch.xpack.prelert.job.JobTests.buildJobBuilder; import static org.elasticsearch.xpack.prelert.job.JobTests.buildJobBuilder;
@ -34,65 +31,54 @@ import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.sameInstance; import static org.hamcrest.Matchers.sameInstance;
public class PrelertMetadataTests extends ESTestCase { public class PrelertMetadataTests extends AbstractSerializingTestCase<PrelertMetadata> {
public void testSerialization() throws Exception { @Override
protected PrelertMetadata createTestInstance() {
PrelertMetadata.Builder builder = new PrelertMetadata.Builder(); PrelertMetadata.Builder builder = new PrelertMetadata.Builder();
int numJobs = randomIntBetween(0, 4);
Job job1 = JobTests.createRandomizedJob(); for (int i = 0; i < numJobs; i++) {
Job job2 = JobTests.createRandomizedJob(); Job job = JobTests.createRandomizedJob();
Job job3 = JobTests.createRandomizedJob(); builder.putJob(job, false);
if (randomBoolean()) {
builder.putJob(job1, false); builder.updateStatus(job.getId(), JobStatus.OPENING, randomBoolean() ? "first reason" : null);
builder.putJob(job2, false); if (randomBoolean()) {
builder.putJob(job3, false); builder.updateStatus(job.getId(), JobStatus.OPENED, randomBoolean() ? "second reason" : null);
if (randomBoolean()) {
builder.updateStatus(job1.getId(), JobStatus.OPENING, null); builder.updateStatus(job.getId(), JobStatus.CLOSING, randomBoolean() ? "third reason" : null);
builder.assignToNode(job2.getId(), "node1"); }
builder.updateStatus(job2.getId(), JobStatus.OPENING, null); }
builder.assignToNode(job3.getId(), "node1"); }
builder.updateStatus(job3.getId(), JobStatus.OPENING, null); // NORELEASE TODO: randomize scheduler status:
// if (randomBoolean()) {
PrelertMetadata expected = builder.build(); // builder.updateSchedulerStatus(job.getId(), SchedulerStatus.STARTED);
ByteArrayOutputStream out = new ByteArrayOutputStream(); // }
expected.writeTo(new OutputStreamStreamOutput(out)); }
return builder.build();
PrelertMetadata result = (PrelertMetadata)
PrelertMetadata.PROTO.readFrom(new InputStreamStreamInput(new ByteArrayInputStream(out.toByteArray())));
assertThat(result, equalTo(expected));
} }
public void testFromXContent() throws IOException { @Override
PrelertMetadata.Builder builder = new PrelertMetadata.Builder(); protected Writeable.Reader<PrelertMetadata> instanceReader() {
return in -> (PrelertMetadata) PrelertMetadata.PROTO.readFrom(in);
}
Job job1 = JobTests.createRandomizedJob(); @Override
Job job2 = JobTests.createRandomizedJob(); protected PrelertMetadata parseInstance(XContentParser parser, ParseFieldMatcher matcher) {
Job job3 = JobTests.createRandomizedJob(); return PrelertMetadata.PRELERT_METADATA_PARSER.apply(parser, () -> matcher).build();
}
builder.putJob(job1, false); @Override
builder.putJob(job2, false); protected <T extends ToXContent & Writeable> XContentBuilder toXContent(T instance, XContentType contentType) throws IOException {
builder.putJob(job3, false); XContentBuilder builder = XContentFactory.contentBuilder(contentType);
if (randomBoolean()) {
builder.updateStatus(job1.getId(), JobStatus.OPENING, null); builder.prettyPrint();
builder.assignToNode(job1.getId(), "node1"); }
builder.updateStatus(job2.getId(), JobStatus.OPENING, null); // In Metadata.Builder#toXContent(...) custom metadata always gets wrapped in an start and end object,
builder.assignToNode(job2.getId(), "node1"); // so we simulate that here. The PrelertMetadata depends on that as it direct starts to write a start array.
builder.updateStatus(job3.getId(), JobStatus.OPENING, null); builder.startObject();
builder.assignToNode(job3.getId(), "node1"); instance.toXContent(builder, ToXContent.EMPTY_PARAMS);
builder.endObject();
PrelertMetadata expected = builder.build(); return builder;
XContentBuilder xBuilder = XContentFactory.contentBuilder(XContentType.SMILE);
xBuilder.prettyPrint();
xBuilder.startObject();
expected.toXContent(xBuilder, ToXContent.EMPTY_PARAMS);
xBuilder.endObject();
XContentBuilder shuffled = shuffleXContent(xBuilder);
final XContentParser parser = XContentFactory.xContent(shuffled.bytes()).createParser(shuffled.bytes());
MetaData.Custom custom = expected.fromXContent(parser);
assertTrue(custom instanceof PrelertMetadata);
PrelertMetadata result = (PrelertMetadata) custom;
assertThat(result, equalTo(expected));
} }
public void testPutJob() { public void testPutJob() {

View File

@ -65,7 +65,7 @@ public abstract class AbstractSerializingTestCase<T extends ToXContent & Writeab
return Strings.EMPTY_ARRAY; return Strings.EMPTY_ARRAY;
} }
protected static <T extends ToXContent & Writeable> XContentBuilder toXContent(T instance, XContentType contentType) protected <T extends ToXContent & Writeable> XContentBuilder toXContent(T instance, XContentType contentType)
throws IOException { throws IOException {
XContentBuilder builder = XContentFactory.contentBuilder(contentType); XContentBuilder builder = XContentFactory.contentBuilder(contentType);
if (randomBoolean()) { if (randomBoolean()) {