Skip to content

Commit 69aa7bb

Browse files
authored
Modernize cardinality agg tests (elastic#90114)
This provides support for routing more cardinality tests through the "standard" aggregations testing infrastructure. Ultimately, this will help with improving our memory access testing around aggregation context, although this PR doesn't implement that.
1 parent fb59f12 commit 69aa7bb

File tree

3 files changed

+103
-101
lines changed

3 files changed

+103
-101
lines changed

Diff for: server/src/test/java/org/elasticsearch/search/aggregations/metrics/CardinalityAggregatorTests.java

+11-78
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,9 @@
1414
import org.apache.lucene.document.SortedDocValuesField;
1515
import org.apache.lucene.document.SortedNumericDocValuesField;
1616
import org.apache.lucene.document.SortedSetDocValuesField;
17-
import org.apache.lucene.index.DirectoryReader;
18-
import org.apache.lucene.index.IndexReader;
19-
import org.apache.lucene.index.MultiReader;
2017
import org.apache.lucene.search.FieldExistsQuery;
21-
import org.apache.lucene.search.IndexSearcher;
2218
import org.apache.lucene.search.MatchAllDocsQuery;
2319
import org.apache.lucene.search.Query;
24-
import org.apache.lucene.store.Directory;
2520
import org.apache.lucene.tests.index.RandomIndexWriter;
2621
import org.apache.lucene.util.BytesRef;
2722
import org.elasticsearch.common.geo.GeoPoint;
@@ -47,7 +42,6 @@
4742
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
4843
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
4944
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
50-
import org.elasticsearch.search.aggregations.support.AggregationContext;
5145
import org.elasticsearch.search.aggregations.support.AggregationInspectionHelper;
5246
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
5347
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
@@ -410,40 +404,20 @@ public void testUnmappedMissingNumber() throws IOException {
410404
}
411405

412406
public void testSingleValuedFieldPartiallyUnmapped() throws IOException {
413-
final Directory directory = newDirectory();
414-
final RandomIndexWriter indexWriter = new RandomIndexWriter(random(), directory);
415-
final int numDocs = 10;
416-
for (int i = 0; i < numDocs; i++) {
417-
indexWriter.addDocument(singleton(new NumericDocValuesField("number", i + 1)));
418-
}
419-
indexWriter.close();
420-
421-
final Directory unmappedDirectory = newDirectory();
422-
final RandomIndexWriter unmappedIndexWriter = new RandomIndexWriter(random(), unmappedDirectory);
423-
unmappedIndexWriter.close();
424-
425-
final IndexReader indexReader = DirectoryReader.open(directory);
426-
final IndexReader unamappedIndexReader = DirectoryReader.open(unmappedDirectory);
427-
final MultiReader multiReader = new MultiReader(indexReader, unamappedIndexReader);
428-
final IndexSearcher indexSearcher = newSearcher(multiReader, true, true);
429-
430407
final MappedFieldType fieldType = new NumberFieldMapper.NumberFieldType("number", NumberFieldMapper.NumberType.INTEGER);
431408
final AggregationBuilder aggregationBuilder = new CardinalityAggregationBuilder("cardinality").field("number");
432409

433-
final CardinalityAggregator aggregator = createAggregator(aggregationBuilder, indexSearcher, fieldType);
434-
aggregator.preCollection();
435-
indexSearcher.search(new MatchAllDocsQuery(), aggregator.asCollector());
436-
aggregator.postCollection();
437-
438-
final InternalCardinality cardinality = (InternalCardinality) aggregator.buildAggregation(0L);
439-
440-
assertEquals(10.0, cardinality.getValue(), 0);
441-
assertEquals("cardinality", cardinality.getName());
442-
assertTrue(AggregationInspectionHelper.hasValue(cardinality));
443-
444-
multiReader.close();
445-
directory.close();
446-
unmappedDirectory.close();
410+
multiIndexTestCase(aggregationBuilder, new MatchAllDocsQuery(), List.of((unmappedIndexWriter) -> {}, (indexWriter) -> {
411+
final int numDocs = 10;
412+
for (int i = 0; i < numDocs; i++) {
413+
indexWriter.addDocument(singleton(new NumericDocValuesField("number", i + 1)));
414+
}
415+
}), (internalAggregation) -> {
416+
InternalCardinality cardinality = (InternalCardinality) internalAggregation;
417+
assertEquals(10.0, cardinality.getValue(), 0);
418+
assertEquals("cardinality", cardinality.getName());
419+
assertTrue(AggregationInspectionHelper.hasValue(cardinality));
420+
}, fieldType);
447421
}
448422

449423
public void testSingleValuedNumericValueScript() throws IOException {
@@ -618,47 +592,6 @@ public void testAsSubAggregation() throws IOException {
618592
}, mappedFieldTypes);
619593
}
620594

