Skip to content

Commit

Permalink
Tests- added helper methods to ESRestTestCase for checking warnings (#…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
markharwood committed Dec 11, 2018
1 parent eead8a1 commit a9eccbc
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,22 @@ protected static RestHighLevelClient highLevelClient() {
*/
protected static <Req, Resp> Resp execute(Req request, SyncMethod<Req, Resp> syncMethod,
AsyncMethod<Req, Resp> asyncMethod) throws IOException {
return execute(request, syncMethod, asyncMethod, RequestOptions.DEFAULT);
}

/**
* Executes the provided request using either the sync method or its async variant, both provided as functions
*/
protected static <Req, Resp> Resp execute(Req request, SyncMethod<Req, Resp> syncMethod,
AsyncMethod<Req, Resp> asyncMethod, RequestOptions options) throws IOException {
if (randomBoolean()) {
return syncMethod.execute(request, RequestOptions.DEFAULT);
return syncMethod.execute(request, options);
} else {
PlainActionFuture<Resp> future = PlainActionFuture.newFuture();
asyncMethod.execute(request, RequestOptions.DEFAULT, future);
asyncMethod.execute(request, options, future);
return future.actionGet();
}
}
}

/**
* Executes the provided request using either the sync method or its async
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@
import org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksAction;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RequestOptions.Builder;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.WarningsHandler;
import org.elasticsearch.common.CheckedRunnable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.PathUtils;
Expand Down Expand Up @@ -69,12 +71,14 @@
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Predicate;

import static java.util.Collections.sort;
Expand Down Expand Up @@ -177,6 +181,71 @@ public void initClient() throws IOException {
assert hasXPack != null;
assert nodeVersions != null;
}

/**
* Helper class to check warnings in REST responses with sensitivity to versions
* used in the target cluster.
*/
public static class VersionSensitiveWarningsHandler implements WarningsHandler {
Set<String> requiredSameVersionClusterWarnings = new HashSet<>();
Set<String> allowedWarnings = new HashSet<>();
final Set<Version> testNodeVersions;

public VersionSensitiveWarningsHandler(Set<Version> nodeVersions) {
this.testNodeVersions = nodeVersions;
}

/**
* Adds to the set of warnings that are all required in responses if the cluster
* is formed from nodes all running the exact same version as the client.
* @param requiredWarnings a set of required warnings
*/
public void current(String... requiredWarnings) {
requiredSameVersionClusterWarnings.addAll(Arrays.asList(requiredWarnings));
}

/**
* Adds to the set of warnings that are permissible (but not required) when running
* in mixed-version clusters or those that differ in version from the test client.
* @param allowedWarnings optional warnings that will be ignored if received
*/
public void compatible(String... allowedWarnings) {
this.allowedWarnings.addAll(Arrays.asList(allowedWarnings));
}

@Override
public boolean warningsShouldFailRequest(List<String> warnings) {
if (isExclusivelyTargetingCurrentVersionCluster()) {
// absolute equality required in expected and actual.
Set<String> actual = new HashSet<>(warnings);
return false == requiredSameVersionClusterWarnings.equals(actual);
} else {
// Some known warnings can safely be ignored
for (String actualWarning : warnings) {
if (false == allowedWarnings.contains(actualWarning) &&
false == requiredSameVersionClusterWarnings.contains(actualWarning)) {
return true;
}
}
return false;
}
}

private boolean isExclusivelyTargetingCurrentVersionCluster() {
assertFalse("Node versions running in the cluster are missing", testNodeVersions.isEmpty());
return testNodeVersions.size() == 1 &&
testNodeVersions.iterator().next().equals(Version.CURRENT);
}

}

public static RequestOptions expectVersionSpecificWarnings(Consumer<VersionSensitiveWarningsHandler> expectationsSetter) {
Builder builder = RequestOptions.DEFAULT.toBuilder();
VersionSensitiveWarningsHandler warningsHandler = new VersionSensitiveWarningsHandler(nodeVersions);
expectationsSetter.accept(warningsHandler);
builder.setWarningsHandler(warningsHandler);
return builder.build();
}

/**
* Construct an HttpHost from the given host and port
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.elasticsearch.test.rest;

import org.elasticsearch.Version;
import org.elasticsearch.client.WarningsHandler;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.rest.ESRestTestCase.VersionSensitiveWarningsHandler;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Consumer;

public class VersionSensitiveWarningsHandlerTests extends ESTestCase {

public void testSameVersionCluster() throws IOException {
Set<Version> nodeVersions= new HashSet<>();
nodeVersions.add(Version.CURRENT);
WarningsHandler handler = expectVersionSpecificWarnings(nodeVersions, (v)->{
v.current("expectedCurrent1");
});
assertFalse(handler.warningsShouldFailRequest(Arrays.asList("expectedCurrent1")));
assertTrue(handler.warningsShouldFailRequest(Arrays.asList("expectedCurrent1", "unexpected")));
assertTrue(handler.warningsShouldFailRequest(Collections.emptyList()));

}
public void testMixedVersionCluster() throws IOException {
Set<Version> nodeVersions= new HashSet<>();
nodeVersions.add(Version.CURRENT);
nodeVersions.add(Version.CURRENT.minimumIndexCompatibilityVersion());
WarningsHandler handler = expectVersionSpecificWarnings(nodeVersions, (v)->{
v.current("expectedCurrent1");
v.compatible("Expected legacy warning");
});
assertFalse(handler.warningsShouldFailRequest(Arrays.asList("expectedCurrent1")));
assertFalse(handler.warningsShouldFailRequest(Arrays.asList("Expected legacy warning")));
assertFalse(handler.warningsShouldFailRequest(Arrays.asList("expectedCurrent1", "Expected legacy warning")));
assertTrue(handler.warningsShouldFailRequest(Arrays.asList("expectedCurrent1", "Unexpected legacy warning")));
assertTrue(handler.warningsShouldFailRequest(Arrays.asList("Unexpected legacy warning")));
assertFalse(handler.warningsShouldFailRequest(Collections.emptyList()));
}

private static WarningsHandler expectVersionSpecificWarnings(Set<Version> nodeVersions,
Consumer<VersionSensitiveWarningsHandler> expectationsSetter) {
//Based on EsRestTestCase.expectVersionSpecificWarnings helper method but without ESRestTestCase dependency
VersionSensitiveWarningsHandler warningsHandler = new VersionSensitiveWarningsHandler(nodeVersions);
expectationsSetter.accept(warningsHandler);
return warningsHandler;
}
}

0 comments on commit a9eccbc

Please sign in to comment.