Skip to content

Commit ff0fe90

Browse files
committed
Moved test
1 parent 2fa0085 commit ff0fe90

File tree

7 files changed

+208
-90
lines changed

7 files changed

+208
-90
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.test;
11+
12+
import org.hamcrest.BaseMatcher;
13+
import org.hamcrest.Description;
14+
import org.hamcrest.Matcher;
15+
16+
import static org.hamcrest.Matchers.anyOf;
17+
import static org.hamcrest.Matchers.equalTo;
18+
import static org.hamcrest.Matchers.isA;
19+
20+
/**
21+
* A type-agnostic way of comparing integer values, not caring if it's a long or an integer.
22+
*/
23+
public abstract sealed class IntegerMatcher<T> extends BaseMatcher<T> {
24+
public static IntegerMatcher<Integer> matches(int expected) {
25+
return new IntMatcher(expected);
26+
}
27+
28+
public static IntegerMatcher<Long> matches(long expected) {
29+
return new LongMatcher(expected);
30+
}
31+
32+
private static final class IntMatcher extends IntegerMatcher<Integer> {
33+
private final int expected;
34+
35+
private IntMatcher(int expected) {
36+
this.expected = expected;
37+
}
38+
39+
@Override
40+
public boolean matches(Object o) {
41+
return switch (o) {
42+
case Integer i -> expected == i;
43+
case Long l -> expected == l;
44+
default -> false;
45+
};
46+
}
47+
48+
@Override
49+
public void describeTo(Description description) {
50+
equalTo(expected).describeTo(description);
51+
}
52+
}
53+
54+
private static final class LongMatcher extends IntegerMatcher<Long> {
55+
private final long expected;
56+
57+
LongMatcher(long expected) {
58+
this.expected = expected;
59+
}
60+
61+
@Override
62+
public boolean matches(Object o) {
63+
return switch (o) {
64+
case Integer i -> expected == i;
65+
case Long l -> expected == l;
66+
default -> false;
67+
};
68+
}
69+
70+
@Override
71+
public void describeTo(Description description) {
72+
equalTo(expected).describeTo(description);
73+
}
74+
}
75+
76+
public static Matcher<Object> isIntOrLong() {
77+
return anyOf(isA(Integer.class), isA(Long.class));
78+
}
79+
}

x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RestEsqlTestCase.java

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import org.elasticsearch.client.RequestOptions;
1717
import org.elasticsearch.client.Response;
1818
import org.elasticsearch.client.ResponseException;
19-
import org.elasticsearch.client.ResponseListener;
2019
import org.elasticsearch.client.WarningsHandler;
2120
import org.elasticsearch.common.bytes.BytesArray;
2221
import org.elasticsearch.common.io.Streams;
@@ -27,7 +26,6 @@
2726
import org.elasticsearch.core.TimeValue;
2827
import org.elasticsearch.logging.LogManager;
2928
import org.elasticsearch.logging.Logger;
30-
import org.elasticsearch.tasks.TaskId;
3129
import org.elasticsearch.test.ListMatcher;
3230
import org.elasticsearch.test.rest.ESRestTestCase;
3331
import org.elasticsearch.xcontent.ToXContent;
@@ -46,7 +44,6 @@
4644
import java.io.InputStreamReader;
4745
import java.io.OutputStream;
4846
import java.nio.charset.StandardCharsets;
49-
import java.time.Duration;
5047
import java.time.ZoneId;
5148
import java.util.ArrayList;
5249
import java.util.Arrays;
@@ -73,7 +70,6 @@
7370
import static org.hamcrest.Matchers.emptyOrNullString;
7471
import static org.hamcrest.Matchers.equalTo;
7572
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
76-
import static org.hamcrest.Matchers.hasKey;
7773
import static org.hamcrest.Matchers.is;
7874
import static org.hamcrest.Matchers.not;
7975
import static org.hamcrest.Matchers.nullValue;
@@ -1349,56 +1345,6 @@ public void testAsyncGetWithoutContentType() throws IOException {
13491345

13501346
}
13511347

