package voldemort.store.routed;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static voldemort.VoldemortTestConstants.getEightNodeClusterWithZones;
import static voldemort.VoldemortTestConstants.getFourNodeClusterWithZones;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import org.junit.Before;
import org.junit.Test;
import voldemort.TestUtils;
import voldemort.client.RoutingTier;
import voldemort.client.TimeoutConfig;
import voldemort.cluster.Cluster;
import voldemort.cluster.Node;
import voldemort.cluster.failuredetector.NoopFailureDetector;
import voldemort.routing.RoutingStrategyType;
import voldemort.serialization.SerializerDefinition;
import voldemort.store.Store;
import voldemort.store.StoreDefinition;
import voldemort.store.StoreDefinitionBuilder;
import voldemort.store.memory.InMemoryStorageConfiguration;
import voldemort.store.memory.InMemoryStorageEngine;
import voldemort.utils.ByteArray;
import voldemort.versioning.Versioned;
import com.google.common.collect.Maps;
public class GetallNodeReachTest {
private Cluster cluster;
private StoreDefinition storeDef;
private RoutedStore store;
Map<Integer, Store<ByteArray, byte[], byte[]>> subStores;
@Before
public void setUp() throws Exception {}
private void makeStore() {
subStores = Maps.newHashMap();
for(Node n: cluster.getNodes()) {
Store<ByteArray, byte[], byte[]> subStore = new InMemoryStorageEngine<ByteArray, byte[], byte[]>("test");
subStores.put(n.getId(), subStore);
}
RoutedStoreFactory routedStoreFactory = new RoutedStoreFactory(Executors.newFixedThreadPool(2));
store = routedStoreFactory.create(cluster,
storeDef,
subStores,
new NoopFailureDetector(),
new RoutedStoreConfig().setTimeoutConfig(new TimeoutConfig(1000L)));
}
@Test
public void testGetallTouchOneZone() throws Exception {
cluster = getFourNodeClusterWithZones();
HashMap<Integer, Integer> zoneReplicationFactor = new HashMap<Integer, Integer>();
zoneReplicationFactor.put(0, 2);
zoneReplicationFactor.put(1, 1);
zoneReplicationFactor.put(2, 1);
storeDef = new StoreDefinitionBuilder().setName("test")
.setType(InMemoryStorageConfiguration.TYPE_NAME)
.setRoutingPolicy(RoutingTier.CLIENT)
.setRoutingStrategyType(RoutingStrategyType.ZONE_STRATEGY)
.setReplicationFactor(4)
.setZoneReplicationFactor(zoneReplicationFactor)
.setKeySerializer(new SerializerDefinition("string"))
.setValueSerializer(new SerializerDefinition("string"))
.setPreferredReads(2)
.setRequiredReads(1)
.setPreferredWrites(1)
.setRequiredWrites(1)
.setZoneCountReads(0)
.setZoneCountWrites(0)
.build();
makeStore();
Versioned<byte[]> v = Versioned.value("v".getBytes());
subStores.get(0).put(TestUtils.toByteArray("k011_zone0_only"), v, null);
subStores.get(1).put(TestUtils.toByteArray("k011_zone0_only"), v, null);
subStores.get(2).put(TestUtils.toByteArray("k100_zone1_only"), v, null);
/* test single key getall */
List<ByteArray> keys011 = new ArrayList<ByteArray>();
keys011.add(TestUtils.toByteArray("k011_zone0_only"));
List<ByteArray> keys100 = new ArrayList<ByteArray>();
keys100.add(TestUtils.toByteArray("k100_zone1_only"));
assertEquals(2, store.getAll(keys011, null)
.get(TestUtils.toByteArray("k011_zone0_only"))
.size());
assertFalse(store.getAll(keys100, null)
.containsKey(TestUtils.toByteArray("k100_zone1_only")));
/* test multiple keys getall */
List<ByteArray> keys = new ArrayList<ByteArray>();
keys.add(TestUtils.toByteArray("k011_zone0_only"));
keys.add(TestUtils.toByteArray("k100_zone1_only"));
Map<ByteArray, List<Versioned<byte[]>>> result = store.getAll(keys, null);
assertEquals(2, result.get(TestUtils.toByteArray("k011_zone0_only")).size());
assertFalse(result.containsKey(TestUtils.toByteArray("k100_zone1_only")));
}
@Test
public void testGetall_211() throws Exception {
cluster = getFourNodeClusterWithZones();
HashMap<Integer, Integer> zoneReplicationFactor = new HashMap<Integer, Integer>();
zoneReplicationFactor.put(0, 2);
zoneReplicationFactor.put(1, 1);
zoneReplicationFactor.put(2, 1);
storeDef = new StoreDefinitionBuilder().setName("test")
.setType(InMemoryStorageConfiguration.TYPE_NAME)
.setRoutingPolicy(RoutingTier.CLIENT)
.setRoutingStrategyType(RoutingStrategyType.ZONE_STRATEGY)
.setReplicationFactor(4)
.setZoneReplicationFactor(zoneReplicationFactor)
.setKeySerializer(new SerializerDefinition("string"))
.setValueSerializer(new SerializerDefinition("string"))
.setPreferredReads(1)
.setRequiredReads(1)
.setPreferredWrites(1)
.setRequiredWrites(1)
.setZoneCountReads(0)
.setZoneCountWrites(0)
.build();
makeStore();
Versioned<byte[]> v = Versioned.value("v".getBytes());
// k### indicates existence of itself in different nodes
// k**1 means this key exists at least on node 0
// k*1* means this key exists at least on node 1
// k0** means this key does not exist on node 2
subStores.get(0).put(TestUtils.toByteArray("k001"), v, null);
subStores.get(0).put(TestUtils.toByteArray("k011"), v, null);
subStores.get(0).put(TestUtils.toByteArray("k101"), v, null);
subStores.get(0).put(TestUtils.toByteArray("k111"), v, null);
subStores.get(1).put(TestUtils.toByteArray("k010"), v, null);
subStores.get(1).put(TestUtils.toByteArray("k011"), v, null);
subStores.get(1).put(TestUtils.toByteArray("k110"), v, null);
subStores.get(1).put(TestUtils.toByteArray("k111"), v, null);
subStores.get(2).put(TestUtils.toByteArray("k100"), v, null);
subStores.get(2).put(TestUtils.toByteArray("k101"), v, null);
subStores.get(2).put(TestUtils.toByteArray("k110"), v, null);
subStores.get(2).put(TestUtils.toByteArray("k111"), v, null);
/* test multiple keys getall */
List<ByteArray> keys = new ArrayList<ByteArray>();
keys.add(TestUtils.toByteArray("k000"));
keys.add(TestUtils.toByteArray("k001"));
keys.add(TestUtils.toByteArray("k010"));
keys.add(TestUtils.toByteArray("k011"));
keys.add(TestUtils.toByteArray("k100"));
keys.add(TestUtils.toByteArray("k101"));
keys.add(TestUtils.toByteArray("k110"));
keys.add(TestUtils.toByteArray("k111"));
Map<ByteArray, List<Versioned<byte[]>>> result = store.getAll(keys, null);
assertFalse(result.containsKey(TestUtils.toByteArray("not_included")));
assertFalse(result.containsKey(TestUtils.toByteArray("k000")));
assertEquals(1, result.get(TestUtils.toByteArray("k011")).size());
assertFalse(result.containsKey(TestUtils.toByteArray("k100")));
assertEquals(1, result.get(TestUtils.toByteArray("k111")).size());
}
@Test
public void testGetall_211_zoneCountRead_1() throws Exception {
cluster = getFourNodeClusterWithZones();
HashMap<Integer, Integer> zoneReplicationFactor = new HashMap<Integer, Integer>();
zoneReplicationFactor.put(0, 2);
zoneReplicationFactor.put(1, 1);
zoneReplicationFactor.put(2, 1);
/*
* First n nodes on the preference list will be one node from each
* remote n zones, where n=zoneCountReads, therefore preferred read
* should be set > n if want to include local zone node results in
* parallel request
*/
storeDef = new StoreDefinitionBuilder().setName("test")
.setType(InMemoryStorageConfiguration.TYPE_NAME)
.setRoutingPolicy(RoutingTier.CLIENT)
.setRoutingStrategyType(RoutingStrategyType.ZONE_STRATEGY)
.setReplicationFactor(4)
.setZoneReplicationFactor(zoneReplicationFactor)
.setKeySerializer(new SerializerDefinition("string"))
.setValueSerializer(new SerializerDefinition("string"))
.setPreferredReads(2)
.setRequiredReads(1)
.setPreferredWrites(1)
.setRequiredWrites(1)
.setZoneCountReads(1)
.setZoneCountWrites(0)
.build();
makeStore();
Versioned<byte[]> v = Versioned.value("v".getBytes());
subStores.get(0).put(TestUtils.toByteArray("k001"), v, null);
subStores.get(0).put(TestUtils.toByteArray("k011"), v, null);
subStores.get(0).put(TestUtils.toByteArray("k101"), v, null);
subStores.get(0).put(TestUtils.toByteArray("k111"), v, null);
subStores.get(1).put(TestUtils.toByteArray("k010"), v, null);
subStores.get(1).put(TestUtils.toByteArray("k011"), v, null);
subStores.get(1).put(TestUtils.toByteArray("k110"), v, null);
subStores.get(1).put(TestUtils.toByteArray("k111"), v, null);
subStores.get(2).put(TestUtils.toByteArray("k100"), v, null);
subStores.get(2).put(TestUtils.toByteArray("k101"), v, null);
subStores.get(2).put(TestUtils.toByteArray("k110"), v, null);
subStores.get(2).put(TestUtils.toByteArray("k111"), v, null);
/* test multiple keys getall */
List<ByteArray> keys = new ArrayList<ByteArray>();
keys.add(TestUtils.toByteArray("k000"));
keys.add(TestUtils.toByteArray("k001"));
keys.add(TestUtils.toByteArray("k010"));
keys.add(TestUtils.toByteArray("k011"));
keys.add(TestUtils.toByteArray("k100"));
keys.add(TestUtils.toByteArray("k101"));
keys.add(TestUtils.toByteArray("k110"));
keys.add(TestUtils.toByteArray("k111"));
Map<ByteArray, List<Versioned<byte[]>>> result = store.getAll(keys, null);
assertFalse(result.containsKey(TestUtils.toByteArray("not_included")));
/* client will first try all the nodes in local zone */
assertFalse(result.containsKey(TestUtils.toByteArray("k000")));
assertEquals(1, result.get(TestUtils.toByteArray("k011")).size());
assertFalse(result.containsKey(TestUtils.toByteArray("not_included")));
assertFalse(result.containsKey(TestUtils.toByteArray("k000")));
assertEquals(1, result.get(TestUtils.toByteArray("k011")).size());
assertEquals(1, result.get(TestUtils.toByteArray("k100")).size());
assertEquals(2, result.get(TestUtils.toByteArray("k111")).size());
}
@Test
public void testGetall_322() throws Exception {
cluster = getEightNodeClusterWithZones();
HashMap<Integer, Integer> zoneReplicationFactor = new HashMap<Integer, Integer>();
zoneReplicationFactor.put(0, 3);
zoneReplicationFactor.put(1, 3);
storeDef = new StoreDefinitionBuilder().setName("test")
.setType(InMemoryStorageConfiguration.TYPE_NAME)
.setRoutingPolicy(RoutingTier.CLIENT)
.setRoutingStrategyType(RoutingStrategyType.ZONE_STRATEGY)
.setReplicationFactor(6)
.setZoneReplicationFactor(zoneReplicationFactor)
.setKeySerializer(new SerializerDefinition("string"))
.setValueSerializer(new SerializerDefinition("string"))
.setPreferredReads(2)
.setRequiredReads(2)
.setPreferredWrites(2)
.setRequiredWrites(2)
.setZoneCountReads(0)
.setZoneCountWrites(0)
.build();
makeStore();
Versioned<byte[]> v = Versioned.value("v".getBytes());
subStores.get(0).put(TestUtils.toByteArray("k1111_1111"), v, null);
subStores.get(0).put(TestUtils.toByteArray("k0000_1111"), v, null);
subStores.get(1).put(TestUtils.toByteArray("k1111_1111"), v, null);
subStores.get(1).put(TestUtils.toByteArray("k0000_1111"), v, null);
subStores.get(2).put(TestUtils.toByteArray("k1111_1111"), v, null);
subStores.get(2).put(TestUtils.toByteArray("k0000_1111"), v, null);
subStores.get(3).put(TestUtils.toByteArray("k0000_1111"), v, null);
subStores.get(3).put(TestUtils.toByteArray("k1111_1111"), v, null);
subStores.get(4).put(TestUtils.toByteArray("k1111_1111"), v, null);
subStores.get(4).put(TestUtils.toByteArray("k1111_0000"), v, null);
subStores.get(5).put(TestUtils.toByteArray("k1111_1111"), v, null);
subStores.get(5).put(TestUtils.toByteArray("k1111_0000"), v, null);
subStores.get(6).put(TestUtils.toByteArray("k1111_1111"), v, null);
subStores.get(6).put(TestUtils.toByteArray("k1111_0000"), v, null);
subStores.get(7).put(TestUtils.toByteArray("k1111_1111"), v, null);
subStores.get(7).put(TestUtils.toByteArray("k1111_0000"), v, null);
/* test multiple keys getall */
List<ByteArray> keys = new ArrayList<ByteArray>();
keys.add(TestUtils.toByteArray("k0000_0000"));
keys.add(TestUtils.toByteArray("k0000_1111"));
keys.add(TestUtils.toByteArray("k1111_0000"));
keys.add(TestUtils.toByteArray("k1111_1111"));
Map<ByteArray, List<Versioned<byte[]>>> result = store.getAll(keys, null);
assertFalse(result.containsKey(TestUtils.toByteArray("not_included")));
assertFalse(result.containsKey(TestUtils.toByteArray("k0000_0000")));
assertEquals(2, result.get(TestUtils.toByteArray("k0000_1111")).size());
assertFalse(result.containsKey(TestUtils.toByteArray("k1111_0000")));
assertEquals(2, result.get(TestUtils.toByteArray("k1111_1111")).size());
}
}