From 4f0087f8857415a6098ed5bd768c111f038e52f7 Mon Sep 17 00:00:00 2001 From: Jay J Wylie Date: Fri, 3 May 2013 16:05:18 -0700 Subject: [PATCH] Added unit tests for RebalancePlan and for cluster xform & verification methods in RebalanceUtils RebalancePlanTest - Test the core use cases for rebalance planning: - no-op, - rebalance (zone/node topology same, but partition id layout changed), - cluster expansion (zone topology same, but new nodes added & partitions moved to them), - zone expansion (zone topoloigy changes with partitions moved to new zone). RebalanceController - rename method RebalancePlan - added getters for aggregate plan statistics ServerTestUtils - Changed getLocalZonedCluster to accept array of node IDs. Necessary to generalize other test methods. ClusterInstanceTest - pass storage type into helper methods that construct store defs - chnagned all get???Cluster.*() methods to use new getLocalZonedCluster interface. Also added more such helper methods. RebalanceUtilsTest - Test the cluster transformation & verification methods RepartitionUtilsTest - simple clean up --- .../client/rebalance/RebalanceController.java | 2 +- .../client/rebalance/RebalancePlan.java | 20 ++ .../voldemort/routing/StoreRoutingPlan.java | 3 +- src/java/voldemort/utils/RebalanceUtils.java | 15 +- test/common/voldemort/ServerTestUtils.java | 38 ++-- .../client/rebalance/RebalancePlanTest.java | 143 +++++++++++++ .../voldemort/utils/ClusterInstanceTest.java | 197 +++++++++++++----- .../voldemort/utils/RebalanceUtilsTest.java | 142 ++++++++++++- .../voldemort/utils/RepartitionUtilsTest.java | 19 +- 9 files changed, 493 insertions(+), 86 deletions(-) create mode 100644 test/unit/voldemort/client/rebalance/RebalancePlanTest.java diff --git a/src/java/voldemort/client/rebalance/RebalanceController.java b/src/java/voldemort/client/rebalance/RebalanceController.java index 395683644d..24893879ea 100644 --- a/src/java/voldemort/client/rebalance/RebalanceController.java +++ b/src/java/voldemort/client/rebalance/RebalanceController.java @@ -140,7 +140,7 @@ public void rebalance(Cluster currentCluster, // Do some verification if(!rebalanceConfig.isShowPlanEnabled()) { // Now validate that all the nodes ( new + old ) are in normal state - RebalanceUtils.validateClusterState(newCurrentCluster, adminClient); + RebalanceUtils.validateProdClusterStateIsNormal(newCurrentCluster, adminClient); // Verify all old RO stores exist at version 2 RebalanceUtils.validateReadOnlyStores(newCurrentCluster, storeDefs, adminClient); diff --git a/src/java/voldemort/client/rebalance/RebalancePlan.java b/src/java/voldemort/client/rebalance/RebalancePlan.java index 61cb30313b..1e34bd317c 100644 --- a/src/java/voldemort/client/rebalance/RebalancePlan.java +++ b/src/java/voldemort/client/rebalance/RebalancePlan.java @@ -261,6 +261,26 @@ public List getPlan() { return batchPlans; } + public int getPrimariesMoved() { + return numPrimaryPartitionMoves; + } + + public int getPartitionStoresMoved() { + return numPartitionStoreMoves; + } + + public int getPartitionStoresMovedXZone() { + return numXZonePartitionStoreMoves; + } + + public MoveMap getNodeMoveMap() { + return nodeMoveMap; + } + + public MoveMap getZoneMoveMap() { + return zoneMoveMap; + } + @Override public String toString() { StringBuilder sb = new StringBuilder(); diff --git a/src/java/voldemort/routing/StoreRoutingPlan.java b/src/java/voldemort/routing/StoreRoutingPlan.java index a240f9018a..332bae5c80 100644 --- a/src/java/voldemort/routing/StoreRoutingPlan.java +++ b/src/java/voldemort/routing/StoreRoutingPlan.java @@ -87,7 +87,8 @@ public List getReplicatingPartitionList(int masterPartitionId) { return this.routingStrategy.getReplicatingPartitionList(masterPartitionId); } - // TODO: Add test of this method. + // TODO: Add test for this method (if this method is still required after + // the RebalanceController is updated to use RebalancePlan). /** * * @param nodeId diff --git a/src/java/voldemort/utils/RebalanceUtils.java b/src/java/voldemort/utils/RebalanceUtils.java index 23a8dde4f3..6092187f3a 100644 --- a/src/java/voldemort/utils/RebalanceUtils.java +++ b/src/java/voldemort/utils/RebalanceUtils.java @@ -253,7 +253,8 @@ public static void assertSameDonor(List partitionInfos, * @param adminClient Admin client used to query * @throws VoldemortRebalancingException if any node is not in normal state */ - public static void validateClusterState(final Cluster cluster, final AdminClient adminClient) { + public static void validateProdClusterStateIsNormal(final Cluster cluster, + final AdminClient adminClient) { for(Node node: cluster.getNodes()) { Versioned versioned = adminClient.rebalanceOps.getRemoteServerState(node.getId()); @@ -271,7 +272,6 @@ public static void validateClusterState(final Cluster cluster, final AdminClient } } - // TODO: Add tests for all cluster/store validation methods. /** * Verify store definitions are congruent with cluster definition. * @@ -280,12 +280,11 @@ public static void validateClusterState(final Cluster cluster, final AdminClient */ public static void validateClusterStores(final Cluster cluster, final List storeDefs) { - // This is a hack. But, constructing a PartitionBalance object has - // the (desirable in this case) side-effect of verifying that the store - // definition is congruent with the cluster definition. If there are - // issues, exceptions are thrown. - @SuppressWarnings("unused") - PartitionBalance pb = new PartitionBalance(cluster, storeDefs); + // Constructing a PartitionBalance object has the (desirable in this + // case) side-effect of verifying that the store definition is congruent + // with the cluster definition. If there are issues, exceptions are + // thrown. + new PartitionBalance(cluster, storeDefs); return; } diff --git a/test/common/voldemort/ServerTestUtils.java b/test/common/voldemort/ServerTestUtils.java index 926cc051dd..ca173b4f97 100644 --- a/test/common/voldemort/ServerTestUtils.java +++ b/test/common/voldemort/ServerTestUtils.java @@ -496,32 +496,35 @@ public static Cluster getLocalZonedCluster(int numberOfNodes, * a nodes in numberOfZones zones. It is important that * numberOfNodes be divisible by numberOfZones * + * Does + * * @param numberOfZones The number of zones in the cluster. - * @param nodesPerZone An array of size numberOfZones indicating the - * number of nodes in each zone. - * @param partitionMap An array of size total number of nodes (derived from + * @param nodeIdsPerZone An array of size numberOfZones in which each + * internal array is a node ID. * @param partitionMap An array of size total number of nodes (derived from * nodesPerZone that indicates the specific partitions on each * node. * @return */ + // TODO: Method should eventually accept a list of ZoneIds so that + // non-contig zone Ids can be tested. public static Cluster getLocalZonedCluster(int numberOfZones, - int[] nodesPerZone, + int[][] nodeIdsPerZone, int[][] partitionMap) { if(numberOfZones < 1) { throw new VoldemortException("The number of zones must be positive (" + numberOfZones + ")"); } - if(nodesPerZone.length != numberOfZones) { + if(nodeIdsPerZone.length != numberOfZones) { throw new VoldemortException("Mismatch between numberOfZones (" + numberOfZones - + ") and size of nodesPerZone array (" + nodesPerZone - + ")."); + + ") and size of nodesPerZone array (" + + nodeIdsPerZone.length + ")."); } int numNodes = 0; - for(Integer nodesInZone: nodesPerZone) { - numNodes += nodesInZone; + for(int nodeIdsInZone[]: nodeIdsPerZone) { + numNodes += nodeIdsInZone.length; } if(partitionMap.length != numNodes) { throw new VoldemortException("Mismatch between numNodes (" + numNodes @@ -531,22 +534,21 @@ public static Cluster getLocalZonedCluster(int numberOfZones, // Generate nodes List nodes = new ArrayList(); - int[] ports = findFreePorts(3 * numNodes); - int nodeId = 0; + int partitionMapOffset = 0; for(int zoneId = 0; zoneId < numberOfZones; zoneId++) { - for(int j = 0; j < nodesPerZone[zoneId]; j++) { + for(int nodeId: nodeIdsPerZone[zoneId]) { List partitions = new ArrayList(partitionMap[nodeId].length); - for(int p: partitionMap[nodeId]) { + for(int p: partitionMap[partitionMapOffset]) { partitions.add(p); } nodes.add(new Node(nodeId, - "localhost", - ports[3 * nodeId], - ports[3 * nodeId + 1], - ports[3 * nodeId + 2], + "node-" + nodeId, + 64000, + 64001, + 64002, zoneId, partitions)); - nodeId++; + partitionMapOffset++; } } diff --git a/test/unit/voldemort/client/rebalance/RebalancePlanTest.java b/test/unit/voldemort/client/rebalance/RebalancePlanTest.java new file mode 100644 index 0000000000..1b07000a2b --- /dev/null +++ b/test/unit/voldemort/client/rebalance/RebalancePlanTest.java @@ -0,0 +1,143 @@ +/* + * Copyright 2012-2013 LinkedIn, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package voldemort.client.rebalance; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.Test; + +import voldemort.cluster.Cluster; +import voldemort.store.StoreDefinition; +import voldemort.utils.ClusterInstanceTest; + +public class RebalancePlanTest { + + static Cluster zzCurrent; + static Cluster zzRebalance; + static Cluster zzClusterExpansion; + static List zzStores; + + static Cluster zzzCurrent; + static Cluster zzzRebalance; + static Cluster zzzClusterExpansion; + static Cluster zzzZoneExpansion; + static List zzzStores; + + @BeforeClass + public static void setup() { + zzCurrent = ClusterInstanceTest.getZZCluster(); + zzRebalance = ClusterInstanceTest.getZZClusterWithSwappedPartitions(); + zzClusterExpansion = ClusterInstanceTest.getZZClusterWithPP(); + zzStores = ClusterInstanceTest.getZZStoreDefsBDB(); + + zzzCurrent = ClusterInstanceTest.getZZZCluster(); + + zzzRebalance = ClusterInstanceTest.getZZZClusterWithSwappedPartitions(); + zzzClusterExpansion = ClusterInstanceTest.getZZZClusterWithPPP(); + zzzZoneExpansion = ClusterInstanceTest.getZZEClusterXXP(); + zzzStores = ClusterInstanceTest.getZZZStoreDefsBDB(); + } + + RebalancePlan makePlan(Cluster cCluster, + List cStores, + Cluster fCluster, + List fStores) { + // Defaults for plans + boolean stealerBased = true; + int batchSize = 1000; + String outputDir = null; + + return new RebalancePlan(cCluster, + cStores, + fCluster, + fStores, + stealerBased, + batchSize, + outputDir); + } + + @Test + public void testNoop() { + RebalancePlan rebalancePlan; + + // Two zones + rebalancePlan = makePlan(zzCurrent, zzStores, zzCurrent, zzStores); + assertEquals(rebalancePlan.getPlan().size(), 0); + assertEquals(rebalancePlan.getPrimariesMoved(), 0); + assertEquals(rebalancePlan.getPartitionStoresMoved(), 0); + assertEquals(rebalancePlan.getPartitionStoresMovedXZone(), 0); + + // Three zones + rebalancePlan = makePlan(zzzCurrent, zzzStores, zzzCurrent, zzzStores); + assertEquals(rebalancePlan.getPlan().size(), 0); + assertEquals(rebalancePlan.getPrimariesMoved(), 0); + assertEquals(rebalancePlan.getPartitionStoresMoved(), 0); + assertEquals(rebalancePlan.getPartitionStoresMovedXZone(), 0); + } + + @Test + public void testRebalance() { + RebalancePlan rebalancePlan; + + // Two zones + rebalancePlan = makePlan(zzCurrent, zzStores, zzRebalance, zzStores); + assertEquals(rebalancePlan.getPlan().size(), 1); + assertTrue(rebalancePlan.getPrimariesMoved() > 0); + assertTrue(rebalancePlan.getPartitionStoresMoved() > 0); + assertEquals(rebalancePlan.getPartitionStoresMovedXZone(), 0); + + // Three zones + rebalancePlan = makePlan(zzzCurrent, zzzStores, zzzRebalance, zzzStores); + assertEquals(rebalancePlan.getPlan().size(), 1); + assertTrue(rebalancePlan.getPrimariesMoved() > 0); + assertTrue(rebalancePlan.getPartitionStoresMoved() > 0); + assertEquals(rebalancePlan.getPartitionStoresMovedXZone(), 0); + } + + @Test + public void testClusterExpansion() { + RebalancePlan rebalancePlan; + + // Two zones + rebalancePlan = makePlan(zzCurrent, zzStores, zzClusterExpansion, zzStores); + assertEquals(rebalancePlan.getPlan().size(), 1); + assertTrue(rebalancePlan.getPrimariesMoved() > 0); + assertTrue(rebalancePlan.getPartitionStoresMoved() > 0); + assertEquals(rebalancePlan.getPartitionStoresMovedXZone(), 0); + + // Three zones + rebalancePlan = makePlan(zzzCurrent, zzzStores, zzzClusterExpansion, zzzStores); + assertEquals(rebalancePlan.getPlan().size(), 1); + assertTrue(rebalancePlan.getPrimariesMoved() > 0); + assertTrue(rebalancePlan.getPartitionStoresMoved() > 0); + assertEquals(rebalancePlan.getPartitionStoresMovedXZone(), 0); + } + + @Test + public void testZoneExpansion() { + RebalancePlan rebalancePlan; + + rebalancePlan = makePlan(zzCurrent, zzStores, zzzZoneExpansion, zzzStores); + assertEquals(rebalancePlan.getPlan().size(), 1); + assertTrue(rebalancePlan.getPrimariesMoved() > 0); + assertTrue(rebalancePlan.getPartitionStoresMoved() > 0); + assertTrue(rebalancePlan.getPartitionStoresMovedXZone() > 0); + } +} diff --git a/test/unit/voldemort/utils/ClusterInstanceTest.java b/test/unit/voldemort/utils/ClusterInstanceTest.java index 5135d3bea8..3ab67cfa42 100644 --- a/test/unit/voldemort/utils/ClusterInstanceTest.java +++ b/test/unit/voldemort/utils/ClusterInstanceTest.java @@ -36,6 +36,7 @@ import voldemort.serialization.SerializerDefinition; import voldemort.store.StoreDefinition; import voldemort.store.StoreDefinitionBuilder; +import voldemort.store.bdb.BdbStorageConfiguration; import voldemort.store.memory.InMemoryStorageConfiguration; import com.google.common.collect.Lists; @@ -67,14 +68,14 @@ public class ClusterInstanceTest { // TODO: Move these storeDefs and cluster helper test methods into // ClusterTestUtils. - public static List getZZ111StoreDefs() { + public static List getZZ111StoreDefs(String storageType) { List storeDefs = new LinkedList(); HashMap zoneRep111 = new HashMap(); zoneRep111.put(0, 1); zoneRep111.put(1, 1); StoreDefinition storeDef111 = new StoreDefinitionBuilder().setName("ZZ111") - .setType(InMemoryStorageConfiguration.TYPE_NAME) + .setType(storageType) .setRoutingPolicy(RoutingTier.CLIENT) .setRoutingStrategyType(RoutingStrategyType.ZONE_STRATEGY) .setKeySerializer(new SerializerDefinition("string")) @@ -90,14 +91,14 @@ public static List getZZ111StoreDefs() { return storeDefs; } - public static List getZZ211StoreDefs() { + public static List getZZ211StoreDefs(String storageType) { List storeDefs = new LinkedList(); HashMap zoneRep211 = new HashMap(); zoneRep211.put(0, 2); zoneRep211.put(1, 2); StoreDefinition storeDef211 = new StoreDefinitionBuilder().setName("ZZ211") - .setType(InMemoryStorageConfiguration.TYPE_NAME) + .setType(storageType) .setRoutingPolicy(RoutingTier.CLIENT) .setRoutingStrategyType(RoutingStrategyType.ZONE_STRATEGY) .setKeySerializer(new SerializerDefinition("string")) @@ -113,14 +114,14 @@ public static List getZZ211StoreDefs() { return storeDefs; } - public static List getZZ322StoreDefs() { + public static List getZZ322StoreDefs(String storageType) { List storeDefs = new LinkedList(); HashMap zoneRep322 = new HashMap(); zoneRep322.put(0, 3); zoneRep322.put(1, 3); StoreDefinition storeDef322 = new StoreDefinitionBuilder().setName("ZZ322") - .setType(InMemoryStorageConfiguration.TYPE_NAME) + .setType(storageType) .setRoutingPolicy(RoutingTier.CLIENT) .setRoutingStrategyType(RoutingStrategyType.ZONE_STRATEGY) .setKeySerializer(new SerializerDefinition("string")) @@ -140,15 +141,23 @@ public static List getZZ322StoreDefs() { * Store defs for zoned clusters with 2 zones. Covers the three store * definitions of interest: 3/2/2, 2/1/1, and */ - public static List getZZStoreDefs() { + public static List getZZStoreDefsInMemory() { List storeDefs = new LinkedList(); - storeDefs.addAll(getZZ111StoreDefs()); - storeDefs.addAll(getZZ211StoreDefs()); - storeDefs.addAll(getZZ322StoreDefs()); + storeDefs.addAll(getZZ111StoreDefs(InMemoryStorageConfiguration.TYPE_NAME)); + storeDefs.addAll(getZZ211StoreDefs(InMemoryStorageConfiguration.TYPE_NAME)); + storeDefs.addAll(getZZ322StoreDefs(InMemoryStorageConfiguration.TYPE_NAME)); return storeDefs; } - public static List getZZZ111StoreDefs() { + public static List getZZStoreDefsBDB() { + List storeDefs = new LinkedList(); + storeDefs.addAll(getZZ111StoreDefs(BdbStorageConfiguration.TYPE_NAME)); + storeDefs.addAll(getZZ211StoreDefs(BdbStorageConfiguration.TYPE_NAME)); + storeDefs.addAll(getZZ322StoreDefs(BdbStorageConfiguration.TYPE_NAME)); + return storeDefs; + } + + public static List getZZZ111StoreDefs(String storageType) { List storeDefs = new LinkedList(); HashMap zoneRep111 = new HashMap(); @@ -156,7 +165,7 @@ public static List getZZZ111StoreDefs() { zoneRep111.put(1, 1); zoneRep111.put(2, 1); StoreDefinition storeDef111 = new StoreDefinitionBuilder().setName("ZZ111") - .setType(InMemoryStorageConfiguration.TYPE_NAME) + .setType(storageType) .setRoutingPolicy(RoutingTier.CLIENT) .setRoutingStrategyType(RoutingStrategyType.ZONE_STRATEGY) .setKeySerializer(new SerializerDefinition("string")) @@ -172,7 +181,7 @@ public static List getZZZ111StoreDefs() { return storeDefs; } - public static List getZZZ211StoreDefs() { + public static List getZZZ211StoreDefs(String storageType) { List storeDefs = new LinkedList(); HashMap zoneRep211 = new HashMap(); @@ -180,7 +189,7 @@ public static List getZZZ211StoreDefs() { zoneRep211.put(1, 2); zoneRep211.put(2, 2); StoreDefinition storeDef211 = new StoreDefinitionBuilder().setName("ZZ211") - .setType(InMemoryStorageConfiguration.TYPE_NAME) + .setType(storageType) .setRoutingPolicy(RoutingTier.CLIENT) .setRoutingStrategyType(RoutingStrategyType.ZONE_STRATEGY) .setKeySerializer(new SerializerDefinition("string")) @@ -196,7 +205,7 @@ public static List getZZZ211StoreDefs() { return storeDefs; } - public static List getZZZ322StoreDefs() { + public static List getZZZ322StoreDefs(String storageType) { List storeDefs = new LinkedList(); HashMap zoneRep322 = new HashMap(); @@ -204,7 +213,7 @@ public static List getZZZ322StoreDefs() { zoneRep322.put(1, 3); zoneRep322.put(2, 3); StoreDefinition storeDef322 = new StoreDefinitionBuilder().setName("ZZ322") - .setType(InMemoryStorageConfiguration.TYPE_NAME) + .setType(storageType) .setRoutingPolicy(RoutingTier.CLIENT) .setRoutingStrategyType(RoutingStrategyType.ZONE_STRATEGY) .setKeySerializer(new SerializerDefinition("string")) @@ -224,11 +233,19 @@ public static List getZZZ322StoreDefs() { * Store defs for zoned clusters with 2 zones. Covers the three store * definitions of interest: 3/2/2, 2/1/1, and */ - public static List getZZZStoreDefs() { + public static List getZZZStoreDefsInMemory() { + List storeDefs = new LinkedList(); + storeDefs.addAll(getZZZ111StoreDefs(InMemoryStorageConfiguration.TYPE_NAME)); + storeDefs.addAll(getZZZ211StoreDefs(InMemoryStorageConfiguration.TYPE_NAME)); + storeDefs.addAll(getZZZ322StoreDefs(InMemoryStorageConfiguration.TYPE_NAME)); + return storeDefs; + } + + public static List getZZZStoreDefsBDB() { List storeDefs = new LinkedList(); - storeDefs.addAll(getZZZ111StoreDefs()); - storeDefs.addAll(getZZZ211StoreDefs()); - storeDefs.addAll(getZZZ322StoreDefs()); + storeDefs.addAll(getZZZ111StoreDefs(BdbStorageConfiguration.TYPE_NAME)); + storeDefs.addAll(getZZZ211StoreDefs(BdbStorageConfiguration.TYPE_NAME)); + storeDefs.addAll(getZZZ322StoreDefs(BdbStorageConfiguration.TYPE_NAME)); return storeDefs; } @@ -243,23 +260,47 @@ public static List getZZZStoreDefs() { */ public static Cluster getZZCluster() { int numberOfZones = 2; - int nodesPerZone[] = new int[] { 3, 3 }; + int nodesPerZone[][] = new int[][] { { 0, 1, 2 }, { 3, 4, 5 } }; int partitionMap[][] = new int[][] { { 0, 6, 12, 16, 17 }, { 1, 7, 15 }, { 2, 8, 14 }, { 3, 9, 13 }, { 4, 10 }, { 5, 11 } }; return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); } + public static Cluster getZZClusterWithExtraPartitions() { + int numberOfZones = 2; + int nodesPerZone[][] = new int[][] { { 0, 1, 2 }, { 3, 4, 5 } }; + int partitionMap[][] = new int[][] { { 0, 6, 12, 16, 17 }, { 1, 7, 15 }, { 2, 8, 14 }, + { 3, 9, 13 }, { 4, 10 }, { 5, 11, 18 } }; + return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); + } + + public static Cluster getZZClusterWithSwappedPartitions() { + int numberOfZones = 2; + int nodesPerZone[][] = new int[][] { { 0, 1, 2 }, { 3, 4, 5 } }; + int partitionMap[][] = new int[][] { { 0, 6, 16, 17 }, { 1, 7, 15 }, { 2, 8, 11, 14 }, + { 3, 9, 13 }, { 4, 10 }, { 5, 12 } }; + return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); + } + public static Cluster getZZZCluster() { int numberOfZones = 3; - int nodesPerZone[] = new int[] { 3, 3, 3 }; + int nodesPerZone[][] = new int[][] { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 } }; int partitionMap[][] = new int[][] { { 0, 9, 15, 16, 17 }, { 1, 10 }, { 2, 11 }, { 3, 12 }, { 4, 13 }, { 5, 14 }, { 6 }, { 7 }, { 8 } }; return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); } + public static Cluster getZZZClusterWithSwappedPartitions() { + int numberOfZones = 3; + int nodesPerZone[][] = new int[][] { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 } }; + int partitionMap[][] = new int[][] { { 0, 9, 17 }, { 1, 10 }, { 2, 11 }, { 3, 12 }, + { 4, 13 }, { 5, 14 }, { 6 }, { 7, 15 }, { 8, 16 } }; + return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); + } + public static Cluster getZECluster() { int numberOfZones = 2; - int nodesPerZone[] = new int[] { 3, 3 }; + int nodesPerZone[][] = new int[][] { { 0, 1, 2 }, { 3, 4, 5 } }; int partitionMap[][] = new int[][] { { 0, 1, 6, 7, 12, 13, 16, 17 }, { 2, 3, 8, 9, 14, 15 }, { 4, 5, 10, 11 }, {}, {}, {} }; return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); @@ -267,27 +308,43 @@ public static Cluster getZECluster() { public static Cluster getZEZCluster() { int numberOfZones = 3; - int nodesPerZone[] = new int[] { 3, 3, 3 }; + int nodesPerZone[][] = new int[][] { { 0, 1, 2 }, { 6, 7, 8 }, { 3, 4, 5 } }; int partitionMap[][] = new int[][] { { 0, 9, 6, 17 }, { 1, 10, 15 }, { 2, 11, 7 }, {}, {}, {}, { 3, 12, 16 }, { 4, 13, 8 }, { 5, 14 } }; return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); } + public static Cluster getZZECluster() { + int numberOfZones = 3; + int nodesPerZone[][] = new int[][] { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 } }; + int partitionMap[][] = new int[][] { { 0, 6, 12, 16, 17 }, { 1, 7, 15 }, { 2, 8, 14 }, + { 3, 9, 13 }, { 4, 10 }, { 5, 11 }, {}, {}, {} }; + return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); + } + /** * The 'N' and 'X' suffixes indicate whether there are nodes added in a zone * ('N') or not ('X'). By definition, an 'E' zone is labeled with 'N. */ public static Cluster getZZClusterWithNN() { int numberOfZones = 2; - int nodesPerZone[] = new int[] { 4, 4 }; - int partitionMap[][] = new int[][] { { 0, 6, 12, 16, 17 }, { 1, 7, 13 }, { 2, 8, 14 }, {}, - { 3, 9, 15 }, { 4, 10 }, { 5, 11 }, {} }; + int nodesPerZone[][] = new int[][] { { 0, 1, 2, 6 }, { 3, 4, 5, 7 } }; + int partitionMap[][] = new int[][] { { 0, 6, 12, 16, 17 }, { 1, 7, 15 }, { 2, 8, 14 }, {}, + { 3, 9, 13 }, { 4, 10 }, { 5, 11 }, {} }; + return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); + } + + public static Cluster getZZClusterWithNNWithSwappedNodeIds() { + int numberOfZones = 2; + int nodesPerZone[][] = new int[][] { { 0, 1, 6, 2 }, { 3, 4, 5, 7 } }; + int partitionMap[][] = new int[][] { { 0, 6, 12, 16, 17 }, { 1, 7, 15 }, { 2, 8, 14 }, {}, + { 3, 9, 13 }, { 4, 10 }, { 5, 11 }, {} }; return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); } public static Cluster getZZZClusterWithNNN() { int numberOfZones = 3; - int nodesPerZone[] = new int[] { 4, 4, 4 }; + int nodesPerZone[][] = new int[][] { { 0, 1, 2, 9 }, { 3, 4, 5, 10 }, { 6, 7, 8, 11 } }; int partitionMap[][] = new int[][] { { 0, 9, 15, 16, 17 }, { 1, 10 }, { 2, 11 }, {}, { 3, 12 }, { 4, 13 }, { 5, 14 }, {}, { 6 }, { 7 }, { 8 }, {} }; return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); @@ -295,17 +352,62 @@ public static Cluster getZZZClusterWithNNN() { public static Cluster getZEZClusterWithXNN() { int numberOfZones = 3; - int nodesPerZone[] = new int[] { 3, 3, 4 }; + int nodesPerZone[][] = new int[][] { { 0, 1, 2 }, { 6, 7, 8 }, { 3, 4, 5, 9 } }; int partitionMap[][] = new int[][] { { 0, 9, 6, 17 }, { 1, 10, 15 }, { 2, 11, 7 }, {}, {}, {}, { 3, 12, 16 }, { 4, 13, 8 }, { 5, 14 }, {} }; return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); } - public static Cluster getZZECluster() { + /** + * The 'P' and 'X' suffixes indicate whether there are nodes added in a zone + * ('N') that have been populated with partitions. ('X' indicates no new + * nodes in zone). + */ + public static Cluster getZZClusterWithPP() { + int numberOfZones = 2; + int nodesPerZone[][] = new int[][] { { 0, 1, 2, 6 }, { 3, 4, 5, 7 } }; + int partitionMap[][] = new int[][] { { 0, 6, 12, 16, 17 }, { 7, 13 }, { 8, 14 }, { 1, 2 }, + { 9, 15 }, { 10 }, { 5, 11 }, { 3, 4 } }; + return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); + } + + public static Cluster getZZClusterWithPPWithSwappedNodeIds() { + int numberOfZones = 2; + int nodesPerZone[][] = new int[][] { { 0, 1, 6, 2 }, { 3, 4, 5, 7 } }; + int partitionMap[][] = new int[][] { { 0, 6, 12, 16, 17 }, { 7, 13 }, { 8, 14 }, { 1, 2 }, + { 9, 15 }, { 10 }, { 5, 11 }, { 3, 4 } }; + return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); + } + + public static Cluster getZZClusterWithPPWithTooManyNodes() { + int numberOfZones = 2; + int nodesPerZone[][] = new int[][] { { 0, 1, 6, 2 }, { 3, 4, 5, 7, 8 } }; + int partitionMap[][] = new int[][] { { 0, 6, 12, 16, 17 }, { 7, 13 }, { 8, 14 }, { 1, 2 }, + { 9, 15 }, { 10 }, { 5, 11 }, { 3 }, { 4 } }; + return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); + } + + public static Cluster getZZZClusterWithPPP() { + int numberOfZones = 3; + int nodesPerZone[][] = new int[][] { { 0, 1, 2, 9 }, { 3, 4, 5, 10 }, { 6, 7, 8, 11 } }; + int partitionMap[][] = new int[][] { { 0, 15, 16, 17 }, { 1, 10 }, { 11 }, { 2 }, { 12 }, + { 4, 13 }, { 5, 14 }, { 3 }, { 6 }, { 7 }, { 8 }, { 9 } }; + return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); + } + + public static Cluster getZEZClusterWithXPP() { + int numberOfZones = 3; + int nodesPerZone[][] = new int[][] { { 0, 1, 2 }, { 6, 7, 8 }, { 3, 4, 5, 9 } }; + int partitionMap[][] = new int[][] { { 0, 17 }, { 1, 15 }, { 2, 11, 7 }, { 6 }, { 9 }, + { 10 }, { 3, 12, 16 }, { 4, 8 }, { 5, 14 }, { 13 } }; + return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); + } + + public static Cluster getZZEClusterXXP() { int numberOfZones = 3; - int nodesPerZone[] = new int[] { 3, 3, 3 }; - int partitionMap[][] = new int[][] { { 0, 6, 12, 16, 17 }, { 1, 7, 13 }, { 2, 8, 14 }, - { 3, 9, 15 }, { 4, 10 }, { 5, 11 }, {}, {}, {} }; + int nodesPerZone[][] = new int[][] { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 } }; + int partitionMap[][] = new int[][] { { 16, 17 }, { 1, 13 }, { 8, 14 }, { 3, 15 }, + { 4, 10 }, { 5, 11 }, { 0, 6 }, { 2, 12 }, { 7, 9 } }; return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); } @@ -315,7 +417,7 @@ public static Cluster getZZECluster() { */ public static Cluster getZEZClusterWithOnlyOneNodeInNewZone() { int numberOfZones = 3; - int nodesPerZone[] = new int[] { 3, 1, 3 }; + int nodesPerZone[][] = new int[][] { { 0, 1, 2 }, { 6 }, { 3, 4, 5 } }; int partitionMap[][] = new int[][] { { 0, 9, 6, 17 }, { 1, 10, 15 }, { 2, 11, 7 }, {}, { 3, 12, 16 }, { 4, 13, 8 }, { 5, 14 } }; return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); @@ -323,7 +425,7 @@ public static Cluster getZEZClusterWithOnlyOneNodeInNewZone() { public static Cluster getZZZClusterWithOnlyOneNodeInNewZone() { int numberOfZones = 3; - int nodesPerZone[] = new int[] { 3, 1, 3 }; + int nodesPerZone[][] = new int[][] { { 0, 1, 2 }, { 6 }, { 3, 4, 5 } }; int partitionMap[][] = new int[][] { { 0, 9, 6, 17 }, { 1, 10, 15 }, { 2, 11, 7 }, { 14 }, { 3, 12, 16 }, { 4, 13, 8 }, { 5 } }; return ServerTestUtils.getLocalZonedCluster(numberOfZones, nodesPerZone, partitionMap); @@ -402,10 +504,10 @@ public static Cluster getZZClusterWithNonContiguousZoneIDsAndNonContiguousNodeID public void testBasicThingsThatShouldWork() { ClusterInstance ci; - ci = new ClusterInstance(getZZCluster(), getZZStoreDefs()); + ci = new ClusterInstance(getZZCluster(), getZZStoreDefsInMemory()); ci.getPartitionBalance(); - ci = new ClusterInstance(getZZZCluster(), getZZZStoreDefs()); + ci = new ClusterInstance(getZZZCluster(), getZZZStoreDefsInMemory()); ci.getPartitionBalance(); } @@ -413,13 +515,13 @@ public void testBasicThingsThatShouldWork() { public void testEmptyZoneThingsThatShouldWork() { ClusterInstance ci; - ci = new ClusterInstance(getZECluster(), getZZStoreDefs()); + ci = new ClusterInstance(getZECluster(), getZZStoreDefsInMemory()); ci.getPartitionBalance(); - ci = new ClusterInstance(getZEZCluster(), getZZZStoreDefs()); + ci = new ClusterInstance(getZEZCluster(), getZZZStoreDefsInMemory()); ci.getPartitionBalance(); - ci = new ClusterInstance(getZEZClusterWithOnlyOneNodeInNewZone(), getZZZStoreDefs()); + ci = new ClusterInstance(getZEZClusterWithOnlyOneNodeInNewZone(), getZZZStoreDefsInMemory()); ci.getPartitionBalance(); } @@ -427,10 +529,10 @@ public void testEmptyZoneThingsThatShouldWork() { public void testNewNodeThingsThatShouldWork() { ClusterInstance ci; - ci = new ClusterInstance(getZZClusterWithNN(), getZZStoreDefs()); + ci = new ClusterInstance(getZZClusterWithNN(), getZZStoreDefsInMemory()); ci.getPartitionBalance(); - ci = new ClusterInstance(getZEZClusterWithXNN(), getZZZStoreDefs()); + ci = new ClusterInstance(getZEZClusterWithXNN(), getZZZStoreDefsInMemory()); ci.getPartitionBalance(); } @@ -441,7 +543,7 @@ public void testClusterStoreZoneCountMismatch() { veCaught = false; try { - ci = new ClusterInstance(getZZCluster(), getZZZStoreDefs()); + ci = new ClusterInstance(getZZCluster(), getZZZStoreDefsInMemory()); ci.getPartitionBalance(); } catch(VoldemortException ve) { veCaught = true; @@ -450,7 +552,7 @@ public void testClusterStoreZoneCountMismatch() { veCaught = false; try { - ci = new ClusterInstance(getZZZCluster(), getZZStoreDefs()); + ci = new ClusterInstance(getZZZCluster(), getZZStoreDefsInMemory()); ci.getPartitionBalance(); } catch(VoldemortException ve) { veCaught = true; @@ -464,7 +566,8 @@ public void testClusterWithZoneThatCannotFullyReplicate() { boolean veCaught = false; try { - ci = new ClusterInstance(getZZZClusterWithOnlyOneNodeInNewZone(), getZZZStoreDefs()); + ci = new ClusterInstance(getZZZClusterWithOnlyOneNodeInNewZone(), + getZZZStoreDefsInMemory()); ci.getPartitionBalance(); } catch(VoldemortException ve) { veCaught = true; @@ -481,7 +584,7 @@ public void testNonContiguousZonesThatShouldWork() { ClusterInstance ci; ci = new ClusterInstance(getZZClusterWithNonContiguousZoneIDsButContiguousNodeIDs(), - getZZStoreDefs()); + getZZStoreDefsInMemory()); ci.getPartitionBalance(); } @@ -498,7 +601,7 @@ public void testNonContiguousZonesThatShouldWorkButDoNot() { boolean veCaught = false; try { ci = new ClusterInstance(getZZClusterWithNonContiguousZoneIDsAndNonContiguousNodeIDs(), - getZZStoreDefs()); + getZZStoreDefsInMemory()); ci.getPartitionBalance(); } catch(VoldemortException ve) { veCaught = true; diff --git a/test/unit/voldemort/utils/RebalanceUtilsTest.java b/test/unit/voldemort/utils/RebalanceUtilsTest.java index 95be5d585d..b4ff6fd579 100644 --- a/test/unit/voldemort/utils/RebalanceUtilsTest.java +++ b/test/unit/voldemort/utils/RebalanceUtilsTest.java @@ -16,18 +16,25 @@ package voldemort.utils; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import java.util.ArrayList; import java.util.List; -import junit.framework.TestCase; +import org.junit.Test; + import voldemort.ServerTestUtils; +import voldemort.VoldemortException; import voldemort.cluster.Cluster; import voldemort.cluster.Node; import com.google.common.collect.Lists; -public class RebalanceUtilsTest extends TestCase { +public class RebalanceUtilsTest { + @Test public void testUpdateCluster() { Cluster currentCluster = ServerTestUtils.getLocalCluster(2, new int[][] { { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, {} }); @@ -39,6 +46,7 @@ public void testUpdateCluster() { assertEquals("updated cluster should match targetCluster", updatedCluster, targetCluster); } + @Test public void testGetNodeIds() { List nodes = Lists.newArrayList(); @@ -51,6 +59,7 @@ public void testGetNodeIds() { assertEquals(NodeUtils.getNodeIds(nodes).get(0).intValue(), 0); } + @Test public void testGetClusterWithNewNodes() { Cluster cluster = ServerTestUtils.getLocalCluster(2, 10, 1); @@ -76,7 +85,136 @@ public void testGetClusterWithNewNodes() { cluster.getNodeById(1).getPartitionIds()), true); assertEquals(generatedCluster.getNodeById(2).getPartitionIds().size(), 0); assertEquals(generatedCluster.getNodeById(3).getPartitionIds().size(), 0); + } + + private void doClusterTransformationBase(Cluster currentC, + Cluster targetC, + Cluster finalC, + boolean verify) { + Cluster derivedTarget1 = RebalanceUtils.getClusterWithNewNodes(currentC, targetC); + if(verify) + assertEquals(targetC, derivedTarget1); + + Cluster derivedTarget2 = RebalanceUtils.getTargetCluster(currentC, finalC); + if(verify) + assertEquals(targetC, derivedTarget2); + + RebalanceUtils.validateCurrentFinalCluster(currentC, finalC); + RebalanceUtils.validateCurrentTargetCluster(currentC, targetC); + RebalanceUtils.validateTargetFinalCluster(targetC, finalC); + } + + private void doClusterTransformation(Cluster currentC, Cluster targetC, Cluster finalC) { + doClusterTransformationBase(currentC, targetC, finalC, false); + } + + public void doClusterTransformationAndVerification(Cluster currentC, + Cluster targetC, + Cluster finalC) { + doClusterTransformationBase(currentC, targetC, finalC, true); + } + + @Test + public void testClusterTransformationAndVerification() { + // Two-zone cluster: no-op + doClusterTransformationAndVerification(ClusterInstanceTest.getZZCluster(), + ClusterInstanceTest.getZZCluster(), + ClusterInstanceTest.getZZCluster()); + + // Two-zone cluster: rebalance + doClusterTransformationAndVerification(ClusterInstanceTest.getZZCluster(), + ClusterInstanceTest.getZZCluster(), + ClusterInstanceTest.getZZClusterWithSwappedPartitions()); + + // Two-zone cluster: cluster expansion + doClusterTransformationAndVerification(ClusterInstanceTest.getZZCluster(), + ClusterInstanceTest.getZZClusterWithNN(), + ClusterInstanceTest.getZZClusterWithPP()); + // Three-zone cluster: no-op + doClusterTransformationAndVerification(ClusterInstanceTest.getZZZCluster(), + ClusterInstanceTest.getZZZCluster(), + ClusterInstanceTest.getZZZCluster()); + + // Three-zone cluster: rebalance + doClusterTransformationAndVerification(ClusterInstanceTest.getZZZCluster(), + ClusterInstanceTest.getZZZCluster(), + ClusterInstanceTest.getZZZClusterWithSwappedPartitions()); + + // Three-zone cluster: cluster expansion + doClusterTransformationAndVerification(ClusterInstanceTest.getZZZCluster(), + ClusterInstanceTest.getZZZClusterWithNNN(), + ClusterInstanceTest.getZZZClusterWithPPP()); + + // TODO: Fix this test to pass. This test currently fails because the + // method RebalanceUtils.getClusterWithNewNodes cannot handle a new zone + // coming into existence between currentCluster & targetCluster. + // Two- to Three-zone clusters: zone expansion + /*- + doClusterTransformationAndVerification(ClusterInstanceTest.getZZCluster(), + ClusterInstanceTest.getZZECluster(), + ClusterInstanceTest.getZZEClusterXXP()); + */ } + @Test + public void testClusterTransformationAndVerificationExceptions() { + boolean excepted; + + // Two-zone cluster: rebalance with extra partitions in target + excepted = false; + try { + doClusterTransformation(ClusterInstanceTest.getZZCluster(), + ClusterInstanceTest.getZZClusterWithExtraPartitions(), + ClusterInstanceTest.getZZClusterWithSwappedPartitions()); + } catch(VoldemortException ve) { + excepted = true; + } + assertTrue(excepted); + + // Two-zone cluster: rebalance with extra partitions in final + excepted = false; + try { + doClusterTransformation(ClusterInstanceTest.getZZCluster(), + ClusterInstanceTest.getZZCluster(), + ClusterInstanceTest.getZZClusterWithExtraPartitions()); + } catch(VoldemortException ve) { + excepted = true; + } + assertTrue(excepted); + + // Two-zone cluster: node ids swapped in target + excepted = false; + try { + doClusterTransformation(ClusterInstanceTest.getZZCluster(), + ClusterInstanceTest.getZZClusterWithNNWithSwappedNodeIds(), + ClusterInstanceTest.getZZClusterWithPP()); + } catch(VoldemortException ve) { + excepted = true; + } + assertTrue(excepted); + + // Two-zone cluster: node ids swapped in final is OK because this is the + // same as partitions being migrated among nodes. + excepted = false; + try { + doClusterTransformation(ClusterInstanceTest.getZZCluster(), + ClusterInstanceTest.getZZClusterWithNN(), + ClusterInstanceTest.getZZClusterWithPPWithSwappedNodeIds()); + } catch(VoldemortException ve) { + excepted = true; + } + assertFalse(excepted); + + // Two-zone cluster: too many node ids in final + excepted = false; + try { + doClusterTransformation(ClusterInstanceTest.getZZCluster(), + ClusterInstanceTest.getZZClusterWithNN(), + ClusterInstanceTest.getZZClusterWithPPWithTooManyNodes()); + } catch(VoldemortException ve) { + excepted = true; + } + assertTrue(excepted); + } } diff --git a/test/unit/voldemort/utils/RepartitionUtilsTest.java b/test/unit/voldemort/utils/RepartitionUtilsTest.java index ae2c997fe4..0eb6e30308 100644 --- a/test/unit/voldemort/utils/RepartitionUtilsTest.java +++ b/test/unit/voldemort/utils/RepartitionUtilsTest.java @@ -364,7 +364,7 @@ public void verifyGreedySwapsImproveBalance(Cluster currentCluster, public void testRebalance() { // Two zone cluster Cluster currentCluster = ClusterInstanceTest.getZZCluster(); - List storeDefs = ClusterInstanceTest.getZZStoreDefs(); + List storeDefs = ClusterInstanceTest.getZZStoreDefsInMemory(); verifyBalanceZoneAndNode(currentCluster, storeDefs, currentCluster, storeDefs); verifyBalanceNodesNotZones(currentCluster, storeDefs, currentCluster, storeDefs); verifyRepartitionNoop(currentCluster, storeDefs, currentCluster, storeDefs); @@ -373,7 +373,7 @@ public void testRebalance() { // Three zone cluster currentCluster = ClusterInstanceTest.getZZZCluster(); - storeDefs = ClusterInstanceTest.getZZZStoreDefs(); + storeDefs = ClusterInstanceTest.getZZZStoreDefsInMemory(); verifyBalanceZoneAndNode(currentCluster, storeDefs, currentCluster, storeDefs); verifyBalanceNodesNotZones(currentCluster, storeDefs, currentCluster, storeDefs); verifyRepartitionNoop(currentCluster, storeDefs, currentCluster, storeDefs); @@ -386,7 +386,7 @@ public void testClusterExpansion() { // Two zone cluster Cluster currentCluster = ClusterInstanceTest.getZZCluster(); Cluster targetCluster = ClusterInstanceTest.getZZClusterWithNN(); - List storeDefs = ClusterInstanceTest.getZZStoreDefs(); + List storeDefs = ClusterInstanceTest.getZZStoreDefsInMemory(); verifyBalanceZoneAndNode(currentCluster, storeDefs, targetCluster, storeDefs); verifyBalanceNodesNotZones(currentCluster, storeDefs, targetCluster, storeDefs); verifyRepartitionNoop(currentCluster, storeDefs, targetCluster, storeDefs); @@ -394,7 +394,7 @@ public void testClusterExpansion() { // Three zone cluster currentCluster = ClusterInstanceTest.getZZZCluster(); targetCluster = ClusterInstanceTest.getZZZClusterWithNNN(); - storeDefs = ClusterInstanceTest.getZZZStoreDefs(); + storeDefs = ClusterInstanceTest.getZZZStoreDefsInMemory(); verifyBalanceZoneAndNode(currentCluster, storeDefs, targetCluster, storeDefs); verifyBalanceNodesNotZones(currentCluster, storeDefs, targetCluster, storeDefs); verifyRepartitionNoop(currentCluster, storeDefs, targetCluster, storeDefs); @@ -403,10 +403,10 @@ public void testClusterExpansion() { @Test public void testZoneExpansion() { Cluster currentCluster = ClusterInstanceTest.getZZCluster(); - List currentStoreDefs = ClusterInstanceTest.getZZStoreDefs(); + List currentStoreDefs = ClusterInstanceTest.getZZStoreDefsInMemory(); Cluster targetCluster = ClusterInstanceTest.getZZZClusterWithNNN(); - List targetStoreDefs = ClusterInstanceTest.getZZZStoreDefs(); + List targetStoreDefs = ClusterInstanceTest.getZZZStoreDefsInMemory(); verifyBalanceZoneAndNode(currentCluster, currentStoreDefs, targetCluster, targetStoreDefs); // verifyBalanceNodesNotZones does not make sense for zone expansion. @@ -479,21 +479,22 @@ public void decontigRepartition(Cluster currentCluster, List cu public void testDeContig() { // Two zone cluster Cluster currentCluster = ClusterInstanceTest.getZZCluster(); - List storeDefs = ClusterInstanceTest.getZZStoreDefs(); + List storeDefs = ClusterInstanceTest.getZZStoreDefsInMemory(); decontigRepartition(currentCluster, storeDefs); // Three zone cluster currentCluster = ClusterInstanceTest.getZZZCluster(); - storeDefs = ClusterInstanceTest.getZZZStoreDefs(); + storeDefs = ClusterInstanceTest.getZZZStoreDefsInMemory(); decontigRepartition(currentCluster, storeDefs); } + // TODO: Switch from numberOfZones to a set of zoneIds // TODO: Create a ClusterTest or ClusterUtilsTest and add this test to that // class/file @Test public void testGetMapOfContiguousPartitionRunLengths() { int numberOfZones = 2; - int nodesPerZone[] = new int[] { 3, 3 }; + int nodesPerZone[][] = new int[][] { { 0, 1, 2 }, { 3, 4, 5 } }; int partitionMap[][] = new int[][] { { 0, 6, 12, 16, 17 }, { 1, 7, 15 }, { 2, 8, 14 }, { 3, 9, 13 }, { 4, 10 }, { 5, 11 } }; Cluster cluster = ServerTestUtils.getLocalZonedCluster(numberOfZones,