Skip to content

Commit 942d0e5

Browse files
authored
[TEST] Adjust PartialHitCountCollectorTests#testCollectedHitCount (#116181) (#116243)
Split the test in two, one to verify behaviour with threashold greather than 1. Wrote a specific test for the edge case of threshold set to 1. Added a comment that explains the nuance around the behaviour and what influences it. Closes #106647
1 parent 15482ce commit 942d0e5

File tree

1 file changed

+32
-3
lines changed

1 file changed

+32
-3
lines changed

server/src/test/java/org/elasticsearch/search/query/PartialHitCountCollectorTests.java

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,17 @@
1515
import org.apache.lucene.index.IndexReader;
1616
import org.apache.lucene.index.LeafReaderContext;
1717
import org.apache.lucene.index.Term;
18+
import org.apache.lucene.search.BulkScorer;
19+
import org.apache.lucene.search.CollectionTerminatedException;
1820
import org.apache.lucene.search.CollectorManager;
21+
import org.apache.lucene.search.DocIdSetIterator;
1922
import org.apache.lucene.search.FilterLeafCollector;
2023
import org.apache.lucene.search.IndexSearcher;
2124
import org.apache.lucene.search.LeafCollector;
2225
import org.apache.lucene.search.MatchAllDocsQuery;
2326
import org.apache.lucene.search.Query;
2427
import org.apache.lucene.search.ScoreMode;
28+
import org.apache.lucene.search.Weight;
2529
import org.apache.lucene.store.Directory;
2630
import org.apache.lucene.tests.index.RandomIndexWriter;
2731
import org.elasticsearch.test.ESTestCase;
@@ -121,15 +125,40 @@ public void testHitCountFromWeightDoesNotEarlyTerminate() throws IOException {
121125

122126
public void testCollectedHitCount() throws Exception {
123127
Query query = new NonCountingTermQuery(new Term("string", "a1"));
124-
int threshold = randomIntBetween(1, 10000);
125-
assumeTrue("bug with single collection & single segment: https://github.com/elastic/elasticsearch/issues/106647", threshold > 1);
126-
// there's one doc matching the query: any totalHitsThreshold greater than or equal to 1 will not cause early termination
128+
int threshold = randomIntBetween(2, 10000);
129+
// there's one doc matching the query: any totalHitsThreshold greater than 1 will not cause early termination
127130
CollectorManager<PartialHitCountCollector, Result> collectorManager = createCollectorManager(new HitsThresholdChecker(threshold));
128131
Result result = searcher.search(query, collectorManager);
129132
assertEquals(1, result.totalHits);
130133
assertFalse(result.terminatedAfter);
131134
}
132135

136+
public void testThresholdOne() throws Exception {
137+
Query query = new NonCountingTermQuery(new Term("string", "a1"));
138+
Weight weight = query.createWeight(searcher, ScoreMode.COMPLETE, 0f);
139+
CollectorManager<PartialHitCountCollector, Result> collectorManager = createCollectorManager(new HitsThresholdChecker(1));
140+
// threshold 1 behaves differently depending on whether there is a single segment (no early termination) or multiple segments.
141+
// With inter-segment concurrency the behaviour is not deterministic and depends on the timing of the different threads.
142+
// Without inter-segment concurrency the behaviour depends on which segment holds the matching document.
143+
// This is because the check for early termination is performed every time a leaf collector is pulled for a segment, as well
144+
// as for every collected doc.
145+
PartialHitCountCollector partialHitCountCollector = collectorManager.newCollector();
146+
int i = 0;
147+
while (partialHitCountCollector.getTotalHits() == 0 && i < searcher.getLeafContexts().size()) {
148+
LeafReaderContext ctx = searcher.getLeafContexts().get(i++);
149+
LeafCollector leafCollector = partialHitCountCollector.getLeafCollector(ctx);
150+
BulkScorer bulkScorer = weight.bulkScorer(ctx);
151+
bulkScorer.score(leafCollector, ctx.reader().getLiveDocs(), 0, DocIdSetIterator.NO_MORE_DOCS);
152+
}
153+
assertEquals(1, partialHitCountCollector.getTotalHits());
154+
assertFalse(partialHitCountCollector.hasEarlyTerminated());
155+
expectThrows(
156+
CollectionTerminatedException.class,
157+
() -> partialHitCountCollector.getLeafCollector(randomFrom(searcher.getLeafContexts()))
158+
);
159+
assertTrue(partialHitCountCollector.hasEarlyTerminated());
160+
}
161+
133162
public void testCollectedHitCountEarlyTerminated() throws Exception {
134163
Query query = new NonCountingTermQuery(new Term("string", "foo"));
135164
// there's three docs matching the query: any totalHitsThreshold lower than 3 will trigger early termination

0 commit comments

Comments
 (0)