Browse Source

Retry rolling upgrade junit tests (#99760)

Re-applies the changes from #99572 to move some bwc tests to a junit-based build infrastructure. Some tests that did not handle the move well have been kept in rolling-upgrade-legacy using the old gradle-based infrastructure
Simon Cooper 2 years ago
parent
commit
5f43cd8f46
28 changed files with 893 additions and 638 deletions
  1. 1 1
      build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/RestrictedBuildApiService.java
  2. 1 1
      build-tools-internal/src/main/resources/checkstyle_suppressions.xml
  3. 5 0
      qa/full-cluster-restart/build.gradle
  4. 143 0
      qa/rolling-upgrade-legacy/build.gradle
  5. 0 18
      qa/rolling-upgrade-legacy/src/test/java/org/elasticsearch/upgrades/AbstractRollingTestCase.java
  6. 19 1
      qa/rolling-upgrade-legacy/src/test/java/org/elasticsearch/upgrades/RecoveryIT.java
  7. 0 5
      qa/rolling-upgrade-legacy/src/test/java/org/elasticsearch/upgrades/UpgradeClusterClientYamlTestSuiteIT.java
  8. 0 0
      qa/rolling-upgrade-legacy/src/test/resources/rest-api-spec/test/mixed_cluster/10_basic.yml
  9. 0 0
      qa/rolling-upgrade-legacy/src/test/resources/rest-api-spec/test/mixed_cluster/20_camel_case_on_format.yml
  10. 0 0
      qa/rolling-upgrade-legacy/src/test/resources/rest-api-spec/test/mixed_cluster/30_vector_search.yml
  11. 0 0
      qa/rolling-upgrade-legacy/src/test/resources/rest-api-spec/test/old_cluster/10_basic.yml
  12. 0 0
      qa/rolling-upgrade-legacy/src/test/resources/rest-api-spec/test/old_cluster/20_camel_case_on_format.yml
  13. 0 2
      qa/rolling-upgrade-legacy/src/test/resources/rest-api-spec/test/old_cluster/30_vector_search.yml
  14. 0 0
      qa/rolling-upgrade-legacy/src/test/resources/rest-api-spec/test/upgraded_cluster/10_basic.yml
  15. 0 0
      qa/rolling-upgrade-legacy/src/test/resources/rest-api-spec/test/upgraded_cluster/20_camel_case_on_format.yml
  16. 0 0
      qa/rolling-upgrade-legacy/src/test/resources/rest-api-spec/test/upgraded_cluster/30_vector_search.yml
  17. 13 122
      qa/rolling-upgrade/build.gradle
  18. 30 35
      qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/DesiredNodesUpgradeIT.java
  19. 10 6
      qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/FeatureUpgradeIT.java
  20. 20 14
      qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/FieldCapsIT.java
  21. 166 197
      qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/IndexingIT.java
  22. 226 0
      qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/ParameterizedRollingUpgradeTestCase.java
  23. 82 78
      qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/SnapshotBasedRecoveryIT.java
  24. 9 3
      qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/SystemIndicesUpgradeIT.java
  25. 26 20
      qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/TsdbIT.java
  26. 132 0
      qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/UpgradeWithOldIndexSettingsIT.java
  27. 10 4
      qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/XPackIT.java
  28. 0 131
      qa/rolling-upgrade/src/test/java/org/elasticsearch/upgrades/UpgradeWithOldIndexSettingsIT.java

+ 1 - 1
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/RestrictedBuildApiService.java

@@ -66,7 +66,7 @@ public abstract class RestrictedBuildApiService implements BuildService<Restrict
         map.put(LegacyRestTestBasePlugin.class, ":qa:multi-cluster-search");
         map.put(LegacyRestTestBasePlugin.class, ":qa:multi-cluster-search");
         map.put(LegacyRestTestBasePlugin.class, ":qa:remote-clusters");
         map.put(LegacyRestTestBasePlugin.class, ":qa:remote-clusters");
         map.put(LegacyRestTestBasePlugin.class, ":qa:repository-multi-version");
         map.put(LegacyRestTestBasePlugin.class, ":qa:repository-multi-version");
-        map.put(LegacyRestTestBasePlugin.class, ":qa:rolling-upgrade");
+        map.put(LegacyRestTestBasePlugin.class, ":qa:rolling-upgrade-legacy");
         map.put(LegacyRestTestBasePlugin.class, ":qa:smoke-test-http");
         map.put(LegacyRestTestBasePlugin.class, ":qa:smoke-test-http");
         map.put(LegacyRestTestBasePlugin.class, ":qa:smoke-test-ingest-disabled");
         map.put(LegacyRestTestBasePlugin.class, ":qa:smoke-test-ingest-disabled");
         map.put(LegacyRestTestBasePlugin.class, ":qa:smoke-test-ingest-with-all-dependencies");
         map.put(LegacyRestTestBasePlugin.class, ":qa:smoke-test-ingest-with-all-dependencies");

+ 1 - 1
build-tools-internal/src/main/resources/checkstyle_suppressions.xml

@@ -32,7 +32,7 @@
 
 
   <!-- Intentionally have multi line string for a bulk request, otherwise this needs to fallback to string concatenation  -->
   <!-- Intentionally have multi line string for a bulk request, otherwise this needs to fallback to string concatenation  -->
   <suppress files="modules[/\\]data-streams[/\\]src[/\\]javaRestTest[/\\]java[/\\]org[/\\]elasticsearch[/\\]datastreams[/\\]TsdbDataStreamRestIT.java" checks="LineLength" />
   <suppress files="modules[/\\]data-streams[/\\]src[/\\]javaRestTest[/\\]java[/\\]org[/\\]elasticsearch[/\\]datastreams[/\\]TsdbDataStreamRestIT.java" checks="LineLength" />
-  <suppress files="qa[/\\]rolling-upgrade[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]upgrades[/\\]TsdbIT.java" checks="LineLength" />
+  <suppress files="qa[/\\]rolling-upgrade[/\\]src[/\\]javaRestTest[/\\]java[/\\]org[/\\]elasticsearch[/\\]upgrades[/\\]TsdbIT.java" checks="LineLength" />
 
 
   <!-- Gradle requires inputs to be seriablizable -->
   <!-- Gradle requires inputs to be seriablizable -->
   <suppress files="build-tools-internal[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]gradle[/\\]internal[/\\]precommit[/\\]TestingConventionRule.java" checks="RegexpSinglelineJava" />
   <suppress files="build-tools-internal[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]gradle[/\\]internal[/\\]precommit[/\\]TestingConventionRule.java" checks="RegexpSinglelineJava" />

+ 5 - 0
qa/full-cluster-restart/build.gradle

@@ -19,3 +19,8 @@ BuildParams.bwcVersions.withIndexCompatible { bwcVersion, baseName ->
     systemProperty("tests.old_cluster_version", bwcVersion)
     systemProperty("tests.old_cluster_version", bwcVersion)
   }
   }
 }
 }
+
+tasks.withType(Test).configureEach {
+  // CI doesn't like it when there's multiple clusters running at once
+  maxParallelForks = 1
+}

+ 143 - 0
qa/rolling-upgrade-legacy/build.gradle

@@ -0,0 +1,143 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+
+import org.elasticsearch.gradle.Version
+import org.elasticsearch.gradle.internal.BwcVersions
+import org.elasticsearch.gradle.internal.info.BuildParams
+import org.elasticsearch.gradle.testclusters.StandaloneRestIntegTestTask
+
+apply plugin: 'elasticsearch.internal-testclusters'
+apply plugin: 'elasticsearch.standalone-rest-test'
+apply plugin: 'elasticsearch.bwc-test'
+apply plugin: 'elasticsearch.rest-resources'
+
+BuildParams.bwcVersions.withWireCompatible { bwcVersion, baseName ->
+  /*
+   * NOTE: This module is for the tests that were problematic when converting :qa:rolling-upgrade to the junit-based bwc test definition
+   * Over time, these should be migrated into the :qa:rolling-upgrade module and fixed properly
+   *
+   * The goal here is to:
+   * <ul>
+   *  <li>start three nodes on the old version
+   *  <li>run tests with systemProperty 'tests.rest.suite', 'old_cluster'
+   *  <li>upgrade one node
+   *  <li>run tests with systemProperty 'tests.rest.suite', 'mixed_cluster'
+   *  <li>upgrade one more node
+   *  <li>run tests with systemProperty 'tests.rest.suite', 'mixed_cluster' again
+   *  <li>updgrade the last node
+   *  <li>run tests with systemProperty 'tests.rest.suite', 'upgraded_cluster'
+   * </ul>
+   */
+
+  def baseCluster = testClusters.register(baseName) {
+    versions = [bwcVersion.toString(), project.version]
+    numberOfNodes = 3
+
+    setting 'repositories.url.allowed_urls', 'http://snapshot.test*'
+    setting 'path.repo', "${buildDir}/cluster/shared/repo/${baseName}"
+    setting 'xpack.security.enabled', 'false'
+    setting 'logger.org.elasticsearch.cluster.service.MasterService', 'TRACE'
+    setting 'logger.org.elasticsearch.cluster.routing.allocation.allocator.DesiredBalanceShardsAllocator', 'TRACE'
+    setting 'logger.org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders', 'TRACE'
+    requiresFeature 'es.index_mode_feature_flag_registered', Version.fromString("8.0.0")
+  }
+
+  String oldVersion = bwcVersion.toString()
+
+  tasks.register("${baseName}#oldClusterTest", StandaloneRestIntegTestTask) {
+    dependsOn "processTestResources"
+    useCluster baseCluster
+    mustRunAfter("precommit")
+    doFirst {
+      delete("${buildDir}/cluster/shared/repo/${baseName}")
+    }
+    def excludeList = []
+    systemProperty 'tests.rest.suite', 'old_cluster'
+    systemProperty 'tests.upgrade_from_version', oldVersion
+    nonInputProperties.systemProperty('tests.rest.cluster', baseCluster.map(c -> c.allHttpSocketURI.join(",")))
+    nonInputProperties.systemProperty('tests.clustername', baseName)
+    if (bwcVersion.before("8.4.0")) {
+      excludeList.addAll(["old_cluster/30_vector_search/*"])
+    } else if (bwcVersion.before("8.6.0")) {
+      excludeList.addAll(["old_cluster/30_vector_search/Create indexed byte vectors and search"])
+    }
+    if (excludeList.isEmpty() == false) {
+      systemProperty 'tests.rest.blacklist', excludeList.join(',')
+    }
+  }
+
+  tasks.register("${baseName}#oneThirdUpgradedTest", StandaloneRestIntegTestTask) {
+    dependsOn "${baseName}#oldClusterTest"
+    useCluster baseCluster
+    doFirst {
+      baseCluster.get().nextNodeToNextVersion()
+    }
+    systemProperty 'tests.rest.suite', 'mixed_cluster'
+    systemProperty 'tests.upgrade_from_version', oldVersion
+    systemProperty 'tests.first_round', 'true'
+    nonInputProperties.systemProperty('tests.rest.cluster', baseCluster.map(c -> c.allHttpSocketURI.join(",")))
+    nonInputProperties.systemProperty('tests.clustername', baseName)
+    def excludeList = []
+    if (bwcVersion.before("8.4.0")) {
+      excludeList.addAll(["mixed_cluster/30_vector_search/*"])
+    } else if (bwcVersion.before("8.6.0")) {
+      excludeList.addAll(["mixed_cluster/30_vector_search/Search byte indices created in old cluster"])
+    }
+    if (excludeList.isEmpty() == false) {
+      systemProperty 'tests.rest.blacklist', excludeList.join(',')
+    }
+  }
+
+  tasks.register("${baseName}#twoThirdsUpgradedTest", StandaloneRestIntegTestTask) {
+    dependsOn "${baseName}#oneThirdUpgradedTest"
+    useCluster baseCluster
+    doFirst {
+      baseCluster.get().nextNodeToNextVersion()
+    }
+    systemProperty 'tests.rest.suite', 'mixed_cluster'
+    systemProperty 'tests.upgrade_from_version', oldVersion
+    systemProperty 'tests.first_round', 'false'
+    nonInputProperties.systemProperty('tests.rest.cluster', baseCluster.map(c -> c.allHttpSocketURI.join(",")))
+    nonInputProperties.systemProperty('tests.clustername', baseName)
+    def excludeList = []
+    if (bwcVersion.before("8.4.0")) {
+      excludeList.addAll(["mixed_cluster/30_vector_search/*"])
+    } else if (bwcVersion.before("8.6.0")) {
+      excludeList.addAll(["mixed_cluster/30_vector_search/Search byte indices created in old cluster"])
+    }
+    if (excludeList.isEmpty() == false) {
+      systemProperty 'tests.rest.blacklist', excludeList.join(',')
+    }
+  }
+
+  tasks.register("${baseName}#upgradedClusterTest", StandaloneRestIntegTestTask) {
+    dependsOn "${baseName}#twoThirdsUpgradedTest"
+    doFirst {
+      baseCluster.get().nextNodeToNextVersion()
+    }
+    useCluster testClusters.named(baseName)
+    systemProperty 'tests.rest.suite', 'upgraded_cluster'
+    systemProperty 'tests.upgrade_from_version', oldVersion
+    nonInputProperties.systemProperty('tests.rest.cluster', baseCluster.map(c -> c.allHttpSocketURI.join(",")))
+    nonInputProperties.systemProperty('tests.clustername', baseName)
+    def excludeList = []
+    if (bwcVersion.before("8.4.0")) {
+      excludeList.addAll(["upgraded_cluster/30_vector_search/*"])
+    } else if (bwcVersion.before("8.6.0")) {
+      excludeList.addAll(["upgraded_cluster/30_vector_search/Search byte indices created in old cluster"])
+    }
+    if (excludeList.isEmpty() == false) {
+      systemProperty 'tests.rest.blacklist', excludeList.join(',')
+    }
+  }
+
+  tasks.register(bwcTaskName(bwcVersion)) {
+    dependsOn tasks.named("${baseName}#upgradedClusterTest")
+  }
+}

+ 0 - 18
qa/rolling-upgrade/src/test/java/org/elasticsearch/upgrades/AbstractRollingTestCase.java → qa/rolling-upgrade-legacy/src/test/java/org/elasticsearch/upgrades/AbstractRollingTestCase.java

@@ -9,11 +9,8 @@ package org.elasticsearch.upgrades;
 
 
 import org.elasticsearch.Version;
 import org.elasticsearch.Version;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.index.IndexVersion;
 import org.elasticsearch.test.rest.ESRestTestCase;
 import org.elasticsearch.test.rest.ESRestTestCase;
 
 
