Skip to content

Commit 772e6a1

Browse files
authored
Abstract version features checking to work with non-semantic versions (#137199)
When I resumed work on #105641 (now #136853), I had some serverless tests failures. When we moved away from Version in ESRestTest, we added fallbacks for non-sematic versions, which applied the concept "not a semantic version? We assume everything is "current" and supported", which played well for e.g. serverless. Down the road we acquired the concept of "version features", but we lost this concept; now tests with e.g. skip: gte_v720 are failing on serverless because it does not have a "7.2.0" node (*) This PR fixes the problem by re-introducing the non-semver == current version equivalency via a version features predicate. (*) after applying #136853
1 parent 5e61b1e commit 772e6a1

File tree

6 files changed

+42
-43
lines changed

6 files changed

+42
-43
lines changed

qa/ccs-common-rest/src/yamlRestTest/java/org/elasticsearch/test/rest/yaml/CcsCommonYamlTestSuiteIT.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import org.elasticsearch.test.cluster.ElasticsearchCluster;
2929
import org.elasticsearch.test.cluster.FeatureFlag;
3030
import org.elasticsearch.test.cluster.local.LocalClusterConfigProvider;
31-
import org.elasticsearch.test.rest.ESRestTestCase;
3231
import org.elasticsearch.test.rest.ObjectPath;
3332
import org.elasticsearch.test.rest.TestFeatureService;
3433
import org.elasticsearch.test.rest.yaml.restspec.ClientYamlSuiteRestApi;
@@ -50,7 +49,6 @@
5049
import java.util.ArrayList;
5150
import java.util.List;
5251
import java.util.Map;
53-
import java.util.Optional;
5452
import java.util.Set;
5553
import java.util.concurrent.atomic.AtomicBoolean;
5654
import java.util.concurrent.atomic.AtomicReference;
@@ -315,13 +313,10 @@ protected ClientYamlTestExecutionContext createRestTestExecutionContext(
315313
// Reconcile and provide unified features, os, version(s), based on both clientYamlTestClient and searchYamlTestClient
316314
var searchOs = readOsFromNodesInfo(adminSearchClient);
317315
var searchNodeVersions = readVersionsFromNodesInfo(adminSearchClient);
318-
var semanticNodeVersions = searchNodeVersions.stream()
319-
.map(ESRestTestCase::parseLegacyVersion)
320-
.flatMap(Optional::stream)
321-
.collect(Collectors.toSet());
316+
322317
final TestFeatureService searchTestFeatureService = createTestFeatureService(
323318
getClusterStateFeatures(adminSearchClient),
324-
semanticNodeVersions
319+
fromSemanticVersions(searchNodeVersions)
325320
);
326321
final TestFeatureService combinedTestFeatureService = (featureId, any) -> {
327322
boolean adminFeature = testFeatureService.clusterHasFeature(featureId, any);

qa/ccs-common-rest/src/yamlRestTest/java/org/elasticsearch/test/rest/yaml/RcsCcsCommonYamlTestSuiteIT.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import org.elasticsearch.test.cluster.FeatureFlag;
3131
import org.elasticsearch.test.cluster.local.LocalClusterConfigProvider;
3232
import org.elasticsearch.test.cluster.util.resource.Resource;
33-
import org.elasticsearch.test.rest.ESRestTestCase;
3433
import org.elasticsearch.test.rest.ObjectPath;
3534
import org.elasticsearch.test.rest.TestFeatureService;
3635
import org.elasticsearch.test.rest.yaml.CcsCommonYamlTestSuiteIT.TestCandidateAwareClient;
@@ -45,7 +44,6 @@
4544
import java.util.ArrayList;
4645
import java.util.List;
4746
import java.util.Map;
48-
import java.util.Optional;
4947
import java.util.Set;
5048
import java.util.concurrent.atomic.AtomicBoolean;
5149
import java.util.concurrent.atomic.AtomicReference;
@@ -298,14 +296,9 @@ protected ClientYamlTestExecutionContext createRestTestExecutionContext(
298296
var searchOs = readOsFromNodesInfo(adminSearchClient);
299297
var searchNodeVersions = readVersionsFromNodesInfo(adminSearchClient);
300298

301-
var semanticNodeVersions = searchNodeVersions.stream()
302-
.map(ESRestTestCase::parseLegacyVersion)
303-
.flatMap(Optional::stream)
304-
.collect(Collectors.toSet());
305-
306299
final TestFeatureService searchTestFeatureService = createTestFeatureService(
307300
getClusterStateFeatures(adminSearchClient),
308-
semanticNodeVersions
301+
fromSemanticVersions(searchNodeVersions)
309302
);
310303

311304
final TestFeatureService combinedTestFeatureService = (featureId, any) -> {

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

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ public abstract class ESRestTestCase extends ESTestCase {
176176

177177
private static final Pattern SEMANTIC_VERSION_PATTERN = Pattern.compile("^(\\d+\\.\\d+\\.\\d+)\\D?.*");
178178

179+
public interface VersionFeaturesPredicate {
180+
boolean test(Version featureVersion, boolean canMatchAnyNode);
181+
}
182+
179183
private static final Logger SUITE_LOGGER = LogManager.getLogger(ESRestTestCase.class);
180184

181185
private static final String EXPECTED_ROLLUP_WARNING_MESSAGE =
@@ -446,13 +450,7 @@ public void initClient() throws IOException {
446450
}
447451
}
448452
nodesVersions = Collections.unmodifiableSet(versions);
449-
450-
var semanticNodeVersions = nodesVersions.stream()
451-
.map(ESRestTestCase::parseLegacyVersion)
452-
.flatMap(Optional::stream)
453-
.collect(Collectors.toSet());
454-
assert semanticNodeVersions.isEmpty() == false || serverless;
455-
testFeatureService = createTestFeatureService(getClusterStateFeatures(adminClient), semanticNodeVersions);
453+
testFeatureService = createTestFeatureService(getClusterStateFeatures(adminClient), fromSemanticVersions(nodesVersions));
456454

457455
configureProjects();
458456
}
@@ -467,9 +465,9 @@ public void initClient() throws IOException {
467465

468466
protected final TestFeatureService createTestFeatureService(
469467
Map<String, Set<String>> clusterStateFeatures,
470-
Set<Version> semanticNodeVersions
468+
VersionFeaturesPredicate versionFeaturesPredicate
471469
) {
472-
return new ESRestTestFeatureService(semanticNodeVersions, clusterStateFeatures.values());
470+
return new ESRestTestFeatureService(versionFeaturesPredicate, clusterStateFeatures.values());
473471
}
474472

475473
protected static boolean has(ProductFeature feature) {
@@ -2584,6 +2582,27 @@ public static Optional<Version> parseLegacyVersion(String version) {
25842582
return Optional.empty();
25852583
}
25862584

2585+
public static VersionFeaturesPredicate fromSemanticVersions(Set<String> nodesVersions) {
2586+
Set<Version> semanticNodeVersions = nodesVersions.stream()
2587+
.map(ESRestTestCase::parseLegacyVersion)
2588+
.flatMap(Optional::stream)
2589+
.collect(Collectors.toSet());
2590+
if (semanticNodeVersions.isEmpty()) {
2591+
// Nodes do not have a semantic version (e.g. serverless).
2592+
// We assume the cluster is on the "latest version", and all is supported.
2593+
return ((featureVersion, canMatchAnyNode) -> true);
2594+
}
2595+
2596+
return (featureVersion, canMatchAnyNode) -> {
2597+
if (canMatchAnyNode) {
2598+
return semanticNodeVersions.stream().anyMatch(nodeVersion -> nodeVersion.onOrAfter(featureVersion));
2599+
} else {
2600+
return semanticNodeVersions.isEmpty() == false
2601+
&& semanticNodeVersions.stream().allMatch(nodeVersion -> nodeVersion.onOrAfter(featureVersion));
2602+
}
2603+
};
2604+
}
2605+
25872606
/**
25882607
* Wait for the license to be applied and active. The specified admin client is used to check the license and this is done using
25892608
* {@link ESTestCase#assertBusy(CheckedRunnable)} to give some time to the License to be applied on nodes.

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ class ESRestTestFeatureService implements TestFeatureService {
4242
*/
4343
private static final Pattern VERSION_FEATURE_PATTERN = Pattern.compile("gte_v(\\d+\\.\\d+\\.\\d+)");
4444

45-
private final Collection<Version> nodeVersions;
45+
private final ESRestTestCase.VersionFeaturesPredicate versionFeaturesPredicate;
4646
private final Collection<Set<String>> nodeFeatures;
4747

48-
ESRestTestFeatureService(Set<Version> nodeVersions, Collection<Set<String>> nodeFeatures) {
49-
this.nodeVersions = nodeVersions;
48+
ESRestTestFeatureService(ESRestTestCase.VersionFeaturesPredicate versionFeaturesPredicate, Collection<Set<String>> nodeFeatures) {
49+
this.versionFeaturesPredicate = versionFeaturesPredicate;
5050
this.nodeFeatures = nodeFeatures;
5151
}
5252

@@ -55,8 +55,8 @@ private static <T> boolean checkCollection(Collection<T> coll, Predicate<T> pred
5555
}
5656

5757
@Override
58-
public boolean clusterHasFeature(String featureId, boolean any) {
59-
if (checkCollection(nodeFeatures, s -> s.contains(featureId), any)) {
58+
public boolean clusterHasFeature(String featureId, boolean canMatchAnyNode) {
59+
if (checkCollection(nodeFeatures, s -> s.contains(featureId), canMatchAnyNode)) {
6060
return true;
6161
}
6262
if (MetadataHolder.FEATURE_NAMES.contains(featureId)) {
@@ -88,7 +88,7 @@ public boolean clusterHasFeature(String featureId, boolean any) {
8888
);
8989
}
9090

91-
return checkCollection(nodeVersions, v -> v.onOrAfter(extractedVersion), any);
91+
return versionFeaturesPredicate.test(extractedVersion, canMatchAnyNode);
9292
}
9393

9494
if (hasFeatureMetadata()) {

test/yaml-rest-runner/src/main/java/org/elasticsearch/test/rest/yaml/ESClientYamlSuiteTestCase.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
import java.util.Set;
5555
import java.util.SortedSet;
5656
import java.util.TreeSet;
57-
import java.util.stream.Collectors;
5857

5958
/**
6059
* Runs a suite of yaml tests shared with all the official Elasticsearch
@@ -127,13 +126,9 @@ public void initAndResetContext() throws Exception {
127126

128127
logger.info("initializing client, node versions [{}], hosts {}, os [{}]", nodesVersions, hosts, os);
129128

130-
var semanticNodeVersions = nodesVersions.stream()
131-
.map(ESRestTestCase::parseLegacyVersion)
132-
.flatMap(Optional::stream)
133-
.collect(Collectors.toSet());
134129
final TestFeatureService testFeatureService = createTestFeatureService(
135130
getClusterStateFeatures(adminClient()),
136-
semanticNodeVersions
131+
fromSemanticVersions(nodesVersions)
137132
);
138133

139134
logger.info("initializing client, node versions [{}], hosts {}, os [{}]", nodesVersions, hosts, os);

x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClusterSpecIT.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import org.elasticsearch.core.IOUtils;
2121
import org.elasticsearch.test.TestClustersThreadFilter;
2222
import org.elasticsearch.test.cluster.ElasticsearchCluster;
23-
import org.elasticsearch.test.rest.ESRestTestCase;
2423
import org.elasticsearch.test.rest.TestFeatureService;
2524
import org.elasticsearch.xpack.esql.CsvSpecReader;
2625
import org.elasticsearch.xpack.esql.CsvSpecReader.CsvTestCase;
@@ -38,7 +37,6 @@
3837
import java.util.Arrays;
3938
import java.util.List;
4039
import java.util.Locale;
41-
import java.util.Optional;
4240
import java.util.Set;
4341
import java.util.regex.Pattern;
4442
import java.util.stream.Collectors;
@@ -179,11 +177,10 @@ protected void shouldSkipTest(String testName) throws IOException {
179177
private TestFeatureService remoteFeaturesService() throws IOException {
180178
if (remoteFeaturesService == null) {
181179
var remoteNodeVersions = readVersionsFromNodesInfo(remoteClusterClient());
182-
var semanticNodeVersions = remoteNodeVersions.stream()
183-
.map(ESRestTestCase::parseLegacyVersion)
184-
.flatMap(Optional::stream)
185-
.collect(Collectors.toSet());
186-
remoteFeaturesService = createTestFeatureService(getClusterStateFeatures(remoteClusterClient()), semanticNodeVersions);
180+
remoteFeaturesService = createTestFeatureService(
181+
getClusterStateFeatures(remoteClusterClient()),
182+
fromSemanticVersions(remoteNodeVersions)
183+
);
187184
}
188185
return remoteFeaturesService;
189186
}

0 commit comments

Comments
 (0)