From 385e0d9259f29d9351c37647e5f526040b232d24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lorenzo=20Dematt=C3=A9?= Date: Wed, 11 Jun 2025 17:22:54 +0200 Subject: [PATCH] [BC Upgrage] Fix incorrect version parsing in tests (#129243) This PR introduces several fixes to various IT tests, related to the use and misuse of the version identifier for the start cluster: wherever we can, we replace of versions in test code with features where we can't, we make sure we use the actual stack version (the one provided by -Dtests.bwc.main.version and not the bogus "0.0.0" version string) when requesting the cluster version we make sure we do use the "unresolved" version identifier (the value of the tests.old_cluster_version system property e.g. 0.0.0 ) so we resolve the right distribution These changes enabled the tests to be used in BC upgrade tests (and potentially in serverless upgrade tests too, where they would have also failed) Relates to ES-12010 Precedes #128614, #128823 and #128983 --- ...rameterizedFullClusterRestartTestCase.java | 6 ++- .../AbstractRollingUpgradeTestCase.java | 10 +++-- ...actRollingUpgradeWithSecurityTestCase.java | 9 ++-- .../upgrades/DenseVectorMappingUpdateIT.java | 2 +- .../upgrades/FileSettingsUpgradeIT.java | 11 ++++- .../upgrades/LogsUsageRollingUpgradeIT.java | 2 +- .../ParameterizedRollingUpgradeTestCase.java | 21 +++++---- .../upgrades/SnapshotBasedRecoveryIT.java | 20 ++++++--- .../upgrades/SourceModeRollingUpgradeIT.java | 4 +- .../upgrades/VectorSearchIT.java | 43 +++++++------------ .../test/cluster/util/Version.java | 18 ++++++++ .../AzureOpenAiServiceUpgradeIT.java | 9 ++-- .../application/CohereServiceUpgradeIT.java | 19 ++++---- .../HuggingFaceServiceUpgradeIT.java | 18 ++++---- .../application/InferenceUpgradeTestCase.java | 6 ++- .../application/OpenAiServiceUpgradeIT.java | 27 ++++++------ 16 files changed, 128 insertions(+), 97 deletions(-) diff --git a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/ParameterizedFullClusterRestartTestCase.java b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/ParameterizedFullClusterRestartTestCase.java index 7518a799540b..5c83fee97cdc 100644 --- a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/ParameterizedFullClusterRestartTestCase.java +++ b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/ParameterizedFullClusterRestartTestCase.java @@ -134,7 +134,11 @@ public abstract class ParameterizedFullClusterRestartTestCase extends ESRestTest return requestedUpgradeStatus == OLD; } - public static String getOldClusterVersion() { + /** + * The version of the "old" (initial) cluster. It is an opaque string, do not even think about parsing it for version + * comparison. Use (test) cluster features and {@link ParameterizedFullClusterRestartTestCase#oldClusterHasFeature} instead. + */ + protected static String getOldClusterVersion() { return System.getProperty("tests.bwc.main.version", OLD_CLUSTER_VERSION); } diff --git a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/AbstractRollingUpgradeTestCase.java b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/AbstractRollingUpgradeTestCase.java index 99db4c267755..87096277cfce 100644 --- a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/AbstractRollingUpgradeTestCase.java +++ b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/AbstractRollingUpgradeTestCase.java @@ -30,10 +30,11 @@ public abstract class AbstractRollingUpgradeTestCase extends ParameterizedRollin private static final ElasticsearchCluster cluster = buildCluster(); private static ElasticsearchCluster buildCluster() { - Version oldVersion = Version.fromString(OLD_CLUSTER_VERSION); + // Note we need to use OLD_CLUSTER_VERSION directly here, as it may contain special values (e.g. 0.0.0) the ElasticsearchCluster + // builder uses to lookup a particular distribution var cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(getOldClusterTestVersion()) + .version(OLD_CLUSTER_VERSION) .nodes(NODE_NUM) .setting("path.repo", new Supplier<>() { @Override @@ -46,8 +47,9 @@ public abstract class AbstractRollingUpgradeTestCase extends ParameterizedRollin .feature(FeatureFlag.TIME_SERIES_MODE); // Avoid triggering bogus assertion when serialized parsed mappings don't match with original mappings, because _source key is - // inconsistent - if (oldVersion.before(Version.fromString("8.18.0"))) { + // inconsistent. As usual, we operate under the premise that "versionless" clusters (serverless) are on the latest code and + // do not need this. + if (Version.tryParse(getOldClusterVersion()).map(v -> v.before(Version.fromString("8.18.0"))).orElse(false)) { cluster.jvmArg("-da:org.elasticsearch.index.mapper.DocumentMapper"); cluster.jvmArg("-da:org.elasticsearch.index.mapper.MapperService"); } diff --git a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/AbstractRollingUpgradeWithSecurityTestCase.java b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/AbstractRollingUpgradeWithSecurityTestCase.java index 9f74573ca83f..961e4a353df9 100644 --- a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/AbstractRollingUpgradeWithSecurityTestCase.java +++ b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/AbstractRollingUpgradeWithSecurityTestCase.java @@ -35,10 +35,11 @@ public abstract class AbstractRollingUpgradeWithSecurityTestCase extends Paramet private static final ElasticsearchCluster cluster = buildCluster(); private static ElasticsearchCluster buildCluster() { - Version oldVersion = Version.fromString(OLD_CLUSTER_VERSION); + // Note we need to use OLD_CLUSTER_VERSION directly here, as it may contain special values (e.g. 0.0.0) the ElasticsearchCluster + // builder uses to lookup a particular distribution var cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(getOldClusterTestVersion()) + .version(OLD_CLUSTER_VERSION) .nodes(NODE_NUM) .user(USER, PASS) .setting("xpack.security.autoconfiguration.enabled", "false") @@ -51,8 +52,8 @@ public abstract class AbstractRollingUpgradeWithSecurityTestCase extends Paramet }); // Avoid triggering bogus assertion when serialized parsed mappings don't match with original mappings, because _source key is - // inconsistent - if (oldVersion.before(Version.fromString("8.18.0"))) { + // inconsistent. Assume non-parseable versions (serverless) do not need this. + if (Version.tryParse(getOldClusterVersion()).map(v -> v.before(Version.fromString("8.18.0"))).orElse(false)) { cluster.jvmArg("-da:org.elasticsearch.index.mapper.DocumentMapper"); cluster.jvmArg("-da:org.elasticsearch.index.mapper.MapperService"); } diff --git a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/DenseVectorMappingUpdateIT.java b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/DenseVectorMappingUpdateIT.java index b8fc3b15636f..dff0e9419305 100644 --- a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/DenseVectorMappingUpdateIT.java +++ b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/DenseVectorMappingUpdateIT.java @@ -82,7 +82,7 @@ public class DenseVectorMappingUpdateIT extends AbstractRollingUpgradeTestCase { } public void testDenseVectorMappingUpdateOnOldCluster() throws IOException { - if (getOldClusterTestVersion().after(Version.V_8_7_0.toString())) { + if (oldClusterHasFeature("gte_v8.7.1")) { String indexName = "test_index"; if (isOldCluster()) { Request createIndex = new Request("PUT", "/" + indexName); diff --git a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/FileSettingsUpgradeIT.java b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/FileSettingsUpgradeIT.java index 0f48fb65b41f..6d16714cc67b 100644 --- a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/FileSettingsUpgradeIT.java +++ b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/FileSettingsUpgradeIT.java @@ -14,6 +14,7 @@ import com.carrotsearch.randomizedtesting.annotations.Name; import org.elasticsearch.client.Request; import org.elasticsearch.common.xcontent.support.XContentMapValues; import org.elasticsearch.core.SuppressForbidden; +import org.elasticsearch.core.UpdateForV10; import org.elasticsearch.test.cluster.ElasticsearchCluster; import org.elasticsearch.test.cluster.FeatureFlag; import org.elasticsearch.test.cluster.local.distribution.DistributionType; @@ -33,8 +34,12 @@ import static org.hamcrest.Matchers.equalTo; public class FileSettingsUpgradeIT extends ParameterizedRollingUpgradeTestCase { + @UpdateForV10(owner = UpdateForV10.Owner.CORE_INFRA) // Remove this rule entirely private static final RunnableTestRuleAdapter versionLimit = new RunnableTestRuleAdapter( - () -> assumeTrue("Only valid when upgrading from pre-file settings", getOldClusterTestVersion().before(new Version(8, 4, 0))) + () -> assumeTrue( + "Only valid when upgrading from pre-file settings", + Version.tryParse(getOldClusterVersion()).map(v -> v.before(new Version(8, 4, 0))).orElse(false) + ) ); private static final String settingsJSON = """ @@ -52,9 +57,11 @@ public class FileSettingsUpgradeIT extends ParameterizedRollingUpgradeTestCase { private static final TemporaryFolder repoDirectory = new TemporaryFolder(); + // Note we need to use OLD_CLUSTER_VERSION directly here, as it may contain special values (e.g. 0.0.0) the ElasticsearchCluster + // builder uses to lookup a particular distribution private static final ElasticsearchCluster cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(getOldClusterTestVersion()) + .version(OLD_CLUSTER_VERSION) .nodes(NODE_NUM) .setting("path.repo", new Supplier<>() { @Override diff --git a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/LogsUsageRollingUpgradeIT.java b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/LogsUsageRollingUpgradeIT.java index b72060a34489..6fea6917bebc 100644 --- a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/LogsUsageRollingUpgradeIT.java +++ b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/LogsUsageRollingUpgradeIT.java @@ -30,7 +30,7 @@ public class LogsUsageRollingUpgradeIT extends AbstractRollingUpgradeWithSecurit } public void testUsage() throws Exception { - assumeTrue("logsdb.prior_logs_usage only gets set in 8.x", getOldClusterTestVersion().before("9.0.0")); + assumeFalse("logsdb.prior_logs_usage only gets set in 8.x", oldClusterHasFeature("gte_v9.0.0")); String dataStreamName = "logs-mysql-error"; if (isOldCluster()) { bulkIndex(dataStreamName, 4, 256, Instant.now()); diff --git a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/ParameterizedRollingUpgradeTestCase.java b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/ParameterizedRollingUpgradeTestCase.java index 00adf18bba6e..43a908196448 100644 --- a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/ParameterizedRollingUpgradeTestCase.java +++ b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/ParameterizedRollingUpgradeTestCase.java @@ -127,11 +127,6 @@ public abstract class ParameterizedRollingUpgradeTestCase extends ESRestTestCase upgradeFailed = false; } - @Deprecated // Use the new testing framework and oldClusterHasFeature(feature) instead - protected static String getOldClusterVersion() { - return OLD_CLUSTER_VERSION; - } - protected static boolean oldClusterHasFeature(String featureId) { assert oldClusterTestFeatureService != null; return oldClusterTestFeatureService.clusterHasFeature(featureId); @@ -146,12 +141,20 @@ public abstract class ParameterizedRollingUpgradeTestCase extends ESRestTestCase return oldIndexVersion; } - protected static Version getOldClusterTestVersion() { - return Version.fromString(OLD_CLUSTER_VERSION); + /** + * The version of the "old" (initial) cluster. It is an opaque string, do not even think about parsing it for version + * comparison. Use (test) cluster features and {@link ParameterizedRollingUpgradeTestCase#oldClusterHasFeature} instead. + */ + protected static String getOldClusterVersion() { + return System.getProperty("tests.bwc.main.version", OLD_CLUSTER_VERSION); } - protected static boolean isOldClusterVersion(String nodeVersion) { - return OLD_CLUSTER_VERSION.equals(nodeVersion); + protected static boolean isOldClusterVersion(String nodeVersion, String buildHash) { + String bwcRefSpec = System.getProperty("tests.bwc.refspec.main"); + if (bwcRefSpec != null) { + return bwcRefSpec.equals(buildHash); + } + return getOldClusterVersion().equals(nodeVersion); } protected static boolean isOldCluster() { diff --git a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/SnapshotBasedRecoveryIT.java b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/SnapshotBasedRecoveryIT.java index 485e1d4f2882..312c238cb17e 100644 --- a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/SnapshotBasedRecoveryIT.java +++ b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/SnapshotBasedRecoveryIT.java @@ -88,7 +88,7 @@ public class SnapshotBasedRecoveryIT extends AbstractRollingUpgradeTestCase { } String primaryNodeId = getPrimaryNodeIdOfShard(indexName, 0); - String primaryNodeVersion = getNodeVersion(primaryNodeId); + var primaryNodeVersion = getNodeVersion(primaryNodeId); // Sometimes the primary shard ends on the upgraded node (i.e. after a rebalance) // This causes issues when removing and adding replicas, since then we cannot allocate to any of the old nodes. @@ -96,13 +96,14 @@ public class SnapshotBasedRecoveryIT extends AbstractRollingUpgradeTestCase { // In that case we exclude the upgraded node from the shard allocation and cancel the shard to force moving // the primary to a node in the old version, this allows adding replicas in the first mixed round. logger.info("--> Primary node in first mixed round {} / {}", primaryNodeId, primaryNodeVersion); - if (isOldClusterVersion(primaryNodeVersion) == false) { + if (isOldClusterVersion(primaryNodeVersion.version(), primaryNodeVersion.buildHash()) == false) { logger.info("--> cancelling primary shard on node [{}]", primaryNodeId); cancelShard(indexName, 0, primaryNodeId); logger.info("--> done cancelling primary shard on node [{}]", primaryNodeId); String currentPrimaryNodeId = getPrimaryNodeIdOfShard(indexName, 0); - assertTrue(isOldClusterVersion(getNodeVersion(currentPrimaryNodeId))); + var currentPrimaryNodeVersion = getNodeVersion(currentPrimaryNodeId); + assertTrue(isOldClusterVersion(currentPrimaryNodeVersion.version(), currentPrimaryNodeVersion.buildHash())); } } else { logger.info("--> not in first upgrade round, removing exclusions for [{}]", indexName); @@ -137,17 +138,24 @@ public class SnapshotBasedRecoveryIT extends AbstractRollingUpgradeTestCase { List upgradedNodes = new ArrayList<>(); for (Map.Entry> nodeInfoEntry : nodes.entrySet()) { String nodeVersion = extractValue(nodeInfoEntry.getValue(), "version"); - if (isOldClusterVersion(nodeVersion) == false) { + String nodeBuildHash = extractValue(nodeInfoEntry.getValue(), "build_hash"); + if (isOldClusterVersion(nodeVersion, nodeBuildHash) == false) { upgradedNodes.add(nodeInfoEntry.getKey()); } } return upgradedNodes; } - private String getNodeVersion(String primaryNodeId) throws IOException { + private record NodeVersion(String version, String buildHash) {} + + private NodeVersion getNodeVersion(String primaryNodeId) throws IOException { Request request = new Request(HttpGet.METHOD_NAME, "_nodes/" + primaryNodeId); Response response = client().performRequest(request); - return extractValue(responseAsMap(response), "nodes." + primaryNodeId + ".version"); + Map responseAsMap = responseAsMap(response); + return new NodeVersion( + extractValue(responseAsMap, "nodes." + primaryNodeId + ".version"), + extractValue(responseAsMap, "nodes." + primaryNodeId + ".build_hash") + ); } private String getPrimaryNodeIdOfShard(String indexName, int shard) throws Exception { diff --git a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/SourceModeRollingUpgradeIT.java b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/SourceModeRollingUpgradeIT.java index 55a03da7c9e9..b512835b8201 100644 --- a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/SourceModeRollingUpgradeIT.java +++ b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/SourceModeRollingUpgradeIT.java @@ -27,7 +27,7 @@ public class SourceModeRollingUpgradeIT extends AbstractRollingUpgradeTestCase { } public void testConfigureStoredSourceBeforeIndexCreationLegacy() throws IOException { - assumeTrue("testing deprecation warnings and deprecation migrations", getOldClusterTestVersion().before("9.0.0")); + assumeFalse("testing deprecation warnings and deprecation migrations", oldClusterHasFeature("gte_v9.0.0")); String templateName = "logs@custom"; if (isOldCluster()) { var storedSourceMapping = """ @@ -56,7 +56,7 @@ public class SourceModeRollingUpgradeIT extends AbstractRollingUpgradeTestCase { } public void testConfigureStoredSourceWhenIndexIsCreatedLegacy() throws IOException { - assumeTrue("testing deprecation warnings and deprecation migrations", getOldClusterTestVersion().before("9.0.0")); + assumeFalse("testing deprecation warnings and deprecation migrations", oldClusterHasFeature("gte_v9.0.0")); String templateName = "logs@custom"; if (isOldCluster()) { var storedSourceMapping = """ diff --git a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/VectorSearchIT.java b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/VectorSearchIT.java index 07034618be4a..afee17cd82e2 100644 --- a/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/VectorSearchIT.java +++ b/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/VectorSearchIT.java @@ -37,14 +37,16 @@ public class VectorSearchIT extends AbstractRollingUpgradeTestCase { private static final String BBQ_INDEX_NAME = "bbq_vector_index"; private static final String FLAT_QUANTIZED_INDEX_NAME = "flat_quantized_vector_index"; private static final String FLAT_BBQ_INDEX_NAME = "flat_bbq_vector_index"; - private static final String FLOAT_VECTOR_SEARCH_VERSION = "8.4.0"; - private static final String BYTE_VECTOR_SEARCH_VERSION = "8.6.0"; - private static final String QUANTIZED_VECTOR_SEARCH_VERSION = "8.12.1"; - private static final String FLAT_QUANTIZED_VECTOR_SEARCH_VERSION = "8.13.0"; - private static final String BBQ_VECTOR_SEARCH_VERSION = "8.18.0"; + + // TODO: replace these with proper test features + private static final String FLOAT_VECTOR_SEARCH_TEST_FEATURE = "gte_v8.4.0"; + private static final String BYTE_VECTOR_SEARCH_TEST_FEATURE = "gte_v8.6.0"; + private static final String QUANTIZED_VECTOR_SEARCH_TEST_FEATURE = "gte_v8.12.1"; + private static final String FLAT_QUANTIZED_VECTOR_SEARCH_TEST_FEATURE = "gte_v8.13.0"; + private static final String BBQ_VECTOR_SEARCH_TEST_FEATURE = "gte_v8.18.0"; public void testScriptByteVectorSearch() throws Exception { - assumeTrue("byte vector search is not supported on this version", getOldClusterTestVersion().onOrAfter(BYTE_VECTOR_SEARCH_VERSION)); + assumeTrue("byte vector search is not supported on this version", oldClusterHasFeature(BYTE_VECTOR_SEARCH_TEST_FEATURE)); if (isOldCluster()) { // create index and index 10 random floating point vectors String mapping = """ @@ -91,10 +93,7 @@ public class VectorSearchIT extends AbstractRollingUpgradeTestCase { } public void testScriptVectorSearch() throws Exception { - assumeTrue( - "Float vector search is not supported on this version", - getOldClusterTestVersion().onOrAfter(FLOAT_VECTOR_SEARCH_VERSION) - ); + assumeTrue("Float vector search is not supported on this version", oldClusterHasFeature(FLOAT_VECTOR_SEARCH_TEST_FEATURE)); if (isOldCluster()) { // create index and index 10 random floating point vectors String mapping = """ @@ -140,10 +139,7 @@ public class VectorSearchIT extends AbstractRollingUpgradeTestCase { } public void testFloatVectorSearch() throws Exception { - assumeTrue( - "Float vector search is not supported on this version", - getOldClusterTestVersion().onOrAfter(FLOAT_VECTOR_SEARCH_VERSION) - ); + assumeTrue("Float vector search is not supported on this version", oldClusterHasFeature(FLOAT_VECTOR_SEARCH_TEST_FEATURE)); if (isOldCluster()) { String mapping = """ { @@ -215,7 +211,7 @@ public class VectorSearchIT extends AbstractRollingUpgradeTestCase { } public void testByteVectorSearch() throws Exception { - assumeTrue("Byte vector search is not supported on this version", getOldClusterTestVersion().onOrAfter(BYTE_VECTOR_SEARCH_VERSION)); + assumeTrue("Byte vector search is not supported on this version", oldClusterHasFeature(BYTE_VECTOR_SEARCH_TEST_FEATURE)); if (isOldCluster()) { String mapping = """ { @@ -288,10 +284,7 @@ public class VectorSearchIT extends AbstractRollingUpgradeTestCase { } public void testQuantizedVectorSearch() throws Exception { - assumeTrue( - "Quantized vector search is not supported on this version", - getOldClusterTestVersion().onOrAfter(QUANTIZED_VECTOR_SEARCH_VERSION) - ); + assumeTrue("Quantized vector search is not supported on this version", oldClusterHasFeature(QUANTIZED_VECTOR_SEARCH_TEST_FEATURE)); if (isOldCluster()) { String mapping = """ { @@ -364,7 +357,7 @@ public class VectorSearchIT extends AbstractRollingUpgradeTestCase { public void testFlatQuantizedVectorSearch() throws Exception { assumeTrue( "Quantized vector search is not supported on this version", - getOldClusterTestVersion().onOrAfter(FLAT_QUANTIZED_VECTOR_SEARCH_VERSION) + oldClusterHasFeature(FLAT_QUANTIZED_VECTOR_SEARCH_TEST_FEATURE) ); if (isOldCluster()) { String mapping = """ @@ -434,10 +427,7 @@ public class VectorSearchIT extends AbstractRollingUpgradeTestCase { } public void testBBQVectorSearch() throws Exception { - assumeTrue( - "Quantized vector search is not supported on this version", - getOldClusterTestVersion().onOrAfter(BBQ_VECTOR_SEARCH_VERSION) - ); + assumeTrue("Quantized vector search is not supported on this version", oldClusterHasFeature(BBQ_VECTOR_SEARCH_TEST_FEATURE)); if (isOldCluster()) { String mapping = """ { @@ -518,10 +508,7 @@ public class VectorSearchIT extends AbstractRollingUpgradeTestCase { } public void testFlatBBQVectorSearch() throws Exception { - assumeTrue( - "Quantized vector search is not supported on this version", - getOldClusterTestVersion().onOrAfter(BBQ_VECTOR_SEARCH_VERSION) - ); + assumeTrue("Quantized vector search is not supported on this version", oldClusterHasFeature(BBQ_VECTOR_SEARCH_TEST_FEATURE)); if (isOldCluster()) { String mapping = """ { diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/util/Version.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/util/Version.java index 7a07876e2fb3..2136d88a9e2a 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/util/Version.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/util/Version.java @@ -13,6 +13,7 @@ import java.io.InputStream; import java.io.Serializable; import java.io.UncheckedIOException; import java.util.Objects; +import java.util.Optional; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -96,6 +97,23 @@ public class Version implements Comparable, Serializable { return new Version(Integer.parseInt(major), Integer.parseInt(minor), revision == null ? 0 : Integer.parseInt(revision), qualifier); } + public static Optional tryParse(final String s) { + Objects.requireNonNull(s); + Matcher matcher = pattern.matcher(s); + if (matcher.matches() == false) { + return Optional.empty(); + } + + String major = matcher.group(1); + String minor = matcher.group(2); + String revision = matcher.group(3); + String qualifier = matcher.group(4); + + return Optional.of( + new Version(Integer.parseInt(major), Integer.parseInt(minor), revision == null ? 0 : Integer.parseInt(revision), qualifier) + ); + } + @Override public String toString() { return getMajor() + "." + getMinor() + "." + getRevision(); diff --git a/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/AzureOpenAiServiceUpgradeIT.java b/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/AzureOpenAiServiceUpgradeIT.java index f0196834b917..82ebc755bdca 100644 --- a/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/AzureOpenAiServiceUpgradeIT.java +++ b/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/AzureOpenAiServiceUpgradeIT.java @@ -26,7 +26,7 @@ import static org.hamcrest.Matchers.not; public class AzureOpenAiServiceUpgradeIT extends InferenceUpgradeTestCase { - private static final String OPEN_AI_AZURE_EMBEDDINGS_ADDED = "8.14.0"; + private static final String OPEN_AI_AZURE_EMBEDDINGS_ADDED_FEATURE = "gte_v8.14.0"; private static MockWebServer openAiEmbeddingsServer; @@ -48,10 +48,9 @@ public class AzureOpenAiServiceUpgradeIT extends InferenceUpgradeTestCase { @SuppressWarnings("unchecked") @AwaitsFix(bugUrl = "Cannot set the URL in the tests") public void testOpenAiEmbeddings() throws IOException { - var openAiEmbeddingsSupported = getOldClusterTestVersion().onOrAfter(OPEN_AI_AZURE_EMBEDDINGS_ADDED); - // `gte_v` indicates that the cluster version is Greater Than or Equal to MODELS_RENAMED_TO_ENDPOINTS - String oldClusterEndpointIdentifier = oldClusterHasFeature("gte_v" + MODELS_RENAMED_TO_ENDPOINTS) ? "endpoints" : "models"; - assumeTrue("Azure OpenAI embedding service added in " + OPEN_AI_AZURE_EMBEDDINGS_ADDED, openAiEmbeddingsSupported); + var openAiEmbeddingsSupported = oldClusterHasFeature(OPEN_AI_AZURE_EMBEDDINGS_ADDED_FEATURE); + String oldClusterEndpointIdentifier = oldClusterHasFeature(MODELS_RENAMED_TO_ENDPOINTS_FEATURE) ? "endpoints" : "models"; + assumeTrue("Azure OpenAI embedding service supported", openAiEmbeddingsSupported); final String oldClusterId = "old-cluster-embeddings"; final String upgradedClusterId = "upgraded-cluster-embeddings"; diff --git a/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/CohereServiceUpgradeIT.java b/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/CohereServiceUpgradeIT.java index 0acbc148515b..7851a093a95c 100644 --- a/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/CohereServiceUpgradeIT.java +++ b/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/CohereServiceUpgradeIT.java @@ -33,9 +33,9 @@ import static org.hamcrest.Matchers.oneOf; public class CohereServiceUpgradeIT extends InferenceUpgradeTestCase { - private static final String COHERE_EMBEDDINGS_ADDED = "8.13.0"; - private static final String COHERE_RERANK_ADDED = "8.14.0"; - private static final String BYTE_ALIAS_FOR_INT8_ADDED = "8.14.0"; + // TODO: replace with proper test features + private static final String COHERE_EMBEDDINGS_ADDED_TEST_FEATURE = "gte_v8.13.0"; + private static final String COHERE_RERANK_ADDED_TEST_FEATURE = "gte_v8.14.0"; private static MockWebServer cohereEmbeddingsServer; private static MockWebServer cohereRerankServer; @@ -61,10 +61,9 @@ public class CohereServiceUpgradeIT extends InferenceUpgradeTestCase { @SuppressWarnings("unchecked") public void testCohereEmbeddings() throws IOException { - var embeddingsSupported = getOldClusterTestVersion().onOrAfter(COHERE_EMBEDDINGS_ADDED); - // `gte_v` indicates that the cluster version is Greater Than or Equal to MODELS_RENAMED_TO_ENDPOINTS - String oldClusterEndpointIdentifier = oldClusterHasFeature("gte_v" + MODELS_RENAMED_TO_ENDPOINTS) ? "endpoints" : "models"; - assumeTrue("Cohere embedding service added in " + COHERE_EMBEDDINGS_ADDED, embeddingsSupported); + var embeddingsSupported = oldClusterHasFeature(COHERE_EMBEDDINGS_ADDED_TEST_FEATURE); + String oldClusterEndpointIdentifier = oldClusterHasFeature(MODELS_RENAMED_TO_ENDPOINTS_FEATURE) ? "endpoints" : "models"; + assumeTrue("Cohere embedding service supported", embeddingsSupported); final String oldClusterIdInt8 = "old-cluster-embeddings-int8"; final String oldClusterIdFloat = "old-cluster-embeddings-float"; @@ -191,9 +190,9 @@ public class CohereServiceUpgradeIT extends InferenceUpgradeTestCase { @SuppressWarnings("unchecked") public void testRerank() throws IOException { - var rerankSupported = getOldClusterTestVersion().onOrAfter(COHERE_RERANK_ADDED); - String old_cluster_endpoint_identifier = oldClusterHasFeature("gte_v" + MODELS_RENAMED_TO_ENDPOINTS) ? "endpoints" : "models"; - assumeTrue("Cohere rerank service added in " + COHERE_RERANK_ADDED, rerankSupported); + var rerankSupported = oldClusterHasFeature(COHERE_RERANK_ADDED_TEST_FEATURE); + String old_cluster_endpoint_identifier = oldClusterHasFeature(MODELS_RENAMED_TO_ENDPOINTS_FEATURE) ? "endpoints" : "models"; + assumeTrue("Cohere rerank service supported", rerankSupported); final String oldClusterId = "old-cluster-rerank"; final String upgradedClusterId = "upgraded-cluster-rerank"; diff --git a/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/HuggingFaceServiceUpgradeIT.java b/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/HuggingFaceServiceUpgradeIT.java index 61556e02e5cd..41e67d7f3985 100644 --- a/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/HuggingFaceServiceUpgradeIT.java +++ b/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/HuggingFaceServiceUpgradeIT.java @@ -29,8 +29,9 @@ import static org.hamcrest.Matchers.nullValue; public class HuggingFaceServiceUpgradeIT extends InferenceUpgradeTestCase { - private static final String HF_EMBEDDINGS_ADDED = "8.12.0"; - private static final String HF_ELSER_ADDED = "8.12.0"; + // TODO: replace with proper test features + private static final String HF_EMBEDDINGS_TEST_FEATURE = "gte_v8.12.0"; + private static final String HF_ELSER_TEST_FEATURE = "gte_v8.12.0"; private static MockWebServer embeddingsServer; private static MockWebServer elserServer; @@ -56,10 +57,9 @@ public class HuggingFaceServiceUpgradeIT extends InferenceUpgradeTestCase { @SuppressWarnings("unchecked") public void testHFEmbeddings() throws IOException { - var embeddingsSupported = getOldClusterTestVersion().onOrAfter(HF_EMBEDDINGS_ADDED); - // `gte_v` indicates that the cluster version is Greater Than or Equal to MODELS_RENAMED_TO_ENDPOINTS - String oldClusterEndpointIdentifier = oldClusterHasFeature("gte_v" + MODELS_RENAMED_TO_ENDPOINTS) ? "endpoints" : "models"; - assumeTrue("Hugging Face embedding service added in " + HF_EMBEDDINGS_ADDED, embeddingsSupported); + var embeddingsSupported = oldClusterHasFeature(HF_EMBEDDINGS_TEST_FEATURE); + String oldClusterEndpointIdentifier = oldClusterHasFeature(MODELS_RENAMED_TO_ENDPOINTS_FEATURE) ? "endpoints" : "models"; + assumeTrue("Hugging Face embedding service supported", embeddingsSupported); final String oldClusterId = "old-cluster-embeddings"; final String upgradedClusterId = "upgraded-cluster-embeddings"; @@ -110,9 +110,9 @@ public class HuggingFaceServiceUpgradeIT extends InferenceUpgradeTestCase { @SuppressWarnings("unchecked") public void testElser() throws IOException { - var supported = getOldClusterTestVersion().onOrAfter(HF_ELSER_ADDED); - String old_cluster_endpoint_identifier = oldClusterHasFeature("gte_v" + MODELS_RENAMED_TO_ENDPOINTS) ? "endpoints" : "models"; - assumeTrue("HF elser service added in " + HF_ELSER_ADDED, supported); + var supported = oldClusterHasFeature(HF_ELSER_TEST_FEATURE); + String old_cluster_endpoint_identifier = oldClusterHasFeature(MODELS_RENAMED_TO_ENDPOINTS_FEATURE) ? "endpoints" : "models"; + assumeTrue("HF elser service supported", supported); final String oldClusterId = "old-cluster-elser"; final String upgradedClusterId = "upgraded-cluster-elser"; diff --git a/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/InferenceUpgradeTestCase.java b/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/InferenceUpgradeTestCase.java index bdbaedf53281..7b28c562b13f 100644 --- a/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/InferenceUpgradeTestCase.java +++ b/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/InferenceUpgradeTestCase.java @@ -29,16 +29,18 @@ import static org.hamcrest.Matchers.containsString; public class InferenceUpgradeTestCase extends ParameterizedRollingUpgradeTestCase { - static final String MODELS_RENAMED_TO_ENDPOINTS = "8.15.0"; + static final String MODELS_RENAMED_TO_ENDPOINTS_FEATURE = "gte_v8.15.0"; public InferenceUpgradeTestCase(@Name("upgradedNodes") int upgradedNodes) { super(upgradedNodes); } + // Note we need to use OLD_CLUSTER_VERSION directly here, as it may contain special values (e.g. 0.0.0) the ElasticsearchCluster + // builder uses to lookup a particular distribution @ClassRule public static ElasticsearchCluster cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(getOldClusterTestVersion()) + .version(OLD_CLUSTER_VERSION) .nodes(NODE_NUM) .setting("xpack.security.enabled", "false") .setting("xpack.license.self_generated.type", "trial") diff --git a/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/OpenAiServiceUpgradeIT.java b/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/OpenAiServiceUpgradeIT.java index b6dcfcb84a77..0f6ac361dadf 100644 --- a/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/OpenAiServiceUpgradeIT.java +++ b/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/OpenAiServiceUpgradeIT.java @@ -31,9 +31,10 @@ import static org.hamcrest.Matchers.nullValue; public class OpenAiServiceUpgradeIT extends InferenceUpgradeTestCase { - private static final String OPEN_AI_EMBEDDINGS_ADDED = "8.12.0"; - private static final String OPEN_AI_EMBEDDINGS_MODEL_SETTING_MOVED = "8.13.0"; - private static final String OPEN_AI_COMPLETIONS_ADDED = "8.14.0"; + // TODO: replace with proper test features + private static final String OPEN_AI_EMBEDDINGS_TEST_FEATURE = "gte_v8.12.0"; + private static final String OPEN_AI_EMBEDDINGS_MODEL_SETTING_MOVED_TEST_FEATURE = "gte_v8.13.0"; + private static final String OPEN_AI_COMPLETIONS_TEST_FEATURE = "gte_v8.14.0"; private static MockWebServer openAiEmbeddingsServer; private static MockWebServer openAiChatCompletionsServer; @@ -59,10 +60,9 @@ public class OpenAiServiceUpgradeIT extends InferenceUpgradeTestCase { @SuppressWarnings("unchecked") public void testOpenAiEmbeddings() throws IOException { - var openAiEmbeddingsSupported = getOldClusterTestVersion().onOrAfter(OPEN_AI_EMBEDDINGS_ADDED); - // `gte_v` indicates that the cluster version is Greater Than or Equal to MODELS_RENAMED_TO_ENDPOINTS - String oldClusterEndpointIdentifier = oldClusterHasFeature("gte_v" + MODELS_RENAMED_TO_ENDPOINTS) ? "endpoints" : "models"; - assumeTrue("OpenAI embedding service added in " + OPEN_AI_EMBEDDINGS_ADDED, openAiEmbeddingsSupported); + var openAiEmbeddingsSupported = oldClusterHasFeature(OPEN_AI_EMBEDDINGS_TEST_FEATURE); + String oldClusterEndpointIdentifier = oldClusterHasFeature(MODELS_RENAMED_TO_ENDPOINTS_FEATURE) ? "endpoints" : "models"; + assumeTrue("OpenAI embedding service supported", openAiEmbeddingsSupported); final String oldClusterId = "old-cluster-embeddings"; final String upgradedClusterId = "upgraded-cluster-embeddings"; @@ -86,7 +86,8 @@ public class OpenAiServiceUpgradeIT extends InferenceUpgradeTestCase { var serviceSettings = (Map) configs.get(0).get("service_settings"); var taskSettings = (Map) configs.get(0).get("task_settings"); var modelIdFound = serviceSettings.containsKey("model_id") - || (taskSettings.containsKey("model") && getOldClusterTestVersion().onOrBefore(OPEN_AI_EMBEDDINGS_MODEL_SETTING_MOVED)); + || (taskSettings.containsKey("model") + && (oldClusterHasFeature(OPEN_AI_EMBEDDINGS_MODEL_SETTING_MOVED_TEST_FEATURE) == false)); assertTrue("model_id not found in config: " + configs, modelIdFound); assertEmbeddingInference(oldClusterId); @@ -124,9 +125,9 @@ public class OpenAiServiceUpgradeIT extends InferenceUpgradeTestCase { @SuppressWarnings("unchecked") public void testOpenAiCompletions() throws IOException { - var openAiEmbeddingsSupported = getOldClusterTestVersion().onOrAfter(OPEN_AI_COMPLETIONS_ADDED); - String old_cluster_endpoint_identifier = oldClusterHasFeature("gte_v" + MODELS_RENAMED_TO_ENDPOINTS) ? "endpoints" : "models"; - assumeTrue("OpenAI completions service added in " + OPEN_AI_COMPLETIONS_ADDED, openAiEmbeddingsSupported); + var openAiEmbeddingsSupported = oldClusterHasFeature(OPEN_AI_COMPLETIONS_TEST_FEATURE); + String old_cluster_endpoint_identifier = oldClusterHasFeature(MODELS_RENAMED_TO_ENDPOINTS_FEATURE) ? "endpoints" : "models"; + assumeTrue("OpenAI completions service supported" + OPEN_AI_COMPLETIONS_TEST_FEATURE, openAiEmbeddingsSupported); final String oldClusterId = "old-cluster-completions"; final String upgradedClusterId = "upgraded-cluster-completions"; @@ -145,7 +146,7 @@ public class OpenAiServiceUpgradeIT extends InferenceUpgradeTestCase { List> configs = new LinkedList<>(); var request = get(testTaskType, oldClusterId); configs.addAll((Collection>) request.getOrDefault("endpoints", List.of())); - if (oldClusterHasFeature("gte_v" + MODELS_RENAMED_TO_ENDPOINTS) == false) { + if (oldClusterHasFeature(MODELS_RENAMED_TO_ENDPOINTS_FEATURE) == false) { configs.addAll((List>) request.getOrDefault(old_cluster_endpoint_identifier, List.of())); // in version 8.15, there was a breaking change where "models" was renamed to "endpoints" } @@ -186,7 +187,7 @@ public class OpenAiServiceUpgradeIT extends InferenceUpgradeTestCase { } private String oldClusterVersionCompatibleEmbeddingConfig() { - if (getOldClusterTestVersion().before(OPEN_AI_EMBEDDINGS_MODEL_SETTING_MOVED)) { + if (oldClusterHasFeature(OPEN_AI_EMBEDDINGS_MODEL_SETTING_MOVED_TEST_FEATURE) == false) { return embeddingConfigWithModelInTaskSettings(getUrl(openAiEmbeddingsServer)); } else { return embeddingConfigWithModelInServiceSettings(getUrl(openAiEmbeddingsServer));