-import static org.hamcrest.Matchers.lessThan;
-
 public abstract class AbstractRollingTestCase extends ESRestTestCase {
 public abstract class AbstractRollingTestCase extends ESRestTestCase {
     protected enum ClusterType {
     protected enum ClusterType {
         OLD,
         OLD,
@@ -34,16 +31,6 @@ public abstract class AbstractRollingTestCase extends ESRestTestCase {
     protected static final boolean FIRST_MIXED_ROUND = Boolean.parseBoolean(System.getProperty("tests.first_round", "false"));
     protected static final boolean FIRST_MIXED_ROUND = Boolean.parseBoolean(System.getProperty("tests.first_round", "false"));
     protected static final Version UPGRADE_FROM_VERSION = Version.fromString(System.getProperty("tests.upgrade_from_version"));
     protected static final Version UPGRADE_FROM_VERSION = Version.fromString(System.getProperty("tests.upgrade_from_version"));
 
 
-    protected static IndexVersion getOldClusterIndexVersion() {
-        var version = UPGRADE_FROM_VERSION;
-        if (version.equals(org.elasticsearch.Version.CURRENT)) {
-            return IndexVersion.current();
-        } else {
-            assertThat("Index version needs to be added to rolling test parameters", version, lessThan(org.elasticsearch.Version.V_8_11_0));
-            return IndexVersion.fromId(version.id);
-        }
-    }
-
     @Override
     @Override
     protected final boolean resetFeatureStates() {
     protected final boolean resetFeatureStates() {
         return false;
         return false;
@@ -54,11 +41,6 @@ public abstract class AbstractRollingTestCase extends ESRestTestCase {
         return true;
         return true;
     }
     }
 
 
-    @Override
-    protected final boolean preserveDataStreamsUponCompletion() {
-        return true;
-    }
-
     @Override
     @Override
     protected final boolean preserveReposUponCompletion() {
     protected final boolean preserveReposUponCompletion() {
         return true;
         return true;

+ 19 - 1
qa/rolling-upgrade/src/test/java/org/elasticsearch/upgrades/RecoveryIT.java → qa/rolling-upgrade-legacy/src/test/java/org/elasticsearch/upgrades/RecoveryIT.java

@@ -41,7 +41,6 @@ import static com.carrotsearch.randomizedtesting.RandomizedTest.randomAsciiLette
 import static org.elasticsearch.cluster.routing.UnassignedInfo.INDEX_DELAYED_NODE_LEFT_TIMEOUT_SETTING;
 import static org.elasticsearch.cluster.routing.UnassignedInfo.INDEX_DELAYED_NODE_LEFT_TIMEOUT_SETTING;
 import static org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider.INDEX_ROUTING_ALLOCATION_ENABLE_SETTING;
 import static org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider.INDEX_ROUTING_ALLOCATION_ENABLE_SETTING;
 import static org.elasticsearch.cluster.routing.allocation.decider.MaxRetryAllocationDecider.SETTING_ALLOCATION_MAX_RETRY;
 import static org.elasticsearch.cluster.routing.allocation.decider.MaxRetryAllocationDecider.SETTING_ALLOCATION_MAX_RETRY;
-import static org.elasticsearch.upgrades.UpgradeWithOldIndexSettingsIT.updateIndexSettingsPermittingSlowlogDeprecationWarning;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.in;
 import static org.hamcrest.Matchers.in;
@@ -747,4 +746,23 @@ public class RecoveryIT extends AbstractRollingTestCase {
         ensureGreen(indexName);
         ensureGreen(indexName);
         indexDocs(indexName, randomInt(100), randomInt(100));
         indexDocs(indexName, randomInt(100), randomInt(100));
     }
     }
+
+    /*
+     * Copied from UpgradeWithOldIndexSettingsIT in the new format
+     */
+    private static void updateIndexSettingsPermittingSlowlogDeprecationWarning(String index, Settings.Builder settings) throws IOException {
+        Request request = new Request("PUT", "/" + index + "/_settings");
+        request.setJsonEntity(org.elasticsearch.common.Strings.toString(settings.build()));
+        if (UPGRADE_FROM_VERSION.before(Version.V_7_17_9)) {
+            // There is a bug (fixed in 7.17.9 and 8.7.0 where deprecation warnings could leak into ClusterApplierService#applyChanges)
+            // Below warnings are set (and leaking) from an index in this test case
+            request.setOptions(expectVersionSpecificWarnings(v -> {
+                v.compatible(
+                    "[index.indexing.slowlog.level] setting was deprecated in Elasticsearch and will be removed in a future release! "
+                        + "See the breaking changes documentation for the next major version."
+                );
+            }));
+        }
+        client().performRequest(request);
+    }
 }
 }

+ 0 - 5
qa/rolling-upgrade/src/test/java/org/elasticsearch/upgrades/UpgradeClusterClientYamlTestSuiteIT.java → qa/rolling-upgrade-legacy/src/test/java/org/elasticsearch/upgrades/UpgradeClusterClientYamlTestSuiteIT.java

@@ -40,11 +40,6 @@ public class UpgradeClusterClientYamlTestSuiteIT extends ESClientYamlSuiteTestCa
         return true;
         return true;
     }
     }
 
 
-    @Override
-    protected boolean preserveDataStreamsUponCompletion() {
-        return true;
-    }
-
     public UpgradeClusterClientYamlTestSuiteIT(ClientYamlTestCandidate testCandidate) {
     public UpgradeClusterClientYamlTestSuiteIT(ClientYamlTestCandidate testCandidate) {
         super(testCandidate);
         super(testCandidate);
     }
     }

+ 0 - 0
qa/rolling-upgrade/src/test/resources/rest-api-spec/test/mixed_cluster/10_basic.yml → qa/rolling-upgrade-legacy/src/test/resources/rest-api-spec/test/mixed_cluster/10_basic.yml


+ 0 - 0
qa/rolling-upgrade/src/test/resources/rest-api-spec/test/mixed_cluster/20_camel_case_on_format.yml → qa/rolling-upgrade-legacy/src/test/resources/rest-api-spec/test/mixed_cluster/20_camel_case_on_format.yml


+ 0 - 0
qa/rolling-upgrade/src/test/resources/rest-api-spec/test/mixed_cluster/30_vector_search.yml → qa/rolling-upgrade-legacy/src/test/resources/rest-api-spec/test/mixed_cluster/30_vector_search.yml


+ 0 - 0
qa/rolling-upgrade/src/test/resources/rest-api-spec/test/old_cluster/10_basic.yml → qa/rolling-upgrade-legacy/src/test/resources/rest-api-spec/test/old_cluster/10_basic.yml


+ 0 - 0
qa/rolling-upgrade/src/test/resources/rest-api-spec/test/old_cluster/20_camel_case_on_format.yml → qa/rolling-upgrade-legacy/src/test/resources/rest-api-spec/test/old_cluster/20_camel_case_on_format.yml


+ 0 - 2
qa/rolling-upgrade/src/test/resources/rest-api-spec/test/old_cluster/30_vector_search.yml → qa/rolling-upgrade-legacy/src/test/resources/rest-api-spec/test/old_cluster/30_vector_search.yml

@@ -11,7 +11,6 @@
               bdv:
               bdv:
                 type: dense_vector
                 type: dense_vector
                 dims: 3
                 dims: 3
-                index: false
               knn:
               knn:
                 type: dense_vector
                 type: dense_vector
                 dims: 3
                 dims: 3
@@ -126,7 +125,6 @@
               bdv:
               bdv:
                 type: dense_vector
                 type: dense_vector
                 element_type: byte
                 element_type: byte
-                index: false
                 dims: 3
                 dims: 3
               knn:
               knn:
                 type: dense_vector
                 type: dense_vector

+ 0 - 0
qa/rolling-upgrade/src/test/resources/rest-api-spec/test/upgraded_cluster/10_basic.yml → qa/rolling-upgrade-legacy/src/test/resources/rest-api-spec/test/upgraded_cluster/10_basic.yml


+ 0 - 0
qa/rolling-upgrade/src/test/resources/rest-api-spec/test/upgraded_cluster/20_camel_case_on_format.yml → qa/rolling-upgrade-legacy/src/test/resources/rest-api-spec/test/upgraded_cluster/20_camel_case_on_format.yml


+ 0 - 0
qa/rolling-upgrade/src/test/resources/rest-api-spec/test/upgraded_cluster/30_vector_search.yml → qa/rolling-upgrade-legacy/src/test/resources/rest-api-spec/test/upgraded_cluster/30_vector_search.yml


+ 13 - 122
qa/rolling-upgrade/build.gradle

@@ -6,135 +6,26 @@
  * Side Public License, v 1.
  * Side Public License, v 1.
  */
  */
 
 
-
-import org.elasticsearch.gradle.Version
-import org.elasticsearch.gradle.internal.BwcVersions
 import org.elasticsearch.gradle.internal.info.BuildParams
 import org.elasticsearch.gradle.internal.info.BuildParams
 import org.elasticsearch.gradle.testclusters.StandaloneRestIntegTestTask
 import org.elasticsearch.gradle.testclusters.StandaloneRestIntegTestTask
 
 
 apply plugin: 'elasticsearch.internal-testclusters'
 apply plugin: 'elasticsearch.internal-testclusters'
-apply plugin: 'elasticsearch.standalone-rest-test'
+apply plugin: 'elasticsearch.internal-java-rest-test'
+apply plugin: 'elasticsearch.internal-test-artifact-base'
 apply plugin: 'elasticsearch.bwc-test'
 apply plugin: 'elasticsearch.bwc-test'
-apply plugin: 'elasticsearch.rest-resources'
-
-BuildParams.bwcVersions.withWireCompatible { bwcVersion, baseName ->
-  /*
-   * The goal here is to:
-   * <ul>
-   *  <li>start three nodes on the old version
-   *  <li>run tests with systemProperty 'tests.rest.suite', 'old_cluster'
-   *  <li>upgrade one node
-   *  <li>run tests with systemProperty 'tests.rest.suite', 'mixed_cluster'
-   *  <li>upgrade one more node
-   *  <li>run tests with systemProperty 'tests.rest.suite', 'mixed_cluster' again
-   *  <li>updgrade the last node
-   *  <li>run tests with systemProperty 'tests.rest.suite', 'upgraded_cluster'
-   * </ul>
-   */
-
-  def baseCluster = testClusters.register(baseName) {
-    versions = [bwcVersion.toString(), project.version]
-    numberOfNodes = 3
-
-    setting 'repositories.url.allowed_urls', 'http://snapshot.test*'
-    setting 'path.repo', "${buildDir}/cluster/shared/repo/${baseName}"
-    setting 'xpack.security.enabled', 'false'
-    setting 'logger.org.elasticsearch.cluster.service.MasterService', 'TRACE'
-    setting 'logger.org.elasticsearch.cluster.routing.allocation.allocator.DesiredBalanceShardsAllocator', 'TRACE'
-    setting 'logger.org.elasticsearch.cluster.routing.allocation.decider.AllocationDeciders', 'TRACE'
-    requiresFeature 'es.index_mode_feature_flag_registered', Version.fromString("8.0.0")
-  }
-
-  String oldVersion = bwcVersion.toString()
-
-  tasks.register("${baseName}#oldClusterTest", StandaloneRestIntegTestTask) {
-    dependsOn "processTestResources"
-    useCluster baseCluster
-    mustRunAfter("precommit")
-    doFirst {
-      delete("${buildDir}/cluster/shared/repo/${baseName}")
-    }
-    def excludeList = []
-    systemProperty 'tests.rest.suite', 'old_cluster'
-    systemProperty 'tests.upgrade_from_version', oldVersion
-    nonInputProperties.systemProperty('tests.rest.cluster', baseCluster.map(c -> c.allHttpSocketURI.join(",")))
-    nonInputProperties.systemProperty('tests.clustername', baseName)
-    if (bwcVersion.before("8.4.0")) {
-      excludeList.addAll(["old_cluster/30_vector_search/*"])
-    } else if (bwcVersion.before("8.6.0")) {
-      excludeList.addAll(["old_cluster/30_vector_search/Create indexed byte vectors and search"])
-    }
-    if (excludeList.isEmpty() == false) {
-      systemProperty 'tests.rest.blacklist', excludeList.join(',')
-    }
-  }
-
-  tasks.register("${baseName}#oneThirdUpgradedTest", StandaloneRestIntegTestTask) {
-    dependsOn "${baseName}#oldClusterTest"
-    useCluster baseCluster
-    doFirst {
-      baseCluster.get().nextNodeToNextVersion()
-    }
-    systemProperty 'tests.rest.suite', 'mixed_cluster'
-    systemProperty 'tests.upgrade_from_version', oldVersion
-    systemProperty 'tests.first_round', 'true'
-    nonInputProperties.systemProperty('tests.rest.cluster', baseCluster.map(c -> c.allHttpSocketURI.join(",")))
-    nonInputProperties.systemProperty('tests.clustername', baseName)
-    def excludeList = []
-    if (bwcVersion.before("8.4.0")) {
-      excludeList.addAll(["mixed_cluster/30_vector_search/*"])
-    } else if (bwcVersion.before("8.6.0")) {
-      excludeList.addAll(["mixed_cluster/30_vector_search/Search byte indices created in old cluster"])
-    }
-    if (excludeList.isEmpty() == false) {
-      systemProperty 'tests.rest.blacklist', excludeList.join(',')
-    }
-  }
 
 
-  tasks.register("${baseName}#twoThirdsUpgradedTest", StandaloneRestIntegTestTask) {
-    dependsOn "${baseName}#oneThirdUpgradedTest"
-    useCluster baseCluster
-    doFirst {
-      baseCluster.get().nextNodeToNextVersion()
-    }
-    systemProperty 'tests.rest.suite', 'mixed_cluster'
-    systemProperty 'tests.upgrade_from_version', oldVersion
-    systemProperty 'tests.first_round', 'false'
-    nonInputProperties.systemProperty('tests.rest.cluster', baseCluster.map(c -> c.allHttpSocketURI.join(",")))
-    nonInputProperties.systemProperty('tests.clustername', baseName)
-    def excludeList = []
-    if (bwcVersion.before("8.4.0")) {
-      excludeList.addAll(["mixed_cluster/30_vector_search/*"])
-    } else if (bwcVersion.before("8.6.0")) {
-      excludeList.addAll(["mixed_cluster/30_vector_search/Search byte indices created in old cluster"])
-    }
-    if (excludeList.isEmpty() == false) {
-      systemProperty 'tests.rest.blacklist', excludeList.join(',')
-    }
-  }
+testArtifacts {
+  registerTestArtifactFromSourceSet(sourceSets.javaRestTest)
+}
 
 
-  tasks.register("${baseName}#upgradedClusterTest", StandaloneRestIntegTestTask) {
-    dependsOn "${baseName}#twoThirdsUpgradedTest"
-    doFirst {
-      baseCluster.get().nextNodeToNextVersion()
-    }
-    useCluster testClusters.named(baseName)
-    systemProperty 'tests.rest.suite', 'upgraded_cluster'
-    systemProperty 'tests.upgrade_from_version', oldVersion
-    nonInputProperties.systemProperty('tests.rest.cluster', baseCluster.map(c -> c.allHttpSocketURI.join(",")))
-    nonInputProperties.systemProperty('tests.clustername', baseName)
-    def excludeList = []
-    if (bwcVersion.before("8.4.0")) {
-      excludeList.addAll(["upgraded_cluster/30_vector_search/*"])
-    } else if (bwcVersion.before("8.6.0")) {
-      excludeList.addAll(["upgraded_cluster/30_vector_search/Search byte indices created in old cluster"])
-    }
-    if (excludeList.isEmpty() == false) {
-      systemProperty 'tests.rest.blacklist', excludeList.join(',')
-    }
+BuildParams.bwcVersions.withWireCompatible { bwcVersion, baseName ->
+  tasks.register(bwcTaskName(bwcVersion), StandaloneRestIntegTestTask) {
+    usesBwcDistribution(bwcVersion)
+    systemProperty("tests.old_cluster_version", bwcVersion)
   }
   }
+}
 
 
-  tasks.register(bwcTaskName(bwcVersion)) {
-    dependsOn tasks.named("${baseName}#upgradedClusterTest")
-  }
+tasks.withType(Test).configureEach {
+  // CI doesn't like it when there's multiple clusters running at once
+  maxParallelForks = 1
 }
 }

+ 30 - 35
qa/rolling-upgrade/src/test/java/org/elasticsearch/upgrades/DesiredNodesUpgradeIT.java → qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/DesiredNodesUpgradeIT.java

@@ -8,6 +8,8 @@
 
 
 package org.elasticsearch.upgrades;
 package org.elasticsearch.upgrades;
 
 
+import com.carrotsearch.randomizedtesting.annotations.Name;
+
 import org.elasticsearch.Version;
 import org.elasticsearch.Version;
 import org.elasticsearch.action.admin.cluster.desirednodes.UpdateDesiredNodesRequest;
 import org.elasticsearch.action.admin.cluster.desirednodes.UpdateDesiredNodesRequest;
 import org.elasticsearch.client.Request;
 import org.elasticsearch.client.Request;
@@ -31,18 +33,26 @@ import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.greaterThan;
 import static org.hamcrest.Matchers.greaterThan;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.is;
 
 
-public class DesiredNodesUpgradeIT extends AbstractRollingTestCase {
+public class DesiredNodesUpgradeIT extends ParameterizedRollingUpgradeTestCase {
+
+    private final int desiredNodesVersion;
+
+    public DesiredNodesUpgradeIT(@Name("upgradedNodes") int upgradedNodes) {
+        super(upgradedNodes);
+        desiredNodesVersion = upgradedNodes + 1;
+    }
+
     private enum ProcessorsPrecision {
     private enum ProcessorsPrecision {
         DOUBLE,
         DOUBLE,
         FLOAT
         FLOAT
     }
     }
 
 
     public void testUpgradeDesiredNodes() throws Exception {
     public void testUpgradeDesiredNodes() throws Exception {
-        assumeTrue("Desired nodes was introduced in 8.1", UPGRADE_FROM_VERSION.onOrAfter(Version.V_8_1_0));
+        assumeTrue("Desired nodes was introduced in 8.1", getOldClusterVersion().onOrAfter(Version.V_8_1_0));
 
 
-        if (UPGRADE_FROM_VERSION.onOrAfter(Processors.DOUBLE_PROCESSORS_SUPPORT_VERSION)) {
+        if (getOldClusterVersion().onOrAfter(Processors.DOUBLE_PROCESSORS_SUPPORT_VERSION)) {
             assertUpgradedNodesCanReadDesiredNodes();
             assertUpgradedNodesCanReadDesiredNodes();
-        } else if (UPGRADE_FROM_VERSION.onOrAfter(DesiredNode.RANGE_FLOAT_PROCESSORS_SUPPORT_VERSION)) {
+        } else if (getOldClusterVersion().onOrAfter(DesiredNode.RANGE_FLOAT_PROCESSORS_SUPPORT_VERSION)) {
             assertDesiredNodesUpdatedWithRoundedUpFloatsAreIdempotent();
             assertDesiredNodesUpdatedWithRoundedUpFloatsAreIdempotent();
         } else {
         } else {
             assertDesiredNodesWithFloatProcessorsAreRejectedInOlderVersions();
             assertDesiredNodesWithFloatProcessorsAreRejectedInOlderVersions();
@@ -50,13 +60,7 @@ public class DesiredNodesUpgradeIT extends AbstractRollingTestCase {
     }
     }
 
 
     private void assertUpgradedNodesCanReadDesiredNodes() throws Exception {
     private void assertUpgradedNodesCanReadDesiredNodes() throws Exception {
-        final int desiredNodesVersion = switch (CLUSTER_TYPE) {
-            case OLD -> 1;
-            case MIXED -> FIRST_MIXED_ROUND ? 2 : 3;
-            case UPGRADED -> 4;
-        };
-
-        if (CLUSTER_TYPE != ClusterType.OLD) {
+        if (isMixedCluster() || isUpgradedCluster()) {
             final Map<String, Object> desiredNodes = getLatestDesiredNodes();
             final Map<String, Object> desiredNodes = getLatestDesiredNodes();
             final String historyId = extractValue(desiredNodes, "history_id");
             final String historyId = extractValue(desiredNodes, "history_id");
             final int version = extractValue(desiredNodes, "version");
             final int version = extractValue(desiredNodes, "version");
@@ -83,13 +87,7 @@ public class DesiredNodesUpgradeIT extends AbstractRollingTestCase {
             )
             )
             .toList();
             .toList();
 
 
-        final int desiredNodesVersion = switch (CLUSTER_TYPE) {
-            case OLD -> 1;
-            case MIXED -> FIRST_MIXED_ROUND ? 2 : 3;
-            case UPGRADED -> 4;
-        };
-
-        if (CLUSTER_TYPE != ClusterType.OLD) {
+        if (isMixedCluster() || isUpgradedCluster()) {
             updateDesiredNodes(desiredNodes, desiredNodesVersion - 1);
             updateDesiredNodes(desiredNodes, desiredNodesVersion - 1);
         }
         }
         for (int i = 0; i < 2; i++) {
         for (int i = 0; i < 2; i++) {
@@ -100,28 +98,25 @@ public class DesiredNodesUpgradeIT extends AbstractRollingTestCase {
         final int latestDesiredNodesVersion = extractValue(latestDesiredNodes, "version");
         final int latestDesiredNodesVersion = extractValue(latestDesiredNodes, "version");
         assertThat(latestDesiredNodesVersion, is(equalTo(desiredNodesVersion)));
         assertThat(latestDesiredNodesVersion, is(equalTo(desiredNodesVersion)));
 
 
-        if (CLUSTER_TYPE == ClusterType.UPGRADED) {
+        if (isUpgradedCluster()) {
             assertAllDesiredNodesAreActualized();
             assertAllDesiredNodesAreActualized();
         }
         }
     }
     }
 
 
     private void assertDesiredNodesWithFloatProcessorsAreRejectedInOlderVersions() throws Exception {
     private void assertDesiredNodesWithFloatProcessorsAreRejectedInOlderVersions() throws Exception {
-        switch (CLUSTER_TYPE) {
-            case OLD -> addClusterNodesToDesiredNodesWithIntegerProcessors(1);
-            case MIXED -> {
-                int version = FIRST_MIXED_ROUND ? 2 : 3;
-                // Processor ranges or float processors are forbidden during upgrades: 8.2 -> 8.3 clusters
-                final var responseException = expectThrows(
-                    ResponseException.class,
-                    () -> addClusterNodesToDesiredNodesWithProcessorsOrProcessorRanges(version, ProcessorsPrecision.FLOAT)
-                );
-                final var statusCode = responseException.getResponse().getStatusLine().getStatusCode();
-                assertThat(statusCode, is(equalTo(400)));
-            }
-            case UPGRADED -> {
-                assertAllDesiredNodesAreActualized();
-                addClusterNodesToDesiredNodesWithProcessorsOrProcessorRanges(4, ProcessorsPrecision.FLOAT);
-            }
+        if (isOldCluster()) {
+            addClusterNodesToDesiredNodesWithIntegerProcessors(1);
+        } else if (isMixedCluster()) {
+            // Processor ranges or float processors are forbidden during upgrades: 8.2 -> 8.3 clusters
+            final var responseException = expectThrows(
+                ResponseException.class,
+                () -> addClusterNodesToDesiredNodesWithProcessorsOrProcessorRanges(desiredNodesVersion, ProcessorsPrecision.FLOAT)
+            );
+            final var statusCode = responseException.getResponse().getStatusLine().getStatusCode();
+            assertThat(statusCode, is(equalTo(400)));
+        } else {
+            assertAllDesiredNodesAreActualized();
+            addClusterNodesToDesiredNodesWithProcessorsOrProcessorRanges(4, ProcessorsPrecision.FLOAT);
         }
         }
 
 
         getLatestDesiredNodes();
         getLatestDesiredNodes();

+ 10 - 6
qa/rolling-upgrade/src/test/java/org/elasticsearch/upgrades/FeatureUpgradeIT.java → qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/FeatureUpgradeIT.java

@@ -8,6 +8,8 @@
 
 
 package org.elasticsearch.upgrades;
 package org.elasticsearch.upgrades;
 
 
+import com.carrotsearch.randomizedtesting.annotations.Name;
+
 import org.elasticsearch.action.admin.cluster.migration.TransportGetFeatureUpgradeStatusAction;
 import org.elasticsearch.action.admin.cluster.migration.TransportGetFeatureUpgradeStatusAction;
 import org.elasticsearch.client.Request;
 import org.elasticsearch.client.Request;
 import org.elasticsearch.client.ResponseException;
 import org.elasticsearch.client.ResponseException;
@@ -21,14 +23,17 @@ import static org.hamcrest.Matchers.aMapWithSize;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.is;
 
 
-public class FeatureUpgradeIT extends AbstractRollingTestCase {
+public class FeatureUpgradeIT extends ParameterizedRollingUpgradeTestCase {
+
+    public FeatureUpgradeIT(@Name("upgradedNodes") int upgradedNodes) {
+        super(upgradedNodes);
+    }
 
 
-    @SuppressWarnings("unchecked")
     public void testGetFeatureUpgradeStatus() throws Exception {
     public void testGetFeatureUpgradeStatus() throws Exception {
 
 
         final String systemIndexWarning = "this request accesses system indices: [.tasks], but in a future major version, direct "
         final String systemIndexWarning = "this request accesses system indices: [.tasks], but in a future major version, direct "
             + "access to system indices will be prevented by default";
             + "access to system indices will be prevented by default";
-        if (CLUSTER_TYPE == ClusterType.OLD) {
+        if (isOldCluster()) {
             // setup - put something in the tasks index
             // setup - put something in the tasks index
             // create index
             // create index
             Request createTestIndex = new Request("PUT", "/feature_test_index_old");
             Request createTestIndex = new Request("PUT", "/feature_test_index_old");
@@ -79,7 +84,7 @@ public class FeatureUpgradeIT extends AbstractRollingTestCase {
                 }
                 }
             });
             });
 
 
-        } else if (CLUSTER_TYPE == ClusterType.UPGRADED) {
+        } else if (isUpgradedCluster()) {
             // check results
             // check results
             assertBusy(() -> {
             assertBusy(() -> {
                 Request clusterStateRequest = new Request("GET", "/_migration/system_features");
                 Request clusterStateRequest = new Request("GET", "/_migration/system_features");
@@ -95,7 +100,7 @@ public class FeatureUpgradeIT extends AbstractRollingTestCase {
 
 
                 assertThat(feature, aMapWithSize(4));
                 assertThat(feature, aMapWithSize(4));
                 assertThat(feature.get("minimum_index_version"), equalTo(getOldClusterIndexVersion().toString()));
                 assertThat(feature.get("minimum_index_version"), equalTo(getOldClusterIndexVersion().toString()));
-                if (UPGRADE_FROM_VERSION.before(TransportGetFeatureUpgradeStatusAction.NO_UPGRADE_REQUIRED_VERSION)) {
+                if (getOldClusterVersion().before(TransportGetFeatureUpgradeStatusAction.NO_UPGRADE_REQUIRED_VERSION)) {
                     assertThat(feature.get("migration_status"), equalTo("MIGRATION_NEEDED"));
                     assertThat(feature.get("migration_status"), equalTo("MIGRATION_NEEDED"));
                 } else {
                 } else {
                     assertThat(feature.get("migration_status"), equalTo("NO_MIGRATION_NEEDED"));
                     assertThat(feature.get("migration_status"), equalTo("NO_MIGRATION_NEEDED"));
@@ -103,5 +108,4 @@ public class FeatureUpgradeIT extends AbstractRollingTestCase {
             });
             });
         }
         }
     }
     }
-
 }
 }

+ 20 - 14
qa/rolling-upgrade/src/test/java/org/elasticsearch/upgrades/FieldCapsIT.java → qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/FieldCapsIT.java

@@ -8,6 +8,8 @@
 
 
 package org.elasticsearch.upgrades;
 package org.elasticsearch.upgrades;
 
 
+import com.carrotsearch.randomizedtesting.annotations.Name;
+
 import org.apache.http.HttpHost;
 import org.apache.http.HttpHost;
 import org.elasticsearch.Version;
 import org.elasticsearch.Version;
 import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
 import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
@@ -36,15 +38,17 @@ import static org.hamcrest.Matchers.equalTo;
  * In 8.2 we also added the ability to filter fields by type and metadata, with some post-hoc filtering applied on
  * In 8.2 we also added the ability to filter fields by type and metadata, with some post-hoc filtering applied on
  * the co-ordinating node if older nodes were included in the system
  * the co-ordinating node if older nodes were included in the system
  */
  */
-public class FieldCapsIT extends AbstractRollingTestCase {
-    private static boolean indicesCreated = false;
+public class FieldCapsIT extends ParameterizedRollingUpgradeTestCase {
+
+    public FieldCapsIT(@Name("upgradedNodes") int upgradedNodes) {
+        super(upgradedNodes);
+    }
+
+    private static boolean oldIndicesCreated;
+    private static boolean newIndicesCreated;
 
 
     @Before
     @Before
     public void setupIndices() throws Exception {
     public void setupIndices() throws Exception {
-        if (indicesCreated) {
-            return;
-        }
-        indicesCreated = true;
         final String redMapping = """
         final String redMapping = """
              "properties": {
              "properties": {
                "red_field": { "type": "keyword" },
                "red_field": { "type": "keyword" },
@@ -63,7 +67,7 @@ public class FieldCapsIT extends AbstractRollingTestCase {
                "timestamp": {"type": "date"}
                "timestamp": {"type": "date"}
              }
              }
             """;
             """;
-        if (CLUSTER_TYPE == ClusterType.OLD) {
+        if (isOldCluster() && oldIndicesCreated == false) {
             createIndex("old_red_1", Settings.EMPTY, redMapping);
             createIndex("old_red_1", Settings.EMPTY, redMapping);
             createIndex("old_red_2", Settings.EMPTY, redMapping);
             createIndex("old_red_2", Settings.EMPTY, redMapping);
             createIndex("old_red_empty", Settings.EMPTY, redMapping);
             createIndex("old_red_empty", Settings.EMPTY, redMapping);
@@ -78,7 +82,8 @@ public class FieldCapsIT extends AbstractRollingTestCase {
                 );
                 );
                 assertOK(client().performRequest(indexRequest));
                 assertOK(client().performRequest(indexRequest));
             }
             }
-        } else if (CLUSTER_TYPE == ClusterType.MIXED && FIRST_MIXED_ROUND) {
+            oldIndicesCreated = true;
+        } else if (isFirstMixedCluster() && newIndicesCreated == false) {
             createIndex("new_red_1", Settings.EMPTY, redMapping);
             createIndex("new_red_1", Settings.EMPTY, redMapping);
             createIndex("new_red_2", Settings.EMPTY, redMapping);
             createIndex("new_red_2", Settings.EMPTY, redMapping);
             createIndex("new_red_empty", Settings.EMPTY, redMapping);
             createIndex("new_red_empty", Settings.EMPTY, redMapping);
@@ -93,6 +98,7 @@ public class FieldCapsIT extends AbstractRollingTestCase {
                 );
                 );
                 assertOK(client().performRequest(indexRequest));
                 assertOK(client().performRequest(indexRequest));
             }
             }
+            newIndicesCreated = true;
         }
         }
     }
     }
 
 
@@ -149,7 +155,7 @@ public class FieldCapsIT extends AbstractRollingTestCase {
     }
     }
 
 
     public void testNewIndicesOnly() throws Exception {
     public void testNewIndicesOnly() throws Exception {
-        assumeFalse("required mixed or upgraded cluster", CLUSTER_TYPE == ClusterType.OLD);
+        assumeFalse("required mixed or upgraded cluster", isOldCluster());
         {
         {
             FieldCapabilitiesResponse resp = fieldCaps(List.of("new_red_*"), List.of("*"), null, null, null);
             FieldCapabilitiesResponse resp = fieldCaps(List.of("new_red_*"), List.of("*"), null, null, null);
             assertThat(resp.getIndices(), equalTo(new String[] { "new_red_1", "new_red_2", "new_red_empty" }));
             assertThat(resp.getIndices(), equalTo(new String[] { "new_red_1", "new_red_2", "new_red_empty" }));
@@ -177,7 +183,7 @@ public class FieldCapsIT extends AbstractRollingTestCase {
     }
     }
 
 
     public void testNewIndicesOnlyWithIndexFilter() throws Exception {
     public void testNewIndicesOnlyWithIndexFilter() throws Exception {
-        assumeFalse("required mixed or upgraded cluster", CLUSTER_TYPE == ClusterType.OLD);
+        assumeFalse("required mixed or upgraded cluster", isOldCluster());
         final QueryBuilder indexFilter = QueryBuilders.rangeQuery("timestamp").gte("2020-01-01").lte("2020-12-12");
         final QueryBuilder indexFilter = QueryBuilders.rangeQuery("timestamp").gte("2020-01-01").lte("2020-12-12");
         {
         {
             FieldCapabilitiesResponse resp = fieldCaps(List.of("new_red_*"), List.of("*"), indexFilter, null, null);
             FieldCapabilitiesResponse resp = fieldCaps(List.of("new_red_*"), List.of("*"), indexFilter, null, null);
@@ -203,7 +209,7 @@ public class FieldCapsIT extends AbstractRollingTestCase {
     }
     }
 
 
     public void testAllIndices() throws Exception {
     public void testAllIndices() throws Exception {
-        assumeFalse("required mixed or upgraded cluster", CLUSTER_TYPE == ClusterType.OLD);
+        assumeFalse("required mixed or upgraded cluster", isOldCluster());
         FieldCapabilitiesResponse resp = fieldCaps(List.of("old_*", "new_*"), List.of("*"), null, null, null);
         FieldCapabilitiesResponse resp = fieldCaps(List.of("old_*", "new_*"), List.of("*"), null, null, null);
         assertThat(
         assertThat(
             resp.getIndices(),
             resp.getIndices(),
@@ -235,7 +241,7 @@ public class FieldCapsIT extends AbstractRollingTestCase {
     }
     }
 
 
     public void testAllIndicesWithIndexFilter() throws Exception {
     public void testAllIndicesWithIndexFilter() throws Exception {
-        assumeFalse("required mixed or upgraded cluster", CLUSTER_TYPE == ClusterType.OLD);
+        assumeFalse("required mixed or upgraded cluster", isOldCluster());
         final QueryBuilder indexFilter = QueryBuilders.rangeQuery("timestamp").gte("2020-01-01").lte("2020-12-12");
         final QueryBuilder indexFilter = QueryBuilders.rangeQuery("timestamp").gte("2020-01-01").lte("2020-12-12");
         FieldCapabilitiesResponse resp = fieldCaps(List.of("old_*", "new_*"), List.of("*"), indexFilter, null, null);
         FieldCapabilitiesResponse resp = fieldCaps(List.of("old_*", "new_*"), List.of("*"), indexFilter, null, null);
         assertThat(
         assertThat(
@@ -285,7 +291,7 @@ public class FieldCapsIT extends AbstractRollingTestCase {
     // because we are testing that the upgraded node will correctly apply filtering
     // because we are testing that the upgraded node will correctly apply filtering
     // to responses from older nodes that don't understand the filter parameters
     // to responses from older nodes that don't understand the filter parameters
     public void testAllIndicesWithFieldTypeFilter() throws Exception {
     public void testAllIndicesWithFieldTypeFilter() throws Exception {
-        assumeFalse("required mixed or upgraded cluster", CLUSTER_TYPE == ClusterType.OLD);
+        assumeFalse("required mixed or upgraded cluster", isOldCluster());
         RestClient restClient = getUpgradedNodeClient();
         RestClient restClient = getUpgradedNodeClient();
         FieldCapabilitiesResponse resp = fieldCaps(restClient, List.of("old_*", "new_*"), List.of("*"), null, "keyword", null);
         FieldCapabilitiesResponse resp = fieldCaps(restClient, List.of("old_*", "new_*"), List.of("*"), null, "keyword", null);
         assertThat(resp.getField("red_field").keySet(), contains("keyword"));
         assertThat(resp.getField("red_field").keySet(), contains("keyword"));
@@ -298,7 +304,7 @@ public class FieldCapsIT extends AbstractRollingTestCase {
     // because we are testing that the upgraded node will correctly apply filtering
     // because we are testing that the upgraded node will correctly apply filtering
     // to responses from older nodes that don't understand the filter parameters
     // to responses from older nodes that don't understand the filter parameters
     public void testAllIndicesWithExclusionFilter() throws Exception {
     public void testAllIndicesWithExclusionFilter() throws Exception {
-        assumeFalse("required mixed or upgraded cluster", CLUSTER_TYPE == ClusterType.OLD);
+        assumeFalse("required mixed or upgraded cluster", isOldCluster());
         RestClient client = getUpgradedNodeClient();
         RestClient client = getUpgradedNodeClient();
         {
         {
             FieldCapabilitiesResponse resp = fieldCaps(client, List.of("old_*", "new_*"), List.of("*"), null, null, null);
             FieldCapabilitiesResponse resp = fieldCaps(client, List.of("old_*", "new_*"), List.of("*"), null, null, null);

+ 166 - 197
qa/rolling-upgrade/src/test/java/org/elasticsearch/upgrades/IndexingIT.java → qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/IndexingIT.java

@@ -7,6 +7,8 @@
  */
  */
 package org.elasticsearch.upgrades;
 package org.elasticsearch.upgrades;
 
 
+import com.carrotsearch.randomizedtesting.annotations.Name;
+
 import org.apache.http.util.EntityUtils;
 import org.apache.http.util.EntityUtils;
 import org.elasticsearch.Version;
 import org.elasticsearch.Version;
 import org.elasticsearch.client.Request;
 import org.elasticsearch.client.Request;
@@ -15,7 +17,6 @@ import org.elasticsearch.client.ResponseException;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.common.time.DateUtils;
 import org.elasticsearch.common.time.DateUtils;
 import org.elasticsearch.common.xcontent.support.XContentMapValues;
 import org.elasticsearch.common.xcontent.support.XContentMapValues;
-import org.elasticsearch.core.Booleans;
 import org.elasticsearch.index.mapper.DateFieldMapper;
 import org.elasticsearch.index.mapper.DateFieldMapper;
 import org.elasticsearch.test.ListMatcher;
 import org.elasticsearch.test.ListMatcher;
 import org.elasticsearch.xcontent.XContentBuilder;
 import org.elasticsearch.xcontent.XContentBuilder;
@@ -40,39 +41,36 @@ import static org.hamcrest.Matchers.equalTo;
 
 
 /**
 /**
  * Basic test that indexed documents survive the rolling restart. See
  * Basic test that indexed documents survive the rolling restart. See
- * {@link RecoveryIT} for much more in depth testing of the mechanism
+ * {@code RecoveryIT} for much more in depth testing of the mechanism
  * by which they survive.
  * by which they survive.
  * <p>
  * <p>
  * This test is an almost exact copy of <code>IndexingIT</code> in the
  * This test is an almost exact copy of <code>IndexingIT</code> in the
  * xpack rolling restart tests. We should work on a way to remove this
  * xpack rolling restart tests. We should work on a way to remove this
  * duplication but for now we have no real way to share code.
  * duplication but for now we have no real way to share code.
  */
  */
-public class IndexingIT extends AbstractRollingTestCase {
+public class IndexingIT extends ParameterizedRollingUpgradeTestCase {
+
+    public IndexingIT(@Name("upgradedNodes") int upgradedNodes) {
+        super(upgradedNodes);
+    }
 
 
     public void testIndexing() throws IOException {
     public void testIndexing() throws IOException {
-        switch (CLUSTER_TYPE) {
-            case OLD:
-                break;
-            case MIXED:
-                Request waitForYellow = new Request("GET", "/_cluster/health");
-                waitForYellow.addParameter("wait_for_nodes", "3");
-                waitForYellow.addParameter("wait_for_status", "yellow");
-                client().performRequest(waitForYellow);
-                break;
-            case UPGRADED:
-                Request waitForGreen = new Request("GET", "/_cluster/health/test_index,index_with_replicas,empty_index");
-                waitForGreen.addParameter("wait_for_nodes", "3");
-                waitForGreen.addParameter("wait_for_status", "green");
-                // wait for long enough that we give delayed unassigned shards to stop being delayed
-                waitForGreen.addParameter("timeout", "70s");
-                waitForGreen.addParameter("level", "shards");
-                client().performRequest(waitForGreen);
-                break;
-            default:
-                throw new UnsupportedOperationException("Unknown cluster type [" + CLUSTER_TYPE + "]");
+        if (isMixedCluster()) {
+            Request waitForYellow = new Request("GET", "/_cluster/health");
+            waitForYellow.addParameter("wait_for_nodes", "3");
+            waitForYellow.addParameter("wait_for_status", "yellow");
+            client().performRequest(waitForYellow);
+        } else if (isUpgradedCluster()) {
+            Request waitForGreen = new Request("GET", "/_cluster/health/test_index,index_with_replicas,empty_index");
+            waitForGreen.addParameter("wait_for_nodes", "3");
+            waitForGreen.addParameter("wait_for_status", "green");
+            // wait for long enough that we give delayed unassigned shards to stop being delayed
+            waitForGreen.addParameter("timeout", "70s");
+            waitForGreen.addParameter("level", "shards");
+            client().performRequest(waitForGreen);
         }
         }
 
 
-        if (CLUSTER_TYPE == ClusterType.OLD) {
+        if (isOldCluster()) {
             Request createTestIndex = new Request("PUT", "/test_index");
             Request createTestIndex = new Request("PUT", "/test_index");
             createTestIndex.setJsonEntity("{\"settings\": {\"index.number_of_replicas\": 0}}");
             createTestIndex.setJsonEntity("{\"settings\": {\"index.number_of_replicas\": 0}}");
             useIgnoreMultipleMatchingTemplatesWarningsHandler(createTestIndex);
             useIgnoreMultipleMatchingTemplatesWarningsHandler(createTestIndex);
@@ -95,30 +93,20 @@ public class IndexingIT extends AbstractRollingTestCase {
         }
         }
 
 
         int expectedCount;
         int expectedCount;
-        switch (CLUSTER_TYPE) {
-            case OLD:
-                expectedCount = 5;
-                break;
-            case MIXED:
-                if (Booleans.parseBoolean(System.getProperty("tests.first_round"))) {
-                    expectedCount = 5;
-                } else {
-                    expectedCount = 10;
-                }
-                break;
-            case UPGRADED:
-                expectedCount = 15;
-                break;
-            default:
-                throw new UnsupportedOperationException("Unknown cluster type [" + CLUSTER_TYPE + "]");
+        if (isOldCluster() || isFirstMixedCluster()) {
+            expectedCount = 5;
+        } else if (isMixedCluster()) {
+            expectedCount = 10;
+        } else {
+            expectedCount = 15;
         }
         }
 
 
         assertCount("test_index", expectedCount);
         assertCount("test_index", expectedCount);
         assertCount("index_with_replicas", 5);
         assertCount("index_with_replicas", 5);
         assertCount("empty_index", 0);
         assertCount("empty_index", 0);
 
 
-        if (CLUSTER_TYPE != ClusterType.OLD) {
-            bulk("test_index", "_" + CLUSTER_TYPE, 5);
+        if (isOldCluster() == false) {
+            bulk("test_index", "_" + (isMixedCluster() ? "MIXED" : "UPGRADED"), 5);
             Request toBeDeleted = new Request("PUT", "/test_index/_doc/to_be_deleted");
             Request toBeDeleted = new Request("PUT", "/test_index/_doc/to_be_deleted");
             toBeDeleted.addParameter("refresh", "true");
             toBeDeleted.addParameter("refresh", "true");
             toBeDeleted.setJsonEntity("{\"f1\": \"delete-me\"}");
             toBeDeleted.setJsonEntity("{\"f1\": \"delete-me\"}");
@@ -143,82 +131,76 @@ public class IndexingIT extends AbstractRollingTestCase {
         bulk.addParameter("refresh", "true");
         bulk.addParameter("refresh", "true");
         bulk.setJsonEntity(b);
         bulk.setJsonEntity(b);
 
 
-        switch (CLUSTER_TYPE) {
-            case OLD -> {
-                Request createTestIndex = new Request("PUT", "/" + indexName);
-                createTestIndex.setJsonEntity("{\"settings\": {\"index.number_of_replicas\": 0}}");
-                client().performRequest(createTestIndex);
-            }
-            case MIXED -> {
-                Request waitForGreen = new Request("GET", "/_cluster/health");
-                waitForGreen.addParameter("wait_for_nodes", "3");
-                client().performRequest(waitForGreen);
-                Version minNodeVersion = minNodeVersion();
-                if (minNodeVersion.before(Version.V_7_5_0)) {
-                    ResponseException e = expectThrows(ResponseException.class, () -> client().performRequest(bulk));
-                    assertEquals(400, e.getResponse().getStatusLine().getStatusCode());
-                    assertThat(
-                        e.getMessage(),
-                        // if request goes to 7.5+ node
-                        either(containsString("optype create not supported for indexing requests without explicit id until"))
-                            // if request goes to < 7.5 node
-                            .or(containsString("an id must be provided if version type or value are set"))
-                    );
-                } else {
-                    client().performRequest(bulk);
-                }
+        if (isOldCluster()) {
+            Request createTestIndex = new Request("PUT", "/" + indexName);
+            createTestIndex.setJsonEntity("{\"settings\": {\"index.number_of_replicas\": 0}}");
+            client().performRequest(createTestIndex);
+        } else if (isMixedCluster()) {
+            Request waitForGreen = new Request("GET", "/_cluster/health");
+            waitForGreen.addParameter("wait_for_nodes", "3");
+            client().performRequest(waitForGreen);
+            Version minNodeVersion = minNodeVersion();
+            if (minNodeVersion.before(Version.V_7_5_0)) {
+                ResponseException e = expectThrows(ResponseException.class, () -> client().performRequest(bulk));
+                assertEquals(400, e.getResponse().getStatusLine().getStatusCode());
+                assertThat(
+                    e.getMessage(),
+                    // if request goes to 7.5+ node
+                    either(containsString("optype create not supported for indexing requests without explicit id until"))
+                        // if request goes to < 7.5 node
+                        .or(containsString("an id must be provided if version type or value are set"))
+                );
+            } else {
+                client().performRequest(bulk);
             }
             }
-            case UPGRADED -> client().performRequest(bulk);
-            default -> throw new UnsupportedOperationException("Unknown cluster type [" + CLUSTER_TYPE + "]");
+        } else if (isUpgradedCluster()) {
+            client().performRequest(bulk);
         }
         }
     }
     }
 
 
     public void testDateNanosFormatUpgrade() throws IOException {
     public void testDateNanosFormatUpgrade() throws IOException {
         final String indexName = "test_date_nanos";
         final String indexName = "test_date_nanos";
-        switch (CLUSTER_TYPE) {
-            case OLD -> {
-                Request createIndex = new Request("PUT", "/" + indexName);
-                XContentBuilder mappings = XContentBuilder.builder(XContentType.JSON.xContent())
-                    .startObject()
-                    .startObject("mappings")
-                    .startObject("properties")
-                    .startObject("date")
-                    .field("type", "date")
-                    .endObject()
-                    .startObject("date_nanos")
-                    .field("type", "date_nanos")
-                    .endObject()
-                    .endObject()
-                    .endObject()
-                    .endObject();
-                createIndex.setJsonEntity(Strings.toString(mappings));
-                client().performRequest(createIndex);
-                Request index = new Request("POST", "/" + indexName + "/_doc/");
-                XContentBuilder doc = XContentBuilder.builder(XContentType.JSON.xContent())
-                    .startObject()
-                    .field("date", "2015-01-01T12:10:30.123456789Z")
-                    .field("date_nanos", "2015-01-01T12:10:30.123456789Z")
-                    .endObject();
-                index.addParameter("refresh", "true");
-                index.setJsonEntity(Strings.toString(doc));
-                client().performRequest(index);
-            }
-            case UPGRADED -> {
-                Request search = new Request("POST", "/" + indexName + "/_search");
-                XContentBuilder query = XContentBuilder.builder(XContentType.JSON.xContent())
-                    .startObject()
-                    .array("fields", new String[] { "date", "date_nanos" })
-                    .endObject();
-                search.setJsonEntity(Strings.toString(query));
-                Map<String, Object> response = entityAsMap(client().performRequest(search));
-                Map<?, ?> bestHit = (Map<?, ?>) ((List<?>) (XContentMapValues.extractValue("hits.hits", response))).get(0);
-                List<?> date = (List<?>) XContentMapValues.extractValue("fields.date", bestHit);
-                assertThat(date.size(), equalTo(1));
-                assertThat(date.get(0), equalTo("2015-01-01T12:10:30.123Z"));
-                List<?> dateNanos = (List<?>) XContentMapValues.extractValue("fields.date_nanos", bestHit);
-                assertThat(dateNanos.size(), equalTo(1));
-                assertThat(dateNanos.get(0), equalTo("2015-01-01T12:10:30.123456789Z"));
-            }
+        if (isOldCluster()) {
+            Request createIndex = new Request("PUT", "/" + indexName);
+            XContentBuilder mappings = XContentBuilder.builder(XContentType.JSON.xContent())
+                .startObject()
+                .startObject("mappings")
+                .startObject("properties")
+                .startObject("date")
+                .field("type", "date")
+                .endObject()
+                .startObject("date_nanos")
+                .field("type", "date_nanos")
+                .endObject()
+                .endObject()
+                .endObject()
+                .endObject();
+            createIndex.setJsonEntity(Strings.toString(mappings));
+            client().performRequest(createIndex);
+            Request index = new Request("POST", "/" + indexName + "/_doc/");
+            XContentBuilder doc = XContentBuilder.builder(XContentType.JSON.xContent())
+                .startObject()
+                .field("date", "2015-01-01T12:10:30.123456789Z")
+                .field("date_nanos", "2015-01-01T12:10:30.123456789Z")
+                .endObject();
+            index.addParameter("refresh", "true");
+            index.setJsonEntity(Strings.toString(doc));
+            client().performRequest(index);
+        } else if (isUpgradedCluster()) {
+            Request search = new Request("POST", "/" + indexName + "/_search");
+            XContentBuilder query = XContentBuilder.builder(XContentType.JSON.xContent())
+                .startObject()
+                .array("fields", new String[] { "date", "date_nanos" })
+                .endObject();
+            search.setJsonEntity(Strings.toString(query));
+            Map<String, Object> response = entityAsMap(client().performRequest(search));
+            Map<?, ?> bestHit = (Map<?, ?>) ((List<?>) (XContentMapValues.extractValue("hits.hits", response))).get(0);
+            List<?> date = (List<?>) XContentMapValues.extractValue("fields.date", bestHit);
+            assertThat(date.size(), equalTo(1));
+            assertThat(date.get(0), equalTo("2015-01-01T12:10:30.123Z"));
+            List<?> dateNanos = (List<?>) XContentMapValues.extractValue("fields.date_nanos", bestHit);
+            assertThat(dateNanos.size(), equalTo(1));
+            assertThat(dateNanos.get(0), equalTo("2015-01-01T12:10:30.123456789Z"));
         }
         }
     }
     }
 
 
@@ -247,51 +229,45 @@ public class IndexingIT extends AbstractRollingTestCase {
     }
     }
 
 
     public void testTsdb() throws IOException {
     public void testTsdb() throws IOException {
-        assumeTrue("indexing time series indices changed in 8.2.0", UPGRADE_FROM_VERSION.onOrAfter(Version.V_8_2_0));
+        assumeTrue("indexing time series indices changed in 8.2.0", getOldClusterVersion().onOrAfter(Version.V_8_2_0));
 
 
         StringBuilder bulk = new StringBuilder();
         StringBuilder bulk = new StringBuilder();
-        switch (CLUSTER_TYPE) {
-            case OLD -> {
-                createTsdbIndex();
-                tsdbBulk(bulk, TSDB_DIMS.get(0), TSDB_TIMES[0], TSDB_TIMES[1], 0.1);
-                tsdbBulk(bulk, TSDB_DIMS.get(1), TSDB_TIMES[0], TSDB_TIMES[1], -0.1);
-                bulk("tsdb", bulk.toString());
-                assertTsdbAgg(closeTo(215.95, 0.005), closeTo(-215.95, 0.005));
-                return;
-            }
-            case MIXED -> {
-                if (FIRST_MIXED_ROUND) {
-                    tsdbBulk(bulk, TSDB_DIMS.get(0), TSDB_TIMES[1], TSDB_TIMES[2], 0.1);
-                    tsdbBulk(bulk, TSDB_DIMS.get(1), TSDB_TIMES[1], TSDB_TIMES[2], -0.1);
-                    tsdbBulk(bulk, TSDB_DIMS.get(2), TSDB_TIMES[0], TSDB_TIMES[2], 1.1);
-                    bulk("tsdb", bulk.toString());
-                    assertTsdbAgg(closeTo(217.45, 0.005), closeTo(-217.45, 0.005), closeTo(2391.95, 0.005));
-                    return;
-                }
-                tsdbBulk(bulk, TSDB_DIMS.get(0), TSDB_TIMES[2], TSDB_TIMES[3], 0.1);
-                tsdbBulk(bulk, TSDB_DIMS.get(1), TSDB_TIMES[2], TSDB_TIMES[3], -0.1);
-                tsdbBulk(bulk, TSDB_DIMS.get(2), TSDB_TIMES[2], TSDB_TIMES[3], 1.1);
-                tsdbBulk(bulk, TSDB_DIMS.get(3), TSDB_TIMES[0], TSDB_TIMES[3], 10);
-                bulk("tsdb", bulk.toString());
-                assertTsdbAgg(closeTo(218.95, 0.005), closeTo(-218.95, 0.005), closeTo(2408.45, 0.005), closeTo(21895, 0.5));
-                return;
-            }
-            case UPGRADED -> {
-                tsdbBulk(bulk, TSDB_DIMS.get(0), TSDB_TIMES[3], TSDB_TIMES[4], 0.1);
-                tsdbBulk(bulk, TSDB_DIMS.get(1), TSDB_TIMES[3], TSDB_TIMES[4], -0.1);
-                tsdbBulk(bulk, TSDB_DIMS.get(2), TSDB_TIMES[3], TSDB_TIMES[4], 1.1);
-                tsdbBulk(bulk, TSDB_DIMS.get(3), TSDB_TIMES[3], TSDB_TIMES[4], 10);
-                tsdbBulk(bulk, TSDB_DIMS.get(4), TSDB_TIMES[0], TSDB_TIMES[4], -5);
-                bulk("tsdb", bulk.toString());
-                assertTsdbAgg(
-                    closeTo(220.45, 0.005),
-                    closeTo(-220.45, 0.005),
-                    closeTo(2424.95, 0.005),
-                    closeTo(22045, 0.5),
-                    closeTo(-11022.5, 0.5)
-                );
-                return;
-            }
+        if (isOldCluster()) {
+            createTsdbIndex();
+            tsdbBulk(bulk, TSDB_DIMS.get(0), TSDB_TIMES[0], TSDB_TIMES[1], 0.1);
+            tsdbBulk(bulk, TSDB_DIMS.get(1), TSDB_TIMES[0], TSDB_TIMES[1], -0.1);
+            bulk("tsdb", bulk.toString());
+            assertTsdbAgg(closeTo(215.95, 0.005), closeTo(-215.95, 0.005));
+            return;
+        } else if (isFirstMixedCluster()) {
+            tsdbBulk(bulk, TSDB_DIMS.get(0), TSDB_TIMES[1], TSDB_TIMES[2], 0.1);
+            tsdbBulk(bulk, TSDB_DIMS.get(1), TSDB_TIMES[1], TSDB_TIMES[2], -0.1);
+            tsdbBulk(bulk, TSDB_DIMS.get(2), TSDB_TIMES[0], TSDB_TIMES[2], 1.1);
+            bulk("tsdb", bulk.toString());
+            assertTsdbAgg(closeTo(217.45, 0.005), closeTo(-217.45, 0.005), closeTo(2391.95, 0.005));
+
+        } else if (isMixedCluster()) {
+            tsdbBulk(bulk, TSDB_DIMS.get(0), TSDB_TIMES[2], TSDB_TIMES[3], 0.1);
+            tsdbBulk(bulk, TSDB_DIMS.get(1), TSDB_TIMES[2], TSDB_TIMES[3], -0.1);
+            tsdbBulk(bulk, TSDB_DIMS.get(2), TSDB_TIMES[2], TSDB_TIMES[3], 1.1);
+            tsdbBulk(bulk, TSDB_DIMS.get(3), TSDB_TIMES[0], TSDB_TIMES[3], 10);
+            bulk("tsdb", bulk.toString());
+            assertTsdbAgg(closeTo(218.95, 0.005), closeTo(-218.95, 0.005), closeTo(2408.45, 0.005), closeTo(21895, 0.5));
+            return;
+        } else {
+            tsdbBulk(bulk, TSDB_DIMS.get(0), TSDB_TIMES[3], TSDB_TIMES[4], 0.1);
+            tsdbBulk(bulk, TSDB_DIMS.get(1), TSDB_TIMES[3], TSDB_TIMES[4], -0.1);
+            tsdbBulk(bulk, TSDB_DIMS.get(2), TSDB_TIMES[3], TSDB_TIMES[4], 1.1);
+            tsdbBulk(bulk, TSDB_DIMS.get(3), TSDB_TIMES[3], TSDB_TIMES[4], 10);
+            tsdbBulk(bulk, TSDB_DIMS.get(4), TSDB_TIMES[0], TSDB_TIMES[4], -5);
+            bulk("tsdb", bulk.toString());
+            assertTsdbAgg(
+                closeTo(220.45, 0.005),
+                closeTo(-220.45, 0.005),
+                closeTo(2424.95, 0.005),
+                closeTo(22045, 0.5),
+                closeTo(-11022.5, 0.5)
+            );
         }
         }
     }
     }
 
 
@@ -361,67 +337,60 @@ public class IndexingIT extends AbstractRollingTestCase {
     }
     }
 
 
     public void testSyntheticSource() throws IOException {
     public void testSyntheticSource() throws IOException {
-        assumeTrue("added in 8.4.0", UPGRADE_FROM_VERSION.onOrAfter(Version.V_8_4_0));
-
-        switch (CLUSTER_TYPE) {
-            case OLD -> {
-                Request createIndex = new Request("PUT", "/synthetic");
-                XContentBuilder indexSpec = XContentBuilder.builder(XContentType.JSON.xContent()).startObject();
-                indexSpec.startObject("mappings");
-                {
-                    indexSpec.startObject("_source").field("mode", "synthetic").endObject();
-                    indexSpec.startObject("properties").startObject("kwd").field("type", "keyword").endObject().endObject();
-                }
-                indexSpec.endObject();
-                createIndex.setJsonEntity(Strings.toString(indexSpec.endObject()));
-                client().performRequest(createIndex);
-                bulk("synthetic", """
-                    {"index": {"_index": "synthetic", "_id": "old"}}
-                    {"kwd": "old", "int": -12}
-                    """);
-                break;
-            }
-            case MIXED -> {
-                if (FIRST_MIXED_ROUND) {
-                    bulk("synthetic", """
-                        {"index": {"_index": "synthetic", "_id": "mixed_1"}}
-                        {"kwd": "mixed_1", "int": 22}
-                        """);
-                } else {
-                    bulk("synthetic", """
-                        {"index": {"_index": "synthetic", "_id": "mixed_2"}}
-                        {"kwd": "mixed_2", "int": 33}
-                        """);
-                }
-                break;
-            }
-            case UPGRADED -> {
-                bulk("synthetic", """
-                    {"index": {"_index": "synthetic", "_id": "new"}}
-                    {"kwd": "new", "int": 21341325}
-                    """);
+        assumeTrue("added in 8.4.0", getOldClusterVersion().onOrAfter(Version.V_8_4_0));
+
+        if (isOldCluster()) {
+            Request createIndex = new Request("PUT", "/synthetic");
+            XContentBuilder indexSpec = XContentBuilder.builder(XContentType.JSON.xContent()).startObject();
+            indexSpec.startObject("mappings");
+            {
+                indexSpec.startObject("_source").field("mode", "synthetic").endObject();
+                indexSpec.startObject("properties").startObject("kwd").field("type", "keyword").endObject().endObject();
             }
             }
+            indexSpec.endObject();
+            createIndex.setJsonEntity(Strings.toString(indexSpec.endObject()));
+            client().performRequest(createIndex);
+            bulk("synthetic", """
+                {"index": {"_index": "synthetic", "_id": "old"}}
+                {"kwd": "old", "int": -12}
+                """);
+        } else if (isFirstMixedCluster()) {
+            bulk("synthetic", """
+                {"index": {"_index": "synthetic", "_id": "mixed_1"}}
+                {"kwd": "mixed_1", "int": 22}
+                """);
+        } else if (isMixedCluster()) {
+            bulk("synthetic", """
+                {"index": {"_index": "synthetic", "_id": "mixed_2"}}
+                {"kwd": "mixed_2", "int": 33}
+                """);
+
+        } else {
+            bulk("synthetic", """
+                {"index": {"_index": "synthetic", "_id": "new"}}
+                {"kwd": "new", "int": 21341325}
+                """);
         }
         }
 
 
         assertMap(
         assertMap(
             entityAsMap(client().performRequest(new Request("GET", "/synthetic/_doc/old"))),
             entityAsMap(client().performRequest(new Request("GET", "/synthetic/_doc/old"))),
             matchesMap().extraOk().entry("_source", matchesMap().entry("kwd", "old").entry("int", -12))
             matchesMap().extraOk().entry("_source", matchesMap().entry("kwd", "old").entry("int", -12))
         );
         );
-        if (CLUSTER_TYPE == ClusterType.OLD) {
+        if (isOldCluster()) {
             return;
             return;
         }
         }
         assertMap(
         assertMap(
             entityAsMap(client().performRequest(new Request("GET", "/synthetic/_doc/mixed_1"))),
             entityAsMap(client().performRequest(new Request("GET", "/synthetic/_doc/mixed_1"))),
             matchesMap().extraOk().entry("_source", matchesMap().entry("kwd", "mixed_1").entry("int", 22))
             matchesMap().extraOk().entry("_source", matchesMap().entry("kwd", "mixed_1").entry("int", 22))
         );
         );
-        if (CLUSTER_TYPE == ClusterType.MIXED && FIRST_MIXED_ROUND) {
+        if (isFirstMixedCluster()) {
             return;
             return;
         }
         }
         assertMap(
         assertMap(
             entityAsMap(client().performRequest(new Request("GET", "/synthetic/_doc/mixed_2"))),
             entityAsMap(client().performRequest(new Request("GET", "/synthetic/_doc/mixed_2"))),
             matchesMap().extraOk().entry("_source", matchesMap().entry("kwd", "mixed_2").entry("int", 33))
             matchesMap().extraOk().entry("_source", matchesMap().entry("kwd", "mixed_2").entry("int", 33))
         );
         );
-        if (CLUSTER_TYPE == ClusterType.MIXED) {
+        if (isMixedCluster()) {
             return;
             return;
         }
         }
         assertMap(
         assertMap(

+ 226 - 0
qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/ParameterizedRollingUpgradeTestCase.java

@@ -0,0 +1,226 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+package org.elasticsearch.upgrades;
+
+import com.carrotsearch.randomizedtesting.annotations.Name;
+import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
+
+import org.elasticsearch.client.Request;
+import org.elasticsearch.client.Response;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.core.SuppressForbidden;
+import org.elasticsearch.index.IndexVersion;
+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.rest.ESRestTestCase;
+import org.elasticsearch.test.rest.ObjectPath;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestRule;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Supplier;
+import java.util.stream.IntStream;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.notNullValue;
+
+public abstract class ParameterizedRollingUpgradeTestCase extends ESRestTestCase {
+    private static final Version OLD_CLUSTER_VERSION = Version.fromString(System.getProperty("tests.old_cluster_version"));
+
+    private static final TemporaryFolder repoDirectory = new TemporaryFolder();
+
+    private static final int NODE_NUM = 3;
+
+    private static final ElasticsearchCluster cluster = ElasticsearchCluster.local()
+        .distribution(DistributionType.DEFAULT)
+        .version(getOldClusterTestVersion())
+        .nodes(NODE_NUM)
+        .setting("path.repo", new Supplier<>() {
+            @Override
+            @SuppressForbidden(reason = "TemporaryFolder only has io.File methods, not nio.File")
+            public String get() {
+                return repoDirectory.getRoot().getPath();
+            }
+        })
+        .setting("xpack.security.enabled", "false")
+        .feature(FeatureFlag.TIME_SERIES_MODE)
+        .build();
+
+    @ClassRule
+    public static TestRule ruleChain = RuleChain.outerRule(repoDirectory).around(cluster);
+
+    @ParametersFactory(shuffle = false)
+    public static Iterable<Object[]> parameters() {
+        return IntStream.rangeClosed(0, NODE_NUM).boxed().map(n -> new Object[] { n }).toList();
+    }
+
+    private static final Set<Integer> upgradedNodes = new HashSet<>();
+    private static boolean upgradeFailed = false;
+    private static IndexVersion oldIndexVersion;
+
+    private final int requestedUpgradedNodes;
+
+    protected ParameterizedRollingUpgradeTestCase(@Name("upgradedNodes") int upgradedNodes) {
+        this.requestedUpgradedNodes = upgradedNodes;
+    }
+
+    @Before
+    public void extractOldIndexVersion() throws Exception {
+        if (oldIndexVersion == null && upgradedNodes.isEmpty()) {
+            IndexVersion indexVersion = null;   // these should all be the same version
+
+            Request request = new Request("GET", "_nodes");
+            request.addParameter("filter_path", "nodes.*.index_version,nodes.*.name");
+            Response response = client().performRequest(request);
+            ObjectPath objectPath = ObjectPath.createFromResponse(response);
+            Map<String, Object> nodeMap = objectPath.evaluate("nodes");
+            for (String id : nodeMap.keySet()) {
+                Number ix = objectPath.evaluate("nodes." + id + ".index_version");
+                IndexVersion version;
+                if (ix != null) {
+                    version = IndexVersion.fromId(ix.intValue());
+                } else {
+                    // it doesn't have index version (pre 8.11) - just infer it from the release version
+                    version = IndexVersion.fromId(getOldClusterVersion().id);
+                }
+
+                if (indexVersion == null) {
+                    indexVersion = version;
+                } else {
+                    String name = objectPath.evaluate("nodes." + id + ".name");
+                    assertThat("Node " + name + " has a different index version to other nodes", version, equalTo(indexVersion));
+                }
+            }
+
+            assertThat("Index version could not be read", indexVersion, notNullValue());
+            oldIndexVersion = indexVersion;
+        }
+    }
+
+    @Before
+    public void upgradeNode() throws Exception {
+        // Skip remaining tests if upgrade failed
+        assumeFalse("Cluster upgrade failed", upgradeFailed);
+
+        if (upgradedNodes.size() < requestedUpgradedNodes) {
+            closeClients();
+            // we might be running a specific upgrade test by itself - check previous nodes too
+            for (int n = 0; n < requestedUpgradedNodes; n++) {
+                if (upgradedNodes.add(n)) {
+                    try {
+                        logger.info("Upgrading node {} to version {}", n, Version.CURRENT);
+                        cluster.upgradeNodeToVersion(n, Version.CURRENT);
+                    } catch (Exception e) {
+                        upgradeFailed = true;
+                        throw e;
+                    }
+                }
+            }
+            initClient();
+        }
+    }
+
+    @AfterClass
+    public static void resetNodes() {
+        oldIndexVersion = null;
+        upgradedNodes.clear();
+        upgradeFailed = false;
+    }
+
+    protected static org.elasticsearch.Version getOldClusterVersion() {
+        return org.elasticsearch.Version.fromString(OLD_CLUSTER_VERSION.toString());
+    }
+
+    protected static IndexVersion getOldClusterIndexVersion() {
+        assert oldIndexVersion != null;
+        return oldIndexVersion;
+    }
+
+    protected static Version getOldClusterTestVersion() {
+        return Version.fromString(OLD_CLUSTER_VERSION.toString());
+    }
+
+    protected static boolean isOldCluster() {
+        return upgradedNodes.isEmpty();
+    }
+
+    protected static boolean isFirstMixedCluster() {
+        return upgradedNodes.size() == 1;
+    }
+
+    protected static boolean isMixedCluster() {
+        return upgradedNodes.isEmpty() == false && upgradedNodes.size() < NODE_NUM;
+    }
+
+    protected static boolean isUpgradedCluster() {
+        return upgradedNodes.size() == NODE_NUM;
+    }
+
+    @Override
+    protected String getTestRestCluster() {
+        return cluster.getHttpAddresses();
+    }
+
+    @Override
+    protected final boolean resetFeatureStates() {
+        return false;
+    }
+
+    @Override
+    protected final boolean preserveIndicesUponCompletion() {
+        return true;
+    }
+
+    @Override
+    protected final boolean preserveDataStreamsUponCompletion() {
+        return true;
+    }
+
+    @Override
+    protected final boolean preserveReposUponCompletion() {
+        return true;
+    }
+
+    @Override
+    protected boolean preserveTemplatesUponCompletion() {
+        return true;
+    }
+
+    @Override
+    protected boolean preserveClusterUponCompletion() {
+        return true;
+    }
+
+    @Override
+    protected final Settings restClientSettings() {
+        return Settings.builder()
+            .put(super.restClientSettings())
+            // increase the timeout here to 90 seconds to handle long waits for a green
+            // cluster health. the waits for green need to be longer than a minute to
+            // account for delayed shards
+            .put(ESRestTestCase.CLIENT_SOCKET_TIMEOUT, "90s")
+            .build();
+    }
+
+    @Override
+    protected final String getEnsureGreenTimeout() {
+        // increase the timeout here to 70 seconds to handle long waits for a green
+        // cluster health. the waits for green need to be longer than a minute to
+        // account for delayed shards
+        return "70s";
+    }
+}

+ 82 - 78
qa/rolling-upgrade/src/test/java/org/elasticsearch/upgrades/SnapshotBasedRecoveryIT.java → qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/SnapshotBasedRecoveryIT.java

@@ -8,6 +8,8 @@
 
 
 package org.elasticsearch.upgrades;
 package org.elasticsearch.upgrades;
 
 
+import com.carrotsearch.randomizedtesting.annotations.Name;
+
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.util.EntityUtils;
 import org.apache.http.util.EntityUtils;
@@ -40,100 +42,102 @@ import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.lessThan;
 import static org.hamcrest.Matchers.lessThan;
 import static org.hamcrest.Matchers.notNullValue;
 import static org.hamcrest.Matchers.notNullValue;
 
 
-public class SnapshotBasedRecoveryIT extends AbstractRollingTestCase {
+public class SnapshotBasedRecoveryIT extends ParameterizedRollingUpgradeTestCase {
+
+    public SnapshotBasedRecoveryIT(@Name("upgradedNodes") int upgradedNodes) {
+        super(upgradedNodes);
+    }
 
 
     public void testSnapshotBasedRecovery() throws Exception {
     public void testSnapshotBasedRecovery() throws Exception {
 
 
         assumeFalse(
         assumeFalse(
             "Cancel shard allocation command is broken for initial desired balance versions and might allocate shard "
             "Cancel shard allocation command is broken for initial desired balance versions and might allocate shard "
                 + "on the node where it is not supposed to be. Fixed by https://github.com/elastic/elasticsearch/pull/93635",
                 + "on the node where it is not supposed to be. Fixed by https://github.com/elastic/elasticsearch/pull/93635",
-            UPGRADE_FROM_VERSION == Version.V_8_6_0 || UPGRADE_FROM_VERSION == Version.V_8_6_1 || UPGRADE_FROM_VERSION == Version.V_8_7_0
+            getOldClusterVersion() == Version.V_8_6_0
+                || getOldClusterVersion() == Version.V_8_6_1
+                || getOldClusterVersion() == Version.V_8_7_0
         );
         );
 
 
         final String indexName = "snapshot_based_recovery";
         final String indexName = "snapshot_based_recovery";
         final String repositoryName = "snapshot_based_recovery_repo";
         final String repositoryName = "snapshot_based_recovery_repo";
         final int numDocs = 200;
         final int numDocs = 200;
-        switch (CLUSTER_TYPE) {
-            case OLD -> {
-                Settings.Builder settings = Settings.builder()
-                    .put(IndexMetadata.INDEX_NUMBER_OF_SHARDS_SETTING.getKey(), 1)
-                    .put(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), 0)
-                    .put(INDEX_DELAYED_NODE_LEFT_TIMEOUT_SETTING.getKey(), "100ms")
-                    .put(SETTING_ALLOCATION_MAX_RETRY.getKey(), "0"); // fail faster
-                createIndex(indexName, settings.build());
-                ensureGreen(indexName);
-                indexDocs(indexName, numDocs);
-                flush(indexName, true);
-                registerRepository(
-                    repositoryName,
-                    "fs",
-                    true,
-                    Settings.builder()
-                        .put("location", "./snapshot_based_recovery")
-                        .put(BlobStoreRepository.USE_FOR_PEER_RECOVERY_SETTING.getKey(), true)
-                        .build()
-                );
-                createSnapshot(repositoryName, "snap", true);
-                updateIndexSettings(indexName, Settings.builder().put(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), 1));
-                ensureGreen(indexName);
-            }
-            case MIXED, UPGRADED -> {
-                if (FIRST_MIXED_ROUND) {
-                    List<String> upgradedNodeIds = getUpgradedNodeIds();
-                    // It's possible that the test simply does a rolling-restart, i.e. it "upgrades" to
-                    // the same version. In that case we proceed without excluding any node
-                    if (upgradedNodeIds.isEmpty() == false) {
-                        assertThat(upgradedNodeIds.size(), is(equalTo(1)));
-                        String upgradedNodeId = upgradedNodeIds.get(0);
-                        logger.info("--> excluding [{}] from node [{}]", indexName, upgradedNodeId);
-                        updateIndexSettings(indexName, Settings.builder().put("index.routing.allocation.exclude._id", upgradedNodeId));
-                        ensureGreen(indexName);
-                        logger.info("--> finished excluding [{}] from node [{}]", indexName, upgradedNodeId);
-                    } else {
-                        logger.info("--> no upgrading nodes, not adding any exclusions for [{}]", indexName);
-                    }
+        if (isOldCluster()) {
+            Settings.Builder settings = Settings.builder()
+                .put(IndexMetadata.INDEX_NUMBER_OF_SHARDS_SETTING.getKey(), 1)
+                .put(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), 0)
+                .put(INDEX_DELAYED_NODE_LEFT_TIMEOUT_SETTING.getKey(), "100ms")
+                .put(SETTING_ALLOCATION_MAX_RETRY.getKey(), "0"); // fail faster
+            createIndex(indexName, settings.build());
+            ensureGreen(indexName);
+            indexDocs(indexName, numDocs);
+            flush(indexName, true);
+            registerRepository(
+                repositoryName,
+                "fs",
+                true,
+                Settings.builder()
+                    .put("location", "./snapshot_based_recovery")
+                    .put(BlobStoreRepository.USE_FOR_PEER_RECOVERY_SETTING.getKey(), true)
+                    .build()
+            );
+            createSnapshot(repositoryName, "snap", true);
+            updateIndexSettings(indexName, Settings.builder().put(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), 1));
+            ensureGreen(indexName);
+        } else {
+            if (isFirstMixedCluster()) {
+                List<String> upgradedNodeIds = getUpgradedNodeIds();
+                // It's possible that the test simply does a rolling-restart, i.e. it "upgrades" to
+                // the same version. In that case we proceed without excluding any node
+                if (upgradedNodeIds.isEmpty() == false) {
+                    assertThat(upgradedNodeIds.size(), is(equalTo(1)));
+                    String upgradedNodeId = upgradedNodeIds.get(0);
+                    logger.info("--> excluding [{}] from node [{}]", indexName, upgradedNodeId);
+                    updateIndexSettings(indexName, Settings.builder().put("index.routing.allocation.exclude._id", upgradedNodeId));
+                    ensureGreen(indexName);
+                    logger.info("--> finished excluding [{}] from node [{}]", indexName, upgradedNodeId);
+                } else {
+                    logger.info("--> no upgrading nodes, not adding any exclusions for [{}]", indexName);
+                }
 
 
-                    String primaryNodeId = getPrimaryNodeIdOfShard(indexName, 0);
-                    Version primaryNodeVersion = getNodeVersion(primaryNodeId);
+                String primaryNodeId = getPrimaryNodeIdOfShard(indexName, 0);
+                Version primaryNodeVersion = getNodeVersion(primaryNodeId);
 
 
-                    // Sometimes the primary shard ends on the upgraded node (i.e. after a rebalance)
-                    // This causes issues when removing and adding replicas, since then we cannot allocate to any of the old nodes.
-                    // That is an issue only for the first mixed round.
-                    // In that case we exclude the upgraded node from the shard allocation and cancel the shard to force moving
-                    // the primary to a node in the old version, this allows adding replicas in the first mixed round.
-                    logger.info("--> Primary node in first mixed round {} / {}", primaryNodeId, primaryNodeVersion);
-                    if (primaryNodeVersion.after(UPGRADE_FROM_VERSION)) {
-                        logger.info("--> cancelling primary shard on node [{}]", primaryNodeId);
-                        cancelShard(indexName, 0, primaryNodeId);
-                        logger.info("--> done cancelling primary shard on node [{}]", primaryNodeId);
+                // Sometimes the primary shard ends on the upgraded node (i.e. after a rebalance)
+                // This causes issues when removing and adding replicas, since then we cannot allocate to any of the old nodes.
+                // That is an issue only for the first mixed round.
+                // In that case we exclude the upgraded node from the shard allocation and cancel the shard to force moving
+                // the primary to a node in the old version, this allows adding replicas in the first mixed round.
+                logger.info("--> Primary node in first mixed round {} / {}", primaryNodeId, primaryNodeVersion);
+                if (primaryNodeVersion.after(getOldClusterVersion())) {
+                    logger.info("--> cancelling primary shard on node [{}]", primaryNodeId);
+                    cancelShard(indexName, 0, primaryNodeId);
+                    logger.info("--> done cancelling primary shard on node [{}]", primaryNodeId);
 
 
-                        String currentPrimaryNodeId = getPrimaryNodeIdOfShard(indexName, 0);
-                        assertThat(getNodeVersion(currentPrimaryNodeId), is(equalTo(UPGRADE_FROM_VERSION)));
-                    }
-                } else {
-                    logger.info("--> not in first upgrade round, removing exclusions for [{}]", indexName);
-                    updateIndexSettings(indexName, Settings.builder().putNull("index.routing.allocation.exclude._id"));
-                    logger.info("--> done removing exclusions for [{}]", indexName);
+                    String currentPrimaryNodeId = getPrimaryNodeIdOfShard(indexName, 0);
+                    assertThat(getNodeVersion(currentPrimaryNodeId), is(equalTo(getOldClusterVersion())));
                 }
                 }
+            } else {
+                logger.info("--> not in first upgrade round, removing exclusions for [{}]", indexName);
+                updateIndexSettings(indexName, Settings.builder().putNull("index.routing.allocation.exclude._id"));
+                logger.info("--> done removing exclusions for [{}]", indexName);
+            }
 
 
-                // Drop replicas
-                logger.info("--> dropping replicas from [{}]", indexName);
-                updateIndexSettingsPermittingSlowlogDeprecationWarning(
-                    indexName,
-                    Settings.builder().put(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), 0)
-                );
-                logger.info("--> finished dropping replicas from [{}], adding them back", indexName);
-                updateIndexSettingsPermittingSlowlogDeprecationWarning(
-                    indexName,
-                    Settings.builder().put(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), 1)
-                );
-                logger.info("--> finished adding replicas from [{}]", indexName);
-                ensureGreen(indexName);
+            // Drop replicas
+            logger.info("--> dropping replicas from [{}]", indexName);
+            updateIndexSettingsPermittingSlowlogDeprecationWarning(
+                indexName,
+                Settings.builder().put(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), 0)
+            );
+            logger.info("--> finished dropping replicas from [{}], adding them back", indexName);
+            updateIndexSettingsPermittingSlowlogDeprecationWarning(
+                indexName,
+                Settings.builder().put(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), 1)
+            );
+            logger.info("--> finished adding replicas from [{}]", indexName);
+            ensureGreen(indexName);
 
 
-                assertMatchAllReturnsAllDocuments(indexName, numDocs);
-                assertMatchQueryReturnsAllDocuments(indexName, numDocs);
-            }
-            default -> throw new IllegalStateException("unknown type " + CLUSTER_TYPE);
+            assertMatchAllReturnsAllDocuments(indexName, numDocs);
+            assertMatchQueryReturnsAllDocuments(indexName, numDocs);
         }
         }
     }
     }
 
 
@@ -145,7 +149,7 @@ public class SnapshotBasedRecoveryIT extends AbstractRollingTestCase {
         List<String> upgradedNodes = new ArrayList<>();
         List<String> upgradedNodes = new ArrayList<>();
         for (Map.Entry<String, Map<String, Object>> nodeInfoEntry : nodes.entrySet()) {
         for (Map.Entry<String, Map<String, Object>> nodeInfoEntry : nodes.entrySet()) {
             Version nodeVersion = Version.fromString(extractValue(nodeInfoEntry.getValue(), "version"));
             Version nodeVersion = Version.fromString(extractValue(nodeInfoEntry.getValue(), "version"));
-            if (nodeVersion.after(UPGRADE_FROM_VERSION)) {
+            if (nodeVersion.after(getOldClusterVersion())) {
                 upgradedNodes.add(nodeInfoEntry.getKey());
                 upgradedNodes.add(nodeInfoEntry.getKey());
             }
             }
         }
         }

+ 9 - 3
qa/rolling-upgrade/src/test/java/org/elasticsearch/upgrades/SystemIndicesUpgradeIT.java → qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/SystemIndicesUpgradeIT.java

@@ -8,6 +8,8 @@
 
 
 package org.elasticsearch.upgrades;
 package org.elasticsearch.upgrades;
 
 
+import com.carrotsearch.randomizedtesting.annotations.Name;
+
 import org.elasticsearch.client.Request;
 import org.elasticsearch.client.Request;
 import org.elasticsearch.client.ResponseException;
 import org.elasticsearch.client.ResponseException;
 import org.elasticsearch.index.IndexVersion;
 import org.elasticsearch.index.IndexVersion;
@@ -21,13 +23,17 @@ import static org.hamcrest.Matchers.hasKey;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.notNullValue;
 import static org.hamcrest.Matchers.notNullValue;
 
 
-public class SystemIndicesUpgradeIT extends AbstractRollingTestCase {
+public class SystemIndicesUpgradeIT extends ParameterizedRollingUpgradeTestCase {
+
+    public SystemIndicesUpgradeIT(@Name("upgradedNodes") int upgradedNodes) {
+        super(upgradedNodes);
+    }
 
 
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
     public void testSystemIndicesUpgrades() throws Exception {
     public void testSystemIndicesUpgrades() throws Exception {
         final String systemIndexWarning = "this request accesses system indices: [.tasks], but in a future major version, direct "
         final String systemIndexWarning = "this request accesses system indices: [.tasks], but in a future major version, direct "
             + "access to system indices will be prevented by default";
             + "access to system indices will be prevented by default";
-        if (CLUSTER_TYPE == ClusterType.OLD) {
+        if (isOldCluster()) {
             // create index
             // create index
             Request createTestIndex = new Request("PUT", "/test_index_old");
             Request createTestIndex = new Request("PUT", "/test_index_old");
             createTestIndex.setJsonEntity("{\"settings\": {\"index.number_of_replicas\": 0}}");
             createTestIndex.setJsonEntity("{\"settings\": {\"index.number_of_replicas\": 0}}");
@@ -99,7 +105,7 @@ public class SystemIndicesUpgradeIT extends AbstractRollingTestCase {
                 }));
                 }));
                 assertThat(client().performRequest(putAliasRequest).getStatusLine().getStatusCode(), is(200));
                 assertThat(client().performRequest(putAliasRequest).getStatusLine().getStatusCode(), is(200));
             }
             }
-        } else if (CLUSTER_TYPE == ClusterType.UPGRADED) {
+        } else if (isUpgradedCluster()) {
             assertBusy(() -> {
             assertBusy(() -> {
                 Request clusterStateRequest = new Request("GET", "/_cluster/state/metadata");
                 Request clusterStateRequest = new Request("GET", "/_cluster/state/metadata");
                 Map<String, Object> indices = new JsonMapView(entityAsMap(client().performRequest(clusterStateRequest))).get(
                 Map<String, Object> indices = new JsonMapView(entityAsMap(client().performRequest(clusterStateRequest))).get(

+ 26 - 20
qa/rolling-upgrade/src/test/java/org/elasticsearch/upgrades/TsdbIT.java → qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/TsdbIT.java

@@ -8,6 +8,8 @@
 
 
 package org.elasticsearch.upgrades;
 package org.elasticsearch.upgrades;
 
 
+import com.carrotsearch.randomizedtesting.annotations.Name;
+
 import org.elasticsearch.Version;
 import org.elasticsearch.Version;
 import org.elasticsearch.client.Request;
 import org.elasticsearch.client.Request;
 import org.elasticsearch.common.time.DateFormatter;
 import org.elasticsearch.common.time.DateFormatter;
@@ -24,7 +26,11 @@ import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.notNullValue;
 import static org.hamcrest.Matchers.notNullValue;
 import static org.hamcrest.Matchers.nullValue;
 import static org.hamcrest.Matchers.nullValue;
 
 
-public class TsdbIT extends AbstractRollingTestCase {
+public class TsdbIT extends ParameterizedRollingUpgradeTestCase {
+
+    public TsdbIT(@Name("upgradedNodes") int upgradedNodes) {
+        super(upgradedNodes);
+    }
 
 
     private static final String TEMPLATE = """
     private static final String TEMPLATE = """
         {
         {
@@ -88,21 +94,21 @@ public class TsdbIT extends AbstractRollingTestCase {
     private static final String BULK =
     private static final String BULK =
         """
         """
             {"create": {}}
             {"create": {}}
-            {"@timestamp": "$now", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507","ip": "10.10.55.1", "network": {"tx": 2001818691, "rx": 802133794}}}}
+            {"@timestamp": "$now", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507", "ip": "10.10.55.1", "network": {"tx": 2001818691, "rx": 802133794}}}}
             {"create": {}}
             {"create": {}}
-            {"@timestamp": "$now", "metricset": "pod", "k8s": {"pod": {"name": "hamster", "uid":"947e4ced-1786-4e53-9e0c-5c447e959508","ip": "10.10.55.1", "network": {"tx": 2005177954, "rx": 801479970}}}}
+            {"@timestamp": "$now", "metricset": "pod", "k8s": {"pod": {"name": "hamster", "uid":"947e4ced-1786-4e53-9e0c-5c447e959508", "ip": "10.10.55.1", "network": {"tx": 2005177954, "rx": 801479970}}}}
             {"create": {}}
             {"create": {}}
-            {"@timestamp": "$now", "metricset": "pod", "k8s": {"pod": {"name": "cow", "uid":"947e4ced-1786-4e53-9e0c-5c447e959509","ip": "10.10.55.1", "network": {"tx": 2006223737, "rx": 802337279}}}}
+            {"@timestamp": "$now", "metricset": "pod", "k8s": {"pod": {"name": "cow", "uid":"947e4ced-1786-4e53-9e0c-5c447e959509", "ip": "10.10.55.1", "network": {"tx": 2006223737, "rx": 802337279}}}}
             {"create": {}}
             {"create": {}}
-            {"@timestamp": "$now", "metricset": "pod", "k8s": {"pod": {"name": "rat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959510","ip": "10.10.55.2", "network": {"tx": 2012916202, "rx": 803685721}}}}
+            {"@timestamp": "$now", "metricset": "pod", "k8s": {"pod": {"name": "rat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959510", "ip": "10.10.55.2", "network": {"tx": 2012916202, "rx": 803685721}}}}
             {"create": {}}
             {"create": {}}
-            {"@timestamp": "$now", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9","ip": "10.10.55.3", "network": {"tx": 1434521831, "rx": 530575198}}}}
+            {"@timestamp": "$now", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9", "ip": "10.10.55.3", "network": {"tx": 1434521831, "rx": 530575198}}}}
             {"create": {}}
             {"create": {}}
-            {"@timestamp": "$now", "metricset": "pod", "k8s": {"pod": {"name": "tiger", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea10","ip": "10.10.55.3", "network": {"tx": 1434577921, "rx": 530600088}}}}
+            {"@timestamp": "$now", "metricset": "pod", "k8s": {"pod": {"name": "tiger", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea10", "ip": "10.10.55.3", "network": {"tx": 1434577921, "rx": 530600088}}}}
             {"create": {}}
             {"create": {}}
-            {"@timestamp": "$now", "metricset": "pod", "k8s": {"pod": {"name": "lion", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876e11","ip": "10.10.55.3", "network": {"tx": 1434587694, "rx": 530604797}}}}
+            {"@timestamp": "$now", "metricset": "pod", "k8s": {"pod": {"name": "lion", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876e11", "ip": "10.10.55.3", "network": {"tx": 1434587694, "rx": 530604797}}}}
             {"create": {}}
             {"create": {}}
-            {"@timestamp": "$now", "metricset": "pod", "k8s": {"pod": {"name": "elephant", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876eb4","ip": "10.10.55.3", "network": {"tx": 1434595272, "rx": 530605511}}}}
+            {"@timestamp": "$now", "metricset": "pod", "k8s": {"pod": {"name": "elephant", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876eb4", "ip": "10.10.55.3", "network": {"tx": 1434595272, "rx": 530605511}}}}
             """;
             """;
 
 
     private static final String DOC = """
     private static final String DOC = """
@@ -125,11 +131,11 @@ public class TsdbIT extends AbstractRollingTestCase {
 
 
     public void testTsdbDataStream() throws Exception {
     public void testTsdbDataStream() throws Exception {
         assumeTrue(
         assumeTrue(
-            "Skipping version [" + UPGRADE_FROM_VERSION + "], because TSDB was GA-ed in 8.7.0",
-            UPGRADE_FROM_VERSION.onOrAfter(Version.V_8_7_0)
+            "Skipping version [" + getOldClusterVersion() + "], because TSDB was GA-ed in 8.7.0",
+            getOldClusterVersion().onOrAfter(Version.V_8_7_0)
         );
         );
         String dataStreamName = "k8s";
         String dataStreamName = "k8s";
-        if (CLUSTER_TYPE == ClusterType.OLD) {
+        if (isOldCluster()) {
             final String INDEX_TEMPLATE = """
             final String INDEX_TEMPLATE = """
                 {
                 {
                     "index_patterns": ["$PATTERN"],
                     "index_patterns": ["$PATTERN"],
@@ -144,20 +150,20 @@ public class TsdbIT extends AbstractRollingTestCase {
             assertOK(client().performRequest(putIndexTemplateRequest));
             assertOK(client().performRequest(putIndexTemplateRequest));
 
 
             performOldClustertOperations(templateName, dataStreamName);
             performOldClustertOperations(templateName, dataStreamName);
-        } else if (CLUSTER_TYPE == ClusterType.MIXED) {
+        } else if (isMixedCluster()) {
             performMixedClusterOperations(dataStreamName);
             performMixedClusterOperations(dataStreamName);
-        } else if (CLUSTER_TYPE == ClusterType.UPGRADED) {
+        } else if (isUpgradedCluster()) {
             performUpgradedClusterOperations(dataStreamName);
             performUpgradedClusterOperations(dataStreamName);
         }
         }
     }
     }
 
 
     public void testTsdbDataStreamWithComponentTemplate() throws Exception {
     public void testTsdbDataStreamWithComponentTemplate() throws Exception {
         assumeTrue(
         assumeTrue(
-            "Skipping version [" + UPGRADE_FROM_VERSION + "], because TSDB was GA-ed in 8.7.0 and bug was fixed in 8.11.0",
-            UPGRADE_FROM_VERSION.onOrAfter(Version.V_8_7_0) && UPGRADE_FROM_VERSION.before(Version.V_8_11_0)
+            "Skipping version [" + getOldClusterVersion() + "], because TSDB was GA-ed in 8.7.0 and bug was fixed in 8.11.0",
+            getOldClusterVersion().onOrAfter(Version.V_8_7_0) && getOldClusterVersion().before(Version.V_8_11_0)
         );
         );
         String dataStreamName = "template-with-component-template";
         String dataStreamName = "template-with-component-template";
-        if (CLUSTER_TYPE == ClusterType.OLD) {
+        if (isOldCluster()) {
             final String COMPONENT_TEMPLATE = """
             final String COMPONENT_TEMPLATE = """
                     {
                     {
                         "template": $TEMPLATE
                         "template": $TEMPLATE
@@ -181,9 +187,9 @@ public class TsdbIT extends AbstractRollingTestCase {
             assertOK(client().performRequest(putIndexTemplateRequest));
             assertOK(client().performRequest(putIndexTemplateRequest));
 
 
             performOldClustertOperations(templateName, dataStreamName);
             performOldClustertOperations(templateName, dataStreamName);
-        } else if (CLUSTER_TYPE == ClusterType.MIXED) {
+        } else if (isMixedCluster()) {
             performMixedClusterOperations(dataStreamName);
             performMixedClusterOperations(dataStreamName);
-        } else if (CLUSTER_TYPE == ClusterType.UPGRADED) {
+        } else if (isUpgradedCluster()) {
             performUpgradedClusterOperations(dataStreamName);
             performUpgradedClusterOperations(dataStreamName);
 
 
             var dataStreams = getDataStream(dataStreamName);
             var dataStreams = getDataStream(dataStreamName);
@@ -242,7 +248,7 @@ public class TsdbIT extends AbstractRollingTestCase {
 
 
     private static void performMixedClusterOperations(String dataStreamName) throws IOException {
     private static void performMixedClusterOperations(String dataStreamName) throws IOException {
         ensureHealth(dataStreamName, request -> request.addParameter("wait_for_status", "yellow"));
         ensureHealth(dataStreamName, request -> request.addParameter("wait_for_status", "yellow"));
-        if (FIRST_MIXED_ROUND) {
+        if (isFirstMixedCluster()) {
             indexDoc(dataStreamName);
             indexDoc(dataStreamName);
         }
         }
         assertSearch(dataStreamName, 9);
         assertSearch(dataStreamName, 9);

+ 132 - 0
qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/UpgradeWithOldIndexSettingsIT.java

@@ -0,0 +1,132 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+package org.elasticsearch.upgrades;
+
+import com.carrotsearch.randomizedtesting.annotations.Name;
+
+import org.elasticsearch.Version;
+import org.elasticsearch.client.Request;
+import org.elasticsearch.client.Response;
+import org.elasticsearch.client.ResponseException;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.common.xcontent.support.XContentMapValues;
+import org.elasticsearch.core.Strings;
+
+import java.io.IOException;
+import java.util.Map;
+
+import static org.elasticsearch.rest.action.search.RestSearchAction.TOTAL_HITS_AS_INT_PARAM;
+import static org.hamcrest.Matchers.is;
+
+public class UpgradeWithOldIndexSettingsIT extends ParameterizedRollingUpgradeTestCase {
+
+    public UpgradeWithOldIndexSettingsIT(@Name("upgradedNodes") int upgradedNodes) {
+        super(upgradedNodes);
+    }
+
+    private static final String INDEX_NAME = "test_index_old_settings";
+    private static final String EXPECTED_WARNING = "[index.indexing.slowlog.level] setting was deprecated in Elasticsearch and will "
+        + "be removed in a future release! See the breaking changes documentation for the next major version.";
+
+    private static final String EXPECTED_V8_WARNING = "[index.indexing.slowlog.level] setting was deprecated in the previous Elasticsearch"
+        + " release and is removed in this release.";
+
+    public void testOldIndexSettings() throws Exception {
+        if (isOldCluster()) {
+            Request createTestIndex = new Request("PUT", "/" + INDEX_NAME);
+            createTestIndex.setJsonEntity("{\"settings\": {\"index.indexing.slowlog.level\": \"WARN\"}}");
+            createTestIndex.setOptions(expectWarnings(EXPECTED_WARNING));
+            if (getOldClusterVersion().before(Version.V_8_0_0)) {
+                // create index with settings no longer valid in 8.0
+                client().performRequest(createTestIndex);
+            } else {
+                assertTrue(
+                    expectThrows(ResponseException.class, () -> client().performRequest(createTestIndex)).getMessage()
+                        .contains("unknown setting [index.indexing.slowlog.level]")
+                );
+
+                Request createTestIndex1 = new Request("PUT", "/" + INDEX_NAME);
+                client().performRequest(createTestIndex1);
+            }
+
+            // add some data
+            Request bulk = new Request("POST", "/_bulk");
+            bulk.addParameter("refresh", "true");
+            if (getOldClusterVersion().before(Version.V_8_0_0)) {
+                bulk.setOptions(expectWarnings(EXPECTED_WARNING));
+            }
+            bulk.setJsonEntity(Strings.format("""
+                {"index": {"_index": "%s"}}
+                {"f1": "v1", "f2": "v2"}
+                """, INDEX_NAME));
+            client().performRequest(bulk);
+        } else if (isMixedCluster()) {
+            // add some more data
+            Request bulk = new Request("POST", "/_bulk");
+            bulk.addParameter("refresh", "true");
+            if (getOldClusterVersion().before(Version.V_8_0_0)) {
+                bulk.setOptions(expectWarnings(EXPECTED_WARNING));
+            }
+            bulk.setJsonEntity(Strings.format("""
+                {"index": {"_index": "%s"}}
+                {"f1": "v3", "f2": "v4"}
+                """, INDEX_NAME));
+            client().performRequest(bulk);
+        } else {
+            if (getOldClusterVersion().before(Version.V_8_0_0)) {
+                Request createTestIndex = new Request("PUT", "/" + INDEX_NAME + "/_settings");
+                // update index settings should work
+                createTestIndex.setJsonEntity("{\"index.indexing.slowlog.level\": \"INFO\"}");
+                createTestIndex.setOptions(expectWarnings(EXPECTED_V8_WARNING));
+                client().performRequest(createTestIndex);
+
+                // ensure we were able to change the setting, despite it having no effect
+                Request indexSettingsRequest = new Request("GET", "/" + INDEX_NAME + "/_settings");
+                Map<String, Object> response = entityAsMap(client().performRequest(indexSettingsRequest));
+
+                var slowLogLevel = (String) (XContentMapValues.extractValue(
+                    INDEX_NAME + ".settings.index.indexing.slowlog.level",
+                    response
+                ));
+
+                // check that we can read our old index settings
+                assertThat(slowLogLevel, is("INFO"));
+            }
+            assertCount(INDEX_NAME, 2);
+        }
+    }
+
+    private void assertCount(String index, int countAtLeast) throws IOException {
+        Request searchTestIndexRequest = new Request("POST", "/" + index + "/_search");
+        searchTestIndexRequest.addParameter(TOTAL_HITS_AS_INT_PARAM, "true");
+        searchTestIndexRequest.addParameter("filter_path", "hits.total");
+        Response searchTestIndexResponse = client().performRequest(searchTestIndexRequest);
+        Map<String, Object> response = entityAsMap(searchTestIndexResponse);
+
+        var hitsTotal = (Integer) (XContentMapValues.extractValue("hits.total", response));
+
+        assertTrue(hitsTotal >= countAtLeast);
+    }
+
+    public static void updateIndexSettingsPermittingSlowlogDeprecationWarning(String index, Settings.Builder settings) throws IOException {
+        Request request = new Request("PUT", "/" + index + "/_settings");
+        request.setJsonEntity(org.elasticsearch.common.Strings.toString(settings.build()));
+        if (getOldClusterVersion().before(Version.V_7_17_9)) {
+            // There is a bug (fixed in 7.17.9 and 8.7.0 where deprecation warnings could leak into ClusterApplierService#applyChanges)
+            // Below warnings are set (and leaking) from an index in this test case
+            request.setOptions(expectVersionSpecificWarnings(v -> {
+                v.compatible(
+                    "[index.indexing.slowlog.level] setting was deprecated in Elasticsearch and will be removed in a future release! "
+                        + "See the breaking changes documentation for the next major version."
+                );
+            }));
+        }
+        client().performRequest(request);
+    }
+}

+ 10 - 4
qa/rolling-upgrade/src/test/java/org/elasticsearch/upgrades/XPackIT.java → qa/rolling-upgrade/src/javaRestTest/java/org/elasticsearch/upgrades/XPackIT.java

@@ -7,6 +7,8 @@
  */
  */
 package org.elasticsearch.upgrades;
 package org.elasticsearch.upgrades;
 
 
+import com.carrotsearch.randomizedtesting.annotations.Name;
+
 import org.apache.http.util.EntityUtils;
 import org.apache.http.util.EntityUtils;
 import org.elasticsearch.client.Request;
 import org.elasticsearch.client.Request;
 import org.junit.Before;
 import org.junit.Before;
@@ -20,7 +22,12 @@ import static org.junit.Assume.assumeThat;
  * Basic tests for simple xpack functionality that are only run if the
  * Basic tests for simple xpack functionality that are only run if the
  * cluster is the on the default distribution.
  * cluster is the on the default distribution.
  */
  */
-public class XPackIT extends AbstractRollingTestCase {
+public class XPackIT extends ParameterizedRollingUpgradeTestCase {
+
+    public XPackIT(@Name("upgradedNodes") int upgradedNodes) {
+        super(upgradedNodes);
+    }
+
     @Before
     @Before
     public void skipIfNotXPack() {
     public void skipIfNotXPack() {
         assumeThat(
         assumeThat(
@@ -28,10 +35,9 @@ public class XPackIT extends AbstractRollingTestCase {
             System.getProperty("tests.distribution"),
             System.getProperty("tests.distribution"),
             equalTo("default")
             equalTo("default")
         );
         );
-        assumeThat(
+        assumeTrue(
             "running this on the unupgraded cluster would change its state and it wouldn't work prior to 6.3 anyway",
             "running this on the unupgraded cluster would change its state and it wouldn't work prior to 6.3 anyway",
-            CLUSTER_TYPE,
-            equalTo(ClusterType.UPGRADED)
+            isUpgradedCluster()
         );
         );
         /*
         /*
          * *Mostly* we want this for when we're upgrading from pre-6.3's
          * *Mostly* we want this for when we're upgrading from pre-6.3's

+ 0 - 131
qa/rolling-upgrade/src/test/java/org/elasticsearch/upgrades/UpgradeWithOldIndexSettingsIT.java

@@ -1,131 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-package org.elasticsearch.upgrades;
-
-import org.elasticsearch.Version;
-import org.elasticsearch.client.Request;
-import org.elasticsearch.client.Response;
-import org.elasticsearch.client.ResponseException;
-import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.common.xcontent.support.XContentMapValues;
-import org.elasticsearch.core.Strings;
-
-import java.io.IOException;
-import java.util.Map;
-
-import static org.elasticsearch.rest.action.search.RestSearchAction.TOTAL_HITS_AS_INT_PARAM;
-import static org.hamcrest.Matchers.is;
-
-public class UpgradeWithOldIndexSettingsIT extends AbstractRollingTestCase {
-
-    private static final String INDEX_NAME = "test_index_old_settings";
-    private static final String EXPECTED_WARNING = "[index.indexing.slowlog.level] setting was deprecated in Elasticsearch and will "
-        + "be removed in a future release! See the breaking changes documentation for the next major version.";
-
-    private static final String EXPECTED_V8_WARNING = "[index.indexing.slowlog.level] setting was deprecated in the previous Elasticsearch"
-        + " release and is removed in this release.";
-
-    @SuppressWarnings("unchecked")
-    public void testOldIndexSettings() throws Exception {
-        switch (CLUSTER_TYPE) {
-            case OLD -> {
-                Request createTestIndex = new Request("PUT", "/" + INDEX_NAME);
-                createTestIndex.setJsonEntity("{\"settings\": {\"index.indexing.slowlog.level\": \"WARN\"}}");
-                createTestIndex.setOptions(expectWarnings(EXPECTED_WARNING));
-                if (UPGRADE_FROM_VERSION.before(Version.V_8_0_0)) {
-                    // create index with settings no longer valid in 8.0
-                    client().performRequest(createTestIndex);
-                } else {
-                    assertTrue(
-                        expectThrows(ResponseException.class, () -> client().performRequest(createTestIndex)).getMessage()
-                            .contains("unknown setting [index.indexing.slowlog.level]")
-                    );
-
-                    Request createTestIndex1 = new Request("PUT", "/" + INDEX_NAME);
-                    client().performRequest(createTestIndex1);
-                }
-
-                // add some data
-                Request bulk = new Request("POST", "/_bulk");
-                bulk.addParameter("refresh", "true");
-                if (UPGRADE_FROM_VERSION.before(Version.V_8_0_0)) {
-                    bulk.setOptions(expectWarnings(EXPECTED_WARNING));
-                }
-                bulk.setJsonEntity(Strings.format("""
-                    {"index": {"_index": "%s"}}
-                    {"f1": "v1", "f2": "v2"}
-                    """, INDEX_NAME));
-                client().performRequest(bulk);
-            }
-            case MIXED -> {
-                // add some more data
-                Request bulk = new Request("POST", "/_bulk");
-                bulk.addParameter("refresh", "true");
-                if (UPGRADE_FROM_VERSION.before(Version.V_8_0_0)) {
-                    bulk.setOptions(expectWarnings(EXPECTED_WARNING));
-                }
-                bulk.setJsonEntity(Strings.format("""
-                    {"index": {"_index": "%s"}}
-                    {"f1": "v3", "f2": "v4"}
-                    """, INDEX_NAME));
-                client().performRequest(bulk);
-            }
-            case UPGRADED -> {
-                if (UPGRADE_FROM_VERSION.before(Version.V_8_0_0)) {
-                    Request createTestIndex = new Request("PUT", "/" + INDEX_NAME + "/_settings");
-                    // update index settings should work
-                    createTestIndex.setJsonEntity("{\"index.indexing.slowlog.level\": \"INFO\"}");
-                    createTestIndex.setOptions(expectWarnings(EXPECTED_V8_WARNING));
-                    client().performRequest(createTestIndex);
-
-                    // ensure we were able to change the setting, despite it having no effect
-                    Request indexSettingsRequest = new Request("GET", "/" + INDEX_NAME + "/_settings");
-                    Map<String, Object> response = entityAsMap(client().performRequest(indexSettingsRequest));
-
-                    var slowLogLevel = (String) (XContentMapValues.extractValue(
-                        INDEX_NAME + ".settings.index.indexing.slowlog.level",
-                        response
-                    ));
-
-                    // check that we can read our old index settings
-                    assertThat(slowLogLevel, is("INFO"));
-                }
-                assertCount(INDEX_NAME, 2);
-            }
-        }
-    }
-
-    private void assertCount(String index, int countAtLeast) throws IOException {
-        Request searchTestIndexRequest = new Request("POST", "/" + index + "/_search");
-        searchTestIndexRequest.addParameter(TOTAL_HITS_AS_INT_PARAM, "true");
-        searchTestIndexRequest.addParameter("filter_path", "hits.total");
-        Response searchTestIndexResponse = client().performRequest(searchTestIndexRequest);
-        Map<String, Object> response = entityAsMap(searchTestIndexResponse);
-
-        var hitsTotal = (Integer) (XContentMapValues.extractValue("hits.total", response));
-
-        assertTrue(hitsTotal >= countAtLeast);
-    }
-
-    public static void updateIndexSettingsPermittingSlowlogDeprecationWarning(String index, Settings.Builder settings) throws IOException {
-        Request request = new Request("PUT", "/" + index + "/_settings");
-        request.setJsonEntity(org.elasticsearch.common.Strings.toString(settings.build()));
-        if (UPGRADE_FROM_VERSION.before(Version.V_7_17_9)) {
-            // There is a bug (fixed in 7.17.9 and 8.7.0 where deprecation warnings could leak into ClusterApplierService#applyChanges)
-            // Below warnings are set (and leaking) from an index in this test case
-            request.setOptions(expectVersionSpecificWarnings(v -> {
-                v.compatible(
-                    "[index.indexing.slowlog.level] setting was deprecated in Elasticsearch and will be removed in a future release! "
-                        + "See the breaking changes documentation for the next major version."
-                );
-            }));
-        }
-        client().performRequest(request);
-    }
-}