mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-04-25 07:37:19 -04:00
Replace Version with String in YAML framework, pushing Version parsing where is actually needed (#103311)
* Pushing down node versions as strings Deferring Version parsing to the actual places where a minimum node version/common cluster version is needed; eventually this will be completely lazy and/or replaced by other checks (e.g. features). Combine versions, oses and features in multi-cluster YAML test contexts.
This commit is contained in:
parent
28362cd9b4
commit
cea88cbeec
11 changed files with 263 additions and 231 deletions
|
@ -16,7 +16,6 @@ import org.apache.http.HttpHost;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.lucene.tests.util.TimeUnits;
|
import org.apache.lucene.tests.util.TimeUnits;
|
||||||
import org.elasticsearch.Version;
|
|
||||||
import org.elasticsearch.client.NodeSelector;
|
import org.elasticsearch.client.NodeSelector;
|
||||||
import org.elasticsearch.client.Request;
|
import org.elasticsearch.client.Request;
|
||||||
import org.elasticsearch.client.Response;
|
import org.elasticsearch.client.Response;
|
||||||
|
@ -30,6 +29,7 @@ import org.elasticsearch.test.cluster.FeatureFlag;
|
||||||
import org.elasticsearch.test.cluster.local.LocalClusterConfigProvider;
|
import org.elasticsearch.test.cluster.local.LocalClusterConfigProvider;
|
||||||
import org.elasticsearch.test.rest.ESRestTestCase;
|
import org.elasticsearch.test.rest.ESRestTestCase;
|
||||||
import org.elasticsearch.test.rest.ObjectPath;
|
import org.elasticsearch.test.rest.ObjectPath;
|
||||||
|
import org.elasticsearch.test.rest.TestFeatureService;
|
||||||
import org.elasticsearch.test.rest.yaml.restspec.ClientYamlSuiteRestApi;
|
import org.elasticsearch.test.rest.yaml.restspec.ClientYamlSuiteRestApi;
|
||||||
import org.elasticsearch.test.rest.yaml.restspec.ClientYamlSuiteRestSpec;
|
import org.elasticsearch.test.rest.yaml.restspec.ClientYamlSuiteRestSpec;
|
||||||
import org.elasticsearch.test.rest.yaml.section.ClientYamlTestSection;
|
import org.elasticsearch.test.rest.yaml.section.ClientYamlTestSection;
|
||||||
|
@ -45,12 +45,15 @@ import org.junit.rules.RuleChain;
|
||||||
import org.junit.rules.TestRule;
|
import org.junit.rules.TestRule;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.UncheckedIOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.BiPredicate;
|
import java.util.function.BiPredicate;
|
||||||
import java.util.function.Predicate;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static java.util.Collections.unmodifiableList;
|
import static java.util.Collections.unmodifiableList;
|
||||||
|
|
||||||
|
@ -286,29 +289,55 @@ public class CcsCommonYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
|
||||||
protected ClientYamlTestExecutionContext createRestTestExecutionContext(
|
protected ClientYamlTestExecutionContext createRestTestExecutionContext(
|
||||||
ClientYamlTestCandidate clientYamlTestCandidate,
|
ClientYamlTestCandidate clientYamlTestCandidate,
|
||||||
ClientYamlTestClient clientYamlTestClient,
|
ClientYamlTestClient clientYamlTestClient,
|
||||||
final Version esVersion,
|
final Set<String> nodesVersions,
|
||||||
final Predicate<String> clusterFeaturesPredicate,
|
final TestFeatureService testFeatureService,
|
||||||
final String os
|
final Set<String> osSet
|
||||||
) {
|
) {
|
||||||
// depending on the API called, we either return the client running against the "write" or the "search" cluster here
|
try {
|
||||||
|
// Ensure the test specific initialization is run by calling it explicitly (@Before annotations on base-derived class may
|
||||||
// TODO: reconcile and provide unified features, os, version(s), based on both clientYamlTestClient and searchYamlTestClient
|
// be called in a different order)
|
||||||
return new ClientYamlTestExecutionContext(
|
initSearchClient();
|
||||||
clientYamlTestCandidate,
|
// Reconcile and provide unified features, os, version(s), based on both clientYamlTestClient and searchYamlTestClient
|
||||||
clientYamlTestClient,
|
var searchOs = readOsFromNodesInfo(adminSearchClient);
|
||||||
randomizeContentType(),
|
var searchNodeVersions = readVersionsFromNodesInfo(adminSearchClient);
|
||||||
esVersion,
|
var semanticNodeVersions = searchNodeVersions.stream()
|
||||||
ESRestTestCase::clusterHasFeature,
|
.map(ESRestTestCase::parseLegacyVersion)
|
||||||
os
|
.flatMap(Optional::stream)
|
||||||
) {
|
.collect(Collectors.toSet());
|
||||||
protected ClientYamlTestClient clientYamlTestClient(String apiName) {
|
final TestFeatureService searchTestFeatureService = createTestFeatureService(
|
||||||
if (CCS_APIS.contains(apiName)) {
|
getClusterStateFeatures(adminSearchClient),
|
||||||
return searchYamlTestClient;
|
semanticNodeVersions
|
||||||
} else {
|
);
|
||||||
return super.clientYamlTestClient(apiName);
|
final TestFeatureService combinedTestFeatureService = new TestFeatureService() {
|
||||||
|
@Override
|
||||||
|
public boolean clusterHasFeature(String featureId) {
|
||||||
|
return testFeatureService.clusterHasFeature(featureId) && searchTestFeatureService.clusterHasFeature(featureId);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
final Set<String> combinedOsSet = Stream.concat(osSet.stream(), Stream.of(searchOs)).collect(Collectors.toSet());
|
||||||
|
final Set<String> combinedNodeVersions = Stream.concat(nodesVersions.stream(), searchNodeVersions.stream())
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
return new ClientYamlTestExecutionContext(
|
||||||
|
clientYamlTestCandidate,
|
||||||
|
clientYamlTestClient,
|
||||||
|
randomizeContentType(),
|
||||||
|
combinedNodeVersions,
|
||||||
|
combinedTestFeatureService,
|
||||||
|
combinedOsSet
|
||||||
|
) {
|
||||||
|
// depending on the API called, we either return the client running against the "write" or the "search" cluster here
|
||||||
|
protected ClientYamlTestClient clientYamlTestClient(String apiName) {
|
||||||
|
if (CCS_APIS.contains(apiName)) {
|
||||||
|
return searchYamlTestClient;
|
||||||
|
} else {
|
||||||
|
return super.clientYamlTestClient(apiName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new UncheckedIOException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
|
|
|
@ -15,7 +15,6 @@ import org.apache.http.HttpHost;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.lucene.tests.util.TimeUnits;
|
import org.apache.lucene.tests.util.TimeUnits;
|
||||||
import org.elasticsearch.Version;
|
|
||||||
import org.elasticsearch.client.Request;
|
import org.elasticsearch.client.Request;
|
||||||
import org.elasticsearch.client.RequestOptions;
|
import org.elasticsearch.client.RequestOptions;
|
||||||
import org.elasticsearch.client.Response;
|
import org.elasticsearch.client.Response;
|
||||||
|
@ -32,6 +31,7 @@ import org.elasticsearch.test.cluster.local.LocalClusterConfigProvider;
|
||||||
import org.elasticsearch.test.cluster.util.resource.Resource;
|
import org.elasticsearch.test.cluster.util.resource.Resource;
|
||||||
import org.elasticsearch.test.rest.ESRestTestCase;
|
import org.elasticsearch.test.rest.ESRestTestCase;
|
||||||
import org.elasticsearch.test.rest.ObjectPath;
|
import org.elasticsearch.test.rest.ObjectPath;
|
||||||
|
import org.elasticsearch.test.rest.TestFeatureService;
|
||||||
import org.elasticsearch.test.rest.yaml.CcsCommonYamlTestSuiteIT.TestCandidateAwareClient;
|
import org.elasticsearch.test.rest.yaml.CcsCommonYamlTestSuiteIT.TestCandidateAwareClient;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@ -44,8 +44,11 @@ import java.io.UncheckedIOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.function.Predicate;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static java.util.Collections.unmodifiableList;
|
import static java.util.Collections.unmodifiableList;
|
||||||
import static org.elasticsearch.test.rest.yaml.CcsCommonYamlTestSuiteIT.CCS_APIS;
|
import static org.elasticsearch.test.rest.yaml.CcsCommonYamlTestSuiteIT.CCS_APIS;
|
||||||
|
@ -271,29 +274,55 @@ public class RcsCcsCommonYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
|
||||||
protected ClientYamlTestExecutionContext createRestTestExecutionContext(
|
protected ClientYamlTestExecutionContext createRestTestExecutionContext(
|
||||||
ClientYamlTestCandidate clientYamlTestCandidate,
|
ClientYamlTestCandidate clientYamlTestCandidate,
|
||||||
ClientYamlTestClient clientYamlTestClient,
|
ClientYamlTestClient clientYamlTestClient,
|
||||||
final Version esVersion,
|
final Set<String> nodesVersions,
|
||||||
final Predicate<String> clusterFeaturesPredicate,
|
final TestFeatureService testFeatureService,
|
||||||
final String os
|
final Set<String> osSet
|
||||||
) {
|
) {
|
||||||
// depending on the API called, we either return the client running against the "write" or the "search" cluster here
|
try {
|
||||||
|
// Ensure the test specific initialization is run by calling it explicitly (@Before annotations on base-derived class may
|
||||||
// TODO: reconcile and provide unified features, os, version(s), based on both clientYamlTestClient and searchYamlTestClient
|
// be called in a different order)
|
||||||
return new ClientYamlTestExecutionContext(
|
initSearchClient();
|
||||||
clientYamlTestCandidate,
|
// Reconcile and provide unified features, os, version(s), based on both clientYamlTestClient and searchYamlTestClient
|
||||||
clientYamlTestClient,
|
var searchOs = readOsFromNodesInfo(adminSearchClient);
|
||||||
randomizeContentType(),
|
var searchNodeVersions = readVersionsFromNodesInfo(adminSearchClient);
|
||||||
esVersion,
|
var semanticNodeVersions = searchNodeVersions.stream()
|
||||||
ESRestTestCase::clusterHasFeature,
|
.map(ESRestTestCase::parseLegacyVersion)
|
||||||
os
|
.flatMap(Optional::stream)
|
||||||
) {
|
.collect(Collectors.toSet());
|
||||||
protected ClientYamlTestClient clientYamlTestClient(String apiName) {
|
final TestFeatureService searchTestFeatureService = createTestFeatureService(
|
||||||
if (CCS_APIS.contains(apiName)) {
|
getClusterStateFeatures(adminSearchClient),
|
||||||
return searchYamlTestClient;
|
semanticNodeVersions
|
||||||
} else {
|
);
|
||||||
return super.clientYamlTestClient(apiName);
|
final TestFeatureService combinedTestFeatureService = new TestFeatureService() {
|
||||||
|
@Override
|
||||||
|
public boolean clusterHasFeature(String featureId) {
|
||||||
|
return testFeatureService.clusterHasFeature(featureId) && searchTestFeatureService.clusterHasFeature(featureId);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
final Set<String> combinedOsSet = Stream.concat(osSet.stream(), Stream.of(searchOs)).collect(Collectors.toSet());
|
||||||
|
final Set<String> combinedNodeVersions = Stream.concat(nodesVersions.stream(), searchNodeVersions.stream())
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
return new ClientYamlTestExecutionContext(
|
||||||
|
clientYamlTestCandidate,
|
||||||
|
clientYamlTestClient,
|
||||||
|
randomizeContentType(),
|
||||||
|
combinedNodeVersions,
|
||||||
|
combinedTestFeatureService,
|
||||||
|
combinedOsSet
|
||||||
|
) {
|
||||||
|
// depending on the API called, we either return the client running against the "write" or the "search" cluster here
|
||||||
|
protected ClientYamlTestClient clientYamlTestClient(String apiName) {
|
||||||
|
if (CCS_APIS.contains(apiName)) {
|
||||||
|
return searchYamlTestClient;
|
||||||
|
} else {
|
||||||
|
return super.clientYamlTestClient(apiName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new UncheckedIOException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
|
|
|
@ -13,26 +13,27 @@ import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||||
import com.carrotsearch.randomizedtesting.annotations.TimeoutSuite;
|
import com.carrotsearch.randomizedtesting.annotations.TimeoutSuite;
|
||||||
|
|
||||||
import org.apache.lucene.tests.util.TimeUnits;
|
import org.apache.lucene.tests.util.TimeUnits;
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.test.rest.TestFeatureService;
|
||||||
import org.elasticsearch.test.rest.ESRestTestCase;
|
|
||||||
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||||
import org.elasticsearch.test.rest.yaml.ClientYamlTestClient;
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestClient;
|
||||||
import org.elasticsearch.test.rest.yaml.ClientYamlTestExecutionContext;
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestExecutionContext;
|
||||||
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
import java.util.function.Predicate;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@TimeoutSuite(millis = 5 * TimeUnits.MINUTE) // to account for slow as hell VMs
|
@TimeoutSuite(millis = 5 * TimeUnits.MINUTE) // to account for slow as hell VMs
|
||||||
public class MultiClusterSearchYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
|
public class MultiClusterSearchYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
|
||||||
|
|
||||||
private static Version remoteEsVersion = null;
|
private static String remoteEsVersion = null;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void determineRemoteClusterMinimumVersion() {
|
public static void readRemoteClusterVersion() {
|
||||||
String remoteClusterVersion = System.getProperty("tests.rest.remote_cluster_version");
|
String remoteClusterVersion = System.getProperty("tests.rest.remote_cluster_version");
|
||||||
if (remoteClusterVersion != null) {
|
if (remoteClusterVersion != null) {
|
||||||
remoteEsVersion = Version.fromString(remoteClusterVersion);
|
remoteEsVersion = remoteClusterVersion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,26 +41,32 @@ public class MultiClusterSearchYamlTestSuiteIT extends ESClientYamlSuiteTestCase
|
||||||
protected ClientYamlTestExecutionContext createRestTestExecutionContext(
|
protected ClientYamlTestExecutionContext createRestTestExecutionContext(
|
||||||
ClientYamlTestCandidate clientYamlTestCandidate,
|
ClientYamlTestCandidate clientYamlTestCandidate,
|
||||||
ClientYamlTestClient clientYamlTestClient,
|
ClientYamlTestClient clientYamlTestClient,
|
||||||
final Version esVersion,
|
final Set<String> nodesVersions,
|
||||||
final Predicate<String> clusterFeaturesPredicate,
|
final TestFeatureService testFeatureService,
|
||||||
final String os
|
final Set<String> osSet
|
||||||
) {
|
) {
|
||||||
/*
|
/*
|
||||||
* Since the esVersion is used to skip tests in ESClientYamlSuiteTestCase, we also take into account the
|
* Since the esVersion is used to skip tests in ESClientYamlSuiteTestCase, we also take into account the
|
||||||
* remote cluster version here and return it if it is lower than the local client version. This is used to
|
* remote cluster version here. This is used to skip tests if some feature isn't available on the remote cluster yet.
|
||||||
* skip tests if some feature isn't available on the remote cluster yet.
|
|
||||||
*/
|
*/
|
||||||
final Version commonEsVersion = remoteEsVersion != null && remoteEsVersion.before(esVersion) ? remoteEsVersion : esVersion;
|
final Set<String> commonVersions;
|
||||||
|
if (remoteEsVersion == null || nodesVersions.contains(remoteEsVersion)) {
|
||||||
// TODO: same for os and features
|
commonVersions = nodesVersions;
|
||||||
|
} else {
|
||||||
|
var versionsCopy = new HashSet<>(nodesVersions);
|
||||||
|
versionsCopy.add(remoteEsVersion);
|
||||||
|
commonVersions = Collections.unmodifiableSet(versionsCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: same for os and features. Better to do that once this test(s) have been migrated to the new ElasticsearchCluster-based
|
||||||
|
// framework. See CcsCommonYamlTestSuiteIT for example.
|
||||||
return new ClientYamlTestExecutionContext(
|
return new ClientYamlTestExecutionContext(
|
||||||
clientYamlTestCandidate,
|
clientYamlTestCandidate,
|
||||||
clientYamlTestClient,
|
clientYamlTestClient,
|
||||||
randomizeContentType(),
|
randomizeContentType(),
|
||||||
commonEsVersion,
|
commonVersions,
|
||||||
ESRestTestCase::clusterHasFeature,
|
testFeatureService,
|
||||||
os
|
osSet
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -337,7 +337,7 @@ public abstract class ESRestTestCase extends ESTestCase {
|
||||||
? List.of(new RestTestLegacyFeatures(), new ESRestTestCaseHistoricalFeatures())
|
? List.of(new RestTestLegacyFeatures(), new ESRestTestCaseHistoricalFeatures())
|
||||||
: List.of(new RestTestLegacyFeatures());
|
: List.of(new RestTestLegacyFeatures());
|
||||||
|
|
||||||
return new TestFeatureService(
|
return new ESRestTestFeatureService(
|
||||||
hasHistoricalFeaturesInformation,
|
hasHistoricalFeaturesInformation,
|
||||||
providers,
|
providers,
|
||||||
semanticNodeVersions,
|
semanticNodeVersions,
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||||
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.test.rest;
|
||||||
|
|
||||||
|
import org.elasticsearch.Version;
|
||||||
|
import org.elasticsearch.core.Strings;
|
||||||
|
import org.elasticsearch.features.FeatureData;
|
||||||
|
import org.elasticsearch.features.FeatureSpecification;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.NavigableMap;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
class ESRestTestFeatureService implements TestFeatureService {
|
||||||
|
private final Predicate<String> historicalFeaturesPredicate;
|
||||||
|
private final Set<String> clusterStateFeatures;
|
||||||
|
|
||||||
|
ESRestTestFeatureService(
|
||||||
|
boolean hasHistoricalFeaturesInformation,
|
||||||
|
List<? extends FeatureSpecification> specs,
|
||||||
|
Collection<Version> nodeVersions,
|
||||||
|
Set<String> clusterStateFeatures
|
||||||
|
) {
|
||||||
|
var minNodeVersion = nodeVersions.stream().min(Version::compareTo);
|
||||||
|
var featureData = FeatureData.createFromSpecifications(specs);
|
||||||
|
var historicalFeatures = featureData.getHistoricalFeatures();
|
||||||
|
var allHistoricalFeatures = historicalFeatures.lastEntry() == null ? Set.of() : historicalFeatures.lastEntry().getValue();
|
||||||
|
|
||||||
|
var errorMessage = hasHistoricalFeaturesInformation
|
||||||
|
? "Check the feature has been added to the correct FeatureSpecification in the relevant module or, if this is a "
|
||||||
|
+ "legacy feature used only in tests, to a test-only FeatureSpecification"
|
||||||
|
: "This test is running on the legacy test framework; historical features from production code will not be available."
|
||||||
|
+ " You need to port the test to the new test plugins in order to use historical features from production code."
|
||||||
|
+ " If this is a legacy feature used only in tests, you can add it to a test-only FeatureSpecification";
|
||||||
|
this.historicalFeaturesPredicate = minNodeVersion.<Predicate<String>>map(v -> featureId -> {
|
||||||
|
assert allHistoricalFeatures.contains(featureId) : Strings.format("Unknown historical feature %s: %s", featureId, errorMessage);
|
||||||
|
return hasHistoricalFeature(historicalFeatures, v, featureId);
|
||||||
|
}).orElse(featureId -> {
|
||||||
|
// We can safely assume that new non-semantic versions (serverless) support all historical features
|
||||||
|
assert allHistoricalFeatures.contains(featureId) : Strings.format("Unknown historical feature %s: %s", featureId, errorMessage);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
this.clusterStateFeatures = clusterStateFeatures;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasHistoricalFeature(NavigableMap<Version, Set<String>> historicalFeatures, Version version, String featureId) {
|
||||||
|
var features = historicalFeatures.floorEntry(version);
|
||||||
|
return features != null && features.getValue().contains(featureId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean clusterHasFeature(String featureId) {
|
||||||
|
if (clusterStateFeatures.contains(featureId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return historicalFeaturesPredicate.test(featureId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,58 +8,6 @@
|
||||||
|
|
||||||
package org.elasticsearch.test.rest;
|
package org.elasticsearch.test.rest;
|
||||||
|
|
||||||
import org.elasticsearch.Version;
|
public interface TestFeatureService {
|
||||||
import org.elasticsearch.core.Strings;
|
boolean clusterHasFeature(String featureId);
|
||||||
import org.elasticsearch.features.FeatureData;
|
|
||||||
import org.elasticsearch.features.FeatureSpecification;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.NavigableMap;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
public class TestFeatureService {
|
|
||||||
private final Predicate<String> historicalFeaturesPredicate;
|
|
||||||
private final Set<String> clusterStateFeatures;
|
|
||||||
|
|
||||||
TestFeatureService(
|
|
||||||
boolean hasHistoricalFeaturesInformation,
|
|
||||||
List<? extends FeatureSpecification> specs,
|
|
||||||
Collection<Version> nodeVersions,
|
|
||||||
Set<String> clusterStateFeatures
|
|
||||||
) {
|
|
||||||
var minNodeVersion = nodeVersions.stream().min(Version::compareTo);
|
|
||||||
var featureData = FeatureData.createFromSpecifications(specs);
|
|
||||||
var historicalFeatures = featureData.getHistoricalFeatures();
|
|
||||||
var allHistoricalFeatures = historicalFeatures.lastEntry() == null ? Set.of() : historicalFeatures.lastEntry().getValue();
|
|
||||||
|
|
||||||
var errorMessage = hasHistoricalFeaturesInformation
|
|
||||||
? "Check the feature has been added to the correct FeatureSpecification in the relevant module or, if this is a "
|
|
||||||
+ "legacy feature used only in tests, to a test-only FeatureSpecification"
|
|
||||||
: "This test is running on the legacy test framework; historical features from production code will not be available."
|
|
||||||
+ " You need to port the test to the new test plugins in order to use historical features from production code."
|
|
||||||
+ " If this is a legacy feature used only in tests, you can add it to a test-only FeatureSpecification";
|
|
||||||
this.historicalFeaturesPredicate = minNodeVersion.<Predicate<String>>map(v -> featureId -> {
|
|
||||||
assert allHistoricalFeatures.contains(featureId) : Strings.format("Unknown historical feature %s: %s", featureId, errorMessage);
|
|
||||||
return hasHistoricalFeature(historicalFeatures, v, featureId);
|
|
||||||
}).orElse(featureId -> {
|
|
||||||
// We can safely assume that new non-semantic versions (serverless) support all historical features
|
|
||||||
assert allHistoricalFeatures.contains(featureId) : Strings.format("Unknown historical feature %s: %s", featureId, errorMessage);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
this.clusterStateFeatures = clusterStateFeatures;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean hasHistoricalFeature(NavigableMap<Version, Set<String>> historicalFeatures, Version version, String featureId) {
|
|
||||||
var features = historicalFeatures.floorEntry(version);
|
|
||||||
return features != null && features.getValue().contains(featureId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean clusterHasFeature(String featureId) {
|
|
||||||
if (clusterStateFeatures.contains(featureId)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return historicalFeaturesPredicate.test(featureId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,8 @@ import org.apache.http.entity.ContentType;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.elasticsearch.Version;
|
|
||||||
import org.elasticsearch.client.NodeSelector;
|
import org.elasticsearch.client.NodeSelector;
|
||||||
import org.elasticsearch.common.VersionId;
|
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
import org.elasticsearch.test.rest.ESRestTestCase;
|
|
||||||
import org.elasticsearch.test.rest.Stash;
|
import org.elasticsearch.test.rest.Stash;
|
||||||
import org.elasticsearch.test.rest.TestFeatureService;
|
import org.elasticsearch.test.rest.TestFeatureService;
|
||||||
import org.elasticsearch.test.rest.yaml.restspec.ClientYamlSuiteRestApi;
|
import org.elasticsearch.test.rest.yaml.restspec.ClientYamlSuiteRestApi;
|
||||||
|
@ -33,10 +30,8 @@ import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.BiPredicate;
|
import java.util.function.BiPredicate;
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execution context passed across the REST tests.
|
* Execution context passed across the REST tests.
|
||||||
|
@ -56,43 +51,21 @@ public class ClientYamlTestExecutionContext {
|
||||||
|
|
||||||
private ClientYamlTestResponse response;
|
private ClientYamlTestResponse response;
|
||||||
|
|
||||||
private final Version esVersion;
|
private final Set<String> nodesVersions;
|
||||||
|
|
||||||
private final String os;
|
private final Set<String> osSet;
|
||||||
private final Predicate<String> clusterFeaturesPredicate;
|
private final TestFeatureService testFeatureService;
|
||||||
|
|
||||||
private final boolean randomizeContentType;
|
private final boolean randomizeContentType;
|
||||||
private final BiPredicate<ClientYamlSuiteRestApi, ClientYamlSuiteRestApi.Path> pathPredicate;
|
private final BiPredicate<ClientYamlSuiteRestApi, ClientYamlSuiteRestApi.Path> pathPredicate;
|
||||||
|
|
||||||
// TODO: this will become the ctor once work is done on serverless side and https://github.com/elastic/elasticsearch/pull/103311/
|
|
||||||
// has been merged
|
|
||||||
public ClientYamlTestExecutionContext(
|
public ClientYamlTestExecutionContext(
|
||||||
ClientYamlTestCandidate clientYamlTestCandidate,
|
ClientYamlTestCandidate clientYamlTestCandidate,
|
||||||
ClientYamlTestClient clientYamlTestClient,
|
ClientYamlTestClient clientYamlTestClient,
|
||||||
boolean randomizeContentType,
|
boolean randomizeContentType,
|
||||||
final Set<String> nodesVersions,
|
final Set<String> nodesVersions,
|
||||||
final TestFeatureService testFeatureService,
|
final TestFeatureService testFeatureService,
|
||||||
final Set<String> osList,
|
final Set<String> osSet
|
||||||
BiPredicate<ClientYamlSuiteRestApi, ClientYamlSuiteRestApi.Path> pathPredicate
|
|
||||||
) {
|
|
||||||
this(
|
|
||||||
clientYamlTestCandidate,
|
|
||||||
clientYamlTestClient,
|
|
||||||
randomizeContentType,
|
|
||||||
getEsVersion(nodesVersions),
|
|
||||||
testFeatureService::clusterHasFeature,
|
|
||||||
osList.iterator().next(),
|
|
||||||
pathPredicate
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClientYamlTestExecutionContext(
|
|
||||||
ClientYamlTestCandidate clientYamlTestCandidate,
|
|
||||||
ClientYamlTestClient clientYamlTestClient,
|
|
||||||
boolean randomizeContentType,
|
|
||||||
final Set<String> nodesVersions,
|
|
||||||
final TestFeatureService testFeatureService,
|
|
||||||
final Set<String> osList
|
|
||||||
) {
|
) {
|
||||||
this(
|
this(
|
||||||
clientYamlTestCandidate,
|
clientYamlTestCandidate,
|
||||||
|
@ -100,56 +73,26 @@ public class ClientYamlTestExecutionContext {
|
||||||
randomizeContentType,
|
randomizeContentType,
|
||||||
nodesVersions,
|
nodesVersions,
|
||||||
testFeatureService,
|
testFeatureService,
|
||||||
osList,
|
osSet,
|
||||||
(ignoreApi, ignorePath) -> true
|
(ignoreApi, ignorePath) -> true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
static Version getEsVersion(Set<String> nodesVersions) {
|
|
||||||
return nodesVersions.stream()
|
|
||||||
.map(ESRestTestCase::parseLegacyVersion)
|
|
||||||
.flatMap(Optional::stream)
|
|
||||||
.min(VersionId::compareTo)
|
|
||||||
.orElse(Version.CURRENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public ClientYamlTestExecutionContext(
|
public ClientYamlTestExecutionContext(
|
||||||
ClientYamlTestCandidate clientYamlTestCandidate,
|
ClientYamlTestCandidate clientYamlTestCandidate,
|
||||||
ClientYamlTestClient clientYamlTestClient,
|
ClientYamlTestClient clientYamlTestClient,
|
||||||
boolean randomizeContentType,
|
boolean randomizeContentType,
|
||||||
final Version esVersion,
|
final Set<String> nodesVersions,
|
||||||
final Predicate<String> clusterFeaturesPredicate,
|
final TestFeatureService testFeatureService,
|
||||||
final String os
|
final Set<String> osSet,
|
||||||
) {
|
|
||||||
this(
|
|
||||||
clientYamlTestCandidate,
|
|
||||||
clientYamlTestClient,
|
|
||||||
randomizeContentType,
|
|
||||||
esVersion,
|
|
||||||
clusterFeaturesPredicate,
|
|
||||||
os,
|
|
||||||
(ignoreApi, ignorePath) -> true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public ClientYamlTestExecutionContext(
|
|
||||||
ClientYamlTestCandidate clientYamlTestCandidate,
|
|
||||||
ClientYamlTestClient clientYamlTestClient,
|
|
||||||
boolean randomizeContentType,
|
|
||||||
final Version esVersion,
|
|
||||||
final Predicate<String> clusterFeaturesPredicate,
|
|
||||||
final String os,
|
|
||||||
BiPredicate<ClientYamlSuiteRestApi, ClientYamlSuiteRestApi.Path> pathPredicate
|
BiPredicate<ClientYamlSuiteRestApi, ClientYamlSuiteRestApi.Path> pathPredicate
|
||||||
) {
|
) {
|
||||||
this.clientYamlTestClient = clientYamlTestClient;
|
this.clientYamlTestClient = clientYamlTestClient;
|
||||||
this.clientYamlTestCandidate = clientYamlTestCandidate;
|
this.clientYamlTestCandidate = clientYamlTestCandidate;
|
||||||
this.randomizeContentType = randomizeContentType;
|
this.randomizeContentType = randomizeContentType;
|
||||||
this.esVersion = esVersion;
|
this.nodesVersions = nodesVersions;
|
||||||
this.clusterFeaturesPredicate = clusterFeaturesPredicate;
|
this.testFeatureService = testFeatureService;
|
||||||
this.os = os;
|
this.osSet = osSet;
|
||||||
this.pathPredicate = pathPredicate;
|
this.pathPredicate = pathPredicate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,14 +247,14 @@ public class ClientYamlTestExecutionContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the version of the oldest node in the cluster
|
* @return the distinct node versions running in the cluster
|
||||||
*/
|
*/
|
||||||
public Version esVersion() {
|
public Set<String> nodesVersions() {
|
||||||
return esVersion;
|
return nodesVersions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String os() {
|
public String os() {
|
||||||
return os;
|
return osSet.iterator().next();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClientYamlTestCandidate getClientYamlTestCandidate() {
|
public ClientYamlTestCandidate getClientYamlTestCandidate() {
|
||||||
|
@ -319,6 +262,6 @@ public class ClientYamlTestExecutionContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean clusterHasFeature(String featureId) {
|
public boolean clusterHasFeature(String featureId) {
|
||||||
return clusterFeaturesPredicate.test(featureId);
|
return testFeatureService.clusterHasFeature(featureId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.elasticsearch.client.WarningsHandler;
|
||||||
import org.elasticsearch.client.sniff.ElasticsearchNodesSniffer;
|
import org.elasticsearch.client.sniff.ElasticsearchNodesSniffer;
|
||||||
import org.elasticsearch.cluster.metadata.IndexMetadata;
|
import org.elasticsearch.cluster.metadata.IndexMetadata;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
|
import org.elasticsearch.common.VersionId;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
||||||
import org.elasticsearch.core.IOUtils;
|
import org.elasticsearch.core.IOUtils;
|
||||||
|
@ -61,10 +62,8 @@ import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.function.Predicate;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.elasticsearch.test.rest.yaml.ClientYamlTestExecutionContext.getEsVersion;
|
|
||||||
import static org.elasticsearch.xcontent.XContentFactory.jsonBuilder;
|
import static org.elasticsearch.xcontent.XContentFactory.jsonBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,6 +143,8 @@ public abstract class ESClientYamlSuiteTestCase extends ESRestTestCase {
|
||||||
final Set<String> nodesVersions = getCachedNodesVersions();
|
final Set<String> nodesVersions = getCachedNodesVersions();
|
||||||
final String os = readOsFromNodesInfo(adminClient());
|
final String os = readOsFromNodesInfo(adminClient());
|
||||||
|
|
||||||
|
logger.info("initializing client, node versions [{}], hosts {}, os [{}]", nodesVersions, hosts, os);
|
||||||
|
|
||||||
var semanticNodeVersions = nodesVersions.stream()
|
var semanticNodeVersions = nodesVersions.stream()
|
||||||
.map(ESRestTestCase::parseLegacyVersion)
|
.map(ESRestTestCase::parseLegacyVersion)
|
||||||
.flatMap(Optional::stream)
|
.flatMap(Optional::stream)
|
||||||
|
@ -199,32 +200,15 @@ public abstract class ESClientYamlSuiteTestCase extends ESRestTestCase {
|
||||||
ClientYamlTestClient clientYamlTestClient,
|
ClientYamlTestClient clientYamlTestClient,
|
||||||
final Set<String> nodesVersions,
|
final Set<String> nodesVersions,
|
||||||
final TestFeatureService testFeatureService,
|
final TestFeatureService testFeatureService,
|
||||||
final Set<String> osList
|
final Set<String> osSet
|
||||||
) {
|
|
||||||
return createRestTestExecutionContext(
|
|
||||||
clientYamlTestCandidate,
|
|
||||||
clientYamlTestClient,
|
|
||||||
getEsVersion(nodesVersions),
|
|
||||||
testFeatureService::clusterHasFeature,
|
|
||||||
osList.iterator().next()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
protected ClientYamlTestExecutionContext createRestTestExecutionContext(
|
|
||||||
ClientYamlTestCandidate clientYamlTestCandidate,
|
|
||||||
ClientYamlTestClient clientYamlTestClient,
|
|
||||||
final Version esVersion,
|
|
||||||
final Predicate<String> clusterFeaturesPredicate,
|
|
||||||
final String os
|
|
||||||
) {
|
) {
|
||||||
return new ClientYamlTestExecutionContext(
|
return new ClientYamlTestExecutionContext(
|
||||||
clientYamlTestCandidate,
|
clientYamlTestCandidate,
|
||||||
clientYamlTestClient,
|
clientYamlTestClient,
|
||||||
randomizeContentType(),
|
randomizeContentType(),
|
||||||
esVersion,
|
nodesVersions,
|
||||||
clusterFeaturesPredicate,
|
testFeatureService,
|
||||||
os
|
osSet
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,20 +447,31 @@ public abstract class ESClientYamlSuiteTestCase extends ESRestTestCase {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to extract the minimum node version. Assume CURRENT if nodes have non-semantic versions
|
||||||
|
// TODO: after https://github.com/elastic/elasticsearch/pull/103404 is merged, we can push this logic into SkipVersionContext.
|
||||||
|
// This way will have version parsing only when we actually have to skip on a version, we can remove the default and throw an
|
||||||
|
// IllegalArgumentException instead (attempting to skip on version where version is not semantic)
|
||||||
|
var oldestNodeVersion = restTestExecutionContext.nodesVersions()
|
||||||
|
.stream()
|
||||||
|
.map(ESRestTestCase::parseLegacyVersion)
|
||||||
|
.flatMap(Optional::stream)
|
||||||
|
.min(VersionId::compareTo)
|
||||||
|
.orElse(Version.CURRENT);
|
||||||
|
|
||||||
// skip test if the whole suite (yaml file) is disabled
|
// skip test if the whole suite (yaml file) is disabled
|
||||||
assumeFalse(
|
assumeFalse(
|
||||||
testCandidate.getSetupSection().getSkipSection().getSkipMessage(testCandidate.getSuitePath()),
|
testCandidate.getSetupSection().getSkipSection().getSkipMessage(testCandidate.getSuitePath()),
|
||||||
testCandidate.getSetupSection().getSkipSection().skip(restTestExecutionContext.esVersion())
|
testCandidate.getSetupSection().getSkipSection().skip(oldestNodeVersion)
|
||||||
);
|
);
|
||||||
// skip test if the whole suite (yaml file) is disabled
|
// skip test if the whole suite (yaml file) is disabled
|
||||||
assumeFalse(
|
assumeFalse(
|
||||||
testCandidate.getTeardownSection().getSkipSection().getSkipMessage(testCandidate.getSuitePath()),
|
testCandidate.getTeardownSection().getSkipSection().getSkipMessage(testCandidate.getSuitePath()),
|
||||||
testCandidate.getTeardownSection().getSkipSection().skip(restTestExecutionContext.esVersion())
|
testCandidate.getTeardownSection().getSkipSection().skip(oldestNodeVersion)
|
||||||
);
|
);
|
||||||
// skip test if test section is disabled
|
// skip test if test section is disabled
|
||||||
assumeFalse(
|
assumeFalse(
|
||||||
testCandidate.getTestSection().getSkipSection().getSkipMessage(testCandidate.getTestPath()),
|
testCandidate.getTestSection().getSkipSection().getSkipMessage(testCandidate.getTestPath()),
|
||||||
testCandidate.getTestSection().getSkipSection().skip(restTestExecutionContext.esVersion())
|
testCandidate.getTestSection().getSkipSection().skip(oldestNodeVersion)
|
||||||
);
|
);
|
||||||
// skip test if os is excluded
|
// skip test if os is excluded
|
||||||
assumeFalse(
|
assumeFalse(
|
||||||
|
|
|
@ -17,10 +17,12 @@ import org.elasticsearch.client.Node;
|
||||||
import org.elasticsearch.client.NodeSelector;
|
import org.elasticsearch.client.NodeSelector;
|
||||||
import org.elasticsearch.common.ParsingException;
|
import org.elasticsearch.common.ParsingException;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
|
import org.elasticsearch.common.VersionId;
|
||||||
import org.elasticsearch.common.logging.HeaderWarning;
|
import org.elasticsearch.common.logging.HeaderWarning;
|
||||||
import org.elasticsearch.core.Tuple;
|
import org.elasticsearch.core.Tuple;
|
||||||
import org.elasticsearch.core.UpdateForV9;
|
import org.elasticsearch.core.UpdateForV9;
|
||||||
import org.elasticsearch.rest.action.admin.indices.RestPutIndexTemplateAction;
|
import org.elasticsearch.rest.action.admin.indices.RestPutIndexTemplateAction;
|
||||||
|
import org.elasticsearch.test.rest.ESRestTestCase;
|
||||||
import org.elasticsearch.test.rest.RestTestLegacyFeatures;
|
import org.elasticsearch.test.rest.RestTestLegacyFeatures;
|
||||||
import org.elasticsearch.test.rest.yaml.ClientYamlTestExecutionContext;
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestExecutionContext;
|
||||||
import org.elasticsearch.test.rest.yaml.ClientYamlTestResponse;
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestResponse;
|
||||||
|
@ -39,6 +41,7 @@ import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
@ -376,8 +379,14 @@ public class DoSection implements ExecutableSection {
|
||||||
// This is really difficult to express just with features, so I will break it down into 2 parts: version check for v7,
|
// This is really difficult to express just with features, so I will break it down into 2 parts: version check for v7,
|
||||||
// and feature check for v8. This way the version check can be removed once we move to v9
|
// and feature check for v8. This way the version check can be removed once we move to v9
|
||||||
@UpdateForV9
|
@UpdateForV9
|
||||||
var fixedInV7 = executionContext.esVersion().major == Version.V_7_17_0.major
|
var fixedInV7 = executionContext.nodesVersions()
|
||||||
&& executionContext.esVersion().onOrAfter(Version.V_7_17_2);
|
.stream()
|
||||||
|
.map(ESRestTestCase::parseLegacyVersion)
|
||||||
|
.flatMap(Optional::stream)
|
||||||
|
.min(VersionId::compareTo)
|
||||||
|
.map(v -> v.major == Version.V_7_17_0.major && v.onOrAfter(Version.V_7_17_2))
|
||||||
|
.orElse(false);
|
||||||
|
|
||||||
var fixedProductionHeader = fixedInV7
|
var fixedProductionHeader = fixedInV7
|
||||||
|| executionContext.clusterHasFeature(RestTestLegacyFeatures.REST_ELASTIC_PRODUCT_HEADER_PRESENT.id());
|
|| executionContext.clusterHasFeature(RestTestLegacyFeatures.REST_ELASTIC_PRODUCT_HEADER_PRESENT.id());
|
||||||
if (fixedProductionHeader) {
|
if (fixedProductionHeader) {
|
||||||
|
|
|
@ -9,31 +9,38 @@
|
||||||
package org.elasticsearch.test.rest.yaml;
|
package org.elasticsearch.test.rest.yaml;
|
||||||
|
|
||||||
import org.apache.http.HttpEntity;
|
import org.apache.http.HttpEntity;
|
||||||
import org.elasticsearch.Version;
|
|
||||||
import org.elasticsearch.client.NodeSelector;
|
import org.elasticsearch.client.NodeSelector;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.test.VersionUtils;
|
import org.elasticsearch.test.rest.TestFeatureService;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
public class ClientYamlTestExecutionContextTests extends ESTestCase {
|
public class ClientYamlTestExecutionContextTests extends ESTestCase {
|
||||||
|
|
||||||
|
private static class MockTestFeatureService implements TestFeatureService {
|
||||||
|
@Override
|
||||||
|
public boolean clusterHasFeature(String featureId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void testHeadersSupportStashedValueReplacement() throws IOException {
|
public void testHeadersSupportStashedValueReplacement() throws IOException {
|
||||||
final AtomicReference<Map<String, String>> headersRef = new AtomicReference<>();
|
final AtomicReference<Map<String, String>> headersRef = new AtomicReference<>();
|
||||||
final Version version = VersionUtils.randomVersion(random());
|
final String version = randomAlphaOfLength(10);
|
||||||
final ClientYamlTestExecutionContext context = new ClientYamlTestExecutionContext(
|
final ClientYamlTestExecutionContext context = new ClientYamlTestExecutionContext(
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
randomBoolean(),
|
randomBoolean(),
|
||||||
version,
|
Set.of(version),
|
||||||
feature -> true,
|
new MockTestFeatureService(),
|
||||||
"os"
|
Set.of("os")
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
ClientYamlTestResponse callApiInternal(
|
ClientYamlTestResponse callApiInternal(
|
||||||
|
@ -64,14 +71,14 @@ public class ClientYamlTestExecutionContextTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStashHeadersOnException() throws IOException {
|
public void testStashHeadersOnException() throws IOException {
|
||||||
final Version version = VersionUtils.randomVersion(random());
|
final String version = randomAlphaOfLength(10);
|
||||||
final ClientYamlTestExecutionContext context = new ClientYamlTestExecutionContext(
|
final ClientYamlTestExecutionContext context = new ClientYamlTestExecutionContext(
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
randomBoolean(),
|
randomBoolean(),
|
||||||
version,
|
Set.of(version),
|
||||||
feature -> true,
|
new MockTestFeatureService(),
|
||||||
"os"
|
Set.of("os")
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
ClientYamlTestResponse callApiInternal(
|
ClientYamlTestResponse callApiInternal(
|
||||||
|
|
|
@ -16,7 +16,6 @@ import org.elasticsearch.client.NodeSelector;
|
||||||
import org.elasticsearch.common.ParsingException;
|
import org.elasticsearch.common.ParsingException;
|
||||||
import org.elasticsearch.common.logging.HeaderWarning;
|
import org.elasticsearch.common.logging.HeaderWarning;
|
||||||
import org.elasticsearch.core.Strings;
|
import org.elasticsearch.core.Strings;
|
||||||
import org.elasticsearch.test.VersionUtils;
|
|
||||||
import org.elasticsearch.test.rest.yaml.ClientYamlTestExecutionContext;
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestExecutionContext;
|
||||||
import org.elasticsearch.test.rest.yaml.ClientYamlTestResponse;
|
import org.elasticsearch.test.rest.yaml.ClientYamlTestResponse;
|
||||||
import org.elasticsearch.xcontent.XContentLocation;
|
import org.elasticsearch.xcontent.XContentLocation;
|
||||||
|
@ -31,6 +30,7 @@ import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
|
@ -610,7 +610,7 @@ public class DoSectionTests extends AbstractClientYamlTestFragmentParserTestCase
|
||||||
doSection.getApiCallSection().getNodeSelector()
|
doSection.getApiCallSection().getNodeSelector()
|
||||||
)
|
)
|
||||||
).thenReturn(mockResponse);
|
).thenReturn(mockResponse);
|
||||||
when(context.esVersion()).thenReturn(VersionUtils.randomVersion(random()));
|
when(context.nodesVersions()).thenReturn(Set.of(randomAlphaOfLength(10)));
|
||||||
when(mockResponse.getHeaders("X-elastic-product")).thenReturn(List.of("Elasticsearch"));
|
when(mockResponse.getHeaders("X-elastic-product")).thenReturn(List.of("Elasticsearch"));
|
||||||
doSection.execute(context);
|
doSection.execute(context);
|
||||||
verify(context).callApi(
|
verify(context).callApi(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue