/*
* Copyright 2008-2009 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.routing;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import junit.framework.TestCase;
import voldemort.ClusterTestUtils;
import voldemort.ServerTestUtils;
import voldemort.cluster.Cluster;
import voldemort.cluster.Node;
public class ZoneRoutingStrategyTest extends TestCase {
private ZoneRoutingStrategy getRouter(int... zonesRepFactor) {
int totalZoneRepFactor = 0;
for(int i = 0; i < zonesRepFactor.length; i++) {
totalZoneRepFactor += zonesRepFactor[i];
}
return new ZoneRoutingStrategy(getTestCluster(),
getTestZoneReplicationFactor(zonesRepFactor),
totalZoneRepFactor);
}
private HashMap<Integer, Integer> getTestZoneReplicationFactor(int... zonesRepFactor) {
HashMap<Integer, Integer> returnHashMap = new HashMap<Integer, Integer>();
int zoneId = 0;
for(int zoneRepFactor: zonesRepFactor) {
returnHashMap.put(zoneId++, zoneRepFactor);
}
return returnHashMap;
}
private Cluster getTestCluster() {
int numberOfNodes = 13;
int numberOfZones = 4;
int[] nodeToZoneMapping = new int[] { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3 };
int[][] partitionMap = new int[][] { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7 }, { 8, 9, 10 },
{ 11, 12, 13 }, { 14, 15 }, { 16, 17, 18 }, { 19, 20, 21 }, { 22, 23, 24, 25 },
{ 26, 27, 28 }, { 29, 30 }, { 31 }, { 32 } };
int ports[] = new int [3*numberOfNodes];
for (int i=0; i<numberOfNodes; i++) {
ports[i*3] = 8080;
ports[i*3+1] = 6666;
ports[i*3+2] = 6667;
}
return ServerTestUtils.getLocalZonedCluster(numberOfNodes,
numberOfZones,
nodeToZoneMapping,
partitionMap,
ports);
}
private void assertReplicationPartitions(List<Integer> partitions, int... expected) {
assertEquals("Router produced unexpected number of replication partitions.",
expected.length,
partitions.size());
for(int i = 0; i < partitions.size(); i++)
assertEquals("Replication partitions should match",
new Integer(expected[i]),
partitions.get(i));
}
public void testReplication() {
assertReplicationPartitions(getRouter(1).getReplicatingPartitionList(0), 0);
assertReplicationPartitions(getRouter(1, 1).getReplicatingPartitionList(0), 0, 11);
assertReplicationPartitions(getRouter(1, 1, 1).getReplicatingPartitionList(0), 0, 11, 22);
assertReplicationPartitions(getRouter(1, 1, 1, 1).getReplicatingPartitionList(0),
0,
11,
22,
31);
// Should ignore the last zone
assertReplicationPartitions(getRouter(1, 1, 1, 1, 1).getReplicatingPartitionList(0),
0,
11,
22,
31);
assertReplicationPartitions(getRouter(2).getReplicatingPartitionList(0), 0, 3);
assertReplicationPartitions(getRouter(2, 1).getReplicatingPartitionList(0), 0, 3, 11);
assertReplicationPartitions(getRouter(2, 1, 1).getReplicatingPartitionList(0), 0, 3, 11, 22);
assertReplicationPartitions(getRouter(2, 1, 1, 1).getReplicatingPartitionList(0),
0,
3,
11,
22,
31);
assertReplicationPartitions(getRouter(2, 2).getReplicatingPartitionList(0), 0, 3, 11, 14);
assertReplicationPartitions(getRouter(2, 2, 1).getReplicatingPartitionList(0),
0,
3,
11,
14,
22);
assertReplicationPartitions(getRouter(2, 2, 1, 2).getReplicatingPartitionList(0),
0,
3,
11,
14,
22,
31,
32);
// Should not fail
assertReplicationPartitions(getRouter(2, 2, 1, 3).getReplicatingPartitionList(0),
0,
3,
11,
14,
22,
31,
32);
}
private ZoneRoutingStrategy getRouterForNonContiguousZones(List<Integer> zoneIds, int... zonesRepFactor) {
int totalZoneRepFactor = 0;
for(int i = 0; i < zonesRepFactor.length; i++) {
totalZoneRepFactor += zonesRepFactor[i];
}
return new ZoneRoutingStrategy(getTestClusterWithNonContiguousZones(),
getTestZoneReplicationFactorWithNonContiguousZones(zoneIds, zonesRepFactor),
totalZoneRepFactor);
}
private HashMap<Integer, Integer> getTestZoneReplicationFactorWithNonContiguousZones(List<Integer> zoneIds,
int... zonesRepFactor) {
HashMap<Integer, Integer> returnHashMap = new HashMap<Integer, Integer>();
int index = 0;
for(int zoneId: zoneIds) {
returnHashMap.put(zoneId, zonesRepFactor[index]);
index++;
}
return returnHashMap;
}
private Cluster getTestClusterWithNonContiguousZones() {
return ClusterTestUtils.getZ1Z3Z5Z10ClusterWithNonContiguousNodeIds();
}
public void testReplicationWithNonContiguousZonesAndNodes() {
ArrayList<Integer> zoneIds = new ArrayList<Integer>();
zoneIds.add(1);
assertReplicationPartitions(getRouterForNonContiguousZones(zoneIds, 1)
.getReplicatingPartitionList(0), 0);
zoneIds.add(3);
assertReplicationPartitions(getRouterForNonContiguousZones(zoneIds, 1, 1)
.getReplicatingPartitionList(0), 0, 4);
zoneIds.add(5);
assertReplicationPartitions(getRouterForNonContiguousZones(zoneIds, 1, 1, 1)
.getReplicatingPartitionList(0), 0, 4, 22);
zoneIds.add(10);
assertReplicationPartitions(getRouterForNonContiguousZones(zoneIds, 1, 1, 1, 1)
.getReplicatingPartitionList(0), 0, 4, 22, 29);
zoneIds.clear();
zoneIds.add(1);
assertReplicationPartitions(getRouterForNonContiguousZones(zoneIds, 2)
.getReplicatingPartitionList(0), 0, 1);
zoneIds.add(3);
assertReplicationPartitions(getRouterForNonContiguousZones(zoneIds, 2, 1)
.getReplicatingPartitionList(0), 0, 1, 4);
zoneIds.add(5);
assertReplicationPartitions(getRouterForNonContiguousZones(zoneIds, 2, 1, 1)
.getReplicatingPartitionList(0), 0, 1, 4, 22);
zoneIds.add(10);
assertReplicationPartitions(getRouterForNonContiguousZones(zoneIds, 2, 1, 1, 1)
.getReplicatingPartitionList(0), 0, 1, 4, 22, 29);
zoneIds.clear();
zoneIds.add(1);
zoneIds.add(3);
assertReplicationPartitions(getRouterForNonContiguousZones(zoneIds, 2, 2)
.getReplicatingPartitionList(0), 0, 1, 4, 5);
zoneIds.add(5);
assertReplicationPartitions(getRouterForNonContiguousZones(zoneIds, 2, 2, 1)
.getReplicatingPartitionList(0), 0, 1, 4, 5, 22);
zoneIds.add(10);
assertReplicationPartitions(getRouterForNonContiguousZones(zoneIds, 2, 2, 1, 2)
.getReplicatingPartitionList(0),
0, 1, 4, 5, 22, 29, 31);
// Should not fail
assertReplicationPartitions(getRouterForNonContiguousZones(zoneIds, 2, 2, 1, 3)
.getReplicatingPartitionList(0),
0, 1, 4, 5, 22, 29, 31);
}
}