package de.zalando.sprocwrapper; import java.util.List; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.google.common.collect.Lists; import de.zalando.sprocwrapper.example.ExampleBitmapShardSProcService; import de.zalando.sprocwrapper.example.ExampleShardedObject; import de.zalando.sprocwrapper.example.ShardingSprocService; /** * @author hjacobs */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:backendContextTest.xml"}) public class ShardingIT { @Autowired private ShardingSprocService shardingSProcService; @Autowired private ExampleBitmapShardSProcService exampleBitmapShardSProcService; @Test public void testSharding() { // test simple identity + modulo sharding strategy Assert.assertEquals(0, shardingSProcService.getShardIndex(122)); Assert.assertEquals(1, shardingSProcService.getShardIndex(123)); } @Test public void testRunOnAllShards() { final List<String> results = shardingSProcService.collectDataFromAllShards("a"); Assert.assertEquals(4, results.size()); Assert.assertEquals("shard1row1", results.get(0)); Assert.assertEquals("shard2row1", results.get(2)); Assert.assertEquals("shard2row2", results.get(3)); } @Test public void testRunOnAllShardsParallel() { final List<String> results = shardingSProcService.collectDataFromAllShardsParallel("a"); Assert.assertEquals(4, results.size()); Assert.assertEquals("shard1row1", results.get(0)); Assert.assertEquals("shard2row1", results.get(2)); Assert.assertEquals("shard2row2", results.get(3)); shardingSProcService.collectDataFromAllShardsParallel("a"); } @Test public void testRunOnAllShardsSearchShardsOn() { // Search should stop on first shard with results. final List<String> results = shardingSProcService.collectDataFromAllShardsSearchShardsOn("a"); Assert.assertEquals(2, results.size()); Assert.assertEquals("shard2row1", results.get(0)); Assert.assertEquals("shard2row2", results.get(1)); } @Test public void testRunOnAllShardsParallelSearchShardsOn() { // Search should stop on first shard with results. final List<String> results = shardingSProcService.collectDataFromAllShardsParallelSearchShardsOn("a"); Assert.assertEquals(2, results.size()); Assert.assertEquals("shard2row1", results.get(0)); Assert.assertEquals("shard2row2", results.get(1)); } @Test public void testSearchShards() { Integer result = exampleBitmapShardSProcService.searchSomethingOnShards("X"); Assert.assertNull(result); result = exampleBitmapShardSProcService.searchSomethingOnShards("A"); Assert.assertEquals(1, (int) result); result = exampleBitmapShardSProcService.searchSomethingOnShards("B"); Assert.assertEquals(2, (int) result); final List<Integer> result2 = exampleBitmapShardSProcService.searchSomethingElseOnShards("UNUSED"); Assert.assertEquals(1, result2.size()); } @Test public void testBitmapShards() { Assert.assertEquals(0, exampleBitmapShardSProcService.getShardIndex(0)); Assert.assertEquals(1, exampleBitmapShardSProcService.getShardIndex(1)); Assert.assertEquals(0, exampleBitmapShardSProcService.getShardIndex(124)); Assert.assertEquals(1, exampleBitmapShardSProcService.getShardIndex(125)); Assert.assertEquals("00", exampleBitmapShardSProcService.getShardName(0)); Assert.assertEquals("1", exampleBitmapShardSProcService.getShardName(1)); Assert.assertEquals("10", exampleBitmapShardSProcService.getShardName(2)); Assert.assertEquals("1", exampleBitmapShardSProcService.getShardName(3)); } @Test public void testAutoPartitioning() { List<String> keys = Lists.newArrayList("a"); // config in backendContextText.xml: // 00 -> shard 1 // 10 -> shard 1 // 01 -> shard 2 // 11 -> shard 2 // MD5(a), last 3 byte => 0x772661 => 7808609 => binary endswith 1001 => // shard 2 // MD5(b), last 3 byte => 0x31578f => 3233679 => binary endswith 1001 => // shard 2 // MD5(c), last 3 byte => 0x8b5f33 => 9133875 => binary endswith 0101 => // shard 2 // MD5(d), last 3 byte => 0xe091ad => 14717357 => binary endswith 0111 // => shard 2 // MD5(e), last 3 byte => 0x41ec32 => 4320306 => binary endswith 0110 => // shard 1 List<String> results = exampleBitmapShardSProcService.collectDataUsingAutoPartition(keys); Assert.assertEquals(2, results.size()); Assert.assertEquals("shard2row1a", results.get(0)); Assert.assertEquals("shard2row2a", results.get(1)); keys = Lists.newArrayList("e"); results = exampleBitmapShardSProcService.collectDataUsingAutoPartition(keys); Assert.assertEquals(2, results.size()); Assert.assertEquals("shard1row1e", results.get(0)); Assert.assertEquals("shard1row2e", results.get(1)); keys = Lists.newArrayList("a", "b", "c", "d", "e"); results = exampleBitmapShardSProcService.collectDataUsingAutoPartition(keys); Assert.assertEquals(4, results.size()); Assert.assertEquals("shard1row1e", results.get(0)); Assert.assertEquals("shard1row2e", results.get(1)); Assert.assertEquals("shard2row1a", results.get(2)); Assert.assertEquals("shard2row2a", results.get(3)); final List<ExampleShardedObject> objectKeys = Lists.newArrayList(new ExampleShardedObject("a", "b"), new ExampleShardedObject("c", "d"), new ExampleShardedObject("e", "f")); results = exampleBitmapShardSProcService.collectDataUsingAutoPartition2(objectKeys, 3); Assert.assertEquals(2, results.size()); Assert.assertEquals("shard1row1ef3", results.get(0)); Assert.assertEquals("shard2row1ab3", results.get(1)); } }