package com.alibaba.cobar.client.router.rules; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertTrue; import static org.testng.AssertJUnit.fail; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import com.alibaba.cobar.client.entities.Tweet; import com.alibaba.cobar.client.router.rules.ibatis.IBatisNamespaceShardingRule; import com.alibaba.cobar.client.router.rules.support.ModFunction; import com.alibaba.cobar.client.router.support.IBatisRoutingFact; import com.alibaba.cobar.client.support.utils.CollectionUtils; @Test public class IBatisNamespaceShardingRuleTest { public static final String DEFAULT_TYPE_PATTEN = "com.alibaba.cobar.client.entity.Tweet"; public static final String DEFAULT_SHARDING_PATTERN = "id>=10000 and id < 20000"; public static final String[] DEFAULT_SHARDS = { "shard1", "shard2" }; private IBatisNamespaceShardingRule rule; @BeforeMethod protected void setUp() throws Exception { rule = new IBatisNamespaceShardingRule(DEFAULT_TYPE_PATTEN, "shard1,shard2", DEFAULT_SHARDING_PATTERN); } @AfterMethod protected void tearDown() throws Exception { rule = null; } public void testShardIdAssemblyNormally() { List<String> shards = rule.action(); assertTrue(CollectionUtils.isNotEmpty(shards)); assertEquals(2, shards.size()); for (String shard : shards) { assertTrue(ArrayUtils.contains(DEFAULT_SHARDS, shard)); } } public void testShardIdAssemblyAbnormally() { try { new IBatisNamespaceShardingRule(DEFAULT_TYPE_PATTEN, null, DEFAULT_SHARDING_PATTERN); fail(); } catch (IllegalArgumentException e) { // pass } try { new IBatisNamespaceShardingRule(DEFAULT_TYPE_PATTEN, "", DEFAULT_SHARDING_PATTERN); fail(); } catch (IllegalArgumentException e) { // pass } } public void testShardIdAssemblyWithCustomActionPatternSeparatorNormally() { rule.setActionPatternSeparator(";"); List<String> shards = rule.action(); assertTrue(CollectionUtils.isNotEmpty(shards)); assertEquals(1, shards.size()); assertEquals("shard1,shard2", shards.get(0)); rule = new IBatisNamespaceShardingRule(DEFAULT_TYPE_PATTEN, "shard1;shard2", DEFAULT_SHARDING_PATTERN); rule.setActionPatternSeparator(";"); shards = null; shards = rule.action(); assertTrue(CollectionUtils.isNotEmpty(shards)); assertEquals(2, shards.size()); for (String shard : shards) { assertTrue(ArrayUtils.contains(DEFAULT_SHARDS, shard)); } } public void testShardIdAssemblyWithCustomActionPatternSeparatorAbnormally() { try { rule.setActionPatternSeparator(null); fail(); } catch (IllegalArgumentException e) { // pass } } public void testRuleTypePatternMatchingNormally() { Tweet t = new Tweet(); t.setId(15000L); t.setTweet("anything"); IBatisRoutingFact fact = new IBatisRoutingFact( "com.alibaba.cobar.client.entity.Tweet.create", t); assertTrue(rule.isDefinedAt(fact)); fact = new IBatisRoutingFact("com.alibaba.cobar.client.entity.Tweet.update", t); assertTrue(rule.isDefinedAt(fact)); fact = new IBatisRoutingFact("com.alibaba.cobar.client.entity.Follower.update", t); assertFalse(rule.isDefinedAt(fact)); } public void testRuleTypePatternMatchingAbnormally() { // abnormal parameter try { rule.isDefinedAt(null); fail(); } catch (IllegalArgumentException e) { // pass } // construction abnormally try { rule = new IBatisNamespaceShardingRule(null, "shard1,shard2", DEFAULT_SHARDING_PATTERN); fail(); } catch (IllegalArgumentException e) { // pass } try { rule = new IBatisNamespaceShardingRule("", "shard1,shard2", DEFAULT_SHARDING_PATTERN); fail(); } catch (IllegalArgumentException e) { // pass } } public void testRuleShardingPatternMatchingNormally() { Tweet t = new Tweet(); t.setId(15000L); t.setTweet("anything"); IBatisRoutingFact fact = new IBatisRoutingFact( "com.alibaba.cobar.client.entity.Tweet.update", t); assertTrue(rule.isDefinedAt(fact)); t.setId(20000001L); fact = new IBatisRoutingFact("com.alibaba.cobar.client.entity.Tweet.update", t); assertFalse(rule.isDefinedAt(fact)); fact = new IBatisRoutingFact("com.alibaba.cobar.client.entity.Tweet.update", null); assertFalse(rule.isDefinedAt(fact)); Map<String, Long> ctx = new HashMap<String, Long>(); fact = new IBatisRoutingFact("com.alibaba.cobar.client.entity.Tweet.update", ctx); assertFalse(rule.isDefinedAt(fact)); ctx.put("id", 18000L); assertTrue(rule.isDefinedAt(fact)); } public void testRuleShardingPatternMatchingAbnormally() { try { new IBatisNamespaceShardingRule(DEFAULT_TYPE_PATTEN, "shard1,shard2", null); fail(); } catch (IllegalArgumentException e) { // pass } try { new IBatisNamespaceShardingRule(DEFAULT_TYPE_PATTEN, "shard1,shard2", ""); fail(); } catch (IllegalArgumentException e) { // pass } } public void testRuleShardingPatternWithCustomFunctions() throws Exception { String shardingExpression = "mod.apply(id)==3"; IBatisNamespaceShardingRule r = new IBatisNamespaceShardingRule(DEFAULT_TYPE_PATTEN, StringUtils.join(DEFAULT_SHARDS, ","), shardingExpression); Map<String, Object> functions = new HashMap<String, Object>(); functions.put("mod", new ModFunction(18L)); r.setFunctionMap(functions); Tweet t = new Tweet(); t.setId(3L); t.setTweet("anything"); IBatisRoutingFact fact = new IBatisRoutingFact( "com.alibaba.cobar.client.entity.Tweet.create", t); assertTrue(r.isDefinedAt(fact)); } public void testRuleExpressionEvaluationWithSimpleTypeRoutingFact() { IBatisNamespaceShardingRule r = new IBatisNamespaceShardingRule(DEFAULT_TYPE_PATTEN, "shard2", "$ROOT.startsWith(\"A\")"); IBatisRoutingFact fact = new IBatisRoutingFact( "com.alibaba.cobar.client.entity.Tweet.create", "Arron"); assertTrue(r.isDefinedAt(fact)); r = new IBatisNamespaceShardingRule(DEFAULT_TYPE_PATTEN, "shard2", "startsWith(\"A\")"); assertTrue(r.isDefinedAt(fact)); fact = new IBatisRoutingFact( "com.alibaba.cobar.client.entity.Tweet.create", "Donald"); assertFalse(r.isDefinedAt(fact)); } }