Skip to content

Commit b12c8a3

Browse files
committed
More tests
1 parent fd812df commit b12c8a3

File tree

9 files changed

+186
-157
lines changed

9 files changed

+186
-157
lines changed

server/src/internalClusterTest/java/org/elasticsearch/search/ccs/CCSUsageTelemetryIT.java

Lines changed: 6 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -40,27 +40,19 @@
4040
import org.elasticsearch.tasks.Task;
4141
import org.elasticsearch.test.AbstractMultiClustersTestCase;
4242
import org.elasticsearch.test.InternalTestCluster;
43+
import org.elasticsearch.test.SkipUnavailableRule;
44+
import org.elasticsearch.test.SkipUnavailableRule.NotSkipped;
4345
import org.elasticsearch.usage.UsageService;
4446
import org.junit.Assert;
4547
import org.junit.Rule;
46-
import org.junit.rules.TestRule;
47-
import org.junit.runner.Description;
48-
import org.junit.runners.model.Statement;
49-
50-
import java.lang.annotation.ElementType;
51-
import java.lang.annotation.Retention;
52-
import java.lang.annotation.RetentionPolicy;
53-
import java.lang.annotation.Target;
54-
import java.util.Arrays;
48+
5549
import java.util.Collection;
5650
import java.util.Collections;
5751
import java.util.HashMap;
5852
import java.util.List;
5953
import java.util.Map;
6054
import java.util.concurrent.ExecutionException;
6155
import java.util.concurrent.TimeUnit;
62-
import java.util.function.Function;
63-
import java.util.stream.Collectors;
6456

6557
import static org.elasticsearch.action.admin.cluster.stats.CCSUsageTelemetry.ASYNC_FEATURE;
6658
import static org.elasticsearch.action.admin.cluster.stats.CCSUsageTelemetry.MRT_FEATURE;
@@ -498,7 +490,7 @@ public void testRemoteOnlyTimesOut() throws Exception {
498490
assertThat(perCluster.get(REMOTE2), equalTo(null));
499491
}
500492

