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));
}
}