diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterConfiguration.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterConfiguration.groovy
index ab618a0fdc7f7..af84a44233aa3 100644
--- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterConfiguration.groovy
+++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterConfiguration.groovy
@@ -63,13 +63,11 @@ class ClusterConfiguration {
boolean debug = false
/**
- * if true
each node will be configured with discovery.zen.minimum_master_nodes set
- * to the total number of nodes in the cluster. This will also cause that each node has `0s` state recovery
- * timeout which can lead to issues if for instance an existing clusterstate is expected to be recovered
- * before any tests start
+ * Configuration of the setting discovery.zen.minimum_master_nodes on the nodes.
+ * In case of more than one node, this defaults to (number of nodes / 2) + 1
*/
@Input
- boolean useMinimumMasterNodes = true
+ Closure minimumMasterNodes = { getNumNodes() > 1 ? getNumNodes().intdiv(2) + 1 : -1 }
@Input
String jvmArgs = "-Xms" + System.getProperty('tests.heap.size', '512m') +
diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterFormationTasks.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterFormationTasks.groovy
index 217ecb4ed90fb..14074f241df91 100644
--- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterFormationTasks.groovy
+++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterFormationTasks.groovy
@@ -311,13 +311,14 @@ class ClusterFormationTasks {
// Define a node attribute so we can test that it exists
'node.attr.testattr' : 'test'
]
- // we set min master nodes to the total number of nodes in the cluster and
- // basically skip initial state recovery to allow the cluster to form using a realistic master election
- // this means all nodes must be up, join the seed node and do a master election. This will also allow new and
- // old nodes in the BWC case to become the master
- if (node.config.useMinimumMasterNodes && node.config.numNodes > 1) {
- esConfig['discovery.zen.minimum_master_nodes'] = node.config.numNodes
- esConfig['discovery.initial_state_timeout'] = '0s' // don't wait for state.. just start up quickly
+ int minimumMasterNodes = node.config.minimumMasterNodes.call()
+ if (minimumMasterNodes > 0) {
+ esConfig['discovery.zen.minimum_master_nodes'] = minimumMasterNodes
+ }
+ if (node.config.numNodes > 1) {
+ // don't wait for state.. just start up quickly
+ // this will also allow new and old nodes in the BWC case to become the master
+ esConfig['discovery.initial_state_timeout'] = '0s'
}
esConfig['node.max_local_storage_nodes'] = node.config.numNodes
esConfig['http.port'] = node.config.httpPort
diff --git a/qa/rolling-upgrade/build.gradle b/qa/rolling-upgrade/build.gradle
index b5f841601308e..fc3cf88b272f1 100644
--- a/qa/rolling-upgrade/build.gradle
+++ b/qa/rolling-upgrade/build.gradle
@@ -61,6 +61,7 @@ for (Version version : wireCompatVersions) {
distribution = 'zip'
clusterName = 'rolling-upgrade'
unicastTransportUri = { seedNode, node, ant -> oldClusterTest.nodes.get(0).transportUri() }
+ minimumMasterNodes = { 2 }
/* Override the data directory so the new node always gets the node we
* just stopped's data directory. */
dataDir = { nodeNumber -> oldClusterTest.nodes[1].dataDir }
@@ -81,6 +82,7 @@ for (Version version : wireCompatVersions) {
distribution = 'zip'
clusterName = 'rolling-upgrade'
unicastTransportUri = { seedNode, node, ant -> mixedClusterTest.nodes.get(0).transportUri() }
+ minimumMasterNodes = { 2 }
/* Override the data directory so the new node always gets the node we
* just stopped's data directory. */
dataDir = { nodeNumber -> oldClusterTest.nodes[0].dataDir}