From d058b7e46acca95a4208fa411ec1e26322834177 Mon Sep 17 00:00:00 2001 From: Mariusz Jozala Date: Thu, 11 Sep 2025 23:16:58 +0200 Subject: [PATCH 01/16] [Test] Replace 0.0.0 version with "detached" property on ElasticsearchDistibution for tests Introduce a new property to indicate if the version is a custom build not tied to any release. This was previously handled by specifying version as 0.0.0, but caused problems when comparing versions (e.g., to decide on configuration). --- ...lDistributionDownloadPluginFuncTest.groovy | 47 ++++++++++++++--- .../elasticsearch.bc-upgrade-test.gradle | 16 ++++-- .../InternalDistributionDownloadPlugin.java | 13 +++-- .../test/rest/RestTestBasePlugin.java | 50 ++++++++++++++++--- .../gradle/ElasticsearchDistribution.java | 15 ++++++ .../org/elasticsearch/gradle/Version.java | 4 ++ .../elasticsearch/gradle/VersionSpec.groovy | 6 +++ qa/full-cluster-restart/build.gradle | 16 ++++-- .../AbstractRollingUpgradeTestCase.java | 5 +- ...actRollingUpgradeWithSecurityTestCase.java | 5 +- .../upgrades/FileSettingsUpgradeIT.java | 5 +- .../ParameterizedRollingUpgradeTestCase.java | 15 ++++-- .../local/AbstractLocalClusterFactory.java | 8 +-- .../AbstractLocalClusterSpecBuilder.java | 1 + .../local/AbstractLocalSpecBuilder.java | 15 ++++++ .../test/cluster/local/LocalClusterSpec.java | 20 +++++--- .../test/cluster/local/LocalSpecBuilder.java | 5 ++ .../distribution/DistributionResolver.java | 2 +- .../LocalDistributionResolver.java | 6 +-- .../ReleasedDistributionResolver.java | 2 +- .../SnapshotDistributionResolver.java | 7 ++- .../application/InferenceUpgradeTestCase.java | 5 +- ...dardToLogsDbIndexModeRollingUpgradeIT.java | 3 +- 23 files changed, 207 insertions(+), 64 deletions(-) diff --git a/build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/internal/InternalDistributionDownloadPluginFuncTest.groovy b/build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/internal/InternalDistributionDownloadPluginFuncTest.groovy index c7643da1c73b9..57f4fd6d7f625 100644 --- a/build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/internal/InternalDistributionDownloadPluginFuncTest.groovy +++ b/build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/internal/InternalDistributionDownloadPluginFuncTest.groovy @@ -51,7 +51,7 @@ class InternalDistributionDownloadPluginFuncTest extends AbstractGradleFuncTest def "resolves expanded bwc versions from source"() { given: internalBuild() - bwcMajor1ProjectSetup() + bwcProjectSetup("major1") buildFile << """ apply plugin: 'elasticsearch.internal-distribution-download' @@ -81,7 +81,7 @@ class InternalDistributionDownloadPluginFuncTest extends AbstractGradleFuncTest def "fails on resolving bwc versions with no bundled jdk"() { given: internalBuild() - bwcMajor1ProjectSetup() + bwcProjectSetup("major1") buildFile << """ apply plugin: 'elasticsearch.internal-distribution-download' @@ -105,12 +105,47 @@ class InternalDistributionDownloadPluginFuncTest extends AbstractGradleFuncTest "without a bundled JDK is not supported.") } - private void bwcMajor1ProjectSetup() { + def "resolves detached version from source"() { + given: + internalBuild() + bwcProjectSetup("main") + buildFile << """ + apply plugin: 'elasticsearch.internal-distribution-download' + + System.setProperty("tests.bwc.main.version", "9.2.0") + + elasticsearch_distributions { + test_distro { + version = "9.2.0" + type = "archive" + platform = "linux" + architecture = Architecture.current(); + detachedVersion = true + } + } + + tasks.register("setupDistro", Sync) { + from(elasticsearch_distributions.test_distro) + into("build/distro") + } + """ + + when: + def result = gradleRunner("setupDistro").build() + + then: + result.task(":distribution:bwc:main:buildBwcExpandedTask").outcome == TaskOutcome.SUCCESS + result.task(":setupDistro").outcome == TaskOutcome.SUCCESS + assertExtractedDistroIsCreated("distribution/bwc/main/build/install/elastic-distro", + 'bwc-marker.txt') + } + + private void bwcProjectSetup(String bwcProjectName) { settingsFile << """ - include ':distribution:bwc:major1' + include ':distribution:bwc:$bwcProjectName' """ - def bwcSubProjectFolder = testProjectDir.newFolder("distribution", "bwc", "major1") - new File(bwcSubProjectFolder, 'bwc-marker.txt') << "bwc=major1" + def bwcSubProjectFolder = testProjectDir.newFolder("distribution", "bwc", bwcProjectName) + new File(bwcSubProjectFolder, 'bwc-marker.txt') << "bwc=$bwcProjectName" new File(bwcSubProjectFolder, 'build.gradle') << """ apply plugin:'base' diff --git a/build-tools-internal/src/main/groovy/elasticsearch.bc-upgrade-test.gradle b/build-tools-internal/src/main/groovy/elasticsearch.bc-upgrade-test.gradle index 94702c840c745..3af273c0d6f34 100644 --- a/build-tools-internal/src/main/groovy/elasticsearch.bc-upgrade-test.gradle +++ b/build-tools-internal/src/main/groovy/elasticsearch.bc-upgrade-test.gradle @@ -11,8 +11,16 @@ import org.elasticsearch.gradle.Version import org.elasticsearch.gradle.testclusters.StandaloneRestIntegTestTask tasks.register("bcUpgradeTest", StandaloneRestIntegTestTask) { - // We use a phony version here as the real version is provided via `tests.bwc.main.version` system property - usesBwcDistribution(Version.fromString("0.0.0")) - systemProperty("tests.old_cluster_version", "0.0.0") - onlyIf("tests.bwc.main.version system property exists") { System.getProperty("tests.bwc.main.version") != null } + doFirst { + if (System.getProperty("tests.bwc.refspec.main") == null) { + throw new GradleException("You must set the `tests.bwc.refspec.main` system property to run bcUpgradeTest") + } + if (System.getProperty("tests.bwc.main.version") == null) { + throw new GradleException("You must set the `tests.bwc.main.version` system property to run bcUpgradeTest") + } + } + if (System.getProperty("tests.bwc.refspec.main") != null && System.getProperty("tests.bwc.main.version") != null) { + usesBwcDistributionFromRef(System.getProperty("tests.bwc.refspec.main"), Version.fromString(System.getProperty("tests.bwc.main.version"))) + systemProperty("tests.old_cluster_version", System.getProperty("tests.bwc.main.version")) + } } diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/InternalDistributionDownloadPlugin.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/InternalDistributionDownloadPlugin.java index 4c0c224aff3f3..d16bb5efd557f 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/InternalDistributionDownloadPlugin.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/InternalDistributionDownloadPlugin.java @@ -74,7 +74,7 @@ public void apply(Project project) { */ private void registerInternalDistributionResolutions(List resolutions, Provider bwcVersions) { resolutions.add(new DistributionResolution("local-build", (project, distribution) -> { - if (isCurrentVersion(distribution)) { + if (isCurrentVersion(distribution) && distribution.isDetachedVersion() == false) { // non-external project, so depend on local build return new ProjectBasedDistributionDependency( config -> projectDependency(project.getDependencies(), distributionProjectPath(distribution), config) @@ -86,7 +86,7 @@ private void registerInternalDistributionResolutions(List { BwcVersions.UnreleasedVersionInfo unreleasedInfo = bwcVersions.get() .unreleasedInfo(Version.fromString(distribution.getVersion())); - if (unreleasedInfo != null) { + if (unreleasedInfo != null && distribution.isDetachedVersion() == false) { if (distribution.getBundledJdk() == false) { throw new GradleException( "Configuring a snapshot bwc distribution ('" @@ -103,16 +103,15 @@ private void registerInternalDistributionResolutions(List { - String versionProperty = System.getProperty("tests.bwc.main.version"); - // We use this phony version as a placeholder for the real version - if (distribution.getVersion().equals("0.0.0")) { + resolutions.add(new DistributionResolution("detached", (project, distribution) -> { + if (distribution.isDetachedVersion()) { + String versionProperty = System.getProperty("tests.bwc.main.version"); BwcVersions.UnreleasedVersionInfo unreleasedVersionInfo = new BwcVersions.UnreleasedVersionInfo( Version.fromString(versionProperty), "main", diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/RestTestBasePlugin.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/RestTestBasePlugin.java index 2f9fe2ed06e98..c6ff0a425fcd7 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/RestTestBasePlugin.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/RestTestBasePlugin.java @@ -100,13 +100,15 @@ public void apply(Project project) { ElasticsearchDistribution defaultDistro = createDistribution( project, DEFAULT_REST_INTEG_TEST_DISTRO, - VersionProperties.getElasticsearch() + VersionProperties.getElasticsearch(), + false ); ElasticsearchDistribution integTestDistro = createDistribution( project, INTEG_TEST_REST_INTEG_TEST_DISTRO, VersionProperties.getElasticsearch(), - ElasticsearchDistributionTypes.INTEG_TEST_ZIP + ElasticsearchDistributionTypes.INTEG_TEST_ZIP, + false ); // Create configures for module and plugin dependencies @@ -232,9 +234,9 @@ public Void call(Object... args) { } Version version = (Version) args[0]; - boolean isReleased = bwcVersions.unreleasedInfo(version) == null && version.toString().equals("0.0.0") == false; + boolean isReleased = bwcVersions.unreleasedInfo(version) == null; String versionString = version.toString(); - ElasticsearchDistribution bwcDistro = createDistribution(project, "bwc_" + versionString, versionString); + ElasticsearchDistribution bwcDistro = createDistribution(project, "bwc_" + versionString, versionString, false); task.dependsOn(bwcDistro); registerDistributionInputs(task, bwcDistro); @@ -244,13 +246,38 @@ public Void call(Object... args) { providerFactory.provider(() -> bwcDistro.getExtracted().getSingleFile().getPath()) ); - if (version.getMajor() > 0 && version.before(bwcVersions.getMinimumWireCompatibleVersion())) { + if (version.before(bwcVersions.getMinimumWireCompatibleVersion())) { // If we are upgrade testing older versions we also need to upgrade to 7.last this.call(bwcVersions.getMinimumWireCompatibleVersion()); } return null; } }); + + task.getExtensions().getExtraProperties().set("usesBwcDistributionFromRef", new Closure(task) { + @Override + public Void call(Object... args) { + if (args.length != 2 || args[0] instanceof String == false || args[1] instanceof Version == false) { + throw new IllegalArgumentException("Expected arguments (String refSpec, org.elasticsearch.gradle.Version version)"); + } + + String refSpec = (String) args[0]; + Version version = (Version) args[1]; + boolean isDetachedVersion = true; + String versionString = version.toString(); + + ElasticsearchDistribution bwcDistro = createDistribution(project, "bwc_" + refSpec, versionString, isDetachedVersion); + + task.dependsOn(bwcDistro); + registerDistributionInputs(task, bwcDistro); + + nonInputSystemProperties.systemProperty( + BWC_SNAPSHOT_DISTRIBUTION_SYSPROP_PREFIX + versionString, + providerFactory.provider(() -> bwcDistro.getExtracted().getSingleFile().getPath()) + ); + return null; + } + }); }); } @@ -262,16 +289,23 @@ private void copyDependencies(Project project, DependencySet dependencies, Confi .forEach(dependencies::add); } - private ElasticsearchDistribution createDistribution(Project project, String name, String version) { - return createDistribution(project, name, version, null); + private ElasticsearchDistribution createDistribution(Project project, String name, String version, boolean detachedVersion) { + return createDistribution(project, name, version, null, detachedVersion); } - private ElasticsearchDistribution createDistribution(Project project, String name, String version, ElasticsearchDistributionType type) { + private ElasticsearchDistribution createDistribution( + Project project, + String name, + String version, + ElasticsearchDistributionType type, + boolean detachedVersion + ) { NamedDomainObjectContainer distributions = DistributionDownloadPlugin.getContainer(project); ElasticsearchDistribution maybeDistro = distributions.findByName(name); if (maybeDistro == null) { return distributions.create(name, distro -> { distro.setVersion(version); + distro.setDetachedVersion(detachedVersion); distro.setArchitecture(Architecture.current()); if (type != null) { distro.setType(type); diff --git a/build-tools/src/main/java/org/elasticsearch/gradle/ElasticsearchDistribution.java b/build-tools/src/main/java/org/elasticsearch/gradle/ElasticsearchDistribution.java index 3f9669af0568b..94d373cc59add 100644 --- a/build-tools/src/main/java/org/elasticsearch/gradle/ElasticsearchDistribution.java +++ b/build-tools/src/main/java/org/elasticsearch/gradle/ElasticsearchDistribution.java @@ -49,6 +49,7 @@ public String toString() { private final Property architecture; private final Property version; + private final Property detachedVersion; private final Property type; private final Property platform; private final Property bundledJdk; @@ -69,6 +70,7 @@ public String toString() { this.configuration = fileConfiguration; this.architecture = objectFactory.property(Architecture.class); this.version = objectFactory.property(String.class).convention(VersionProperties.getElasticsearch()); + this.detachedVersion = objectFactory.property(Boolean.class).convention(false); this.type = objectFactory.property(ElasticsearchDistributionType.class); this.type.convention(ElasticsearchDistributionTypes.ARCHIVE); this.platform = objectFactory.property(Platform.class); @@ -91,6 +93,19 @@ public void setVersion(String version) { this.version.set(version); } + /** + * Informs if the version is not tied to any Elasticsearch release and is a custom build. + * This is true when the distribution is not from HEAD but also not any known released version. + * In that case the detached source build needs to be prepared by `usedBwcDistributionFromRef(ref, version)`. + */ + public boolean isDetachedVersion() { + return detachedVersion.get(); + } + + public void setDetachedVersion(boolean detachedVersion) { + this.detachedVersion.set(detachedVersion); + } + public Platform getPlatform() { return platform.getOrNull(); } diff --git a/build-tools/src/main/java/org/elasticsearch/gradle/Version.java b/build-tools/src/main/java/org/elasticsearch/gradle/Version.java index f0bc936e683a2..2efeb39047247 100644 --- a/build-tools/src/main/java/org/elasticsearch/gradle/Version.java +++ b/build-tools/src/main/java/org/elasticsearch/gradle/Version.java @@ -79,6 +79,10 @@ public static Version fromString(final String s, final Mode mode) { String revision = matcher.group(3); String qualifier = matcher.group(4); + if (major.equals("0") && minor.equals("0") && revision.equals("0")) { + throw new IllegalArgumentException("Version 0.0.0 is not allowed"); + } + return new Version(Integer.parseInt(major), Integer.parseInt(minor), revision == null ? 0 : Integer.parseInt(revision), qualifier); } diff --git a/build-tools/src/test/groovy/org/elasticsearch/gradle/VersionSpec.groovy b/build-tools/src/test/groovy/org/elasticsearch/gradle/VersionSpec.groovy index 96a7c63d665ed..65c5e8e5fb071 100644 --- a/build-tools/src/test/groovy/org/elasticsearch/gradle/VersionSpec.groovy +++ b/build-tools/src/test/groovy/org/elasticsearch/gradle/VersionSpec.groovy @@ -76,6 +76,12 @@ class VersionSpec extends Specification { then: e = thrown(IllegalArgumentException) assert e.message == "Invalid version format: 'foo.bar.baz'. Should be major.minor.revision[-(alpha|beta|rc)Number|-SNAPSHOT]" + + when: + Version.fromString("0.0.0") + then: + e = thrown(IllegalArgumentException) + assert e.message == "Version 0.0.0 is not allowed" } def "handles qualifier"() { diff --git a/qa/full-cluster-restart/build.gradle b/qa/full-cluster-restart/build.gradle index 55881b7b29d20..b5b81d41c170f 100644 --- a/qa/full-cluster-restart/build.gradle +++ b/qa/full-cluster-restart/build.gradle @@ -23,10 +23,18 @@ buildParams.bwcVersions.withIndexCompatible { bwcVersion, baseName -> } tasks.register("luceneBwcTest", StandaloneRestIntegTestTask) { - // We use a phony version here as the real version is provided via `tests.bwc.main.version` system property - usesBwcDistribution(Version.fromString("0.0.0")) - systemProperty("tests.old_cluster_version", "0.0.0") - onlyIf("tests.bwc.main.version system property exists") { System.getProperty("tests.bwc.main.version") != null } + doFirst { + if (System.getProperty("tests.bwc.refspec.main") == null) { + throw new GradleException("You must set the `tests.bwc.refspec.main` system property to run luceneBwcTest") + } + if (System.getProperty("tests.bwc.main.version") == null) { + throw new GradleException("You must set the `tests.bwc.main.version` system property to run luceneBwcTest") + } + } + if (System.getProperty("tests.bwc.refspec.main") != null && System.getProperty("tests.bwc.main.version") != null) { + usesBwcDistributionFromRef(System.getProperty("tests.bwc.refspec.main"), Version.fromString(System.getProperty("tests.bwc.main.version"))) + systemProperty("tests.old_cluster_version", System.getProperty("tests.bwc.main.version")) + } } tasks.named("bcUpgradeTest").configure { 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 87096277cfce6..2b19044459e79 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,11 +30,10 @@ public abstract class AbstractRollingUpgradeTestCase extends ParameterizedRollin private static final ElasticsearchCluster cluster = buildCluster(); private static ElasticsearchCluster buildCluster() { - // 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(OLD_CLUSTER_VERSION) + .version(getOldClusterVersion()) + .detachedVersion(isOldClusterDetachedVersion()) .nodes(NODE_NUM) .setting("path.repo", new Supplier<>() { @Override 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 961e4a353df95..0b3fb6cd7acab 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,11 +35,10 @@ public abstract class AbstractRollingUpgradeWithSecurityTestCase extends Paramet private static final ElasticsearchCluster cluster = buildCluster(); private static ElasticsearchCluster buildCluster() { - // 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(OLD_CLUSTER_VERSION) + .version(getOldClusterVersion()) + .detachedVersion(isOldClusterDetachedVersion()) .nodes(NODE_NUM) .user(USER, PASS) .setting("xpack.security.autoconfiguration.enabled", "false") 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 6d16714cc67bb..b9c7a70c8a3e1 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 @@ -57,11 +57,10 @@ 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(OLD_CLUSTER_VERSION) + .version(getOldClusterVersion()) + .detachedVersion(isOldClusterDetachedVersion()) .nodes(NODE_NUM) .setting("path.repo", new Supplier<>() { @Override 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 43a9081964483..876ac7fae9d8c 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 @@ -36,7 +36,7 @@ public abstract class ParameterizedRollingUpgradeTestCase extends ESRestTestCase { protected static final int NODE_NUM = 3; - protected static final String OLD_CLUSTER_VERSION = System.getProperty("tests.old_cluster_version"); + private static final String OLD_CLUSTER_VERSION = System.getProperty("tests.old_cluster_version"); private static final Set upgradedNodes = new HashSet<>(); private static TestFeatureService oldClusterTestFeatureService = null; private static boolean upgradeFailed = false; @@ -149,10 +149,17 @@ protected static String getOldClusterVersion() { return System.getProperty("tests.bwc.main.version", OLD_CLUSTER_VERSION); } + /** + * Whether the old cluster version is not of the released versions, but a detached build. + * In that case the Git ref has to be specified via {@code tests.bwc.refspec.main} system property. + */ + protected static boolean isOldClusterDetachedVersion() { + return System.getProperty("tests.bwc.refspec.main") != null; + } + protected static boolean isOldClusterVersion(String nodeVersion, String buildHash) { - String bwcRefSpec = System.getProperty("tests.bwc.refspec.main"); - if (bwcRefSpec != null) { - return bwcRefSpec.equals(buildHash); + if (isOldClusterDetachedVersion()) { + return System.getProperty("tests.bwc.refspec.main").equals(buildHash); } return getOldClusterVersion().equals(nodeVersion); } diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java index 10fd1de940d00..98c8dd80f730c 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java @@ -74,7 +74,7 @@ public abstract class AbstractLocalClusterFactory { private static final Logger LOGGER = LogManager.getLogger(AbstractLocalClusterFactory.class); private static final Duration NODE_UP_TIMEOUT = Duration.ofMinutes(6); - private static final Map, DistributionDescriptor> TEST_DISTRIBUTIONS = new ConcurrentHashMap<>(); + private static final Map TEST_DISTRIBUTIONS = new ConcurrentHashMap<>(); private static final String TESTS_CLUSTER_MODULES_PATH_SYSPROP = "tests.cluster.modules.path"; private static final String TESTS_CLUSTER_PLUGINS_PATH_SYSPROP = "tests.cluster.plugins.path"; private static final String TESTS_CLUSTER_FIPS_JAR_PATH_SYSPROP = "tests.cluster.fips.jars.path"; @@ -396,8 +396,8 @@ private void copyExtraJarFiles() { private DistributionDescriptor resolveDistribution() { return TEST_DISTRIBUTIONS.computeIfAbsent( - Pair.of(spec.getVersion(), spec.getDistributionType()), - key -> distributionResolver.resolve(key.left, key.right) + new DistributionKey(spec.getVersion(), spec.isDetachedVersion(), spec.getDistributionType()), + key -> distributionResolver.resolve(key.version, key.detachedVersion, key.distributionType) ); } @@ -985,4 +985,6 @@ public String toString() { return "{ cluster: '" + spec.getCluster().getName() + "', node: '" + name + "' }"; } } + + public record DistributionKey(Version version, boolean detachedVersion, DistributionType distributionType) {} } diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterSpecBuilder.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterSpecBuilder.java index 73c5afdec5b9f..93d2c0cc2512d 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterSpecBuilder.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterSpecBuilder.java @@ -197,6 +197,7 @@ private LocalNodeSpec build(LocalClusterSpec cluster, int nodeIndex) { cluster, resolveName(cluster, nodeIndex), Optional.ofNullable(getVersion()).orElse(Version.CURRENT), + isDetachedVersion(), getSettingsProviders(), getSettings(), getEnvironmentProviders(), diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java index 3deadf49cca30..5c3e2aa7e7808 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java @@ -47,6 +47,7 @@ public abstract class AbstractLocalSpecBuilder> im private final List jvmArgs = new ArrayList<>(); private DistributionType distributionType; private Version version; + private Boolean detachedVersion; private String keystorePassword; private Supplier configDirSupplier; @@ -305,6 +306,20 @@ public Version getVersion() { return inherit(() -> parent.getVersion(), version); } + @Override + public T detachedVersion(boolean detachedVersion) { + this.detachedVersion = detachedVersion; + return cast(this); + } + + public boolean isDetachedVersion() { + Boolean isDetached = inherit(() -> parent.isDetachedVersion(), detachedVersion); + if (isDetached != null) { + return isDetached; + } + return false; + } + private List inherit(Supplier> parent, List child) { List combinedList = new ArrayList<>(); if (this.parent != null) { diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java index 633381cefbbbb..f50e06b50bc21 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java @@ -106,11 +106,13 @@ public static class LocalNodeSpec { private final List jvmArgs; private final Path configDir; private Version version; + private final boolean detachedVersion; public LocalNodeSpec( LocalClusterSpec cluster, String name, Version version, + boolean detachedVersion, List settingsProviders, Map settings, List environmentProviders, @@ -132,6 +134,7 @@ public LocalNodeSpec( this.cluster = cluster; this.name = name; this.version = version; + this.detachedVersion = detachedVersion; this.settingsProviders = settingsProviders; this.settings = settings; this.environmentProviders = environmentProviders; @@ -167,6 +170,15 @@ public Version getVersion() { return version; } + /** + * Informs if the version is not tied to any Elasticsearch release and is a custom build. + * This is true when the distribution is not from HEAD but also not any known released version. + * In that case the detached source build needs to be prepared by `usedBwcDistributionFromRef(ref, version)`. + */ + public boolean isDetachedVersion() { + return detachedVersion; + } + public List getUsers() { return cluster.getUsers(); } @@ -212,12 +224,7 @@ public Path getConfigDir() { } public boolean isSecurityEnabled() { - return Boolean.parseBoolean( - getSetting( - "xpack.security.enabled", - getVersion().equals(Version.fromString("0.0.0")) || getVersion().onOrAfter("8.0.0") ? "true" : "false" - ) - ); + return Boolean.parseBoolean(getSetting("xpack.security.enabled", getVersion().onOrAfter("8.0.0") ? "true" : "false")); } public boolean isRemoteClusterServerEnabled() { @@ -337,6 +344,7 @@ private LocalNodeSpec getFilteredSpec(SettingsProvider filteredProvider, Setting newCluster, n.name, n.version, + n.detachedVersion, n.settingsProviders.stream().filter(s -> s != filteredProvider).toList(), n.settings, n.environmentProviders, diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java index 53d283224b26f..553ed5b33be3e 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java @@ -136,6 +136,11 @@ interface LocalSpecBuilder> { */ T version(String version); + /** + * Sets whether using unreleased version of Elasticsearch, different from the local current HEAD. Defaults to false. + */ + T detachedVersion(boolean detachedVersion); + /** * Adds a system property to node JVM arguments. */ diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/DistributionResolver.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/DistributionResolver.java index 02d755c50c674..ff1f90f095e06 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/DistributionResolver.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/DistributionResolver.java @@ -13,5 +13,5 @@ public interface DistributionResolver { - DistributionDescriptor resolve(Version version, DistributionType type); + DistributionDescriptor resolve(Version version, boolean detachedVersion, DistributionType type); } diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/LocalDistributionResolver.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/LocalDistributionResolver.java index a853576d9b371..87526fcd53597 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/LocalDistributionResolver.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/LocalDistributionResolver.java @@ -25,8 +25,8 @@ public LocalDistributionResolver(DistributionResolver delegate) { } @Override - public DistributionDescriptor resolve(Version version, DistributionType type) { - if (version.equals(Version.CURRENT)) { + public DistributionDescriptor resolve(Version version, boolean detachedVersion, DistributionType type) { + if (version.equals(Version.CURRENT) && detachedVersion == false) { String testDistributionPath = System.getProperty(type.getSystemProperty()); if (testDistributionPath == null) { @@ -67,6 +67,6 @@ public DistributionDescriptor resolve(Version version, DistributionType type) { ); } - return delegate.resolve(version, type); + return delegate.resolve(version, detachedVersion, type); } } diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/ReleasedDistributionResolver.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/ReleasedDistributionResolver.java index f76c5ad4d1dee..87521ce837e51 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/ReleasedDistributionResolver.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/ReleasedDistributionResolver.java @@ -21,7 +21,7 @@ public class ReleasedDistributionResolver implements DistributionResolver { private static final String BWC_DISTRIBUTION_SYSPROP_PREFIX = "tests.release.distribution."; @Override - public DistributionDescriptor resolve(Version version, DistributionType type) { + public DistributionDescriptor resolve(Version version, boolean detachedVersion, DistributionType type) { String distributionPath = System.getProperty(BWC_DISTRIBUTION_SYSPROP_PREFIX + version.toString()); if (distributionPath == null) { diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/SnapshotDistributionResolver.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/SnapshotDistributionResolver.java index db71f8cec9ab4..fb7ca46345e85 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/SnapshotDistributionResolver.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/SnapshotDistributionResolver.java @@ -26,7 +26,7 @@ public SnapshotDistributionResolver(DistributionResolver delegate) { } @Override - public DistributionDescriptor resolve(Version version, DistributionType type) { + public DistributionDescriptor resolve(Version version, boolean detachedVersion, DistributionType type) { String distributionPath = System.getProperty(BWC_DISTRIBUTION_SYSPROP_PREFIX + version.toString()); if (distributionPath != null) { @@ -38,11 +38,10 @@ public DistributionDescriptor resolve(Version version, DistributionType type) { } // Snapshot distributions are never release builds and always use the default distribution - Version realVersion = Version.fromString(System.getProperty("tests.bwc.main.version", version.toString())); boolean isSnapshot = System.getProperty("tests.bwc.snapshot", "true").equals("false") == false; - return new DefaultDistributionDescriptor(realVersion, isSnapshot, distributionDir, DistributionType.DEFAULT); + return new DefaultDistributionDescriptor(version, isSnapshot, distributionDir, DistributionType.DEFAULT); } - return delegate.resolve(version, type); + return delegate.resolve(version, detachedVersion, type); } } 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 7b28c562b13fc..53824be0e4385 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 @@ -35,12 +35,11 @@ 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(OLD_CLUSTER_VERSION) + .version(getOldClusterVersion()) + .detachedVersion(isOldClusterDetachedVersion()) .nodes(NODE_NUM) .setting("xpack.security.enabled", "false") .setting("xpack.license.self_generated.type", "trial") diff --git a/x-pack/plugin/logsdb/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/StandardToLogsDbIndexModeRollingUpgradeIT.java b/x-pack/plugin/logsdb/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/StandardToLogsDbIndexModeRollingUpgradeIT.java index e8cf3027ac067..7dc81f8cd7d49 100644 --- a/x-pack/plugin/logsdb/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/StandardToLogsDbIndexModeRollingUpgradeIT.java +++ b/x-pack/plugin/logsdb/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/StandardToLogsDbIndexModeRollingUpgradeIT.java @@ -46,7 +46,8 @@ public class StandardToLogsDbIndexModeRollingUpgradeIT extends AbstractRollingUp @ClassRule() public static final ElasticsearchCluster cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(OLD_CLUSTER_VERSION) + .version(getOldClusterVersion()) + .detachedVersion(isOldClusterDetachedVersion()) .nodes(NODE_NUM) .user(USER, PASS) .module("constant-keyword") From fd5b4572d531ed90c8a1aad3715439488a15bb6a Mon Sep 17 00:00:00 2001 From: Mariusz Jozala Date: Fri, 12 Sep 2025 11:49:54 +0200 Subject: [PATCH 02/16] Change test clusters configuration to support bcUpgradeTest explicitly Added `.detachedVersion(System.getProperty("tests.bwc.refspec.main") != null)` to all the tests which apply 'elasticsearch.bc-upgrade-test' plugin to make them properly resolve distribution (previously configured by specifying `0.0.0` version). --- .../elasticsearch/ingest/geoip/FullClusterRestartIT.java | 1 + .../upgrades/FullClusterRestartArchivedSettingsIT.java | 1 + .../upgrades/FullClusterRestartDownsampleIT.java | 1 + .../org/elasticsearch/upgrades/FullClusterRestartIT.java | 1 + .../upgrades/LogsIndexModeFullClusterRestartIT.java | 1 + .../org/elasticsearch/upgrades/QueryBuilderBWCIT.java | 1 + .../upgrades/ParameterizedRollingUpgradeTestCase.java | 8 -------- .../java/org/elasticsearch/test/rest/ESRestTestCase.java | 8 ++++++++ .../xpack/application/FullClusterRestartIT.java | 1 + .../org/elasticsearch/xpack/esql/qa/mixed/Clusters.java | 5 +++-- .../xpack/inference/qa/mixed/MixedClustersSpec.java | 3 ++- .../RemoteClusterSecurityBWCToRCS1ClusterRestIT.java | 1 + .../RemoteClusterSecurityBWCToRCS2ClusterRestIT.java | 1 + .../elasticsearch/xpack/restart/FullClusterRestartIT.java | 1 + .../restart/AbstractXpackFullClusterRestartTestCase.java | 1 + 15 files changed, 24 insertions(+), 11 deletions(-) diff --git a/modules/ingest-geoip/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/ingest/geoip/FullClusterRestartIT.java b/modules/ingest-geoip/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/ingest/geoip/FullClusterRestartIT.java index a82b236c01aaa..6a1ee6b446541 100644 --- a/modules/ingest-geoip/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/ingest/geoip/FullClusterRestartIT.java +++ b/modules/ingest-geoip/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/ingest/geoip/FullClusterRestartIT.java @@ -42,6 +42,7 @@ public class FullClusterRestartIT extends ParameterizedFullClusterRestartTestCas private static final ElasticsearchCluster cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) .version(Version.fromString(OLD_CLUSTER_VERSION)) + .detachedVersion(isOldClusterDetachedVersion()) .nodes(2) .setting("ingest.geoip.downloader.endpoint", () -> fixture.getAddress(), s -> useFixture) .setting("xpack.security.enabled", "false") diff --git a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartArchivedSettingsIT.java b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartArchivedSettingsIT.java index fe0a9f33cb226..6f58e680bf4e1 100644 --- a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartArchivedSettingsIT.java +++ b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartArchivedSettingsIT.java @@ -46,6 +46,7 @@ public class FullClusterRestartArchivedSettingsIT extends ParameterizedFullClust private static ElasticsearchCluster cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) .version(Version.fromString(OLD_CLUSTER_VERSION)) + .detachedVersion(isOldClusterDetachedVersion()) .nodes(2) .setting("path.repo", () -> repoDirectory.getRoot().getPath()) .setting("xpack.security.enabled", "false") diff --git a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartDownsampleIT.java b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartDownsampleIT.java index 71352355fb61e..c3a3603c60b4a 100644 --- a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartDownsampleIT.java +++ b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartDownsampleIT.java @@ -51,6 +51,7 @@ private static ElasticsearchCluster buildCluster() { var cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) .version(Version.fromString(OLD_CLUSTER_VERSION)) + .detachedVersion(isOldClusterDetachedVersion()) .nodes(2) .setting("xpack.security.enabled", "false") .setting("indices.lifecycle.poll_interval", "5s") diff --git a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartIT.java b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartIT.java index cbe383a7da550..4dfbbdf0f9a44 100644 --- a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartIT.java +++ b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartIT.java @@ -110,6 +110,7 @@ private static ElasticsearchCluster buildCluster() { var cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) .version(Version.fromString(OLD_CLUSTER_VERSION)) + .detachedVersion(isOldClusterDetachedVersion()) .nodes(2) .setting("path.repo", () -> repoDirectory.getRoot().getPath()) .setting("xpack.security.enabled", "false") diff --git a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/LogsIndexModeFullClusterRestartIT.java b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/LogsIndexModeFullClusterRestartIT.java index d677c6adf2459..a09d74bd677f5 100644 --- a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/LogsIndexModeFullClusterRestartIT.java +++ b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/LogsIndexModeFullClusterRestartIT.java @@ -40,6 +40,7 @@ private static ElasticsearchCluster buildCluster() { var cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) .version(Version.fromString(OLD_CLUSTER_VERSION)) + .detachedVersion(isOldClusterDetachedVersion()) .module("constant-keyword") .module("data-streams") .module("mapper-extras") diff --git a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/QueryBuilderBWCIT.java b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/QueryBuilderBWCIT.java index d336de92c3e93..d867d65ad3f64 100644 --- a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/QueryBuilderBWCIT.java +++ b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/QueryBuilderBWCIT.java @@ -74,6 +74,7 @@ public class QueryBuilderBWCIT extends ParameterizedFullClusterRestartTestCase { public static ElasticsearchCluster cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) .version(org.elasticsearch.test.cluster.util.Version.fromString(OLD_CLUSTER_VERSION)) + .detachedVersion(isOldClusterDetachedVersion()) .nodes(2) .setting("xpack.security.enabled", "false") .apply(() -> clusterConfig) 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 876ac7fae9d8c..435ecaf8ee56c 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 @@ -149,14 +149,6 @@ protected static String getOldClusterVersion() { return System.getProperty("tests.bwc.main.version", OLD_CLUSTER_VERSION); } - /** - * Whether the old cluster version is not of the released versions, but a detached build. - * In that case the Git ref has to be specified via {@code tests.bwc.refspec.main} system property. - */ - protected static boolean isOldClusterDetachedVersion() { - return System.getProperty("tests.bwc.refspec.main") != null; - } - protected static boolean isOldClusterVersion(String nodeVersion, String buildHash) { if (isOldClusterDetachedVersion()) { return System.getProperty("tests.bwc.refspec.main").equals(buildHash); diff --git a/test/framework/src/main/java/org/elasticsearch/test/rest/ESRestTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/rest/ESRestTestCase.java index 1572c82510202..db1f50b9a30b4 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/rest/ESRestTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/rest/ESRestTestCase.java @@ -364,6 +364,14 @@ protected static boolean testFeatureServiceInitialized() { return testFeatureService != ALL_FEATURES; } + /** + * Whether the old cluster version is not of the released versions, but a detached build. + * In that case the Git ref has to be specified via {@code tests.bwc.refspec.main} system property. + */ + protected static boolean isOldClusterDetachedVersion() { + return System.getProperty("tests.bwc.refspec.main") != null; + } + @BeforeClass public static void initializeProjectIds() { // The active project-id is slightly longer, and has a fixed prefix so that it's easier to pick in error messages etc. diff --git a/x-pack/plugin/ent-search/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/application/FullClusterRestartIT.java b/x-pack/plugin/ent-search/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/application/FullClusterRestartIT.java index 7bebd8fe05a54..4cc5476902190 100644 --- a/x-pack/plugin/ent-search/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/application/FullClusterRestartIT.java +++ b/x-pack/plugin/ent-search/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/application/FullClusterRestartIT.java @@ -42,6 +42,7 @@ public class FullClusterRestartIT extends ParameterizedFullClusterRestartTestCas public static final ElasticsearchCluster cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) .version(org.elasticsearch.test.cluster.util.Version.fromString(OLD_CLUSTER_VERSION)) + .detachedVersion(isOldClusterDetachedVersion()) .nodes(2) .setting("xpack.security.enabled", "false") .setting("xpack.license.self_generated.type", "trial") diff --git a/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/Clusters.java b/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/Clusters.java index 9d4043dccab6a..7c1ab2c492634 100644 --- a/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/Clusters.java +++ b/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/Clusters.java @@ -14,11 +14,12 @@ public class Clusters { public static ElasticsearchCluster mixedVersionCluster() { Version oldVersion = Version.fromString(System.getProperty("tests.old_cluster_version")); + boolean isDetachedVersion = System.getProperty("tests.bwc.refspec.main") != null; var cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .withNode(node -> node.version(oldVersion)) + .withNode(node -> node.version(oldVersion).detachedVersion(isDetachedVersion)) .withNode(node -> node.version(Version.CURRENT)) - .withNode(node -> node.version(oldVersion)) + .withNode(node -> node.version(oldVersion).detachedVersion(isDetachedVersion)) .withNode(node -> node.version(Version.CURRENT)) .setting("xpack.security.enabled", "false") .setting("xpack.license.self_generated.type", "trial"); diff --git a/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/MixedClustersSpec.java b/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/MixedClustersSpec.java index 7802c2e966e01..706938f818d7b 100644 --- a/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/MixedClustersSpec.java +++ b/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/MixedClustersSpec.java @@ -14,9 +14,10 @@ public class MixedClustersSpec { public static ElasticsearchCluster mixedVersionCluster() { Version oldVersion = Version.fromString(System.getProperty("tests.old_cluster_version")); + boolean isDetachedVersion = System.getProperty("tests.bwc.refspec.main") != null; return ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .withNode(node -> node.version(oldVersion)) + .withNode(node -> node.version(oldVersion).detachedVersion(isDetachedVersion)) .withNode(node -> node.version(Version.CURRENT)) .setting("xpack.security.enabled", "false") .setting("xpack.license.self_generated.type", "trial") diff --git a/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS1ClusterRestIT.java b/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS1ClusterRestIT.java index 73e0f096039f9..7f536c59bff9d 100644 --- a/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS1ClusterRestIT.java +++ b/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS1ClusterRestIT.java @@ -31,6 +31,7 @@ public class RemoteClusterSecurityBWCToRCS1ClusterRestIT extends AbstractRemoteC static { fulfillingCluster = ElasticsearchCluster.local() .version(OLD_CLUSTER_VERSION) + .detachedVersion(isOldClusterDetachedVersion()) .distribution(DistributionType.DEFAULT) .name("fulfilling-cluster") .apply(commonClusterConfig) diff --git a/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS2ClusterRestIT.java b/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS2ClusterRestIT.java index 5e173b72c66de..63bbf7dc86057 100644 --- a/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS2ClusterRestIT.java +++ b/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS2ClusterRestIT.java @@ -35,6 +35,7 @@ public class RemoteClusterSecurityBWCToRCS2ClusterRestIT extends AbstractRemoteC fulfillingCluster = ElasticsearchCluster.local() .name("fulfilling-cluster") .version(OLD_CLUSTER_VERSION) + .detachedVersion(isOldClusterDetachedVersion()) .distribution(DistributionType.DEFAULT) .apply(commonClusterConfig) .setting("xpack.ml.enabled", "false") diff --git a/x-pack/plugin/shutdown/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/restart/FullClusterRestartIT.java b/x-pack/plugin/shutdown/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/restart/FullClusterRestartIT.java index d04560a2f47b2..2ed3dd9be96fc 100644 --- a/x-pack/plugin/shutdown/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/restart/FullClusterRestartIT.java +++ b/x-pack/plugin/shutdown/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/restart/FullClusterRestartIT.java @@ -47,6 +47,7 @@ public class FullClusterRestartIT extends ParameterizedFullClusterRestartTestCas public static ElasticsearchCluster cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) .version(Version.fromString(OLD_CLUSTER_VERSION)) + .detachedVersion(isOldClusterDetachedVersion()) .nodes(2) // some tests rely on the translog not being flushed .setting("indices.memory.shard_inactive_time", "60m") diff --git a/x-pack/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/restart/AbstractXpackFullClusterRestartTestCase.java b/x-pack/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/restart/AbstractXpackFullClusterRestartTestCase.java index 2c3e2e1ee69a3..146b569d3fe44 100644 --- a/x-pack/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/restart/AbstractXpackFullClusterRestartTestCase.java +++ b/x-pack/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/restart/AbstractXpackFullClusterRestartTestCase.java @@ -22,6 +22,7 @@ public abstract class AbstractXpackFullClusterRestartTestCase extends Parameteri public static ElasticsearchCluster cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) .version(Version.fromString(OLD_CLUSTER_VERSION)) + .detachedVersion(isOldClusterDetachedVersion()) .nodes(2) // some tests rely on the translog not being flushed .setting("indices.memory.shard_inactive_time", "60m") From 8da8b0f2eeaf94f25348f42cd4e6d5eb79c7dc4f Mon Sep 17 00:00:00 2001 From: Mariusz Jozala Date: Fri, 12 Sep 2025 11:57:32 +0200 Subject: [PATCH 03/16] Change version handling in the tests In the bcUpgradeTests these tests were previously skipped because version was set to `0.0.0` which was outside the supported range. Now, when `tests.old_cluster_version` has correct version they run, but fail just because `9.2.0-SNAPSHOT` was considered unsupported version format with the "SNAPSHOT". --- .../xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java | 2 +- .../xpack/inference/qa/mixed/CohereServiceMixedIT.java | 3 +-- .../xpack/inference/qa/mixed/HuggingFaceServiceMixedIT.java | 2 +- .../xpack/inference/qa/mixed/MixedClusterSpecTestCase.java | 2 +- .../xpack/inference/qa/mixed/OpenAIServiceMixedIT.java | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java b/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java index 93e2ecb14c2ff..2bc20f4c92122 100644 --- a/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java +++ b/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java @@ -32,7 +32,7 @@ protected String getTestRestCluster() { return cluster.getHttpAddresses(); } - static final Version bwcVersion = Version.fromString(System.getProperty("tests.old_cluster_version")); + static final Version bwcVersion = Version.fromString(System.getProperty("tests.old_cluster_version").replace("-SNAPSHOT", "")); private static TestFeatureService oldClusterTestFeatureService = null; diff --git a/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/CohereServiceMixedIT.java b/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/CohereServiceMixedIT.java index c16271ed44083..961c36efac3b3 100644 --- a/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/CohereServiceMixedIT.java +++ b/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/CohereServiceMixedIT.java @@ -7,9 +7,9 @@ package org.elasticsearch.xpack.inference.qa.mixed; -import org.elasticsearch.Version; import org.elasticsearch.common.Strings; import org.elasticsearch.inference.TaskType; +import org.elasticsearch.test.cluster.util.Version; import org.elasticsearch.test.http.MockResponse; import org.elasticsearch.test.http.MockWebServer; import org.elasticsearch.xpack.inference.services.cohere.embeddings.CohereEmbeddingType; @@ -21,7 +21,6 @@ import java.util.List; import java.util.Map; -import static org.elasticsearch.xpack.inference.qa.mixed.MixedClusterSpecTestCase.bwcVersion; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.hasEntry; diff --git a/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/HuggingFaceServiceMixedIT.java b/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/HuggingFaceServiceMixedIT.java index 457ae525b7f4b..63cffb6fdee33 100644 --- a/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/HuggingFaceServiceMixedIT.java +++ b/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/HuggingFaceServiceMixedIT.java @@ -7,9 +7,9 @@ package org.elasticsearch.xpack.inference.qa.mixed; -import org.elasticsearch.Version; import org.elasticsearch.common.Strings; import org.elasticsearch.inference.TaskType; +import org.elasticsearch.test.cluster.util.Version; import org.elasticsearch.test.http.MockResponse; import org.elasticsearch.test.http.MockWebServer; import org.junit.AfterClass; diff --git a/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/MixedClusterSpecTestCase.java b/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/MixedClusterSpecTestCase.java index 45cd3716f21df..172d52bd1a8db 100644 --- a/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/MixedClusterSpecTestCase.java +++ b/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/MixedClusterSpecTestCase.java @@ -7,9 +7,9 @@ package org.elasticsearch.xpack.inference.qa.mixed; -import org.elasticsearch.Version; import org.elasticsearch.features.NodeFeature; import org.elasticsearch.test.cluster.ElasticsearchCluster; +import org.elasticsearch.test.cluster.util.Version; import org.elasticsearch.test.rest.ESRestTestCase; import org.elasticsearch.test.rest.TestFeatureService; import org.junit.AfterClass; diff --git a/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/OpenAIServiceMixedIT.java b/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/OpenAIServiceMixedIT.java index b37bd1801b331..749684db43aac 100644 --- a/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/OpenAIServiceMixedIT.java +++ b/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/OpenAIServiceMixedIT.java @@ -7,9 +7,9 @@ package org.elasticsearch.xpack.inference.qa.mixed; -import org.elasticsearch.Version; import org.elasticsearch.common.Strings; import org.elasticsearch.inference.TaskType; +import org.elasticsearch.test.cluster.util.Version; import org.elasticsearch.test.http.MockResponse; import org.elasticsearch.test.http.MockWebServer; import org.junit.AfterClass; From 2d30bbb13fcd2011c480996b628ce0dbde8bc987 Mon Sep 17 00:00:00 2001 From: Mariusz Jozala Date: Mon, 15 Sep 2025 10:07:37 +0200 Subject: [PATCH 04/16] Use distribution version in the detached DistributionResolver Update logic to use version from distribution. It no longer needs to use overridden version in system property as it should be the same as in the distribution. --- .../gradle/internal/InternalDistributionDownloadPlugin.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/InternalDistributionDownloadPlugin.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/InternalDistributionDownloadPlugin.java index d16bb5efd557f..809089c7b0b5c 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/InternalDistributionDownloadPlugin.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/InternalDistributionDownloadPlugin.java @@ -108,12 +108,12 @@ private void registerInternalDistributionResolutions(List { if (distribution.isDetachedVersion()) { - String versionProperty = System.getProperty("tests.bwc.main.version"); BwcVersions.UnreleasedVersionInfo unreleasedVersionInfo = new BwcVersions.UnreleasedVersionInfo( - Version.fromString(versionProperty), + Version.fromString(distribution.getVersion()), "main", ":distribution:bwc:main" ); From 6f687c067b57895469bef047803d8f2ec041767a Mon Sep 17 00:00:00 2001 From: Mariusz Jozala Date: Thu, 18 Sep 2025 14:24:00 +0200 Subject: [PATCH 05/16] Reset the detachedVersion flag on upgrading cluster This is needed so that the cluster is upgraded to the actual specified version and not keep using the same detached version as before. It has a limitation of not being able to upgrade to the detached version, but there is no such test case currently. --- .../test/cluster/local/DefaultLocalClusterHandle.java | 2 ++ .../elasticsearch/test/cluster/local/LocalClusterSpec.java | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/DefaultLocalClusterHandle.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/DefaultLocalClusterHandle.java index f2e2245e7321e..c74aaa7802cc2 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/DefaultLocalClusterHandle.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/DefaultLocalClusterHandle.java @@ -167,6 +167,7 @@ public void upgradeNodeToVersion(int index, Version version) { Node node = nodes.get(index); node.stop(false); LOGGER.info("Upgrading node '{}' to version {}", node.getName(), version); + node.getSpec().setDetachedVersion(false); node.start(version); waitUntilReady(); } @@ -174,6 +175,7 @@ public void upgradeNodeToVersion(int index, Version version) { @Override public void upgradeToVersion(Version version) { stop(false); + nodes.forEach(node -> node.getSpec().setDetachedVersion(false)); if (started.getAndSet(true) == false) { LOGGER.info("Upgrading Elasticsearch test cluster '{}' to version {}", name, version); execute(() -> nodes.parallelStream().forEach(n -> n.start(version))); diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java index f50e06b50bc21..cc0b821917bd0 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java @@ -106,7 +106,7 @@ public static class LocalNodeSpec { private final List jvmArgs; private final Path configDir; private Version version; - private final boolean detachedVersion; + private boolean detachedVersion; public LocalNodeSpec( LocalClusterSpec cluster, @@ -179,6 +179,10 @@ public boolean isDetachedVersion() { return detachedVersion; } + public void setDetachedVersion(boolean detachedVersion) { + this.detachedVersion = detachedVersion; + } + public List getUsers() { return cluster.getUsers(); } From 3da46f9d66847c2210558df7c00b6f1e47c15b1a Mon Sep 17 00:00:00 2001 From: Mariusz Jozala Date: Thu, 18 Sep 2025 14:29:23 +0200 Subject: [PATCH 06/16] Allow version 0.0.0 for tests Need to keep allowing that for serverless tests that doesn't know the version for the detached version distribution when registering the BwC test tasks. --- .../src/main/java/org/elasticsearch/gradle/Version.java | 4 ---- .../test/groovy/org/elasticsearch/gradle/VersionSpec.groovy | 6 ------ 2 files changed, 10 deletions(-) diff --git a/build-tools/src/main/java/org/elasticsearch/gradle/Version.java b/build-tools/src/main/java/org/elasticsearch/gradle/Version.java index 2efeb39047247..f0bc936e683a2 100644 --- a/build-tools/src/main/java/org/elasticsearch/gradle/Version.java +++ b/build-tools/src/main/java/org/elasticsearch/gradle/Version.java @@ -79,10 +79,6 @@ public static Version fromString(final String s, final Mode mode) { String revision = matcher.group(3); String qualifier = matcher.group(4); - if (major.equals("0") && minor.equals("0") && revision.equals("0")) { - throw new IllegalArgumentException("Version 0.0.0 is not allowed"); - } - return new Version(Integer.parseInt(major), Integer.parseInt(minor), revision == null ? 0 : Integer.parseInt(revision), qualifier); } diff --git a/build-tools/src/test/groovy/org/elasticsearch/gradle/VersionSpec.groovy b/build-tools/src/test/groovy/org/elasticsearch/gradle/VersionSpec.groovy index 65c5e8e5fb071..96a7c63d665ed 100644 --- a/build-tools/src/test/groovy/org/elasticsearch/gradle/VersionSpec.groovy +++ b/build-tools/src/test/groovy/org/elasticsearch/gradle/VersionSpec.groovy @@ -76,12 +76,6 @@ class VersionSpec extends Specification { then: e = thrown(IllegalArgumentException) assert e.message == "Invalid version format: 'foo.bar.baz'. Should be major.minor.revision[-(alpha|beta|rc)Number|-SNAPSHOT]" - - when: - Version.fromString("0.0.0") - then: - e = thrown(IllegalArgumentException) - assert e.message == "Version 0.0.0 is not allowed" } def "handles qualifier"() { From 264f7bba0d3a940f3a9f9983cc10a95f990bc7b8 Mon Sep 17 00:00:00 2001 From: Mariusz Jozala Date: Thu, 18 Sep 2025 14:32:55 +0200 Subject: [PATCH 07/16] Expect null version in MixedClusterEsqlSpecIT This is needed explicitly now for serverless tests. Previously it was also null but was implicit. --- .../xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java b/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java index 2bc20f4c92122..5e467695f3faf 100644 --- a/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java +++ b/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java @@ -32,7 +32,10 @@ protected String getTestRestCluster() { return cluster.getHttpAddresses(); } - static final Version bwcVersion = Version.fromString(System.getProperty("tests.old_cluster_version").replace("-SNAPSHOT", "")); + static final Version bwcVersion = Version.fromString( + System.getProperty("tests.old_cluster_version") != null ? + System.getProperty("tests.old_cluster_version").replace("-SNAPSHOT", "") : + null); private static TestFeatureService oldClusterTestFeatureService = null; From 28b4a02cb19169dc1d24c2b1aaf26a9389232106 Mon Sep 17 00:00:00 2001 From: elasticsearchmachine Date: Thu, 18 Sep 2025 12:40:50 +0000 Subject: [PATCH 08/16] [CI] Auto commit changes from spotless --- .../xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java b/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java index 5e467695f3faf..c35ba5b92b65b 100644 --- a/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java +++ b/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java @@ -33,9 +33,10 @@ protected String getTestRestCluster() { } static final Version bwcVersion = Version.fromString( - System.getProperty("tests.old_cluster_version") != null ? - System.getProperty("tests.old_cluster_version").replace("-SNAPSHOT", "") : - null); + System.getProperty("tests.old_cluster_version") != null + ? System.getProperty("tests.old_cluster_version").replace("-SNAPSHOT", "") + : null + ); private static TestFeatureService oldClusterTestFeatureService = null; From f2820f61a009a96a30b2e5a3ef0cc148eb823095 Mon Sep 17 00:00:00 2001 From: Mariusz Jozala Date: Thu, 25 Sep 2025 15:51:55 +0200 Subject: [PATCH 09/16] Refactor ElasticsearchCluster detached version handling Updated the ElasticsearchCluster initialization to use a single method for setting the version and detached version flag. It also integrates the detached property into Version to make it transparent in case the detached functionality is not used in the test. --- .../ingest/geoip/FullClusterRestartIT.java | 3 +- .../FullClusterRestartArchivedSettingsIT.java | 3 +- .../FullClusterRestartDownsampleIT.java | 3 +- .../upgrades/FullClusterRestartIT.java | 3 +- .../LogsIndexModeFullClusterRestartIT.java | 3 +- .../upgrades/QueryBuilderBWCIT.java | 3 +- .../AbstractRollingUpgradeTestCase.java | 3 +- ...actRollingUpgradeWithSecurityTestCase.java | 3 +- .../upgrades/FileSettingsUpgradeIT.java | 3 +- .../local/AbstractLocalClusterFactory.java | 6 ++-- .../AbstractLocalClusterSpecBuilder.java | 1 - .../local/AbstractLocalSpecBuilder.java | 13 ++------ .../local/DefaultLocalClusterHandle.java | 2 -- .../test/cluster/local/LocalClusterSpec.java | 17 ---------- .../test/cluster/local/LocalSpecBuilder.java | 11 +++++-- .../distribution/DistributionResolver.java | 2 +- .../LocalDistributionResolver.java | 6 ++-- .../ReleasedDistributionResolver.java | 2 +- .../SnapshotDistributionResolver.java | 4 +-- .../test/cluster/util/Version.java | 31 ++++++++++++++++++- .../application/FullClusterRestartIT.java | 3 +- .../xpack/esql/qa/mixed/Clusters.java | 7 +++-- .../inference/qa/mixed/MixedClustersSpec.java | 4 +-- .../application/InferenceUpgradeTestCase.java | 3 +- ...dardToLogsDbIndexModeRollingUpgradeIT.java | 3 +- ...ClusterSecurityBWCToRCS1ClusterRestIT.java | 5 ++- ...ClusterSecurityBWCToRCS2ClusterRestIT.java | 5 ++- .../xpack/restart/FullClusterRestartIT.java | 4 +-- ...stractXpackFullClusterRestartTestCase.java | 4 +-- 29 files changed, 74 insertions(+), 86 deletions(-) diff --git a/modules/ingest-geoip/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/ingest/geoip/FullClusterRestartIT.java b/modules/ingest-geoip/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/ingest/geoip/FullClusterRestartIT.java index 6a1ee6b446541..569146d9d2664 100644 --- a/modules/ingest-geoip/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/ingest/geoip/FullClusterRestartIT.java +++ b/modules/ingest-geoip/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/ingest/geoip/FullClusterRestartIT.java @@ -41,8 +41,7 @@ public class FullClusterRestartIT extends ParameterizedFullClusterRestartTestCas private static final ElasticsearchCluster cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(Version.fromString(OLD_CLUSTER_VERSION)) - .detachedVersion(isOldClusterDetachedVersion()) + .version(OLD_CLUSTER_VERSION, isOldClusterDetachedVersion()) .nodes(2) .setting("ingest.geoip.downloader.endpoint", () -> fixture.getAddress(), s -> useFixture) .setting("xpack.security.enabled", "false") diff --git a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartArchivedSettingsIT.java b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartArchivedSettingsIT.java index 6f58e680bf4e1..6c96b67cf959b 100644 --- a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartArchivedSettingsIT.java +++ b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartArchivedSettingsIT.java @@ -45,8 +45,7 @@ public class FullClusterRestartArchivedSettingsIT extends ParameterizedFullClust private static ElasticsearchCluster cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(Version.fromString(OLD_CLUSTER_VERSION)) - .detachedVersion(isOldClusterDetachedVersion()) + .version(OLD_CLUSTER_VERSION, isOldClusterDetachedVersion()) .nodes(2) .setting("path.repo", () -> repoDirectory.getRoot().getPath()) .setting("xpack.security.enabled", "false") diff --git a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartDownsampleIT.java b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartDownsampleIT.java index c3a3603c60b4a..10bbd3dc42e67 100644 --- a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartDownsampleIT.java +++ b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartDownsampleIT.java @@ -50,8 +50,7 @@ private static ElasticsearchCluster buildCluster() { Version oldVersion = Version.fromString(OLD_CLUSTER_VERSION); var cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(Version.fromString(OLD_CLUSTER_VERSION)) - .detachedVersion(isOldClusterDetachedVersion()) + .version(OLD_CLUSTER_VERSION, isOldClusterDetachedVersion()) .nodes(2) .setting("xpack.security.enabled", "false") .setting("indices.lifecycle.poll_interval", "5s") diff --git a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartIT.java b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartIT.java index 4dfbbdf0f9a44..b0fda4051bf4b 100644 --- a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartIT.java +++ b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartIT.java @@ -109,8 +109,7 @@ private static ElasticsearchCluster buildCluster() { Version oldVersion = Version.fromString(OLD_CLUSTER_VERSION); var cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(Version.fromString(OLD_CLUSTER_VERSION)) - .detachedVersion(isOldClusterDetachedVersion()) + .version(OLD_CLUSTER_VERSION, isOldClusterDetachedVersion()) .nodes(2) .setting("path.repo", () -> repoDirectory.getRoot().getPath()) .setting("xpack.security.enabled", "false") diff --git a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/LogsIndexModeFullClusterRestartIT.java b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/LogsIndexModeFullClusterRestartIT.java index a09d74bd677f5..7236bcba96b3f 100644 --- a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/LogsIndexModeFullClusterRestartIT.java +++ b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/LogsIndexModeFullClusterRestartIT.java @@ -39,8 +39,7 @@ private static ElasticsearchCluster buildCluster() { Version oldVersion = Version.fromString(OLD_CLUSTER_VERSION); var cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(Version.fromString(OLD_CLUSTER_VERSION)) - .detachedVersion(isOldClusterDetachedVersion()) + .version(OLD_CLUSTER_VERSION, isOldClusterDetachedVersion()) .module("constant-keyword") .module("data-streams") .module("mapper-extras") diff --git a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/QueryBuilderBWCIT.java b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/QueryBuilderBWCIT.java index d867d65ad3f64..701bf83e5e6eb 100644 --- a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/QueryBuilderBWCIT.java +++ b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/QueryBuilderBWCIT.java @@ -73,8 +73,7 @@ public class QueryBuilderBWCIT extends ParameterizedFullClusterRestartTestCase { @ClassRule public static ElasticsearchCluster cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(org.elasticsearch.test.cluster.util.Version.fromString(OLD_CLUSTER_VERSION)) - .detachedVersion(isOldClusterDetachedVersion()) + .version(OLD_CLUSTER_VERSION, isOldClusterDetachedVersion()) .nodes(2) .setting("xpack.security.enabled", "false") .apply(() -> clusterConfig) 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 2b19044459e79..c702d82912aca 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 @@ -32,8 +32,7 @@ public abstract class AbstractRollingUpgradeTestCase extends ParameterizedRollin private static ElasticsearchCluster buildCluster() { var cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(getOldClusterVersion()) - .detachedVersion(isOldClusterDetachedVersion()) + .version(getOldClusterVersion(), isOldClusterDetachedVersion()) .nodes(NODE_NUM) .setting("path.repo", new Supplier<>() { @Override 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 0b3fb6cd7acab..accbef575e923 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 @@ -37,8 +37,7 @@ public abstract class AbstractRollingUpgradeWithSecurityTestCase extends Paramet private static ElasticsearchCluster buildCluster() { var cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(getOldClusterVersion()) - .detachedVersion(isOldClusterDetachedVersion()) + .version(getOldClusterVersion(), isOldClusterDetachedVersion()) .nodes(NODE_NUM) .user(USER, PASS) .setting("xpack.security.autoconfiguration.enabled", "false") 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 b9c7a70c8a3e1..9ac2d39ee2ef4 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 @@ -59,8 +59,7 @@ public class FileSettingsUpgradeIT extends ParameterizedRollingUpgradeTestCase { private static final ElasticsearchCluster cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(getOldClusterVersion()) - .detachedVersion(isOldClusterDetachedVersion()) + .version(getOldClusterVersion(), isOldClusterDetachedVersion()) .nodes(NODE_NUM) .setting("path.repo", new Supplier<>() { @Override diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java index a095a0cba78e7..f760be4ec4302 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java @@ -397,8 +397,8 @@ private void copyExtraJarFiles() { private DistributionDescriptor resolveDistribution() { return TEST_DISTRIBUTIONS.computeIfAbsent( - new DistributionKey(spec.getVersion(), spec.isDetachedVersion(), spec.getDistributionType()), - key -> distributionResolver.resolve(key.version, key.detachedVersion, key.distributionType) + new DistributionKey(spec.getVersion(), spec.getDistributionType()), + key -> distributionResolver.resolve(key.version, key.distributionType) ); } @@ -995,5 +995,5 @@ public String toString() { } } - public record DistributionKey(Version version, boolean detachedVersion, DistributionType distributionType) {} + public record DistributionKey(Version version, DistributionType distributionType) {} } diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterSpecBuilder.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterSpecBuilder.java index 93d2c0cc2512d..73c5afdec5b9f 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterSpecBuilder.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterSpecBuilder.java @@ -197,7 +197,6 @@ private LocalNodeSpec build(LocalClusterSpec cluster, int nodeIndex) { cluster, resolveName(cluster, nodeIndex), Optional.ofNullable(getVersion()).orElse(Version.CURRENT), - isDetachedVersion(), getSettingsProviders(), getSettings(), getEnvironmentProviders(), diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java index 5c3e2aa7e7808..ea5c76bd551c8 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalSpecBuilder.java @@ -47,7 +47,6 @@ public abstract class AbstractLocalSpecBuilder> im private final List jvmArgs = new ArrayList<>(); private DistributionType distributionType; private Version version; - private Boolean detachedVersion; private String keystorePassword; private Supplier configDirSupplier; @@ -307,19 +306,11 @@ public Version getVersion() { } @Override - public T detachedVersion(boolean detachedVersion) { - this.detachedVersion = detachedVersion; + public T version(String version, boolean detachedVersion) { + this.version = Version.fromString(version, detachedVersion); return cast(this); } - public boolean isDetachedVersion() { - Boolean isDetached = inherit(() -> parent.isDetachedVersion(), detachedVersion); - if (isDetached != null) { - return isDetached; - } - return false; - } - private List inherit(Supplier> parent, List child) { List combinedList = new ArrayList<>(); if (this.parent != null) { diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/DefaultLocalClusterHandle.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/DefaultLocalClusterHandle.java index c74aaa7802cc2..f2e2245e7321e 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/DefaultLocalClusterHandle.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/DefaultLocalClusterHandle.java @@ -167,7 +167,6 @@ public void upgradeNodeToVersion(int index, Version version) { Node node = nodes.get(index); node.stop(false); LOGGER.info("Upgrading node '{}' to version {}", node.getName(), version); - node.getSpec().setDetachedVersion(false); node.start(version); waitUntilReady(); } @@ -175,7 +174,6 @@ public void upgradeNodeToVersion(int index, Version version) { @Override public void upgradeToVersion(Version version) { stop(false); - nodes.forEach(node -> node.getSpec().setDetachedVersion(false)); if (started.getAndSet(true) == false) { LOGGER.info("Upgrading Elasticsearch test cluster '{}' to version {}", name, version); execute(() -> nodes.parallelStream().forEach(n -> n.start(version))); diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java index cc0b821917bd0..cccf2a95234c9 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalClusterSpec.java @@ -106,13 +106,11 @@ public static class LocalNodeSpec { private final List jvmArgs; private final Path configDir; private Version version; - private boolean detachedVersion; public LocalNodeSpec( LocalClusterSpec cluster, String name, Version version, - boolean detachedVersion, List settingsProviders, Map settings, List environmentProviders, @@ -134,7 +132,6 @@ public LocalNodeSpec( this.cluster = cluster; this.name = name; this.version = version; - this.detachedVersion = detachedVersion; this.settingsProviders = settingsProviders; this.settings = settings; this.environmentProviders = environmentProviders; @@ -170,19 +167,6 @@ public Version getVersion() { return version; } - /** - * Informs if the version is not tied to any Elasticsearch release and is a custom build. - * This is true when the distribution is not from HEAD but also not any known released version. - * In that case the detached source build needs to be prepared by `usedBwcDistributionFromRef(ref, version)`. - */ - public boolean isDetachedVersion() { - return detachedVersion; - } - - public void setDetachedVersion(boolean detachedVersion) { - this.detachedVersion = detachedVersion; - } - public List getUsers() { return cluster.getUsers(); } @@ -348,7 +332,6 @@ private LocalNodeSpec getFilteredSpec(SettingsProvider filteredProvider, Setting newCluster, n.name, n.version, - n.detachedVersion, n.settingsProviders.stream().filter(s -> s != filteredProvider).toList(), n.settings, n.environmentProviders, diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java index 553ed5b33be3e..5be15687459e2 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/LocalSpecBuilder.java @@ -137,9 +137,14 @@ interface LocalSpecBuilder> { T version(String version); /** - * Sets whether using unreleased version of Elasticsearch, different from the local current HEAD. Defaults to false. - */ - T detachedVersion(boolean detachedVersion); + * Sets the version of Elasticsearch and whether it is a detached version. + * If not set, then defaults to {@link Version#CURRENT} and {@code false}. + * + * @param version the ES cluster version string + * @param detachedVersion true if using unreleased version of Elasticsearch that is also different from the local current HEAD. + * Defaults to false. + */ + T version(String version, boolean detachedVersion); /** * Adds a system property to node JVM arguments. diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/DistributionResolver.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/DistributionResolver.java index ff1f90f095e06..02d755c50c674 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/DistributionResolver.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/DistributionResolver.java @@ -13,5 +13,5 @@ public interface DistributionResolver { - DistributionDescriptor resolve(Version version, boolean detachedVersion, DistributionType type); + DistributionDescriptor resolve(Version version, DistributionType type); } diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/LocalDistributionResolver.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/LocalDistributionResolver.java index 87526fcd53597..b42b5da249645 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/LocalDistributionResolver.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/LocalDistributionResolver.java @@ -25,8 +25,8 @@ public LocalDistributionResolver(DistributionResolver delegate) { } @Override - public DistributionDescriptor resolve(Version version, boolean detachedVersion, DistributionType type) { - if (version.equals(Version.CURRENT) && detachedVersion == false) { + public DistributionDescriptor resolve(Version version, DistributionType type) { + if (version.equals(Version.CURRENT) && version.isDetached() == false) { String testDistributionPath = System.getProperty(type.getSystemProperty()); if (testDistributionPath == null) { @@ -67,6 +67,6 @@ public DistributionDescriptor resolve(Version version, boolean detachedVersion, ); } - return delegate.resolve(version, detachedVersion, type); + return delegate.resolve(version, type); } } diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/ReleasedDistributionResolver.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/ReleasedDistributionResolver.java index 87521ce837e51..f76c5ad4d1dee 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/ReleasedDistributionResolver.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/ReleasedDistributionResolver.java @@ -21,7 +21,7 @@ public class ReleasedDistributionResolver implements DistributionResolver { private static final String BWC_DISTRIBUTION_SYSPROP_PREFIX = "tests.release.distribution."; @Override - public DistributionDescriptor resolve(Version version, boolean detachedVersion, DistributionType type) { + public DistributionDescriptor resolve(Version version, DistributionType type) { String distributionPath = System.getProperty(BWC_DISTRIBUTION_SYSPROP_PREFIX + version.toString()); if (distributionPath == null) { diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/SnapshotDistributionResolver.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/SnapshotDistributionResolver.java index fb7ca46345e85..f57f36460b627 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/SnapshotDistributionResolver.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/distribution/SnapshotDistributionResolver.java @@ -26,7 +26,7 @@ public SnapshotDistributionResolver(DistributionResolver delegate) { } @Override - public DistributionDescriptor resolve(Version version, boolean detachedVersion, DistributionType type) { + public DistributionDescriptor resolve(Version version, DistributionType type) { String distributionPath = System.getProperty(BWC_DISTRIBUTION_SYSPROP_PREFIX + version.toString()); if (distributionPath != null) { @@ -42,6 +42,6 @@ public DistributionDescriptor resolve(Version version, boolean detachedVersion, return new DefaultDistributionDescriptor(version, isSnapshot, distributionDir, DistributionType.DEFAULT); } - return delegate.resolve(version, detachedVersion, type); + return delegate.resolve(version, type); } } 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 2136d88a9e2aa..06768c23ba98b 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 @@ -33,6 +33,7 @@ public class Version implements Comparable, Serializable { private final int revision; private final int id; private final String qualifier; + private final boolean detached; static { Properties versionProperties = new Properties(); @@ -65,6 +66,10 @@ public Version(int major, int minor, int revision) { } public Version(int major, int minor, int revision, String qualifier) { + this(major, minor, revision, qualifier, false); + } + + private Version(int major, int minor, int revision, String qualifier, boolean detached) { this.major = major; this.minor = minor; this.revision = revision; @@ -73,6 +78,7 @@ public Version(int major, int minor, int revision, String qualifier) { this.id = major * 10000000 + minor * 100000 + revision * 1000; this.qualifier = qualifier; + this.detached = detached; } public static Version fromString(final String s) { @@ -80,6 +86,14 @@ public static Version fromString(final String s) { } public static Version fromString(final String s, final Mode mode) { + return fromString(s, mode, false); + } + + public static Version fromString(final String s, final boolean detached) { + return fromString(s, Mode.STRICT, detached); + } + + private static Version fromString(final String s, final Mode mode, final boolean detached) { Objects.requireNonNull(s); Matcher matcher = mode == Mode.STRICT ? pattern.matcher(s) : relaxedPattern.matcher(s); if (matcher.matches() == false) { @@ -94,7 +108,13 @@ public static Version fromString(final String s, final Mode mode) { String revision = matcher.group(3); String qualifier = matcher.group(4); - return new Version(Integer.parseInt(major), Integer.parseInt(minor), revision == null ? 0 : Integer.parseInt(revision), qualifier); + return new Version( + Integer.parseInt(major), + Integer.parseInt(minor), + revision == null ? 0 : Integer.parseInt(revision), + qualifier, + detached + ); } public static Optional tryParse(final String s) { @@ -188,6 +208,15 @@ public String getQualifier() { return qualifier; } + /** + * Informs if the version is not tied to any Elasticsearch release and is a custom build. + * This is true when the distribution is not from HEAD but also not any known released version. + * In that case the detached source build needs to be prepared by `usedBwcDistributionFromRef(ref, version)`. + */ + public boolean isDetached() { + return detached; + } + @Override public int compareTo(Version other) { return Integer.compare(getId(), other.getId()); diff --git a/x-pack/plugin/ent-search/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/application/FullClusterRestartIT.java b/x-pack/plugin/ent-search/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/application/FullClusterRestartIT.java index 4cc5476902190..a536998635d63 100644 --- a/x-pack/plugin/ent-search/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/application/FullClusterRestartIT.java +++ b/x-pack/plugin/ent-search/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/application/FullClusterRestartIT.java @@ -41,8 +41,7 @@ public class FullClusterRestartIT extends ParameterizedFullClusterRestartTestCas @ClassRule public static final ElasticsearchCluster cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(org.elasticsearch.test.cluster.util.Version.fromString(OLD_CLUSTER_VERSION)) - .detachedVersion(isOldClusterDetachedVersion()) + .version(OLD_CLUSTER_VERSION, isOldClusterDetachedVersion()) .nodes(2) .setting("xpack.security.enabled", "false") .setting("xpack.license.self_generated.type", "trial") diff --git a/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/Clusters.java b/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/Clusters.java index 7c1ab2c492634..c68561b3b3594 100644 --- a/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/Clusters.java +++ b/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/Clusters.java @@ -13,13 +13,14 @@ public class Clusters { public static ElasticsearchCluster mixedVersionCluster() { - Version oldVersion = Version.fromString(System.getProperty("tests.old_cluster_version")); + String oldVersionString = System.getProperty("tests.old_cluster_version"); + Version oldVersion = Version.fromString(oldVersionString); boolean isDetachedVersion = System.getProperty("tests.bwc.refspec.main") != null; var cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .withNode(node -> node.version(oldVersion).detachedVersion(isDetachedVersion)) + .withNode(node -> node.version(oldVersionString, isDetachedVersion)) .withNode(node -> node.version(Version.CURRENT)) - .withNode(node -> node.version(oldVersion).detachedVersion(isDetachedVersion)) + .withNode(node -> node.version(oldVersionString, isDetachedVersion)) .withNode(node -> node.version(Version.CURRENT)) .setting("xpack.security.enabled", "false") .setting("xpack.license.self_generated.type", "trial"); diff --git a/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/MixedClustersSpec.java b/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/MixedClustersSpec.java index 706938f818d7b..00203d4b1261d 100644 --- a/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/MixedClustersSpec.java +++ b/x-pack/plugin/inference/qa/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/inference/qa/mixed/MixedClustersSpec.java @@ -13,11 +13,11 @@ public class MixedClustersSpec { public static ElasticsearchCluster mixedVersionCluster() { - Version oldVersion = Version.fromString(System.getProperty("tests.old_cluster_version")); + String oldVersion = System.getProperty("tests.old_cluster_version"); boolean isDetachedVersion = System.getProperty("tests.bwc.refspec.main") != null; return ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .withNode(node -> node.version(oldVersion).detachedVersion(isDetachedVersion)) + .withNode(node -> node.version(oldVersion, isDetachedVersion)) .withNode(node -> node.version(Version.CURRENT)) .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/InferenceUpgradeTestCase.java b/x-pack/plugin/inference/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/xpack/application/InferenceUpgradeTestCase.java index 53824be0e4385..7e80e8643d4cc 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 @@ -38,8 +38,7 @@ public InferenceUpgradeTestCase(@Name("upgradedNodes") int upgradedNodes) { @ClassRule public static ElasticsearchCluster cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(getOldClusterVersion()) - .detachedVersion(isOldClusterDetachedVersion()) + .version(getOldClusterVersion(), isOldClusterDetachedVersion()) .nodes(NODE_NUM) .setting("xpack.security.enabled", "false") .setting("xpack.license.self_generated.type", "trial") diff --git a/x-pack/plugin/logsdb/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/StandardToLogsDbIndexModeRollingUpgradeIT.java b/x-pack/plugin/logsdb/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/StandardToLogsDbIndexModeRollingUpgradeIT.java index 7dc81f8cd7d49..bf969736e6c01 100644 --- a/x-pack/plugin/logsdb/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/StandardToLogsDbIndexModeRollingUpgradeIT.java +++ b/x-pack/plugin/logsdb/qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/StandardToLogsDbIndexModeRollingUpgradeIT.java @@ -46,8 +46,7 @@ public class StandardToLogsDbIndexModeRollingUpgradeIT extends AbstractRollingUp @ClassRule() public static final ElasticsearchCluster cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(getOldClusterVersion()) - .detachedVersion(isOldClusterDetachedVersion()) + .version(getOldClusterVersion(), isOldClusterDetachedVersion()) .nodes(NODE_NUM) .user(USER, PASS) .module("constant-keyword") diff --git a/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS1ClusterRestIT.java b/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS1ClusterRestIT.java index 7f536c59bff9d..2de7a4be792db 100644 --- a/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS1ClusterRestIT.java +++ b/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS1ClusterRestIT.java @@ -26,12 +26,11 @@ */ public class RemoteClusterSecurityBWCToRCS1ClusterRestIT extends AbstractRemoteClusterSecurityBWCRestIT { - private static final Version OLD_CLUSTER_VERSION = Version.fromString(System.getProperty("tests.old_cluster_version")); + private static final String OLD_CLUSTER_VERSION = System.getProperty("tests.old_cluster_version"); static { fulfillingCluster = ElasticsearchCluster.local() - .version(OLD_CLUSTER_VERSION) - .detachedVersion(isOldClusterDetachedVersion()) + .version(OLD_CLUSTER_VERSION, isOldClusterDetachedVersion()) .distribution(DistributionType.DEFAULT) .name("fulfilling-cluster") .apply(commonClusterConfig) diff --git a/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS2ClusterRestIT.java b/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS2ClusterRestIT.java index 63bbf7dc86057..4a010ba33e71f 100644 --- a/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS2ClusterRestIT.java +++ b/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS2ClusterRestIT.java @@ -27,15 +27,14 @@ */ public class RemoteClusterSecurityBWCToRCS2ClusterRestIT extends AbstractRemoteClusterSecurityBWCRestIT { - private static final Version OLD_CLUSTER_VERSION = Version.fromString(System.getProperty("tests.old_cluster_version")); + private static final String OLD_CLUSTER_VERSION = System.getProperty("tests.old_cluster_version"); private static final AtomicReference> API_KEY_MAP_REF = new AtomicReference<>(); static { fulfillingCluster = ElasticsearchCluster.local() .name("fulfilling-cluster") - .version(OLD_CLUSTER_VERSION) - .detachedVersion(isOldClusterDetachedVersion()) + .version(OLD_CLUSTER_VERSION, isOldClusterDetachedVersion()) .distribution(DistributionType.DEFAULT) .apply(commonClusterConfig) .setting("xpack.ml.enabled", "false") diff --git a/x-pack/plugin/shutdown/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/restart/FullClusterRestartIT.java b/x-pack/plugin/shutdown/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/restart/FullClusterRestartIT.java index 2ed3dd9be96fc..3df11ac6661d7 100644 --- a/x-pack/plugin/shutdown/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/restart/FullClusterRestartIT.java +++ b/x-pack/plugin/shutdown/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/restart/FullClusterRestartIT.java @@ -17,7 +17,6 @@ import org.elasticsearch.test.cluster.ElasticsearchCluster; import org.elasticsearch.test.cluster.FeatureFlag; import org.elasticsearch.test.cluster.local.distribution.DistributionType; -import org.elasticsearch.test.cluster.util.Version; import org.elasticsearch.test.cluster.util.resource.Resource; import org.elasticsearch.test.rest.ESRestTestCase; import org.elasticsearch.upgrades.FullClusterRestartUpgradeStatus; @@ -46,8 +45,7 @@ public class FullClusterRestartIT extends ParameterizedFullClusterRestartTestCas @ClassRule public static ElasticsearchCluster cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(Version.fromString(OLD_CLUSTER_VERSION)) - .detachedVersion(isOldClusterDetachedVersion()) + .version(OLD_CLUSTER_VERSION, isOldClusterDetachedVersion()) .nodes(2) // some tests rely on the translog not being flushed .setting("indices.memory.shard_inactive_time", "60m") diff --git a/x-pack/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/restart/AbstractXpackFullClusterRestartTestCase.java b/x-pack/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/restart/AbstractXpackFullClusterRestartTestCase.java index 146b569d3fe44..9b209da0033f7 100644 --- a/x-pack/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/restart/AbstractXpackFullClusterRestartTestCase.java +++ b/x-pack/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/xpack/restart/AbstractXpackFullClusterRestartTestCase.java @@ -10,7 +10,6 @@ import org.elasticsearch.test.cluster.ElasticsearchCluster; import org.elasticsearch.test.cluster.FeatureFlag; import org.elasticsearch.test.cluster.local.distribution.DistributionType; -import org.elasticsearch.test.cluster.util.Version; import org.elasticsearch.test.cluster.util.resource.Resource; import org.elasticsearch.upgrades.FullClusterRestartUpgradeStatus; import org.elasticsearch.upgrades.ParameterizedFullClusterRestartTestCase; @@ -21,8 +20,7 @@ public abstract class AbstractXpackFullClusterRestartTestCase extends Parameteri @ClassRule public static ElasticsearchCluster cluster = ElasticsearchCluster.local() .distribution(DistributionType.DEFAULT) - .version(Version.fromString(OLD_CLUSTER_VERSION)) - .detachedVersion(isOldClusterDetachedVersion()) + .version(OLD_CLUSTER_VERSION, isOldClusterDetachedVersion()) .nodes(2) // some tests rely on the translog not being flushed .setting("indices.memory.shard_inactive_time", "60m") From 90052f81efee281262c6f143b1394459a431ea35 Mon Sep 17 00:00:00 2001 From: Mariusz Jozala Date: Thu, 25 Sep 2025 16:05:56 +0200 Subject: [PATCH 10/16] Do not check for `0.0.0` version for JDK-OS compatibility This check in no longer needed, because the version should be now set to the real value instead of `0.0.0`, even in the bcUpgradeTest task --- .../test/rest/RestTestBasePlugin.java | 34 +++++++++++++------ .../elasticsearch/gradle/util/OsUtils.java | 2 +- .../local/AbstractLocalClusterFactory.java | 2 +- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/RestTestBasePlugin.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/RestTestBasePlugin.java index 2a48b6748ecbf..5e3b8edb912dd 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/RestTestBasePlugin.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/rest/RestTestBasePlugin.java @@ -244,17 +244,7 @@ public Void call(Object... args) { String versionString = version.toString(); ElasticsearchDistribution bwcDistro = createDistribution(project, "bwc_" + versionString, versionString, false); - if (jdkIsIncompatibleWithOS(Version.fromString(versionString))) { - var toolChainService = project.getExtensions().getByType(JavaToolchainService.class); - var fallbackJdk17Launcher = toolChainService.launcherFor(spec -> { - spec.getVendor().set(JvmVendorSpec.ADOPTIUM); - spec.getLanguageVersion().set(JavaLanguageVersion.of(17)); - }); - task.environment( - "ES_FALLBACK_JAVA_HOME", - fallbackJdk17Launcher.get().getMetadata().getInstallationPath().getAsFile().getPath() - ); - } + handleJdkIncompatibleWithOS(version, project, task); task.dependsOn(bwcDistro); registerDistributionInputs(task, bwcDistro); @@ -284,6 +274,7 @@ public Void call(Object... args) { String versionString = version.toString(); ElasticsearchDistribution bwcDistro = createDistribution(project, "bwc_" + refSpec, versionString, isDetachedVersion); + handleJdkIncompatibleWithOS(version, project, task); task.dependsOn(bwcDistro); registerDistributionInputs(task, bwcDistro); @@ -298,6 +289,27 @@ public Void call(Object... args) { }); } + /** + * Older distributions ship with openjdk versions that are not compatible with newer kernels of ubuntu 24.04 and later + * Therefore we pass explicitly the runtime java to use the adoptium jdk that is maintained longer and compatible + * with newer kernels. + * 8.10.4 is the last version shipped with jdk < 21. We configure these cluster to run with jdk 17 adoptium as 17 was + * the last LTS release before 21 + */ + private static void handleJdkIncompatibleWithOS(Version version, Project project, StandaloneRestIntegTestTask task) { + if (jdkIsIncompatibleWithOS(version)) { + var toolChainService = project.getExtensions().getByType(JavaToolchainService.class); + var fallbackJdk17Launcher = toolChainService.launcherFor(spec -> { + spec.getVendor().set(JvmVendorSpec.ADOPTIUM); + spec.getLanguageVersion().set(JavaLanguageVersion.of(17)); + }); + task.environment( + "ES_FALLBACK_JAVA_HOME", + fallbackJdk17Launcher.get().getMetadata().getInstallationPath().getAsFile().getPath() + ); + } + } + private void copyDependencies(Project project, DependencySet dependencies, Configuration configuration) { configuration.getDependencies() .stream() diff --git a/build-tools/src/main/java/org/elasticsearch/gradle/util/OsUtils.java b/build-tools/src/main/java/org/elasticsearch/gradle/util/OsUtils.java index 486edf4150ab2..c0f38ece0c8d6 100644 --- a/build-tools/src/main/java/org/elasticsearch/gradle/util/OsUtils.java +++ b/build-tools/src/main/java/org/elasticsearch/gradle/util/OsUtils.java @@ -38,7 +38,7 @@ private OsUtils() {} * This method returns true if the given version of the JDK is known to be incompatible */ public static boolean jdkIsIncompatibleWithOS(Version version) { - return version.after("0.0.0") && version.onOrBefore("8.10.4") && isUbuntu2404OrLater(); + return version.onOrBefore("8.10.4") && isUbuntu2404OrLater(); } private static boolean isUbuntu2404OrLater() { diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java index f760be4ec4302..d65b26fbe3819 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java @@ -923,7 +923,7 @@ private Map getEnvironmentVariables() { } private boolean jdkIsIncompatible(Version version) { - return version.after("0.0.0") && version.before(FIRST_DISTRO_WITH_JDK_21); + return version.before(FIRST_DISTRO_WITH_JDK_21); } private record ReplacementKey(String key, String fallback) { From 62d7bd268563333b9d169fffdbecca1e3225ad59 Mon Sep 17 00:00:00 2001 From: Mariusz Jozala Date: Thu, 25 Sep 2025 16:15:25 +0200 Subject: [PATCH 11/16] Spotless fixes --- .../org/elasticsearch/ingest/geoip/FullClusterRestartIT.java | 1 - .../upgrades/FullClusterRestartArchivedSettingsIT.java | 1 - .../main/java/org/elasticsearch/test/cluster/util/Version.java | 2 +- .../RemoteClusterSecurityBWCToRCS2ClusterRestIT.java | 1 - 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/modules/ingest-geoip/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/ingest/geoip/FullClusterRestartIT.java b/modules/ingest-geoip/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/ingest/geoip/FullClusterRestartIT.java index 569146d9d2664..0f68547ecbd76 100644 --- a/modules/ingest-geoip/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/ingest/geoip/FullClusterRestartIT.java +++ b/modules/ingest-geoip/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/ingest/geoip/FullClusterRestartIT.java @@ -17,7 +17,6 @@ import org.elasticsearch.test.cluster.ElasticsearchCluster; import org.elasticsearch.test.cluster.FeatureFlag; import org.elasticsearch.test.cluster.local.distribution.DistributionType; -import org.elasticsearch.test.cluster.util.Version; import org.elasticsearch.upgrades.FullClusterRestartUpgradeStatus; import org.elasticsearch.upgrades.ParameterizedFullClusterRestartTestCase; import org.junit.ClassRule; diff --git a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartArchivedSettingsIT.java b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartArchivedSettingsIT.java index 6c96b67cf959b..d1781afa9dbea 100644 --- a/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartArchivedSettingsIT.java +++ b/qa/full-cluster-restart/src/javaRestTest/java/org/elasticsearch/upgrades/FullClusterRestartArchivedSettingsIT.java @@ -21,7 +21,6 @@ import org.elasticsearch.test.cluster.FeatureFlag; import org.elasticsearch.test.cluster.local.LocalClusterConfigProvider; import org.elasticsearch.test.cluster.local.distribution.DistributionType; -import org.elasticsearch.test.cluster.util.Version; import org.elasticsearch.test.rest.ObjectPath; import org.junit.ClassRule; import org.junit.rules.RuleChain; 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 06768c23ba98b..887c89e40b3c2 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 @@ -86,7 +86,7 @@ public static Version fromString(final String s) { } public static Version fromString(final String s, final Mode mode) { - return fromString(s, mode, false); + return fromString(s, mode, false); } public static Version fromString(final String s, final boolean detached) { diff --git a/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS2ClusterRestIT.java b/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS2ClusterRestIT.java index 4a010ba33e71f..c53cca6054fce 100644 --- a/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS2ClusterRestIT.java +++ b/x-pack/plugin/security/qa/multi-cluster/src/javaRestTest/java/org/elasticsearch/xpack/remotecluster/RemoteClusterSecurityBWCToRCS2ClusterRestIT.java @@ -9,7 +9,6 @@ import org.elasticsearch.test.cluster.ElasticsearchCluster; import org.elasticsearch.test.cluster.local.distribution.DistributionType; -import org.elasticsearch.test.cluster.util.Version; import org.junit.Before; import org.junit.ClassRule; import org.junit.rules.RuleChain; From ff0faeaa2553d7f684a8846052ab3ce20d845580 Mon Sep 17 00:00:00 2001 From: Mariusz Jozala Date: Thu, 25 Sep 2025 18:08:26 +0200 Subject: [PATCH 12/16] Make Version constructor protected to be able to use detached from Serverless --- .../main/java/org/elasticsearch/test/cluster/util/Version.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 887c89e40b3c2..59f9c0222c929 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 @@ -69,7 +69,7 @@ public Version(int major, int minor, int revision, String qualifier) { this(major, minor, revision, qualifier, false); } - private Version(int major, int minor, int revision, String qualifier, boolean detached) { + protected Version(int major, int minor, int revision, String qualifier, boolean detached) { this.major = major; this.minor = minor; this.revision = revision; From ebc9f8996ffc7a433c5fefd0756b66128018564b Mon Sep 17 00:00:00 2001 From: Mariusz Jozala Date: Mon, 29 Sep 2025 14:52:14 +0200 Subject: [PATCH 13/16] Verify the availability of the required system property with Gradle whenReady Using `project.gradle.taskGraph.whenReady` to check the required system properties as soon as possible. --- .../groovy/elasticsearch.bc-upgrade-test.gradle | 14 ++++++++------ qa/full-cluster-restart/build.gradle | 14 ++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/build-tools-internal/src/main/groovy/elasticsearch.bc-upgrade-test.gradle b/build-tools-internal/src/main/groovy/elasticsearch.bc-upgrade-test.gradle index 3af273c0d6f34..568201ca11130 100644 --- a/build-tools-internal/src/main/groovy/elasticsearch.bc-upgrade-test.gradle +++ b/build-tools-internal/src/main/groovy/elasticsearch.bc-upgrade-test.gradle @@ -11,12 +11,14 @@ import org.elasticsearch.gradle.Version import org.elasticsearch.gradle.testclusters.StandaloneRestIntegTestTask tasks.register("bcUpgradeTest", StandaloneRestIntegTestTask) { - doFirst { - if (System.getProperty("tests.bwc.refspec.main") == null) { - throw new GradleException("You must set the `tests.bwc.refspec.main` system property to run bcUpgradeTest") - } - if (System.getProperty("tests.bwc.main.version") == null) { - throw new GradleException("You must set the `tests.bwc.main.version` system property to run bcUpgradeTest") + project.gradle.taskGraph.whenReady { allTasks -> + if (allTasks.hasTask(getPath())) { + if (System.getProperty("tests.bwc.refspec.main") == null) { + throw new GradleException("You must set the `tests.bwc.refspec.main` system property to run bcUpgradeTest") + } + if (System.getProperty("tests.bwc.main.version") == null) { + throw new GradleException("You must set the `tests.bwc.main.version` system property to run bcUpgradeTest") + } } } if (System.getProperty("tests.bwc.refspec.main") != null && System.getProperty("tests.bwc.main.version") != null) { diff --git a/qa/full-cluster-restart/build.gradle b/qa/full-cluster-restart/build.gradle index b5b81d41c170f..26d51876b05ab 100644 --- a/qa/full-cluster-restart/build.gradle +++ b/qa/full-cluster-restart/build.gradle @@ -23,12 +23,14 @@ buildParams.bwcVersions.withIndexCompatible { bwcVersion, baseName -> } tasks.register("luceneBwcTest", StandaloneRestIntegTestTask) { - doFirst { - if (System.getProperty("tests.bwc.refspec.main") == null) { - throw new GradleException("You must set the `tests.bwc.refspec.main` system property to run luceneBwcTest") - } - if (System.getProperty("tests.bwc.main.version") == null) { - throw new GradleException("You must set the `tests.bwc.main.version` system property to run luceneBwcTest") + project.gradle.taskGraph.whenReady { allTasks -> + if (allTasks.hasTask(getPath())) { + if (System.getProperty("tests.bwc.refspec.main") == null) { + throw new GradleException("You must set the `tests.bwc.refspec.main` system property to run luceneBwcTest") + } + if (System.getProperty("tests.bwc.main.version") == null) { + throw new GradleException("You must set the `tests.bwc.main.version` system property to run luceneBwcTest") + } } } if (System.getProperty("tests.bwc.refspec.main") != null && System.getProperty("tests.bwc.main.version") != null) { From ed1f0bf86305afea5a39b17318a2cdec8cb61f5f Mon Sep 17 00:00:00 2001 From: Mariusz Jozala Date: Tue, 30 Sep 2025 09:36:05 +0200 Subject: [PATCH 14/16] Make detached part of the equals and hashcode methods for Version --- .../java/org/elasticsearch/test/cluster/util/Version.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 59f9c0222c929..9115537c24204 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 @@ -180,12 +180,12 @@ public boolean equals(Object o) { return false; } Version version = (Version) o; - return major == version.major && minor == version.minor && revision == version.revision; + return major == version.major && minor == version.minor && revision == version.revision && detached == version.detached; } @Override public int hashCode() { - return Objects.hash(major, minor, revision, id); + return Objects.hash(major, minor, revision, id, detached); } public int getMajor() { From f79252823db521f1277e4b16e6fde4647b4010b0 Mon Sep 17 00:00:00 2001 From: Mariusz Jozala Date: Tue, 30 Sep 2025 09:38:07 +0200 Subject: [PATCH 15/16] Revert to use Pair for Distribution key --- .../test/cluster/local/AbstractLocalClusterFactory.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java index d65b26fbe3819..1d52d305c18e3 100644 --- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java +++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/local/AbstractLocalClusterFactory.java @@ -74,7 +74,7 @@ public abstract class AbstractLocalClusterFactory { private static final Logger LOGGER = LogManager.getLogger(AbstractLocalClusterFactory.class); private static final Duration NODE_UP_TIMEOUT = Duration.ofMinutes(6); - private static final Map TEST_DISTRIBUTIONS = new ConcurrentHashMap<>(); + private static final Map, DistributionDescriptor> TEST_DISTRIBUTIONS = new ConcurrentHashMap<>(); private static final String TESTS_CLUSTER_MODULES_PATH_SYSPROP = "tests.cluster.modules.path"; private static final String TESTS_CLUSTER_PLUGINS_PATH_SYSPROP = "tests.cluster.plugins.path"; private static final String TESTS_CLUSTER_FIPS_JAR_PATH_SYSPROP = "tests.cluster.fips.jars.path"; @@ -397,8 +397,8 @@ private void copyExtraJarFiles() { private DistributionDescriptor resolveDistribution() { return TEST_DISTRIBUTIONS.computeIfAbsent( - new DistributionKey(spec.getVersion(), spec.getDistributionType()), - key -> distributionResolver.resolve(key.version, key.distributionType) + Pair.of(spec.getVersion(), spec.getDistributionType()), + key -> distributionResolver.resolve(key.left, key.right) ); } @@ -994,6 +994,4 @@ public String toString() { return "{ cluster: '" + spec.getCluster().getName() + "', node: '" + name + "' }"; } } - - public record DistributionKey(Version version, DistributionType distributionType) {} } From 44177270b2d25893ff2058212551018222f45193 Mon Sep 17 00:00:00 2001 From: Mariusz Jozala Date: Fri, 3 Oct 2025 11:16:58 +0200 Subject: [PATCH 16/16] Version `0.0.0` exception reverted Needs to stay there, because of the serverless tests. --- .../src/main/java/org/elasticsearch/gradle/util/OsUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-tools/src/main/java/org/elasticsearch/gradle/util/OsUtils.java b/build-tools/src/main/java/org/elasticsearch/gradle/util/OsUtils.java index c0f38ece0c8d6..486edf4150ab2 100644 --- a/build-tools/src/main/java/org/elasticsearch/gradle/util/OsUtils.java +++ b/build-tools/src/main/java/org/elasticsearch/gradle/util/OsUtils.java @@ -38,7 +38,7 @@ private OsUtils() {} * This method returns true if the given version of the JDK is known to be incompatible */ public static boolean jdkIsIncompatibleWithOS(Version version) { - return version.onOrBefore("8.10.4") && isUbuntu2404OrLater(); + return version.after("0.0.0") && version.onOrBefore("8.10.4") && isUbuntu2404OrLater(); } private static boolean isUbuntu2404OrLater() {