Skip to content

Commit 70507a6

Browse files
authored
Verify execution info in remote index resolution tests (#137361)
1 parent 3017e33 commit 70507a6

File tree

2 files changed

+102
-14
lines changed

2 files changed

+102
-14
lines changed

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

Lines changed: 98 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,18 @@
77

88
package org.elasticsearch.xpack.esql.plugin;
99

10-
import org.elasticsearch.ElasticsearchTimeoutException;
10+
import org.elasticsearch.index.query.MatchAllQueryBuilder;
11+
import org.elasticsearch.index.query.MatchNoneQueryBuilder;
1112
import org.elasticsearch.transport.NoSuchRemoteClusterException;
1213
import org.elasticsearch.xpack.esql.VerificationException;
1314
import org.elasticsearch.xpack.esql.action.AbstractCrossClusterTestCase;
15+
import org.elasticsearch.xpack.esql.action.EsqlExecutionInfo.Cluster.Status;
1416
import org.elasticsearch.xpack.esql.action.EsqlQueryAction;
1517
import org.elasticsearch.xpack.esql.action.EsqlQueryRequest;
1618
import org.elasticsearch.xpack.esql.action.EsqlQueryResponse;
1719
import org.elasticsearch.xpack.esql.core.expression.MetadataAttribute;
1820

21+
import java.util.List;
1922
import java.util.Objects;
2023
import java.util.concurrent.TimeUnit;
2124

@@ -29,9 +32,14 @@ public class RemoteIndexResolutionIT extends AbstractCrossClusterTestCase {
2932
public void testResolvesRemoteIndex() {
3033
indexRandom(REMOTE_CLUSTER_1, true, "index-1", 1);
3134

32-
try (var response = run(syncEsqlQueryRequest().query("FROM " + REMOTE_CLUSTER_1 + ":index-1 METADATA _index"))) {
35+
try (
36+
var response = run(
37+
syncEsqlQueryRequest().query("FROM " + REMOTE_CLUSTER_1 + ":index-1 METADATA _index").includeCCSMetadata(true)
38+
)
39+
) {
3340
assertOk(response);
3441
assertResultConcreteIndices(response, REMOTE_CLUSTER_1 + ":index-1");
42+
assertExecutionInfo(response, new EsqlResponseExecutionInfo(REMOTE_CLUSTER_1, "index-1", Status.SUCCESSFUL));
3543
}
3644
}
3745

@@ -40,6 +48,17 @@ public void testResolveRemoteUnknownIndex() {
4048
// This index is mixed into the resultset to test error handling of the missing concrete remote, not the empty result.
4149
indexRandom(LOCAL_CLUSTER, true, "data", 1);
4250

51+
expectThrows(
52+
VerificationException.class,
53+
containsString("Unknown index [" + REMOTE_CLUSTER_1 + ":fake]"),
54+
() -> run(syncEsqlQueryRequest().query("FROM data," + REMOTE_CLUSTER_1 + ":fake"))
55+
);
56+
expectThrows(
57+
VerificationException.class,
58+
containsString("Unknown index [" + REMOTE_CLUSTER_1 + ":fake]"),
59+
() -> run(syncEsqlQueryRequest().query("FROM data," + REMOTE_CLUSTER_1 + ":fake").allowPartialResults(true))
60+
);
61+
4362
setSkipUnavailable(REMOTE_CLUSTER_1, false);
4463
expectThrows(
4564
VerificationException.class,
@@ -48,25 +67,52 @@ public void testResolveRemoteUnknownIndex() {
4867
);
4968

5069
setSkipUnavailable(REMOTE_CLUSTER_1, true);
51-
try (var response = run(syncEsqlQueryRequest().query("FROM data," + REMOTE_CLUSTER_1 + ":fake METADATA _index"))) {
70+
try (
71+
var response = run(
72+
syncEsqlQueryRequest().query("FROM data," + REMOTE_CLUSTER_1 + ":fake METADATA _index").includeCCSMetadata(true)
73+
)
74+
) {
5275
assertPartial(response);
5376
assertResultConcreteIndices(response, "data");
77+
assertExecutionInfo(
78+
response,
79+
new EsqlResponseExecutionInfo(LOCAL_CLUSTER, "data", Status.SUCCESSFUL),
80+
new EsqlResponseExecutionInfo(REMOTE_CLUSTER_1, "fake", Status.SKIPPED)
81+
);
5482
}
5583

5684
setSkipUnavailable(REMOTE_CLUSTER_1, null);
57-
try (var response = run(syncEsqlQueryRequest().query("FROM data," + REMOTE_CLUSTER_1 + ":fake METADATA _index"))) {
85+
try (
86+
var response = run(
87+
syncEsqlQueryRequest().query("FROM data," + REMOTE_CLUSTER_1 + ":fake METADATA _index").includeCCSMetadata(true)
88+
)
89+
) {
5890
assertPartial(response);
5991
assertResultConcreteIndices(response, "data");
92+
assertExecutionInfo(
93+
response,
94+
new EsqlResponseExecutionInfo(LOCAL_CLUSTER, "data", Status.SUCCESSFUL),
95+
new EsqlResponseExecutionInfo(REMOTE_CLUSTER_1, "fake", Status.SKIPPED)
96+
);
6097
}
6198
}
6299

63100
public void testResolvesLocalAndRemoteIndex() {
64101
indexRandom(LOCAL_CLUSTER, true, "index-1", 1);
65102
indexRandom(REMOTE_CLUSTER_1, true, "index-1", 1);
66103

67-
try (var response = run(syncEsqlQueryRequest().query("FROM index-1," + REMOTE_CLUSTER_1 + ":index-1 METADATA _index"))) {
104+
try (
105+
var response = run(
106+
syncEsqlQueryRequest().query("FROM index-1," + REMOTE_CLUSTER_1 + ":index-1 METADATA _index").includeCCSMetadata(true)
107+
)
108+
) {
68109
assertOk(response);
69110
assertResultConcreteIndices(response, "index-1", REMOTE_CLUSTER_1 + ":index-1");
111+
assertExecutionInfo(
112+
response,
113+
new EsqlResponseExecutionInfo(LOCAL_CLUSTER, "index-1", Status.SUCCESSFUL),
114+
new EsqlResponseExecutionInfo(REMOTE_CLUSTER_1, "index-1", Status.SUCCESSFUL)
115+
);
70116
}
71117
}
72118

@@ -75,13 +121,19 @@ public void testResolvesRemotesWithPattern() {
75121
indexRandom(REMOTE_CLUSTER_1, true, "index-1", 1);
76122
indexRandom(REMOTE_CLUSTER_2, true, "index-1", 1);
77123

78-
try (var response = run(syncEsqlQueryRequest().query("FROM *:index-1 METADATA _index"))) {
124+
try (var response = run(syncEsqlQueryRequest().query("FROM *:index-1 METADATA _index").includeCCSMetadata(true))) {
79125
assertOk(response);
80126
assertResultConcreteIndices(response, REMOTE_CLUSTER_1 + ":index-1", REMOTE_CLUSTER_2 + ":index-1"); // local is not included
127+
assertExecutionInfo(
128+
response,
129+
new EsqlResponseExecutionInfo(REMOTE_CLUSTER_1, "index-1", Status.SUCCESSFUL),
130+
new EsqlResponseExecutionInfo(REMOTE_CLUSTER_2, "index-1", Status.SUCCESSFUL)
131+
);
81132
}
82-
try (var response = run(syncEsqlQueryRequest().query("FROM fake*:index-1 METADATA _index"))) {
133+
try (var response = run(syncEsqlQueryRequest().query("FROM fake*:index-1 METADATA _index").includeCCSMetadata(true))) {
83134
assertOk(response);
84135
assertResultConcreteIndices(response); // empty
136+
assertExecutionInfo(response); // empty
85137
}
86138
}
87139

@@ -93,14 +145,33 @@ public void testDoesNotResolvesUnknownRemote() {
93145
);
94146
}
95147

96-
private EsqlQueryResponse run(EsqlQueryRequest request) {
97-
try {
98-
return client(LOCAL_CLUSTER).execute(EsqlQueryAction.INSTANCE, request).actionGet(30, TimeUnit.SECONDS);
99-
} catch (ElasticsearchTimeoutException e) {
100-
throw new AssertionError("timeout", e);
148+
public void testResolutionWithFilter() {
149+
indexRandom(REMOTE_CLUSTER_1, true, "index-1", 1);
150+
151+
try (
152+
var response = run(
153+
syncEsqlQueryRequest().query("FROM " + REMOTE_CLUSTER_1 + ":index-1 METADATA _index").filter(new MatchAllQueryBuilder())
154+
)
155+
) {
156+
assertOk(response);
157+
assertResultConcreteIndices(response, REMOTE_CLUSTER_1 + ":index-1");
158+
assertExecutionInfo(response, new EsqlResponseExecutionInfo(REMOTE_CLUSTER_1, "index-1", Status.SUCCESSFUL));
159+
}
160+
try (
161+
var response = run(
162+
syncEsqlQueryRequest().query("FROM " + REMOTE_CLUSTER_1 + ":index-1 METADATA _index").filter(new MatchNoneQueryBuilder())
163+
)
164+
) {
165+
assertOk(response);
166+
assertResultConcreteIndices(response);
167+
assertExecutionInfo(response, new EsqlResponseExecutionInfo(REMOTE_CLUSTER_1, "index-1", Status.SUCCESSFUL));
101168
}
102169
}
103170

171+
private EsqlQueryResponse run(EsqlQueryRequest request) {
172+
return client(LOCAL_CLUSTER).execute(EsqlQueryAction.INSTANCE, request).actionGet(30, TimeUnit.SECONDS);
173+
}
174+
104175
private void indexRandom(String clusterAlias, boolean forceRefresh, String index, int numDocs) {
105176
assert numDocs == 1;
106177
var client = client(clusterAlias);
@@ -123,6 +194,10 @@ private static void assertResultConcreteIndices(EsqlQueryResponse response, Obje
123194
assertThat(() -> response.column(indexColumn), containsInAnyOrder(indices));
124195
}
125196

197+
private static void assertExecutionInfo(EsqlQueryResponse response, EsqlResponseExecutionInfo... infos) {
198+
assertThat(executionInfo(response), containsInAnyOrder(infos));
199+
}
200+
126201
private static int findIndexColumn(EsqlQueryResponse response) {
127202
for (int c = 0; c < response.columns().size(); c++) {
128203
if (Objects.equals(response.columns().get(c).name(), MetadataAttribute.INDEX)) {
@@ -131,4 +206,15 @@ private static int findIndexColumn(EsqlQueryResponse response) {
131206
}
132207
throw new AssertionError("no _index column found");
133208
}
209+
210+
private static List<EsqlResponseExecutionInfo> executionInfo(EsqlQueryResponse response) {
211+
return response.getExecutionInfo()
212+
.getClusters()
213+
.values()
214+
.stream()
215+
.map(cluster -> new EsqlResponseExecutionInfo(cluster.getClusterAlias(), cluster.getIndexExpression(), cluster.getStatus()))
216+
.toList();
217+
}
218+
219+
private record EsqlResponseExecutionInfo(String alias, String index, Status status) {}
134220
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,18 @@ public void profile(boolean profile) {
143143
this.profile = profile;
144144
}
145145

146-
public void includeCCSMetadata(Boolean include) {
146+
public EsqlQueryRequest includeCCSMetadata(Boolean include) {
147147
this.includeCCSMetadata = include;
148+
return this;
148149
}
149150

150151
public Boolean includeCCSMetadata() {
151152
return includeCCSMetadata;
152153
}
153154

154-
public void includeExecutionMetadata(Boolean include) {
155+
public EsqlQueryRequest includeExecutionMetadata(Boolean include) {
155156
this.includeExecutionMetadata = include;
157+
return this;
156158
}
157159

158160
public Boolean includeExecutionMetadata() {

0 commit comments

Comments
 (0)