From 391d3a20f3554109cbf3326acd0f97f733802559 Mon Sep 17 00:00:00 2001 From: Tanguy Leroux Date: Thu, 15 Dec 2016 16:12:33 +0100 Subject: [PATCH] Add unit tests for toXContent methods in ReplicationResponse (#22188) This commit adds unit tests for the toXContent() methods of the inner classes ReplicationResponse.ShardInfo and ReplicationResponse.ShardInfo.Failure. --- .../replication/ReplicationResponse.java | 56 +++--- .../replication/ReplicationResponseTests.java | 162 +++++++++++++++++- 2 files changed, 182 insertions(+), 36 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/action/support/replication/ReplicationResponse.java b/core/src/main/java/org/elasticsearch/action/support/replication/ReplicationResponse.java index e2cd8e3a817..6e44c4f158c 100644 --- a/core/src/main/java/org/elasticsearch/action/support/replication/ReplicationResponse.java +++ b/core/src/main/java/org/elasticsearch/action/support/replication/ReplicationResponse.java @@ -67,6 +67,12 @@ public class ReplicationResponse extends ActionResponse { public static class ShardInfo implements Streamable, ToXContent { + private static final String _SHARDS = "_shards"; + private static final String TOTAL = "total"; + private static final String SUCCESSFUL = "successful"; + private static final String FAILED = "failed"; + private static final String FAILURES = "failures"; + private int total; private int successful; private Failure[] failures = EMPTY; @@ -165,12 +171,12 @@ public class ReplicationResponse extends ActionResponse { @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.startObject(Fields._SHARDS); - builder.field(Fields.TOTAL, total); - builder.field(Fields.SUCCESSFUL, successful); - builder.field(Fields.FAILED, getFailed()); + builder.startObject(_SHARDS); + builder.field(TOTAL, total); + builder.field(SUCCESSFUL, successful); + builder.field(FAILED, getFailed()); if (failures.length > 0) { - builder.startArray(Fields.FAILURES); + builder.startArray(FAILURES); for (Failure failure : failures) { failure.toXContent(builder, params); } @@ -197,6 +203,13 @@ public class ReplicationResponse extends ActionResponse { public static class Failure implements ShardOperationFailedException, ToXContent { + private static final String _INDEX = "_index"; + private static final String _SHARD = "_shard"; + private static final String _NODE = "_node"; + private static final String REASON = "reason"; + private static final String STATUS = "status"; + private static final String PRIMARY = "primary"; + private ShardId shardId; private String nodeId; private Exception cause; @@ -313,39 +326,18 @@ public class ReplicationResponse extends ActionResponse { @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); - builder.field(Fields._INDEX, shardId.getIndexName()); - builder.field(Fields._SHARD, shardId.id()); - builder.field(Fields._NODE, nodeId); - builder.field(Fields.REASON); + builder.field(_INDEX, shardId.getIndexName()); + builder.field(_SHARD, shardId.id()); + builder.field(_NODE, nodeId); + builder.field(REASON); builder.startObject(); ElasticsearchException.toXContent(builder, params, cause); builder.endObject(); - builder.field(Fields.STATUS, status); - builder.field(Fields.PRIMARY, primary); + builder.field(STATUS, status); + builder.field(PRIMARY, primary); builder.endObject(); return builder; } - - private static class Fields { - - private static final String _INDEX = "_index"; - private static final String _SHARD = "_shard"; - private static final String _NODE = "_node"; - private static final String REASON = "reason"; - private static final String STATUS = "status"; - private static final String PRIMARY = "primary"; - - } - } - - private static class Fields { - - private static final String _SHARDS = "_shards"; - private static final String TOTAL = "total"; - private static final String SUCCESSFUL = "successful"; - private static final String FAILED = "failed"; - private static final String FAILURES = "failures"; - } } } diff --git a/core/src/test/java/org/elasticsearch/action/support/replication/ReplicationResponseTests.java b/core/src/test/java/org/elasticsearch/action/support/replication/ReplicationResponseTests.java index 0c805d6d32c..7d82b744133 100644 --- a/core/src/test/java/org/elasticsearch/action/support/replication/ReplicationResponseTests.java +++ b/core/src/test/java/org/elasticsearch/action/support/replication/ReplicationResponseTests.java @@ -21,6 +21,11 @@ package org.elasticsearch.action.support.replication; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.RoutingMissingException; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContent; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.Index; import org.elasticsearch.index.shard.IndexShardRecoveringException; import org.elasticsearch.index.shard.ShardId; @@ -28,13 +33,13 @@ import org.elasticsearch.rest.RestStatus; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.EqualsHashCodeTestUtils; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.function.Supplier; import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode; -import static org.hamcrest.CoreMatchers.equalTo; public class ReplicationResponseTests extends ESTestCase { @@ -42,9 +47,7 @@ public class ReplicationResponseTests extends ESTestCase { final int total = 5; final int successful = randomIntBetween(1, total); final ReplicationResponse.ShardInfo shardInfo = new ReplicationResponse.ShardInfo(total, successful); - assertThat( - shardInfo.toString(), - equalTo(String.format(Locale.ROOT, "ShardInfo{total=5, successful=%d, failures=[]}", successful))); + assertEquals(String.format(Locale.ROOT, "ShardInfo{total=5, successful=%d, failures=[]}", successful), shardInfo.toString()); } public void testShardInfoEqualsAndHashcode() { @@ -113,6 +116,157 @@ public class ReplicationResponseTests extends ESTestCase { checkEqualsAndHashCode(randomFailure(), copy, mutate); } + public void testShardInfoToXContent() throws IOException { + ReplicationResponse.ShardInfo shardInfo = new ReplicationResponse.ShardInfo(5, 3); + + final XContent xContent = randomFrom(XContentType.values()).xContent(); + try (XContentBuilder builder = XContentBuilder.builder(xContent)) { + builder.startObject(); + shardInfo.toXContent(builder, ToXContent.EMPTY_PARAMS); + builder.endObject(); + + // Expected JSON is {"_shards":{"total":5,"successful":3,"failed":0}} + try (XContentParser parser = xContent.createParser(builder.bytes())) { + assertEquals(XContentParser.Token.START_OBJECT, parser.nextToken()); + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals("_shards", parser.currentName()); + assertEquals(XContentParser.Token.START_OBJECT, parser.nextToken()); + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals("total", parser.currentName()); + assertEquals(XContentParser.Token.VALUE_NUMBER, parser.nextToken()); + assertEquals(shardInfo.getTotal(), parser.intValue()); + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals("successful", parser.currentName()); + assertEquals(XContentParser.Token.VALUE_NUMBER, parser.nextToken()); + assertEquals(shardInfo.getSuccessful(), parser.intValue()); + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals("failed", parser.currentName()); + assertEquals(XContentParser.Token.VALUE_NUMBER, parser.nextToken()); + assertEquals(shardInfo.getFailed(), parser.intValue()); + assertEquals(XContentParser.Token.END_OBJECT, parser.nextToken()); + assertEquals(XContentParser.Token.END_OBJECT, parser.nextToken()); + assertNull(parser.nextToken()); + } + } + } + + public void testRandomShardInfoToXContent() throws IOException { + final ReplicationResponse.ShardInfo shardInfo = randomShardInfo(); + + final XContent xContent = randomFrom(XContentType.values()).xContent(); + try (XContentBuilder builder = XContentBuilder.builder(xContent)) { + builder.startObject(); + shardInfo.toXContent(builder, ToXContent.EMPTY_PARAMS); + builder.endObject(); + + try (XContentParser parser = xContent.createParser(builder.bytes())) { + assertEquals(XContentParser.Token.START_OBJECT, parser.nextToken()); + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals("_shards", parser.currentName()); + assertEquals(XContentParser.Token.START_OBJECT, parser.nextToken()); + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals("total", parser.currentName()); + assertEquals(XContentParser.Token.VALUE_NUMBER, parser.nextToken()); + assertEquals(shardInfo.getTotal(), parser.intValue()); + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals("successful", parser.currentName()); + assertEquals(XContentParser.Token.VALUE_NUMBER, parser.nextToken()); + assertEquals(shardInfo.getSuccessful(), parser.intValue()); + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals("failed", parser.currentName()); + assertEquals(XContentParser.Token.VALUE_NUMBER, parser.nextToken()); + assertEquals(shardInfo.getFailed(), parser.intValue()); + + if (shardInfo.getFailures() != null && shardInfo.getFailures().length > 0) { + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals("failures", parser.currentName()); + assertEquals(XContentParser.Token.START_ARRAY, parser.nextToken()); + + for (int i = 0; i < shardInfo.getFailures().length; i++) { + assertFailure(parser, shardInfo.getFailures()[i]); + } + assertEquals(XContentParser.Token.END_ARRAY, parser.nextToken()); + } + + assertEquals(XContentParser.Token.END_OBJECT, parser.nextToken()); + assertEquals(XContentParser.Token.END_OBJECT, parser.nextToken()); + assertNull(parser.nextToken()); + } + } + } + + public void testRandomFailureToXContent() throws IOException { + ReplicationResponse.ShardInfo.Failure shardInfoFailure = randomFailure(); + + final XContent xContent = randomFrom(XContentType.values()).xContent(); + try (XContentBuilder builder = XContentBuilder.builder(xContent)) { + shardInfoFailure.toXContent(builder, ToXContent.EMPTY_PARAMS); + + try (XContentParser parser = xContent.createParser(builder.bytes())) { + assertFailure(parser, shardInfoFailure); + } + } + } + + private static void assertFailure(XContentParser parser, ReplicationResponse.ShardInfo.Failure failure) throws IOException { + assertEquals(XContentParser.Token.START_OBJECT, parser.nextToken()); + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals("_index", parser.currentName()); + assertEquals(XContentParser.Token.VALUE_STRING, parser.nextToken()); + assertEquals(failure.index(), parser.text()); + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals("_shard", parser.currentName()); + assertEquals(XContentParser.Token.VALUE_NUMBER, parser.nextToken()); + assertEquals(failure.shardId(), parser.intValue()); + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals("_node", parser.currentName()); + assertEquals(XContentParser.Token.VALUE_STRING, parser.nextToken()); + assertEquals(failure.nodeId(), parser.text()); + + Throwable cause = failure.getCause(); + if (cause != null) { + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals("reason", parser.currentName()); + assertThrowable(parser, cause); + } + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals("status", parser.currentName()); + assertEquals(XContentParser.Token.VALUE_STRING, parser.nextToken()); + assertEquals(failure.status(), RestStatus.valueOf(parser.text())); + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals("primary", parser.currentName()); + assertEquals(XContentParser.Token.VALUE_BOOLEAN, parser.nextToken()); + assertEquals(failure.primary(), parser.booleanValue()); + assertEquals(XContentParser.Token.END_OBJECT, parser.nextToken()); + } + + private static void assertThrowable(XContentParser parser, Throwable cause) throws IOException { + assertEquals(XContentParser.Token.START_OBJECT, parser.nextToken()); + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals("type", parser.currentName()); + assertEquals(XContentParser.Token.VALUE_STRING, parser.nextToken()); + assertEquals(ElasticsearchException.getExceptionName(cause), parser.text()); + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals("reason", parser.currentName()); + assertEquals(XContentParser.Token.VALUE_STRING, parser.nextToken()); + assertEquals(cause.getMessage(), parser.text()); + if (cause instanceof ElasticsearchException) { + ElasticsearchException ex = (ElasticsearchException) cause; + for (String name : ex.getHeaderKeys()) { + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals(name.replaceFirst("es.", ""), parser.currentName()); + assertEquals(XContentParser.Token.VALUE_STRING, parser.nextToken()); + assertEquals(ex.getHeader(name).get(0), parser.text()); + } + if (ex.getCause() != null) { + assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); + assertEquals("caused_by", parser.currentName()); + assertThrowable(parser, ex.getCause()); + } + } + assertEquals(XContentParser.Token.END_OBJECT, parser.nextToken()); + } + private static ReplicationResponse.ShardInfo randomShardInfo() { int total = randomIntBetween(1, 10); int successful = randomIntBetween(0, total);