Skip to content

Commit 15d1e70

Browse files
committed
Tests- added helper methods to ESRestTestCase for checking warnings (#36443)
Added helper methods to ESRestTestCase for checking warnings in mixed and current-version-only clusters. This is supported by a new VersionSpecificWarningsHandler class with associated unit test. Closes #36251
1 parent ab5a11c commit 15d1e70

File tree

3 files changed

+151
-3
lines changed

3 files changed

+151
-3
lines changed

client/rest-high-level/src/test/java/org/elasticsearch/client/ESRestHighLevelClientTestCase.java

+11-3
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,22 @@ protected static RestHighLevelClient highLevelClient() {
7676
*/
7777
protected static <Req, Resp> Resp execute(Req request, SyncMethod<Req, Resp> syncMethod,
7878
AsyncMethod<Req, Resp> asyncMethod) throws IOException {
79+
return execute(request, syncMethod, asyncMethod, RequestOptions.DEFAULT);
80+
}
81+
82+
/**
83+
* Executes the provided request using either the sync method or its async variant, both provided as functions
84+
*/
85+
protected static <Req, Resp> Resp execute(Req request, SyncMethod<Req, Resp> syncMethod,
86+
AsyncMethod<Req, Resp> asyncMethod, RequestOptions options) throws IOException {
7987
if (randomBoolean()) {
80-
return syncMethod.execute(request, RequestOptions.DEFAULT);
88+
return syncMethod.execute(request, options);
8189
} else {
8290
PlainActionFuture<Resp> future = PlainActionFuture.newFuture();
83-
asyncMethod.execute(request, RequestOptions.DEFAULT, future);
91+
asyncMethod.execute(request, options, future);
8492
return future.actionGet();
8593
}
86-
}
94+
}
8795

8896
/**
8997
* Executes the provided request using either the sync method or its async

test/framework/src/main/java/org/elasticsearch/test/rest/ESRestTestCase.java

+70
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,13 @@
2929
import org.elasticsearch.Version;
3030
import org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksAction;
3131
import org.elasticsearch.client.Request;
32+
import org.elasticsearch.client.RequestOptions;
33+
import org.elasticsearch.client.RequestOptions.Builder;
3234
import org.elasticsearch.client.Response;
3335
import org.elasticsearch.client.ResponseException;
3436
import org.elasticsearch.client.RestClient;
3537
import org.elasticsearch.client.RestClientBuilder;
38+
import org.elasticsearch.client.WarningsHandler;
3639
import org.elasticsearch.common.CheckedRunnable;
3740
import org.elasticsearch.common.Strings;
3841
import org.elasticsearch.common.io.PathUtils;
@@ -68,12 +71,14 @@
6871
import java.security.NoSuchAlgorithmException;
6972
import java.security.cert.CertificateException;
7073
import java.util.ArrayList;
74+
import java.util.Arrays;
7175
import java.util.HashSet;
7276
import java.util.List;
7377
import java.util.Map;
7478
import java.util.Set;
7579
import java.util.TreeSet;
7680
import java.util.concurrent.TimeUnit;
81+
import java.util.function.Consumer;
7782
import java.util.function.Predicate;
7883

7984
import static java.util.Collections.sort;
@@ -176,6 +181,71 @@ public void initClient() throws IOException {
176181
assert hasXPack != null;
177182
assert nodeVersions != null;
178183
}
184+
185+
/**
186+
* Helper class to check warnings in REST responses with sensitivity to versions
187+
* used in the target cluster.
188+
*/
189+
public static class VersionSensitiveWarningsHandler implements WarningsHandler {
190+
Set<String> requiredSameVersionClusterWarnings = new HashSet<>();
191+
Set<String> allowedWarnings = new HashSet<>();
192+
final Set<Version> testNodeVersions;
193+
194+
public VersionSensitiveWarningsHandler(Set<Version> nodeVersions) {
195+
this.testNodeVersions = nodeVersions;
196+
}
197+
198+
/**
199+
* Adds to the set of warnings that are all required in responses if the cluster
200+
* is formed from nodes all running the exact same version as the client.
201+
* @param requiredWarnings a set of required warnings
202+
*/
203+
public void current(String... requiredWarnings) {
204+
requiredSameVersionClusterWarnings.addAll(Arrays.asList(requiredWarnings));
205+
}
206+
207+
/**
208+
* Adds to the set of warnings that are permissible (but not required) when running
209+
* in mixed-version clusters or those that differ in version from the test client.
210+
* @param allowedWarnings optional warnings that will be ignored if received
211+
*/
212+
public void compatible(String... allowedWarnings) {
213+
this.allowedWarnings.addAll(Arrays.asList(allowedWarnings));
214+
}
215+
216+
@Override
217+
public boolean warningsShouldFailRequest(List<String> warnings) {
218+
if (isExclusivelyTargetingCurrentVersionCluster()) {
219+
// absolute equality required in expected and actual.
220+
Set<String> actual = new HashSet<>(warnings);
221+
return false == requiredSameVersionClusterWarnings.equals(actual);
222+
} else {
223+
// Some known warnings can safely be ignored
224+
for (String actualWarning : warnings) {
225+
if (false == allowedWarnings.contains(actualWarning) &&
226+
false == requiredSameVersionClusterWarnings.contains(actualWarning)) {
227+
return true;
228+
}
229+
}
230+
return false;
231+
}
232+
}
233+
234+
private boolean isExclusivelyTargetingCurrentVersionCluster() {
235+
assertFalse("Node versions running in the cluster are missing", testNodeVersions.isEmpty());
236+
return testNodeVersions.size() == 1 &&
237+
testNodeVersions.iterator().next().equals(Version.CURRENT);
238+
}
239+
240+
}
241+
242+
public static RequestOptions expectVersionSpecificWarnings(Consumer<VersionSensitiveWarningsHandler> expectationsSetter) {
243+
Builder builder = RequestOptions.DEFAULT.toBuilder();
244+
VersionSensitiveWarningsHandler warningsHandler = new VersionSensitiveWarningsHandler(nodeVersions);
245+
expectationsSetter.accept(warningsHandler);
246+
builder.setWarningsHandler(warningsHandler);
247+
return builder.build();
248+
}
179249

180250
/**
181251
* Construct an HttpHost from the given host and port
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.test.rest;
21+
22+
import org.elasticsearch.Version;
23+
import org.elasticsearch.client.WarningsHandler;
24+
import org.elasticsearch.test.ESTestCase;
25+
import org.elasticsearch.test.rest.ESRestTestCase.VersionSensitiveWarningsHandler;
26+
27+
import java.io.IOException;
28+
import java.util.Arrays;
29+
import java.util.Collections;
30+
import java.util.HashSet;
31+
import java.util.Set;
32+
import java.util.function.Consumer;
33+
34+
public class VersionSensitiveWarningsHandlerTests extends ESTestCase {
35+
36+
public void testSameVersionCluster() throws IOException {
37+
Set<Version> nodeVersions= new HashSet<>();
38+
nodeVersions.add(Version.CURRENT);
39+
WarningsHandler handler = expectVersionSpecificWarnings(nodeVersions, (v)->{
40+
v.current("expectedCurrent1");
41+
});
42+
assertFalse(handler.warningsShouldFailRequest(Arrays.asList("expectedCurrent1")));
43+
assertTrue(handler.warningsShouldFailRequest(Arrays.asList("expectedCurrent1", "unexpected")));
44+
assertTrue(handler.warningsShouldFailRequest(Collections.emptyList()));
45+
46+
}
47+
public void testMixedVersionCluster() throws IOException {
48+
Set<Version> nodeVersions= new HashSet<>();
49+
nodeVersions.add(Version.CURRENT);
50+
nodeVersions.add(Version.CURRENT.minimumIndexCompatibilityVersion());
51+
WarningsHandler handler = expectVersionSpecificWarnings(nodeVersions, (v)->{
52+
v.current("expectedCurrent1");
53+
v.compatible("Expected legacy warning");
54+
});
55+
assertFalse(handler.warningsShouldFailRequest(Arrays.asList("expectedCurrent1")));
56+
assertFalse(handler.warningsShouldFailRequest(Arrays.asList("Expected legacy warning")));
57+
assertFalse(handler.warningsShouldFailRequest(Arrays.asList("expectedCurrent1", "Expected legacy warning")));
58+
assertTrue(handler.warningsShouldFailRequest(Arrays.asList("expectedCurrent1", "Unexpected legacy warning")));
59+
assertTrue(handler.warningsShouldFailRequest(Arrays.asList("Unexpected legacy warning")));
60+
assertFalse(handler.warningsShouldFailRequest(Collections.emptyList()));
61+
}
62+
63+
private static WarningsHandler expectVersionSpecificWarnings(Set<Version> nodeVersions,
64+
Consumer<VersionSensitiveWarningsHandler> expectationsSetter) {
65+
//Based on EsRestTestCase.expectVersionSpecificWarnings helper method but without ESRestTestCase dependency
66+
VersionSensitiveWarningsHandler warningsHandler = new VersionSensitiveWarningsHandler(nodeVersions);
67+
expectationsSetter.accept(warningsHandler);
68+
return warningsHandler;
69+
}
70+
}

0 commit comments

Comments
 (0)