|
19 | 19 |
|
20 | 20 | package org.elasticsearch.search; |
21 | 21 |
|
| 22 | +import org.apache.lucene.util.BytesRef; |
| 23 | +import org.elasticsearch.Version; |
22 | 24 | import org.elasticsearch.common.Strings; |
23 | | -import org.elasticsearch.common.bytes.BytesReference; |
24 | | -import org.elasticsearch.common.io.stream.BytesStreamOutput; |
25 | | -import org.elasticsearch.common.io.stream.StreamInput; |
| 25 | +import org.elasticsearch.common.io.stream.Writeable; |
| 26 | +import org.elasticsearch.common.lucene.LuceneTests; |
26 | 27 | import org.elasticsearch.common.xcontent.ToXContent; |
27 | 28 | import org.elasticsearch.common.xcontent.XContentBuilder; |
28 | 29 | import org.elasticsearch.common.xcontent.XContentParser; |
29 | 30 | import org.elasticsearch.common.xcontent.XContentType; |
30 | 31 | import org.elasticsearch.common.xcontent.json.JsonXContent; |
31 | | -import org.elasticsearch.test.ESTestCase; |
| 32 | +import org.elasticsearch.test.AbstractSerializingTestCase; |
| 33 | +import org.elasticsearch.test.RandomObjects; |
32 | 34 |
|
33 | 35 | import java.io.IOException; |
34 | | -import java.util.ArrayList; |
35 | 36 | import java.util.Arrays; |
36 | | -import java.util.List; |
37 | | -import java.util.function.Supplier; |
38 | 37 |
|
39 | | -import static org.elasticsearch.common.xcontent.XContentHelper.toXContent; |
40 | | -import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode; |
41 | | -import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent; |
42 | | - |
43 | | -public class SearchSortValuesTests extends ESTestCase { |
44 | | - |
45 | | - public static SearchSortValues createTestItem() { |
46 | | - List<Supplier<Object>> valueSuppliers = new ArrayList<>(); |
47 | | - // this should reflect all values that are allowed to go through the transport layer |
48 | | - valueSuppliers.add(() -> null); |
49 | | - valueSuppliers.add(ESTestCase::randomInt); |
50 | | - valueSuppliers.add(ESTestCase::randomLong); |
51 | | - valueSuppliers.add(ESTestCase::randomDouble); |
52 | | - valueSuppliers.add(ESTestCase::randomFloat); |
53 | | - valueSuppliers.add(ESTestCase::randomByte); |
54 | | - valueSuppliers.add(ESTestCase::randomShort); |
55 | | - valueSuppliers.add(ESTestCase::randomBoolean); |
56 | | - valueSuppliers.add(() -> frequently() ? randomAlphaOfLengthBetween(1, 30) : randomRealisticUnicodeOfCodepointLength(30)); |
| 38 | +public class SearchSortValuesTests extends AbstractSerializingTestCase<SearchSortValues> { |
57 | 39 |
|
| 40 | + public static SearchSortValues createTestItem(XContentType xContentType, boolean transportSerialization) { |
58 | 41 | int size = randomIntBetween(1, 20); |
59 | 42 | Object[] values = new Object[size]; |
| 43 | + DocValueFormat[] sortValueFormats = new DocValueFormat[size]; |
60 | 44 | for (int i = 0; i < size; i++) { |
61 | | - Supplier<Object> supplier = randomFrom(valueSuppliers); |
62 | | - values[i] = supplier.get(); |
| 45 | + Object sortValue = randomSortValue(xContentType, transportSerialization); |
| 46 | + values[i] = sortValue; |
| 47 | + //make sure that for BytesRef, we provide a specific doc value format that overrides format(BytesRef) |
| 48 | + sortValueFormats[i] = sortValue instanceof BytesRef ? DocValueFormat.RAW : randomDocValueFormat(); |
63 | 49 | } |
64 | | - return new SearchSortValues(values); |
| 50 | + return new SearchSortValues(values, sortValueFormats); |
| 51 | + } |
| 52 | + |
| 53 | + private static Object randomSortValue(XContentType xContentType, boolean transportSerialization) { |
| 54 | + Object randomSortValue = LuceneTests.randomSortValue(); |
| 55 | + //to simplify things, we directly serialize what we expect we would parse back when testing xcontent serialization |
| 56 | + return transportSerialization ? randomSortValue : RandomObjects.getExpectedParsedValue(xContentType, randomSortValue); |
65 | 57 | } |
66 | 58 |
|
67 | | - public void testFromXContent() throws IOException { |
68 | | - SearchSortValues sortValues = createTestItem(); |
69 | | - XContentType xcontentType = randomFrom(XContentType.values()); |
70 | | - boolean humanReadable = randomBoolean(); |
71 | | - BytesReference originalBytes = toShuffledXContent(sortValues, xcontentType, ToXContent.EMPTY_PARAMS, humanReadable); |
| 59 | + private static DocValueFormat randomDocValueFormat() { |
| 60 | + return randomFrom(DocValueFormat.BOOLEAN, DocValueFormat.RAW, DocValueFormat.IP, DocValueFormat.BINARY, DocValueFormat.GEOHASH); |
| 61 | + } |
72 | 62 |
|
73 | | - SearchSortValues parsed; |
74 | | - try (XContentParser parser = createParser(xcontentType.xContent(), originalBytes)) { |
75 | | - parser.nextToken(); // skip to the elements start array token, fromXContent advances from there if called |
76 | | - parser.nextToken(); |
77 | | - parser.nextToken(); |
78 | | - parsed = SearchSortValues.fromXContent(parser); |
79 | | - parser.nextToken(); |
80 | | - assertEquals(XContentParser.Token.END_OBJECT, parser.currentToken()); |
81 | | - assertNull(parser.nextToken()); |
82 | | - } |
83 | | - assertToXContentEquivalent(originalBytes, toXContent(parsed, xcontentType, humanReadable), xcontentType); |
| 63 | + @Override |
| 64 | + protected SearchSortValues doParseInstance(XContentParser parser) throws IOException { |
| 65 | + parser.nextToken(); // skip to the elements start array token, fromXContent advances from there if called |
| 66 | + parser.nextToken(); |
| 67 | + parser.nextToken(); |
| 68 | + SearchSortValues searchSortValues = SearchSortValues.fromXContent(parser); |
| 69 | + parser.nextToken(); |
| 70 | + assertEquals(XContentParser.Token.END_OBJECT, parser.currentToken()); |
| 71 | + assertNull(parser.nextToken()); |
| 72 | + return searchSortValues; |
84 | 73 | } |
85 | 74 |
|
86 | | - public void testToXContent() throws IOException { |
87 | | - SearchSortValues sortValues = new SearchSortValues(new Object[]{ 1, "foo", 3.0}); |
88 | | - XContentBuilder builder = JsonXContent.contentBuilder(); |
89 | | - builder.startObject(); |
90 | | - sortValues.toXContent(builder, ToXContent.EMPTY_PARAMS); |
91 | | - builder.endObject(); |
92 | | - assertEquals("{\"sort\":[1,\"foo\",3.0]}", Strings.toString(builder)); |
| 75 | + @Override |
| 76 | + protected SearchSortValues createXContextTestInstance(XContentType xContentType) { |
| 77 | + return createTestItem(xContentType, false); |
93 | 78 | } |
94 | 79 |
|
95 | | - /** |
96 | | - * Test equality and hashCode properties |
97 | | - */ |
98 | | - public void testEqualsAndHashcode() { |
99 | | - checkEqualsAndHashCode(createTestItem(), SearchSortValuesTests::copy, SearchSortValuesTests::mutate); |
| 80 | + @Override |
| 81 | + protected SearchSortValues createTestInstance() { |
| 82 | + return createTestItem(randomFrom(XContentType.values()), true); |
100 | 83 | } |
101 | 84 |
|
102 | | - public void testSerialization() throws IOException { |
103 | | - SearchSortValues sortValues = createTestItem(); |
104 | | - try (BytesStreamOutput output = new BytesStreamOutput()) { |
105 | | - sortValues.writeTo(output); |
106 | | - try (StreamInput in = output.bytes().streamInput()) { |
107 | | - SearchSortValues deserializedCopy = new SearchSortValues(in); |
108 | | - assertEquals(sortValues, deserializedCopy); |
109 | | - assertEquals(sortValues.hashCode(), deserializedCopy.hashCode()); |
110 | | - assertNotSame(sortValues, deserializedCopy); |
111 | | - } |
| 85 | + @Override |
| 86 | + protected Writeable.Reader<SearchSortValues> instanceReader() { |
| 87 | + return SearchSortValues::new; |
| 88 | + } |
| 89 | + |
| 90 | + @Override |
| 91 | + protected String[] getShuffleFieldsExceptions() { |
| 92 | + return new String[]{"sort"}; |
| 93 | + } |
| 94 | + |
| 95 | + public void testToXContent() throws IOException { |
| 96 | + { |
| 97 | + SearchSortValues sortValues = new SearchSortValues(new Object[]{ 1, "foo", 3.0}); |
| 98 | + XContentBuilder builder = JsonXContent.contentBuilder(); |
| 99 | + builder.startObject(); |
| 100 | + sortValues.toXContent(builder, ToXContent.EMPTY_PARAMS); |
| 101 | + builder.endObject(); |
| 102 | + assertEquals("{\"sort\":[1,\"foo\",3.0]}", Strings.toString(builder)); |
| 103 | + } |
| 104 | + { |
| 105 | + SearchSortValues sortValues = new SearchSortValues(new Object[0]); |
| 106 | + XContentBuilder builder = JsonXContent.contentBuilder(); |
| 107 | + builder.startObject(); |
| 108 | + sortValues.toXContent(builder, ToXContent.EMPTY_PARAMS); |
| 109 | + builder.endObject(); |
| 110 | + assertEquals("{}", Strings.toString(builder)); |
112 | 111 | } |
113 | 112 | } |
114 | 113 |
|
115 | | - private static SearchSortValues mutate(SearchSortValues original) { |
116 | | - Object[] sortValues = original.sortValues(); |
| 114 | + @Override |
| 115 | + protected SearchSortValues mutateInstance(SearchSortValues instance) { |
| 116 | + Object[] sortValues = instance.sortValues(); |
117 | 117 | if (sortValues.length == 0) { |
118 | | - return new SearchSortValues(new Object[] { 1 }); |
| 118 | + return createTestInstance(); |
119 | 119 | } |
120 | | - return new SearchSortValues(Arrays.copyOf(sortValues, sortValues.length + 1)); |
| 120 | + if (randomBoolean()) { |
| 121 | + return new SearchSortValues(new Object[0]); |
| 122 | + } |
| 123 | + Object[] values = Arrays.copyOf(sortValues, sortValues.length + 1); |
| 124 | + values[sortValues.length] = randomSortValue(randomFrom(XContentType.values()), true); |
| 125 | + return new SearchSortValues(values); |
121 | 126 | } |
122 | 127 |
|
123 | | - private static SearchSortValues copy(SearchSortValues original) { |
124 | | - return new SearchSortValues(Arrays.copyOf(original.sortValues(), original.sortValues().length)); |
| 128 | + @Override |
| 129 | + protected SearchSortValues copyInstance(SearchSortValues instance, Version version) { |
| 130 | + return new SearchSortValues(Arrays.copyOf(instance.sortValues(), instance.sortValues().length)); |
125 | 131 | } |
126 | 132 | } |
0 commit comments