-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Optimize AsyncSearchErrorTraceIT to avoid failures #137716
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
Changes from all commits
07d3482
3eeb382
f85e0e0
9f43a48
8eb666d
7a196af
9f29d54
579a670
a7d09d4
470111d
2564e70
87b0136
24b8090
abe679e
9436352
01a6f6e
e7dac60
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,8 @@ | |
|
|
||
| package org.elasticsearch.xpack.search; | ||
|
|
||
| import org.apache.http.HttpEntity; | ||
| import org.apache.http.util.EntityUtils; | ||
| import org.apache.logging.log4j.Level; | ||
| import org.apache.logging.log4j.core.config.Configurator; | ||
| import org.elasticsearch.client.Request; | ||
|
|
@@ -16,7 +18,6 @@ | |
| import org.elasticsearch.plugins.Plugin; | ||
| import org.elasticsearch.search.ErrorTraceHelper; | ||
| import org.elasticsearch.search.SearchService; | ||
| import org.elasticsearch.test.ESIntegTestCase; | ||
| import org.elasticsearch.test.MockLog; | ||
| import org.elasticsearch.test.junit.annotations.TestLogging; | ||
| import org.elasticsearch.test.transport.MockTransportService; | ||
|
|
@@ -31,7 +32,7 @@ | |
| reason = "testing debug log output to identify race condition", | ||
| value = "org.elasticsearch.xpack.search.MutableSearchResponse:DEBUG,org.elasticsearch.xpack.search.AsyncSearchTask:DEBUG" | ||
| ) | ||
| public class AsyncSearchErrorTraceIT extends ESIntegTestCase { | ||
| public class AsyncSearchErrorTraceIT extends AsyncSearchIntegTestCase { | ||
|
|
||
| @Override | ||
| protected boolean addMockHttpTransport() { | ||
|
|
@@ -77,10 +78,15 @@ public void testAsyncSearchFailingQueryErrorTraceDefault() throws Exception { | |
| createAsyncRequest.addParameter("wait_for_completion_timeout", "0ms"); | ||
| ErrorTraceHelper.expectStackTraceCleared(internalCluster()); | ||
| Map<String, Object> createAsyncResponseEntity = performRequestAndGetResponseEntity(createAsyncRequest); | ||
| if (Boolean.TRUE.equals(createAsyncResponseEntity.get("is_running"))) { | ||
| String asyncExecutionId = (String) createAsyncResponseEntity.get("id"); | ||
| Request getAsyncRequest = new Request("GET", "/_async_search/" + asyncExecutionId); | ||
| awaitAsyncRequestDoneRunning(getAsyncRequest); | ||
|
|
||
| try { | ||
| if (Boolean.TRUE.equals(createAsyncResponseEntity.get("is_running"))) { | ||
| String asyncExecutionId = (String) createAsyncResponseEntity.get("id"); | ||
| Request getAsyncRequest = new Request("GET", "/_async_search/" + asyncExecutionId); | ||
| awaitAsyncRequestDoneRunning(getAsyncRequest); | ||
| } | ||
| } finally { | ||
| deleteAsyncSearchIfPresent(createAsyncResponseEntity); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makes sense to me, I see a similar thing is done in CCSDuelIT for async searches.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you, Ben, for the review. Yes, this is actually the most important part of this PR, ensuring that the entry (with id) in the index is deleted before the test reaches the “after test cleanup,” where the exception is thrown. |
||
| } | ||
| } | ||
|
|
||
|
|
@@ -103,11 +109,16 @@ public void testAsyncSearchFailingQueryErrorTraceTrue() throws Exception { | |
| createAsyncRequest.addParameter("wait_for_completion_timeout", "0ms"); | ||
| ErrorTraceHelper.expectStackTraceObserved(internalCluster()); | ||
| Map<String, Object> createAsyncResponseEntity = performRequestAndGetResponseEntity(createAsyncRequest); | ||
| if (Boolean.TRUE.equals(createAsyncResponseEntity.get("is_running"))) { | ||
| String asyncExecutionId = (String) createAsyncResponseEntity.get("id"); | ||
| Request getAsyncRequest = new Request("GET", "/_async_search/" + asyncExecutionId); | ||
| getAsyncRequest.addParameter("error_trace", "true"); | ||
| awaitAsyncRequestDoneRunning(getAsyncRequest); | ||
|
|
||
| try { | ||
| if (Boolean.TRUE.equals(createAsyncResponseEntity.get("is_running"))) { | ||
| String asyncExecutionId = (String) createAsyncResponseEntity.get("id"); | ||
| Request getAsyncRequest = new Request("GET", "/_async_search/" + asyncExecutionId); | ||
| getAsyncRequest.addParameter("error_trace", "true"); | ||
| awaitAsyncRequestDoneRunning(getAsyncRequest); | ||
| } | ||
| } finally { | ||
| deleteAsyncSearchIfPresent(createAsyncResponseEntity); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -130,11 +141,16 @@ public void testAsyncSearchFailingQueryErrorTraceFalse() throws Exception { | |
| createAsyncRequest.addParameter("wait_for_completion_timeout", "0ms"); | ||
| ErrorTraceHelper.expectStackTraceCleared(internalCluster()); | ||
| Map<String, Object> createAsyncResponseEntity = performRequestAndGetResponseEntity(createAsyncRequest); | ||
| if (Boolean.TRUE.equals(createAsyncResponseEntity.get("is_running"))) { | ||
| String asyncExecutionId = (String) createAsyncResponseEntity.get("id"); | ||
| Request getAsyncRequest = new Request("GET", "/_async_search/" + asyncExecutionId); | ||
| getAsyncRequest.addParameter("error_trace", "false"); | ||
| awaitAsyncRequestDoneRunning(getAsyncRequest); | ||
|
|
||
| try { | ||
| if (Boolean.TRUE.equals(createAsyncResponseEntity.get("is_running"))) { | ||
| String asyncExecutionId = (String) createAsyncResponseEntity.get("id"); | ||
| Request getAsyncRequest = new Request("GET", "/_async_search/" + asyncExecutionId); | ||
| getAsyncRequest.addParameter("error_trace", "false"); | ||
| awaitAsyncRequestDoneRunning(getAsyncRequest); | ||
| } | ||
| } finally { | ||
| deleteAsyncSearchIfPresent(createAsyncResponseEntity); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -169,19 +185,24 @@ public void testDataNodeLogsStackTrace() throws Exception { | |
| try (var mockLog = MockLog.capture(SearchService.class)) { | ||
| ErrorTraceHelper.addSeenLoggingExpectations(numShards, mockLog, errorTriggeringIndex); | ||
| Map<String, Object> createAsyncResponseEntity = performRequestAndGetResponseEntity(createAsyncRequest); | ||
| if (Boolean.TRUE.equals(createAsyncResponseEntity.get("is_running"))) { | ||
| String asyncExecutionId = (String) createAsyncResponseEntity.get("id"); | ||
| Request getAsyncRequest = new Request("GET", "/_async_search/" + asyncExecutionId); | ||
| // Use the same value of error_trace as the search request | ||
| if (errorTraceValue == 0) { | ||
| getAsyncRequest.addParameter("error_trace", "true"); | ||
| } else if (errorTraceValue == 1) { | ||
| getAsyncRequest.addParameter("error_trace", "false"); | ||
| } // else empty | ||
| awaitAsyncRequestDoneRunning(getAsyncRequest); | ||
| } | ||
|
|
||
| mockLog.assertAllExpectationsMatched(); | ||
| try { | ||
| if (Boolean.TRUE.equals(createAsyncResponseEntity.get("is_running"))) { | ||
| String asyncExecutionId = (String) createAsyncResponseEntity.get("id"); | ||
| Request getAsyncRequest = new Request("GET", "/_async_search/" + asyncExecutionId); | ||
| // Use the same value of error_trace as the search request | ||
| if (errorTraceValue == 0) { | ||
| getAsyncRequest.addParameter("error_trace", "true"); | ||
| } else if (errorTraceValue == 1) { | ||
| getAsyncRequest.addParameter("error_trace", "false"); | ||
| } // else empty | ||
| awaitAsyncRequestDoneRunning(getAsyncRequest); | ||
| } | ||
|
|
||
| mockLog.assertAllExpectationsMatched(); | ||
| } finally { | ||
| deleteAsyncSearchIfPresent(createAsyncResponseEntity); | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -204,11 +225,16 @@ public void testAsyncSearchFailingQueryErrorTraceFalseOnSubmitAndTrueOnGet() thr | |
| createAsyncSearchRequest.addParameter("wait_for_completion_timeout", "0ms"); | ||
| ErrorTraceHelper.expectStackTraceCleared(internalCluster()); | ||
| Map<String, Object> createAsyncResponseEntity = performRequestAndGetResponseEntity(createAsyncSearchRequest); | ||
| if (Boolean.TRUE.equals(createAsyncResponseEntity.get("is_running"))) { | ||
| String asyncExecutionId = (String) createAsyncResponseEntity.get("id"); | ||
| Request getAsyncRequest = new Request("GET", "/_async_search/" + asyncExecutionId); | ||
| getAsyncRequest.addParameter("error_trace", "true"); | ||
| awaitAsyncRequestDoneRunning(getAsyncRequest); | ||
|
|
||
| try { | ||
| if (Boolean.TRUE.equals(createAsyncResponseEntity.get("is_running"))) { | ||
| String asyncExecutionId = (String) createAsyncResponseEntity.get("id"); | ||
| Request getAsyncRequest = new Request("GET", "/_async_search/" + asyncExecutionId); | ||
| getAsyncRequest.addParameter("error_trace", "true"); | ||
| awaitAsyncRequestDoneRunning(getAsyncRequest); | ||
| } | ||
| } finally { | ||
| deleteAsyncSearchIfPresent(createAsyncResponseEntity); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -231,11 +257,15 @@ public void testAsyncSearchFailingQueryErrorTraceTrueOnSubmitAndFalseOnGet() thr | |
| createAsyncSearchRequest.addParameter("wait_for_completion_timeout", "0ms"); | ||
| ErrorTraceHelper.expectStackTraceObserved(internalCluster()); | ||
| Map<String, Object> createAsyncResponseEntity = performRequestAndGetResponseEntity(createAsyncSearchRequest); | ||
| if (Boolean.TRUE.equals(createAsyncResponseEntity.get("is_running"))) { | ||
| String asyncExecutionId = (String) createAsyncResponseEntity.get("id"); | ||
| Request getAsyncRequest = new Request("GET", "/_async_search/" + asyncExecutionId); | ||
| getAsyncRequest.addParameter("error_trace", "false"); | ||
| awaitAsyncRequestDoneRunning(getAsyncRequest); | ||
| try { | ||
| if (Boolean.TRUE.equals(createAsyncResponseEntity.get("is_running"))) { | ||
| String asyncExecutionId = (String) createAsyncResponseEntity.get("id"); | ||
| Request getAsyncRequest = new Request("GET", "/_async_search/" + asyncExecutionId); | ||
| getAsyncRequest.addParameter("error_trace", "false"); | ||
| awaitAsyncRequestDoneRunning(getAsyncRequest); | ||
| } | ||
| } finally { | ||
| deleteAsyncSearchIfPresent(createAsyncResponseEntity); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -245,6 +275,26 @@ private Map<String, Object> performRequestAndGetResponseEntity(Request r) throws | |
| return XContentHelper.convertToMap(entityContentType.xContent(), response.getEntity().getContent(), false); | ||
| } | ||
|
|
||
| private void deleteAsyncSearchIfPresent(Map<String, Object> map) throws IOException { | ||
| String id = (String) map.get("id"); | ||
| if (id == null) { | ||
| return; | ||
| } | ||
|
|
||
| // Make sure the .async-search system index is green before deleting it | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why ensure green?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By the time we reach the cleanup phase, the |
||
| try { | ||
| ensureGreen(".async-search"); | ||
| } catch (Exception ignore) { | ||
| // the index may not exist | ||
| } | ||
|
|
||
| Response response = getRestClient().performRequest(new Request("DELETE", "/_async_search/" + id)); | ||
| HttpEntity entity = response.getEntity(); | ||
| if (entity != null) { | ||
| EntityUtils.consumeQuietly(entity); | ||
| } | ||
| } | ||
|
|
||
| private void awaitAsyncRequestDoneRunning(Request getAsyncRequest) throws Exception { | ||
| assertBusy(() -> { | ||
| Map<String, Object> getAsyncResponseEntity = performRequestAndGetResponseEntity(getAsyncRequest); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this needed for the fix or is it an unrelated improvement?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn’t necessary for this test; I added it to keep it consistent with the other tests in the same package.