1352-
public void testListApi_noRunningQueries_returnsAnObject() throws Exception {
1353-
Request request = prepareListQueriesRequest();
1354-
Response response = performRequest(request);
1355-
assertThat(entityToMap(response.getEntity(), XContentType.JSON), is(Map.of("queries", Map.of())));
1356-
}
1357-
1358-
public void testListApi_runningQuery_returnsQueriesObject() throws Exception {
1359-
bulkLoadTestData(1);
1360-
String query = fromIndex() + " | keep keyword, integer | where delay(10s) | limit 100 ";
1361-
var builder = requestObjectBuilder().query(query);
1362-
Request request = prepareRequest(SYNC);
1363-
String mediaType = attachBody(builder.build(), request);
1364-
RequestOptions.Builder options = request.getOptions().toBuilder();
1365-
options.addHeader("Content-Type", mediaType);
1366-
options.addHeader("Accept", mediaType);
1367-
request.setOptions(options);
1368-
client().performRequestAsync(request, new ResponseListener() {
1369-
@Override
1370-
public void onSuccess(Response response) {}
1371-
1372-
@Override
1373-
public void onFailure(Exception exception) {}
1374-
});
1375-
Thread.sleep(Duration.ofSeconds(5));
1376-
Response response = performRequest(prepareListQueriesRequest());
1377-
@SuppressWarnings("unchecked")
1378-
var listResult = (Map<String, Map<String, Object>>) EsqlTestUtils.singleValue(
1379-
entityToMap(response.getEntity(), XContentType.JSON).values()
1380-
);
1381-
var taskId = new TaskId(EsqlTestUtils.singleValue(listResult.keySet()));
1382-
var queryFromListResult = EsqlTestUtils.singleValue(listResult.values());
1383-
assertThat(queryFromListResult.get("id"), is((int) taskId.getId()));
1384-
assertThat(queryFromListResult.get("node"), is(taskId.getNodeId()));
1385-
assertThat(queryFromListResult.get("query"), is(query));
1386-
assertThat(queryFromListResult, hasKey("start_time_millis"));
1387-
assertThat(queryFromListResult, hasKey("running_time_nanos"));
1388-
1389-
response = performRequest(prepareGetQueryRequest(taskId));
1390-
@SuppressWarnings("unchecked")
1391-
Map<String, Object> getQueryResult = entityToMap(response.getEntity(), XContentType.JSON);
1392-
assertThat(getQueryResult.get("id"), is((int) taskId.getId()));
1393-
assertThat(getQueryResult.get("node"), is(taskId.getNodeId()));
1394-
assertThat(getQueryResult.get("query"), is(query));
1395-
assertThat(getQueryResult.get("start_time_millis"), is(queryFromListResult.get("start_time_millis")));
1396-
assertThat(getQueryResult, hasKey("running_time_nanos"));
1397-
assertThat(getQueryResult, hasKey("coordinating_node"));
1398-
assertThat(getQueryResult, hasKey("data_nodes"));
1399-
Thread.sleep(Duration.ofSeconds(5));
1400-
}
1401-
14021348
protected static Request prepareRequestWithOptions(RequestObjectBuilder requestObject, Mode mode) throws IOException {
14031349
requestObject.build();
14041350
Request request = prepareRequest(mode);
@@ -1580,14 +1526,6 @@ private static Request prepareAsyncDeleteRequest(String id) {
15801526
return finishRequest(new Request("DELETE", "/_query/async/" + id));
15811527
}
15821528

1583-
private static Request prepareListQueriesRequest() {
1584-
return finishRequest(new Request("GET", "/_query/queries/"));
1585-
}
1586-
1587-
private static Request prepareGetQueryRequest(TaskId id) {
1588-
return finishRequest(new Request("GET", "/_query/queries/" + id));
1589-
}
1590-
15911529
private static Request finishRequest(Request request) {
15921530
request.addParameter("error_trace", "true"); // Helps with debugging in case something crazy happens on the server.
15931531
request.addParameter("pretty", "true"); // Improves error reporting readability

x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/AbstractEsqlIntegTestCase.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public void ensureExchangesAreReleased() throws Exception {
5555
ExchangeService exchangeService = esqlQueryAction.exchangeService();
5656
assertBusy(() -> {
5757
if (exchangeService.lifecycleState() == Lifecycle.State.STARTED) {
58-
assertTrue("Leftover exchanges " + exchangeService + " on node " + node, exchangeService.isEmpty());
58+
assertTrue("Leftover exchanges " + exchangeService + " on taskId " + node, exchangeService.isEmpty());
5959
}
6060
});
6161
}
@@ -98,7 +98,7 @@ public void ensureBlocksReleased() {
9898
)
9999
.toList()
100100
);
101-
assertThat("Request breaker not reset to 0 on node: " + node, reqBreaker.getUsed(), equalTo(0L));
101+
assertThat("Request breaker not reset to 0 on taskId: " + node, reqBreaker.getUsed(), equalTo(0L));
102102
});
103103
} catch (Exception e) {
104104
throw new RuntimeException("failed waiting for breakers to clear", e);
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.esql.action;
9+
10+
import org.apache.http.HttpEntity;
11+
import org.elasticsearch.client.Request;
12+
import org.elasticsearch.common.xcontent.XContentHelper;
13+
import org.elasticsearch.tasks.TaskId;
14+
import org.elasticsearch.test.IntegerMatcher;
15+
import org.elasticsearch.test.MapMatcher;
16+
import org.elasticsearch.xcontent.XContentType;
17+
import org.elasticsearch.xpack.core.async.GetAsyncResultRequest;
18+
import org.elasticsearch.xpack.esql.EsqlTestUtils;
19+
20+
import java.io.IOException;
21+
import java.io.InputStream;
22+
import java.util.List;
23+
import java.util.Map;
24+
import java.util.concurrent.TimeUnit;
25+
26+
import static org.elasticsearch.core.TimeValue.timeValueSeconds;
27+
import static org.hamcrest.Matchers.allOf;
28+
import static org.hamcrest.Matchers.everyItem;
29+
import static org.hamcrest.Matchers.is;
30+
import static org.hamcrest.Matchers.isA;
31+
32+
/**
33+
* Individual tests for specific aspects of the async query API.
34+
*/
35+
public class EsqlListQuerriesActionIT extends AbstractPausableIntegTestCase {
36+
public static final String QUERY = "from test | stats sum(pause_me)";
37+
38+
@Override
39+
protected boolean addMockHttpTransport() {
40+
return false;
41+
}
42+
43+
public void testNoRunningQueries() throws Exception {
44+
var request = new Request("GET", "/_query/queries");
45+
var response = getRestClient().performRequest(request);
46+
assertThat(entityToMap(response.getEntity()), is(Map.of("queries", Map.of())));
47+
}
48+
49+
public void testRunningQueries() throws Exception {
50+
String id = null;
51+
try (var initialResponse = sendAsyncQuery()) {
52+
id = initialResponse.asyncExecutionId().get();
53+
// FIXME(gal, NOCOMMIT) more copy paste
54+
var getResultsRequest = new GetAsyncResultRequest(id);
55+
getResultsRequest.setWaitForCompletionTimeout(timeValueSeconds(1));
56+
client().execute(EsqlAsyncGetResultAction.INSTANCE, getResultsRequest).get().close();
57+
var request = new Request("GET", "/_query/queries");
58+
var response = getRestClient().performRequest(request);
59+
@SuppressWarnings("unchecked")
60+
var listResult = (Map<String, Map<String, Object>>) EsqlTestUtils.singleValue(entityToMap(response.getEntity()).values());
61+
var taskId = new TaskId(EsqlTestUtils.singleValue(listResult.keySet()));
62+
MapMatcher basicMatcher = MapMatcher.matchesMap()
63+
.entry("node", is(taskId.getNodeId()))
64+
.entry("id", IntegerMatcher.matches(taskId.getId()))
65+
.entry("query", is(QUERY))
66+
.entry("start_time_millis", IntegerMatcher.isIntOrLong())
67+
.entry("running_time_nanos", IntegerMatcher.isIntOrLong());
68+
MapMatcher.assertMap(EsqlTestUtils.singleValue(listResult.values()), basicMatcher);
69+
70+
request = new Request("GET", "/_query/queries/" + taskId);
71+
response = getRestClient().performRequest(request);
72+
MapMatcher.assertMap(
73+
entityToMap(response.getEntity()),
74+
basicMatcher.entry("coordinating_node", isA(String.class))
75+
.entry("data_nodes", allOf(isA(List.class), everyItem(isA(String.class))))
76+
);
77+
} finally {
78+
if (id != null) {
79+
// Finish the query.
80+
scriptPermits.release(numberOfDocs());
81+
var getResultsRequest = new GetAsyncResultRequest(id);
82+
getResultsRequest.setWaitForCompletionTimeout(timeValueSeconds(60));
83+
client().execute(EsqlAsyncGetResultAction.INSTANCE, getResultsRequest).get().close();
84+
}
85+
scriptPermits.drainPermits();
86+
}
87+
}
88+
89+
// FIXME(gal, NOCOMMIT) copy paste
90+
private EsqlQueryResponse sendAsyncQuery() {
91+
scriptPermits.drainPermits();
92+
scriptPermits.release(between(1, 5));
93+
return EsqlQueryRequestBuilder.newAsyncEsqlQueryRequestBuilder(client()).query(QUERY).execute().actionGet(60, TimeUnit.SECONDS);
94+
}
95+
96+
// FIXME(gal, NOCOMMIT) copy pasted from another place
97+
@SuppressWarnings("unchecked")
98+
private static <T> Map<String, T> entityToMap(HttpEntity entity) throws IOException {
99+
try (InputStream content = entity.getContent()) {
100+
XContentType xContentType = XContentType.fromMediaType(entity.getContentType().getValue());
101+
assertEquals(XContentType.JSON, xContentType);
102+
var map = XContentHelper.convertToMap(xContentType.xContent(), content, false);
103+
return (Map<String, T>) map;
104+
}
105+
}
106+
}

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/RestEsqlListQueriesAction.java

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,9 @@ private static RestChannelConsumer restChannelConsumer(RestRequest request, Node
4545
LOGGER.debug("Beginning execution of ESQL list queries.");
4646

4747
String id = request.param("id");
48-
return id != null
49-
? (channel -> client.execute(
50-
EsqlGetQueryAction.INSTANCE,
51-
new EsqlGetQueryRequest(new TaskId(id)),
52-
new RestToXContentListener<>(channel)
53-
))
54-
: (channel -> client.execute(
55-
EsqlListQueriesAction.INSTANCE,
56-
new EsqlListQueriesRequest(),
57-
new RestToXContentListener<>(channel)
58-
));
48+
var action = id != null ? EsqlGetQueryAction.INSTANCE : EsqlListQueriesAction.INSTANCE;
49+
var actionRequest = id != null ? new EsqlGetQueryRequest(new TaskId(id)) : new EsqlListQueriesRequest();
50+
51+
return channel -> client.execute(action, actionRequest, new RestToXContentListener<>(channel));
5952
}
6053
}

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/TransportEsqlListQueriesAction.java

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,23 @@ public TransportEsqlListQueriesAction(TransportService transportService, NodeCli
4141

4242
@Override
4343
protected void doExecute(Task task, EsqlListQueriesRequest request, ActionListener<EsqlListQueriesResponse> listener) {
44-
new ListTasksRequestBuilder(nodeClient).setActions(EsqlQueryAction.NAME).setDetailed(true).execute(new ActionListener<>() {
45-
@Override
46-
public void onResponse(ListTasksResponse response) {
47-
List<EsqlListQueriesResponse.Query> queries = response.getTasks()
48-
.stream()
49-
.map(TransportEsqlListQueriesAction::toQuery)
50-
.toList();
51-
listener.onResponse(new EsqlListQueriesResponse(queries));
52-
}
44+
new ListTasksRequestBuilder(nodeClient).setActions(EsqlQueryAction.NAME, EsqlQueryAction.NAME + "[a]")
45+
.setDetailed(true)
46+
.execute(new ActionListener<>() {
47+
@Override
48+
public void onResponse(ListTasksResponse response) {
49+
List<EsqlListQueriesResponse.Query> queries = response.getTasks()
50+
.stream()
51+
.map(TransportEsqlListQueriesAction::toQuery)
52+
.toList();
53+
listener.onResponse(new EsqlListQueriesResponse(queries));
54+
}
5355

54-
@Override
55-
public void onFailure(Exception e) {
56-
listener.onFailure(e);
57-
}
58-
});
56+
@Override
57+
public void onFailure(Exception e) {
58+
listener.onFailure(e);
59+
}
60+
});
5961
}
6062

6163
private static EsqlListQueriesResponse.Query toQuery(TaskInfo taskInfo) {

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/TransportEsqlQueryAction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ public EsqlQueryTask createTask(
366366
id,
367367
type,
368368
action,
369-
request.getDescription(),
369+
request.query(), // Pass the query as the description
370370
parentTaskId,
371371
headers,
372372
originHeaders,

0 commit comments

Comments
 (0)