501-
@SkipOverride(aliases = { REMOTE1 })
493+
@NotSkipped(aliases = { REMOTE1 })
502494
public void testRemoteTimesOutFailure() throws Exception {
503495
Map<String, Object> testClusterInfo = setupClusters();
504496
String remoteIndex = (String) testClusterInfo.get("remote.index");
@@ -528,7 +520,7 @@ public void testRemoteTimesOutFailure() throws Exception {
528520
/**
529521
* Search when all the remotes failed and not skipped
530522
*/
531-
@SkipOverride(aliases = { REMOTE1, REMOTE2 })
523+
@NotSkipped(aliases = { REMOTE1, REMOTE2 })
532524
public void testFailedAllRemotesSearch() throws Exception {
533525
Map<String, Object> testClusterInfo = setupClusters();
534526
String localIndex = (String) testClusterInfo.get("local.index");
@@ -577,7 +569,7 @@ public void testRemoteHasNoIndex() throws Exception {
577569
/**
578570
* Test that we're still counting remote search even if remote cluster has no such index
579571
*/
580-
@SkipOverride(aliases = { REMOTE1 })
572+
@NotSkipped(aliases = { REMOTE1 })
581573
public void testRemoteHasNoIndexFailure() throws Exception {
582574
SearchRequest searchRequest = makeSearchRequest(REMOTE1 + ":no_such_index");
583575
CCSTelemetrySnapshot telemetry = getTelemetryFromFailedSearch(searchRequest);
@@ -695,40 +687,4 @@ private void indexDocs(Client client, String index, ActionListener<Void> listene
695687
bulkRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).execute(listener.safeMap(r -> null));
696688
}
697689

698-
/**
699-
* Annotation to mark specific cluster in a test as not to be skipped when unavailable
700-
*/
701-
@Retention(RetentionPolicy.RUNTIME)
702-
@Target(ElementType.METHOD)
703-
@interface SkipOverride {
704-
String[] aliases();
705-
}
706-
707-
/**
708-
* Test rule to process skip annotations
709-
*/
710-
static class SkipUnavailableRule implements TestRule {
711-
private final Map<String, Boolean> skipMap;
712-
713-
SkipUnavailableRule(String... clusterAliases) {
714-
this.skipMap = Arrays.stream(clusterAliases).collect(Collectors.toMap(Function.identity(), alias -> true));
715-
}
716-
717-
public Map<String, Boolean> getMap() {
718-
return skipMap;
719-
}
720-
721-
@Override
722-
public Statement apply(Statement base, Description description) {
723-
// Check for annotation named "SkipOverride" and set the overrides accordingly
724-
var aliases = description.getAnnotation(SkipOverride.class);
725-
if (aliases != null) {
726-
for (String alias : aliases.aliases()) {
727-
skipMap.put(alias, false);
728-
}
729-
}
730-
return base;
731-
}
732-
733-
}
734690
}

server/src/main/java/org/elasticsearch/action/admin/cluster/stats/CCSUsage.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
package org.elasticsearch.action.admin.cluster.stats;
1111

1212
import org.elasticsearch.ElasticsearchSecurityException;
13+
import org.elasticsearch.ElasticsearchStatusException;
1314
import org.elasticsearch.ExceptionsHelper;
1415
import org.elasticsearch.ResourceNotFoundException;
1516
import org.elasticsearch.action.ShardOperationFailedException;
@@ -143,6 +144,9 @@ public static Result getFailureType(Exception e) {
143144
if (ExceptionsHelper.unwrapCorruption(e) != null) {
144145
return Result.CORRUPTION;
145146
}
147+
if (ExceptionsHelper.unwrap(e, ElasticsearchStatusException.class) != null) {
148+
return Result.LICENSE;
149+
}
146150
// This is kind of last resort check - if we still don't know the reason but all shard failures are remote,
147151
// we assume it's remote's fault somehow.
148152
if (e instanceof SearchPhaseExecutionException spe) {

server/src/main/java/org/elasticsearch/action/admin/cluster/stats/CCSUsageTelemetry.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public enum Result {
4747
TIMEOUT("timeout"),
4848
CORRUPTION("corruption"),
4949
SECURITY("security"),
50+
LICENSE("license"),
5051
// May be helpful if there's a lot of other reasons, and it may be hard to calculate the unknowns for some clients.
5152
UNKNOWN("other");
5253

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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.junit.rules.TestRule;
13+
import org.junit.runner.Description;
14+
import org.junit.runners.model.Statement;
15+
16+
import java.lang.annotation.ElementType;
17+
import java.lang.annotation.Retention;
18+
import java.lang.annotation.RetentionPolicy;
19+
import java.lang.annotation.Target;
20+
import java.util.Arrays;
21+
import java.util.Map;
22+
import java.util.function.Function;
23+
import java.util.stream.Collectors;
24+
25+
/**
26+
* Test rule to process skip_unavailable override annotations
27+
*/
28+
public class SkipUnavailableRule implements TestRule {
29+
private final Map<String, Boolean> skipMap;
30+
31+
public SkipUnavailableRule(String... clusterAliases) {
32+
this.skipMap = Arrays.stream(clusterAliases).collect(Collectors.toMap(Function.identity(), alias -> true));
33+
}
34+
35+
public Map<String, Boolean> getMap() {
36+
return skipMap;
37+
}
38+
39+
@Override
40+
public Statement apply(Statement base, Description description) {
41+
// Check for annotation named "SkipOverride" and set the overrides accordingly
42+
var aliases = description.getAnnotation(NotSkipped.class);
43+
if (aliases != null) {
44+
for (String alias : aliases.aliases()) {
45+
skipMap.put(alias, false);
46+
}
47+
}
48+
return base;
49+
}
50+
51+
/**
52+
* Annotation to mark specific cluster in a test as not to be skipped when unavailable
53+
*/
54+
@Retention(RetentionPolicy.RUNTIME)
55+
@Target(ElementType.METHOD)
56+
public @interface NotSkipped {
57+
String[] aliases();
58+
}
59+
60+
}

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

Lines changed: 39 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,21 @@
1111
import org.apache.logging.log4j.Logger;
1212
import org.elasticsearch.action.admin.cluster.stats.CCSTelemetrySnapshot;
1313
import org.elasticsearch.client.internal.Client;
14-
import org.elasticsearch.common.settings.Setting;
1514
import org.elasticsearch.common.settings.Settings;
16-
import org.elasticsearch.compute.operator.exchange.ExchangeService;
17-
import org.elasticsearch.core.TimeValue;
1815
import org.elasticsearch.plugins.Plugin;
1916
import org.elasticsearch.tasks.Task;
2017
import org.elasticsearch.test.AbstractMultiClustersTestCase;
18+
import org.elasticsearch.test.SkipUnavailableRule;
2119
import org.elasticsearch.usage.UsageService;
22-
import org.elasticsearch.xpack.esql.plugin.EsqlPlugin;
2320
import org.junit.Assert;
2421
import org.junit.Rule;
25-
import org.junit.rules.TestRule;
26-
import org.junit.runner.Description;
27-
import org.junit.runners.model.Statement;
28-
29-
import java.lang.annotation.ElementType;
30-
import java.lang.annotation.Retention;
31-
import java.lang.annotation.RetentionPolicy;
32-
import java.lang.annotation.Target;
22+
3323
import java.util.ArrayList;
34-
import java.util.Arrays;
3524
import java.util.Collection;
3625
import java.util.HashMap;
3726
import java.util.List;
3827
import java.util.Map;
3928
import java.util.concurrent.ExecutionException;
40-
import java.util.function.Function;
41-
import java.util.stream.Collectors;
4229

4330
import static org.elasticsearch.action.admin.cluster.stats.CCSUsageTelemetry.ASYNC_FEATURE;
4431
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
@@ -52,19 +39,6 @@ public class CrossClustersUsageTelemetryIT extends AbstractMultiClustersTestCase
5239
private static final String LOCAL_INDEX = "logs-1";
5340
private static final String REMOTE_INDEX = "logs-2";
5441

55-
@Override
56-
protected boolean reuseClusters() {
57-
return false;
58-
}
59-
60-
@Override
61-
protected List<String> remoteClusterAlias() {
62-
return List.of(REMOTE1, REMOTE2);
63-
}
64-
65-
@Rule
66-
public SkipUnavailableRule skipOverride = new SkipUnavailableRule(REMOTE1, REMOTE2);
67-
6842
public void testLocalRemote() throws Exception {
6943
setupClusters();
7044
var telemetry = getTelemetryFromQuery("from logs-*,c*:logs-* | stats sum (v)", "kibana");
@@ -93,11 +67,7 @@ public void testLocalRemote() throws Exception {
9367

9468
}
9569

96-
private CCSTelemetrySnapshot getTelemetryFromQuery(String query) throws ExecutionException, InterruptedException {
97-
return getTelemetryFromQuery(query, null);
98-
}
99-
100-
private CCSTelemetrySnapshot getTelemetryFromQuery(String query, String client) throws ExecutionException, InterruptedException {
70+
protected CCSTelemetrySnapshot getTelemetryFromQuery(String query, String client) throws ExecutionException, InterruptedException {
10171
EsqlQueryRequest request = EsqlQueryRequest.syncEsqlQueryRequest();
10272
request.query(query);
10373
request.pragmas(AbstractEsqlIntegTestCase.randomPragmas());
@@ -106,7 +76,7 @@ private CCSTelemetrySnapshot getTelemetryFromQuery(String query, String client)
10676
return getTelemetryFromQuery(request, client);
10777
}
10878

109-
private CCSTelemetrySnapshot getTelemetryFromQuery(EsqlQueryRequest request, String client) throws ExecutionException,
79+
protected CCSTelemetrySnapshot getTelemetryFromQuery(EsqlQueryRequest request, String client) throws ExecutionException,
11080
InterruptedException {
11181
// We want to send search to a specific node (we don't care which one) so that we could
11282
// collect the CCS telemetry from it later
@@ -116,7 +86,7 @@ private CCSTelemetrySnapshot getTelemetryFromQuery(EsqlQueryRequest request, Str
11686
if (client != null) {
11787
assertResponse(
11888
cluster(LOCAL_CLUSTER).client(nodeName)
119-
.filterWithHeader(Map.of(Task.X_ELASTIC_PRODUCT_ORIGIN_HTTP_HEADER, "kibana"))
89+
.filterWithHeader(Map.of(Task.X_ELASTIC_PRODUCT_ORIGIN_HTTP_HEADER, client))
12090
.execute(EsqlQueryAction.INSTANCE, request),
12191
Assert::assertNotNull
12292
);
@@ -127,12 +97,44 @@ private CCSTelemetrySnapshot getTelemetryFromQuery(EsqlQueryRequest request, Str
12797
return getTelemetrySnapshot(nodeName);
12898
}
12999

100+
protected CCSTelemetrySnapshot getTelemetryFromFailedQuery(String query) throws Exception {
101+
// We want to send search to a specific node (we don't care which one) so that we could
102+
// collect the CCS telemetry from it later
103+
String nodeName = cluster(LOCAL_CLUSTER).getRandomNodeName();
104+
EsqlQueryRequest request = EsqlQueryRequest.syncEsqlQueryRequest();
105+
request.query(query);
106+
request.pragmas(AbstractEsqlIntegTestCase.randomPragmas());
107+
request.columnar(randomBoolean());
108+
request.includeCCSMetadata(randomBoolean());
109+
110+
ExecutionException ee = expectThrows(
111+
ExecutionException.class,
112+
cluster(LOCAL_CLUSTER).client(nodeName).execute(EsqlQueryAction.INSTANCE, request)::get
113+
);
114+
assertNotNull(ee.getCause());
115+
116+
return getTelemetrySnapshot(nodeName);
117+
}
118+
130119
private CCSTelemetrySnapshot getTelemetrySnapshot(String nodeName) {
131120
var usage = cluster(LOCAL_CLUSTER).getInstance(UsageService.class, nodeName);
132121
return usage.getEsqlUsageHolder().getCCSTelemetrySnapshot();
133122
}
134123

135-
Map<String, Object> setupClusters() {
124+
@Override
125+
protected boolean reuseClusters() {
126+
return false;
127+
}
128+
129+
@Override
130+
protected List<String> remoteClusterAlias() {
131+
return List.of(REMOTE1, REMOTE2);
132+
}
133+
134+
@Rule
135+
public SkipUnavailableRule skipOverride = new SkipUnavailableRule(REMOTE1, REMOTE2);
136+
137+
protected Map<String, Object> setupClusters() {
136138
int numShardsLocal = randomIntBetween(1, 5);
137139
populateLocalIndices(LOCAL_INDEX, numShardsLocal);
138140

@@ -186,65 +188,15 @@ void populateRemoteIndices(String clusterAlias, String indexName, int numShards)
186188
@Override
187189
protected Collection<Class<? extends Plugin>> nodePlugins(String clusterAlias) {
188190
List<Class<? extends Plugin>> plugins = new ArrayList<>(super.nodePlugins(clusterAlias));
189-
plugins.add(EsqlPlugin.class);
191+
plugins.add(EsqlPluginWithEnterpriseOrTrialLicense.class);
190192
plugins.add(CrossClustersQueryIT.InternalExchangePlugin.class);
191193
return plugins;
192194
}
193195

194-
public static class InternalExchangePlugin extends Plugin {
195-
@Override
196-
public List<Setting<?>> getSettings() {
197-
return List.of(
198-
Setting.timeSetting(
199-
ExchangeService.INACTIVE_SINKS_INTERVAL_SETTING,
200-
TimeValue.timeValueSeconds(30),
201-
Setting.Property.NodeScope
202-
)
203-
);
204-
}
205-
}
206-
207196
@Override
208197
protected Map<String, Boolean> skipUnavailableForRemoteClusters() {
209198
var map = skipOverride.getMap();
210199
LOGGER.info("Using skip_unavailable map: [{}]", map);
211200
return map;
212201
}
213-
214-
/**
215-
* Annotation to mark specific cluster in a test as not to be skipped when unavailable
216-
*/
217-
@Retention(RetentionPolicy.RUNTIME)
218-
@Target(ElementType.METHOD)
219-
@interface SkipOverride {
220-
String[] aliases();
221-
}
222-
223-
/**
224-
* Test rule to process skip annotations
225-
*/
226-
static class SkipUnavailableRule implements TestRule {
227-
private final Map<String, Boolean> skipMap;
228-
229-
SkipUnavailableRule(String... clusterAliases) {
230-
this.skipMap = Arrays.stream(clusterAliases).collect(Collectors.toMap(Function.identity(), alias -> true));
231-
}
232-
233-
public Map<String, Boolean> getMap() {
234-
return skipMap;
235-
}
236-
237-
@Override
238-
public Statement apply(Statement base, Description description) {
239-
// Check for annotation named "SkipOverride" and set the overrides accordingly
240-
var aliases = description.getAnnotation(SkipOverride.class);
241-
if (aliases != null) {
242-
for (String alias : aliases.aliases()) {
243-
skipMap.put(alias, false);
244-
}
245-
}
246-
return base;
247-
}
248-
249-
}
250202
}

0 commit comments

Comments
 (0)