diff --git a/src/test/java/org/elasticsearch/test/integration/cluster/allocation/AwarenessAllocationTests.java b/src/test/java/org/elasticsearch/test/integration/cluster/allocation/AwarenessAllocationTests.java index a9f0ca25239..745471ec04c 100644 --- a/src/test/java/org/elasticsearch/test/integration/cluster/allocation/AwarenessAllocationTests.java +++ b/src/test/java/org/elasticsearch/test/integration/cluster/allocation/AwarenessAllocationTests.java @@ -133,7 +133,7 @@ public class AwarenessAllocationTests extends AbstractNodesTests { @Test @Slow - @AwaitsFix(bugUrl="simonw works on this") + @AwaitsFix(bugUrl="https://github.com/elasticsearch/elasticsearch/issues/3580") public void testAwarenessZonesIncrementalNodes() throws InterruptedException { Settings commonSettings = ImmutableSettings.settingsBuilder() .put("cluster.routing.allocation.awareness.force.zone.values", "a,b") @@ -141,7 +141,7 @@ public class AwarenessAllocationTests extends AbstractNodesTests { .build(); - logger.info("--> starting 6 nodes on different zones"); + logger.info("--> starting 2 nodes on zones 'a' & 'b'"); startNode("A-0", ImmutableSettings.settingsBuilder().put(commonSettings).put("node.zone", "a")); startNode("B-0", ImmutableSettings.settingsBuilder().put(commonSettings).put("node.zone", "b")); client().admin().indices().prepareCreate("test") @@ -161,10 +161,12 @@ public class AwarenessAllocationTests extends AbstractNodesTests { } assertThat(counts.get("A-0"), equalTo(5)); assertThat(counts.get("B-0"), equalTo(5)); - - startNode("B-1", ImmutableSettings.settingsBuilder().put(commonSettings).put("node.zone", "b")); - Thread.sleep(1000);// TODO this is bad - how can we fix this? + logger.info("--> starting another node in zone 'b'"); + startNode("B-1", ImmutableSettings.settingsBuilder().put(commonSettings).put("node.zone", "b")); + health = client().admin().cluster().prepareHealth().setWaitForEvents(Priority.LANGUID).setWaitForGreenStatus().setWaitForNodes("3").execute().actionGet(); + assertThat(health.isTimedOut(), equalTo(false)); + client().admin().cluster().prepareReroute().get(); health = client().admin().cluster().prepareHealth().setWaitForEvents(Priority.LANGUID).setWaitForGreenStatus().setWaitForNodes("3").setWaitForRelocatingShards(0).execute().actionGet(); assertThat(health.isTimedOut(), equalTo(false)); diff --git a/src/test/java/org/elasticsearch/test/unit/cluster/routing/allocation/AwarenessAllocationTests.java b/src/test/java/org/elasticsearch/test/unit/cluster/routing/allocation/AwarenessAllocationTests.java index 9c0c03590f3..36d06e80c2b 100644 --- a/src/test/java/org/elasticsearch/test/unit/cluster/routing/allocation/AwarenessAllocationTests.java +++ b/src/test/java/org/elasticsearch/test/unit/cluster/routing/allocation/AwarenessAllocationTests.java @@ -20,6 +20,7 @@ package org.elasticsearch.test.unit.cluster.routing.allocation; import com.google.common.collect.ImmutableMap; +import org.apache.lucene.util.LuceneTestCase.AwaitsFix; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.routing.RoutingTable; @@ -754,4 +755,61 @@ public class AwarenessAllocationTests { logger.info("--> do another reroute, make sure nothing moves"); assertThat(strategy.reroute(clusterState).routingTable(), sameInstance(clusterState.routingTable())); } + + @Test + @AwaitsFix(bugUrl="https://github.com/elasticsearch/elasticsearch/issues/3580") + public void testZones() { + AllocationService strategy = new AllocationService(settingsBuilder() + .put("cluster.routing.allocation.awareness.force.zone.values", "a,b") + .put("cluster.routing.allocation.awareness.attributes", "zone") + .put("cluster.routing.allocation.node_concurrent_recoveries", 10) + .put("cluster.routing.allocation.node_initial_primaries_recoveries", 10) + .put("cluster.routing.allocation.allow_rebalance", "always") + .put("cluster.routing.allocation.cluster_concurrent_rebalance", -1) + .build()); + + logger.info("Building initial routing table for 'testZones'"); + + MetaData metaData = newMetaDataBuilder() + .put(newIndexMetaDataBuilder("test").numberOfShards(5).numberOfReplicas(1)) + .build(); + + RoutingTable routingTable = routingTable() + .addAsNew(metaData.index("test")) + .build(); + + ClusterState clusterState = newClusterStateBuilder().metaData(metaData).routingTable(routingTable).build(); + + logger.info("--> adding two nodes on same rack and do rerouting"); + clusterState = newClusterStateBuilder().state(clusterState).nodes(newNodesBuilder() + .put(newNode("A-0", ImmutableMap.of("zone", "a"))) + .put(newNode("B-0", ImmutableMap.of("zone", "b"))) + ).build(); + routingTable = strategy.reroute(clusterState).routingTable(); + clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); + assertThat(clusterState.routingNodes().shardsWithState(STARTED).size(), equalTo(0)); + assertThat(clusterState.routingNodes().shardsWithState(INITIALIZING).size(), equalTo(5)); + + logger.info("--> start the shards (primaries)"); + routingTable = strategy.applyStartedShards(clusterState, clusterState.routingNodes().shardsWithState(INITIALIZING)).routingTable(); + clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); + assertThat(clusterState.routingNodes().shardsWithState(STARTED).size(), equalTo(5)); + assertThat(clusterState.routingNodes().shardsWithState(INITIALIZING).size(), equalTo(5)); + + routingTable = strategy.applyStartedShards(clusterState, clusterState.routingNodes().shardsWithState(INITIALIZING)).routingTable(); + clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); + logger.info("--> replica will not start because we have only one rack value"); + assertThat(clusterState.routingNodes().shardsWithState(STARTED).size(), equalTo(10)); + assertThat(clusterState.routingNodes().shardsWithState(INITIALIZING).size(), equalTo(0)); + + logger.info("--> add a new node in zone 'a' and reroute"); + clusterState = newClusterStateBuilder().state(clusterState).nodes(newNodesBuilder().putAll(clusterState.nodes()) + .put(newNode("A-1", ImmutableMap.of("zone", "a"))) + ).build(); + routingTable = strategy.reroute(clusterState).routingTable(); + clusterState = newClusterStateBuilder().state(clusterState).routingTable(routingTable).build(); + assertThat(clusterState.routingNodes().shardsWithState(ShardRoutingState.STARTED).size(), equalTo(8)); + assertThat(clusterState.routingNodes().shardsWithState(ShardRoutingState.INITIALIZING).size(), equalTo(2)); + assertThat(clusterState.routingNodes().shardsWithState(ShardRoutingState.INITIALIZING).get(0).currentNodeId(), equalTo("A-1")); + } }