621-
public void testCacheAggregation() throws IOException {
622-
final Directory directory = newDirectory();
623-
final RandomIndexWriter indexWriter = new RandomIndexWriter(random(), directory);
624-
final int numDocs = 10;
625-
for (int i = 0; i < numDocs; i++) {
626-
indexWriter.addDocument(singleton(new NumericDocValuesField("number", i + 1)));
627-
}
628-
indexWriter.close();
629-
630-
final Directory unmappedDirectory = newDirectory();
631-
final RandomIndexWriter unmappedIndexWriter = new RandomIndexWriter(random(), unmappedDirectory);
632-
unmappedIndexWriter.close();
633-
634-
final IndexReader indexReader = DirectoryReader.open(directory);
635-
final IndexReader unamappedIndexReader = DirectoryReader.open(unmappedDirectory);
636-
final MultiReader multiReader = new MultiReader(indexReader, unamappedIndexReader);
637-
final IndexSearcher indexSearcher = newSearcher(multiReader, true, true);
638-
639-
final MappedFieldType fieldType = new NumberFieldMapper.NumberFieldType("number", NumberFieldMapper.NumberType.INTEGER);
640-
final CardinalityAggregationBuilder aggregationBuilder = new CardinalityAggregationBuilder("cardinality").field("number");
641-
642-
final AggregationContext context = createAggregationContext(indexSearcher, null, fieldType);
643-
final CardinalityAggregator aggregator = createAggregator(aggregationBuilder, context);
644-
aggregator.preCollection();
645-
indexSearcher.search(new MatchAllDocsQuery(), aggregator.asCollector());
646-
aggregator.postCollection();
647-
648-
final InternalCardinality cardinality = (InternalCardinality) aggregator.buildAggregation(0L);
649-
650-
assertEquals(10.0, cardinality.getValue(), 0);
651-
assertEquals("cardinality", cardinality.getName());
652-
assertTrue(AggregationInspectionHelper.hasValue(cardinality));
653-
654-
// Test that an aggregation not using a script does get cached
655-
assertTrue(context.isCacheable());
656-
657-
multiReader.close();
658-
directory.close();
659-
unmappedDirectory.close();
660-
}
661-
662595
private void testAggregation(
663596
Query query,
664597
CheckedConsumer<RandomIndexWriter, IOException> buildIndex,

Diff for: test/framework/src/main/java/org/elasticsearch/search/aggregations/AggregatorTestCase.java

+65-5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.apache.lucene.index.IndexReaderContext;
2222
import org.apache.lucene.index.IndexWriterConfig;
2323
import org.apache.lucene.index.LeafReaderContext;
24+
import org.apache.lucene.index.MultiReader;
2425
import org.apache.lucene.index.NoMergePolicy;
2526
import org.apache.lucene.sandbox.document.HalfFloatPoint;
2627
import org.apache.lucene.search.Collector;
@@ -56,6 +57,7 @@
5657
import org.elasticsearch.common.util.MockBigArrays;
5758
import org.elasticsearch.common.util.MockPageCacheRecycler;
5859
import org.elasticsearch.core.CheckedConsumer;
60+
import org.elasticsearch.core.IOUtils;
5961
import org.elasticsearch.core.Releasable;
6062
import org.elasticsearch.core.Releasables;
6163
import org.elasticsearch.index.Index;
@@ -451,6 +453,7 @@ protected <A extends InternalAggregation, C extends Aggregator> A searchAndReduc
451453
aggTestConfig.builder(),
452454
aggTestConfig.maxBuckets(),
453455
aggTestConfig.splitLeavesIntoSeparateAggregators(),
456+
aggTestConfig.shouldBeCached(),
454457
crankyService,
455458
aggTestConfig.fieldTypes()
456459
);
@@ -469,6 +472,7 @@ protected <A extends InternalAggregation, C extends Aggregator> A searchAndReduc
469472
aggTestConfig.builder(),
470473
aggTestConfig.maxBuckets(),
471474
aggTestConfig.splitLeavesIntoSeparateAggregators(),
475+
aggTestConfig.shouldBeCached(),
472476
breakerService,
473477
aggTestConfig.fieldTypes()
474478
);
@@ -482,6 +486,7 @@ private <A extends InternalAggregation, C extends Aggregator> A searchAndReduce(
482486
AggregationBuilder builder,
483487
int maxBucket,
484488
boolean splitLeavesIntoSeparateAggregators,
489+
boolean shouldBeCached,
485490
CircuitBreakerService breakerService,
486491
MappedFieldType... fieldTypes
487492
) throws IOException {
@@ -535,6 +540,7 @@ private <A extends InternalAggregation, C extends Aggregator> A searchAndReduce(
535540
root.postCollection();
536541
aggs.add(root.buildTopLevel());
537542
}
543+
assertEquals(shouldBeCached, context.isCacheable());
538544
assertRoundTrip(aggs);
539545
if (randomBoolean() && aggs.size() > 1) {
540546
// sometimes do an incremental reduce
@@ -624,6 +630,55 @@ protected <T extends AggregationBuilder, V extends InternalAggregation> void tes
624630
}
625631
}
626632

