Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix a flaky test that relies on terminate_after for an exact count match #10836

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
fe57058
Enable extensions.
austintlee Oct 2, 2023
bcb2dec
[Remote Store] Fix stats reporting for multistream downloads. (#10402)
Rishikesh1159 Oct 5, 2023
245c056
Mute flaky concurrent segment search tests pending fixes (#10437)
jed326 Oct 6, 2023
31efd2f
Replace multipart download with parallel file download (#10519)
andrross Oct 11, 2023
9e919a9
Fix flaky query profile phase tests with concurrent search enabled (#…
ticheng-aws Oct 11, 2023
f93fab4
Add release notes for 2.11 (#10594)
noCharger Oct 12, 2023
508a7f8
Per request phase latency (#10351)
dzane17 Oct 13, 2023
2f3a3d7
Fix flaky testEqualsAndHashcode in SearchRequestTests (#10649)
dzane17 Oct 17, 2023
b092906
revive remote cluster state auto restore integ tests (#10503)
linuxpi Oct 18, 2023
52b8d1a
Remote Restore Cluster Metadata if local disk state lost after quorum…
linuxpi Oct 18, 2023
b242aa1
Bump JNA version from 5.5 to 5.13.
austintlee Sep 11, 2023
d43c865
[Remote Store] Fix stats reporting for multistream downloads. (#10402)
Rishikesh1159 Oct 5, 2023
8c2c617
Mute flaky concurrent segment search tests pending fixes (#10437)
jed326 Oct 6, 2023
3663301
Replace multipart download with parallel file download (#10519)
andrross Oct 11, 2023
3524c85
Fix flaky query profile phase tests with concurrent search enabled (#…
ticheng-aws Oct 11, 2023
1f56c7c
Per request phase latency (#10351)
dzane17 Oct 13, 2023
0605136
Fix flaky testEqualsAndHashcode in SearchRequestTests (#10649)
dzane17 Oct 17, 2023
aeeab2b
revive remote cluster state auto restore integ tests (#10503)
linuxpi Oct 18, 2023
d21f5f1
Remote Restore Cluster Metadata if local disk state lost after quorum…
linuxpi Oct 18, 2023
0567dd4
Fix a flaky test that relies on terminate_after for an exact count ma…
austintlee Oct 22, 2023
63c556d
Fix precommit failure, spotless check.
austintlee Oct 23, 2023
60db2d0
Fix flaky test for size = 0.
austintlee Oct 25, 2023
de84d82
revive remote cluster state auto restore integ tests (#10503)
linuxpi Oct 18, 2023
8549d8c
Remote Restore Cluster Metadata if local disk state lost after quorum…
linuxpi Oct 18, 2023
770ffbf
revive remote cluster state auto restore integ tests (#10503)
linuxpi Oct 18, 2023
d0aaca7
Remote Restore Cluster Metadata if local disk state lost after quorum…
linuxpi Oct 18, 2023
2c4fd19
revive remote cluster state auto restore integ tests (#10503)
linuxpi Oct 18, 2023
5ccd8f2
Remote Restore Cluster Metadata if local disk state lost after quorum…
linuxpi Oct 18, 2023
803d182
Update skip version to match branches (#11801)
harshavamsi Jan 10, 2024
1fd4fdf
Update skip version to match branches (#11801)
harshavamsi Jan 10, 2024
2c2d4bd
Fix bad rebase.
austintlee Jan 19, 2024
5c190c2
Remove unintended change from log4j properties.
austintlee Jan 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion release-notes/opensearch.release-notes-2.11.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
### Added
- Add coordinator level stats for search latency ([#8386](https://github.com/opensearch-project/OpenSearch/issues/8386))
- Add metrics for thread_pool task wait time ([#9681](https://github.com/opensearch-project/OpenSearch/pull/9681))
- Add parallel file download support for remote store based replication ([#8596](https://github.com/opensearch-project/OpenSearch/pull/8596))
- Add parallel file download support for remote store based replication ([#8596](https://github.com/opensearch-project/OpenSearch/pull/8596))
- Async blob read support for S3 plugin ([#9694](https://github.com/opensearch-project/OpenSearch/pull/9694))
- [Telemetry-Otel] Added support for OtlpGrpcSpanExporter exporter ([#9666](https://github.com/opensearch-project/OpenSearch/pull/9666))
- Async blob read support for encrypted containers ([#10131](https://github.com/opensearch-project/OpenSearch/pull/10131))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,15 @@ public void dotestSimpleTerminateAfterCountWithSize(int size, int max) throws Ex
.setSize(size)
.setTrackTotalHits(true)
.get();
assertHitCount(searchResponse, i);

// Do not expect an exact match as an optimization introduced by https://issues.apache.org/jira/browse/LUCENE-10620
// can produce a total hit count > terminated_after, but this only kicks in
// when size = 0 which is when TotalHitCountCollector is used.
if (size == 0) {
assertHitCount(searchResponse, i, max);
austintlee marked this conversation as resolved.
Show resolved Hide resolved
} else {
assertHitCount(searchResponse, i);
}
assertTrue(searchResponse.isTerminatedEarly());
assertEquals(Math.min(i, size), searchResponse.getHits().getHits().length);
}
Expand All @@ -319,7 +327,6 @@ public void dotestSimpleTerminateAfterCountWithSize(int size, int max) throws Ex
assertFalse(searchResponse.isTerminatedEarly());
}

@AwaitsFix(bugUrl = "https://github.com/opensearch-project/OpenSearch/issues/10435")
public void testSimpleTerminateAfterCountSize0() throws Exception {
int max = randomIntBetween(3, 29);
dotestSimpleTerminateAfterCountWithSize(0, max);
Expand All @@ -330,6 +337,24 @@ public void testSimpleTerminateAfterCountRandomSize() throws Exception {
dotestSimpleTerminateAfterCountWithSize(randomIntBetween(1, max), max);
}

/**
* Special cases when size = 0:
*
* If track_total_hits = true:
* Weight#count optimization can cause totalHits in the response to be up to the total doc count regardless of terminate_after.
* So, we will have to do a range check, not an equality check.
*
* If track_total_hits != true, but set to a value AND terminate_after is set:
* Again, due to the optimization, any count can be returned.
* Up to terminate_after, relation == EQUAL_TO.
* But if track_total_hits_up_to >= terminate_after, relation can be EQ _or_ GTE.
* This ambiguity is due to the fact that totalHits == track_total_hits_up_to
* or totalHits > track_total_hits_up_to and SearchPhaseController sets totalHits = track_total_hits_up_to when returning results
* in which case relation = GTE.
*
* @param size
* @throws Exception
*/
public void doTestSimpleTerminateAfterTrackTotalHitsUpTo(int size) throws Exception {
prepareCreate("test").setSettings(Settings.builder().put(SETTING_NUMBER_OF_SHARDS, 1).put(SETTING_NUMBER_OF_REPLICAS, 0)).get();
ensureGreen();
Expand All @@ -346,6 +371,7 @@ public void doTestSimpleTerminateAfterTrackTotalHitsUpTo(int size) throws Except
refresh();

SearchResponse searchResponse;

searchResponse = client().prepareSearch("test")
.setQuery(QueryBuilders.rangeQuery("field").gte(1).lte(numDocs))
.setTerminateAfter(10)
Expand All @@ -356,25 +382,28 @@ public void doTestSimpleTerminateAfterTrackTotalHitsUpTo(int size) throws Except
assertEquals(5, searchResponse.getHits().getTotalHits().value);
assertEquals(GREATER_THAN_OR_EQUAL_TO, searchResponse.getHits().getTotalHits().relation);

searchResponse = client().prepareSearch("test")
.setQuery(QueryBuilders.rangeQuery("field").gte(1).lte(numDocs))
.setTerminateAfter(5)
.setSize(size)
.setTrackTotalHitsUpTo(10)
.get();
assertTrue(searchResponse.isTerminatedEarly());
assertEquals(5, searchResponse.getHits().getTotalHits().value);
assertEquals(EQUAL_TO, searchResponse.getHits().getTotalHits().relation);
// For size = 0, the following queries terminate early, but hits and relation can vary.
if (size > 0) {
searchResponse = client().prepareSearch("test")
.setQuery(QueryBuilders.rangeQuery("field").gte(1).lte(numDocs))
.setTerminateAfter(5)
.setSize(size)
.setTrackTotalHitsUpTo(10)
.get();
assertTrue(searchResponse.isTerminatedEarly());
assertEquals(5, searchResponse.getHits().getTotalHits().value);
assertEquals(EQUAL_TO, searchResponse.getHits().getTotalHits().relation);

searchResponse = client().prepareSearch("test")
.setQuery(QueryBuilders.rangeQuery("field").gte(1).lte(numDocs))
.setTerminateAfter(5)
.setSize(size)
.setTrackTotalHitsUpTo(5)
.get();
assertTrue(searchResponse.isTerminatedEarly());
assertEquals(5, searchResponse.getHits().getTotalHits().value);
assertEquals(EQUAL_TO, searchResponse.getHits().getTotalHits().relation);
searchResponse = client().prepareSearch("test")
.setQuery(QueryBuilders.rangeQuery("field").gte(1).lte(numDocs))
.setTerminateAfter(5)
.setSize(size)
.setTrackTotalHitsUpTo(5)
.get();
assertTrue(searchResponse.isTerminatedEarly());
assertEquals(5, searchResponse.getHits().getTotalHits().value);
assertEquals(EQUAL_TO, searchResponse.getHits().getTotalHits().relation);
}

searchResponse = client().prepareSearch("test")
.setQuery(QueryBuilders.rangeQuery("field").gte(1).lte(numDocs))
Expand All @@ -383,7 +412,12 @@ public void doTestSimpleTerminateAfterTrackTotalHitsUpTo(int size) throws Except
.setTrackTotalHits(true)
.get();
assertTrue(searchResponse.isTerminatedEarly());
assertEquals(5, searchResponse.getHits().getTotalHits().value);
if (size == 0) {
// Since terminate_after < track_total_hits, we need to do a range check.
assertHitCount(searchResponse, 5, numDocs);
} else {
assertEquals(5, searchResponse.getHits().getTotalHits().value);
}
assertEquals(EQUAL_TO, searchResponse.getHits().getTotalHits().relation);

searchResponse = client().prepareSearch("test")
Expand All @@ -393,7 +427,12 @@ public void doTestSimpleTerminateAfterTrackTotalHitsUpTo(int size) throws Except
.setTrackTotalHits(true)
.get();
assertFalse(searchResponse.isTerminatedEarly());
assertEquals(numDocs, searchResponse.getHits().getTotalHits().value);
if (size == 0) {
// Since terminate_after < track_total_hits, we need to do a range check.
assertHitCount(searchResponse, 5, numDocs);
} else {
assertEquals(5, searchResponse.getHits().getTotalHits().value);
}
assertEquals(EQUAL_TO, searchResponse.getHits().getTotalHits().relation);

searchResponse = client().prepareSearch("test")
Expand All @@ -405,12 +444,11 @@ public void doTestSimpleTerminateAfterTrackTotalHitsUpTo(int size) throws Except
assertEquals(GREATER_THAN_OR_EQUAL_TO, searchResponse.getHits().getTotalHits().relation);
}

@AwaitsFix(bugUrl = "https://github.com/opensearch-project/OpenSearch/issues/10435")
public void testSimpleTerminateAfterTrackTotalHitsUpToRandomSize() throws Exception {
public void testSimpleTerminateAfterTrackTotalHitsUpToRandomSize0() throws Exception {
doTestSimpleTerminateAfterTrackTotalHitsUpTo(0);
}

public void testSimpleTerminateAfterTrackTotalHitsUpToSize0() throws Exception {
public void testSimpleTerminateAfterTrackTotalHitsUpToSize() throws Exception {
doTestSimpleTerminateAfterTrackTotalHitsUpTo(randomIntBetween(1, 29));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,12 @@ private SearchRequest mutate(SearchRequest searchRequest) {
mutators.add(
() -> mutation.setPhaseTook(searchRequest.isPhaseTook() == null ? randomBoolean() : searchRequest.isPhaseTook() == false)
);
mutators.add(
() -> mutation.setPhaseTook(searchRequest.isPhaseTook() == null ? randomBoolean() : searchRequest.isPhaseTook() == false)
);
mutators.add(
() -> mutation.setPhaseTook(searchRequest.isPhaseTook() == null ? randomBoolean() : searchRequest.isPhaseTook() == false)
);
mutators.add(
() -> mutation.setCancelAfterTimeInterval(
searchRequest.getCancelAfterTimeInterval() != null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,22 @@ public static void assertHitCount(SearchResponse countResponse, long expectedHit
}
}

public static void assertHitCount(SearchResponse countResponse, long minHitCount, long maxHitCount) {
final TotalHits totalHits = countResponse.getHits().getTotalHits();
if (!(totalHits.relation == TotalHits.Relation.EQUAL_TO && totalHits.value >= minHitCount && totalHits.value <= maxHitCount)) {
fail(
"Count is "
+ totalHits
+ " not between "
+ minHitCount
+ " and "
+ maxHitCount
+ " inclusive. "
+ formatShardStatus(countResponse)
);
}
}

public static void assertExists(GetResponse response) {
String message = String.format(Locale.ROOT, "Expected %s/%s to exist, but does not", response.getIndex(), response.getId());
assertThat(message, response.isExists(), is(true));
Expand Down
Loading