Universal cluster bootstrap method for tests with autoMinMasterNodes=false (#38038)
Currently, there are a few tests that use autoMinMasterNodes=false and hence override addExtraClusterBootstrapSettings, mostly this is 10-30 lines of codes that are copy-pasted from class to class. This PR introduces `InternalTestCluster.setBootstrapMasterNodeIndex` which is suitable for all classes and copy-paste could be removed. Removing code is always a good thing!
This commit is contained in:
parent
0e6a7c20a1
commit
bfd618cf83
|
@ -28,7 +28,6 @@ import org.elasticsearch.client.Request;
|
|||
import org.elasticsearch.client.Response;
|
||||
import org.elasticsearch.client.ResponseException;
|
||||
import org.elasticsearch.client.RestClient;
|
||||
import org.elasticsearch.cluster.coordination.ClusterBootstrapService;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.routing.UnassignedInfo;
|
||||
import org.elasticsearch.common.Priority;
|
||||
|
@ -41,10 +40,8 @@ import org.elasticsearch.test.discovery.TestZenDiscovery;
|
|||
import org.hamcrest.Matchers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.hamcrest.core.Is.is;
|
||||
|
||||
|
@ -59,30 +56,13 @@ public class Zen2RestApiIT extends ESNetty4IntegTestCase {
|
|||
return Settings.builder().put(super.nodeSettings(nodeOrdinal)).put(TestZenDiscovery.USE_ZEN2.getKey(), true).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Settings> addExtraClusterBootstrapSettings(List<Settings> allNodesSettings) {
|
||||
final Settings firstNodeSettings = allNodesSettings.get(0);
|
||||
final List<Settings> otherNodesSettings = allNodesSettings.subList(1, allNodesSettings.size());
|
||||
final List<String> masterNodeNames = allNodesSettings.stream()
|
||||
.filter(org.elasticsearch.node.Node.NODE_MASTER_SETTING::get)
|
||||
.map(org.elasticsearch.node.Node.NODE_NAME_SETTING::get)
|
||||
.collect(Collectors.toList());
|
||||
final List<Settings> updatedSettings = new ArrayList<>();
|
||||
|
||||
updatedSettings.add(Settings.builder().put(firstNodeSettings)
|
||||
.putList(ClusterBootstrapService.INITIAL_MASTER_NODES_SETTING.getKey(), masterNodeNames)
|
||||
.build());
|
||||
updatedSettings.addAll(otherNodesSettings);
|
||||
|
||||
return updatedSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean addMockHttpTransport() {
|
||||
return false; // enable http
|
||||
}
|
||||
|
||||
public void testRollingRestartOfTwoNodeCluster() throws Exception {
|
||||
internalCluster().setBootstrapMasterNodeIndex(1);
|
||||
final List<String> nodes = internalCluster().startNodes(2);
|
||||
createIndex("test",
|
||||
Settings.builder()
|
||||
|
@ -142,6 +122,7 @@ public class Zen2RestApiIT extends ESNetty4IntegTestCase {
|
|||
}
|
||||
|
||||
public void testClearVotingTombstonesNotWaitingForRemoval() throws Exception {
|
||||
internalCluster().setBootstrapMasterNodeIndex(2);
|
||||
List<String> nodes = internalCluster().startNodes(3);
|
||||
RestClient restClient = getRestClient();
|
||||
Response response = restClient.performRequest(new Request("POST", "/_cluster/voting_config_exclusions/" + nodes.get(2)));
|
||||
|
@ -154,6 +135,7 @@ public class Zen2RestApiIT extends ESNetty4IntegTestCase {
|
|||
}
|
||||
|
||||
public void testClearVotingTombstonesWaitingForRemoval() throws Exception {
|
||||
internalCluster().setBootstrapMasterNodeIndex(2);
|
||||
List<String> nodes = internalCluster().startNodes(3);
|
||||
RestClient restClient = getRestClient();
|
||||
String nodeToWithdraw = nodes.get(randomIntBetween(0, 2));
|
||||
|
@ -167,6 +149,7 @@ public class Zen2RestApiIT extends ESNetty4IntegTestCase {
|
|||
}
|
||||
|
||||
public void testFailsOnUnknownNode() throws Exception {
|
||||
internalCluster().setBootstrapMasterNodeIndex(2);
|
||||
internalCluster().startNodes(3);
|
||||
RestClient restClient = getRestClient();
|
||||
try {
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
package org.elasticsearch.action.admin.indices.exists;
|
||||
|
||||
import org.elasticsearch.cluster.coordination.ClusterBootstrapService;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.discovery.MasterNotDiscoveredException;
|
||||
|
@ -29,26 +28,14 @@ import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
|
|||
import org.elasticsearch.test.InternalTestCluster;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.elasticsearch.node.Node.NODE_MASTER_SETTING;
|
||||
import static org.elasticsearch.node.Node.NODE_NAME_SETTING;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertThrows;
|
||||
|
||||
@ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0, numClientNodes = 0, transportClientRatio = 0.0,
|
||||
autoMinMasterNodes = false)
|
||||
public class IndicesExistsIT extends ESIntegTestCase {
|
||||
|
||||
@Override
|
||||
protected List<Settings> addExtraClusterBootstrapSettings(List<Settings> allNodesSettings) {
|
||||
final List<String> masterNodeNames
|
||||
= allNodesSettings.stream().filter(NODE_MASTER_SETTING::get).map(NODE_NAME_SETTING::get).collect(Collectors.toList());
|
||||
return allNodesSettings.stream().map(s -> Settings.builder().put(s)
|
||||
.putList(ClusterBootstrapService.INITIAL_MASTER_NODES_SETTING.getKey(), masterNodeNames).build()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void testIndexExistsWithBlocksInPlace() throws IOException {
|
||||
internalCluster().setBootstrapMasterNodeIndex(0);
|
||||
Settings settings = Settings.builder()
|
||||
.put(GatewayService.RECOVER_AFTER_NODES_SETTING.getKey(), 99).build();
|
||||
String node = internalCluster().startNode(settings);
|
||||
|
|
|
@ -25,7 +25,6 @@ import org.elasticsearch.action.admin.cluster.configuration.ClearVotingConfigExc
|
|||
import org.elasticsearch.action.admin.cluster.configuration.ClearVotingConfigExclusionsRequest;
|
||||
import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.cluster.coordination.ClusterBootstrapService;
|
||||
import org.elasticsearch.cluster.coordination.FailedToCommitClusterStateException;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||
|
@ -35,7 +34,6 @@ import org.elasticsearch.common.settings.Settings;
|
|||
import org.elasticsearch.discovery.DiscoverySettings;
|
||||
import org.elasticsearch.discovery.zen.ZenDiscovery;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.node.Node;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.test.ESIntegTestCase;
|
||||
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
|
||||
|
@ -46,12 +44,10 @@ import org.elasticsearch.test.disruption.NetworkDisruption.TwoPartitions;
|
|||
import org.elasticsearch.test.junit.annotations.TestLogging;
|
||||
import org.elasticsearch.test.transport.MockTransportService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
@ -68,8 +64,6 @@ import static org.hamcrest.Matchers.nullValue;
|
|||
@TestLogging("_root:DEBUG,org.elasticsearch.cluster.service:TRACE,org.elasticsearch.discovery.zen:TRACE")
|
||||
public class MinimumMasterNodesIT extends ESIntegTestCase {
|
||||
|
||||
private int bootstrapNodeId;
|
||||
|
||||
@Override
|
||||
protected Collection<Class<? extends Plugin>> nodePlugins() {
|
||||
final HashSet<Class<? extends Plugin>> classes = new HashSet<>(super.nodePlugins());
|
||||
|
@ -77,28 +71,8 @@ public class MinimumMasterNodesIT extends ESIntegTestCase {
|
|||
return classes;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Settings> addExtraClusterBootstrapSettings(List<Settings> allNodesSettings) {
|
||||
if (internalCluster().size() + allNodesSettings.size() == bootstrapNodeId) {
|
||||
List<String> nodeNames = new ArrayList<>();
|
||||
Collections.addAll(nodeNames, internalCluster().getNodeNames());
|
||||
allNodesSettings.forEach(settings -> nodeNames.add(Node.NODE_NAME_SETTING.get(settings)));
|
||||
|
||||
List<Settings> otherNodesSettings = allNodesSettings.subList(0, allNodesSettings.size() - 1);
|
||||
Settings lastNodeSettings = allNodesSettings.get(allNodesSettings.size()-1);
|
||||
List<Settings> newSettings = new ArrayList<>();
|
||||
newSettings.addAll(otherNodesSettings);
|
||||
newSettings.add(Settings.builder().put(lastNodeSettings)
|
||||
.putList(ClusterBootstrapService.INITIAL_MASTER_NODES_SETTING.getKey(), nodeNames)
|
||||
.build());
|
||||
return newSettings;
|
||||
}
|
||||
return allNodesSettings;
|
||||
}
|
||||
|
||||
public void testTwoNodesNoMasterBlock() throws Exception {
|
||||
//bootstrap cluster once second node is started
|
||||
bootstrapNodeId = 2;
|
||||
internalCluster().setBootstrapMasterNodeIndex(1);
|
||||
|
||||
Settings settings = Settings.builder()
|
||||
.put(ZenDiscovery.PING_TIMEOUT_SETTING.getKey(), "200ms")
|
||||
|
@ -231,8 +205,7 @@ public class MinimumMasterNodesIT extends ESIntegTestCase {
|
|||
}
|
||||
|
||||
public void testThreeNodesNoMasterBlock() throws Exception {
|
||||
//bootstrap cluster once 3rd node is started
|
||||
bootstrapNodeId = 3;
|
||||
internalCluster().setBootstrapMasterNodeIndex(2);
|
||||
|
||||
Settings settings = Settings.builder()
|
||||
.put(ZenDiscovery.PING_TIMEOUT_SETTING.getKey(), "1s")
|
||||
|
@ -307,8 +280,7 @@ public class MinimumMasterNodesIT extends ESIntegTestCase {
|
|||
}
|
||||
|
||||
public void testCannotCommitStateThreeNodes() throws Exception {
|
||||
//bootstrap cluster once 3rd node is started
|
||||
bootstrapNodeId = 3;
|
||||
internalCluster().setBootstrapMasterNodeIndex(2);
|
||||
|
||||
Settings settings = Settings.builder()
|
||||
.put(ZenDiscovery.PING_TIMEOUT_SETTING.getKey(), "200ms")
|
||||
|
|
|
@ -22,7 +22,6 @@ package org.elasticsearch.cluster;
|
|||
import org.apache.lucene.search.join.ScoreMode;
|
||||
import org.elasticsearch.action.admin.cluster.configuration.AddVotingConfigExclusionsAction;
|
||||
import org.elasticsearch.action.admin.cluster.configuration.AddVotingConfigExclusionsRequest;
|
||||
import org.elasticsearch.cluster.coordination.ClusterBootstrapService;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.discovery.MasterNotDiscoveredException;
|
||||
|
@ -35,8 +34,6 @@ import org.elasticsearch.test.InternalTestCluster;
|
|||
import org.elasticsearch.test.junit.annotations.TestLogging;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
@ -46,20 +43,8 @@ import static org.hamcrest.Matchers.nullValue;
|
|||
@TestLogging("_root:DEBUG,org.elasticsearch.action.admin.cluster.state:TRACE")
|
||||
public class SpecificMasterNodesIT extends ESIntegTestCase {
|
||||
|
||||
@Override
|
||||
protected List<Settings> addExtraClusterBootstrapSettings(List<Settings> allNodesSettings) {
|
||||
// if it's the first master in the cluster bootstrap the cluster with this node name
|
||||
Settings settings = allNodesSettings.get(0);
|
||||
if (internalCluster().numMasterNodes() == 0 && settings.getAsBoolean(Node.NODE_MASTER_SETTING.getKey(), false)) {
|
||||
return Collections.singletonList(Settings.builder()
|
||||
.put(settings)
|
||||
.put(ClusterBootstrapService.INITIAL_MASTER_NODES_SETTING.getKey(), settings.get(Node.NODE_NAME_SETTING.getKey()))
|
||||
.build());
|
||||
}
|
||||
return allNodesSettings;
|
||||
}
|
||||
|
||||
public void testSimpleOnlyMasterNodeElection() throws IOException {
|
||||
internalCluster().setBootstrapMasterNodeIndex(0);
|
||||
logger.info("--> start data node / non master node");
|
||||
internalCluster().startNode(Settings.builder().put(Node.NODE_DATA_SETTING.getKey(), true)
|
||||
.put(Node.NODE_MASTER_SETTING.getKey(), false)
|
||||
|
@ -100,6 +85,7 @@ public class SpecificMasterNodesIT extends ESIntegTestCase {
|
|||
}
|
||||
|
||||
public void testElectOnlyBetweenMasterNodes() throws Exception {
|
||||
internalCluster().setBootstrapMasterNodeIndex(0);
|
||||
logger.info("--> start data node / non master node");
|
||||
internalCluster().startNode(Settings.builder().put(Node.NODE_DATA_SETTING.getKey(), true)
|
||||
.put(Node.NODE_MASTER_SETTING.getKey(), false).put("discovery.initial_state_timeout", "1s"));
|
||||
|
@ -146,6 +132,7 @@ public class SpecificMasterNodesIT extends ESIntegTestCase {
|
|||
}
|
||||
|
||||
public void testAliasFilterValidation() {
|
||||
internalCluster().setBootstrapMasterNodeIndex(0);
|
||||
logger.info("--> start master node / non data");
|
||||
internalCluster().startNode(Settings.builder()
|
||||
.put(Node.NODE_DATA_SETTING.getKey(), false).put(Node.NODE_MASTER_SETTING.getKey(), true));
|
||||
|
|
|
@ -36,11 +36,8 @@ import org.elasticsearch.node.Node;
|
|||
import org.elasticsearch.test.ESIntegTestCase;
|
||||
import org.elasticsearch.test.InternalTestCluster;
|
||||
import org.elasticsearch.test.junit.annotations.TestLogging;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
|
@ -50,42 +47,6 @@ import static org.hamcrest.Matchers.containsString;
|
|||
@TestLogging("_root:DEBUG,org.elasticsearch.cluster.service:TRACE,org.elasticsearch.discovery.zen:TRACE")
|
||||
public class UnsafeBootstrapMasterIT extends ESIntegTestCase {
|
||||
|
||||
private int bootstrapNodeId;
|
||||
|
||||
@Before
|
||||
public void resetBootstrapNodeId() {
|
||||
bootstrapNodeId = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs cluster bootstrap when node with id bootstrapNodeId is started.
|
||||
* Any node of the batch could be selected as bootstrap target.
|
||||
*/
|
||||
@Override
|
||||
protected List<Settings> addExtraClusterBootstrapSettings(List<Settings> allNodesSettings) {
|
||||
if (internalCluster().size() + allNodesSettings.size() == bootstrapNodeId) {
|
||||
List<String> nodeNames = new ArrayList<>();
|
||||
Collections.addAll(nodeNames, internalCluster().getNodeNames());
|
||||
allNodesSettings.forEach(settings -> nodeNames.add(Node.NODE_NAME_SETTING.get(settings)));
|
||||
|
||||
List<Settings> newSettings = new ArrayList<>();
|
||||
int bootstrapIndex = randomInt(allNodesSettings.size() - 1);
|
||||
for (int i = 0; i < allNodesSettings.size(); i++) {
|
||||
Settings nodeSettings = allNodesSettings.get(i);
|
||||
if (i == bootstrapIndex) {
|
||||
newSettings.add(Settings.builder().put(nodeSettings)
|
||||
.putList(ClusterBootstrapService.INITIAL_MASTER_NODES_SETTING.getKey(), nodeNames)
|
||||
.build());
|
||||
} else {
|
||||
newSettings.add(nodeSettings);
|
||||
}
|
||||
}
|
||||
|
||||
return newSettings;
|
||||
}
|
||||
return allNodesSettings;
|
||||
}
|
||||
|
||||
private MockTerminal executeCommand(Environment environment, boolean abort) throws Exception {
|
||||
final UnsafeBootstrapMasterCommand command = new UnsafeBootstrapMasterCommand();
|
||||
final MockTerminal terminal = new MockTerminal();
|
||||
|
@ -169,7 +130,7 @@ public class UnsafeBootstrapMasterIT extends ESIntegTestCase {
|
|||
}
|
||||
|
||||
public void testNoManifestFile() throws IOException {
|
||||
bootstrapNodeId = 1;
|
||||
internalCluster().setBootstrapMasterNodeIndex(0);
|
||||
internalCluster().startNode();
|
||||
ensureStableCluster(1);
|
||||
NodeEnvironment nodeEnvironment = internalCluster().getMasterNodeInstance(NodeEnvironment.class);
|
||||
|
@ -181,7 +142,7 @@ public class UnsafeBootstrapMasterIT extends ESIntegTestCase {
|
|||
}
|
||||
|
||||
public void testNoMetaData() throws IOException {
|
||||
bootstrapNodeId = 1;
|
||||
internalCluster().setBootstrapMasterNodeIndex(0);
|
||||
internalCluster().startNode();
|
||||
ensureStableCluster(1);
|
||||
NodeEnvironment nodeEnvironment = internalCluster().getMasterNodeInstance(NodeEnvironment.class);
|
||||
|
@ -194,7 +155,7 @@ public class UnsafeBootstrapMasterIT extends ESIntegTestCase {
|
|||
}
|
||||
|
||||
public void testAbortedByUser() throws IOException {
|
||||
bootstrapNodeId = 1;
|
||||
internalCluster().setBootstrapMasterNodeIndex(0);
|
||||
internalCluster().startNode();
|
||||
ensureStableCluster(1);
|
||||
internalCluster().stopRandomDataNode();
|
||||
|
@ -204,7 +165,7 @@ public class UnsafeBootstrapMasterIT extends ESIntegTestCase {
|
|||
}
|
||||
|
||||
public void test3MasterNodes2Failed() throws Exception {
|
||||
bootstrapNodeId = 3;
|
||||
internalCluster().setBootstrapMasterNodeIndex(2);
|
||||
List<String> masterNodes = internalCluster().startMasterOnlyNodes(3, Settings.EMPTY);
|
||||
|
||||
String dataNode = internalCluster().startDataOnlyNode();
|
||||
|
|
|
@ -22,7 +22,6 @@ package org.elasticsearch.gateway;
|
|||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.cluster.block.ClusterBlock;
|
||||
import org.elasticsearch.cluster.block.ClusterBlockLevel;
|
||||
import org.elasticsearch.cluster.coordination.ClusterBootstrapService;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.node.Node;
|
||||
|
@ -30,8 +29,6 @@ import org.elasticsearch.test.ESIntegTestCase;
|
|||
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
|
||||
import org.elasticsearch.test.ESIntegTestCase.Scope;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
@ -41,22 +38,6 @@ import static org.hamcrest.Matchers.hasItem;
|
|||
public class RecoverAfterNodesIT extends ESIntegTestCase {
|
||||
private static final TimeValue BLOCK_WAIT_TIMEOUT = TimeValue.timeValueSeconds(10);
|
||||
|
||||
@Override
|
||||
protected List<Settings> addExtraClusterBootstrapSettings(List<Settings> allNodesSettings) {
|
||||
if (internalCluster().numDataAndMasterNodes() == 0) {
|
||||
final Settings firstNodeSettings = allNodesSettings.get(0);
|
||||
final List<Settings> otherNodesSettings = allNodesSettings.subList(1, allNodesSettings.size());
|
||||
|
||||
final List<Settings> updatedSettings = new ArrayList<>();
|
||||
updatedSettings.add(Settings.builder().put(firstNodeSettings)
|
||||
.putList(ClusterBootstrapService.INITIAL_MASTER_NODES_SETTING.getKey(),
|
||||
Node.NODE_NAME_SETTING.get(firstNodeSettings)).build());
|
||||
updatedSettings.addAll(otherNodesSettings);
|
||||
|
||||
return updatedSettings;
|
||||
}
|
||||
return super.addExtraClusterBootstrapSettings(allNodesSettings);
|
||||
}
|
||||
|
||||
public Set<ClusterBlock> waitForNoBlocksOnNode(TimeValue timeout, Client nodeClient) {
|
||||
long start = System.currentTimeMillis();
|
||||
|
@ -75,6 +56,7 @@ public class RecoverAfterNodesIT extends ESIntegTestCase {
|
|||
}
|
||||
|
||||
public void testRecoverAfterNodes() throws Exception {
|
||||
internalCluster().setBootstrapMasterNodeIndex(0);
|
||||
logger.info("--> start node (1)");
|
||||
Client clientNode1 = startNode(Settings.builder().put("gateway.recover_after_nodes", 3));
|
||||
assertThat(clientNode1.admin().cluster().prepareState().setLocal(true).execute().actionGet()
|
||||
|
@ -100,6 +82,7 @@ public class RecoverAfterNodesIT extends ESIntegTestCase {
|
|||
}
|
||||
|
||||
public void testRecoverAfterMasterNodes() throws Exception {
|
||||
internalCluster().setBootstrapMasterNodeIndex(0);
|
||||
logger.info("--> start master_node (1)");
|
||||
Client master1 = startNode(Settings.builder()
|
||||
.put("gateway.recover_after_master_nodes", 2).put(Node.NODE_DATA_SETTING.getKey(), false)
|
||||
|
@ -145,6 +128,7 @@ public class RecoverAfterNodesIT extends ESIntegTestCase {
|
|||
}
|
||||
|
||||
public void testRecoverAfterDataNodes() throws Exception {
|
||||
internalCluster().setBootstrapMasterNodeIndex(0);
|
||||
logger.info("--> start master_node (1)");
|
||||
Client master1 = startNode(Settings.builder()
|
||||
.put("gateway.recover_after_data_nodes", 2)
|
||||
|
|
|
@ -1942,11 +1942,6 @@ public abstract class ESIntegTestCase extends ESTestCase {
|
|||
.put(ESIntegTestCase.this.nodeSettings(nodeOrdinal)).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Settings> addExtraClusterBootstrapSettings(List<Settings> allNodesSettings) {
|
||||
return ESIntegTestCase.this.addExtraClusterBootstrapSettings(allNodesSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path nodeConfigPath(int nodeOrdinal) {
|
||||
return ESIntegTestCase.this.nodeConfigPath(nodeOrdinal);
|
||||
|
@ -1975,18 +1970,6 @@ public abstract class ESIntegTestCase extends ESTestCase {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called before starting a collection of nodes.
|
||||
* At this point the test has a holistic view on all nodes settings and might perform settings adjustments as needed.
|
||||
* For instance, the test could retrieve master node names and fill in
|
||||
* {@link org.elasticsearch.cluster.coordination.ClusterBootstrapService#INITIAL_MASTER_NODES_SETTING} setting.
|
||||
*
|
||||
* @param allNodesSettings list of node settings before update
|
||||
* @return list of node settings after update
|
||||
*/
|
||||
protected List<Settings> addExtraClusterBootstrapSettings(List<Settings> allNodesSettings) {
|
||||
return allNodesSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iff this returns true mock transport implementations are used for the test runs. Otherwise not mock transport impls are used.
|
||||
|
@ -2214,6 +2197,9 @@ public abstract class ESIntegTestCase extends ESTestCase {
|
|||
// Deleting indices is going to clear search contexts implicitly so we
|
||||
// need to check that there are no more in-flight search contexts before
|
||||
// we remove indices
|
||||
if (isInternalCluster()) {
|
||||
internalCluster().setBootstrapMasterNodeIndex(-1);
|
||||
}
|
||||
super.ensureAllSearchContextsReleased();
|
||||
if (runTestScopeLifecycle()) {
|
||||
printTestMessage("cleaning up after");
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.elasticsearch.client.transport.TransportClient;
|
|||
import org.elasticsearch.cluster.ClusterName;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.action.index.MappingUpdatedAction;
|
||||
import org.elasticsearch.cluster.coordination.ClusterBootstrapService;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNode.Role;
|
||||
|
@ -243,6 +244,8 @@ public final class InternalTestCluster extends TestCluster {
|
|||
// If set to true only the first node in the cluster will be made a unicast node
|
||||
private boolean hostsListContainsOnlyFirstNode;
|
||||
|
||||
private int bootstrapMasterNodeIndex = -1;
|
||||
|
||||
public InternalTestCluster(
|
||||
final long clusterSeed,
|
||||
final Path baseDir,
|
||||
|
@ -400,6 +403,22 @@ public final class InternalTestCluster extends TestCluster {
|
|||
EsExecutors.daemonThreadFactory("test_" + clusterName), new ThreadContext(Settings.EMPTY));
|
||||
}
|
||||
|
||||
public int getBootstrapMasterNodeIndex() {
|
||||
return bootstrapMasterNodeIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets {@link #bootstrapMasterNodeIndex} to the given value, see {@link #bootstrapMasterNodeWithSpecifiedIndex(List)}
|
||||
* for the description of how this field is used.
|
||||
* It's only possible to change {@link #bootstrapMasterNodeIndex} value if autoManageMinMasterNodes is false.
|
||||
*/
|
||||
public void setBootstrapMasterNodeIndex(int bootstrapMasterNodeIndex) {
|
||||
if (autoManageMinMasterNodes && bootstrapMasterNodeIndex != -1) {
|
||||
throw new AssertionError("bootstrapMasterNodeIndex should be -1 if autoManageMinMasterNodes is true");
|
||||
}
|
||||
this.bootstrapMasterNodeIndex = bootstrapMasterNodeIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClusterName() {
|
||||
return clusterName;
|
||||
|
@ -1146,7 +1165,7 @@ public final class InternalTestCluster extends TestCluster {
|
|||
settings.add(getNodeSettings(i, sharedNodesSeeds[i], extraSettings.build(), defaultMinMasterNodes));
|
||||
}
|
||||
|
||||
int bootstrapNodeIndex = -1;
|
||||
int autoBootstrapMasterNodeIndex = -1;
|
||||
final List<String> masterNodeNames = settings.stream()
|
||||
.filter(Node.NODE_MASTER_SETTING::get)
|
||||
.map(Node.NODE_NAME_SETTING::get)
|
||||
|
@ -1154,17 +1173,17 @@ public final class InternalTestCluster extends TestCluster {
|
|||
|
||||
if (prevNodeCount == 0 && autoManageMinMasterNodes) {
|
||||
if (numSharedDedicatedMasterNodes > 0) {
|
||||
bootstrapNodeIndex = RandomNumbers.randomIntBetween(random, 0, numSharedDedicatedMasterNodes - 1);
|
||||
autoBootstrapMasterNodeIndex = RandomNumbers.randomIntBetween(random, 0, numSharedDedicatedMasterNodes - 1);
|
||||
} else if (numSharedDataNodes > 0) {
|
||||
bootstrapNodeIndex = RandomNumbers.randomIntBetween(random, 0, numSharedDataNodes - 1);
|
||||
autoBootstrapMasterNodeIndex = RandomNumbers.randomIntBetween(random, 0, numSharedDataNodes - 1);
|
||||
}
|
||||
}
|
||||
|
||||
final List<Settings> updatedSettings = nodeConfigurationSource.addExtraClusterBootstrapSettings(settings);
|
||||
final List<Settings> updatedSettings = bootstrapMasterNodeWithSpecifiedIndex(settings);
|
||||
|
||||
for (int i = 0; i < numSharedDedicatedMasterNodes + numSharedDataNodes + numSharedCoordOnlyNodes; i++) {
|
||||
Settings nodeSettings = updatedSettings.get(i);
|
||||
if (i == bootstrapNodeIndex) {
|
||||
if (i == autoBootstrapMasterNodeIndex) {
|
||||
nodeSettings = Settings.builder().putList(INITIAL_MASTER_NODES_SETTING.getKey(), masterNodeNames).put(nodeSettings).build();
|
||||
}
|
||||
final NodeAndClient nodeAndClient = buildNode(i, nodeSettings, true, onTransportServiceStarted);
|
||||
|
@ -1944,6 +1963,54 @@ public final class InternalTestCluster extends TestCluster {
|
|||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs cluster bootstrap when node with index {@link #bootstrapMasterNodeIndex} is started
|
||||
* with the names of all existing and new master-eligible nodes.
|
||||
* Indexing starts from 0.
|
||||
* If {@link #bootstrapMasterNodeIndex} is -1 (default), this method does nothing.
|
||||
*/
|
||||
private List<Settings> bootstrapMasterNodeWithSpecifiedIndex(List<Settings> allNodesSettings) {
|
||||
if (getBootstrapMasterNodeIndex() == -1) { // fast-path
|
||||
return allNodesSettings;
|
||||
}
|
||||
|
||||
int currentNodeId = numMasterNodes() - 1;
|
||||
List<Settings> newSettings = new ArrayList<>();
|
||||
|
||||
for (Settings settings : allNodesSettings) {
|
||||
if (Node.NODE_MASTER_SETTING.get(settings) == false) {
|
||||
newSettings.add(settings);
|
||||
} else {
|
||||
currentNodeId++;
|
||||
if (currentNodeId != bootstrapMasterNodeIndex) {
|
||||
newSettings.add(settings);
|
||||
} else {
|
||||
List<String> nodeNames = new ArrayList<>();
|
||||
|
||||
for (Settings nodeSettings : getDataOrMasterNodeInstances(Settings.class)) {
|
||||
if (Node.NODE_MASTER_SETTING.get(nodeSettings)) {
|
||||
nodeNames.add(Node.NODE_NAME_SETTING.get(nodeSettings));
|
||||
}
|
||||
}
|
||||
|
||||
for (Settings nodeSettings : allNodesSettings) {
|
||||
if (Node.NODE_MASTER_SETTING.get(nodeSettings)) {
|
||||
nodeNames.add(Node.NODE_NAME_SETTING.get(nodeSettings));
|
||||
}
|
||||
}
|
||||
|
||||
newSettings.add(Settings.builder().put(settings)
|
||||
.putList(ClusterBootstrapService.INITIAL_MASTER_NODES_SETTING.getKey(), nodeNames)
|
||||
.build());
|
||||
|
||||
setBootstrapMasterNodeIndex(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a node with default settings and returns its name.
|
||||
*/
|
||||
|
@ -1992,7 +2059,7 @@ public final class InternalTestCluster extends TestCluster {
|
|||
}
|
||||
final List<NodeAndClient> nodes = new ArrayList<>();
|
||||
final int prevMasterCount = getMasterNodesCount();
|
||||
int bootstrapMasterNodeIndex =
|
||||
int autoBootstrapMasterNodeIndex =
|
||||
prevMasterCount == 0 && autoManageMinMasterNodes && newMasterCount > 0 && Arrays.stream(extraSettings)
|
||||
.allMatch(s -> Node.NODE_MASTER_SETTING.get(s) == false || TestZenDiscovery.USE_ZEN2.get(s) == true)
|
||||
? RandomNumbers.randomIntBetween(random, 0, newMasterCount - 1) : -1;
|
||||
|
@ -2010,16 +2077,16 @@ public final class InternalTestCluster extends TestCluster {
|
|||
.map(Node.NODE_NAME_SETTING::get)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final List<Settings> updatedSettings = nodeConfigurationSource.addExtraClusterBootstrapSettings(settings);
|
||||
final List<Settings> updatedSettings = bootstrapMasterNodeWithSpecifiedIndex(settings);
|
||||
|
||||
for (int i = 0; i < numOfNodes; i++) {
|
||||
final Settings nodeSettings = updatedSettings.get(i);
|
||||
final Builder builder = Settings.builder();
|
||||
if (Node.NODE_MASTER_SETTING.get(nodeSettings)) {
|
||||
if (bootstrapMasterNodeIndex == 0) {
|
||||
if (autoBootstrapMasterNodeIndex == 0) {
|
||||
builder.putList(INITIAL_MASTER_NODES_SETTING.getKey(), initialMasterNodes);
|
||||
}
|
||||
bootstrapMasterNodeIndex -= 1;
|
||||
autoBootstrapMasterNodeIndex -= 1;
|
||||
}
|
||||
|
||||
final NodeAndClient nodeAndClient =
|
||||
|
|
|
@ -24,7 +24,6 @@ import org.elasticsearch.plugins.Plugin;
|
|||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class NodeConfigurationSource {
|
||||
|
||||
|
@ -52,10 +51,6 @@ public abstract class NodeConfigurationSource {
|
|||
|
||||
public abstract Path nodeConfigPath(int nodeOrdinal);
|
||||
|
||||
public List<Settings> addExtraClusterBootstrapSettings(List<Settings> allNodesSettings) {
|
||||
return allNodesSettings;
|
||||
}
|
||||
|
||||
/** Returns plugins that should be loaded on the node */
|
||||
public Collection<Class<? extends Plugin>> nodePlugins() {
|
||||
return Collections.emptyList();
|
||||
|
|
|
@ -56,15 +56,11 @@ import java.util.Random;
|
|||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static org.elasticsearch.cluster.coordination.ClusterBootstrapService.INITIAL_MASTER_NODES_SETTING;
|
||||
import static org.elasticsearch.cluster.node.DiscoveryNode.Role.DATA;
|
||||
import static org.elasticsearch.cluster.node.DiscoveryNode.Role.INGEST;
|
||||
import static org.elasticsearch.cluster.node.DiscoveryNode.Role.MASTER;
|
||||
import static org.elasticsearch.discovery.DiscoveryModule.DISCOVERY_HOSTS_PROVIDER_SETTING;
|
||||
import static org.elasticsearch.node.Node.NODE_MASTER_SETTING;
|
||||
import static org.elasticsearch.node.Node.NODE_NAME_SETTING;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertFileExists;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertFileNotExists;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
@ -144,21 +140,23 @@ public class InternalTestClusterTests extends ESTestCase {
|
|||
final boolean masterNodes;
|
||||
final int minNumDataNodes;
|
||||
final int maxNumDataNodes;
|
||||
final int bootstrapMasterNodeIndex;
|
||||
if (autoManageMinMasterNodes) {
|
||||
masterNodes = randomBoolean();
|
||||
minNumDataNodes = randomIntBetween(0, 3);
|
||||
maxNumDataNodes = randomIntBetween(minNumDataNodes, 4);
|
||||
bootstrapMasterNodeIndex = -1;
|
||||
} else {
|
||||
// if we manage min master nodes, we need to lock down the number of nodes
|
||||
minNumDataNodes = randomIntBetween(0, 4);
|
||||
maxNumDataNodes = minNumDataNodes;
|
||||
masterNodes = false;
|
||||
bootstrapMasterNodeIndex = maxNumDataNodes == 0 ? -1 : randomIntBetween(0, maxNumDataNodes - 1);
|
||||
}
|
||||
final int numClientNodes = randomIntBetween(0, 2);
|
||||
final String clusterName1 = "shared1";
|
||||
final String clusterName2 = "shared2";
|
||||
String transportClient = getTestTransportType();
|
||||
final long bootstrapNodeSelectionSeed = randomLong();
|
||||
NodeConfigurationSource nodeConfigurationSource = new NodeConfigurationSource() {
|
||||
@Override
|
||||
public Settings nodeSettings(int nodeOrdinal) {
|
||||
|
@ -176,14 +174,6 @@ public class InternalTestClusterTests extends ESTestCase {
|
|||
return settings.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Settings> addExtraClusterBootstrapSettings(List<Settings> allNodesSettings) {
|
||||
if (autoManageMinMasterNodes) {
|
||||
return allNodesSettings;
|
||||
}
|
||||
return addBootstrapConfiguration(new Random(bootstrapNodeSelectionSeed), allNodesSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path nodeConfigPath(int nodeOrdinal) {
|
||||
return null;
|
||||
|
@ -202,9 +192,12 @@ public class InternalTestClusterTests extends ESTestCase {
|
|||
InternalTestCluster cluster0 = new InternalTestCluster(clusterSeed, baseDir, masterNodes,
|
||||
autoManageMinMasterNodes, minNumDataNodes, maxNumDataNodes, clusterName1, nodeConfigurationSource, numClientNodes,
|
||||
nodePrefix, mockPlugins(), Function.identity());
|
||||
cluster0.setBootstrapMasterNodeIndex(bootstrapMasterNodeIndex);
|
||||
|
||||
InternalTestCluster cluster1 = new InternalTestCluster(clusterSeed, baseDir, masterNodes,
|
||||
autoManageMinMasterNodes, minNumDataNodes, maxNumDataNodes, clusterName2, nodeConfigurationSource, numClientNodes,
|
||||
nodePrefix, mockPlugins(), Function.identity());
|
||||
cluster1.setBootstrapMasterNodeIndex(bootstrapMasterNodeIndex);
|
||||
|
||||
assertClusters(cluster0, cluster1, false);
|
||||
long seed = randomLong();
|
||||
|
@ -231,19 +224,6 @@ public class InternalTestClusterTests extends ESTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
private static List<Settings> addBootstrapConfiguration(Random random, List<Settings> allNodesSettings) {
|
||||
final List<Settings> updatedSettings = new ArrayList<>(allNodesSettings);
|
||||
final int bootstrapIndex = randomFrom(random, IntStream.range(0, updatedSettings.size())
|
||||
.filter(i -> NODE_MASTER_SETTING.get(allNodesSettings.get(i))).boxed().collect(Collectors.toList()));
|
||||
final Settings settings = updatedSettings.get(bootstrapIndex);
|
||||
assertFalse(INITIAL_MASTER_NODES_SETTING.exists(settings));
|
||||
assertTrue(NODE_MASTER_SETTING.get(settings));
|
||||
updatedSettings.set(bootstrapIndex,
|
||||
Settings.builder().put(settings).putList(INITIAL_MASTER_NODES_SETTING.getKey(), allNodesSettings.stream()
|
||||
.filter(NODE_MASTER_SETTING::get).map(NODE_NAME_SETTING::get).collect(Collectors.toList())).build());
|
||||
return updatedSettings;
|
||||
}
|
||||
|
||||
public void testDataFolderAssignmentAndCleaning() throws IOException, InterruptedException {
|
||||
long clusterSeed = randomLong();
|
||||
boolean masterNodes = randomBoolean();
|
||||
|
@ -353,8 +333,6 @@ public class InternalTestClusterTests extends ESTestCase {
|
|||
InternalTestCluster cluster = new InternalTestCluster(randomLong(), baseDir, false,
|
||||
false, 0, 0, "test", new NodeConfigurationSource() {
|
||||
|
||||
private boolean bootstrapConfigurationSet;
|
||||
|
||||
@Override
|
||||
public Settings nodeSettings(int nodeOrdinal) {
|
||||
return Settings.builder()
|
||||
|
@ -369,16 +347,6 @@ public class InternalTestClusterTests extends ESTestCase {
|
|||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Settings> addExtraClusterBootstrapSettings(List<Settings> allNodesSettings) {
|
||||
if (bootstrapConfigurationSet || allNodesSettings.stream().noneMatch(NODE_MASTER_SETTING::get)) {
|
||||
return allNodesSettings;
|
||||
}
|
||||
|
||||
bootstrapConfigurationSet = true;
|
||||
return addBootstrapConfiguration(random(), allNodesSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path nodeConfigPath(int nodeOrdinal) {
|
||||
return null;
|
||||
|
@ -399,6 +367,8 @@ public class InternalTestClusterTests extends ESTestCase {
|
|||
roles.add(role);
|
||||
}
|
||||
|
||||
cluster.setBootstrapMasterNodeIndex(randomIntBetween(0, (int) roles.stream().filter(role -> role.equals(MASTER)).count() - 1));
|
||||
|
||||
try {
|
||||
Map<DiscoveryNode.Role, Set<String>> pathsPerRole = new HashMap<>();
|
||||
for (int i = 0; i < numNodes; i++) {
|
||||
|
|
Loading…
Reference in New Issue