633+
protected <T extends AggregationBuilder, V extends InternalAggregation> void multiIndexTestCase(
634+
T aggregationBuilder,
635+
Query query,
636+
List<CheckedConsumer<RandomIndexWriter, IOException>> indexBuilders,
637+
Consumer<V> verify,
638+
MappedFieldType... fieldTypes
639+
) throws IOException {
640+
Directory[] directories = new Directory[indexBuilders.size()];
641+
boolean timeSeries = aggregationBuilder.isInSortOrderExecutionRequired();
642+
try {
643+
for (int i = 0; i < indexBuilders.size(); i++) {
644+
directories[i] = newDirectory();
645+
IndexWriterConfig config = LuceneTestCase.newIndexWriterConfig(random(), new MockAnalyzer(random()));
646+
if (timeSeries) {
647+
Sort sort = new Sort(
648+
new SortField(TimeSeriesIdFieldMapper.NAME, SortField.Type.STRING, false),
649+
new SortedNumericSortField(DataStreamTimestampFieldMapper.DEFAULT_PATH, SortField.Type.LONG, true)
650+
);
651+
config.setIndexSort(sort);
652+
}
653+
RandomIndexWriter indexWriter = new RandomIndexWriter(random(), directories[i], config);
654+
indexBuilders.get(i).accept(indexWriter);
655+
indexWriter.close();
656+
}
657+
// construct the multi-reader
658+
List<DirectoryReader> directoryReaders = new ArrayList<>();
659+
try {
660+
for (Directory directory : directories) {
661+
DirectoryReader open = DirectoryReader.open(directory);
662+
directoryReaders.add(open);
663+
}
664+
DirectoryReader[] readers = directoryReaders.toArray(new DirectoryReader[0]);
665+
try (MultiReader multiReader = new MultiReader(readers)) {
666+
IndexSearcher indexSearcher = newIndexSearcher(multiReader);
667+
668+
V agg = searchAndReduce(new AggTestConfig(indexSearcher, query, aggregationBuilder, fieldTypes));
669+
verify.accept(agg);
670+
671+
verifyOutputFieldNames(aggregationBuilder, agg);
672+
}
673+
} finally {
674+
IOUtils.close(directoryReaders);
675+
}
676+
} finally {
677+
IOUtils.close(directories);
678+
}
679+
680+
}
681+
627682
protected void withIndex(
628683
CheckedConsumer<RandomIndexWriter, IOException> buildIndex,
629684
CheckedConsumer<IndexSearcher, IOException> consume
@@ -1421,26 +1476,31 @@ public record AggTestConfig(
14211476
AggregationBuilder builder,
14221477
int maxBuckets,
14231478
boolean splitLeavesIntoSeparateAggregators,
1479+
boolean shouldBeCached,
14241480
MappedFieldType... fieldTypes
14251481
) {
14261482
public AggTestConfig(IndexSearcher searcher, AggregationBuilder builder, MappedFieldType... fieldTypes) {
1427-
this(searcher, new MatchAllDocsQuery(), builder, DEFAULT_MAX_BUCKETS, randomBoolean(), fieldTypes);
1483+
this(searcher, new MatchAllDocsQuery(), builder, DEFAULT_MAX_BUCKETS, randomBoolean(), true, fieldTypes);
14281484
}
14291485

14301486
public AggTestConfig(IndexSearcher searcher, Query query, AggregationBuilder builder, MappedFieldType... fieldTypes) {
1431-
this(searcher, query, builder, DEFAULT_MAX_BUCKETS, randomBoolean(), fieldTypes);
1487+
this(searcher, query, builder, DEFAULT_MAX_BUCKETS, randomBoolean(), true, fieldTypes);
14321488
}
14331489

14341490
public AggTestConfig withQuery(Query query) {
1435-
return new AggTestConfig(searcher, query, builder, maxBuckets, splitLeavesIntoSeparateAggregators, fieldTypes);
1491+
return new AggTestConfig(searcher, query, builder, maxBuckets, splitLeavesIntoSeparateAggregators, shouldBeCached, fieldTypes);
14361492
}
14371493

14381494
public AggTestConfig withSplitLeavesIntoSeperateAggregators(boolean splitLeavesIntoSeparateAggregators) {
1439-
return new AggTestConfig(searcher, query, builder, maxBuckets, splitLeavesIntoSeparateAggregators, fieldTypes);
1495+
return new AggTestConfig(searcher, query, builder, maxBuckets, splitLeavesIntoSeparateAggregators, shouldBeCached, fieldTypes);
1496+
}
1497+
1498+
public AggTestConfig withShouldBeCached(boolean shouldBeCached) {
1499+
return new AggTestConfig(searcher, query, builder, maxBuckets, splitLeavesIntoSeparateAggregators, shouldBeCached, fieldTypes);
14401500
}
14411501

14421502
public AggTestConfig withMaxBuckets(int maxBuckets) {
1443-
return new AggTestConfig(searcher, query, builder, maxBuckets, splitLeavesIntoSeparateAggregators, fieldTypes);
1503+
return new AggTestConfig(searcher, query, builder, maxBuckets, splitLeavesIntoSeparateAggregators, shouldBeCached, fieldTypes);
14441504
}
14451505
}
14461506
}

0 commit comments

Comments
 (0)