Skip to content

Commit 069c3a1

Browse files
DISCOVERY: Cleanup AbstractDisruptionTestCase (elastic#34808)
* DISCOVERY: Cleanup AbstractDisruptionTestCase * Make the internal test cluster manage minimum master nodes where we used the default of (nodes / 2 + 1) before * Remove use of the `NodeConfigurationSource` indirection * Relates elastic#33675
1 parent 41e0da6 commit 069c3a1

File tree

6 files changed

+111
-78
lines changed

6 files changed

+111
-78
lines changed

server/src/test/java/org/elasticsearch/discovery/AbstractDisruptionTestCase.java

+1-49
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,19 @@
1919

2020
package org.elasticsearch.discovery;
2121

22-
import java.nio.file.Path;
2322
import org.elasticsearch.cluster.ClusterState;
2423
import org.elasticsearch.cluster.block.ClusterBlock;
2524
import org.elasticsearch.cluster.block.ClusterBlockLevel;
2625
import org.elasticsearch.cluster.node.DiscoveryNodes;
2726
import org.elasticsearch.common.Nullable;
2827
import org.elasticsearch.common.settings.Settings;
2928
import org.elasticsearch.common.unit.TimeValue;
30-
import org.elasticsearch.discovery.zen.ElectMasterService;
3129
import org.elasticsearch.discovery.zen.FaultDetection;
3230
import org.elasticsearch.discovery.zen.UnicastZenPing;
3331
import org.elasticsearch.discovery.zen.ZenPing;
34-
import org.elasticsearch.env.NodeEnvironment;
3532
import org.elasticsearch.plugins.Plugin;
3633
import org.elasticsearch.test.ESIntegTestCase;
3734
import org.elasticsearch.test.InternalTestCluster;
38-
import org.elasticsearch.test.NodeConfigurationSource;
3935
import org.elasticsearch.test.discovery.TestZenDiscovery;
4036
import org.elasticsearch.test.disruption.NetworkDisruption;
4137
import org.elasticsearch.test.disruption.NetworkDisruption.Bridge;
@@ -56,27 +52,20 @@
5652
import java.util.Set;
5753
import java.util.concurrent.TimeUnit;
5854

59-
import static org.elasticsearch.discovery.DiscoveryModule.DISCOVERY_HOSTS_PROVIDER_SETTING;
6055
import static org.hamcrest.Matchers.equalTo;
6156
import static org.hamcrest.Matchers.not;
6257

6358
public abstract class AbstractDisruptionTestCase extends ESIntegTestCase {
6459

6560
static final TimeValue DISRUPTION_HEALING_OVERHEAD = TimeValue.timeValueSeconds(40); // we use 30s as timeout in many places.
6661

67-
private NodeConfigurationSource discoveryConfig;
6862

6963
@Override
7064
protected Settings nodeSettings(int nodeOrdinal) {
71-
return Settings.builder().put(discoveryConfig.nodeSettings(nodeOrdinal))
65+
return Settings.builder().put(super.nodeSettings(nodeOrdinal)).put(DEFAULT_SETTINGS)
7266
.put(TestZenDiscovery.USE_MOCK_PINGS.getKey(), false).build();
7367
}
7468

75-
@Before
76-
public void clearConfig() {
77-
discoveryConfig = null;
78-
}
79-
8069
@Override
8170
protected int numberOfShards() {
8271
return 3;
@@ -118,11 +107,6 @@ protected void beforeIndexDeletion() throws Exception {
118107
}
119108

120109
List<String> startCluster(int numberOfNodes) {
121-
return startCluster(numberOfNodes, -1);
122-
}
123-
124-
List<String> startCluster(int numberOfNodes, int minimumMasterNode) {
125-
configureCluster(numberOfNodes, minimumMasterNode);
126110
InternalTestCluster internalCluster = internalCluster();
127111
List<String> nodes = internalCluster.startNodes(numberOfNodes);
128112
ensureStableCluster(numberOfNodes);
@@ -151,38 +135,6 @@ protected Collection<Class<? extends Plugin>> nodePlugins() {
151135
return Arrays.asList(MockTransportService.TestPlugin.class);
152136
}
153137

154-
void configureCluster(int numberOfNodes, int minimumMasterNode) {
155-
configureCluster(DEFAULT_SETTINGS, numberOfNodes, minimumMasterNode);
156-
}
157-
158-
void configureCluster(Settings settings, int numberOfNodes, int minimumMasterNode) {
159-
if (minimumMasterNode < 0) {
160-
minimumMasterNode = numberOfNodes / 2 + 1;
161-
}
162-
logger.info("---> configured unicast");
163-
// TODO: Rarely use default settings form some of these
164-
Settings nodeSettings = Settings.builder()
165-
.put(settings)
166-
.put(NodeEnvironment.MAX_LOCAL_STORAGE_NODES_SETTING.getKey(), numberOfNodes)
167-
.put(ElectMasterService.DISCOVERY_ZEN_MINIMUM_MASTER_NODES_SETTING.getKey(), minimumMasterNode)
168-
.putList(DISCOVERY_HOSTS_PROVIDER_SETTING.getKey(), "file")
169-
.build();
170-
171-
if (discoveryConfig == null) {
172-
discoveryConfig = new NodeConfigurationSource() {
173-
@Override
174-
public Settings nodeSettings(final int nodeOrdinal) {
175-
return nodeSettings;
176-
}
177-
178-
@Override
179-
public Path nodeConfigPath(final int nodeOrdinal) {
180-
return null;
181-
}
182-
};
183-
}
184-
}
185-
186138
ClusterState getNodeClusterState(String node) {
187139
return client(node).admin().cluster().prepareState().setLocal(true).get().getState();
188140
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.discovery;
21+
22+
import java.util.ArrayList;
23+
import java.util.Arrays;
24+
import java.util.Collection;
25+
import java.util.List;
26+
import org.elasticsearch.action.index.IndexRequestBuilder;
27+
import org.elasticsearch.cluster.metadata.IndexMetaData;
28+
import org.elasticsearch.common.settings.Settings;
29+
import org.elasticsearch.common.xcontent.XContentType;
30+
import org.elasticsearch.indices.store.IndicesStoreIntegrationIT;
31+
import org.elasticsearch.plugins.Plugin;
32+
import org.elasticsearch.test.ESIntegTestCase;
33+
import org.elasticsearch.test.transport.MockTransportService;
34+
35+
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
36+
import static org.hamcrest.Matchers.equalTo;
37+
38+
@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0, transportClientRatio = 0)
39+
public class ClusterDisruptionCleanSettingsIT extends ESIntegTestCase {
40+
41+
@Override
42+
protected Collection<Class<? extends Plugin>> nodePlugins() {
43+
return Arrays.asList(MockTransportService.TestPlugin.class);
44+
}
45+
46+
/**
47+
* This test creates a scenario where a primary shard (0 replicas) relocates and is in POST_RECOVERY on the target
48+
* node but already deleted on the source node. Search request should still work.
49+
*/
50+
public void testSearchWithRelocationAndSlowClusterStateProcessing() throws Exception {
51+
// Don't use AbstractDisruptionTestCase.DEFAULT_SETTINGS as settings
52+
// (which can cause node disconnects on a slow CI machine)
53+
internalCluster().startMasterOnlyNode();
54+
final String node_1 = internalCluster().startDataOnlyNode();
55+
56+
logger.info("--> creating index [test] with one shard and on replica");
57+
assertAcked(prepareCreate("test").setSettings(
58+
Settings.builder().put(indexSettings())
59+
.put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
60+
.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0))
61+
);
62+
ensureGreen("test");
63+
64+
final String node_2 = internalCluster().startDataOnlyNode();
65+
List<IndexRequestBuilder> indexRequestBuilderList = new ArrayList<>();
66+
for (int i = 0; i < 100; i++) {
67+
indexRequestBuilderList.add(client().prepareIndex().setIndex("test").setType("_doc")
68+
.setSource("{\"int_field\":1}", XContentType.JSON));
69+
}
70+
indexRandom(true, indexRequestBuilderList);
71+
72+
IndicesStoreIntegrationIT.relocateAndBlockCompletion(logger, "test", 0, node_1, node_2);
73+
// now search for the documents and see if we get a reply
74+
assertThat(client().prepareSearch().setSize(0).get().getHits().getTotalHits(), equalTo(100L));
75+
}
76+
}

server/src/test/java/org/elasticsearch/discovery/DiscoveryDisruptionIT.java

+5-14
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@
5454
/**
5555
* Tests for discovery during disruptions.
5656
*/
57-
@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0, transportClientRatio = 0, autoMinMasterNodes = false)
5857
@TestLogging("_root:DEBUG,org.elasticsearch.cluster.service:TRACE")
58+
@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0, transportClientRatio = 0)
5959
public class DiscoveryDisruptionIT extends AbstractDisruptionTestCase {
6060

6161
public void testIsolatedUnicastNodes() throws Exception {
6262
internalCluster().setHostsListContainsOnlyFirstNode(true);
63-
List<String> nodes = startCluster(4, -1);
63+
List<String> nodes = startCluster(4);
6464
// Figure out what is the elected master node
6565
final String unicastTarget = nodes.get(0);
6666

@@ -100,7 +100,7 @@ public void testIsolatedUnicastNodes() throws Exception {
100100
*/
101101
public void testUnicastSinglePingResponseContainsMaster() throws Exception {
102102
internalCluster().setHostsListContainsOnlyFirstNode(true);
103-
List<String> nodes = startCluster(4, -1);
103+
List<String> nodes = startCluster(4);
104104
// Figure out what is the elected master node
105105
final String masterNode = internalCluster().getMasterName();
106106
logger.info("---> legit elected master node={}", masterNode);
@@ -138,15 +138,8 @@ public void testUnicastSinglePingResponseContainsMaster() throws Exception {
138138
* Test cluster join with issues in cluster state publishing *
139139
*/
140140
public void testClusterJoinDespiteOfPublishingIssues() throws Exception {
141-
List<String> nodes = startCluster(2, 1);
142-
143-
String masterNode = internalCluster().getMasterName();
144-
String nonMasterNode;
145-
if (masterNode.equals(nodes.get(0))) {
146-
nonMasterNode = nodes.get(1);
147-
} else {
148-
nonMasterNode = nodes.get(0);
149-
}
141+
String masterNode = internalCluster().startMasterOnlyNode(Settings.EMPTY);
142+
String nonMasterNode = internalCluster().startDataOnlyNode(Settings.EMPTY);
150143

151144
DiscoveryNodes discoveryNodes = internalCluster().getInstance(ClusterService.class, nonMasterNode).state().nodes();
152145

@@ -196,7 +189,6 @@ public void testClusterJoinDespiteOfPublishingIssues() throws Exception {
196189
}
197190

198191
public void testClusterFormingWithASlowNode() throws Exception {
199-
configureCluster(3, 2);
200192

201193
SlowClusterStateProcessing disruption = new SlowClusterStateProcessing(random(), 0, 0, 1000, 2000);
202194

@@ -212,7 +204,6 @@ public void testClusterFormingWithASlowNode() throws Exception {
212204
}
213205

214206
public void testElectMasterWithLatestVersion() throws Exception {
215-
configureCluster(3, 2);
216207
final Set<String> nodes = new HashSet<>(internalCluster().startNodes(3));
217208
ensureStableCluster(3);
218209
ServiceDisruptionScheme isolateAllNodes =

server/src/test/java/org/elasticsearch/discovery/MasterDisruptionIT.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@
6767
/**
6868
* Tests relating to the loss of the master.
6969
*/
70-
@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0, transportClientRatio = 0, autoMinMasterNodes = false)
7170
@TestLogging("_root:DEBUG,org.elasticsearch.cluster.service:TRACE")
71+
@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0, transportClientRatio = 0)
7272
public class MasterDisruptionIT extends AbstractDisruptionTestCase {
7373

7474
/**
@@ -153,8 +153,8 @@ public void testNodesFDAfterMasterReelection() throws Exception {
153153
*/
154154
@TestLogging("_root:DEBUG,org.elasticsearch.cluster.service:TRACE,org.elasticsearch.test.disruption:TRACE")
155155
public void testStaleMasterNotHijackingMajority() throws Exception {
156-
// 3 node cluster with unicast discovery and minimum_master_nodes set to 2:
157-
final List<String> nodes = startCluster(3, 2);
156+
// 3 node cluster with unicast discovery and minimum_master_nodes set to the default of 2:
157+
final List<String> nodes = startCluster(3);
158158

159159
// Save the current master node as old master node, because that node will get frozen
160160
final String oldMasterNode = internalCluster().getMasterName();
@@ -267,7 +267,7 @@ public void onFailure(String source, Exception e) {
267267
* Test that cluster recovers from a long GC on master that causes other nodes to elect a new one
268268
*/
269269
public void testMasterNodeGCs() throws Exception {
270-
List<String> nodes = startCluster(3, -1);
270+
List<String> nodes = startCluster(3);
271271

272272
String oldMasterNode = internalCluster().getMasterName();
273273
// a very long GC, but it's OK as we remove the disruption when it has had an effect

server/src/test/java/org/elasticsearch/discovery/SnapshotDisruptionIT.java

+23-9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
*/
1919
package org.elasticsearch.discovery;
2020

21+
import java.util.Arrays;
22+
import java.util.Collection;
23+
import java.util.concurrent.ExecutionException;
2124
import org.elasticsearch.action.ActionFuture;
2225
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse;
2326
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse;
@@ -28,10 +31,12 @@
2831
import org.elasticsearch.cluster.service.ClusterService;
2932
import org.elasticsearch.common.settings.Settings;
3033
import org.elasticsearch.common.unit.ByteSizeUnit;
34+
import org.elasticsearch.plugins.Plugin;
3135
import org.elasticsearch.snapshots.SnapshotInfo;
3236
import org.elasticsearch.snapshots.SnapshotMissingException;
3337
import org.elasticsearch.snapshots.SnapshotState;
3438
import org.elasticsearch.test.ESIntegTestCase;
39+
import org.elasticsearch.test.discovery.TestZenDiscovery;
3540
import org.elasticsearch.test.disruption.NetworkDisruption;
3641
import org.elasticsearch.test.junit.annotations.TestLogging;
3742

@@ -40,26 +45,35 @@
4045
import java.util.List;
4146
import java.util.Set;
4247
import java.util.concurrent.CountDownLatch;
43-
import java.util.concurrent.ExecutionException;
4448
import java.util.concurrent.TimeUnit;
49+
import org.elasticsearch.test.transport.MockTransportService;
4550

4651
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
4752
import static org.hamcrest.Matchers.instanceOf;
4853

4954
/**
5055
* Tests snapshot operations during disruptions.
5156
*/
52-
@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0, transportClientRatio = 0, autoMinMasterNodes = false)
5357
@TestLogging("org.elasticsearch.snapshot:TRACE")
54-
public class SnapshotDisruptionIT extends AbstractDisruptionTestCase {
58+
@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0, transportClientRatio = 0)
59+
public class SnapshotDisruptionIT extends ESIntegTestCase {
5560

56-
public void testDisruptionOnSnapshotInitialization() throws Exception {
57-
final Settings settings = Settings.builder()
58-
.put(DEFAULT_SETTINGS)
59-
.put(DiscoverySettings.COMMIT_TIMEOUT_SETTING.getKey(), "30s") // wait till cluster state is committed
61+
@Override
62+
protected Collection<Class<? extends Plugin>> nodePlugins() {
63+
return Arrays.asList(MockTransportService.TestPlugin.class);
64+
}
65+
66+
@Override
67+
protected Settings nodeSettings(int nodeOrdinal) {
68+
return Settings.builder().put(super.nodeSettings(nodeOrdinal))
69+
.put(AbstractDisruptionTestCase.DEFAULT_SETTINGS)
70+
.put(TestZenDiscovery.USE_MOCK_PINGS.getKey(), false)
71+
.put(DiscoverySettings.COMMIT_TIMEOUT_SETTING.getKey(), "30s")
6072
.build();
73+
}
74+
75+
public void testDisruptionOnSnapshotInitialization() throws Exception {
6176
final String idxName = "test";
62-
configureCluster(settings, 4, 2);
6377
final List<String> allMasterEligibleNodes = internalCluster().startMasterOnlyNodes(3);
6478
final String dataNode = internalCluster().startDataOnlyNode();
6579
ensureStableCluster(4);
@@ -159,7 +173,7 @@ public void clusterChanged(ClusterChangedEvent event) {
159173
}
160174
}
161175

162-
private void createRandomIndex(String idxName) throws ExecutionException, InterruptedException {
176+
private void createRandomIndex(String idxName) throws InterruptedException, ExecutionException {
163177
assertAcked(prepareCreate(idxName, 0, Settings.builder().put("number_of_shards", between(1, 20))
164178
.put("number_of_replicas", 0)));
165179
logger.info("--> indexing some data");

x-pack/qa/tribe-tests-with-security/src/test/java/org/elasticsearch/xpack/security/SecurityTribeTests.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public void setUp() throws Exception {
104104
super.setUp();
105105
if (cluster2 == null) {
106106
SecuritySettingsSource cluster2SettingsSource =
107-
new SecuritySettingsSource(defaultMaxNumberOfNodes(), useSSL, createTempDir(), Scope.SUITE) {
107+
new SecuritySettingsSource(useSSL, createTempDir(), Scope.SUITE) {
108108
@Override
109109
public Settings nodeSettings(int nodeOrdinal) {
110110
Settings.Builder builder = Settings.builder()
@@ -239,7 +239,7 @@ protected Collection<Class<? extends Plugin>> nodePlugins() {
239239

240240
private void setupTribeNode(Settings settings) throws Exception {
241241
SecuritySettingsSource cluster2SettingsSource =
242-
new SecuritySettingsSource(1, useSSL, createTempDir(), Scope.TEST) {
242+
new SecuritySettingsSource(useSSL, createTempDir(), Scope.TEST) {
243243
@Override
244244
public Settings nodeSettings(int nodeOrdinal) {
245245
return Settings.builder()

0 commit comments

Comments
 (0)