You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by st...@apache.org on 2017/01/22 12:12:06 UTC

[01/31] incubator-rocketmq git commit: [ROCKETMQ-57] Polish unit tests for rocketmq-tools

Repository: incubator-rocketmq
Updated Branches:
  refs/heads/ROCKETMQ-54 d3a7f248c -> e403ca397


[ROCKETMQ-57] Polish unit tests for rocketmq-tools


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/b29ff37d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/b29ff37d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/b29ff37d

Branch: refs/heads/ROCKETMQ-54
Commit: b29ff37db4f75d09419dffa092e38b7765814f04
Parents: 0f9f55f
Author: stevenschew <st...@apache.org>
Authored: Thu Jan 19 11:41:32 2017 +0800
Committer: stevenschew <st...@apache.org>
Committed: Thu Jan 19 11:41:32 2017 +0800

----------------------------------------------------------------------
 .../tools/admin/DefaultMQAdminExtTest.java      | 240 +++++++++++++++++++
 .../rocketmq/tools/command/CommandUtilTest.java |  92 +++++++
 2 files changed, 332 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/b29ff37d/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java
----------------------------------------------------------------------
diff --git a/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java b/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java
new file mode 100644
index 0000000..ab6319f
--- /dev/null
+++ b/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java
@@ -0,0 +1,240 @@
+package org.apache.rocketmq.tools.admin;
+
+import org.apache.rocketmq.client.ClientConfig;
+import org.apache.rocketmq.client.exception.MQBrokerException;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.client.impl.MQClientAPIImpl;
+import org.apache.rocketmq.client.impl.MQClientManager;
+import org.apache.rocketmq.client.impl.factory.MQClientInstance;
+import org.apache.rocketmq.common.namesrv.NamesrvUtil;
+import org.apache.rocketmq.common.protocol.body.*;
+import org.apache.rocketmq.common.protocol.route.BrokerData;
+import org.apache.rocketmq.common.protocol.route.TopicRouteData;
+import org.apache.rocketmq.common.subscription.SubscriptionGroupConfig;
+import org.apache.rocketmq.remoting.exception.RemotingConnectException;
+import org.apache.rocketmq.remoting.exception.RemotingException;
+import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
+import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class DefaultMQAdminExtTest {
+    private DefaultMQAdminExtImpl defaultMQAdminExtImpl;
+    private MQClientInstance mqClientInstance = MQClientManager.getInstance().getAndCreateMQClientInstance(new ClientConfig());
+    private MQClientAPIImpl mQClientAPIImpl;
+    private Properties properties = new Properties();
+    private TopicList topicList = new TopicList();
+    private TopicRouteData topicRouteData = new TopicRouteData();
+    private KVTable kvTable = new KVTable();
+    private ClusterInfo clusterInfo = new ClusterInfo();
+
+    @Before
+    public void init() throws Exception {
+        mQClientAPIImpl = mock(MQClientAPIImpl.class);
+        DefaultMQAdminExt defaultMQAdminExt = new DefaultMQAdminExt();
+        defaultMQAdminExtImpl = new DefaultMQAdminExtImpl(defaultMQAdminExt, 1000);
+
+        Field field = DefaultMQAdminExtImpl.class.getDeclaredField("mqClientInstance");
+        field.setAccessible(true);
+        field.set(defaultMQAdminExtImpl, mqClientInstance);
+        field = MQClientInstance.class.getDeclaredField("mQClientAPIImpl");
+        field.setAccessible(true);
+        field.set(mqClientInstance, mQClientAPIImpl);
+
+        properties.setProperty("maxMessageSize", "5000000");
+        properties.setProperty("flushDelayOffsetInterval", "15000");
+        properties.setProperty("serverSocketRcvBufSize", "655350");
+        when(mQClientAPIImpl.getBrokerConfig(anyString(), anyLong())).thenReturn(properties);
+
+        Set<String> topicSet = new HashSet<>();
+        topicSet.add("topic_one");
+        topicSet.add("topic_two");
+        topicList.setTopicList(topicSet);
+        when(mQClientAPIImpl.getTopicListFromNameServer(anyLong())).thenReturn(topicList);
+
+
+        List<BrokerData> brokerDatas = new ArrayList<>();
+        HashMap<Long, String> brokerAddrs = new HashMap<>();
+        brokerAddrs.put(1234l, "127.0.0.1:10911");
+        BrokerData brokerData = new BrokerData();
+        brokerData.setCluster("default-cluster");
+        brokerData.setBrokerName("default-broker");
+        brokerData.setBrokerAddrs(brokerAddrs);
+        brokerDatas.add(brokerData);
+        topicRouteData.setBrokerDatas(brokerDatas);
+        when(mQClientAPIImpl.getTopicRouteInfoFromNameServer(anyString(), anyLong())).thenReturn(topicRouteData);
+
+        HashMap<String, String> result = new HashMap<>();
+        result.put("id", "1234");
+        result.put("brokerName", "default-broker");
+        kvTable.setTable(result);
+        when(mQClientAPIImpl.getBrokerRuntimeInfo(anyString(), anyLong())).thenReturn(kvTable);
+
+        HashMap<String, BrokerData> brokerAddrTable = new HashMap<>();
+        brokerAddrTable.put("default-broker", brokerData);
+        brokerAddrTable.put("broker-test", new BrokerData());
+        clusterInfo.setBrokerAddrTable(brokerAddrTable);
+        when(mQClientAPIImpl.getBrokerClusterInfo(anyLong())).thenReturn(clusterInfo);
+        when(mQClientAPIImpl.cleanExpiredConsumeQueue(anyString(), anyLong())).thenReturn(true);
+
+        Set<String> clusterList = new HashSet<>();
+        clusterList.add("default-cluster-one");
+        clusterList.add("default-cluster-two");
+        when(mQClientAPIImpl.getClusterList(anyString(), anyLong())).thenReturn(clusterList);
+
+        GroupList groupList = new GroupList();
+        HashSet<String> groups = new HashSet<>();
+        groups.add("consumer-group-one");
+        groups.add("consumer-group-two");
+        groupList.setGroupList(groups);
+        when(mQClientAPIImpl.getTopicRouteInfoFromNameServer(anyString(), anyLong())).thenReturn(topicRouteData);
+        when(mQClientAPIImpl.queryTopicConsumeByWho(anyString(), anyString(), anyLong())).thenReturn(groupList);
+
+        SubscriptionGroupWrapper subscriptionGroupWrapper = new SubscriptionGroupWrapper();
+        ConcurrentHashMap<String, SubscriptionGroupConfig> subscriptions = new ConcurrentHashMap<>();
+        SubscriptionGroupConfig subscriptionGroupConfig = new SubscriptionGroupConfig();
+        subscriptionGroupConfig.setConsumeBroadcastEnable(true);
+        subscriptionGroupConfig.setBrokerId(1234);
+        subscriptionGroupConfig.setGroupName("Consumer-group-one");
+        subscriptions.put("Consumer-group-one", subscriptionGroupConfig);
+        subscriptionGroupWrapper.setSubscriptionGroupTable(subscriptions);
+        when(mQClientAPIImpl.getAllSubscriptionGroup(anyString(), anyLong())).thenReturn(subscriptionGroupWrapper);
+
+        String topicListConfig = "topicListConfig";
+        when(mQClientAPIImpl.getKVConfigValue(anyString(), anyString(), anyLong())).thenReturn(topicListConfig);
+
+        KVTable kvTable = new KVTable();
+        HashMap<String, String> kv = new HashMap<>();
+        kv.put("broker-name", "broker-one");
+        kv.put("cluster-name", "default-cluster");
+        kvTable.setTable(kv);
+        when(mQClientAPIImpl.getKVListByNamespace(anyString(), anyLong())).thenReturn(kvTable);
+    }
+
+    @After
+    public void terminate() throws Exception {
+        if (defaultMQAdminExtImpl != null)
+            defaultMQAdminExtImpl.shutdown();
+    }
+
+    @Test
+    public void testUpdateBrokerConfig() throws InterruptedException, RemotingConnectException, UnsupportedEncodingException, RemotingTimeoutException, MQBrokerException, RemotingSendRequestException {
+        Properties result = defaultMQAdminExtImpl.getBrokerConfig("127.0.0.1:10911");
+        assertThat(result.getProperty("maxMessageSize")).isEqualTo("5000000");
+        assertThat(result.getProperty("flushDelayOffsetInterval")).isEqualTo("15000");
+        assertThat(result.getProperty("serverSocketRcvBufSize")).isEqualTo("655350");
+    }
+
+
+    @Test
+    public void testFetchAllTopicList() throws RemotingException, MQClientException, InterruptedException {
+        TopicList topicList = defaultMQAdminExtImpl.fetchAllTopicList();
+        assertThat(topicList.getTopicList().size()).isEqualTo(2);
+        assertThat(topicList.getTopicList()).contains("topic_one");
+    }
+
+    @Test
+    public void testFetchBrokerRuntimeStats() throws InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException {
+        KVTable brokerStats = defaultMQAdminExtImpl.fetchBrokerRuntimeStats("127.0.0.1:10911");
+        assertThat(brokerStats.getTable().get("id")).isEqualTo("1234");
+        assertThat(brokerStats.getTable().get("brokerName")).isEqualTo("default-broker");
+    }
+
+    @Test
+    public void testExamineBrokerClusterInfo() throws InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException {
+        ClusterInfo clusterInfo = defaultMQAdminExtImpl.examineBrokerClusterInfo();
+        HashMap<String, BrokerData> brokerList = clusterInfo.getBrokerAddrTable();
+        assertThat(brokerList.get("default-broker").getBrokerName()).isEqualTo("default-broker");
+        assertThat(brokerList.containsKey("broker-test")).isTrue();
+
+        HashMap<String, Set<String>> clusterMap = new HashMap<>();
+        Set<String> brokers = new HashSet<>();
+        brokers.add("default-broker");
+        brokers.add("broker-test");
+        clusterMap.put("default-cluster", brokers);
+        ClusterInfo cInfo = mock(ClusterInfo.class);
+        when(cInfo.getClusterAddrTable()).thenReturn(clusterMap);
+        HashMap<String, Set<String>> clusterAddress = cInfo.getClusterAddrTable();
+        assertThat(clusterAddress.containsKey("default-cluster")).isTrue();
+        assertThat(clusterAddress.get("default-cluster").size()).isEqualTo(2);
+    }
+
+    @Test
+    public void testExamineTopicRouteInfo() throws RemotingException, MQClientException, InterruptedException {
+        TopicRouteData topicRouteData = defaultMQAdminExtImpl.examineTopicRouteInfo("UnitTest");
+        assertThat(topicRouteData.getBrokerDatas().get(0).getBrokerName()).isEqualTo("default-broker");
+        assertThat(topicRouteData.getBrokerDatas().get(0).getCluster()).isEqualTo("default-cluster");
+    }
+
+    @Test
+    public void testGetNameServerAddressList() {
+        List<String> result = new ArrayList<>();
+        result.add("default-name-one");
+        result.add("default-name-two");
+        when(mqClientInstance.getMQClientAPIImpl().getNameServerAddressList()).thenReturn(result);
+        List<String> nameList = defaultMQAdminExtImpl.getNameServerAddressList();
+        assertThat(nameList.get(0)).isEqualTo("default-name-one");
+        assertThat(nameList.get(1)).isEqualTo("default-name-two");
+    }
+
+    @Test
+    public void testPutKVConfig() throws RemotingException, MQClientException, InterruptedException {
+        String topicConfig = defaultMQAdminExtImpl.getKVConfig(NamesrvUtil.NAMESPACE_ORDER_TOPIC_CONFIG, "UnitTest");
+        assertThat(topicConfig).isEqualTo("topicListConfig");
+        KVTable kvs = defaultMQAdminExtImpl.getKVListByNamespace(NamesrvUtil.NAMESPACE_ORDER_TOPIC_CONFIG);
+        assertThat(kvs.getTable().get("broker-name")).isEqualTo("broker-one");
+        assertThat(kvs.getTable().get("cluster-name")).isEqualTo("default-cluster");
+    }
+
+
+    @Test
+    public void testQueryTopicConsumeByWho() throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
+        GroupList groupList = defaultMQAdminExtImpl.queryTopicConsumeByWho("UnitTest");
+        assertThat(groupList.getGroupList().contains("consumer-group-two")).isTrue();
+    }
+
+    @Test
+    public void testCleanExpiredConsumerQueueByAddr() throws InterruptedException, RemotingTimeoutException, MQClientException, RemotingSendRequestException, RemotingConnectException {
+        boolean clean = defaultMQAdminExtImpl.cleanExpiredConsumerQueueByAddr("127.0.0.1:10911");
+        assertThat(clean).isTrue();
+    }
+
+    @Test
+    public void testGetClusterList() throws InterruptedException, RemotingTimeoutException, MQClientException, RemotingSendRequestException, RemotingConnectException {
+        Set<String> clusterlist = defaultMQAdminExtImpl.getClusterList("UnitTest");
+        assertThat(clusterlist.contains("default-cluster-one")).isTrue();
+        assertThat(clusterlist.contains("default-cluster-two")).isTrue();
+    }
+
+    @Test
+    public void testFetchConsumeStatsInBroker() throws InterruptedException, RemotingTimeoutException, MQClientException, RemotingSendRequestException, RemotingConnectException {
+        ConsumeStatsList result = new ConsumeStatsList();
+        result.setBrokerAddr("127.0.0.1:10911");
+        when(mqClientInstance.getMQClientAPIImpl().fetchConsumeStatsInBroker("127.0.0.1:10911", false, 10000)).thenReturn(result);
+        ConsumeStatsList consumeStatsList = defaultMQAdminExtImpl.fetchConsumeStatsInBroker("127.0.0.1:10911", false, 10000);
+        assertThat(consumeStatsList.getBrokerAddr()).isEqualTo("127.0.0.1:10911");
+    }
+
+    @Test
+    public void testGetAllSubscriptionGroup() throws InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException {
+        SubscriptionGroupWrapper subscriptionGroupWrapper = defaultMQAdminExtImpl.getAllSubscriptionGroup("127.0.0.1:10911", 10000);
+        assertThat(subscriptionGroupWrapper.getSubscriptionGroupTable().get("Consumer-group-one").getBrokerId()).isEqualTo(1234);
+        assertThat(subscriptionGroupWrapper.getSubscriptionGroupTable().get("Consumer-group-one").getGroupName()).isEqualTo("Consumer-group-one");
+        assertThat(subscriptionGroupWrapper.getSubscriptionGroupTable().get("Consumer-group-one").isConsumeBroadcastEnable()).isTrue();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/b29ff37d/tools/src/test/java/org/apache/rocketmq/tools/command/CommandUtilTest.java
----------------------------------------------------------------------
diff --git a/tools/src/test/java/org/apache/rocketmq/tools/command/CommandUtilTest.java b/tools/src/test/java/org/apache/rocketmq/tools/command/CommandUtilTest.java
new file mode 100644
index 0000000..35c205e
--- /dev/null
+++ b/tools/src/test/java/org/apache/rocketmq/tools/command/CommandUtilTest.java
@@ -0,0 +1,92 @@
+package org.apache.rocketmq.tools.command;
+
+import org.apache.rocketmq.client.ClientConfig;
+import org.apache.rocketmq.client.exception.MQBrokerException;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.client.impl.MQClientAPIImpl;
+import org.apache.rocketmq.client.impl.MQClientManager;
+import org.apache.rocketmq.client.impl.factory.MQClientInstance;
+import org.apache.rocketmq.common.protocol.body.ClusterInfo;
+import org.apache.rocketmq.common.protocol.route.BrokerData;
+import org.apache.rocketmq.remoting.exception.RemotingConnectException;
+import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
+import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
+import org.apache.rocketmq.tools.admin.DefaultMQAdminExt;
+import org.apache.rocketmq.tools.admin.DefaultMQAdminExtImpl;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.lang.reflect.Field;
+import java.util.*;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class CommandUtilTest {
+    private DefaultMQAdminExt defaultMQAdminExt;
+    private DefaultMQAdminExtImpl defaultMQAdminExtImpl;
+    private MQClientInstance mqClientInstance = MQClientManager.getInstance().getAndCreateMQClientInstance(new ClientConfig());
+    private MQClientAPIImpl mQClientAPIImpl;
+
+    @Before
+    public void setup() throws MQClientException, NoSuchFieldException, IllegalAccessException, InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException {
+        defaultMQAdminExt = mock(DefaultMQAdminExt.class);
+        MQClientAPIImpl mQClientAPIImpl = mock(MQClientAPIImpl.class);
+        defaultMQAdminExtImpl = new DefaultMQAdminExtImpl(defaultMQAdminExt, 3000);
+
+        Field field = DefaultMQAdminExtImpl.class.getDeclaredField("mqClientInstance");
+        field.setAccessible(true);
+        field.set(defaultMQAdminExtImpl, mqClientInstance);
+        field = MQClientInstance.class.getDeclaredField("mQClientAPIImpl");
+        field.setAccessible(true);
+        field.set(mqClientInstance, mQClientAPIImpl);
+
+        ClusterInfo clusterInfo = new ClusterInfo();
+        HashMap<String, BrokerData> brokerAddrTable = new HashMap<>();
+        HashMap<String, Set<String>> clusterAddrTable = new HashMap<>();
+        HashMap<Long, String> brokerAddrs = new HashMap<>();
+        brokerAddrs.put(1234l, "127.0.0.1:10911");
+        BrokerData brokerData = new BrokerData();
+        brokerData.setBrokerName("default-broker");
+        brokerData.setCluster("default-cluster");
+        brokerData.setBrokerAddrs(brokerAddrs);
+        brokerAddrTable.put("default-broker", brokerData);
+        brokerAddrTable.put("broker-test", new BrokerData());
+        Set<String> brokerSet = new HashSet<>();
+        brokerSet.add("default-broker");
+        brokerSet.add("default-broker-one");
+        clusterAddrTable.put("default-cluster", brokerSet);
+        clusterInfo.setBrokerAddrTable(brokerAddrTable);
+        clusterInfo.setClusterAddrTable(clusterAddrTable);
+        when(mQClientAPIImpl.getBrokerClusterInfo(anyLong())).thenReturn(clusterInfo);
+        when(mQClientAPIImpl.cleanExpiredConsumeQueue(anyString(), anyLong())).thenReturn(true);
+    }
+
+    @After
+    public void shutdown() throws Exception {
+    }
+
+    @Test
+    public void testFetchMasterAndSlaveDistinguish() throws InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException {
+        Map<String, List<String>> result = CommandUtil.fetchMasterAndSlaveDistinguish(defaultMQAdminExtImpl, "default-cluster");
+        assertThat(result.get(null).get(0)).isEqualTo("127.0.0.1:10911");
+    }
+
+    @Test
+    public void testFetchMasterAddrByClusterName() throws InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException {
+        Set<String> result = CommandUtil.fetchMasterAddrByClusterName(defaultMQAdminExtImpl, "default-cluster");
+        assertThat(result.size()).isEqualTo(0);
+    }
+
+    @Test
+    public void testFetchBrokerNameByClusterName() throws Exception {
+        Set<String> result = CommandUtil.fetchBrokerNameByClusterName(defaultMQAdminExtImpl, "default-cluster");
+        assertThat(result.contains("default-broker")).isTrue();
+        assertThat(result.contains("default-broker-one")).isTrue();
+        assertThat(result.size()).isEqualTo(2);
+    }
+}
\ No newline at end of file


[25/31] incubator-rocketmq git commit: Add javadoc to quick start examples.

Posted by st...@apache.org.
Add javadoc to quick start examples.


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/e9a87ea9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/e9a87ea9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/e9a87ea9

Branch: refs/heads/ROCKETMQ-54
Commit: e9a87ea93e5ed29eb8c335e17c1b5643e572abf6
Parents: e447bd0
Author: Zhanhui Li <li...@apache.org>
Authored: Sun Jan 22 16:20:21 2017 +0800
Committer: Zhanhui Li <li...@apache.org>
Committed: Sun Jan 22 16:20:21 2017 +0800

----------------------------------------------------------------------
 .../rocketmq/example/quickstart/Consumer.java   | 28 ++++++++++++
 .../rocketmq/example/quickstart/Producer.java   | 46 +++++++++++++++-----
 2 files changed, 63 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/e9a87ea9/example/src/main/java/org/apache/rocketmq/example/quickstart/Consumer.java
----------------------------------------------------------------------
diff --git a/example/src/main/java/org/apache/rocketmq/example/quickstart/Consumer.java b/example/src/main/java/org/apache/rocketmq/example/quickstart/Consumer.java
index 00e8fda..58910ab 100644
--- a/example/src/main/java/org/apache/rocketmq/example/quickstart/Consumer.java
+++ b/example/src/main/java/org/apache/rocketmq/example/quickstart/Consumer.java
@@ -25,15 +25,39 @@ import org.apache.rocketmq.client.exception.MQClientException;
 import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
 import org.apache.rocketmq.common.message.MessageExt;
 
+/**
+ * This example shows how to subscribe and consume messages using providing {@link DefaultMQPushConsumer}.
+ */
 public class Consumer {
 
     public static void main(String[] args) throws InterruptedException, MQClientException {
+
+        /*
+         * Instantiate with specified consumer group name.
+         */
         DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("please_rename_unique_group_name_4");
 
+        /*
+         * Specify name server addresses.
+         * <p/>
+         *
+         * Alternatively, you may specify name server addresses via exporting environmental variable: NAMESRV_ADDR
+         */
+        consumer.setNamesrvAddr("name-server1-ip:9876;name-server2-ip:9876");
+
+        /*
+         * Specify where to start in case the specified consumer group is a brand new one.
+         */
         consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
 
+        /*
+         * Subscribe one more more topics to consume.
+         */
         consumer.subscribe("TopicTest", "*");
 
+        /*
+         *  Register callback to execute on arrival of messages fetched from brokers.
+         */
         consumer.registerMessageListener(new MessageListenerConcurrently() {
 
             @Override
@@ -44,7 +68,11 @@ public class Consumer {
             }
         });
 
+        /*
+         *  Launch the consumer instance.
+         */
         consumer.start();
+
         System.out.printf("Consumer Started.%n");
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/e9a87ea9/example/src/main/java/org/apache/rocketmq/example/quickstart/Producer.java
----------------------------------------------------------------------
diff --git a/example/src/main/java/org/apache/rocketmq/example/quickstart/Producer.java b/example/src/main/java/org/apache/rocketmq/example/quickstart/Producer.java
index 27be815..06e1665 100644
--- a/example/src/main/java/org/apache/rocketmq/example/quickstart/Producer.java
+++ b/example/src/main/java/org/apache/rocketmq/example/quickstart/Producer.java
@@ -18,36 +18,60 @@ package org.apache.rocketmq.example.quickstart;
 
 import org.apache.rocketmq.client.exception.MQClientException;
 import org.apache.rocketmq.client.producer.DefaultMQProducer;
-import org.apache.rocketmq.client.producer.LocalTransactionExecuter;
-import org.apache.rocketmq.client.producer.LocalTransactionState;
 import org.apache.rocketmq.client.producer.SendResult;
 import org.apache.rocketmq.common.message.Message;
 import org.apache.rocketmq.remoting.common.RemotingHelper;
 
+/**
+ * This class demonstrates how to send messages to brokers using provided {@link DefaultMQProducer}.
+ */
 public class Producer {
     public static void main(String[] args) throws MQClientException, InterruptedException {
+
+        /*
+         * Instantiate with a producer group name.
+         */
         DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name");
+
+        /*
+         * Specify name server addresses.
+         * <p/>
+         *
+         * Alternatively, you may specify name server addresses via exporting environmental variable: NAMESRV_ADDR
+         */
+        producer.setNamesrvAddr("name-server1-ip:9876;name-server2-ip:9876");
+
+        /*
+         * Launch the instance.
+         */
         producer.start();
 
         for (int i = 0; i < 1000; i++) {
             try {
-                Message msg = new Message("TopicTest",
-                    "TagA",
-                    ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET)
+
+                /*
+                 * Create a message instance, specifying topic, tag and message body.
+                 */
+                Message msg = new Message("TopicTest" /* Topic */,
+                    "TagA" /* Tag */,
+                    ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */
                 );
+
+                /*
+                 * Call send message to deliver message to one of brokers.
+                 */
                 SendResult sendResult = producer.send(msg);
-                LocalTransactionExecuter tranExecuter = new LocalTransactionExecuter() {
-                    @Override
-                    public LocalTransactionState executeLocalTransactionBranch(Message msg, Object arg) {
-                        return null;
-                    }
-                };
+
                 System.out.printf("%s%n", sendResult);
             } catch (Exception e) {
                 e.printStackTrace();
                 Thread.sleep(1000);
             }
         }
+
+        /*
+         * Shut down once the producer instance is not longer in use.
+         */
         producer.shutdown();
     }
 }


[16/31] incubator-rocketmq git commit: Merge branch 'master' into ROCKETMQ-57

Posted by st...@apache.org.
Merge branch 'master' into ROCKETMQ-57


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/63de56c7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/63de56c7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/63de56c7

Branch: refs/heads/ROCKETMQ-54
Commit: 63de56c7b6cada18338bb4be5e84fb17a379e5ac
Parents: f8d881b b4108d2
Author: stevenschew <st...@apache.org>
Authored: Fri Jan 20 14:55:52 2017 +0800
Committer: stevenschew <st...@apache.org>
Committed: Fri Jan 20 14:55:52 2017 +0800

----------------------------------------------------------------------
 .travis.yml                                     |   1 +
 BUILDING                                        |   2 +-
 .../rocketmq/broker/out/BrokerOuterAPI.java     |   1 -
 .../subscription/SubscriptionGroupManager.java  |   2 +-
 .../rocketmq/client/impl/MQClientManager.java   |   3 +-
 .../processor/DefaultRequestProcessorTest.java  | 246 +++++++++++++++
 pom.xml                                         |  73 +++--
 .../remoting/protocol/RemotingSerializable.java |   2 +-
 .../remoting/protocol/RocketMQSerializable.java |  17 +-
 style/rmq_checkstyle.xml                        |   1 -
 test/pom.xml                                    |  52 ++++
 .../test/client/mq/MQAsyncProducer.java         |  85 ++++++
 .../test/client/rmq/RMQAsyncSendProducer.java   | 226 ++++++++++++++
 .../test/client/rmq/RMQBroadCastConsumer.java   |  37 +++
 .../test/client/rmq/RMQNormalConsumer.java      |  90 ++++++
 .../test/client/rmq/RMQNormalProducer.java      | 167 ++++++++++
 .../clientinterface/AbstractMQConsumer.java     | 112 +++++++
 .../clientinterface/AbstractMQProducer.java     | 151 +++++++++
 .../test/clientinterface/MQCollector.java       | 108 +++++++
 .../test/clientinterface/MQConsumer.java        |  26 ++
 .../test/clientinterface/MQProducer.java        |  30 ++
 .../rocketmq/test/factory/ConsumerFactory.java  |  45 +++
 .../rocketmq/test/factory/MQMessageFactory.java | 128 ++++++++
 .../rocketmq/test/factory/MessageFactory.java   |  62 ++++
 .../rocketmq/test/factory/ProducerFactory.java  |  37 +++
 .../test/factory/SendCallBackFactory.java       |  35 +++
 .../rocketmq/test/factory/TagMessage.java       | 108 +++++++
 .../test/listener/AbstractListener.java         | 104 +++++++
 .../rmq/concurrent/RMQDelayListner.java         |  61 ++++
 .../rmq/concurrent/RMQNormalListner.java        |  70 +++++
 .../listener/rmq/order/RMQOrderListener.java    |  85 ++++++
 .../rocketmq/test/message/MessageQueueMsg.java  |  62 ++++
 .../rocketmq/test/sendresult/SendResult.java    |  62 ++++
 .../apache/rocketmq/test/util/Condition.java    |  23 ++
 .../test/util/DuplicateMessageInfo.java         | 137 +++++++++
 .../org/apache/rocketmq/test/util/FileUtil.java | 108 +++++++
 .../org/apache/rocketmq/test/util/MQAdmin.java  | 164 ++++++++++
 .../rocketmq/test/util/MQRandomUtils.java       |  28 ++
 .../org/apache/rocketmq/test/util/MQWait.java   |  93 ++++++
 .../apache/rocketmq/test/util/RandomUtil.java   | 306 +++++++++++++++++++
 .../apache/rocketmq/test/util/RandomUtils.java  |  91 ++++++
 .../org/apache/rocketmq/test/util/TestUtil.java | 122 ++++++++
 .../apache/rocketmq/test/util/TestUtils.java    |  50 +++
 .../apache/rocketmq/test/util/VerifyUtils.java  | 146 +++++++++
 .../test/util/data/collect/DataCollector.java   |  45 +++
 .../util/data/collect/DataCollectorManager.java | 112 +++++++
 .../test/util/data/collect/DataFilter.java      |  22 ++
 .../collect/impl/ListDataCollectorImpl.java     |  95 ++++++
 .../data/collect/impl/MapDataCollectorImpl.java | 111 +++++++
 .../test/util/parallel/ParallelTask.java        |  43 +++
 .../util/parallel/ParallelTaskExecutor.java     |  67 ++++
 .../rocketmq/test/util/parallel/Task4Test.java  |  30 ++
 .../org/apache/rocketmq/test/base/BaseConf.java | 162 ++++++++++
 .../rocketmq/test/base/IntegrationTestBase.java | 143 +++++++++
 .../balance/NormalMsgDynamicBalanceIT.java      | 111 +++++++
 .../balance/NormalMsgStaticBalanceIT.java       | 109 +++++++
 .../consumer/broadcast/BaseBroadCastIT.java     |  56 ++++
 .../normal/BroadCastNormalMsgNotRecvIT.java     |  73 +++++
 .../normal/BroadCastNormalMsgRecvCrashIT.java   |  90 ++++++
 .../normal/BroadCastNormalMsgRecvFailIT.java    |  72 +++++
 .../BroadCastNormalMsgRecvStartLaterIT.java     |  88 ++++++
 .../BroadCastNormalMsgTwoDiffGroupRecvIT.java   |  78 +++++
 .../normal/NormalMsgTwoSameGroupConsumerIT.java |  78 +++++
 .../broadcast/order/OrderMsgBroadCastIT.java    |  75 +++++
 .../tag/BroadCastTwoConsumerFilterIT.java       |  78 +++++
 .../tag/BroadCastTwoConsumerSubDiffTagIT.java   |  75 +++++
 .../tag/BroadCastTwoConsumerSubTagIT.java       |  75 +++++
 .../consumer/cluster/DynamicAddAndCrashIT.java  | 103 +++++++
 .../consumer/cluster/DynamicAddConsumerIT.java  |  97 ++++++
 .../cluster/DynamicCrashConsumerIT.java         | 100 ++++++
 .../test/client/consumer/tag/MulTagSubIT.java   | 156 ++++++++++
 .../consumer/tag/TagMessageWith1ConsumerIT.java | 197 ++++++++++++
 .../tag/TagMessageWithMulConsumerIT.java        | 196 ++++++++++++
 .../tag/TagMessageWithSameGroupConsumerIT.java  | 115 +++++++
 .../consumer/topic/MulConsumerMulTopicIT.java   | 108 +++++++
 .../consumer/topic/OneConsumerMulTopicIT.java   | 104 +++++++
 .../producer/async/AsyncSendExceptionIT.java    | 150 +++++++++
 .../async/AsyncSendWithMessageQueueIT.java      |  85 ++++++
 .../AsyncSendWithMessageQueueSelectorIT.java    | 106 +++++++
 .../async/AsyncSendWithOnlySendCallBackIT.java  |  64 ++++
 .../producer/exception/msg/ChinaPropIT.java     |  74 +++++
 .../exception/msg/MessageExceptionIT.java       | 129 ++++++++
 .../exception/msg/MessageUserPropIT.java        |  94 ++++++
 .../ProducerGroupAndInstanceNameValidityIT.java |  69 +++++
 .../producer/oneway/OneWaySendExceptionIT.java  |  78 +++++
 .../client/producer/oneway/OneWaySendIT.java    |  64 ++++
 .../producer/oneway/OneWaySendWithMQIT.java     |  79 +++++
 .../oneway/OneWaySendWithSelectorIT.java        | 104 +++++++
 .../order/OrderMsgDynamicRebalanceIT.java       | 115 +++++++
 .../test/client/producer/order/OrderMsgIT.java  | 108 +++++++
 .../producer/order/OrderMsgRebalanceIT.java     | 133 ++++++++
 .../producer/order/OrderMsgWithTagIT.java       | 169 ++++++++++
 .../querymsg/QueryMsgByIdExceptionIT.java       |  81 +++++
 .../producer/querymsg/QueryMsgByIdIT.java       |  75 +++++
 .../producer/querymsg/QueryMsgByKeyIT.java      | 104 +++++++
 .../apache/rocketmq/test/delay/DelayConf.java   |  27 ++
 .../rocketmq/test/delay/NormalMsgDelayIT.java   | 116 +++++++
 .../test/smoke/NormalMessageSendAndRecvIT.java  |  62 ++++
 test/src/test/resources/log4j.xml               |  46 +++
 test/src/test/resources/logback-test.xml        |  33 ++
 100 files changed, 8750 insertions(+), 38 deletions(-)
----------------------------------------------------------------------



[11/31] incubator-rocketmq git commit: [RocketMQ-58] Add integration test for RocketMQ, also thanks @fenglianghfl for this commit, closes apache/incubator-rocketmq#46

Posted by st...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/message/MessageQueueMsg.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/message/MessageQueueMsg.java b/test/src/main/java/org/apache/rocketmq/test/message/MessageQueueMsg.java
new file mode 100644
index 0000000..38c2b6b
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/message/MessageQueueMsg.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.message;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.test.factory.MQMessageFactory;
+
+public class MessageQueueMsg {
+    private Map<MessageQueue, List<Object>> msgsWithMQ = null;
+    private Map<Integer, List<Object>> msgsWithMQId = null;
+    private Collection<Object> msgBodys = null;
+
+    public MessageQueueMsg(List<MessageQueue> mqs, int msgSize) {
+        this(mqs, msgSize, null);
+    }
+
+    public MessageQueueMsg(List<MessageQueue> mqs, int msgSize, String tag) {
+        msgsWithMQ = MQMessageFactory.getMsgByMQ(mqs, msgSize, tag);
+        msgsWithMQId = new HashMap<Integer, List<Object>>();
+        msgBodys = new ArrayList<Object>();
+        init();
+    }
+
+    public Map<MessageQueue, List<Object>> getMsgsWithMQ() {
+        return msgsWithMQ;
+    }
+
+    public Map<Integer, List<Object>> getMsgWithMQId() {
+        return msgsWithMQId;
+    }
+
+    public Collection<Object> getMsgBodys() {
+        return msgBodys;
+    }
+
+    private void init() {
+        for (MessageQueue mq : msgsWithMQ.keySet()) {
+            msgsWithMQId.put(mq.getQueueId(), msgsWithMQ.get(mq));
+            msgBodys.addAll(MQMessageFactory.getMessageBody(msgsWithMQ.get(mq)));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/sendresult/SendResult.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/sendresult/SendResult.java b/test/src/main/java/org/apache/rocketmq/test/sendresult/SendResult.java
new file mode 100644
index 0000000..d53ee7d
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/sendresult/SendResult.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.sendresult;
+
+public class SendResult {
+    private boolean sendResult = false;
+    private String msgId = null;
+    private Exception sendException = null;
+    private String brokerIp = null;
+
+    public String getBrokerIp() {
+        return brokerIp;
+    }
+
+    public void setBrokerIp(String brokerIp) {
+        this.brokerIp = brokerIp;
+    }
+
+    public boolean isSendResult() {
+        return sendResult;
+    }
+
+    public void setSendResult(boolean sendResult) {
+        this.sendResult = sendResult;
+    }
+
+    public String getMsgId() {
+        return msgId;
+    }
+
+    public void setMsgId(String msgId) {
+        this.msgId = msgId;
+    }
+
+    public Exception getSendException() {
+        return sendException;
+    }
+
+    public void setSendException(Exception sendException) {
+        this.sendException = sendException;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("sendstatus:%s msgId:%s", sendResult, msgId);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/Condition.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/Condition.java b/test/src/main/java/org/apache/rocketmq/test/util/Condition.java
new file mode 100644
index 0000000..3c5f403
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/Condition.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util;
+
+public interface Condition {
+    boolean meetCondition();
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/DuplicateMessageInfo.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/DuplicateMessageInfo.java b/test/src/main/java/org/apache/rocketmq/test/util/DuplicateMessageInfo.java
new file mode 100644
index 0000000..8bd93b6
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/DuplicateMessageInfo.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.DecimalFormat;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+public class DuplicateMessageInfo<T> {
+
+    public void checkDuplicatedMessageInfo(boolean bPrintLog,
+        List<List<T>> lQueueList) throws IOException {
+        int msgListSize = lQueueList.size();
+        int maxmsgList = 0;
+        Map<T, Integer> msgIdMap = new HashMap<T, Integer>();
+        Map<Integer, Integer> dupMsgMap = new HashMap<Integer, Integer>();
+
+        for (int i = 0; i < msgListSize; i++) {
+            if (maxmsgList < lQueueList.get(i).size())
+                maxmsgList = lQueueList.get(i).size();
+        }
+
+        List<StringBuilder> strBQueue = new LinkedList<StringBuilder>();
+        for (int i = 0; i < msgListSize; i++)
+            strBQueue.add(new StringBuilder());
+
+        for (int msgListIndex = 0; msgListIndex < maxmsgList; msgListIndex++) {
+            for (int msgQueueListIndex = 0; msgQueueListIndex < msgListSize; msgQueueListIndex++) {
+                if (msgListIndex < lQueueList.get(msgQueueListIndex).size()) {
+                    if (msgIdMap.containsKey(lQueueList.get(msgQueueListIndex).get(msgListIndex))) {
+                        if (dupMsgMap.containsKey(msgQueueListIndex)) {
+                            int dupMsgCount = dupMsgMap.get(msgQueueListIndex);
+                            dupMsgCount++;
+                            dupMsgMap.remove(msgQueueListIndex);
+                            dupMsgMap.put(msgQueueListIndex, dupMsgCount);
+                        } else {
+                            dupMsgMap.put(msgQueueListIndex, 1);
+                        }
+
+                        strBQueue.get(msgQueueListIndex).append("" + msgQueueListIndex + "\t" +
+                            msgIdMap.get(lQueueList.get(msgQueueListIndex).get(msgListIndex)) + "\t"
+                            + lQueueList.get(msgQueueListIndex).get(msgListIndex) + "\r\n");
+                    } else {
+                        msgIdMap.put(lQueueList.get(msgQueueListIndex).get(msgListIndex), msgQueueListIndex);
+                    }
+                }
+            }
+        }
+
+        int msgTotalNum = getMsgTotalNumber(lQueueList);
+        int msgTotalDupNum = getDuplicateMsgNum(dupMsgMap);
+        int msgNoDupNum = msgTotalNum - msgTotalDupNum;
+        float msgDupRate = ((float) msgTotalDupNum / (float) msgTotalNum) * 100.0f;
+        StringBuilder strBuilder = new StringBuilder();
+
+        strBuilder.append("msgTotalNum:" + msgTotalNum + "\r\n");
+        strBuilder.append("msgTotalDupNum:" + msgTotalDupNum + "\r\n");
+        strBuilder.append("msgNoDupNum:" + msgNoDupNum + "\r\n");
+        strBuilder.append("msgDupRate" + getFloatNumString(msgDupRate) + "%\r\n");
+
+        strBuilder.append("queue\tmsg(dupNum/dupRate)\tdupRate\r\n");
+        for (int i = 0; i < dupMsgMap.size(); i++) {
+            int msgDupNum = dupMsgMap.get(i);
+            int msgNum = lQueueList.get(i).size();
+            float msgQueueDupRate = ((float) msgDupNum / (float) msgTotalDupNum) * 100.0f;
+            float msgQueueInnerDupRate = ((float) msgDupNum / (float) msgNum) * 100.0f;
+
+            strBuilder.append(i + "\t" + msgDupNum + "/" + getFloatNumString(msgQueueDupRate) + "%" + "\t\t" +
+                getFloatNumString(msgQueueInnerDupRate) + "%\r\n");
+        }
+
+        System.out.print(strBuilder.toString());
+        String titleString = "queue\tdupQueue\tdupMsg\r\n";
+        System.out.print(titleString);
+
+        for (int i = 0; i < msgListSize; i++)
+            System.out.print(strBQueue.get(i).toString());
+
+        if (bPrintLog) {
+            String logFileNameStr = "D:" + File.separator + "checkDuplicatedMessageInfo.txt";
+            File logFileNameFile = new File(logFileNameStr);
+            OutputStream out = new FileOutputStream(logFileNameFile, true);
+
+            String strToWrite;
+            byte[] byteToWrite;
+            strToWrite = strBuilder.toString() + titleString;
+            for (int i = 0; i < msgListSize; i++)
+                strToWrite += strBQueue.get(i).toString() + "\r\n";
+
+            byteToWrite = strToWrite.getBytes();
+            out.write(byteToWrite);
+            out.close();
+        }
+    }
+
+    private int getMsgTotalNumber(List<List<T>> lQueueList) {
+        int msgTotalNum = 0;
+        for (int i = 0; i < lQueueList.size(); i++) {
+            msgTotalNum += lQueueList.get(i).size();
+        }
+        return msgTotalNum;
+    }
+
+    private int getDuplicateMsgNum(Map<Integer, Integer> msgDupMap) {
+        int msgDupNum = 0;
+        for (int i = 0; i < msgDupMap.size(); i++) {
+            msgDupNum += msgDupMap.get(i);
+        }
+        return msgDupNum;
+    }
+
+    private String getFloatNumString(float fNum) {
+        DecimalFormat dcmFmt = new DecimalFormat("0.00");
+        return dcmFmt.format(fNum);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/FileUtil.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/FileUtil.java b/test/src/main/java/org/apache/rocketmq/test/util/FileUtil.java
new file mode 100644
index 0000000..44db782
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/FileUtil.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Properties;
+
+public class FileUtil {
+    private static String lineSeperator = System.getProperty("line.separator");
+
+    private String filePath = "";
+    private String fileName = "";
+
+    public FileUtil(String filePath, String fileName) {
+        this.filePath = filePath;
+        this.fileName = fileName;
+    }
+
+    public static void main(String args[]) {
+        String filePath = FileUtil.class.getResource("/").getPath();
+        String fileName = "test.txt";
+        FileUtil fileUtil = new FileUtil(filePath, fileName);
+        Properties properties = new Properties();
+        properties.put("xx", "yy");
+        properties.put("yy", "xx");
+        fileUtil.writeProperties(properties);
+    }
+
+    public void deleteFile() {
+        File file = new File(filePath + File.separator + fileName);
+        if (file.exists()) {
+            file.delete();
+        }
+    }
+
+    public void appendFile(String content) {
+        File file = openFile();
+        String newContent = lineSeperator + content;
+        writeFile(file, newContent, true);
+    }
+
+    public void coverFile(String content) {
+        File file = openFile();
+        writeFile(file, content, false);
+    }
+
+    public void writeProperties(Properties properties) {
+        String content = getPropertiesAsString(properties);
+        this.coverFile(content);
+    }
+
+    private String getPropertiesAsString(Properties properties) {
+        StringBuilder sb = new StringBuilder();
+        for (Object key : properties.keySet()) {
+            sb.append(key).append("=").append(properties.getProperty((String) key))
+                .append(lineSeperator);
+        }
+        return sb.toString();
+    }
+
+    private void writeFile(File file, String content, boolean append) {
+        FileWriter writer = null;
+        try {
+            writer = new FileWriter(file.getAbsoluteFile(), append);
+            writer.write(content);
+            writer.flush();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if (writer != null) {
+                try {
+                    writer.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    private File openFile() {
+        File file = new File(filePath + File.separator + fileName);
+        if (!file.exists()) {
+            try {
+                file.createNewFile();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return file;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/MQAdmin.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/MQAdmin.java b/test/src/main/java/org/apache/rocketmq/test/util/MQAdmin.java
new file mode 100644
index 0000000..c3e0572
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/MQAdmin.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util;
+
+import java.util.HashMap;
+import java.util.Set;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.common.admin.TopicStatsTable;
+import org.apache.rocketmq.common.protocol.body.ClusterInfo;
+import org.apache.rocketmq.common.protocol.route.BrokerData;
+import org.apache.rocketmq.common.subscription.SubscriptionGroupConfig;
+import org.apache.rocketmq.tools.admin.DefaultMQAdminExt;
+import org.apache.rocketmq.tools.command.CommandUtil;
+
+public class MQAdmin {
+    private static Logger log = Logger.getLogger(MQAdmin.class);
+
+    public static boolean createTopic(String nameSrvAddr, String clusterName, String topic,
+        int queueNum) {
+        int defaultWaitTime = 5;
+        return createTopic(nameSrvAddr, clusterName, topic, queueNum, defaultWaitTime);
+    }
+
+    public static boolean createTopic(String nameSrvAddr, String clusterName, String topic,
+        int queueNum, int waitTimeSec) {
+        boolean createResult = false;
+        DefaultMQAdminExt mqAdminExt = new DefaultMQAdminExt();
+        mqAdminExt.setNamesrvAddr(nameSrvAddr);
+        try {
+            mqAdminExt.start();
+            mqAdminExt.createTopic(clusterName, topic, queueNum);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        long startTime = System.currentTimeMillis();
+        while (!createResult) {
+            createResult = checkTopicExist(mqAdminExt, topic);
+            if (System.currentTimeMillis() - startTime < waitTimeSec * 1000) {
+                TestUtils.waitForMonment(100);
+            } else {
+                log.error(String.format("timeout,but create topic[%s] failed!", topic));
+                break;
+            }
+        }
+
+        mqAdminExt.shutdown();
+        return createResult;
+    }
+
+    private static boolean checkTopicExist(DefaultMQAdminExt mqAdminExt, String topic) {
+        boolean createResult = false;
+        try {
+            TopicStatsTable topicInfo = mqAdminExt.examineTopicStats(topic);
+            createResult = !topicInfo.getOffsetTable().isEmpty();
+        } catch (Exception e) {
+        }
+
+        return createResult;
+    }
+
+    public static boolean createSub(String nameSrvAddr, String clusterName, String consumerId) {
+        boolean createResult = true;
+        DefaultMQAdminExt mqAdminExt = new DefaultMQAdminExt();
+        mqAdminExt.setNamesrvAddr(nameSrvAddr);
+        SubscriptionGroupConfig config = new SubscriptionGroupConfig();
+        config.setGroupName(consumerId);
+        try {
+            mqAdminExt.start();
+            Set<String> masterSet = CommandUtil.fetchMasterAddrByClusterName(mqAdminExt,
+                clusterName);
+            for (String addr : masterSet) {
+                try {
+                    mqAdminExt.createAndUpdateSubscriptionGroupConfig(addr, config);
+                    log.info(String.format("create subscription group %s to %s success.\n", consumerId,
+                        addr));
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    Thread.sleep(1000 * 1);
+                }
+            }
+        } catch (Exception e) {
+            createResult = false;
+            e.printStackTrace();
+        }
+        mqAdminExt.shutdown();
+        return createResult;
+    }
+
+    public static ClusterInfo getCluster(String nameSrvAddr) {
+        DefaultMQAdminExt mqAdminExt = new DefaultMQAdminExt();
+        mqAdminExt.setNamesrvAddr(nameSrvAddr);
+        ClusterInfo clusterInfo = null;
+        try {
+            mqAdminExt.start();
+            clusterInfo = mqAdminExt.examineBrokerClusterInfo();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        mqAdminExt.shutdown();
+        return clusterInfo;
+    }
+
+    public static boolean isBrokerExist(String ns, String ip) {
+        ClusterInfo clusterInfo = getCluster(ns);
+        if (clusterInfo == null) {
+            return false;
+        } else {
+            HashMap<String, BrokerData> brokers = clusterInfo.getBrokerAddrTable();
+            for (String brokerName : brokers.keySet()) {
+                HashMap<Long, String> brokerIps = brokers.get(brokerName).getBrokerAddrs();
+                for (long brokerId : brokerIps.keySet()) {
+                    if (brokerIps.get(brokerId).contains(ip))
+                        return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    public void getSubConnection(String nameSrvAddr, String clusterName, String consumerId) {
+        boolean createResult = true;
+        DefaultMQAdminExt mqAdminExt = new DefaultMQAdminExt();
+        mqAdminExt.setNamesrvAddr(nameSrvAddr);
+        SubscriptionGroupConfig config = new SubscriptionGroupConfig();
+        config.setGroupName(consumerId);
+        try {
+            mqAdminExt.start();
+            Set<String> masterSet = CommandUtil.fetchMasterAddrByClusterName(mqAdminExt,
+                clusterName);
+            for (String addr : masterSet) {
+                try {
+
+                    System.out.printf("create subscription group %s to %s success.\n", consumerId,
+                        addr);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    Thread.sleep(1000 * 1);
+                }
+            }
+        } catch (Exception e) {
+            createResult = false;
+            e.printStackTrace();
+        }
+        mqAdminExt.shutdown();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/MQRandomUtils.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/MQRandomUtils.java b/test/src/main/java/org/apache/rocketmq/test/util/MQRandomUtils.java
new file mode 100644
index 0000000..1d82445
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/MQRandomUtils.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util;
+
+public class MQRandomUtils {
+    public static String getRandomTopic() {
+        return RandomUtils.getStringByUUID();
+    }
+
+    public static String getRandomConsumerGroup() {
+        return RandomUtils.getStringByUUID();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/MQWait.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/MQWait.java b/test/src/main/java/org/apache/rocketmq/test/util/MQWait.java
new file mode 100644
index 0000000..6edeeca
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/MQWait.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.listener.AbstractListener;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class MQWait {
+    private static Logger logger = Logger.getLogger(MQWait.class);
+
+    public static boolean waitConsumeAll(int timeoutMills, Collection<Object> allSendMsgs,
+        AbstractListener... listeners) {
+        boolean recvAll = false;
+        long startTime = System.currentTimeMillis();
+        Collection<Object> noDupMsgs = new ArrayList<Object>();
+        while (!recvAll) {
+            if ((System.currentTimeMillis() - startTime) < timeoutMills) {
+                noDupMsgs.clear();
+                try {
+                    for (AbstractListener listener : listeners) {
+                        Collection<Object> recvMsgs = Collections
+                            .synchronizedCollection(listener.getAllUndupMsgBody());
+                        noDupMsgs.addAll(VerifyUtils.getFilterdMessage(allSendMsgs, recvMsgs));
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+
+                try {
+                    assertThat(noDupMsgs).containsAllIn(allSendMsgs);
+                    recvAll = true;
+                    break;
+                } catch (Throwable e) {
+                }
+                TestUtil.waitForMonment(500);
+            } else {
+                logger.error(String.format(
+                    "timeout but still not receive all messages,expectSize[%s],realSize[%s]",
+                    allSendMsgs.size(), noDupMsgs.size()));
+                break;
+            }
+        }
+
+        return recvAll;
+    }
+
+    public static void setCondition(Condition condition, int waitTimeMills, int intervalMills) {
+        long startTime = System.currentTimeMillis();
+        while (!condition.meetCondition()) {
+            if (System.currentTimeMillis() - startTime > waitTimeMills) {
+                logger.error("time out,but contidion still not meet!");
+                break;
+            } else {
+                TestUtil.waitForMonment(intervalMills);
+            }
+        }
+    }
+
+    public static void main(String args[]) {
+
+        long start = System.currentTimeMillis();
+        MQWait.setCondition(new Condition() {
+            int i = 0;
+
+            public boolean meetCondition() {
+                i++;
+                return i == 100;
+            }
+        }, 10 * 1000, 200);
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/RandomUtil.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/RandomUtil.java b/test/src/main/java/org/apache/rocketmq/test/util/RandomUtil.java
new file mode 100644
index 0000000..1c2bdac
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/RandomUtil.java
@@ -0,0 +1,306 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.Set;
+import java.util.UUID;
+
+public final class RandomUtil {
+
+    private static final int UNICODE_START = '\u4E00';
+    private static final int UNICODE_END = '\u9FA0';
+    private static Random rd = new Random();
+
+    private RandomUtil() {
+
+    }
+
+    public static long getLong() {
+        return rd.nextLong();
+    }
+
+    public static long getLongMoreThanZero() {
+        long res = rd.nextLong();
+        while (res <= 0) {
+            res = rd.nextLong();
+        }
+        return res;
+    }
+
+    public static long getLongLessThan(long n) {
+        long res = rd.nextLong();
+        return res % n;
+    }
+
+    public static long getLongMoreThanZeroLessThan(long n) {
+        long res = getLongLessThan(n);
+        while (res <= 0) {
+            res = getLongLessThan(n);
+        }
+        return res;
+    }
+
+    public static long getLongBetween(long n, long m) {
+        if (m <= n) {
+            return n;
+        }
+        long res = getLongMoreThanZero();
+        return n + res % (m - n);
+    }
+
+    public static int getInteger() {
+        return rd.nextInt();
+    }
+
+    public static int getIntegerMoreThanZero() {
+        int res = rd.nextInt();
+        while (res <= 0) {
+            res = rd.nextInt();
+        }
+        return res;
+    }
+
+    public static int getIntegerLessThan(int n) {
+        int res = rd.nextInt();
+        return res % n;
+    }
+
+    public static int getIntegerMoreThanZeroLessThan(int n) {
+        int res = rd.nextInt(n);
+        while (res == 0) {
+            res = rd.nextInt(n);
+        }
+        return res;
+    }
+
+    public static int getIntegerBetween(int n, int m)// m\ufffd\ufffd\u05b5\ufffd\ufffd\ufffd\ufffd\u03aa\ufffd\ufffd\ufffd\u0623\ufffd
+    {
+        if (m == n) {
+            return n;
+        }
+        int res = getIntegerMoreThanZero();
+        return n + res % (m - n);
+    }
+
+    private static char getChar(int arg[]) {
+        int size = arg.length;
+        int c = rd.nextInt(size / 2);
+        c = c * 2;
+        return (char) (getIntegerBetween(arg[c], arg[c + 1]));
+    }
+
+    private static String getString(int n, int arg[]) {
+        StringBuilder res = new StringBuilder();
+        for (int i = 0; i < n; i++) {
+            res.append(getChar(arg));
+        }
+        return res.toString();
+    }
+
+    public static String getStringWithCharacter(int n) {
+        int arg[] = new int[] {'a', 'z' + 1, 'A', 'Z' + 1};
+        return getString(n, arg);
+    }
+
+    public static String getStringWithNumber(int n) {
+        int arg[] = new int[] {'0', '9' + 1};
+        return getString(n, arg);
+    }
+
+    public static String getStringWithNumAndCha(int n) {
+        int arg[] = new int[] {'a', 'z' + 1, 'A', 'Z' + 1, '0', '9' + 1};
+        return getString(n, arg);
+    }
+
+    public static String getStringShortenThan(int n) {
+        int len = getIntegerMoreThanZeroLessThan(n);
+        return getStringWithCharacter(len);
+    }
+
+    public static String getStringWithNumAndChaShortenThan(int n) {
+        int len = getIntegerMoreThanZeroLessThan(n);
+        return getStringWithNumAndCha(len);
+    }
+
+    public static String getStringBetween(int n, int m) {
+        int len = getIntegerBetween(n, m);
+        return getStringWithCharacter(len);
+    }
+
+    public static String getStringWithNumAndChaBetween(int n, int m) {
+        int len = getIntegerBetween(n, m);
+        return getStringWithNumAndCha(len);
+    }
+
+    public static String getStringWithPrefix(int n, String prefix) {
+        int len = prefix.length();
+        if (n <= len)
+            return prefix;
+        else {
+            len = n - len;
+            StringBuilder res = new StringBuilder(prefix);
+            res.append(getStringWithCharacter(len));
+            return res.toString();
+        }
+    }
+
+    public static String getStringWithSuffix(int n, String suffix) {
+
+        int len = suffix.length();
+        if (n <= len)
+            return suffix;
+        else {
+            len = n - len;
+            StringBuilder res = new StringBuilder();
+            res.append(getStringWithCharacter(len));
+            res.append(suffix);
+            return res.toString();
+        }
+    }
+
+    public static String getStringWithBoth(int n, String prefix, String suffix) {
+        int len = prefix.length() + suffix.length();
+        StringBuilder res = new StringBuilder(prefix);
+        if (n <= len)
+            return res.append(suffix).toString();
+        else {
+            len = n - len;
+            res.append(getStringWithCharacter(len));
+            res.append(suffix);
+            return res.toString();
+        }
+    }
+
+    public static String getCheseWordWithPrifix(int n, String prefix) {
+        int len = prefix.length();
+        if (n <= len)
+            return prefix;
+        else {
+            len = n - len;
+            StringBuilder res = new StringBuilder(prefix);
+            res.append(getCheseWord(len));
+            return res.toString();
+        }
+    }
+
+    public static String getCheseWordWithSuffix(int n, String suffix) {
+
+        int len = suffix.length();
+        if (n <= len)
+            return suffix;
+        else {
+            len = n - len;
+            StringBuilder res = new StringBuilder();
+            res.append(getCheseWord(len));
+            res.append(suffix);
+            return res.toString();
+        }
+    }
+
+    public static String getCheseWordWithBoth(int n, String prefix, String suffix) {
+        int len = prefix.length() + suffix.length();
+        StringBuilder res = new StringBuilder(prefix);
+        if (n <= len)
+            return res.append(suffix).toString();
+        else {
+            len = n - len;
+            res.append(getCheseWord(len));
+            res.append(suffix);
+            return res.toString();
+        }
+    }
+
+    public static String getCheseWord(int len) {
+        StringBuilder res = new StringBuilder();
+        for (int i = 0; i < len; i++) {
+            char str = getCheseChar();
+            res.append(str);
+        }
+        return res.toString();
+    }
+
+    private static char getCheseChar() {
+        return (char) (UNICODE_START + rd.nextInt(UNICODE_END - UNICODE_START));
+    }
+
+    public static boolean getBoolean() {
+        return getIntegerMoreThanZeroLessThan(3) == 1;
+    }
+
+    public static String getStringByUUID() {
+        return UUID.randomUUID().toString();
+    }
+
+    public static int[] getRandomArray(int min, int max, int n) {
+        int len = max - min + 1;
+
+        if (max < min || n > len) {
+            return null;
+        }
+
+        int[] source = new int[len];
+        for (int i = min; i < min + len; i++) {
+            source[i - min] = i;
+        }
+
+        int[] result = new int[n];
+        Random rd = new Random();
+        int index = 0;
+        for (int i = 0; i < result.length; i++) {
+            index = Math.abs(rd.nextInt() % len--);
+            result[i] = source[index];
+            source[index] = source[len];
+        }
+        return result;
+    }
+
+    public static Collection<Integer> getRandomCollection(int min, int max, int n) {
+        Set<Integer> res = new HashSet<Integer>();
+        int mx = max;
+        int mn = min;
+        if (n == (max + 1 - min)) {
+            for (int i = 1; i <= n; i++) {
+                res.add(i);
+            }
+            return res;
+        }
+        for (int i = 0; i < n; i++) {
+            int v = getIntegerBetween(mn, mx);
+            if (v == mx) {
+                mx--;
+            }
+            if (v == mn) {
+                mn++;
+            }
+            while (res.contains(v)) {
+                v = getIntegerBetween(mn, mx);
+                if (v == mx) {
+                    mx = v;
+                }
+                if (v == mn) {
+                    mn = v;
+                }
+            }
+            res.add(v);
+        }
+        return res;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/RandomUtils.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/RandomUtils.java b/test/src/main/java/org/apache/rocketmq/test/util/RandomUtils.java
new file mode 100644
index 0000000..9eca28b
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/RandomUtils.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util;
+
+import java.util.Random;
+import java.util.UUID;
+
+public class RandomUtils {
+    private static final int UNICODE_START = '\u4E00';
+    private static final int UNICODE_END = '\u9FA0';
+    private static Random rd = new Random();
+
+    private RandomUtils() {
+
+    }
+
+    public static String getStringByUUID() {
+        return UUID.randomUUID().toString();
+    }
+
+    public static String getCheseWord(int len) {
+        StringBuilder res = new StringBuilder();
+
+        for (int i = 0; i < len; ++i) {
+            char str = getCheseChar();
+            res.append(str);
+        }
+
+        return res.toString();
+    }
+
+    public static String getStringWithNumber(int n) {
+        int arg[] = new int[] {'0', '9' + 1};
+        return getString(n, arg);
+    }
+
+    public static String getStringWithCharacter(int n) {
+        int arg[] = new int[] {'a', 'z' + 1, 'A', 'Z' + 1};
+        return getString(n, arg);
+    }
+
+    private static String getString(int n, int arg[]) {
+        StringBuilder res = new StringBuilder();
+        for (int i = 0; i < n; i++) {
+            res.append(getChar(arg));
+        }
+        return res.toString();
+    }
+
+    private static char getChar(int arg[]) {
+        int size = arg.length;
+        int c = rd.nextInt(size / 2);
+        c = c * 2;
+        return (char) (getIntegerBetween(arg[c], arg[c + 1]));
+    }
+
+    public static int getIntegerBetween(int n, int m) {
+        if (m == n) {
+            return n;
+        }
+        int res = getIntegerMoreThanZero();
+        return n + res % (m - n);
+    }
+
+    public static int getIntegerMoreThanZero() {
+        int res = rd.nextInt();
+        while (res <= 0) {
+            res = rd.nextInt();
+        }
+        return res;
+    }
+
+    private static char getCheseChar() {
+        return (char) (UNICODE_START + rd.nextInt(UNICODE_END - UNICODE_START));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/TestUtil.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/TestUtil.java b/test/src/main/java/org/apache/rocketmq/test/util/TestUtil.java
new file mode 100644
index 0000000..591b3b7
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/TestUtil.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+public final class TestUtil {
+
+    private TestUtil() {
+    }
+
+    public static Long parseStringToLong(String s, Long defval) {
+        Long val = defval;
+        try {
+            val = Long.parseLong(s);
+        } catch (NumberFormatException e) {
+            val = defval;
+        }
+        return val;
+    }
+
+    public static Integer parseStringToInteger(String s, Integer defval) {
+        Integer val = defval;
+        try {
+            val = Integer.parseInt(s);
+        } catch (NumberFormatException e) {
+            val = defval;
+        }
+        return val;
+    }
+
+    public static String addQuoteToParamater(String param) {
+        StringBuilder sb = new StringBuilder("'");
+        sb.append(param).append("'");
+        return sb.toString();
+    }
+
+    public static void waitForMonment(long time) {
+        try {
+            Thread.sleep(time);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void waitForSeconds(long time) {
+        try {
+            TimeUnit.SECONDS.sleep(time);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void waitForMinutes(long time) {
+        try {
+            TimeUnit.MINUTES.sleep(time);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void waitForInputQuit() {
+        waitForInput("quit");
+    }
+
+    public static void waitForInput(String keyWord) {
+        waitForInput(keyWord,
+            String.format("The thread will wait until you input stop command[%s]:", keyWord));
+    }
+
+    public static void waitForInput(String keyWord, String info) {
+        try {
+            byte[] b = new byte[1024];
+            int n = System.in.read(b);
+            String s = new String(b, 0, n - 1).replace("\r", "").replace("\n", "");
+            while (!s.equals(keyWord)) {
+                n = System.in.read(b);
+                s = new String(b, 0, n - 1);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
+        List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(map.entrySet());
+        Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
+            public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
+                return (o1.getValue()).compareTo(o2.getValue());
+            }
+        });
+
+        Map<K, V> result = new LinkedHashMap<K, V>();
+        for (Map.Entry<K, V> entry : list) {
+            result.put(entry.getKey(), entry.getValue());
+        }
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/TestUtils.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/TestUtils.java b/test/src/main/java/org/apache/rocketmq/test/util/TestUtils.java
new file mode 100644
index 0000000..6326d46
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/TestUtils.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util;
+
+import java.util.concurrent.TimeUnit;
+
+public class TestUtils {
+    public static void waitForMonment(long time) {
+        try {
+            Thread.sleep(time);
+        } catch (InterruptedException var3) {
+            var3.printStackTrace();
+        }
+
+    }
+
+    public static void waitForSeconds(long time) {
+        try {
+            TimeUnit.SECONDS.sleep(time);
+        } catch (InterruptedException var3) {
+            var3.printStackTrace();
+        }
+
+    }
+
+    public static void waitForMinutes(long time) {
+        try {
+            TimeUnit.MINUTES.sleep(time);
+        } catch (InterruptedException var3) {
+            var3.printStackTrace();
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/VerifyUtils.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/VerifyUtils.java b/test/src/main/java/org/apache/rocketmq/test/util/VerifyUtils.java
new file mode 100644
index 0000000..965d2ee
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/VerifyUtils.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.common.message.MessageExt;
+
+public class VerifyUtils {
+    private static Logger logger = Logger.getLogger(VerifyUtils.class);
+
+    public static int verify(Collection<Object> sendMsgs, Collection<Object> recvMsgs) {
+        int miss = 0;
+        for (Object msg : sendMsgs) {
+            if (!recvMsgs.contains(msg)) {
+                miss++;
+            }
+        }
+
+        return miss;
+    }
+
+    public static Collection<Object> getFilterdMessage(Collection<Object> sendMsgs,
+        Collection<Object> recvMsgs) {
+        Collection<Object> recvMsgsSync = Collections.synchronizedCollection(recvMsgs);
+        Collection<Object> filterdMsgs = new ArrayList<Object>();
+        int filterNum = 0;
+        for (Object msg : recvMsgsSync) {
+            if (sendMsgs.contains(msg)) {
+                filterdMsgs.add(msg);
+            } else {
+                filterNum++;
+            }
+        }
+
+        logger.info(String.format("[%s] messages is filterd!", filterNum));
+        return filterdMsgs;
+    }
+
+    public static int verifyUserProperty(Collection<Object> sendMsgs, Collection<Object> recvMsgs) {
+        return 0;
+    }
+
+    public static void verifyMessageQueueId(int expectId, Collection<Object> msgs) {
+        for (Object msg : msgs) {
+            MessageExt msgEx = (MessageExt) msg;
+            assert expectId == msgEx.getQueueId();
+        }
+    }
+
+    public static boolean verifyBalance(int msgSize, float error, int... recvSize) {
+        boolean balance = true;
+        int evenSize = msgSize / recvSize.length;
+        for (int size : recvSize) {
+            if (Math.abs(size - evenSize) > error * evenSize) {
+                balance = false;
+                break;
+            }
+        }
+        return balance;
+    }
+
+    public static boolean verifyBalance(int msgSize, int... recvSize) {
+        return verifyBalance(msgSize, 0.1f, recvSize);
+    }
+
+    public static boolean verifyDelay(long delayTimeMills, Collection<Object> recvMsgTimes,
+        int errorMills) {
+        boolean delay = true;
+        for (Object timeObj : recvMsgTimes) {
+            long time = (Long) timeObj;
+            if (Math.abs(time - delayTimeMills) > errorMills) {
+                delay = false;
+                logger.info(String.format("delay error:%s", Math.abs(time - delayTimeMills)));
+            }
+        }
+        return delay;
+    }
+
+    public static boolean verifyDelay(long delayTimeMills, Collection<Object> recvMsgTimes) {
+        int errorMills = 500;
+        return verifyDelay(delayTimeMills, recvMsgTimes, errorMills);
+    }
+
+    public static boolean verifyOrder(Collection<Collection<Object>> queueMsgs) {
+        for (Collection<Object> msgs : queueMsgs) {
+            if (!verifyOrderMsg(msgs)) {
+                return false;
+            }
+        }
+        return true;
+
+    }
+
+    public static boolean verifyOrderMsg(Collection<Object> msgs) {
+        int min = Integer.MIN_VALUE;
+        int curr;
+        if (msgs.size() == 0 || msgs.size() == 1) {
+            return true;
+        } else {
+            for (Object msg : msgs) {
+                curr = Integer.parseInt((String) msg);
+                if (curr < min) {
+                    return false;
+                } else {
+                    min = curr;
+                }
+            }
+        }
+        return true;
+    }
+
+    public static boolean verifyRT(Collection<Object> rts, long maxRTMills) {
+        boolean rtExpect = true;
+        for (Object obj : rts) {
+            long rt = (Long) obj;
+            if (rt > maxRTMills) {
+                rtExpect = false;
+                logger.info(String.format("%s greater thran maxtRT:%s!", rt, maxRTMills));
+
+            }
+        }
+        return rtExpect;
+    }
+
+    public static void main(String args[]) {
+        verifyBalance(400, 0.1f, 230, 190);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/data/collect/DataCollector.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/data/collect/DataCollector.java b/test/src/main/java/org/apache/rocketmq/test/util/data/collect/DataCollector.java
new file mode 100644
index 0000000..cbbc8a5
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/data/collect/DataCollector.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util.data.collect;
+
+import java.util.Collection;
+
+public interface DataCollector {
+
+    void resetData();
+
+    Collection<Object> getAllData();
+
+    Collection<Object> getAllDataWithoutDuplicate();
+
+    void addData(Object data);
+
+    long getDataSizeWithoutDuplicate();
+
+    long getDataSize();
+
+    boolean isRepeatedData(Object data);
+
+    int getRepeatedTimeForData(Object data);
+
+    void removeData(Object data);
+
+    void lockIncrement();
+
+    void unlockIncrement();
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/data/collect/DataCollectorManager.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/data/collect/DataCollectorManager.java b/test/src/main/java/org/apache/rocketmq/test/util/data/collect/DataCollectorManager.java
new file mode 100644
index 0000000..47f4d81
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/data/collect/DataCollectorManager.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util.data.collect;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.rocketmq.test.util.data.collect.impl.ListDataCollectorImpl;
+import org.apache.rocketmq.test.util.data.collect.impl.MapDataCollectorImpl;
+
+public final class DataCollectorManager {
+    private static DataCollectorManager instance = new DataCollectorManager();
+    private Map<String, DataCollector> collectMap = new HashMap<String, DataCollector>();
+    private Object lock = new Object();
+
+    private DataCollectorManager() {
+    }
+
+    public static DataCollectorManager getInstance() {
+        return instance;
+    }
+
+    public DataCollector fetchDataCollector(String key) {
+        String realKey = key;
+        if (!collectMap.containsKey(realKey)) {
+            synchronized (lock) {
+                if (!collectMap.containsKey(realKey)) {
+                    DataCollector collect = (DataCollector) new MapDataCollectorImpl();
+                    collectMap.put(realKey, collect);
+                }
+            }
+        }
+        return collectMap.get(realKey);
+    }
+
+    public DataCollector fetchMapDataCollector(String key) {
+        String realKey = key;
+        if (!collectMap.containsKey(realKey)
+            || collectMap.get(realKey) instanceof ListDataCollectorImpl) {
+            synchronized (lock) {
+                if (!collectMap.containsKey(realKey)
+                    || collectMap.get(realKey) instanceof ListDataCollectorImpl) {
+                    DataCollector collect = null;
+                    if (collectMap.containsKey(realKey)) {
+                        DataCollector src = collectMap.get(realKey);
+                        collect = new MapDataCollectorImpl(src.getAllData());
+                    } else {
+                        collect = new MapDataCollectorImpl();
+                    }
+                    collectMap.put(realKey, collect);
+
+                }
+            }
+        }
+        return collectMap.get(realKey);
+    }
+
+    public DataCollector fetchListDataCollector(String key) {
+        String realKey = key;
+        if (!collectMap.containsKey(realKey)
+            || collectMap.get(realKey) instanceof MapDataCollectorImpl) {
+            synchronized (lock) {
+                if (!collectMap.containsKey(realKey)
+                    || collectMap.get(realKey) instanceof MapDataCollectorImpl) {
+                    DataCollector collect = null;
+                    if (collectMap.containsKey(realKey)) {
+                        DataCollector src = collectMap.get(realKey);
+                        collect = new ListDataCollectorImpl(src.getAllData());
+                    } else {
+                        collect = new ListDataCollectorImpl();
+                    }
+                    collectMap.put(realKey, collect);
+                }
+            }
+        }
+        return collectMap.get(realKey);
+    }
+
+    public void resetDataCollect(String key) {
+        if (collectMap.containsKey(key)) {
+            collectMap.get(key).resetData();
+        }
+    }
+
+    public void resetAll() {
+        for (Map.Entry<String, DataCollector> entry : collectMap.entrySet()) {
+            entry.getValue().resetData();
+        }
+    }
+
+    public void removeDataCollect(String key) {
+        collectMap.remove(key);
+    }
+
+    public void removeAll() {
+        collectMap.clear();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/data/collect/DataFilter.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/data/collect/DataFilter.java b/test/src/main/java/org/apache/rocketmq/test/util/data/collect/DataFilter.java
new file mode 100644
index 0000000..b01adc5
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/data/collect/DataFilter.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util.data.collect;
+
+public interface DataFilter {
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/data/collect/impl/ListDataCollectorImpl.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/data/collect/impl/ListDataCollectorImpl.java b/test/src/main/java/org/apache/rocketmq/test/util/data/collect/impl/ListDataCollectorImpl.java
new file mode 100644
index 0000000..82ab461
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/data/collect/impl/ListDataCollectorImpl.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util.data.collect.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import org.apache.rocketmq.test.util.data.collect.DataCollector;
+
+public class ListDataCollectorImpl implements DataCollector {
+
+    private List<Object> datas = new ArrayList<Object>();
+    private boolean lock = false;
+
+    public ListDataCollectorImpl() {
+
+    }
+
+    public ListDataCollectorImpl(Collection<Object> datas) {
+        for (Object data : datas) {
+            addData(data);
+        }
+    }
+
+    public Collection<Object> getAllData() {
+        return datas;
+    }
+
+    public void resetData() {
+        datas.clear();
+        unlockIncrement();
+    }
+
+    public long getDataSizeWithoutDuplicate() {
+        return getAllDataWithoutDuplicate().size();
+    }
+
+    public synchronized void addData(Object data) {
+        if (lock) {
+            return;
+        }
+        datas.add(data);
+    }
+
+    public long getDataSize() {
+        return datas.size();
+    }
+
+    public boolean isRepeatedData(Object data) {
+        return Collections.frequency(datas, data) == 1;
+    }
+
+    public Collection<Object> getAllDataWithoutDuplicate() {
+        return new HashSet<Object>(datas);
+    }
+
+    public int getRepeatedTimeForData(Object data) {
+        int res = 0;
+        for (Object obj : datas) {
+            if (obj.equals(data)) {
+                res++;
+            }
+        }
+        return res;
+    }
+
+    public void removeData(Object data) {
+        datas.remove(data);
+    }
+
+    public void lockIncrement() {
+        lock = true;
+    }
+
+    public void unlockIncrement() {
+        lock = false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/data/collect/impl/MapDataCollectorImpl.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/data/collect/impl/MapDataCollectorImpl.java b/test/src/main/java/org/apache/rocketmq/test/util/data/collect/impl/MapDataCollectorImpl.java
new file mode 100644
index 0000000..899bb85
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/data/collect/impl/MapDataCollectorImpl.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util.data.collect.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.rocketmq.test.util.data.collect.DataCollector;
+
+public class MapDataCollectorImpl implements DataCollector {
+
+    private Map<Object, AtomicInteger> datas = new ConcurrentHashMap<Object, AtomicInteger>();
+    private boolean lock = false;
+
+    public MapDataCollectorImpl() {
+
+    }
+
+    public MapDataCollectorImpl(Collection<Object> datas) {
+        for (Object data : datas) {
+            addData(data);
+        }
+    }
+
+    public synchronized void addData(Object data) {
+        if (lock) {
+            return;
+        }
+        if (datas.containsKey(data)) {
+            datas.get(data).addAndGet(1);
+        } else {
+            datas.put(data, new AtomicInteger(1));
+        }
+    }
+
+    public Collection<Object> getAllData() {
+        List<Object> lst = new ArrayList<Object>();
+        for (Entry<Object, AtomicInteger> entry : datas.entrySet()) {
+            for (int i = 0; i < entry.getValue().get(); i++) {
+                lst.add(entry.getKey());
+            }
+        }
+        return lst;
+    }
+
+    public long getDataSizeWithoutDuplicate() {
+        return datas.keySet().size();
+    }
+
+    public void resetData() {
+        datas.clear();
+        unlockIncrement();
+    }
+
+    public long getDataSize() {
+        long sum = 0;
+        for (AtomicInteger count : datas.values()) {
+            sum = sum + count.get();
+        }
+        return sum;
+    }
+
+    public boolean isRepeatedData(Object data) {
+        if (datas.containsKey(data)) {
+            return datas.get(data).get() == 1;
+        }
+        return false;
+    }
+
+    public Collection<Object> getAllDataWithoutDuplicate() {
+        return datas.keySet();
+    }
+
+    public int getRepeatedTimeForData(Object data) {
+        if (datas.containsKey(data)) {
+            return datas.get(data).intValue();
+        }
+        return 0;
+    }
+
+    public void removeData(Object data) {
+        datas.remove(data);
+    }
+
+    public void lockIncrement() {
+        lock = true;
+    }
+
+    public void unlockIncrement() {
+        lock = false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/parallel/ParallelTask.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/parallel/ParallelTask.java b/test/src/main/java/org/apache/rocketmq/test/util/parallel/ParallelTask.java
new file mode 100644
index 0000000..a4ad9a8
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/parallel/ParallelTask.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util.parallel;
+
+import java.util.concurrent.CountDownLatch;
+
+public abstract class ParallelTask extends Thread {
+    private CountDownLatch latch = null;
+
+    public CountDownLatch getLatch() {
+        return latch;
+    }
+
+    public void setLatch(CountDownLatch latch) {
+        this.latch = latch;
+    }
+
+    public abstract void execute();
+
+    @Override
+    public void run() {
+        this.execute();
+
+        if (latch != null) {
+            latch.countDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/parallel/ParallelTaskExecutor.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/parallel/ParallelTaskExecutor.java b/test/src/main/java/org/apache/rocketmq/test/util/parallel/ParallelTaskExecutor.java
new file mode 100644
index 0000000..e7e9209
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/parallel/ParallelTaskExecutor.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util.parallel;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class ParallelTaskExecutor {
+    public List<ParallelTask> tasks = new ArrayList<ParallelTask>();
+    public ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
+    public CountDownLatch latch = null;
+
+    public ParallelTaskExecutor() {
+
+    }
+
+    public void pushTask(ParallelTask task) {
+        tasks.add(task);
+    }
+
+    public void startBlock() {
+        init();
+        startTask();
+        try {
+            latch.await();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void startNoBlock() {
+        for (ParallelTask task : tasks) {
+            cachedThreadPool.execute(task);
+        }
+    }
+
+    private void init() {
+        latch = new CountDownLatch(tasks.size());
+        for (ParallelTask task : tasks) {
+            task.setLatch(latch);
+        }
+    }
+
+    private void startTask() {
+        for (ParallelTask task : tasks) {
+            task.start();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/util/parallel/Task4Test.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/util/parallel/Task4Test.java b/test/src/main/java/org/apache/rocketmq/test/util/parallel/Task4Test.java
new file mode 100644
index 0000000..c168d66
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/util/parallel/Task4Test.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.util.parallel;
+
+public class Task4Test extends ParallelTask {
+    private String name = "";
+
+    public Task4Test(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public void execute() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/base/BaseConf.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/base/BaseConf.java b/test/src/test/java/org/apache/rocketmq/test/base/BaseConf.java
new file mode 100644
index 0000000..57462a2
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/base/BaseConf.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.base;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.broker.BrokerController;
+import org.apache.rocketmq.namesrv.NamesrvController;
+import org.apache.rocketmq.test.client.rmq.RMQAsyncSendProducer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.clientinterface.AbstractMQConsumer;
+import org.apache.rocketmq.test.clientinterface.AbstractMQProducer;
+import org.apache.rocketmq.test.factory.ConsumerFactory;
+import org.apache.rocketmq.test.listener.AbstractListener;
+import org.apache.rocketmq.test.util.MQAdmin;
+import org.apache.rocketmq.test.util.MQRandomUtils;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.junit.Assert;
+
+public class BaseConf {
+    protected static String nsAddr;
+    protected static String broker1Name;
+    protected static String broker2Name;
+    protected static String clusterName;
+    protected static int brokerNum;
+    protected static int waitTime = 5;
+    protected static int consumeTime = 1 * 60 * 1000;
+    protected static int topicCreateTime = 30 * 1000;
+    protected static NamesrvController namesrvController;
+    protected static BrokerController brokerController1;
+    protected static BrokerController brokerController2;
+    protected static List<Object> mqClients = new ArrayList<Object>();
+    protected static boolean debug = false;
+    private static Logger log = Logger.getLogger(BaseConf.class);
+
+    static {
+        namesrvController = IntegrationTestBase.createAndStartNamesrv();
+        nsAddr = "127.0.0.1:" + namesrvController.getNettyServerConfig().getListenPort();
+        brokerController1 = IntegrationTestBase.createAndStartBroker(nsAddr);
+        brokerController2 = IntegrationTestBase.createAndStartBroker(nsAddr);
+        clusterName = brokerController1.getBrokerConfig().getBrokerClusterName();
+        broker1Name = brokerController1.getBrokerConfig().getBrokerName();
+        broker2Name = brokerController2.getBrokerConfig().getBrokerName();
+        brokerNum = 2;
+    }
+
+    public BaseConf() {
+
+    }
+
+    public static String initTopic() {
+        long startTime = System.currentTimeMillis();
+        String topic = MQRandomUtils.getRandomTopic();
+        boolean createResult = false;
+        while (true) {
+            createResult = MQAdmin.createTopic(nsAddr, clusterName, topic, 8);
+            if (createResult) {
+                break;
+            } else if (System.currentTimeMillis() - startTime > topicCreateTime) {
+                Assert.fail(String.format("topic[%s] is created failed after:%d ms", topic,
+                    System.currentTimeMillis() - startTime));
+                break;
+            } else {
+                TestUtils.waitForMonment(500);
+                continue;
+            }
+        }
+
+        return topic;
+    }
+
+    public static String initConsumerGroup() {
+        String group = MQRandomUtils.getRandomConsumerGroup();
+        return initConsumerGroup(group);
+    }
+
+    public static String initConsumerGroup(String group) {
+        MQAdmin.createSub(nsAddr, clusterName, group);
+        return group;
+    }
+
+    public static RMQNormalProducer getProducer(String nsAddr, String topic) {
+        RMQNormalProducer producer = new RMQNormalProducer(nsAddr, topic);
+        if (debug) {
+            producer.setDebug();
+        }
+        mqClients.add(producer);
+        return producer;
+    }
+
+    public static RMQNormalProducer getProducer(String nsAddr, String topic, String producerGoup,
+        String instanceName) {
+        RMQNormalProducer producer = new RMQNormalProducer(nsAddr, topic, producerGoup,
+            instanceName);
+        if (debug) {
+            producer.setDebug();
+        }
+        mqClients.add(producer);
+        return producer;
+    }
+
+    public static RMQAsyncSendProducer getAsyncProducer(String nsAddr, String topic) {
+        RMQAsyncSendProducer producer = new RMQAsyncSendProducer(nsAddr, topic);
+        if (debug) {
+            producer.setDebug();
+        }
+        mqClients.add(producer);
+        return producer;
+    }
+
+    public static RMQNormalConsumer getConsumer(String nsAddr, String topic, String subExpression,
+        AbstractListener listner) {
+        String consumerGroup = initConsumerGroup();
+        return getConsumer(nsAddr, consumerGroup, topic, subExpression, listner);
+    }
+
+    public static RMQNormalConsumer getConsumer(String nsAddr, String consumerGroup, String topic,
+        String subExpression, AbstractListener listner) {
+        RMQNormalConsumer consumer = ConsumerFactory.getRMQNormalConsumer(nsAddr, consumerGroup,
+            topic, subExpression, listner);
+        if (debug) {
+            consumer.setDebug();
+        }
+        mqClients.add(consumer);
+        log.info(String.format("consumer[%s] start,topic[%s],subExpression[%s]", consumerGroup,
+            topic, subExpression));
+        return consumer;
+    }
+
+    public static void shutDown() {
+        try {
+            for (Object mqClient : mqClients) {
+                if (mqClient instanceof AbstractMQProducer) {
+                    ((AbstractMQProducer) mqClient).shutdown();
+
+                } else {
+                    ((AbstractMQConsumer) mqClient).shutdown();
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/base/IntegrationTestBase.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/base/IntegrationTestBase.java b/test/src/test/java/org/apache/rocketmq/test/base/IntegrationTestBase.java
new file mode 100644
index 0000000..ff9996d
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/base/IntegrationTestBase.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.base;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.rocketmq.broker.BrokerController;
+import org.apache.rocketmq.common.BrokerConfig;
+import org.apache.rocketmq.common.namesrv.NamesrvConfig;
+import org.apache.rocketmq.namesrv.NamesrvController;
+import org.apache.rocketmq.remoting.netty.NettyClientConfig;
+import org.apache.rocketmq.remoting.netty.NettyServerConfig;
+import org.apache.rocketmq.store.config.MessageStoreConfig;
+import org.junit.Assert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class IntegrationTestBase {
+    protected static final String SEP = File.separator;
+    protected static final String BROKER_NAME_PREFIX = "TestBrokerName_";
+    protected static final AtomicInteger BROKER_INDEX = new AtomicInteger(0);
+    protected static final List<File> TMPE_FILES = new ArrayList<>();
+    protected static final List<BrokerController> BROKER_CONTROLLERS = new ArrayList<>();
+    protected static final List<NamesrvController> NAMESRV_CONTROLLERS = new ArrayList<>();
+    public static Logger logger = LoggerFactory.getLogger(IntegrationTestBase.class);
+    protected static Random random = new Random();
+
+    static {
+
+        Runtime.getRuntime().addShutdownHook(new Thread() {
+            @Override public void run() {
+                for (NamesrvController namesrvController : NAMESRV_CONTROLLERS) {
+                    if (namesrvController != null) {
+                        namesrvController.shutdown();
+                    }
+                }
+                for (BrokerController brokerController : BROKER_CONTROLLERS) {
+                    if (brokerController != null) {
+                        brokerController.shutdown();
+                    }
+                }
+                for (File file : TMPE_FILES) {
+                    deleteFile(file);
+                }
+            }
+        });
+
+    }
+
+    private static String createBaseDir() {
+        String baseDir = System.getProperty("user.home") + SEP + "unitteststore-" + UUID.randomUUID();
+        final File file = new File(baseDir);
+        if (file.exists()) {
+            logger.info(String.format("[%s] has already existed, please bake up and remove it for integration tests", baseDir));
+            System.exit(1);
+        }
+        TMPE_FILES.add(file);
+        return baseDir;
+    }
+
+    public static NamesrvController createAndStartNamesrv() {
+        String baseDir = createBaseDir();
+        NamesrvConfig namesrvConfig = new NamesrvConfig();
+        NettyServerConfig nameServerNettyServerConfig = new NettyServerConfig();
+        namesrvConfig.setKvConfigPath(baseDir + SEP + "namesrv" + SEP + "kvConfig.json");
+        namesrvConfig.setConfigStorePath(baseDir + SEP + "namesrv" + SEP + "namesrv.properties");
+
+        nameServerNettyServerConfig.setListenPort(9000 + random.nextInt(1000));
+        NamesrvController namesrvController = new NamesrvController(namesrvConfig, nameServerNettyServerConfig);
+        try {
+            Assert.assertTrue(namesrvController.initialize());
+            logger.info("Name Server Start:{}", nameServerNettyServerConfig.getListenPort());
+            namesrvController.start();
+        } catch (Exception e) {
+            logger.info("Name Server start failed");
+            System.exit(1);
+        }
+        NAMESRV_CONTROLLERS.add(namesrvController);
+        return namesrvController;
+
+    }
+
+    public static BrokerController createAndStartBroker(String nsAddr) {
+        String baseDir = createBaseDir();
+        BrokerConfig brokerConfig = new BrokerConfig();
+        NettyServerConfig nettyServerConfig = new NettyServerConfig();
+        NettyClientConfig nettyClientConfig = new NettyClientConfig();
+        MessageStoreConfig storeConfig = new MessageStoreConfig();
+        brokerConfig.setBrokerName(BROKER_NAME_PREFIX + BROKER_INDEX.getAndIncrement());
+        brokerConfig.setBrokerIP1("127.0.0.1");
+        brokerConfig.setNamesrvAddr(nsAddr);
+        storeConfig.setStorePathRootDir(baseDir);
+        storeConfig.setStorePathCommitLog(baseDir + SEP + "commitlog");
+        storeConfig.setHaListenPort(8000 + random.nextInt(1000));
+        nettyServerConfig.setListenPort(10000 + random.nextInt(1000));
+        BrokerController brokerController = new BrokerController(brokerConfig, nettyServerConfig, nettyClientConfig, storeConfig);
+        try {
+            Assert.assertTrue(brokerController.initialize());
+            logger.info("Broker Start name:{} addr:{}", brokerConfig.getBrokerName(), brokerController.getBrokerAddr());
+            brokerController.start();
+        } catch (Exception e) {
+            logger.info("Broker start failed");
+            System.exit(1);
+        }
+        BROKER_CONTROLLERS.add(brokerController);
+        return brokerController;
+    }
+
+    public static void deleteFile(File file) {
+        if (!file.exists()) {
+            return;
+        }
+        if (file.isFile()) {
+            file.delete();
+        } else if (file.isDirectory()) {
+            File[] files = file.listFiles();
+            for (File file1 : files) {
+                deleteFile(file1);
+            }
+            file.delete();
+        }
+    }
+
+}



[06/31] incubator-rocketmq git commit: [ROCKETMQ-59] Change Charset usages in RocketMQSerializable to RocketMQSerializable#CHARSET_UTF8, closes apache/incubator-rocketmq#43

Posted by st...@apache.org.
[ROCKETMQ-59] Change Charset usages in RocketMQSerializable to RocketMQSerializable#CHARSET_UTF8, closes apache/incubator-rocketmq#43


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/457bb61f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/457bb61f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/457bb61f

Branch: refs/heads/ROCKETMQ-54
Commit: 457bb61f0489d58c810330b40c62ccb7e75b602b
Parents: 62d811e
Author: iskl <sh...@kailai.me>
Authored: Fri Jan 20 11:18:42 2017 +0800
Committer: yukon <yu...@apache.org>
Committed: Fri Jan 20 11:18:42 2017 +0800

----------------------------------------------------------------------
 .../remoting/protocol/RemotingSerializable.java    |  2 +-
 .../remoting/protocol/RocketMQSerializable.java    | 17 ++++++++---------
 2 files changed, 9 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/457bb61f/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RemotingSerializable.java
----------------------------------------------------------------------
diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RemotingSerializable.java b/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RemotingSerializable.java
index a9c0a62..f80ff14 100644
--- a/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RemotingSerializable.java
+++ b/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RemotingSerializable.java
@@ -20,7 +20,7 @@ import com.alibaba.fastjson.JSON;
 import java.nio.charset.Charset;
 
 public abstract class RemotingSerializable {
-    public final static Charset CHARSET_UTF8 = Charset.forName("UTF-8");
+    private final static Charset CHARSET_UTF8 = Charset.forName("UTF-8");
 
     public static byte[] encode(final Object obj) {
         final String json = toJson(obj, false);

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/457bb61f/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RocketMQSerializable.java
----------------------------------------------------------------------
diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RocketMQSerializable.java b/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RocketMQSerializable.java
index 0ebe795..86dab46 100644
--- a/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RocketMQSerializable.java
+++ b/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RocketMQSerializable.java
@@ -23,14 +23,14 @@ import java.util.Iterator;
 import java.util.Map;
 
 public class RocketMQSerializable {
-    public static final Charset CHARSET_UTF8 = Charset.forName("UTF-8");
+    private static final Charset CHARSET_UTF8 = Charset.forName("UTF-8");
 
     public static byte[] rocketMQProtocolEncode(RemotingCommand cmd) {
         // String remark
         byte[] remarkBytes = null;
         int remarkLen = 0;
         if (cmd.getRemark() != null && cmd.getRemark().length() > 0) {
-            remarkBytes = cmd.getRemark().getBytes(RemotingSerializable.CHARSET_UTF8);
+            remarkBytes = cmd.getRemark().getBytes(CHARSET_UTF8);
             remarkLen = remarkBytes.length;
         }
 
@@ -89,9 +89,9 @@ public class RocketMQSerializable {
             if (entry.getKey() != null && entry.getValue() != null) {
                 kvLength =
                     // keySize + Key
-                    2 + entry.getKey().getBytes(RemotingSerializable.CHARSET_UTF8).length
+                    2 + entry.getKey().getBytes(CHARSET_UTF8).length
                         // valSize + val
-                        + 4 + entry.getValue().getBytes(RemotingSerializable.CHARSET_UTF8).length;
+                        + 4 + entry.getValue().getBytes(CHARSET_UTF8).length;
                 totalLength += kvLength;
             }
         }
@@ -103,8 +103,8 @@ public class RocketMQSerializable {
         while (it.hasNext()) {
             Map.Entry<String, String> entry = it.next();
             if (entry.getKey() != null && entry.getValue() != null) {
-                key = entry.getKey().getBytes(RemotingSerializable.CHARSET_UTF8);
-                val = entry.getValue().getBytes(RemotingSerializable.CHARSET_UTF8);
+                key = entry.getKey().getBytes(CHARSET_UTF8);
+                val = entry.getValue().getBytes(CHARSET_UTF8);
 
                 content.putShort((short) key.length);
                 content.put(key);
@@ -154,7 +154,7 @@ public class RocketMQSerializable {
         if (remarkLength > 0) {
             byte[] remarkContent = new byte[remarkLength];
             headerBuffer.get(remarkContent);
-            cmd.setRemark(new String(remarkContent, RemotingSerializable.CHARSET_UTF8));
+            cmd.setRemark(new String(remarkContent, CHARSET_UTF8));
         }
 
         // HashMap<String, String> extFields
@@ -187,8 +187,7 @@ public class RocketMQSerializable {
             valContent = new byte[valSize];
             byteBuffer.get(valContent);
 
-            map.put(new String(keyContent, RemotingSerializable.CHARSET_UTF8), new String(valContent,
-                RemotingSerializable.CHARSET_UTF8));
+            map.put(new String(keyContent, CHARSET_UTF8), new String(valContent, CHARSET_UTF8));
         }
         return map;
     }


[13/31] incubator-rocketmq git commit: [ROCKETMQ-42] Closes apache/incubator-rocketmq#35, closes apache/incubator-rocketmq#41, *Won't fix*

Posted by st...@apache.org.
[ROCKETMQ-42] Closes apache/incubator-rocketmq#35, closes apache/incubator-rocketmq#41, *Won't fix*


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/0661ac8c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/0661ac8c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/0661ac8c

Branch: refs/heads/ROCKETMQ-54
Commit: 0661ac8c07a995058b5f33579867779e4d487ee1
Parents: 788771a
Author: yukon <yu...@apache.org>
Authored: Fri Jan 20 13:51:52 2017 +0800
Committer: yukon <yu...@apache.org>
Committed: Fri Jan 20 13:51:52 2017 +0800

----------------------------------------------------------------------

----------------------------------------------------------------------



[10/31] incubator-rocketmq git commit: [RocketMQ-58] Add integration test for RocketMQ, also thanks @fenglianghfl for this commit, closes apache/incubator-rocketmq#46

Posted by st...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/balance/NormalMsgDynamicBalanceIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/balance/NormalMsgDynamicBalanceIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/balance/NormalMsgDynamicBalanceIT.java
new file mode 100644
index 0000000..fdafdf0
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/balance/NormalMsgDynamicBalanceIT.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.balance;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.MQWait;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class NormalMsgDynamicBalanceIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(NormalMsgStaticBalanceIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s !", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testTwoConsumerAndCrashOne() {
+        int msgSize = 400;
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQNormalListner());
+
+        producer.send(msgSize);
+
+        MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(), consumer1.getListner(),
+            consumer2.getListner());
+        consumer2.shutdown();
+
+        producer.send(msgSize);
+        Assert.assertEquals("Not all are sent", msgSize * 2, producer.getAllUndupMsgBody().size());
+
+        boolean recvAll = MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(),
+            consumer1.getListner(), consumer2.getListner());
+        assertThat(recvAll).isEqualTo(true);
+
+        boolean balance = VerifyUtils.verifyBalance(msgSize,
+            VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+                consumer1.getListner().getAllUndupMsgBody()).size() - msgSize,
+            VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+                consumer2.getListner().getAllUndupMsgBody()).size());
+        assertThat(balance).isEqualTo(true);
+    }
+
+    @Test
+    public void test3ConsumerAndCrashOne() {
+        int msgSize = 400;
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQNormalListner());
+        RMQNormalConsumer consumer3 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQNormalListner());
+
+        producer.send(msgSize);
+
+        MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(), consumer1.getListner(),
+            consumer2.getListner(), consumer3.getListner());
+        consumer3.shutdown();
+        producer.clearMsg();
+        consumer1.clearMsg();
+        consumer2.clearMsg();
+
+        producer.send(msgSize);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+
+        boolean recvAll = MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(),
+            consumer1.getListner(), consumer2.getListner());
+        assertThat(recvAll).isEqualTo(true);
+
+        boolean balance = VerifyUtils.verifyBalance(msgSize,
+            VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+                consumer1.getListner().getAllUndupMsgBody()).size(),
+            VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+                consumer2.getListner().getAllUndupMsgBody()).size());
+        assertThat(balance).isEqualTo(true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/balance/NormalMsgStaticBalanceIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/balance/NormalMsgStaticBalanceIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/balance/NormalMsgStaticBalanceIT.java
new file mode 100644
index 0000000..117d643
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/balance/NormalMsgStaticBalanceIT.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.balance;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.MQWait;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class NormalMsgStaticBalanceIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(NormalMsgStaticBalanceIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s !", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testTwoConsumersBalance() {
+        int msgSize = 400;
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQNormalListner());
+        TestUtils.waitForSeconds(waitTime);
+
+        producer.send(msgSize);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+
+        boolean recvAll = MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(),
+            consumer1.getListner(), consumer2.getListner());
+        assertThat(recvAll).isEqualTo(true);
+
+        boolean balance = VerifyUtils.verifyBalance(msgSize,
+            VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+                consumer1.getListner().getAllUndupMsgBody()).size(),
+            VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+                consumer2.getListner().getAllUndupMsgBody()).size());
+        assertThat(balance).isEqualTo(true);
+    }
+
+    @Test
+    public void testFourConsumersBalance() {
+        int msgSize = 600;
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQNormalListner());
+        RMQNormalConsumer consumer3 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQNormalListner());
+        RMQNormalConsumer consumer4 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQNormalListner());
+        TestUtils.waitForSeconds(waitTime);
+
+        producer.send(msgSize);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+
+        boolean recvAll = MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(),
+            consumer1.getListner(), consumer2.getListner(), consumer3.getListner(),
+            consumer4.getListner());
+        assertThat(recvAll).isEqualTo(true);
+
+        boolean balance = VerifyUtils
+            .verifyBalance(msgSize,
+                VerifyUtils
+                    .getFilterdMessage(producer.getAllMsgBody(),
+                        consumer1.getListner().getAllUndupMsgBody())
+                    .size(),
+                VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+                    consumer2.getListner().getAllUndupMsgBody()).size(),
+                VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+                    consumer3.getListner().getAllUndupMsgBody()).size(),
+                VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+                    consumer4.getListner().getAllUndupMsgBody()).size());
+        assertThat(balance).isEqualTo(true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/BaseBroadCastIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/BaseBroadCastIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/BaseBroadCastIT.java
new file mode 100644
index 0000000..94efaef
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/BaseBroadCastIT.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.broadcast;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.rmq.RMQBroadCastConsumer;
+import org.apache.rocketmq.test.factory.ConsumerFactory;
+import org.apache.rocketmq.test.listener.AbstractListener;
+
+public class BaseBroadCastIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(BaseBroadCastIT.class);
+
+    public static RMQBroadCastConsumer getBroadCastConsumer(String nsAddr, String topic,
+        String subExpression,
+        AbstractListener listner) {
+        String consumerGroup = initConsumerGroup();
+        return getBroadCastConsumer(nsAddr, consumerGroup, topic, subExpression, listner);
+    }
+
+    public static RMQBroadCastConsumer getBroadCastConsumer(String nsAddr, String consumerGroup,
+        String topic, String subExpression,
+        AbstractListener listner) {
+        RMQBroadCastConsumer consumer = ConsumerFactory.getRMQBroadCastConsumer(nsAddr,
+            consumerGroup, topic, subExpression, listner);
+
+        consumer.setDebug();
+
+        mqClients.add(consumer);
+        logger.info(String.format("consumer[%s] start,topic[%s],subExpression[%s]", consumerGroup,
+            topic, subExpression));
+        return consumer;
+    }
+
+    public void printSeperator() {
+        for (int i = 0; i < 3; i++) {
+            logger.info(
+                "<<<<<<<<================================================================================>>>>>>>>");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgNotRecvIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgNotRecvIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgNotRecvIT.java
new file mode 100644
index 0000000..65762fa
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgNotRecvIT.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.broadcast.normal;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.client.consumer.broadcast.BaseBroadCastIT;
+import org.apache.rocketmq.test.client.rmq.RMQBroadCastConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class BroadCastNormalMsgNotRecvIT extends BaseBroadCastIT {
+    private static Logger logger = Logger
+        .getLogger(NormalMsgTwoSameGroupConsumerIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        printSeperator();
+        topic = initTopic();
+        logger.info(String.format("use topic: %s;", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testNotConsumeAfterConsume() {
+        int msgSize = 16;
+
+        String group = initConsumerGroup();
+        RMQBroadCastConsumer consumer1 = getBroadCastConsumer(nsAddr, group, topic, "*",
+            new RMQNormalListner(group + "_1"));
+
+        producer.send(msgSize);
+        Assert.assertEquals("Not all sent succeeded", msgSize, producer.getAllUndupMsgBody().size());
+
+        consumer1.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer1.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+
+        RMQBroadCastConsumer consumer2 = getBroadCastConsumer(nsAddr,
+            consumer1.getConsumerGroup(), topic, "*", new RMQNormalListner(group + "_2"));
+        consumer2.getListner().waitForMessageConsume(producer.getAllMsgBody(), waitTime);
+        assertThat(consumer2.getListner().getAllMsgBody().size()).isEqualTo(0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgRecvCrashIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgRecvCrashIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgRecvCrashIT.java
new file mode 100644
index 0000000..b878d09
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgRecvCrashIT.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.broadcast.normal;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.client.consumer.broadcast.BaseBroadCastIT;
+import org.apache.rocketmq.test.client.rmq.RMQBroadCastConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class BroadCastNormalMsgRecvCrashIT extends BaseBroadCastIT {
+    private static Logger logger = Logger
+        .getLogger(NormalMsgTwoSameGroupConsumerIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        printSeperator();
+        topic = initTopic();
+        logger.info(String.format("use topic: %s;", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testStartTwoAndCrashOneLater() {
+        int msgSize = 16;
+
+        String group = initConsumerGroup();
+        RMQBroadCastConsumer consumer1 = getBroadCastConsumer(nsAddr, group, topic, "*",
+            new RMQNormalListner(group + "_1"));
+        RMQBroadCastConsumer consumer2 = getBroadCastConsumer(nsAddr,
+            consumer1.getConsumerGroup(), topic, "*", new RMQNormalListner(group + "_2"));
+        TestUtils.waitForSeconds(waitTime);
+
+        producer.send(msgSize);
+        Assert.assertEquals("Not all sent succeeded", msgSize, producer.getAllUndupMsgBody().size());
+
+        consumer1.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        consumer2.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer1.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer2.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+
+        consumer2.shutdown();
+
+        producer.clearMsg();
+        consumer1.clearMsg();
+
+        producer.send(msgSize);
+        Assert.assertEquals("Not all sent succeeded", msgSize, producer.getAllUndupMsgBody().size());
+
+        consumer1.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer1.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgRecvFailIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgRecvFailIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgRecvFailIT.java
new file mode 100644
index 0000000..26c37f9
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgRecvFailIT.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.broadcast.normal;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
+import org.apache.rocketmq.test.client.consumer.broadcast.BaseBroadCastIT;
+import org.apache.rocketmq.test.client.rmq.RMQBroadCastConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class BroadCastNormalMsgRecvFailIT extends BaseBroadCastIT {
+    private static Logger logger = Logger
+        .getLogger(NormalMsgTwoSameGroupConsumerIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        printSeperator();
+        topic = initTopic();
+        logger.info(String.format("use topic: %s;", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testStartTwoConsumerAndOneConsumerFail() {
+        int msgSize = 16;
+
+        RMQBroadCastConsumer consumer1 = getBroadCastConsumer(nsAddr, topic, "*",
+            new RMQNormalListner());
+        RMQBroadCastConsumer consumer2 = getBroadCastConsumer(nsAddr,
+            consumer1.getConsumerGroup(), topic, "*",
+            new RMQNormalListner(ConsumeConcurrentlyStatus.RECONSUME_LATER));
+
+        producer.send(msgSize);
+        Assert.assertEquals("Not all sent succeeded", msgSize, producer.getAllUndupMsgBody().size());
+
+        consumer1.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer1.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgRecvStartLaterIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgRecvStartLaterIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgRecvStartLaterIT.java
new file mode 100644
index 0000000..027f648
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgRecvStartLaterIT.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.broadcast.normal;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.client.consumer.broadcast.BaseBroadCastIT;
+import org.apache.rocketmq.test.client.rmq.RMQBroadCastConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class BroadCastNormalMsgRecvStartLaterIT extends BaseBroadCastIT {
+    private static Logger logger = Logger
+        .getLogger(NormalMsgTwoSameGroupConsumerIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        printSeperator();
+        topic = initTopic();
+        logger.info(String.format("use topic: %s;", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testStartOneAndStartAnotherLater() {
+        int msgSize = 16;
+
+        String group = initConsumerGroup();
+        RMQBroadCastConsumer consumer1 = getBroadCastConsumer(nsAddr, group, topic, "*",
+            new RMQNormalListner(group + "_1"));
+        TestUtils.waitForSeconds(waitTime);
+
+        producer.send(msgSize);
+        Assert.assertEquals("Not all sent succeeded", msgSize, producer.getAllUndupMsgBody().size());
+
+        consumer1.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer1.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+
+        producer.clearMsg();
+        consumer1.clearMsg();
+
+        RMQBroadCastConsumer consumer2 = getBroadCastConsumer(nsAddr,
+            consumer1.getConsumerGroup(), topic, "*", new RMQNormalListner(group + "_2"));
+        TestUtils.waitForSeconds(waitTime);
+        producer.send(msgSize);
+        Assert.assertEquals("Not all sent succeeded", msgSize, producer.getAllUndupMsgBody().size());
+
+        consumer1.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        consumer2.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer1.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer2.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgTwoDiffGroupRecvIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgTwoDiffGroupRecvIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgTwoDiffGroupRecvIT.java
new file mode 100644
index 0000000..acbaf23
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/BroadCastNormalMsgTwoDiffGroupRecvIT.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.broadcast.normal;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.client.consumer.broadcast.BaseBroadCastIT;
+import org.apache.rocketmq.test.client.rmq.RMQBroadCastConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class BroadCastNormalMsgTwoDiffGroupRecvIT extends BaseBroadCastIT {
+    private static Logger logger = Logger
+        .getLogger(NormalMsgTwoSameGroupConsumerIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        printSeperator();
+        topic = initTopic();
+        logger.info(String.format("use topic: %s;", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testStartDiffSameGroupConsumer() {
+        int msgSize = 16;
+
+        String group1 = initConsumerGroup();
+        String group2 = initConsumerGroup();
+        RMQBroadCastConsumer consumer1 = getBroadCastConsumer(nsAddr, group1, topic, "*",
+            new RMQNormalListner(group1 + "_1"));
+        RMQBroadCastConsumer consumer2 = getBroadCastConsumer(nsAddr, group2, topic, "*",
+            new RMQNormalListner(group2 + "_2"));
+        TestUtils.waitForSeconds(waitTime);
+
+        producer.send(msgSize);
+        Assert.assertEquals("Not all sent succeeded", msgSize, producer.getAllUndupMsgBody().size());
+
+        consumer1.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        consumer2.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer1.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer2.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/NormalMsgTwoSameGroupConsumerIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/NormalMsgTwoSameGroupConsumerIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/NormalMsgTwoSameGroupConsumerIT.java
new file mode 100644
index 0000000..984c941
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/normal/NormalMsgTwoSameGroupConsumerIT.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.broadcast.normal;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.client.consumer.broadcast.BaseBroadCastIT;
+import org.apache.rocketmq.test.client.rmq.RMQBroadCastConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class NormalMsgTwoSameGroupConsumerIT extends BaseBroadCastIT {
+    private static Logger logger = Logger
+        .getLogger(NormalMsgTwoSameGroupConsumerIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        printSeperator();
+        topic = initTopic();
+        logger.info(String.format("use topic: %s;", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testStartTwoSameGroupConsumer() {
+        int msgSize = 16;
+
+        String group = initConsumerGroup();
+        RMQBroadCastConsumer consumer1 = getBroadCastConsumer(nsAddr, group, topic, "*",
+            new RMQNormalListner(group + "_1"));
+        RMQBroadCastConsumer consumer2 = getBroadCastConsumer(nsAddr,
+            consumer1.getConsumerGroup(), topic, "*", new RMQNormalListner(group + "_2"));
+        TestUtils.waitForSeconds(waitTime);
+
+        producer.send(msgSize);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+
+        consumer1.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        consumer2.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer1.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer2.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/order/OrderMsgBroadCastIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/order/OrderMsgBroadCastIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/order/OrderMsgBroadCastIT.java
new file mode 100644
index 0000000..ac8fcf5
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/order/OrderMsgBroadCastIT.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.broadcast.order;
+
+import java.util.List;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.test.client.consumer.broadcast.BaseBroadCastIT;
+import org.apache.rocketmq.test.client.rmq.RMQBroadCastConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.order.RMQOrderListener;
+import org.apache.rocketmq.test.message.MessageQueueMsg;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class OrderMsgBroadCastIT extends BaseBroadCastIT {
+    private static Logger logger = Logger.getLogger(OrderMsgBroadCastIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s;", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testTwoConsumerSubTag() {
+        int msgSize = 10;
+
+        RMQBroadCastConsumer consumer1 = getBroadCastConsumer(nsAddr, topic, "*",
+            new RMQOrderListener());
+        RMQBroadCastConsumer consumer2 = getBroadCastConsumer(nsAddr,
+            consumer1.getConsumerGroup(), topic, "*", new RMQOrderListener());
+        TestUtils.waitForSeconds(waitTime);
+
+        List<MessageQueue> mqs = producer.getMessageQueue();
+        MessageQueueMsg mqMsgs = new MessageQueueMsg(mqs, msgSize);
+        producer.send(mqMsgs.getMsgsWithMQ());
+
+        consumer1.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        consumer2.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer1.getListner()).getMsgs()))
+            .isEqualTo(true);
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer2.getListner()).getMsgs()))
+            .isEqualTo(true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/tag/BroadCastTwoConsumerFilterIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/tag/BroadCastTwoConsumerFilterIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/tag/BroadCastTwoConsumerFilterIT.java
new file mode 100644
index 0000000..a1a2ff7
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/tag/BroadCastTwoConsumerFilterIT.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.broadcast.tag;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.client.consumer.broadcast.BaseBroadCastIT;
+import org.apache.rocketmq.test.client.rmq.RMQBroadCastConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class BroadCastTwoConsumerFilterIT extends BaseBroadCastIT {
+    private static Logger logger = Logger.getLogger(BroadCastTwoConsumerSubTagIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s;", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testTwoConsumerFilter() {
+        int msgSize = 40;
+        String tag1 = "jueyin_tag_1";
+        String tag2 = "jueyin_tag_2";
+
+        RMQBroadCastConsumer consumer1 = getBroadCastConsumer(nsAddr, topic, tag1,
+            new RMQNormalListner());
+        RMQBroadCastConsumer consumer2 = getBroadCastConsumer(nsAddr,
+            consumer1.getConsumerGroup(), topic, tag1, new RMQNormalListner());
+        TestUtils.waitForSeconds(waitTime);
+
+        producer.send(tag2, msgSize);
+        Assert.assertEquals("Not all sent succeeded", msgSize, producer.getAllUndupMsgBody().size());
+        producer.clearMsg();
+        producer.send(tag1, msgSize);
+
+        consumer1.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        consumer2.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer1.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer2.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/tag/BroadCastTwoConsumerSubDiffTagIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/tag/BroadCastTwoConsumerSubDiffTagIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/tag/BroadCastTwoConsumerSubDiffTagIT.java
new file mode 100644
index 0000000..5c2e7fc
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/tag/BroadCastTwoConsumerSubDiffTagIT.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.broadcast.tag;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.client.consumer.broadcast.BaseBroadCastIT;
+import org.apache.rocketmq.test.client.rmq.RMQBroadCastConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class BroadCastTwoConsumerSubDiffTagIT extends BaseBroadCastIT {
+    private static Logger logger = Logger.getLogger(BroadCastTwoConsumerSubTagIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s;", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testTwoConsumerSubDiffTag() {
+        int msgSize = 40;
+        String tag = "jueyin_tag";
+
+        RMQBroadCastConsumer consumer1 = getBroadCastConsumer(nsAddr, topic, "*",
+            new RMQNormalListner());
+        RMQBroadCastConsumer consumer2 = getBroadCastConsumer(nsAddr,
+            consumer1.getConsumerGroup(), topic, tag, new RMQNormalListner());
+        TestUtils.waitForSeconds(waitTime);
+
+        producer.send(tag, msgSize);
+        Assert.assertEquals("Not all sent succeeded", msgSize, producer.getAllUndupMsgBody().size());
+
+        consumer1.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        consumer2.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer1.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer2.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/tag/BroadCastTwoConsumerSubTagIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/tag/BroadCastTwoConsumerSubTagIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/tag/BroadCastTwoConsumerSubTagIT.java
new file mode 100644
index 0000000..e4510de
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/broadcast/tag/BroadCastTwoConsumerSubTagIT.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.broadcast.tag;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.client.consumer.broadcast.BaseBroadCastIT;
+import org.apache.rocketmq.test.client.rmq.RMQBroadCastConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class BroadCastTwoConsumerSubTagIT extends BaseBroadCastIT {
+    private static Logger logger = Logger.getLogger(BroadCastTwoConsumerSubTagIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s;", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testTwoConsumerSubTag() {
+        int msgSize = 20;
+        String tag = "jueyin_tag";
+
+        RMQBroadCastConsumer consumer1 = getBroadCastConsumer(nsAddr, topic, tag,
+            new RMQNormalListner());
+        RMQBroadCastConsumer consumer2 = getBroadCastConsumer(nsAddr,
+            consumer1.getConsumerGroup(), topic, tag, new RMQNormalListner());
+        TestUtils.waitForSeconds(waitTime);
+
+        producer.send(tag, msgSize);
+        Assert.assertEquals("Not all sent succeeded", msgSize, producer.getAllUndupMsgBody().size());
+
+        consumer1.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        consumer2.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer1.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer2.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/cluster/DynamicAddAndCrashIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/cluster/DynamicAddAndCrashIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/cluster/DynamicAddAndCrashIT.java
new file mode 100644
index 0000000..303dfa0
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/cluster/DynamicAddAndCrashIT.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.cluster;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.consumer.balance.NormalMsgStaticBalanceIT;
+import org.apache.rocketmq.test.client.mq.MQAsyncProducer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.MQWait;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class DynamicAddAndCrashIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(NormalMsgStaticBalanceIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s !", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testAddOneConsumerAndCrashAfterWhile() {
+        int msgSize = 150;
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+
+        MQAsyncProducer asyncDefaultMQProducer = new MQAsyncProducer(producer, msgSize, 100);
+        asyncDefaultMQProducer.start();
+        TestUtils.waitForSeconds(waitTime);
+
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQNormalListner());
+        TestUtils.waitForSeconds(waitTime);
+        consumer2.shutdown();
+
+        asyncDefaultMQProducer.waitSendAll(waitTime * 6);
+
+        MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(), consumer1.getListner(),
+            consumer2.getListner());
+
+        boolean recvAll = MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(),
+            consumer1.getListner(), consumer2.getListner());
+        assertThat(recvAll).isEqualTo(true);
+    }
+
+    @Test
+    public void testAddTwoConsumerAndCrashAfterWhile() {
+        int msgSize = 150;
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+
+        MQAsyncProducer asyncDefaultMQProducer = new MQAsyncProducer(producer, msgSize, 100);
+        asyncDefaultMQProducer.start();
+        TestUtils.waitForSeconds(waitTime);
+
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQNormalListner());
+        RMQNormalConsumer consumer3 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQNormalListner());
+        TestUtils.waitForSeconds(waitTime);
+
+        consumer2.shutdown();
+        consumer3.shutdown();
+
+        asyncDefaultMQProducer.waitSendAll(waitTime * 6);
+
+        MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(), consumer1.getListner(),
+            consumer2.getListner(), consumer3.getListner());
+
+        boolean recvAll = MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(),
+            consumer1.getListner(), consumer2.getListner(), consumer3.getListner());
+        assertThat(recvAll).isEqualTo(true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/cluster/DynamicAddConsumerIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/cluster/DynamicAddConsumerIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/cluster/DynamicAddConsumerIT.java
new file mode 100644
index 0000000..46dbb70
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/cluster/DynamicAddConsumerIT.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.cluster;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.consumer.balance.NormalMsgStaticBalanceIT;
+import org.apache.rocketmq.test.client.mq.MQAsyncProducer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.MQWait;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class DynamicAddConsumerIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(NormalMsgStaticBalanceIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s !", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testAddOneConsumer() {
+        int msgSize = 100;
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+
+        MQAsyncProducer asyncDefaultMQProducer = new MQAsyncProducer(producer, msgSize, 100);
+        asyncDefaultMQProducer.start();
+        TestUtils.waitForSeconds(waitTime);
+
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQNormalListner());
+
+        asyncDefaultMQProducer.waitSendAll(waitTime * 6);
+
+        MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(), consumer1.getListner(),
+            consumer2.getListner());
+
+        boolean recvAll = MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(),
+            consumer1.getListner(), consumer2.getListner());
+        assertThat(recvAll).isEqualTo(true);
+    }
+
+    @Test
+    public void testAddTwoConsumer() {
+        int msgSize = 100;
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+
+        MQAsyncProducer asyncDefaultMQProducer = new MQAsyncProducer(producer, msgSize, 100);
+        asyncDefaultMQProducer.start();
+        TestUtils.waitForSeconds(waitTime);
+
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQNormalListner());
+        RMQNormalConsumer consumer3 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQNormalListner());
+
+        asyncDefaultMQProducer.waitSendAll(waitTime * 6);
+
+        MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(), consumer1.getListner(),
+            consumer2.getListner(), consumer3.getListner());
+
+        boolean recvAll = MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(),
+            consumer1.getListner(), consumer2.getListner(), consumer3.getListner());
+        assertThat(recvAll).isEqualTo(true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/cluster/DynamicCrashConsumerIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/cluster/DynamicCrashConsumerIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/cluster/DynamicCrashConsumerIT.java
new file mode 100644
index 0000000..807f950
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/cluster/DynamicCrashConsumerIT.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.cluster;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.consumer.balance.NormalMsgStaticBalanceIT;
+import org.apache.rocketmq.test.client.mq.MQAsyncProducer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.MQWait;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class DynamicCrashConsumerIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(NormalMsgStaticBalanceIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s !", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testAddOneConsumer() {
+        int msgSize = 100;
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQNormalListner());
+
+        MQAsyncProducer asyncDefaultMQProducer = new MQAsyncProducer(producer, msgSize, 100);
+        asyncDefaultMQProducer.start();
+        TestUtils.waitForSeconds(waitTime);
+
+        consumer2.shutdown();
+
+        asyncDefaultMQProducer.waitSendAll(waitTime * 6);
+
+        MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(), consumer1.getListner(),
+            consumer2.getListner());
+
+        boolean recvAll = MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(),
+            consumer1.getListner(), consumer2.getListner());
+        assertThat(recvAll).isEqualTo(true);
+    }
+
+    @Test
+    public void testAddTwoConsumer() {
+        int msgSize = 100;
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQNormalListner());
+        RMQNormalConsumer consumer3 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQNormalListner());
+
+        MQAsyncProducer asyncDefaultMQProducer = new MQAsyncProducer(producer, msgSize, 100);
+        asyncDefaultMQProducer.start();
+        TestUtils.waitForSeconds(waitTime);
+
+        consumer2.shutdown();
+        consumer3.shutdown();
+
+        asyncDefaultMQProducer.waitSendAll(waitTime * 6);
+
+        MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(), consumer1.getListner(),
+            consumer2.getListner(), consumer3.getListner());
+
+        boolean recvAll = MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(),
+            consumer1.getListner(), consumer2.getListner(), consumer3.getListner());
+        assertThat(recvAll).isEqualTo(true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/tag/MulTagSubIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/tag/MulTagSubIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/tag/MulTagSubIT.java
new file mode 100644
index 0000000..ecb204e
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/tag/MulTagSubIT.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.tag;
+
+import java.util.List;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.factory.MQMessageFactory;
+import org.apache.rocketmq.test.factory.TagMessage;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class MulTagSubIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(TagMessageWith1ConsumerIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        String consumerId = initConsumerGroup();
+        logger.info(String.format("use topic: %s; consumerId: %s !", topic, consumerId));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testSubTwoTabMessageOnsTag() {
+        String tag = "jueyin1";
+        String subExpress = String.format("%s||jueyin2", tag);
+        int msgSize = 10;
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, subExpress,
+            new RMQNormalListner());
+        producer.send(tag, msgSize);
+        Assert.assertEquals("Not all sent succeeded", msgSize, producer.getAllUndupMsgBody().size());
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+
+    @Test
+    public void testSubTwoTabAndMatchOne() {
+        String tag1 = "jueyin1";
+        String tag2 = "jueyin2";
+        String subExpress = String.format("%s||noExistTag", tag2);
+        int msgSize = 10;
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, subExpress,
+            new RMQNormalListner());
+
+        producer.send(tag1, msgSize);
+        Assert.assertEquals("Not all sent succeeded", msgSize, producer.getAllUndupMsgBody().size());
+        List<Object> tag2Msgs = MQMessageFactory.getRMQMessage(tag2, topic, msgSize);
+        producer.send(tag2Msgs);
+        Assert.assertEquals("Not all sent succeeded", msgSize * 2, producer.getAllUndupMsgBody().size());
+
+        consumer.getListner().waitForMessageConsume(MQMessageFactory.getMessageBody(tag2Msgs),
+            consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(MQMessageFactory.getMessageBody(tag2Msgs));
+    }
+
+    @Test
+    public void testSubTwoTabAndMatchTwo() {
+        String tags[] = {"jueyin1", "jueyin2"};
+        String subExpress = String.format("%s||%s", tags[0], tags[1]);
+        int msgSize = 10;
+
+        TagMessage tagMessage = new TagMessage(tags, topic, msgSize);
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, subExpress,
+            new RMQNormalListner());
+
+        producer.send(tagMessage.getMixedTagMessages());
+        Assert.assertEquals("Not all sent succeeded", msgSize * tags.length,
+            producer.getAllUndupMsgBody().size());
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(tagMessage.getAllTagMessageBody());
+    }
+
+    @Test
+    public void testSubThreeTabAndMatchTwo() {
+        String tags[] = {"jueyin1", "jueyin2", "jueyin3"};
+        String subExpress = String.format("%s||%s", tags[0], tags[1]);
+        int msgSize = 10;
+
+        TagMessage tagMessage = new TagMessage(tags, topic, msgSize);
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, subExpress,
+            new RMQNormalListner());
+
+        producer.send(tagMessage.getMixedTagMessages());
+        Assert.assertEquals("Not all sent succeeded", msgSize * tags.length,
+            producer.getAllUndupMsgBody().size());
+
+        consumer.getListner().waitForMessageConsume(
+            tagMessage.getMessageBodyByTag(tags[0], tags[1]), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody())).containsExactlyElementsIn(
+            tagMessage.getMessageBodyByTag(tags[0], tags[1]));
+    }
+
+    @Test
+    public void testNoMatch() {
+        String tags[] = {"jueyin1", "jueyin2", "jueyin3"};
+        String subExpress = "no_match";
+        int msgSize = 10;
+
+        TagMessage tagMessage = new TagMessage(tags, topic, msgSize);
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, subExpress,
+            new RMQNormalListner());
+
+        producer.send(tagMessage.getMixedTagMessages());
+        Assert.assertEquals("Not all sent succeeded", msgSize * tags.length,
+            producer.getAllUndupMsgBody().size());
+
+        TestUtils.waitForSeconds(5);
+
+        assertThat(VerifyUtils
+            .getFilterdMessage(producer.getAllMsgBody(), consumer.getListner().getAllMsgBody())
+            .size()).isEqualTo(0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/tag/TagMessageWith1ConsumerIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/tag/TagMessageWith1ConsumerIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/tag/TagMessageWith1ConsumerIT.java
new file mode 100644
index 0000000..f0a1d48
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/tag/TagMessageWith1ConsumerIT.java
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.tag;
+
+import java.util.List;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.factory.MQMessageFactory;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class TagMessageWith1ConsumerIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(TagMessageWith1ConsumerIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        String consumerId = initConsumerGroup();
+        logger.info(String.format("use topic: %s; consumerId: %s !", topic, consumerId));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testTagSmoke() {
+        String tag = "jueyin";
+        int msgSize = 10;
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, tag, new RMQNormalListner());
+        producer.send(tag, msgSize);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+
+    @Test
+    public void testSubAllMessageNoTag() {
+        String subExprress = "*";
+        int msgSize = 10;
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, subExprress,
+            new RMQNormalListner());
+        producer.send(msgSize);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+
+    @Test
+    public void testSubAllMessageWithTag() {
+        String tag = "jueyin";
+        String subExpress = "*";
+        int msgSize = 10;
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, subExpress,
+            new RMQNormalListner());
+        producer.send(tag, msgSize);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+
+    @Test
+    public void testSubAllMessageWithNullTag() {
+        String tag = null;
+        String subExpress = "*";
+        int msgSize = 10;
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, subExpress,
+            new RMQNormalListner());
+        producer.send(tag, msgSize);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+
+    @Test
+    public void testSubNullWithTagNull() {
+        String tag = null;
+        String subExpress = null;
+        int msgSize = 10;
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, subExpress,
+            new RMQNormalListner());
+        producer.send(tag, msgSize);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+
+    @Test
+    public void testSubAllWithKindsOfMessage() {
+        String tag1 = null;
+        String tag2 = "jueyin";
+        String subExpress = "*";
+        int msgSize = 10;
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, subExpress,
+            new RMQNormalListner());
+
+        List<Object> tag1Msgs = MQMessageFactory.getRMQMessage(tag1, topic, msgSize);
+        List<Object> tag2Msgs = MQMessageFactory.getRMQMessage(tag2, topic, msgSize);
+
+        producer.send(tag1Msgs);
+        producer.send(tag2Msgs);
+        producer.send(10);
+        Assert.assertEquals("Not all are sent", msgSize * 3, producer.getAllUndupMsgBody().size());
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+
+    @Test
+    public void testSubNullWithKindsOfMessage() {
+        String tag1 = null;
+        String tag2 = "jueyin";
+        String subExpress = null;
+        int msgSize = 10;
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, subExpress,
+            new RMQNormalListner());
+
+        List<Object> tag1Msgs = MQMessageFactory.getRMQMessage(tag1, topic, msgSize);
+        List<Object> tag2Msgs = MQMessageFactory.getRMQMessage(tag2, topic, msgSize);
+
+        producer.send(tag1Msgs);
+        producer.send(tag2Msgs);
+        Assert.assertEquals("Not all are sent", msgSize * 2, producer.getAllUndupMsgBody().size());
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+
+    @Test
+    public void testSubTagWithKindsOfMessage() {
+        String tag1 = null;
+        String tag2 = "jueyin";
+        String subExpress = tag2;
+        int msgSize = 10;
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, subExpress,
+            new RMQNormalListner());
+
+        List<Object> tag1Msgs = MQMessageFactory.getRMQMessage(tag1, topic, msgSize);
+        List<Object> tag2Msgs = MQMessageFactory.getRMQMessage(tag2, topic, msgSize);
+
+        producer.send(tag1Msgs);
+        producer.send(tag2Msgs);
+        producer.send(10);
+        Assert.assertEquals("Not all are sent", msgSize * 3, producer.getAllUndupMsgBody().size());
+        consumer.getListner().waitForMessageConsume(MQMessageFactory.getMessageBody(tag2Msgs),
+            consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(MQMessageFactory.getMessageBody(tag2Msgs));
+    }
+}


[30/31] incubator-rocketmq git commit: [ROCKETMQ-54] Polish for resolve conflict

Posted by st...@apache.org.
[ROCKETMQ-54] Polish for resolve conflict


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/aae7cbe3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/aae7cbe3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/aae7cbe3

Branch: refs/heads/ROCKETMQ-54
Commit: aae7cbe36133ebe3181d6d30a140983a1c273530
Parents: 09439f7 d3a7f24
Author: stevenschew <st...@apache.org>
Authored: Sun Jan 22 18:09:42 2017 +0800
Committer: stevenschew <st...@apache.org>
Committed: Sun Jan 22 18:09:42 2017 +0800

----------------------------------------------------------------------
 .../rocketmq/namesrv/NameServerInstance.java    | 46 ++++++++++++++++++++
 1 file changed, 46 insertions(+)
----------------------------------------------------------------------



[04/31] incubator-rocketmq git commit: [ROCKETMQ-37] Polish log output information in MQClientManager, closes apache/incubator-rocketmq#33, closes apache/incubator-rocketmq#26

Posted by st...@apache.org.
[ROCKETMQ-37] Polish log output information in MQClientManager, closes apache/incubator-rocketmq#33, closes apache/incubator-rocketmq#26


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/69361f60
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/69361f60
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/69361f60

Branch: refs/heads/ROCKETMQ-54
Commit: 69361f60b70436996e3479e2ed4473f4f1ca2af1
Parents: 4291348
Author: a2888409 <12...@qq.com>
Authored: Fri Jan 20 10:55:48 2017 +0800
Committer: yukon <yu...@apache.org>
Committed: Fri Jan 20 10:55:48 2017 +0800

----------------------------------------------------------------------
 .../rocketmq/broker/subscription/SubscriptionGroupManager.java    | 2 +-
 .../java/org/apache/rocketmq/client/impl/MQClientManager.java     | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/69361f60/broker/src/main/java/org/apache/rocketmq/broker/subscription/SubscriptionGroupManager.java
----------------------------------------------------------------------
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/subscription/SubscriptionGroupManager.java b/broker/src/main/java/org/apache/rocketmq/broker/subscription/SubscriptionGroupManager.java
index 92dc5e7..bdf2a01 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/subscription/SubscriptionGroupManager.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/subscription/SubscriptionGroupManager.java
@@ -184,7 +184,7 @@ public class SubscriptionGroupManager extends ConfigManager {
             this.dataVersion.nextVersion();
             this.persist();
         } else {
-            log.warn("delete subscription group failed, subscription group: {} not exist", old);
+            log.warn("delete subscription group failed, subscription groupName: {} not exist", groupName);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/69361f60/client/src/main/java/org/apache/rocketmq/client/impl/MQClientManager.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/rocketmq/client/impl/MQClientManager.java b/client/src/main/java/org/apache/rocketmq/client/impl/MQClientManager.java
index 6f2c9a3..f596b83 100644
--- a/client/src/main/java/org/apache/rocketmq/client/impl/MQClientManager.java
+++ b/client/src/main/java/org/apache/rocketmq/client/impl/MQClientManager.java
@@ -53,8 +53,9 @@ public class MQClientManager {
             MQClientInstance prev = this.factoryTable.putIfAbsent(clientId, instance);
             if (prev != null) {
                 instance = prev;
+                log.warn("Returned Previous MQClientInstance for clientId:[{}]", clientId);
             } else {
-                log.warn("Previous MQClientInstance has created for clientId:[{}]", clientId);
+                log.info("Created new MQClientInstance for clientId:[{}]", clientId);
             }
         }
 


[03/31] incubator-rocketmq git commit: [ROCKETMQ-57] Add license

Posted by st...@apache.org.
[ROCKETMQ-57] Add license


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/0de84e20
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/0de84e20
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/0de84e20

Branch: refs/heads/ROCKETMQ-54
Commit: 0de84e20fccea6391e3f50fce051be795deeccd7
Parents: 8399389 4291348
Author: stevenschew <st...@apache.org>
Authored: Thu Jan 19 21:00:54 2017 +0800
Committer: stevenschew <st...@apache.org>
Committed: Thu Jan 19 21:00:54 2017 +0800

----------------------------------------------------------------------
 .travis.yml                                     |  45 +++-
 README.md                                       |   2 +-
 .../rocketmq/broker/BrokerTestHarness.java      |  69 ------
 .../broker/api/BrokerFastFailureTest.java       |  61 -----
 .../rocketmq/broker/api/SendMessageTest.java    |  79 ------
 .../offset/ConsumerOffsetManagerTest.java       |  61 -----
 .../broker/topic/TopicConfigManagerTest.java    |  60 -----
 .../consumer/DefaultMQPullConsumerTest.java     | 152 ++++++++++++
 .../consumer/DefaultMQPushConsumerTest.java     | 178 +++++++++++++
 .../store/LocalFileOffsetStoreTest.java         |   3 +-
 .../impl/factory/MQClientInstanceTest.java      |   6 +-
 .../client/producer/DefaultMQProducerTest.java  | 248 +++++++++++++++++++
 pom.xml                                         |  76 +++++-
 .../tools/admin/DefaultMQAdminExtTest.java      |  16 ++
 .../rocketmq/tools/command/CommandUtilTest.java |  16 ++
 15 files changed, 728 insertions(+), 344 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/0de84e20/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java
----------------------------------------------------------------------
diff --cc tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java
index ab6319f,0000000..5964cd1
mode 100644,000000..100644
--- a/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java
+++ b/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java
@@@ -1,240 -1,0 +1,256 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements.  See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You 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 org.apache.rocketmq.tools.admin;
 +
 +import org.apache.rocketmq.client.ClientConfig;
 +import org.apache.rocketmq.client.exception.MQBrokerException;
 +import org.apache.rocketmq.client.exception.MQClientException;
 +import org.apache.rocketmq.client.impl.MQClientAPIImpl;
 +import org.apache.rocketmq.client.impl.MQClientManager;
 +import org.apache.rocketmq.client.impl.factory.MQClientInstance;
 +import org.apache.rocketmq.common.namesrv.NamesrvUtil;
 +import org.apache.rocketmq.common.protocol.body.*;
 +import org.apache.rocketmq.common.protocol.route.BrokerData;
 +import org.apache.rocketmq.common.protocol.route.TopicRouteData;
 +import org.apache.rocketmq.common.subscription.SubscriptionGroupConfig;
 +import org.apache.rocketmq.remoting.exception.RemotingConnectException;
 +import org.apache.rocketmq.remoting.exception.RemotingException;
 +import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
 +import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
 +import org.junit.After;
 +import org.junit.Before;
 +import org.junit.Test;
 +import org.junit.runner.RunWith;
 +import org.mockito.junit.MockitoJUnitRunner;
 +
 +import java.io.UnsupportedEncodingException;
 +import java.lang.reflect.Field;
 +import java.util.*;
 +import java.util.concurrent.ConcurrentHashMap;
 +
 +import static org.assertj.core.api.Assertions.assertThat;
 +import static org.mockito.ArgumentMatchers.anyLong;
 +import static org.mockito.ArgumentMatchers.anyString;
 +import static org.mockito.Mockito.mock;
 +import static org.mockito.Mockito.when;
 +
 +@RunWith(MockitoJUnitRunner.class)
 +public class DefaultMQAdminExtTest {
 +    private DefaultMQAdminExtImpl defaultMQAdminExtImpl;
 +    private MQClientInstance mqClientInstance = MQClientManager.getInstance().getAndCreateMQClientInstance(new ClientConfig());
 +    private MQClientAPIImpl mQClientAPIImpl;
 +    private Properties properties = new Properties();
 +    private TopicList topicList = new TopicList();
 +    private TopicRouteData topicRouteData = new TopicRouteData();
 +    private KVTable kvTable = new KVTable();
 +    private ClusterInfo clusterInfo = new ClusterInfo();
 +
 +    @Before
 +    public void init() throws Exception {
 +        mQClientAPIImpl = mock(MQClientAPIImpl.class);
 +        DefaultMQAdminExt defaultMQAdminExt = new DefaultMQAdminExt();
 +        defaultMQAdminExtImpl = new DefaultMQAdminExtImpl(defaultMQAdminExt, 1000);
 +
 +        Field field = DefaultMQAdminExtImpl.class.getDeclaredField("mqClientInstance");
 +        field.setAccessible(true);
 +        field.set(defaultMQAdminExtImpl, mqClientInstance);
 +        field = MQClientInstance.class.getDeclaredField("mQClientAPIImpl");
 +        field.setAccessible(true);
 +        field.set(mqClientInstance, mQClientAPIImpl);
 +
 +        properties.setProperty("maxMessageSize", "5000000");
 +        properties.setProperty("flushDelayOffsetInterval", "15000");
 +        properties.setProperty("serverSocketRcvBufSize", "655350");
 +        when(mQClientAPIImpl.getBrokerConfig(anyString(), anyLong())).thenReturn(properties);
 +
 +        Set<String> topicSet = new HashSet<>();
 +        topicSet.add("topic_one");
 +        topicSet.add("topic_two");
 +        topicList.setTopicList(topicSet);
 +        when(mQClientAPIImpl.getTopicListFromNameServer(anyLong())).thenReturn(topicList);
 +
 +
 +        List<BrokerData> brokerDatas = new ArrayList<>();
 +        HashMap<Long, String> brokerAddrs = new HashMap<>();
 +        brokerAddrs.put(1234l, "127.0.0.1:10911");
 +        BrokerData brokerData = new BrokerData();
 +        brokerData.setCluster("default-cluster");
 +        brokerData.setBrokerName("default-broker");
 +        brokerData.setBrokerAddrs(brokerAddrs);
 +        brokerDatas.add(brokerData);
 +        topicRouteData.setBrokerDatas(brokerDatas);
 +        when(mQClientAPIImpl.getTopicRouteInfoFromNameServer(anyString(), anyLong())).thenReturn(topicRouteData);
 +
 +        HashMap<String, String> result = new HashMap<>();
 +        result.put("id", "1234");
 +        result.put("brokerName", "default-broker");
 +        kvTable.setTable(result);
 +        when(mQClientAPIImpl.getBrokerRuntimeInfo(anyString(), anyLong())).thenReturn(kvTable);
 +
 +        HashMap<String, BrokerData> brokerAddrTable = new HashMap<>();
 +        brokerAddrTable.put("default-broker", brokerData);
 +        brokerAddrTable.put("broker-test", new BrokerData());
 +        clusterInfo.setBrokerAddrTable(brokerAddrTable);
 +        when(mQClientAPIImpl.getBrokerClusterInfo(anyLong())).thenReturn(clusterInfo);
 +        when(mQClientAPIImpl.cleanExpiredConsumeQueue(anyString(), anyLong())).thenReturn(true);
 +
 +        Set<String> clusterList = new HashSet<>();
 +        clusterList.add("default-cluster-one");
 +        clusterList.add("default-cluster-two");
 +        when(mQClientAPIImpl.getClusterList(anyString(), anyLong())).thenReturn(clusterList);
 +
 +        GroupList groupList = new GroupList();
 +        HashSet<String> groups = new HashSet<>();
 +        groups.add("consumer-group-one");
 +        groups.add("consumer-group-two");
 +        groupList.setGroupList(groups);
 +        when(mQClientAPIImpl.getTopicRouteInfoFromNameServer(anyString(), anyLong())).thenReturn(topicRouteData);
 +        when(mQClientAPIImpl.queryTopicConsumeByWho(anyString(), anyString(), anyLong())).thenReturn(groupList);
 +
 +        SubscriptionGroupWrapper subscriptionGroupWrapper = new SubscriptionGroupWrapper();
 +        ConcurrentHashMap<String, SubscriptionGroupConfig> subscriptions = new ConcurrentHashMap<>();
 +        SubscriptionGroupConfig subscriptionGroupConfig = new SubscriptionGroupConfig();
 +        subscriptionGroupConfig.setConsumeBroadcastEnable(true);
 +        subscriptionGroupConfig.setBrokerId(1234);
 +        subscriptionGroupConfig.setGroupName("Consumer-group-one");
 +        subscriptions.put("Consumer-group-one", subscriptionGroupConfig);
 +        subscriptionGroupWrapper.setSubscriptionGroupTable(subscriptions);
 +        when(mQClientAPIImpl.getAllSubscriptionGroup(anyString(), anyLong())).thenReturn(subscriptionGroupWrapper);
 +
 +        String topicListConfig = "topicListConfig";
 +        when(mQClientAPIImpl.getKVConfigValue(anyString(), anyString(), anyLong())).thenReturn(topicListConfig);
 +
 +        KVTable kvTable = new KVTable();
 +        HashMap<String, String> kv = new HashMap<>();
 +        kv.put("broker-name", "broker-one");
 +        kv.put("cluster-name", "default-cluster");
 +        kvTable.setTable(kv);
 +        when(mQClientAPIImpl.getKVListByNamespace(anyString(), anyLong())).thenReturn(kvTable);
 +    }
 +
 +    @After
 +    public void terminate() throws Exception {
 +        if (defaultMQAdminExtImpl != null)
 +            defaultMQAdminExtImpl.shutdown();
 +    }
 +
 +    @Test
 +    public void testUpdateBrokerConfig() throws InterruptedException, RemotingConnectException, UnsupportedEncodingException, RemotingTimeoutException, MQBrokerException, RemotingSendRequestException {
 +        Properties result = defaultMQAdminExtImpl.getBrokerConfig("127.0.0.1:10911");
 +        assertThat(result.getProperty("maxMessageSize")).isEqualTo("5000000");
 +        assertThat(result.getProperty("flushDelayOffsetInterval")).isEqualTo("15000");
 +        assertThat(result.getProperty("serverSocketRcvBufSize")).isEqualTo("655350");
 +    }
 +
 +
 +    @Test
 +    public void testFetchAllTopicList() throws RemotingException, MQClientException, InterruptedException {
 +        TopicList topicList = defaultMQAdminExtImpl.fetchAllTopicList();
 +        assertThat(topicList.getTopicList().size()).isEqualTo(2);
 +        assertThat(topicList.getTopicList()).contains("topic_one");
 +    }
 +
 +    @Test
 +    public void testFetchBrokerRuntimeStats() throws InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException {
 +        KVTable brokerStats = defaultMQAdminExtImpl.fetchBrokerRuntimeStats("127.0.0.1:10911");
 +        assertThat(brokerStats.getTable().get("id")).isEqualTo("1234");
 +        assertThat(brokerStats.getTable().get("brokerName")).isEqualTo("default-broker");
 +    }
 +
 +    @Test
 +    public void testExamineBrokerClusterInfo() throws InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException {
 +        ClusterInfo clusterInfo = defaultMQAdminExtImpl.examineBrokerClusterInfo();
 +        HashMap<String, BrokerData> brokerList = clusterInfo.getBrokerAddrTable();
 +        assertThat(brokerList.get("default-broker").getBrokerName()).isEqualTo("default-broker");
 +        assertThat(brokerList.containsKey("broker-test")).isTrue();
 +
 +        HashMap<String, Set<String>> clusterMap = new HashMap<>();
 +        Set<String> brokers = new HashSet<>();
 +        brokers.add("default-broker");
 +        brokers.add("broker-test");
 +        clusterMap.put("default-cluster", brokers);
 +        ClusterInfo cInfo = mock(ClusterInfo.class);
 +        when(cInfo.getClusterAddrTable()).thenReturn(clusterMap);
 +        HashMap<String, Set<String>> clusterAddress = cInfo.getClusterAddrTable();
 +        assertThat(clusterAddress.containsKey("default-cluster")).isTrue();
 +        assertThat(clusterAddress.get("default-cluster").size()).isEqualTo(2);
 +    }
 +
 +    @Test
 +    public void testExamineTopicRouteInfo() throws RemotingException, MQClientException, InterruptedException {
 +        TopicRouteData topicRouteData = defaultMQAdminExtImpl.examineTopicRouteInfo("UnitTest");
 +        assertThat(topicRouteData.getBrokerDatas().get(0).getBrokerName()).isEqualTo("default-broker");
 +        assertThat(topicRouteData.getBrokerDatas().get(0).getCluster()).isEqualTo("default-cluster");
 +    }
 +
 +    @Test
 +    public void testGetNameServerAddressList() {
 +        List<String> result = new ArrayList<>();
 +        result.add("default-name-one");
 +        result.add("default-name-two");
 +        when(mqClientInstance.getMQClientAPIImpl().getNameServerAddressList()).thenReturn(result);
 +        List<String> nameList = defaultMQAdminExtImpl.getNameServerAddressList();
 +        assertThat(nameList.get(0)).isEqualTo("default-name-one");
 +        assertThat(nameList.get(1)).isEqualTo("default-name-two");
 +    }
 +
 +    @Test
 +    public void testPutKVConfig() throws RemotingException, MQClientException, InterruptedException {
 +        String topicConfig = defaultMQAdminExtImpl.getKVConfig(NamesrvUtil.NAMESPACE_ORDER_TOPIC_CONFIG, "UnitTest");
 +        assertThat(topicConfig).isEqualTo("topicListConfig");
 +        KVTable kvs = defaultMQAdminExtImpl.getKVListByNamespace(NamesrvUtil.NAMESPACE_ORDER_TOPIC_CONFIG);
 +        assertThat(kvs.getTable().get("broker-name")).isEqualTo("broker-one");
 +        assertThat(kvs.getTable().get("cluster-name")).isEqualTo("default-cluster");
 +    }
 +
 +
 +    @Test
 +    public void testQueryTopicConsumeByWho() throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
 +        GroupList groupList = defaultMQAdminExtImpl.queryTopicConsumeByWho("UnitTest");
 +        assertThat(groupList.getGroupList().contains("consumer-group-two")).isTrue();
 +    }
 +
 +    @Test
 +    public void testCleanExpiredConsumerQueueByAddr() throws InterruptedException, RemotingTimeoutException, MQClientException, RemotingSendRequestException, RemotingConnectException {
 +        boolean clean = defaultMQAdminExtImpl.cleanExpiredConsumerQueueByAddr("127.0.0.1:10911");
 +        assertThat(clean).isTrue();
 +    }
 +
 +    @Test
 +    public void testGetClusterList() throws InterruptedException, RemotingTimeoutException, MQClientException, RemotingSendRequestException, RemotingConnectException {
 +        Set<String> clusterlist = defaultMQAdminExtImpl.getClusterList("UnitTest");
 +        assertThat(clusterlist.contains("default-cluster-one")).isTrue();
 +        assertThat(clusterlist.contains("default-cluster-two")).isTrue();
 +    }
 +
 +    @Test
 +    public void testFetchConsumeStatsInBroker() throws InterruptedException, RemotingTimeoutException, MQClientException, RemotingSendRequestException, RemotingConnectException {
 +        ConsumeStatsList result = new ConsumeStatsList();
 +        result.setBrokerAddr("127.0.0.1:10911");
 +        when(mqClientInstance.getMQClientAPIImpl().fetchConsumeStatsInBroker("127.0.0.1:10911", false, 10000)).thenReturn(result);
 +        ConsumeStatsList consumeStatsList = defaultMQAdminExtImpl.fetchConsumeStatsInBroker("127.0.0.1:10911", false, 10000);
 +        assertThat(consumeStatsList.getBrokerAddr()).isEqualTo("127.0.0.1:10911");
 +    }
 +
 +    @Test
 +    public void testGetAllSubscriptionGroup() throws InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException {
 +        SubscriptionGroupWrapper subscriptionGroupWrapper = defaultMQAdminExtImpl.getAllSubscriptionGroup("127.0.0.1:10911", 10000);
 +        assertThat(subscriptionGroupWrapper.getSubscriptionGroupTable().get("Consumer-group-one").getBrokerId()).isEqualTo(1234);
 +        assertThat(subscriptionGroupWrapper.getSubscriptionGroupTable().get("Consumer-group-one").getGroupName()).isEqualTo("Consumer-group-one");
 +        assertThat(subscriptionGroupWrapper.getSubscriptionGroupTable().get("Consumer-group-one").isConsumeBroadcastEnable()).isTrue();
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/0de84e20/tools/src/test/java/org/apache/rocketmq/tools/command/CommandUtilTest.java
----------------------------------------------------------------------
diff --cc tools/src/test/java/org/apache/rocketmq/tools/command/CommandUtilTest.java
index 35c205e,0000000..ba58010
mode 100644,000000..100644
--- a/tools/src/test/java/org/apache/rocketmq/tools/command/CommandUtilTest.java
+++ b/tools/src/test/java/org/apache/rocketmq/tools/command/CommandUtilTest.java
@@@ -1,92 -1,0 +1,108 @@@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one or more
++ * contributor license agreements.  See the NOTICE file distributed with
++ * this work for additional information regarding copyright ownership.
++ * The ASF licenses this file to You 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 org.apache.rocketmq.tools.command;
 +
 +import org.apache.rocketmq.client.ClientConfig;
 +import org.apache.rocketmq.client.exception.MQBrokerException;
 +import org.apache.rocketmq.client.exception.MQClientException;
 +import org.apache.rocketmq.client.impl.MQClientAPIImpl;
 +import org.apache.rocketmq.client.impl.MQClientManager;
 +import org.apache.rocketmq.client.impl.factory.MQClientInstance;
 +import org.apache.rocketmq.common.protocol.body.ClusterInfo;
 +import org.apache.rocketmq.common.protocol.route.BrokerData;
 +import org.apache.rocketmq.remoting.exception.RemotingConnectException;
 +import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
 +import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
 +import org.apache.rocketmq.tools.admin.DefaultMQAdminExt;
 +import org.apache.rocketmq.tools.admin.DefaultMQAdminExtImpl;
 +import org.junit.After;
 +import org.junit.Before;
 +import org.junit.Test;
 +
 +import java.lang.reflect.Field;
 +import java.util.*;
 +
 +import static org.assertj.core.api.Assertions.assertThat;
 +import static org.mockito.ArgumentMatchers.anyLong;
 +import static org.mockito.ArgumentMatchers.anyString;
 +import static org.mockito.Mockito.mock;
 +import static org.mockito.Mockito.when;
 +
 +public class CommandUtilTest {
 +    private DefaultMQAdminExt defaultMQAdminExt;
 +    private DefaultMQAdminExtImpl defaultMQAdminExtImpl;
 +    private MQClientInstance mqClientInstance = MQClientManager.getInstance().getAndCreateMQClientInstance(new ClientConfig());
 +    private MQClientAPIImpl mQClientAPIImpl;
 +
 +    @Before
 +    public void setup() throws MQClientException, NoSuchFieldException, IllegalAccessException, InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException {
 +        defaultMQAdminExt = mock(DefaultMQAdminExt.class);
 +        MQClientAPIImpl mQClientAPIImpl = mock(MQClientAPIImpl.class);
 +        defaultMQAdminExtImpl = new DefaultMQAdminExtImpl(defaultMQAdminExt, 3000);
 +
 +        Field field = DefaultMQAdminExtImpl.class.getDeclaredField("mqClientInstance");
 +        field.setAccessible(true);
 +        field.set(defaultMQAdminExtImpl, mqClientInstance);
 +        field = MQClientInstance.class.getDeclaredField("mQClientAPIImpl");
 +        field.setAccessible(true);
 +        field.set(mqClientInstance, mQClientAPIImpl);
 +
 +        ClusterInfo clusterInfo = new ClusterInfo();
 +        HashMap<String, BrokerData> brokerAddrTable = new HashMap<>();
 +        HashMap<String, Set<String>> clusterAddrTable = new HashMap<>();
 +        HashMap<Long, String> brokerAddrs = new HashMap<>();
 +        brokerAddrs.put(1234l, "127.0.0.1:10911");
 +        BrokerData brokerData = new BrokerData();
 +        brokerData.setBrokerName("default-broker");
 +        brokerData.setCluster("default-cluster");
 +        brokerData.setBrokerAddrs(brokerAddrs);
 +        brokerAddrTable.put("default-broker", brokerData);
 +        brokerAddrTable.put("broker-test", new BrokerData());
 +        Set<String> brokerSet = new HashSet<>();
 +        brokerSet.add("default-broker");
 +        brokerSet.add("default-broker-one");
 +        clusterAddrTable.put("default-cluster", brokerSet);
 +        clusterInfo.setBrokerAddrTable(brokerAddrTable);
 +        clusterInfo.setClusterAddrTable(clusterAddrTable);
 +        when(mQClientAPIImpl.getBrokerClusterInfo(anyLong())).thenReturn(clusterInfo);
 +        when(mQClientAPIImpl.cleanExpiredConsumeQueue(anyString(), anyLong())).thenReturn(true);
 +    }
 +
 +    @After
 +    public void shutdown() throws Exception {
 +    }
 +
 +    @Test
 +    public void testFetchMasterAndSlaveDistinguish() throws InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException {
 +        Map<String, List<String>> result = CommandUtil.fetchMasterAndSlaveDistinguish(defaultMQAdminExtImpl, "default-cluster");
 +        assertThat(result.get(null).get(0)).isEqualTo("127.0.0.1:10911");
 +    }
 +
 +    @Test
 +    public void testFetchMasterAddrByClusterName() throws InterruptedException, MQBrokerException, RemotingTimeoutException, RemotingSendRequestException, RemotingConnectException {
 +        Set<String> result = CommandUtil.fetchMasterAddrByClusterName(defaultMQAdminExtImpl, "default-cluster");
 +        assertThat(result.size()).isEqualTo(0);
 +    }
 +
 +    @Test
 +    public void testFetchBrokerNameByClusterName() throws Exception {
 +        Set<String> result = CommandUtil.fetchBrokerNameByClusterName(defaultMQAdminExtImpl, "default-cluster");
 +        assertThat(result.contains("default-broker")).isTrue();
 +        assertThat(result.contains("default-broker-one")).isTrue();
 +        assertThat(result.size()).isEqualTo(2);
 +    }
 +}


[31/31] incubator-rocketmq git commit: [ROCKETMQ-54] Polish unit test for RouteInfoManager and BrokerHouseKeepingService

Posted by st...@apache.org.
[ROCKETMQ-54] Polish unit test for RouteInfoManager and BrokerHouseKeepingService


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/e403ca39
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/e403ca39
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/e403ca39

Branch: refs/heads/ROCKETMQ-54
Commit: e403ca3977d7eb597083881034408239b7c79149
Parents: aae7cbe
Author: stevenschew <st...@apache.org>
Authored: Sun Jan 22 20:09:21 2017 +0800
Committer: stevenschew <st...@apache.org>
Committed: Sun Jan 22 20:09:21 2017 +0800

----------------------------------------------------------------------
 .../processor/DefaultRequestProcessorTest.java  |  1 -
 .../BrokerHousekeepingServiceTest.java          | 59 ++++++++++++++++++++
 .../namesrv/routeinfo/RouteInfoManagerTest.java | 25 ++++++++-
 3 files changed, 81 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/e403ca39/namesrv/src/test/java/org/apache/rocketmq/namesrv/processor/DefaultRequestProcessorTest.java
----------------------------------------------------------------------
diff --git a/namesrv/src/test/java/org/apache/rocketmq/namesrv/processor/DefaultRequestProcessorTest.java b/namesrv/src/test/java/org/apache/rocketmq/namesrv/processor/DefaultRequestProcessorTest.java
index 80d968f..4ee944d 100644
--- a/namesrv/src/test/java/org/apache/rocketmq/namesrv/processor/DefaultRequestProcessorTest.java
+++ b/namesrv/src/test/java/org/apache/rocketmq/namesrv/processor/DefaultRequestProcessorTest.java
@@ -45,7 +45,6 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 public class DefaultRequestProcessorTest {
-    /** Test Target */
     private DefaultRequestProcessor defaultRequestProcessor;
 
     private NamesrvController namesrvController;

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/e403ca39/namesrv/src/test/java/org/apache/rocketmq/namesrv/routeinfo/BrokerHousekeepingServiceTest.java
----------------------------------------------------------------------
diff --git a/namesrv/src/test/java/org/apache/rocketmq/namesrv/routeinfo/BrokerHousekeepingServiceTest.java b/namesrv/src/test/java/org/apache/rocketmq/namesrv/routeinfo/BrokerHousekeepingServiceTest.java
new file mode 100644
index 0000000..ce6ce23
--- /dev/null
+++ b/namesrv/src/test/java/org/apache/rocketmq/namesrv/routeinfo/BrokerHousekeepingServiceTest.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.namesrv.routeinfo;
+
+import org.apache.rocketmq.common.namesrv.NamesrvConfig;
+import org.apache.rocketmq.namesrv.NamesrvController;
+import org.apache.rocketmq.remoting.netty.NettyServerConfig;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class BrokerHousekeepingServiceTest {
+    private static BrokerHousekeepingService brokerHousekeepingService;
+
+    @BeforeClass
+    public static void setup() {
+        NamesrvController namesrvController = new NamesrvController(
+            new NamesrvConfig(),
+            new NettyServerConfig()
+        );
+        brokerHousekeepingService = new BrokerHousekeepingService(namesrvController);
+    }
+
+    @AfterClass
+    public static void terminate() {
+
+    }
+
+    @Test
+    public void testOnChannelClose() {
+        brokerHousekeepingService.onChannelClose("127.0.0.1:9876", null);
+    }
+
+    @Test
+    public void testOnChannelException() {
+        brokerHousekeepingService.onChannelException("127.0.0.1:9876", null);
+    }
+
+    @Test
+    public void testOnChannelIdle() {
+        brokerHousekeepingService.onChannelException("127.0.0.1:9876", null);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/e403ca39/namesrv/src/test/java/org/apache/rocketmq/namesrv/routeinfo/RouteInfoManagerTest.java
----------------------------------------------------------------------
diff --git a/namesrv/src/test/java/org/apache/rocketmq/namesrv/routeinfo/RouteInfoManagerTest.java b/namesrv/src/test/java/org/apache/rocketmq/namesrv/routeinfo/RouteInfoManagerTest.java
index cd6c50c..5ab77be 100644
--- a/namesrv/src/test/java/org/apache/rocketmq/namesrv/routeinfo/RouteInfoManagerTest.java
+++ b/namesrv/src/test/java/org/apache/rocketmq/namesrv/routeinfo/RouteInfoManagerTest.java
@@ -18,9 +18,12 @@ package org.apache.rocketmq.namesrv.routeinfo;
 
 import io.netty.channel.Channel;
 import java.util.ArrayList;
+import java.util.concurrent.ConcurrentHashMap;
+import org.apache.rocketmq.common.TopicConfig;
 import org.apache.rocketmq.common.namesrv.RegisterBrokerResult;
 import org.apache.rocketmq.common.protocol.body.TopicConfigSerializeWrapper;
 import org.apache.rocketmq.common.protocol.route.TopicRouteData;
+import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -30,11 +33,18 @@ import static org.mockito.Mockito.mock;
 
 public class RouteInfoManagerTest {
 
-    private RouteInfoManager routeInfoManager;
+    private static RouteInfoManager routeInfoManager;
 
     @Before
     public void setup() {
         routeInfoManager = new RouteInfoManager();
+        testRegisterBroker();
+    }
+
+    @After
+    public void terminate() {
+        routeInfoManager.printAllPeriodically();
+        routeInfoManager.unregisterBroker("default-cluster", "127.0.0.1:10911", "default-broker", 1234);
     }
 
     @Test
@@ -52,7 +62,16 @@ public class RouteInfoManagerTest {
 
     @Test
     public void testRegisterBroker() {
-        TopicConfigSerializeWrapper topicConfigSerializeWrapper = mock(TopicConfigSerializeWrapper.class);
+        TopicConfigSerializeWrapper topicConfigSerializeWrapper = new TopicConfigSerializeWrapper();
+        ConcurrentHashMap<String, TopicConfig> topicConfigConcurrentHashMap = new ConcurrentHashMap<>();
+        TopicConfig topicConfig = new TopicConfig();
+        topicConfig.setWriteQueueNums(8);
+        topicConfig.setTopicName("unit-test");
+        topicConfig.setPerm(6);
+        topicConfig.setReadQueueNums(8);
+        topicConfig.setOrder(false);
+        topicConfigConcurrentHashMap.put("unit-test", topicConfig);
+        topicConfigSerializeWrapper.setTopicConfigTable(topicConfigConcurrentHashMap);
         Channel channel = mock(Channel.class);
         RegisterBrokerResult registerBrokerResult = routeInfoManager.registerBroker("default-cluster", "127.0.0.1:10911", "default-broker", 1234, "127.0.0.1:1001",
             topicConfigSerializeWrapper, new ArrayList<String>(), channel);
@@ -61,7 +80,7 @@ public class RouteInfoManagerTest {
 
     @Test
     public void testWipeWritePermOfBrokerByLock() {
-        int result = routeInfoManager.wipeWritePermOfBrokerByLock("default-broker-name");
+        int result = routeInfoManager.wipeWritePermOfBrokerByLock("default-broker");
         assertThat(result).isEqualTo(0);
     }
 


[15/31] incubator-rocketmq git commit: [ROCKETMQ-57] Add unit test for DefaultMQAdminExt

Posted by st...@apache.org.
[ROCKETMQ-57] Add unit test for DefaultMQAdminExt


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/f8d881ba
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/f8d881ba
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/f8d881ba

Branch: refs/heads/ROCKETMQ-54
Commit: f8d881babe3f8f8810f1303912b2fb0ef2badea0
Parents: 0de84e2
Author: stevenschew <st...@apache.org>
Authored: Fri Jan 20 14:53:43 2017 +0800
Committer: stevenschew <st...@apache.org>
Committed: Fri Jan 20 14:53:43 2017 +0800

----------------------------------------------------------------------
 .../tools/admin/DefaultMQAdminExtTest.java      | 136 ++++++++++++++++++-
 1 file changed, 130 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/f8d881ba/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java
----------------------------------------------------------------------
diff --git a/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java b/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java
index 5964cd1..da3bd8c 100644
--- a/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java
+++ b/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java
@@ -22,15 +22,21 @@ import org.apache.rocketmq.client.exception.MQClientException;
 import org.apache.rocketmq.client.impl.MQClientAPIImpl;
 import org.apache.rocketmq.client.impl.MQClientManager;
 import org.apache.rocketmq.client.impl.factory.MQClientInstance;
+import org.apache.rocketmq.common.admin.*;
+import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.apache.rocketmq.common.message.MessageQueue;
 import org.apache.rocketmq.common.namesrv.NamesrvUtil;
 import org.apache.rocketmq.common.protocol.body.*;
+import org.apache.rocketmq.common.protocol.heartbeat.ConsumeType;
+import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
+import org.apache.rocketmq.common.protocol.heartbeat.SubscriptionData;
 import org.apache.rocketmq.common.protocol.route.BrokerData;
+import org.apache.rocketmq.common.protocol.route.QueueData;
 import org.apache.rocketmq.common.protocol.route.TopicRouteData;
 import org.apache.rocketmq.common.subscription.SubscriptionGroupConfig;
-import org.apache.rocketmq.remoting.exception.RemotingConnectException;
-import org.apache.rocketmq.remoting.exception.RemotingException;
-import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
-import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
+import org.apache.rocketmq.remoting.exception.*;
+import org.apache.rocketmq.tools.admin.api.MessageTrack;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -43,8 +49,7 @@ import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -93,6 +98,8 @@ public class DefaultMQAdminExtTest {
         brokerData.setBrokerAddrs(brokerAddrs);
         brokerDatas.add(brokerData);
         topicRouteData.setBrokerDatas(brokerDatas);
+        topicRouteData.setQueueDatas(new ArrayList<QueueData>());
+        topicRouteData.setFilterServerTable(new HashMap<String, List<String>>());
         when(mQClientAPIImpl.getTopicRouteInfoFromNameServer(anyString(), anyLong())).thenReturn(topicRouteData);
 
         HashMap<String, String> result = new HashMap<>();
@@ -105,6 +112,7 @@ public class DefaultMQAdminExtTest {
         brokerAddrTable.put("default-broker", brokerData);
         brokerAddrTable.put("broker-test", new BrokerData());
         clusterInfo.setBrokerAddrTable(brokerAddrTable);
+        clusterInfo.setClusterAddrTable(new HashMap<String, Set<String>>());
         when(mQClientAPIImpl.getBrokerClusterInfo(anyLong())).thenReturn(clusterInfo);
         when(mQClientAPIImpl.cleanExpiredConsumeQueue(anyString(), anyLong())).thenReturn(true);
 
@@ -140,6 +148,52 @@ public class DefaultMQAdminExtTest {
         kv.put("cluster-name", "default-cluster");
         kvTable.setTable(kv);
         when(mQClientAPIImpl.getKVListByNamespace(anyString(), anyLong())).thenReturn(kvTable);
+
+        ConsumeStats consumeStats = new ConsumeStats();
+        consumeStats.setConsumeTps(1234);
+        MessageQueue messageQueue = new MessageQueue();
+        OffsetWrapper offsetWrapper = new OffsetWrapper();
+        HashMap<MessageQueue, OffsetWrapper> stats = new HashMap<>();
+        stats.put(messageQueue, offsetWrapper);
+        consumeStats.setOffsetTable(stats);
+        when(mQClientAPIImpl.getConsumeStats(anyString(), anyString(), anyString(), anyLong())).thenReturn(consumeStats);
+
+        ConsumerConnection consumerConnection = new ConsumerConnection();
+        consumerConnection.setConsumeType(ConsumeType.CONSUME_PASSIVELY);
+        consumerConnection.setMessageModel(MessageModel.CLUSTERING);
+        HashSet<Connection> connections = new HashSet<>();
+        connections.add(new Connection());
+        consumerConnection.setConnectionSet(connections);
+        consumerConnection.setSubscriptionTable(new ConcurrentHashMap<String, SubscriptionData>());
+        consumerConnection.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
+        when(mQClientAPIImpl.getConsumerConnectionList(anyString(), anyString(), anyLong())).thenReturn(consumerConnection);
+
+        ProducerConnection producerConnection = new ProducerConnection();
+        Connection connection = new Connection();
+        connection.setClientAddr("127.0.0.1:9898");
+        connection.setClientId("PID_12345");
+        HashSet<Connection> connectionSet = new HashSet<Connection>();
+        connectionSet.add(connection);
+        producerConnection.setConnectionSet(connectionSet);
+        when(mQClientAPIImpl.getProducerConnectionList(anyString(), anyString(), anyLong())).thenReturn(producerConnection);
+
+        when(mQClientAPIImpl.wipeWritePermOfBroker(anyString(), anyString(), anyLong())).thenReturn(6);
+
+        TopicStatsTable topicStatsTable = new TopicStatsTable();
+        topicStatsTable.setOffsetTable(new HashMap<MessageQueue, TopicOffset>());
+
+        Map<String, Map<MessageQueue, Long>> consumerStatus = new HashMap<>();
+        when(mQClientAPIImpl.invokeBrokerToGetConsumerStatus(anyString(), anyString(), anyString(), anyString(), anyLong())).thenReturn(consumerStatus);
+
+        List<QueueTimeSpan> queueTimeSpanList = new ArrayList<>();
+        when(mQClientAPIImpl.queryConsumeTimeSpan(anyString(), anyString(), anyString(), anyLong())).thenReturn(queueTimeSpanList);
+
+        ConsumerRunningInfo consumerRunningInfo = new ConsumerRunningInfo();
+        consumerRunningInfo.setJstack("test");
+        consumerRunningInfo.setMqTable(new TreeMap<MessageQueue, ProcessQueueInfo>());
+        consumerRunningInfo.setStatusTable(new TreeMap<String, ConsumeStatus>());
+        consumerRunningInfo.setSubscriptionSet(new TreeSet<SubscriptionData>());
+        when(mQClientAPIImpl.getConsumerRunningInfo(anyString(), anyString(), anyString(), anyBoolean(), anyLong())).thenReturn(consumerRunningInfo);
     }
 
     @After
@@ -191,6 +245,31 @@ public class DefaultMQAdminExtTest {
     }
 
     @Test
+    public void testExamineConsumeStats() throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
+        ConsumeStats consumeStats = defaultMQAdminExtImpl.examineConsumeStats("default-consumer-group", "unit-test");
+        assertThat(consumeStats.getConsumeTps()).isEqualTo(1234);
+    }
+
+    @Test
+    public void testExamineConsumerConnectionInfo() throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
+        ConsumerConnection consumerConnection = defaultMQAdminExtImpl.examineConsumerConnectionInfo("default-consumer-group");
+        assertThat(consumerConnection.getConsumeType()).isEqualTo(ConsumeType.CONSUME_PASSIVELY);
+        assertThat(consumerConnection.getMessageModel()).isEqualTo(MessageModel.CLUSTERING);
+    }
+
+    @Test
+    public void testExamineProducerConnectionInfo() throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
+        ProducerConnection producerConnection = defaultMQAdminExtImpl.examineProducerConnectionInfo("default-producer-group", "unit-test");
+        assertThat(producerConnection.getConnectionSet().size()).isEqualTo(1);
+    }
+
+    @Test
+    public void testWipeWritePermOfBroker() throws InterruptedException, RemotingCommandException, RemotingSendRequestException, RemotingTimeoutException, MQClientException, RemotingConnectException {
+        int result = defaultMQAdminExtImpl.wipeWritePermOfBroker("127.0.0.1:9876", "default-broker");
+        assertThat(result).isEqualTo(6);
+    }
+
+    @Test
     public void testExamineTopicRouteInfo() throws RemotingException, MQClientException, InterruptedException {
         TopicRouteData topicRouteData = defaultMQAdminExtImpl.examineTopicRouteInfo("UnitTest");
         assertThat(topicRouteData.getBrokerDatas().get(0).getBrokerName()).isEqualTo("default-broker");
@@ -225,12 +304,57 @@ public class DefaultMQAdminExtTest {
     }
 
     @Test
+    public void testQueryConsumeTimeSpan() throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
+        List<QueueTimeSpan> result = defaultMQAdminExtImpl.queryConsumeTimeSpan("unit-test", "default-broker-group");
+        assertThat(result.size()).isEqualTo(0);
+    }
+
+    @Test
+    public void testCleanExpiredConsumerQueue() throws InterruptedException, RemotingTimeoutException, MQClientException, RemotingSendRequestException, RemotingConnectException {
+        boolean result = defaultMQAdminExtImpl.cleanExpiredConsumerQueue("default-cluster");
+        assertThat(result).isFalse();
+    }
+
+    @Test
     public void testCleanExpiredConsumerQueueByAddr() throws InterruptedException, RemotingTimeoutException, MQClientException, RemotingSendRequestException, RemotingConnectException {
         boolean clean = defaultMQAdminExtImpl.cleanExpiredConsumerQueueByAddr("127.0.0.1:10911");
         assertThat(clean).isTrue();
     }
 
     @Test
+    public void testCleanUnusedTopic() throws InterruptedException, RemotingTimeoutException, MQClientException, RemotingSendRequestException, RemotingConnectException {
+        boolean result = defaultMQAdminExtImpl.cleanUnusedTopic("default-cluster");
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void testGetConsumerRunningInfo() throws RemotingException, MQClientException, InterruptedException {
+        ConsumerRunningInfo consumerRunningInfo = defaultMQAdminExtImpl.getConsumerRunningInfo("consumer-group", "cid_123", false);
+        assertThat(consumerRunningInfo.getJstack()).isEqualTo("test");
+    }
+
+    @Test
+    public void testMessageTrackDetail() throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
+        MessageExt messageExt = new MessageExt();
+        messageExt.setMsgId("msgId");
+        messageExt.setTopic("unit-test");
+        List<MessageTrack> messageTrackList = defaultMQAdminExtImpl.messageTrackDetail(messageExt);
+        assertThat(messageTrackList.size()).isEqualTo(2);
+    }
+
+    @Test
+    public void testGetConsumeStatus() throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
+        Map<String, Map<MessageQueue, Long>> result = defaultMQAdminExtImpl.getConsumeStatus("unit-test", "default-broker-group", "127.0.0.1:10911");
+        assertThat(result.size()).isEqualTo(0);
+    }
+
+    @Test
+    public void testGetTopicClusterList() throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
+        Set<String> result = defaultMQAdminExtImpl.getTopicClusterList("unit-test");
+        assertThat(result.size()).isEqualTo(0);
+    }
+
+    @Test
     public void testGetClusterList() throws InterruptedException, RemotingTimeoutException, MQClientException, RemotingSendRequestException, RemotingConnectException {
         Set<String> clusterlist = defaultMQAdminExtImpl.getClusterList("UnitTest");
         assertThat(clusterlist.contains("default-cluster-one")).isTrue();


[20/31] incubator-rocketmq git commit: [ROCKETMQ-51] Add unit tests for ClientManageProcessor

Posted by st...@apache.org.
[ROCKETMQ-51] Add unit tests for ClientManageProcessor


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/b29c318c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/b29c318c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/b29c318c

Branch: refs/heads/ROCKETMQ-54
Commit: b29c318cdde225ef3a33a73e939e49e087766a28
Parents: 6729967
Author: yukon <yu...@apache.org>
Authored: Sat Jan 21 23:13:01 2017 +0800
Committer: yukon <yu...@apache.org>
Committed: Sat Jan 21 23:21:37 2017 +0800

----------------------------------------------------------------------
 .../processor/ClientManageProcessorTest.java    | 132 +++++++++++++++++++
 .../processor/PullMessageProcessorTest.java     |  38 +++++-
 .../processor/SendMessageProcessorTest.java     |  44 ++++++-
 3 files changed, 207 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/b29c318c/broker/src/test/java/org/apache/rocketmq/broker/processor/ClientManageProcessorTest.java
----------------------------------------------------------------------
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/processor/ClientManageProcessorTest.java b/broker/src/test/java/org/apache/rocketmq/broker/processor/ClientManageProcessorTest.java
new file mode 100644
index 0000000..147c732
--- /dev/null
+++ b/broker/src/test/java/org/apache/rocketmq/broker/processor/ClientManageProcessorTest.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.broker.processor;
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import java.util.HashMap;
+import java.util.UUID;
+import org.apache.rocketmq.broker.BrokerController;
+import org.apache.rocketmq.broker.client.ClientChannelInfo;
+import org.apache.rocketmq.broker.client.ConsumerGroupInfo;
+import org.apache.rocketmq.common.BrokerConfig;
+import org.apache.rocketmq.common.protocol.RequestCode;
+import org.apache.rocketmq.common.protocol.ResponseCode;
+import org.apache.rocketmq.common.protocol.header.UnregisterClientRequestHeader;
+import org.apache.rocketmq.common.protocol.heartbeat.ConsumerData;
+import org.apache.rocketmq.remoting.exception.RemotingCommandException;
+import org.apache.rocketmq.remoting.netty.NettyClientConfig;
+import org.apache.rocketmq.remoting.netty.NettyServerConfig;
+import org.apache.rocketmq.remoting.protocol.LanguageCode;
+import org.apache.rocketmq.remoting.protocol.RemotingCommand;
+import org.apache.rocketmq.store.config.MessageStoreConfig;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import static org.apache.rocketmq.broker.processor.PullMessageProcessorTest.createConsumerData;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ClientManageProcessorTest {
+    private ClientManageProcessor clientManageProcessor;
+    @Spy
+    private BrokerController brokerController = new BrokerController(new BrokerConfig(), new NettyServerConfig(), new NettyClientConfig(), new MessageStoreConfig());
+    @Mock
+    private ChannelHandlerContext handlerContext;
+    @Mock
+    private Channel channel;
+
+    private ClientChannelInfo clientChannelInfo;
+    private String clientId = UUID.randomUUID().toString();
+    private String group = "FooBarGroup";
+    private String topic = "FooBar";
+
+    @Before
+    public void init() {
+        when(handlerContext.channel()).thenReturn(channel);
+        clientManageProcessor = new ClientManageProcessor(brokerController);
+        clientChannelInfo = new ClientChannelInfo(channel, clientId, LanguageCode.JAVA, 100);
+        brokerController.getProducerManager().registerProducer(group, clientChannelInfo);
+
+        ConsumerData consumerData = createConsumerData(group, topic);
+        brokerController.getConsumerManager().registerConsumer(
+            consumerData.getGroupName(),
+            clientChannelInfo,
+            consumerData.getConsumeType(),
+            consumerData.getMessageModel(),
+            consumerData.getConsumeFromWhere(),
+            consumerData.getSubscriptionDataSet(),
+            false);
+    }
+
+    @Test
+    public void processRequest_UnRegisterProducer() throws Exception {
+        brokerController.getProducerManager().registerProducer(group, clientChannelInfo);
+        HashMap<Channel, ClientChannelInfo> channelMap = brokerController.getProducerManager().getGroupChannelTable().get(group);
+        assertThat(channelMap).isNotNull();
+        assertThat(channelMap.get(channel)).isEqualTo(clientChannelInfo);
+
+        RemotingCommand request = createUnRegisterProducerCommand();
+        RemotingCommand response = clientManageProcessor.processRequest(handlerContext, request);
+        assertThat(response).isNotNull();
+        assertThat(response.getCode()).isEqualTo(ResponseCode.SUCCESS);
+
+        channelMap = brokerController.getProducerManager().getGroupChannelTable().get(group);
+        assertThat(channelMap).isNull();
+    }
+
+    @Test
+    public void processRequest_UnRegisterConsumer() throws RemotingCommandException {
+        ConsumerGroupInfo consumerGroupInfo = brokerController.getConsumerManager().getConsumerGroupInfo(group);
+        assertThat(consumerGroupInfo).isNotNull();
+
+        RemotingCommand request = createUnRegisterConsumerCommand();
+        RemotingCommand response = clientManageProcessor.processRequest(handlerContext, request);
+        assertThat(response).isNotNull();
+        assertThat(response.getCode()).isEqualTo(ResponseCode.SUCCESS);
+
+        consumerGroupInfo = brokerController.getConsumerManager().getConsumerGroupInfo(group);
+        assertThat(consumerGroupInfo).isNull();
+    }
+
+    private RemotingCommand createUnRegisterProducerCommand() {
+        UnregisterClientRequestHeader requestHeader = new UnregisterClientRequestHeader();
+        requestHeader.setClientID(clientId);
+        requestHeader.setProducerGroup(group);
+        RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.UNREGISTER_CLIENT, requestHeader);
+        request.setLanguage(LanguageCode.JAVA);
+        request.setVersion(100);
+        request.makeCustomHeaderToNet();
+        return request;
+    }
+
+    private RemotingCommand createUnRegisterConsumerCommand() {
+        UnregisterClientRequestHeader requestHeader = new UnregisterClientRequestHeader();
+        requestHeader.setClientID(clientId);
+        requestHeader.setConsumerGroup(group);
+        RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.UNREGISTER_CLIENT, requestHeader);
+        request.setLanguage(LanguageCode.JAVA);
+        request.setVersion(100);
+        request.makeCustomHeaderToNet();
+        return request;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/b29c318c/broker/src/test/java/org/apache/rocketmq/broker/processor/PullMessageProcessorTest.java
----------------------------------------------------------------------
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/processor/PullMessageProcessorTest.java b/broker/src/test/java/org/apache/rocketmq/broker/processor/PullMessageProcessorTest.java
index 9c3ec67..d3d9812 100644
--- a/broker/src/test/java/org/apache/rocketmq/broker/processor/PullMessageProcessorTest.java
+++ b/broker/src/test/java/org/apache/rocketmq/broker/processor/PullMessageProcessorTest.java
@@ -19,10 +19,14 @@ package org.apache.rocketmq.broker.processor;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandlerContext;
 import java.net.InetSocketAddress;
+import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import org.apache.rocketmq.broker.BrokerController;
 import org.apache.rocketmq.broker.client.ClientChannelInfo;
+import org.apache.rocketmq.broker.mqtrace.ConsumeMessageContext;
+import org.apache.rocketmq.broker.mqtrace.ConsumeMessageHook;
 import org.apache.rocketmq.common.BrokerConfig;
 import org.apache.rocketmq.common.TopicConfig;
 import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
@@ -78,7 +82,7 @@ public class PullMessageProcessorTest {
         when(handlerContext.channel()).thenReturn(mockChannel);
         brokerController.getTopicConfigManager().getTopicConfigTable().put(topic, new TopicConfig());
         clientChannelInfo = new ClientChannelInfo(mockChannel);
-        ConsumerData consumerData = createConsumerData();
+        ConsumerData consumerData = createConsumerData(group, topic);
         brokerController.getConsumerManager().registerConsumer(
             consumerData.getGroupName(),
             clientChannelInfo,
@@ -131,6 +135,36 @@ public class PullMessageProcessorTest {
     }
 
     @Test
+    public void testProcessRequest_FoundWithHook() throws RemotingCommandException {
+        GetMessageResult getMessageResult = createGetMessageResult();
+        when(messageStore.getMessage(anyString(), anyString(), anyInt(), anyLong(), anyInt(), any(SubscriptionData.class))).thenReturn(getMessageResult);
+        List<ConsumeMessageHook> consumeMessageHookList = new ArrayList<>();
+        final ConsumeMessageContext[] messageContext = new ConsumeMessageContext[1];
+        ConsumeMessageHook consumeMessageHook = new ConsumeMessageHook() {
+            @Override public String hookName() {
+                return "TestHook";
+            }
+
+            @Override public void consumeMessageBefore(ConsumeMessageContext context) {
+                messageContext[0] = context;
+            }
+
+            @Override public void consumeMessageAfter(ConsumeMessageContext context) {
+            }
+        };
+        consumeMessageHookList.add(consumeMessageHook);
+        pullMessageProcessor.registerConsumeMessageHook(consumeMessageHookList);
+        final RemotingCommand request = createPullMsgCommand(RequestCode.PULL_MESSAGE);
+        RemotingCommand response = pullMessageProcessor.processRequest(handlerContext, request);
+        assertThat(response).isNotNull();
+        assertThat(response.getCode()).isEqualTo(ResponseCode.SUCCESS);
+        assertThat(messageContext[0]).isNotNull();
+        assertThat(messageContext[0].getConsumerGroup()).isEqualTo(group);
+        assertThat(messageContext[0].getTopic()).isEqualTo(topic);
+        assertThat(messageContext[0].getQueueId()).isEqualTo(1);
+    }
+
+    @Test
     public void testProcessRequest_MsgWasRemoving() throws RemotingCommandException {
         GetMessageResult getMessageResult = createGetMessageResult();
         getMessageResult.setStatus(GetMessageStatus.MESSAGE_WAS_REMOVING);
@@ -170,7 +204,7 @@ public class PullMessageProcessorTest {
         return request;
     }
 
-    private ConsumerData createConsumerData() {
+    static ConsumerData createConsumerData(String group, String topic) {
         ConsumerData consumerData = new ConsumerData();
         consumerData.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
         consumerData.setConsumeType(ConsumeType.CONSUME_PASSIVELY);

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/b29c318c/broker/src/test/java/org/apache/rocketmq/broker/processor/SendMessageProcessorTest.java
----------------------------------------------------------------------
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/processor/SendMessageProcessorTest.java b/broker/src/test/java/org/apache/rocketmq/broker/processor/SendMessageProcessorTest.java
index 2cf8d45..02490a0 100644
--- a/broker/src/test/java/org/apache/rocketmq/broker/processor/SendMessageProcessorTest.java
+++ b/broker/src/test/java/org/apache/rocketmq/broker/processor/SendMessageProcessorTest.java
@@ -19,7 +19,11 @@ package org.apache.rocketmq.broker.processor;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandlerContext;
 import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.List;
 import org.apache.rocketmq.broker.BrokerController;
+import org.apache.rocketmq.broker.mqtrace.SendMessageContext;
+import org.apache.rocketmq.broker.mqtrace.SendMessageHook;
 import org.apache.rocketmq.common.BrokerConfig;
 import org.apache.rocketmq.common.MixAll;
 import org.apache.rocketmq.common.message.MessageExt;
@@ -64,6 +68,9 @@ public class SendMessageProcessorTest {
     @Mock
     private MessageStore messageStore;
 
+    private String topic = "FooBar";
+    private String group = "FooBarGroup";
+
     @Before
     public void init() {
         brokerController.setMessageStore(messageStore);
@@ -72,6 +79,7 @@ public class SendMessageProcessorTest {
         when(mockChannel.remoteAddress()).thenReturn(new InetSocketAddress(1024));
         when(handlerContext.channel()).thenReturn(mockChannel);
         when(messageStore.lookMessageByOffset(anyLong())).thenReturn(new MessageExt());
+        sendMessageProcessor = new SendMessageProcessor(brokerController);
     }
 
     @Test
@@ -80,6 +88,33 @@ public class SendMessageProcessorTest {
         assertPutResult(ResponseCode.SUCCESS);
     }
 
+    @Test
+    public void testProcessRequest_WithHook() throws RemotingCommandException {
+        when(messageStore.putMessage(any(MessageExtBrokerInner.class))).thenReturn(new PutMessageResult(PutMessageStatus.PUT_OK, new AppendMessageResult(AppendMessageStatus.PUT_OK)));
+        List<SendMessageHook> sendMessageHookList = new ArrayList<>();
+        final SendMessageContext[] sendMessageContext = new SendMessageContext[1];
+        SendMessageHook sendMessageHook = new SendMessageHook() {
+            @Override public String hookName() {
+                return null;
+            }
+
+            @Override public void sendMessageBefore(SendMessageContext context) {
+                sendMessageContext[0] = context;
+            }
+
+            @Override public void sendMessageAfter(SendMessageContext context) {
+
+            }
+        };
+        sendMessageHookList.add(sendMessageHook);
+        sendMessageProcessor.registerSendMessageHook(sendMessageHookList);
+        assertPutResult(ResponseCode.SUCCESS);
+        System.out.println(sendMessageContext[0]);
+        assertThat(sendMessageContext[0]).isNotNull();
+        assertThat(sendMessageContext[0].getTopic()).isEqualTo(topic);
+        assertThat(sendMessageContext[0].getProducerGroup()).isEqualTo(group);
+    }
+
 
     @Test
     public void testProcessRequest_FlushTimeOut() throws RemotingCommandException {
@@ -142,8 +177,8 @@ public class SendMessageProcessorTest {
 
     private RemotingCommand createSendMsgCommand(int requestCode) {
         SendMessageRequestHeader requestHeader = new SendMessageRequestHeader();
-        requestHeader.setProducerGroup("FooBar_PID");
-        requestHeader.setTopic("FooBar");
+        requestHeader.setProducerGroup(group);
+        requestHeader.setTopic(topic);
         requestHeader.setDefaultTopic(MixAll.DEFAULT_TOPIC);
         requestHeader.setDefaultTopicQueueNums(3);
         requestHeader.setQueueId(1);
@@ -153,6 +188,7 @@ public class SendMessageProcessorTest {
         requestHeader.setReconsumeTimes(0);
 
         RemotingCommand request = RemotingCommand.createRequestCommand(requestCode, requestHeader);
+        request.setBody(new byte[] {'a'});
         request.makeCustomHeaderToNet();
         return request;
     }
@@ -162,7 +198,7 @@ public class SendMessageProcessorTest {
 
         requestHeader.setMaxReconsumeTimes(3);
         requestHeader.setDelayLevel(4);
-        requestHeader.setGroup("FooBar_PID");
+        requestHeader.setGroup(group);
         requestHeader.setOffset(123L);
 
         RemotingCommand request = RemotingCommand.createRequestCommand(requestCode, requestHeader);
@@ -179,8 +215,6 @@ public class SendMessageProcessorTest {
                 return null;
             }
         }).when(handlerContext).writeAndFlush(any(Object.class));
-
-        sendMessageProcessor = new SendMessageProcessor(brokerController);
         RemotingCommand responseToReturn = sendMessageProcessor.processRequest(handlerContext, request);
         if (responseToReturn != null) {
             assertThat(response[0]).isNull();


[19/31] incubator-rocketmq git commit: [ROCKETMQ-51] Add unit tests for PullMessageProcessor

Posted by st...@apache.org.
[ROCKETMQ-51] Add unit tests for PullMessageProcessor


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/f17da4f4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/f17da4f4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/f17da4f4

Branch: refs/heads/ROCKETMQ-54
Commit: f17da4f4f8c0d10deff9a51075f366ff3e141319
Parents: 264a056
Author: yukon <yu...@apache.org>
Authored: Sat Jan 21 21:12:51 2017 +0800
Committer: yukon <yu...@apache.org>
Committed: Sat Jan 21 23:21:27 2017 +0800

----------------------------------------------------------------------
 .../processor/PullMessageProcessorTest.java     | 197 +++++++++++++++++++
 .../processor/SendMessageProcessorTest.java     |  12 +-
 2 files changed, 199 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/f17da4f4/broker/src/test/java/org/apache/rocketmq/broker/processor/PullMessageProcessorTest.java
----------------------------------------------------------------------
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/processor/PullMessageProcessorTest.java b/broker/src/test/java/org/apache/rocketmq/broker/processor/PullMessageProcessorTest.java
new file mode 100644
index 0000000..9c3ec67
--- /dev/null
+++ b/broker/src/test/java/org/apache/rocketmq/broker/processor/PullMessageProcessorTest.java
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.broker.processor;
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import java.net.InetSocketAddress;
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.rocketmq.broker.BrokerController;
+import org.apache.rocketmq.broker.client.ClientChannelInfo;
+import org.apache.rocketmq.common.BrokerConfig;
+import org.apache.rocketmq.common.TopicConfig;
+import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
+import org.apache.rocketmq.common.protocol.RequestCode;
+import org.apache.rocketmq.common.protocol.ResponseCode;
+import org.apache.rocketmq.common.protocol.header.PullMessageRequestHeader;
+import org.apache.rocketmq.common.protocol.heartbeat.ConsumeType;
+import org.apache.rocketmq.common.protocol.heartbeat.ConsumerData;
+import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
+import org.apache.rocketmq.common.protocol.heartbeat.SubscriptionData;
+import org.apache.rocketmq.remoting.exception.RemotingCommandException;
+import org.apache.rocketmq.remoting.netty.NettyClientConfig;
+import org.apache.rocketmq.remoting.netty.NettyServerConfig;
+import org.apache.rocketmq.remoting.protocol.RemotingCommand;
+import org.apache.rocketmq.store.GetMessageResult;
+import org.apache.rocketmq.store.GetMessageStatus;
+import org.apache.rocketmq.store.MessageStore;
+import org.apache.rocketmq.store.config.MessageStoreConfig;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class PullMessageProcessorTest {
+    private PullMessageProcessor pullMessageProcessor;
+    @Spy
+    private BrokerController brokerController = new BrokerController(new BrokerConfig(), new NettyServerConfig(), new NettyClientConfig(), new MessageStoreConfig());
+    @Mock
+    private ChannelHandlerContext handlerContext;
+    @Mock
+    private MessageStore messageStore;
+    private ClientChannelInfo clientChannelInfo;
+    private String group = "FooBarGroup";
+    private String topic = "FooBar";
+
+    @Before
+    public void init() {
+        brokerController.setMessageStore(messageStore);
+        pullMessageProcessor = new PullMessageProcessor(brokerController);
+        Channel mockChannel = mock(Channel.class);
+        when(mockChannel.remoteAddress()).thenReturn(new InetSocketAddress(1024));
+        when(handlerContext.channel()).thenReturn(mockChannel);
+        brokerController.getTopicConfigManager().getTopicConfigTable().put(topic, new TopicConfig());
+        clientChannelInfo = new ClientChannelInfo(mockChannel);
+        ConsumerData consumerData = createConsumerData();
+        brokerController.getConsumerManager().registerConsumer(
+            consumerData.getGroupName(),
+            clientChannelInfo,
+            consumerData.getConsumeType(),
+            consumerData.getMessageModel(),
+            consumerData.getConsumeFromWhere(),
+            consumerData.getSubscriptionDataSet(),
+            false);
+    }
+
+    @Test
+    public void testProcessRequest_TopicNotExist() throws RemotingCommandException {
+        brokerController.getTopicConfigManager().getTopicConfigTable().remove(topic);
+        final RemotingCommand request = createPullMsgCommand(RequestCode.PULL_MESSAGE);
+        RemotingCommand response = pullMessageProcessor.processRequest(handlerContext, request);
+        assertThat(response).isNotNull();
+        assertThat(response.getCode()).isEqualTo(ResponseCode.TOPIC_NOT_EXIST);
+        assertThat(response.getRemark()).contains("topic[" + topic + "] not exist");
+    }
+
+    @Test
+    public void testProcessRequest_SubNotExist() throws RemotingCommandException {
+        brokerController.getConsumerManager().unregisterConsumer(group, clientChannelInfo, false);
+        final RemotingCommand request = createPullMsgCommand(RequestCode.PULL_MESSAGE);
+        RemotingCommand response = pullMessageProcessor.processRequest(handlerContext, request);
+        assertThat(response).isNotNull();
+        assertThat(response.getCode()).isEqualTo(ResponseCode.SUBSCRIPTION_NOT_EXIST);
+        assertThat(response.getRemark()).contains("consumer's group info not exist");
+    }
+
+    @Test
+    public void testProcessRequest_SubNotLatest() throws RemotingCommandException {
+        final RemotingCommand request = createPullMsgCommand(RequestCode.PULL_MESSAGE);
+        request.addExtField("subVersion", String.valueOf(101));
+        RemotingCommand response = pullMessageProcessor.processRequest(handlerContext, request);
+        assertThat(response).isNotNull();
+        assertThat(response.getCode()).isEqualTo(ResponseCode.SUBSCRIPTION_NOT_LATEST);
+        assertThat(response.getRemark()).contains("subscription not latest");
+    }
+
+    @Test
+    public void testProcessRequest_Found() throws RemotingCommandException {
+        GetMessageResult getMessageResult = createGetMessageResult();
+        when(messageStore.getMessage(anyString(), anyString(), anyInt(), anyLong(), anyInt(), any(SubscriptionData.class))).thenReturn(getMessageResult);
+
+        final RemotingCommand request = createPullMsgCommand(RequestCode.PULL_MESSAGE);
+        RemotingCommand response = pullMessageProcessor.processRequest(handlerContext, request);
+        assertThat(response).isNotNull();
+        assertThat(response.getCode()).isEqualTo(ResponseCode.SUCCESS);
+    }
+
+    @Test
+    public void testProcessRequest_MsgWasRemoving() throws RemotingCommandException {
+        GetMessageResult getMessageResult = createGetMessageResult();
+        getMessageResult.setStatus(GetMessageStatus.MESSAGE_WAS_REMOVING);
+        when(messageStore.getMessage(anyString(), anyString(), anyInt(), anyLong(), anyInt(), any(SubscriptionData.class))).thenReturn(getMessageResult);
+
+        final RemotingCommand request = createPullMsgCommand(RequestCode.PULL_MESSAGE);
+        RemotingCommand response = pullMessageProcessor.processRequest(handlerContext, request);
+        assertThat(response).isNotNull();
+        assertThat(response.getCode()).isEqualTo(ResponseCode.PULL_RETRY_IMMEDIATELY);
+    }
+
+    @Test
+    public void testProcessRequest_NoMsgInQueue() throws RemotingCommandException {
+        GetMessageResult getMessageResult = createGetMessageResult();
+        getMessageResult.setStatus(GetMessageStatus.NO_MESSAGE_IN_QUEUE);
+        when(messageStore.getMessage(anyString(), anyString(), anyInt(), anyLong(), anyInt(), any(SubscriptionData.class))).thenReturn(getMessageResult);
+
+        final RemotingCommand request = createPullMsgCommand(RequestCode.PULL_MESSAGE);
+        RemotingCommand response = pullMessageProcessor.processRequest(handlerContext, request);
+        assertThat(response).isNotNull();
+        assertThat(response.getCode()).isEqualTo(ResponseCode.PULL_OFFSET_MOVED);
+    }
+
+    private RemotingCommand createPullMsgCommand(int requestCode) {
+        PullMessageRequestHeader requestHeader = new PullMessageRequestHeader();
+        requestHeader.setCommitOffset(123L);
+        requestHeader.setConsumerGroup(group);
+        requestHeader.setMaxMsgNums(100);
+        requestHeader.setQueueId(1);
+        requestHeader.setQueueOffset(456L);
+        requestHeader.setSubscription("*");
+        requestHeader.setTopic(topic);
+        requestHeader.setSysFlag(0);
+        requestHeader.setSubVersion(100L);
+        RemotingCommand request = RemotingCommand.createRequestCommand(requestCode, requestHeader);
+        request.makeCustomHeaderToNet();
+        return request;
+    }
+
+    private ConsumerData createConsumerData() {
+        ConsumerData consumerData = new ConsumerData();
+        consumerData.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
+        consumerData.setConsumeType(ConsumeType.CONSUME_PASSIVELY);
+        consumerData.setGroupName(group);
+        consumerData.setMessageModel(MessageModel.CLUSTERING);
+        Set<SubscriptionData> subscriptionDataSet = new HashSet<>();
+        SubscriptionData subscriptionData = new SubscriptionData();
+        subscriptionData.setTopic(topic);
+        subscriptionData.setSubString("*");
+        subscriptionData.setSubVersion(100L);
+        subscriptionDataSet.add(subscriptionData);
+        consumerData.setSubscriptionDataSet(subscriptionDataSet);
+        return consumerData;
+    }
+
+    private GetMessageResult createGetMessageResult() {
+        GetMessageResult getMessageResult = new GetMessageResult();
+        getMessageResult.setStatus(GetMessageStatus.FOUND);
+        getMessageResult.setMinOffset(100);
+        getMessageResult.setMaxOffset(1024);
+        getMessageResult.setNextBeginOffset(516);
+        return getMessageResult;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/f17da4f4/broker/src/test/java/org/apache/rocketmq/broker/processor/SendMessageProcessorTest.java
----------------------------------------------------------------------
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/processor/SendMessageProcessorTest.java b/broker/src/test/java/org/apache/rocketmq/broker/processor/SendMessageProcessorTest.java
index d41d03a..2cf8d45 100644
--- a/broker/src/test/java/org/apache/rocketmq/broker/processor/SendMessageProcessorTest.java
+++ b/broker/src/test/java/org/apache/rocketmq/broker/processor/SendMessageProcessorTest.java
@@ -153,13 +153,7 @@ public class SendMessageProcessorTest {
         requestHeader.setReconsumeTimes(0);
 
         RemotingCommand request = RemotingCommand.createRequestCommand(requestCode, requestHeader);
-        request.addExtField("queueId", String.valueOf(requestHeader.getQueueId()));
-        request.addExtField("topic", String.valueOf(requestHeader.getTopic()));
-        request.addExtField("defaultTopicQueueNums", String.valueOf(requestHeader.getDefaultTopicQueueNums()));
-        request.addExtField("defaultTopic", requestHeader.getDefaultTopic());
-        request.addExtField("sysFlag", String.valueOf(requestHeader.getSysFlag()));
-        request.addExtField("flag", String.valueOf(requestHeader.getFlag()));
-        request.addExtField("bornTimestamp", String.valueOf(requestHeader.getBornTimestamp()));
+        request.makeCustomHeaderToNet();
         return request;
     }
 
@@ -172,9 +166,7 @@ public class SendMessageProcessorTest {
         requestHeader.setOffset(123L);
 
         RemotingCommand request = RemotingCommand.createRequestCommand(requestCode, requestHeader);
-        request.addExtField("group", requestHeader.getGroup());
-        request.addExtField("offset", String.valueOf(requestHeader.getOffset()));
-        request.addExtField("delayLevel", String.valueOf(requestHeader.getDelayLevel()));
+        request.makeCustomHeaderToNet();
         return request;
     }
 


[12/31] incubator-rocketmq git commit: [RocketMQ-58] Add integration test for RocketMQ, also thanks @fenglianghfl for this commit, closes apache/incubator-rocketmq#46

Posted by st...@apache.org.
[RocketMQ-58] Add integration test for RocketMQ, also thanks @fenglianghfl for this commit, closes apache/incubator-rocketmq#46


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/788771a8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/788771a8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/788771a8

Branch: refs/heads/ROCKETMQ-54
Commit: 788771a851512f1e588ebeb6952e61fe8d892804
Parents: 581039b
Author: dongeforever <zh...@yeah.net>
Authored: Fri Jan 20 11:36:31 2017 +0800
Committer: yukon <yu...@apache.org>
Committed: Fri Jan 20 11:36:31 2017 +0800

----------------------------------------------------------------------
 .travis.yml                                     |   1 +
 BUILDING                                        |   2 +-
 pom.xml                                         |  73 +++--
 test/pom.xml                                    |  52 ++++
 .../test/client/mq/MQAsyncProducer.java         |  85 ++++++
 .../test/client/rmq/RMQAsyncSendProducer.java   | 226 ++++++++++++++
 .../test/client/rmq/RMQBroadCastConsumer.java   |  37 +++
 .../test/client/rmq/RMQNormalConsumer.java      |  90 ++++++
 .../test/client/rmq/RMQNormalProducer.java      | 167 ++++++++++
 .../clientinterface/AbstractMQConsumer.java     | 112 +++++++
 .../clientinterface/AbstractMQProducer.java     | 151 +++++++++
 .../test/clientinterface/MQCollector.java       | 108 +++++++
 .../test/clientinterface/MQConsumer.java        |  26 ++
 .../test/clientinterface/MQProducer.java        |  30 ++
 .../rocketmq/test/factory/ConsumerFactory.java  |  45 +++
 .../rocketmq/test/factory/MQMessageFactory.java | 128 ++++++++
 .../rocketmq/test/factory/MessageFactory.java   |  62 ++++
 .../rocketmq/test/factory/ProducerFactory.java  |  37 +++
 .../test/factory/SendCallBackFactory.java       |  35 +++
 .../rocketmq/test/factory/TagMessage.java       | 108 +++++++
 .../test/listener/AbstractListener.java         | 104 +++++++
 .../rmq/concurrent/RMQDelayListner.java         |  61 ++++
 .../rmq/concurrent/RMQNormalListner.java        |  70 +++++
 .../listener/rmq/order/RMQOrderListener.java    |  85 ++++++
 .../rocketmq/test/message/MessageQueueMsg.java  |  62 ++++
 .../rocketmq/test/sendresult/SendResult.java    |  62 ++++
 .../apache/rocketmq/test/util/Condition.java    |  23 ++
 .../test/util/DuplicateMessageInfo.java         | 137 +++++++++
 .../org/apache/rocketmq/test/util/FileUtil.java | 108 +++++++
 .../org/apache/rocketmq/test/util/MQAdmin.java  | 164 ++++++++++
 .../rocketmq/test/util/MQRandomUtils.java       |  28 ++
 .../org/apache/rocketmq/test/util/MQWait.java   |  93 ++++++
 .../apache/rocketmq/test/util/RandomUtil.java   | 306 +++++++++++++++++++
 .../apache/rocketmq/test/util/RandomUtils.java  |  91 ++++++
 .../org/apache/rocketmq/test/util/TestUtil.java | 122 ++++++++
 .../apache/rocketmq/test/util/TestUtils.java    |  50 +++
 .../apache/rocketmq/test/util/VerifyUtils.java  | 146 +++++++++
 .../test/util/data/collect/DataCollector.java   |  45 +++
 .../util/data/collect/DataCollectorManager.java | 112 +++++++
 .../test/util/data/collect/DataFilter.java      |  22 ++
 .../collect/impl/ListDataCollectorImpl.java     |  95 ++++++
 .../data/collect/impl/MapDataCollectorImpl.java | 111 +++++++
 .../test/util/parallel/ParallelTask.java        |  43 +++
 .../util/parallel/ParallelTaskExecutor.java     |  67 ++++
 .../rocketmq/test/util/parallel/Task4Test.java  |  30 ++
 .../org/apache/rocketmq/test/base/BaseConf.java | 162 ++++++++++
 .../rocketmq/test/base/IntegrationTestBase.java | 143 +++++++++
 .../balance/NormalMsgDynamicBalanceIT.java      | 111 +++++++
 .../balance/NormalMsgStaticBalanceIT.java       | 109 +++++++
 .../consumer/broadcast/BaseBroadCastIT.java     |  56 ++++
 .../normal/BroadCastNormalMsgNotRecvIT.java     |  73 +++++
 .../normal/BroadCastNormalMsgRecvCrashIT.java   |  90 ++++++
 .../normal/BroadCastNormalMsgRecvFailIT.java    |  72 +++++
 .../BroadCastNormalMsgRecvStartLaterIT.java     |  88 ++++++
 .../BroadCastNormalMsgTwoDiffGroupRecvIT.java   |  78 +++++
 .../normal/NormalMsgTwoSameGroupConsumerIT.java |  78 +++++
 .../broadcast/order/OrderMsgBroadCastIT.java    |  75 +++++
 .../tag/BroadCastTwoConsumerFilterIT.java       |  78 +++++
 .../tag/BroadCastTwoConsumerSubDiffTagIT.java   |  75 +++++
 .../tag/BroadCastTwoConsumerSubTagIT.java       |  75 +++++
 .../consumer/cluster/DynamicAddAndCrashIT.java  | 103 +++++++
 .../consumer/cluster/DynamicAddConsumerIT.java  |  97 ++++++
 .../cluster/DynamicCrashConsumerIT.java         | 100 ++++++
 .../test/client/consumer/tag/MulTagSubIT.java   | 156 ++++++++++
 .../consumer/tag/TagMessageWith1ConsumerIT.java | 197 ++++++++++++
 .../tag/TagMessageWithMulConsumerIT.java        | 196 ++++++++++++
 .../tag/TagMessageWithSameGroupConsumerIT.java  | 115 +++++++
 .../consumer/topic/MulConsumerMulTopicIT.java   | 108 +++++++
 .../consumer/topic/OneConsumerMulTopicIT.java   | 104 +++++++
 .../producer/async/AsyncSendExceptionIT.java    | 150 +++++++++
 .../async/AsyncSendWithMessageQueueIT.java      |  85 ++++++
 .../AsyncSendWithMessageQueueSelectorIT.java    | 106 +++++++
 .../async/AsyncSendWithOnlySendCallBackIT.java  |  64 ++++
 .../producer/exception/msg/ChinaPropIT.java     |  74 +++++
 .../exception/msg/MessageExceptionIT.java       | 129 ++++++++
 .../exception/msg/MessageUserPropIT.java        |  94 ++++++
 .../ProducerGroupAndInstanceNameValidityIT.java |  69 +++++
 .../producer/oneway/OneWaySendExceptionIT.java  |  78 +++++
 .../client/producer/oneway/OneWaySendIT.java    |  64 ++++
 .../producer/oneway/OneWaySendWithMQIT.java     |  79 +++++
 .../oneway/OneWaySendWithSelectorIT.java        | 104 +++++++
 .../order/OrderMsgDynamicRebalanceIT.java       | 115 +++++++
 .../test/client/producer/order/OrderMsgIT.java  | 108 +++++++
 .../producer/order/OrderMsgRebalanceIT.java     | 133 ++++++++
 .../producer/order/OrderMsgWithTagIT.java       | 169 ++++++++++
 .../querymsg/QueryMsgByIdExceptionIT.java       |  81 +++++
 .../producer/querymsg/QueryMsgByIdIT.java       |  75 +++++
 .../producer/querymsg/QueryMsgByKeyIT.java      | 104 +++++++
 .../apache/rocketmq/test/delay/DelayConf.java   |  27 ++
 .../rocketmq/test/delay/NormalMsgDelayIT.java   | 116 +++++++
 .../test/smoke/NormalMessageSendAndRecvIT.java  |  62 ++++
 test/src/test/resources/log4j.xml               |  46 +++
 test/src/test/resources/logback-test.xml        |  33 ++
 93 files changed, 8492 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index dd57ba3..916cac5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -39,4 +39,5 @@ script:
   - travis_retry mvn -B package jacoco:report coveralls:report
 
 after_success:
+  - mvn clean install -Pit-test
   - mvn sonar:sonar

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/BUILDING
----------------------------------------------------------------------
diff --git a/BUILDING b/BUILDING
index a92cbd5..1498b3e 100644
--- a/BUILDING
+++ b/BUILDING
@@ -34,4 +34,4 @@ Then, import to eclipse by specifying the root directory of the project via:
 
 Execute the following command in order to build the tar.gz packages and install JAR to the local repository:
 
-$ mvn clean package install -Prelease-all assembly:assembly -U
\ No newline at end of file
+$ mvn clean install -Prelease-all assembly:assembly -U
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 8ec8170..8b8c468 100644
--- a/pom.xml
+++ b/pom.xml
@@ -160,9 +160,6 @@
         <!-- Compiler settings properties -->
         <maven.compiler.source>1.7</maven.compiler.source>
         <maven.compiler.target>1.7</maven.compiler.target>
-
-        <!-- Overwritten by the test configuration,otherwise the JaCoCo agent cannot be attached.Details see http://www.eclemma.org/jacoco/trunk/doc/prepare-agent-mojo.html -->
-        <argLine>-Xms512m -Xmx1024m</argLine>
         <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
         <!-- URL of the ASF SonarQube server -->
         <sonar.host.url>https://builds.apache.org/analysis</sonar.host.url>
@@ -181,6 +178,7 @@
         <module>example</module>
         <module>filtersrv</module>
         <module>srvutil</module>
+        <module>test</module>
     </modules>
 
     <build>
@@ -237,25 +235,6 @@
                 </configuration>
             </plugin>
             <plugin>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <version>2.19.1</version>
-                <configuration>
-                    <forkCount>1</forkCount>
-                    <reuseForks>true</reuseForks>
-                    <includes>
-                        <include>**/*Test.java</include>
-                    </includes>
-                </configuration>
-            </plugin>
-            <plugin>
-                <artifactId>maven-failsafe-plugin</artifactId>
-                <version>2.19.1</version>
-                <configuration>
-                    <forkCount>1</forkCount>
-                    <reuseForks>true</reuseForks>
-                </configuration>
-            </plugin>
-            <plugin>
                 <artifactId>maven-javadoc-plugin</artifactId>
                 <version>2.10.4</version>
                 <configuration>
@@ -310,6 +289,7 @@
                             <encoding>UTF-8</encoding>
                             <consoleOutput>true</consoleOutput>
                             <failsOnError>true</failsOnError>
+                            <includeTestSourceDirectory>false</includeTestSourceDirectory>
                         </configuration>
                         <goals>
                             <goal>check</goal>
@@ -352,12 +332,20 @@
                         <goals>
                             <goal>prepare-agent</goal>
                         </goals>
+                        <configuration>
+                            <destFile>${project.build.directory}/jacoco.exec</destFile>
+                        </configuration>
                     </execution>
                     <execution>
                         <id>default-prepare-agent-integration</id>
+                        <phase>pre-integration-test</phase>
                         <goals>
                             <goal>prepare-agent-integration</goal>
                         </goals>
+                        <configuration>
+                            <destFile>${project.build.directory}/jacoco-it.exec</destFile>
+                            <propertyName>failsafeArgLine</propertyName>
+                        </configuration>
                     </execution>
                     <execution>
                         <id>default-report</id>
@@ -374,6 +362,14 @@
                 </executions>
             </plugin>
             <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>2.19.1</version>
+                <configuration>
+                    <forkCount>1</forkCount>
+                    <reuseForks>true</reuseForks>
+                </configuration>
+            </plugin>
+            <plugin>
                 <groupId>org.codehaus.mojo</groupId>
                 <artifactId>findbugs-maven-plugin</artifactId>
                 <version>3.0.4</version>
@@ -475,6 +471,37 @@
                 </plugins>
             </build>
         </profile>
+        <profile>
+            <id>it-test</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-failsafe-plugin</artifactId>
+                        <version>2.19.1</version>
+                        <configuration>
+                            <forkCount>1</forkCount>
+                            <reuseForks>true</reuseForks>
+                            <argLine>@{failsafeArgLine}</argLine>
+                            <excludes>
+                                <exclude>**/NormalMsgDelayIT.java</exclude>
+                                <exclude>**/BroadCastNormalMsgNotRecvIT.java</exclude>
+                                <exclude>**/TagMessageWithSameGroupConsumerIT.java</exclude>
+                                <exclude>**/AsyncSendWithMessageQueueSelectorIT.java</exclude>
+                                <exclude>**/AsyncSendWithMessageQueueIT.java</exclude>
+                            </excludes>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <goals>
+                                    <goal>integration-test</goal>
+                                    <goal>verify</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
     </profiles>
 
     <dependencies>
@@ -537,7 +564,7 @@
             </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
-                <artifactId>rocketmq-qatest</artifactId>
+                <artifactId>rocketmq-test</artifactId>
                 <version>${project.version}</version>
             </dependency>
             <dependency>

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/pom.xml
----------------------------------------------------------------------
diff --git a/test/pom.xml b/test/pom.xml
new file mode 100644
index 0000000..09ec9d3
--- /dev/null
+++ b/test/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You 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.
+  -->
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>rocketmq-all</artifactId>
+        <groupId>org.apache.rocketmq</groupId>
+        <version>4.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>rocketmq-test</artifactId>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.17</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>rocketmq-broker</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>rocketmq-namesrv</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.truth</groupId>
+            <artifactId>truth</artifactId>
+            <version>0.30</version>
+        </dependency>
+    </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/client/mq/MQAsyncProducer.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/client/mq/MQAsyncProducer.java b/test/src/main/java/org/apache/rocketmq/test/client/mq/MQAsyncProducer.java
new file mode 100644
index 0000000..6b2357b
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/client/mq/MQAsyncProducer.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.mq;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.clientinterface.AbstractMQProducer;
+import org.apache.rocketmq.test.util.TestUtil;
+
+public class MQAsyncProducer {
+    private static Logger logger = Logger.getLogger(MQAsyncProducer.class);
+    private AbstractMQProducer producer = null;
+    private long msgNum;
+    private int intervalMills;
+    private Thread sendT;
+    private AtomicBoolean bPause = new AtomicBoolean(false);
+
+    public MQAsyncProducer(final AbstractMQProducer producer, final long msgNum,
+        final int intervalMills) {
+        this.producer = producer;
+        this.msgNum = msgNum;
+        this.intervalMills = intervalMills;
+
+        sendT = new Thread(new Runnable() {
+            public void run() {
+                for (int i = 0; i < msgNum; i++) {
+                    if (!bPause.get()) {
+                        producer.send();
+                        TestUtil.waitForMonment(intervalMills);
+                    } else {
+                        while (true) {
+                            if (bPause.get()) {
+                                TestUtil.waitForMonment(10);
+                            } else
+                                break;
+                        }
+                    }
+
+                }
+            }
+        });
+
+    }
+
+    public void start() {
+        sendT.start();
+    }
+
+    public void waitSendAll(int waitMills) {
+        long startTime = System.currentTimeMillis();
+        while ((producer.getAllMsgBody().size() + producer.getSendErrorMsg().size()) < msgNum) {
+            if (System.currentTimeMillis() - startTime < waitMills) {
+                TestUtil.waitForMonment(200);
+            } else {
+                logger.error(String.format("time elapse:%s, but the message sending has not finished",
+                    System.currentTimeMillis() - startTime));
+                break;
+            }
+        }
+    }
+
+    public void pauseProducer() {
+        bPause.set(true);
+    }
+
+    public void notifyProducer() {
+        bPause.set(false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/client/rmq/RMQAsyncSendProducer.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/client/rmq/RMQAsyncSendProducer.java b/test/src/main/java/org/apache/rocketmq/test/client/rmq/RMQAsyncSendProducer.java
new file mode 100644
index 0000000..4a2ce2b
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/client/rmq/RMQAsyncSendProducer.java
@@ -0,0 +1,226 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.rmq;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.client.producer.DefaultMQProducer;
+import org.apache.rocketmq.client.producer.MessageQueueSelector;
+import org.apache.rocketmq.client.producer.SendCallback;
+import org.apache.rocketmq.common.message.Message;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.test.clientinterface.AbstractMQProducer;
+import org.apache.rocketmq.test.sendresult.SendResult;
+import org.apache.rocketmq.test.util.RandomUtil;
+import org.apache.rocketmq.test.util.TestUtil;
+
+public class RMQAsyncSendProducer extends AbstractMQProducer {
+    private static Logger logger = Logger
+        .getLogger(RMQAsyncSendProducer.class);
+    private String nsAddr = null;
+    private DefaultMQProducer producer = null;
+    private SendCallback sendCallback = null;
+    private List<org.apache.rocketmq.client.producer.SendResult> successSendResult = new ArrayList<org.apache.rocketmq.client.producer.SendResult>();
+    private AtomicInteger exceptionMsgCount = new AtomicInteger(
+        0);
+    private int msgSize = 0;
+
+    public RMQAsyncSendProducer(String nsAddr, String topic) {
+        super(topic);
+        this.nsAddr = nsAddr;
+        sendCallback = new SendCallback() {
+            public void onSuccess(org.apache.rocketmq.client.producer.SendResult sendResult) {
+                successSendResult.add(sendResult);
+            }
+
+            public void onException(Throwable throwable) {
+                exceptionMsgCount.getAndIncrement();
+            }
+        };
+
+        create();
+        start();
+    }
+
+    public int getSuccessMsgCount() {
+        return successSendResult.size();
+    }
+
+    public List<org.apache.rocketmq.client.producer.SendResult> getSuccessSendResult() {
+        return successSendResult;
+    }
+
+    public int getExceptionMsgCount() {
+        return exceptionMsgCount.get();
+    }
+
+    private void create() {
+        producer = new DefaultMQProducer();
+        producer.setProducerGroup(RandomUtil.getStringByUUID());
+        producer.setInstanceName(RandomUtil.getStringByUUID());
+
+        if (nsAddr != null) {
+            producer.setNamesrvAddr(nsAddr);
+        }
+
+    }
+
+    private void start() {
+        try {
+            producer.start();
+        } catch (MQClientException e) {
+            logger.error("producer start failed!");
+            e.printStackTrace();
+        }
+    }
+
+    public SendResult send(Object msg, Object arg) {
+        return null;
+    }
+
+    public void shutdown() {
+        producer.shutdown();
+    }
+
+    public void asyncSend(Object msg) {
+        Message metaqMsg = (Message) msg;
+        try {
+            producer.send(metaqMsg, sendCallback);
+            msgBodys.addData(new String(metaqMsg.getBody()));
+            originMsgs.addData(msg);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void asyncSend(int msgSize) {
+        this.msgSize = msgSize;
+
+        for (int i = 0; i < msgSize; i++) {
+            Message msg = new Message(topic, RandomUtil.getStringByUUID().getBytes());
+            this.asyncSend(msg);
+        }
+    }
+
+    public void asyncSend(Object msg, MessageQueueSelector selector, Object arg) {
+        Message metaqMsg = (Message) msg;
+        try {
+            producer.send(metaqMsg, selector, arg, sendCallback);
+            msgBodys.addData(new String(metaqMsg.getBody()));
+            originMsgs.addData(msg);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void asyncSend(int msgSize, MessageQueueSelector selector) {
+        this.msgSize = msgSize;
+        for (int i = 0; i < msgSize; i++) {
+            Message msg = new Message(topic, RandomUtil.getStringByUUID().getBytes());
+            this.asyncSend(msg, selector, i);
+        }
+    }
+
+    public void asyncSend(Object msg, MessageQueue mq) {
+        Message metaqMsg = (Message) msg;
+        try {
+            producer.send(metaqMsg, mq, sendCallback);
+            msgBodys.addData(new String(metaqMsg.getBody()));
+            originMsgs.addData(msg);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void asyncSend(int msgSize, MessageQueue mq) {
+        this.msgSize = msgSize;
+        for (int i = 0; i < msgSize; i++) {
+            Message msg = new Message(topic, RandomUtil.getStringByUUID().getBytes());
+            this.asyncSend(msg, mq);
+        }
+    }
+
+    public void waitForResponse(int timeoutMills) {
+        long startTime = System.currentTimeMillis();
+        while (this.successSendResult.size() != this.msgSize) {
+            if (System.currentTimeMillis() - startTime < timeoutMills) {
+                TestUtil.waitForMonment(100);
+            } else {
+                logger.info("timeout but still not recv all response!");
+                break;
+            }
+        }
+    }
+
+    public void sendOneWay(Object msg) {
+        Message metaqMsg = (Message) msg;
+        try {
+            producer.sendOneway(metaqMsg);
+            msgBodys.addData(new String(metaqMsg.getBody()));
+            originMsgs.addData(msg);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void sendOneWay(int msgSize) {
+        for (int i = 0; i < msgSize; i++) {
+            Message msg = new Message(topic, RandomUtil.getStringByUUID().getBytes());
+            this.sendOneWay(msg);
+        }
+    }
+
+    public void sendOneWay(Object msg, MessageQueue mq) {
+        Message metaqMsg = (Message) msg;
+        try {
+            producer.sendOneway(metaqMsg, mq);
+            msgBodys.addData(new String(metaqMsg.getBody()));
+            originMsgs.addData(msg);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void sendOneWay(int msgSize, MessageQueue mq) {
+        for (int i = 0; i < msgSize; i++) {
+            Message msg = new Message(topic, RandomUtil.getStringByUUID().getBytes());
+            this.sendOneWay(msg, mq);
+        }
+    }
+
+    public void sendOneWay(Object msg, MessageQueueSelector selector, Object arg) {
+        Message metaqMsg = (Message) msg;
+        try {
+            producer.sendOneway(metaqMsg, selector, arg);
+            msgBodys.addData(new String(metaqMsg.getBody()));
+            originMsgs.addData(msg);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void sendOneWay(int msgSize, MessageQueueSelector selector) {
+        for (int i = 0; i < msgSize; i++) {
+            Message msg = new Message(topic, RandomUtil.getStringByUUID().getBytes());
+            this.sendOneWay(msg, selector, i);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/client/rmq/RMQBroadCastConsumer.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/client/rmq/RMQBroadCastConsumer.java b/test/src/main/java/org/apache/rocketmq/test/client/rmq/RMQBroadCastConsumer.java
new file mode 100644
index 0000000..8af49ea
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/client/rmq/RMQBroadCastConsumer.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.rmq;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
+import org.apache.rocketmq.test.listener.AbstractListener;
+
+public class RMQBroadCastConsumer extends RMQNormalConsumer {
+    private static Logger logger = Logger.getLogger(RMQBroadCastConsumer.class);
+
+    public RMQBroadCastConsumer(String nsAddr, String topic, String subExpression,
+        String consumerGroup, AbstractListener listner) {
+        super(nsAddr, topic, subExpression, consumerGroup, listner);
+    }
+
+    @Override
+    public void create() {
+        super.create();
+        consumer.setMessageModel(MessageModel.BROADCASTING);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/client/rmq/RMQNormalConsumer.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/client/rmq/RMQNormalConsumer.java b/test/src/main/java/org/apache/rocketmq/test/client/rmq/RMQNormalConsumer.java
new file mode 100644
index 0000000..3f185d3
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/client/rmq/RMQNormalConsumer.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.rmq;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.test.clientinterface.AbstractMQConsumer;
+import org.apache.rocketmq.test.listener.AbstractListener;
+import org.apache.rocketmq.test.util.RandomUtil;
+
+public class RMQNormalConsumer extends AbstractMQConsumer {
+    private static Logger logger = Logger.getLogger(RMQNormalConsumer.class);
+    protected DefaultMQPushConsumer consumer = null;
+
+    public RMQNormalConsumer(String nsAddr, String topic, String subExpression,
+        String consumerGroup, AbstractListener listner) {
+        super(nsAddr, topic, subExpression, consumerGroup, listner);
+    }
+
+    public AbstractListener getListner() {
+        return listner;
+    }
+
+    public void setListner(AbstractListener listner) {
+        this.listner = listner;
+    }
+
+    public void create() {
+        consumer = new DefaultMQPushConsumer(consumerGroup);
+        consumer.setInstanceName(RandomUtil.getStringByUUID());
+        consumer.setNamesrvAddr(nsAddr);
+        try {
+            consumer.subscribe(topic, subExpression);
+        } catch (MQClientException e) {
+            logger.error("consumer subscribe failed!");
+            e.printStackTrace();
+        }
+        consumer.setMessageListener(listner);
+    }
+
+    public void start() {
+        try {
+            consumer.start();
+            logger.info(String.format("consumer[%s] started!", consumer.getConsumerGroup()));
+        } catch (MQClientException e) {
+            logger.error("consumer start failed!");
+            e.printStackTrace();
+        }
+    }
+
+    public void subscribe(String topic, String subExpression) {
+        try {
+            consumer.subscribe(topic, subExpression);
+        } catch (MQClientException e) {
+            logger.error("consumer subscribe failed!");
+            e.printStackTrace();
+        }
+    }
+
+    public void shutdown() {
+        consumer.shutdown();
+    }
+
+    @Override
+    public void clearMsg() {
+        this.listner.clearMsg();
+    }
+
+    public void restart() {
+        consumer.shutdown();
+        create();
+        start();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/client/rmq/RMQNormalProducer.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/client/rmq/RMQNormalProducer.java b/test/src/main/java/org/apache/rocketmq/test/client/rmq/RMQNormalProducer.java
new file mode 100644
index 0000000..26b77fe
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/client/rmq/RMQNormalProducer.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.rmq;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.client.producer.DefaultMQProducer;
+import org.apache.rocketmq.client.producer.SendStatus;
+import org.apache.rocketmq.common.message.Message;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.test.clientinterface.AbstractMQProducer;
+import org.apache.rocketmq.test.sendresult.SendResult;
+
+public class RMQNormalProducer extends AbstractMQProducer {
+    private static Logger logger = Logger.getLogger(RMQNormalProducer.class);
+    private DefaultMQProducer producer = null;
+    private String nsAddr = null;
+
+    public RMQNormalProducer(String nsAddr, String topic) {
+        super(topic);
+        this.nsAddr = nsAddr;
+        create();
+        start();
+    }
+
+    public RMQNormalProducer(String nsAddr, String topic, String producerGroupName,
+        String producerInstanceName) {
+        super(topic);
+        this.producerGroupName = producerGroupName;
+        this.producerInstanceName = producerInstanceName;
+        this.nsAddr = nsAddr;
+
+        create();
+        start();
+    }
+
+    public DefaultMQProducer getProducer() {
+        return producer;
+    }
+
+    public void setProducer(DefaultMQProducer producer) {
+        this.producer = producer;
+    }
+
+    protected void create() {
+        producer = new DefaultMQProducer();
+        producer.setProducerGroup(getProducerGroupName());
+        producer.setInstanceName(getProducerInstanceName());
+
+        if (nsAddr != null) {
+            producer.setNamesrvAddr(nsAddr);
+        }
+
+    }
+
+    public void start() {
+        try {
+            producer.start();
+            super.setStartSuccess(true);
+        } catch (MQClientException e) {
+            super.setStartSuccess(false);
+            logger.error("producer start failed!");
+            e.printStackTrace();
+        }
+    }
+
+    public SendResult send(Object msg, Object orderKey) {
+        org.apache.rocketmq.client.producer.SendResult metaqResult = null;
+        Message metaqMsg = (Message) msg;
+        try {
+            long start = System.currentTimeMillis();
+            metaqResult = producer.send(metaqMsg);
+            this.msgRTs.addData(System.currentTimeMillis() - start);
+            if (isDebug) {
+                logger.info(metaqResult);
+            }
+            sendResult.setMsgId(metaqResult.getMsgId());
+            sendResult.setSendResult(metaqResult.getSendStatus().equals(SendStatus.SEND_OK));
+            sendResult.setBrokerIp(metaqResult.getMessageQueue().getBrokerName());
+            msgBodys.addData(new String(metaqMsg.getBody()));
+            originMsgs.addData(msg);
+            originMsgIndex.put(new String(metaqMsg.getBody()), metaqResult);
+        } catch (Exception e) {
+            if (isDebug) {
+                e.printStackTrace();
+            }
+
+            sendResult.setSendResult(false);
+            sendResult.setSendException(e);
+            errorMsgs.addData(msg);
+        }
+
+        return sendResult;
+    }
+
+    public void send(Map<MessageQueue, List<Object>> msgs) {
+        for (MessageQueue mq : msgs.keySet()) {
+            send(msgs.get(mq), mq);
+        }
+    }
+
+    public void send(List<Object> msgs, MessageQueue mq) {
+        for (Object msg : msgs) {
+            sendMQ((Message) msg, mq);
+        }
+    }
+
+    public SendResult sendMQ(Message msg, MessageQueue mq) {
+        org.apache.rocketmq.client.producer.SendResult metaqResult = null;
+        try {
+            long start = System.currentTimeMillis();
+            metaqResult = producer.send(msg, mq);
+            this.msgRTs.addData(System.currentTimeMillis() - start);
+            if (isDebug) {
+                logger.info(metaqResult);
+            }
+            sendResult.setMsgId(metaqResult.getMsgId());
+            sendResult.setSendResult(metaqResult.getSendStatus().equals(SendStatus.SEND_OK));
+            sendResult.setBrokerIp(metaqResult.getMessageQueue().getBrokerName());
+            msgBodys.addData(new String(msg.getBody()));
+            originMsgs.addData(msg);
+            originMsgIndex.put(new String(msg.getBody()), metaqResult);
+        } catch (Exception e) {
+            if (isDebug) {
+                e.printStackTrace();
+            }
+
+            sendResult.setSendResult(false);
+            sendResult.setSendException(e);
+            errorMsgs.addData(msg);
+        }
+
+        return sendResult;
+    }
+
+    public void shutdown() {
+        producer.shutdown();
+    }
+
+    @Override
+    public List<MessageQueue> getMessageQueue() {
+        List<MessageQueue> mqs = null;
+        try {
+            mqs = producer.fetchPublishMessageQueues(topic);
+        } catch (MQClientException e) {
+            e.printStackTrace();
+        }
+        return mqs;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/clientinterface/AbstractMQConsumer.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/clientinterface/AbstractMQConsumer.java b/test/src/main/java/org/apache/rocketmq/test/clientinterface/AbstractMQConsumer.java
new file mode 100644
index 0000000..a077129
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/clientinterface/AbstractMQConsumer.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.clientinterface;
+
+import org.apache.rocketmq.test.listener.AbstractListener;
+
+public abstract class AbstractMQConsumer implements MQConsumer {
+    protected AbstractListener listner = null;
+    protected String nsAddr = null;
+    protected String topic = null;
+    protected String subExpression = null;
+    protected String consumerGroup = null;
+    protected boolean isDebug = false;
+
+    public AbstractMQConsumer() {
+    }
+
+    public AbstractMQConsumer(String nsAddr, String topic, String subExpression,
+        String consumerGroup, AbstractListener listner) {
+        this.topic = topic;
+        this.subExpression = subExpression;
+        this.consumerGroup = consumerGroup;
+        this.listner = listner;
+        this.nsAddr = nsAddr;
+    }
+
+    public AbstractMQConsumer(String topic, String subExpression) {
+        this.topic = topic;
+        this.subExpression = subExpression;
+    }
+
+    public void setDebug() {
+        if (listner != null) {
+            listner.setDebug(true);
+        }
+
+        isDebug = true;
+    }
+
+    public void setDebug(boolean isDebug) {
+        if (listner != null) {
+            listner.setDebug(isDebug);
+        }
+
+        this.isDebug = isDebug;
+    }
+
+    public void setSubscription(String topic, String subExpression) {
+        this.topic = topic;
+        this.subExpression = subExpression;
+    }
+
+    public AbstractListener getListner() {
+        return listner;
+    }
+
+    public void setListner(AbstractListener listner) {
+        this.listner = listner;
+    }
+
+    public String getNsAddr() {
+        return nsAddr;
+    }
+
+    public void setNsAddr(String nsAddr) {
+        this.nsAddr = nsAddr;
+    }
+
+    public String getTopic() {
+        return topic;
+    }
+
+    public void setTopic(String topic) {
+        this.topic = topic;
+    }
+
+    public String getSubExpression() {
+        return subExpression;
+    }
+
+    public void setSubExpression(String subExpression) {
+        this.subExpression = subExpression;
+    }
+
+    public String getConsumerGroup() {
+        return consumerGroup;
+    }
+
+    public void setConsumerGroup(String consumerGroup) {
+        this.consumerGroup = consumerGroup;
+    }
+
+    public void clearMsg() {
+        listner.clearMsg();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/clientinterface/AbstractMQProducer.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/clientinterface/AbstractMQProducer.java b/test/src/main/java/org/apache/rocketmq/test/clientinterface/AbstractMQProducer.java
new file mode 100644
index 0000000..8201e63
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/clientinterface/AbstractMQProducer.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.clientinterface;
+
+import java.util.Date;
+import java.util.List;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.sendresult.SendResult;
+import org.apache.rocketmq.test.util.RandomUtil;
+import org.apache.rocketmq.test.util.TestUtil;
+
+public abstract class AbstractMQProducer extends MQCollector implements MQProducer {
+    protected String topic = null;
+
+    protected SendResult sendResult = new SendResult();
+    protected boolean startSuccess = false;
+    protected String producerGroupName = null;
+    protected String producerInstanceName = null;
+    protected boolean isDebug = false;
+
+    public AbstractMQProducer(String topic) {
+        super();
+        producerGroupName = RandomUtil.getStringByUUID();
+        producerInstanceName = RandomUtil.getStringByUUID();
+        this.topic = topic;
+
+    }
+
+    public AbstractMQProducer(String topic, String originMsgCollector, String msgBodyCollector) {
+        super(originMsgCollector, msgBodyCollector);
+        producerGroupName = RandomUtil.getStringByUUID();
+        producerInstanceName = RandomUtil.getStringByUUID();
+        this.topic = topic;
+    }
+
+    public boolean isStartSuccess() {
+        return startSuccess;
+    }
+
+    public void setStartSuccess(boolean startSuccess) {
+        this.startSuccess = startSuccess;
+    }
+
+    public String getProducerInstanceName() {
+        return producerInstanceName;
+    }
+
+    public void setProducerInstanceName(String producerInstanceName) {
+        this.producerInstanceName = producerInstanceName;
+    }
+
+    public String getProducerGroupName() {
+        return producerGroupName;
+    }
+
+    public void setProducerGroupName(String producerGroupName) {
+        this.producerGroupName = producerGroupName;
+    }
+
+    public void setDebug() {
+        isDebug = true;
+    }
+
+    public void setDebug(boolean isDebug) {
+        this.isDebug = isDebug;
+    }
+
+    public void setRun() {
+        isDebug = false;
+    }
+
+    public List<MessageQueue> getMessageQueue() {
+        return null;
+    }
+
+    private Object getMessage() {
+        return this.getMessageByTag(null);
+    }
+
+    public Object getMessageByTag(String tag) {
+        Object objMsg = null;
+        if (this instanceof RMQNormalProducer) {
+            org.apache.rocketmq.common.message.Message msg = new org.apache.rocketmq.common.message.Message(
+                topic, (RandomUtil.getStringByUUID() + "." + new Date()).getBytes());
+            objMsg = msg;
+            if (tag != null) {
+                msg.setTags(tag);
+            }
+        }
+        return objMsg;
+    }
+
+    public void send() {
+        Object msg = getMessage();
+        send(msg, null);
+    }
+
+    public void send(Object msg) {
+        send(msg, null);
+    }
+
+    public void send(long msgNum) {
+        for (int i = 0; i < msgNum; i++) {
+            this.send();
+        }
+    }
+
+    public void send(long msgNum, int intervalMills) {
+        for (int i = 0; i < msgNum; i++) {
+            this.send();
+            TestUtil.waitForMonment(intervalMills);
+        }
+    }
+
+    public void send(String tag, int msgSize) {
+        for (int i = 0; i < msgSize; i++) {
+            Object msg = getMessageByTag(tag);
+            send(msg, null);
+        }
+    }
+
+    public void send(String tag, int msgSize, int intervalMills) {
+        for (int i = 0; i < msgSize; i++) {
+            Object msg = getMessageByTag(tag);
+            send(msg, null);
+            TestUtil.waitForMonment(intervalMills);
+        }
+    }
+
+    public void send(List<Object> msgs) {
+        for (Object msg : msgs) {
+            this.send(msg, null);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/clientinterface/MQCollector.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/clientinterface/MQCollector.java b/test/src/main/java/org/apache/rocketmq/test/clientinterface/MQCollector.java
new file mode 100644
index 0000000..42d4b62
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/clientinterface/MQCollector.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.clientinterface;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import org.apache.rocketmq.test.util.RandomUtil;
+import org.apache.rocketmq.test.util.data.collect.DataCollector;
+import org.apache.rocketmq.test.util.data.collect.DataCollectorManager;
+
+public abstract class MQCollector {
+    protected DataCollector msgBodys = null;
+    protected DataCollector originMsgs = null;
+    protected DataCollector errorMsgs = null;
+    protected Map<Object, Object> originMsgIndex = null;
+    protected Collection<Object> msgBodysCopy = null;
+
+    protected DataCollector msgRTs = null;
+
+    public MQCollector() {
+        msgBodys = DataCollectorManager.getInstance()
+            .fetchListDataCollector(RandomUtil.getStringByUUID());
+        originMsgs = DataCollectorManager.getInstance()
+            .fetchListDataCollector(RandomUtil.getStringByUUID());
+        errorMsgs = DataCollectorManager.getInstance()
+            .fetchListDataCollector(RandomUtil.getStringByUUID());
+        originMsgIndex = new ConcurrentHashMap<Object, Object>();
+        msgRTs = DataCollectorManager.getInstance()
+            .fetchListDataCollector(RandomUtil.getStringByUUID());
+    }
+
+    public MQCollector(String originMsgCollector, String msgBodyCollector) {
+        originMsgs = DataCollectorManager.getInstance().fetchDataCollector(originMsgCollector);
+        msgBodys = DataCollectorManager.getInstance().fetchDataCollector(msgBodyCollector);
+    }
+
+    public Collection<Object> getAllMsgBody() {
+        return msgBodys.getAllData();
+    }
+
+    public Collection<Object> getAllOriginMsg() {
+        return originMsgs.getAllData();
+    }
+
+    public Object getFirstMsg() {
+        return ((List<Object>) originMsgs.getAllData()).get(0);
+    }
+
+    public Collection<Object> getAllUndupMsgBody() {
+        return msgBodys.getAllDataWithoutDuplicate();
+    }
+
+    public Collection<Object> getAllUndupOriginMsg() {
+        return originMsgs.getAllData();
+    }
+
+    public Collection<Object> getSendErrorMsg() {
+        return errorMsgs.getAllData();
+    }
+
+    public Collection<Object> getMsgRTs() {
+        return msgRTs.getAllData();
+    }
+
+    public Map<Object, Object> getOriginMsgIndex() {
+        return originMsgIndex;
+    }
+
+    public Collection<Object> getMsgBodysCopy() {
+        msgBodysCopy = new ArrayList<Object>();
+        msgBodysCopy.addAll(msgBodys.getAllData());
+        return msgBodysCopy;
+    }
+
+    public void clearMsg() {
+        msgBodys.resetData();
+        originMsgs.resetData();
+        errorMsgs.resetData();
+        originMsgIndex.clear();
+        msgRTs.resetData();
+    }
+
+    public void lockCollectors() {
+        msgBodys.lockIncrement();
+        originMsgs.lockIncrement();
+        errorMsgs.lockIncrement();
+        msgRTs.lockIncrement();
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/clientinterface/MQConsumer.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/clientinterface/MQConsumer.java b/test/src/main/java/org/apache/rocketmq/test/clientinterface/MQConsumer.java
new file mode 100644
index 0000000..aaa4b27
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/clientinterface/MQConsumer.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.clientinterface;
+
+public interface MQConsumer {
+    void create();
+
+    void start();
+
+    void shutdown();
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/clientinterface/MQProducer.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/clientinterface/MQProducer.java b/test/src/main/java/org/apache/rocketmq/test/clientinterface/MQProducer.java
new file mode 100644
index 0000000..795457d
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/clientinterface/MQProducer.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.clientinterface;
+
+import org.apache.rocketmq.test.sendresult.SendResult;
+
+public interface MQProducer {
+    SendResult send(Object msg, Object arg);
+
+    void setDebug();
+
+    void setRun();
+
+    void shutdown();
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/factory/ConsumerFactory.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/factory/ConsumerFactory.java b/test/src/main/java/org/apache/rocketmq/test/factory/ConsumerFactory.java
new file mode 100644
index 0000000..b5b3fdd
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/factory/ConsumerFactory.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.factory;
+
+import org.apache.rocketmq.test.client.rmq.RMQBroadCastConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.listener.AbstractListener;
+
+public class ConsumerFactory {
+
+    public static RMQNormalConsumer getRMQNormalConsumer(String nsAddr, String consumerGroup,
+        String topic, String subExpression,
+        AbstractListener listner) {
+        RMQNormalConsumer consumer = new RMQNormalConsumer(nsAddr, topic, subExpression,
+            consumerGroup, listner);
+        consumer.create();
+        consumer.start();
+        return consumer;
+    }
+
+    public static RMQBroadCastConsumer getRMQBroadCastConsumer(String nsAddr, String consumerGroup,
+        String topic, String subExpression,
+        AbstractListener listner) {
+        RMQBroadCastConsumer consumer = new RMQBroadCastConsumer(nsAddr, topic, subExpression,
+            consumerGroup, listner);
+        consumer.create();
+        consumer.start();
+        return consumer;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/factory/MQMessageFactory.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/factory/MQMessageFactory.java b/test/src/main/java/org/apache/rocketmq/test/factory/MQMessageFactory.java
new file mode 100644
index 0000000..f998fcb
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/factory/MQMessageFactory.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.factory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.rocketmq.common.message.Message;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.test.util.RandomUtil;
+
+public class MQMessageFactory {
+    private static Integer index = 0;
+
+    public static List<Object> getRMQMessage(String tag, String topic, int msgSize) {
+        List<Object> msgs = new ArrayList<Object>();
+        for (int i = 0; i < msgSize; i++) {
+            msgs.add(new Message(topic, tag, RandomUtil.getStringByUUID().getBytes()));
+        }
+
+        return msgs;
+    }
+
+    public static List<Object> getRMQMessage(List<String> tags, String topic, int msgSize) {
+        List<Object> msgs = new ArrayList<Object>();
+        for (int i = 0; i < msgSize; i++) {
+            for (String tag : tags) {
+                msgs.add(new Message(topic, tag, RandomUtil.getStringByUUID().getBytes()));
+            }
+        }
+        return msgs;
+    }
+
+    public static List<Object> getMessageBody(List<Object> msgs) {
+        List<Object> msgBodys = new ArrayList<Object>();
+        for (Object msg : msgs) {
+            msgBodys.add(new String(((Message) msg).getBody()));
+        }
+
+        return msgBodys;
+    }
+
+    public static Collection<Object> getMessage(Collection<Object>... msgs) {
+        Collection<Object> allMsgs = new ArrayList<Object>();
+        for (Collection<Object> msg : msgs) {
+            allMsgs.addAll(msg);
+        }
+        return allMsgs;
+    }
+
+    public static List<Object> getDelayMsg(String topic, int delayLevel, int msgSize) {
+        List<Object> msgs = new ArrayList<Object>();
+        for (int i = 0; i < msgSize; i++) {
+            Message msg = new Message(topic, RandomUtil.getStringByUUID().getBytes());
+            msg.setDelayTimeLevel(delayLevel);
+            msgs.add(msg);
+        }
+        return msgs;
+    }
+
+    public static List<Object> getKeyMsg(String topic, String key, int msgSize) {
+        List<Object> msgs = new ArrayList<Object>();
+        for (int i = 0; i < msgSize; i++) {
+            Message msg = new Message(topic, null, key, RandomUtil.getStringByUUID().getBytes());
+            msgs.add(msg);
+        }
+        return msgs;
+    }
+
+    public static Map<MessageQueue, List<Object>> getMsgByMQ(MessageQueue mq, int msgSize) {
+        List<MessageQueue> mqs = new ArrayList<MessageQueue>();
+        mqs.add(mq);
+        return getMsgByMQ(mqs, msgSize);
+    }
+
+    public static Map<MessageQueue, List<Object>> getMsgByMQ(List<MessageQueue> mqs, int msgSize) {
+        return getMsgByMQ(mqs, msgSize, null);
+    }
+
+    public static Map<MessageQueue, List<Object>> getMsgByMQ(List<MessageQueue> mqs, int msgSize,
+        String tag) {
+        Map<MessageQueue, List<Object>> msgs = new HashMap<MessageQueue, List<Object>>();
+        for (MessageQueue mq : mqs) {
+            msgs.put(mq, getMsg(mq.getTopic(), msgSize, tag));
+        }
+        return msgs;
+    }
+
+    public static List<Object> getMsg(String topic, int msgSize) {
+        return getMsg(topic, msgSize, null);
+    }
+
+    public static List<Object> getMsg(String topic, int msgSize, String tag) {
+        List<Object> msgs = new ArrayList<Object>();
+        while (msgSize > 0) {
+            Message msg = new Message(topic, (index++).toString().getBytes());
+            if (tag != null) {
+                msg.setTags(tag);
+            }
+            msgs.add(msg);
+            msgSize--;
+        }
+
+        return msgs;
+    }
+
+    public static List<MessageQueue> getMessageQueues(MessageQueue... mq) {
+        return Arrays.asList(mq);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/factory/MessageFactory.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/factory/MessageFactory.java b/test/src/main/java/org/apache/rocketmq/test/factory/MessageFactory.java
new file mode 100644
index 0000000..8f71700
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/factory/MessageFactory.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.factory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.apache.rocketmq.common.message.Message;
+import org.apache.rocketmq.test.util.RandomUtils;
+
+public class MessageFactory {
+
+    public static Message getRandomMessage(String topic) {
+        return getStringMessage(topic, RandomUtils.getStringByUUID());
+    }
+
+    public static Message getStringMessage(String topic, String body) {
+        Message msg = new Message(topic, body.getBytes());
+        return msg;
+    }
+
+    public static Message getStringMessageByTag(String topic, String tags, String body) {
+        Message msg = new Message(topic, tags, body.getBytes());
+        return msg;
+    }
+
+    public static Message getRandomMessageByTag(String topic, String tags) {
+        return getStringMessageByTag(topic, tags, RandomUtils.getStringByUUID());
+    }
+
+    public static Collection<Message> getRandomMessageList(String topic, int size) {
+        List<Message> msgList = new ArrayList<Message>();
+        for (int i = 0; i < size; i++) {
+            msgList.add(getRandomMessage(topic));
+        }
+        return msgList;
+    }
+
+    public static Collection<Message> getRandomMessageListByTag(String topic, String tags, int size) {
+        List<Message> msgList = new ArrayList<Message>();
+        for (int i = 0; i < size; i++) {
+            msgList.add(getRandomMessageByTag(topic, tags));
+        }
+        return msgList;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/factory/ProducerFactory.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/factory/ProducerFactory.java b/test/src/main/java/org/apache/rocketmq/test/factory/ProducerFactory.java
new file mode 100644
index 0000000..66767cc
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/factory/ProducerFactory.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.factory;
+
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.client.producer.DefaultMQProducer;
+import org.apache.rocketmq.test.util.RandomUtil;
+
+public class ProducerFactory {
+
+    public static DefaultMQProducer getRMQProducer(String ns) {
+        DefaultMQProducer producer = new DefaultMQProducer(RandomUtil.getStringByUUID());
+        producer.setNamesrvAddr(ns);
+        try {
+            producer.start();
+        } catch (MQClientException e) {
+            e.printStackTrace();
+        }
+
+        return producer;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/factory/SendCallBackFactory.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/factory/SendCallBackFactory.java b/test/src/main/java/org/apache/rocketmq/test/factory/SendCallBackFactory.java
new file mode 100644
index 0000000..64764c6
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/factory/SendCallBackFactory.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.factory;
+
+import org.apache.rocketmq.client.producer.SendCallback;
+import org.apache.rocketmq.client.producer.SendResult;
+
+public class SendCallBackFactory {
+    public static SendCallback getSendCallBack() {
+        return new SendCallback() {
+            @Override
+            public void onSuccess(SendResult sendResult) {
+            }
+
+            @Override
+            public void onException(Throwable throwable) {
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/factory/TagMessage.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/factory/TagMessage.java b/test/src/main/java/org/apache/rocketmq/test/factory/TagMessage.java
new file mode 100644
index 0000000..b7eb6a6
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/factory/TagMessage.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.factory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class TagMessage {
+    private List<String> tags = null;
+    private String topic = null;
+    private int msgSize = 0;
+    private Map<String, List<Object>> rmqMsgs = new HashMap<String, List<Object>>();
+
+    public TagMessage(String tag, String topic, int msgSize) {
+        String[] tags = {tag};
+        this.tags = Arrays.asList(tags);
+        this.topic = topic;
+        this.msgSize = msgSize;
+
+        init();
+    }
+
+    public TagMessage(String[] tags, String topic, int msgSize) {
+        this(Arrays.asList(tags), topic, msgSize);
+    }
+
+    public TagMessage(List<String> tags, String topic, int msgSize) {
+        this.tags = tags;
+        this.topic = topic;
+        this.msgSize = msgSize;
+
+        init();
+    }
+
+    private void init() {
+        for (String tag : tags) {
+            List<Object> tagMsgs = MQMessageFactory.getRMQMessage(tag, topic, msgSize);
+            rmqMsgs.put(tag, tagMsgs);
+        }
+    }
+
+    public List<Object> getMessageByTag(String tag) {
+        if (tags.contains(tag)) {
+            return rmqMsgs.get(tag);
+        } else {
+            return new ArrayList<Object>();
+        }
+    }
+
+    public List<Object> getMixedTagMessages() {
+        List<Object> mixedMsgs = new ArrayList<Object>();
+        for (int i = 0; i < msgSize; i++) {
+            for (String tag : tags) {
+                mixedMsgs.add(rmqMsgs.get(tag).get(i));
+            }
+        }
+
+        return mixedMsgs;
+    }
+
+    public List<Object> getMessageBodyByTag(String tag) {
+        if (tags.contains(tag)) {
+            return MQMessageFactory.getMessageBody(rmqMsgs.get(tag));
+        } else {
+            return new ArrayList<Object>();
+        }
+    }
+
+    public List<Object> getMessageBodyByTag(String... tag) {
+        return this.getMessageBodyByTag(Arrays.asList(tag));
+    }
+
+    public List<Object> getMessageBodyByTag(List<String> tags) {
+        List<Object> msgBodys = new ArrayList<Object>();
+        for (String tag : tags) {
+            msgBodys.addAll(MQMessageFactory.getMessageBody(rmqMsgs.get(tag)));
+        }
+        return msgBodys;
+    }
+
+    public List<Object> getAllTagMessageBody() {
+        List<Object> msgs = new ArrayList<Object>();
+        for (String tag : tags) {
+            msgs.addAll(MQMessageFactory.getMessageBody(rmqMsgs.get(tag)));
+        }
+
+        return msgs;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/listener/AbstractListener.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/listener/AbstractListener.java b/test/src/main/java/org/apache/rocketmq/test/listener/AbstractListener.java
new file mode 100644
index 0000000..974434a
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/listener/AbstractListener.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.listener;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.client.consumer.listener.MessageListener;
+import org.apache.rocketmq.test.clientinterface.MQCollector;
+import org.apache.rocketmq.test.util.TestUtil;
+
+public class AbstractListener extends MQCollector implements MessageListener {
+    public static Logger logger = Logger.getLogger(AbstractListener.class);
+    protected boolean isDebug = false;
+    protected String listnerName = null;
+    protected Collection<Object> allSendMsgs = null;
+
+    public AbstractListener() {
+        super();
+    }
+
+    public AbstractListener(String listnerName) {
+        super();
+        this.listnerName = listnerName;
+    }
+
+    public AbstractListener(String originMsgCollector, String msgBodyCollector) {
+        super(originMsgCollector, msgBodyCollector);
+    }
+
+    public boolean isDebug() {
+        return isDebug;
+    }
+
+    public void setDebug(boolean debug) {
+        isDebug = debug;
+    }
+
+    public void waitForMessageConsume(int timeoutMills) {
+        TestUtil.waitForMonment(timeoutMills);
+    }
+
+    public void stopRecv() {
+        super.lockCollectors();
+    }
+
+    public Collection<Object> waitForMessageConsume(Collection<Object> allSendMsgs,
+        int timeoutMills) {
+        this.allSendMsgs = allSendMsgs;
+        List<Object> sendMsgs = new ArrayList<Object>();
+        sendMsgs.addAll(allSendMsgs);
+
+        long curTime = System.currentTimeMillis();
+        while (!sendMsgs.isEmpty()) {
+            Iterator<Object> iter = sendMsgs.iterator();
+            while (iter.hasNext()) {
+                Object msg = iter.next();
+                if (msgBodys.getAllData().contains(msg)) {
+                    iter.remove();
+                }
+            }
+            if (sendMsgs.isEmpty()) {
+                break;
+            } else {
+                if (System.currentTimeMillis() - curTime >= timeoutMills) {
+                    logger.error(String.format("timeout but  [%s]  not recv all send messages!",
+                        listnerName));
+                    break;
+                } else {
+                    logger.info(String.format("[%s] still [%s] msg not recv!", listnerName,
+                        sendMsgs.size()));
+                    TestUtil.waitForMonment(500);
+                }
+            }
+        }
+
+        return sendMsgs;
+    }
+
+    public void waitForMessageConsume(Map<Object, Object> sendMsgIndex, int timeoutMills) {
+        Collection<Object> notRecvMsgs = waitForMessageConsume(sendMsgIndex.keySet(), timeoutMills);
+        for (Object object : notRecvMsgs) {
+            logger.info(sendMsgIndex.get(object));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/listener/rmq/concurrent/RMQDelayListner.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/listener/rmq/concurrent/RMQDelayListner.java b/test/src/main/java/org/apache/rocketmq/test/listener/rmq/concurrent/RMQDelayListner.java
new file mode 100644
index 0000000..b4a0870
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/listener/rmq/concurrent/RMQDelayListner.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.listener.rmq.concurrent;
+
+import java.util.Collection;
+import java.util.List;
+import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
+import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
+import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.apache.rocketmq.test.listener.AbstractListener;
+import org.apache.rocketmq.test.util.RandomUtil;
+import org.apache.rocketmq.test.util.data.collect.DataCollector;
+import org.apache.rocketmq.test.util.data.collect.DataCollectorManager;
+
+public class RMQDelayListner extends AbstractListener implements MessageListenerConcurrently {
+    private DataCollector msgDelayTimes = null;
+
+    public RMQDelayListner() {
+        msgDelayTimes = DataCollectorManager.getInstance()
+            .fetchDataCollector(RandomUtil.getStringByUUID());
+    }
+
+    public Collection<Object> getMsgDelayTimes() {
+        return msgDelayTimes.getAllData();
+    }
+
+    public void resetMsgDelayTimes() {
+        msgDelayTimes.resetData();
+    }
+
+    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
+        ConsumeConcurrentlyContext consumeConcurrentlyContext) {
+        long recvTime = System.currentTimeMillis();
+        for (MessageExt msg : msgs) {
+            if (isDebug) {
+                logger.info(listnerName + ":" + msg);
+            }
+
+            msgBodys.addData(new String(msg.getBody()));
+            originMsgs.addData(msg);
+            msgDelayTimes.addData(Math.abs(recvTime - msg.getBornTimestamp()));
+        }
+        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/listener/rmq/concurrent/RMQNormalListner.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/listener/rmq/concurrent/RMQNormalListner.java b/test/src/main/java/org/apache/rocketmq/test/listener/rmq/concurrent/RMQNormalListner.java
new file mode 100644
index 0000000..0d40881
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/listener/rmq/concurrent/RMQNormalListner.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.listener.rmq.concurrent;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
+import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
+import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.apache.rocketmq.test.listener.AbstractListener;
+
+public class RMQNormalListner extends AbstractListener implements MessageListenerConcurrently {
+    private ConsumeConcurrentlyStatus consumeStatus = ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
+    private AtomicInteger msgIndex = new AtomicInteger(0);
+
+    public RMQNormalListner() {
+        super();
+    }
+
+    public RMQNormalListner(String listnerName) {
+        super(listnerName);
+    }
+
+    public RMQNormalListner(ConsumeConcurrentlyStatus consumeStatus) {
+        super();
+        this.consumeStatus = consumeStatus;
+    }
+
+    public RMQNormalListner(String originMsgCollector, String msgBodyCollector) {
+        super(originMsgCollector, msgBodyCollector);
+    }
+
+    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
+        ConsumeConcurrentlyContext consumeConcurrentlyContext) {
+        for (MessageExt msg : msgs) {
+            msgIndex.getAndIncrement();
+            if (isDebug) {
+                if (listnerName != null && listnerName != "") {
+                    logger.info(listnerName + ":" + msgIndex.get() + ":"
+                        + String.format("msgid:%s broker:%s queueId:%s offset:%s",
+                        msg.getMsgId(), msg.getStoreHost(), msg.getQueueId(),
+                        msg.getQueueOffset()));
+                } else {
+                    logger.info(msg);
+                }
+            }
+
+            msgBodys.addData(new String(msg.getBody()));
+            originMsgs.addData(msg);
+            originMsgIndex.put(new String(msg.getBody()), msg);
+        }
+        return consumeStatus;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/main/java/org/apache/rocketmq/test/listener/rmq/order/RMQOrderListener.java
----------------------------------------------------------------------
diff --git a/test/src/main/java/org/apache/rocketmq/test/listener/rmq/order/RMQOrderListener.java b/test/src/main/java/org/apache/rocketmq/test/listener/rmq/order/RMQOrderListener.java
new file mode 100644
index 0000000..91883d8
--- /dev/null
+++ b/test/src/main/java/org/apache/rocketmq/test/listener/rmq/order/RMQOrderListener.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.listener.rmq.order;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
+import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
+import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.apache.rocketmq.test.listener.AbstractListener;
+
+public class RMQOrderListener extends AbstractListener implements MessageListenerOrderly {
+    private Map<String/* brokerId_brokerIp */, Collection<Object>> msgs = new ConcurrentHashMap<String, Collection<Object>>();
+
+    public RMQOrderListener() {
+        super();
+    }
+
+    public RMQOrderListener(String listnerName) {
+        super(listnerName);
+    }
+
+    public RMQOrderListener(String originMsgCollector, String msgBodyCollector) {
+        super(originMsgCollector, msgBodyCollector);
+    }
+
+    public Collection<Collection<Object>> getMsgs() {
+        return msgs.values();
+    }
+
+    private void putMsg(MessageExt msg) {
+        Collection<Object> msgQueue = null;
+        String key = getKey(msg.getQueueId(), msg.getStoreHost().toString());
+        if (!msgs.containsKey(key)) {
+            msgQueue = new ArrayList<Object>();
+        } else {
+            msgQueue = msgs.get(key);
+        }
+
+        msgQueue.add(new String(msg.getBody()));
+        msgs.put(key, msgQueue);
+    }
+
+    private String getKey(int queueId, String brokerIp) {
+        return String.format("%s_%s", queueId, brokerIp);
+    }
+
+    public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs,
+        ConsumeOrderlyContext context) {
+        for (MessageExt msg : msgs) {
+            if (isDebug) {
+                if (listnerName != null && listnerName != "") {
+                    logger.info(listnerName + ": " + msg);
+                } else {
+                    logger.info(msg);
+                }
+            }
+
+            putMsg(msg);
+            msgBodys.addData(new String(msg.getBody()));
+            originMsgs.addData(msg);
+        }
+
+        return ConsumeOrderlyStatus.SUCCESS;
+    }
+}



[28/31] incubator-rocketmq git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-rocketmq

Posted by st...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-rocketmq


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/b8ee0fb0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/b8ee0fb0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/b8ee0fb0

Branch: refs/heads/ROCKETMQ-54
Commit: b8ee0fb0319aa0be106f3ba8c5a3d8f6f9130990
Parents: c77444b 881aef5
Author: stevenschew <st...@apache.org>
Authored: Sun Jan 22 17:57:24 2017 +0800
Committer: stevenschew <st...@apache.org>
Committed: Sun Jan 22 17:57:24 2017 +0800

----------------------------------------------------------------------
 .../rocketmq/store/DefaultMessageStoreTest.java |  65 +++-----
 .../rocketmq/store/MappedFileQueueTest.java     | 162 ++++++-------------
 .../apache/rocketmq/store/MappedFileTest.java   |  56 ++-----
 .../rocketmq/store/StoreCheckpointTest.java     |  21 +--
 .../rocketmq/store/index/IndexFileTest.java     |  26 ++-
 .../store/schedule/ScheduleMessageTest.java     | 133 ---------------
 6 files changed, 91 insertions(+), 372 deletions(-)
----------------------------------------------------------------------



[21/31] incubator-rocketmq git commit: [ROCKETMQ-51] Add unit tests for ProducerManager

Posted by st...@apache.org.
[ROCKETMQ-51] Add unit tests for ProducerManager


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/67299677
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/67299677
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/67299677

Branch: refs/heads/ROCKETMQ-54
Commit: 672996774f2f65d85d5b55b5296f72ec29350783
Parents: f17da4f
Author: yukon <yu...@apache.org>
Authored: Sat Jan 21 22:01:18 2017 +0800
Committer: yukon <yu...@apache.org>
Committed: Sat Jan 21 23:21:37 2017 +0800

----------------------------------------------------------------------
 .../broker/client/ProducerManagerTest.java      | 90 ++++++++++++++++++++
 1 file changed, 90 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/67299677/broker/src/test/java/org/apache/rocketmq/broker/client/ProducerManagerTest.java
----------------------------------------------------------------------
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/client/ProducerManagerTest.java b/broker/src/test/java/org/apache/rocketmq/broker/client/ProducerManagerTest.java
new file mode 100644
index 0000000..08dbb9c
--- /dev/null
+++ b/broker/src/test/java/org/apache/rocketmq/broker/client/ProducerManagerTest.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.broker.client;
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ProducerManagerTest {
+    private ProducerManager producerManager;
+    private String group = "FooBar";
+    private ClientChannelInfo clientInfo;
+
+    @Mock
+    private Channel channel;
+
+    @Before
+    public void init() {
+        producerManager = new ProducerManager();
+        clientInfo = new ClientChannelInfo(channel);
+    }
+
+    @Test
+    public void scanNotActiveChannel() throws Exception {
+        producerManager.registerProducer(group, clientInfo);
+        assertThat(producerManager.getGroupChannelTable().get(group).get(channel)).isNotNull();
+
+        Field field = ProducerManager.class.getDeclaredField("CHANNEL_EXPIRED_TIMEOUT");
+        field.setAccessible(true);
+        long CHANNEL_EXPIRED_TIMEOUT = field.getLong(producerManager);
+        clientInfo.setLastUpdateTimestamp(System.currentTimeMillis() - CHANNEL_EXPIRED_TIMEOUT - 10);
+        when(channel.close()).thenReturn(mock(ChannelFuture.class));
+        producerManager.scanNotActiveChannel();
+        assertThat(producerManager.getGroupChannelTable().get(group).get(channel)).isNull();
+    }
+
+    @Test
+    public void doChannelCloseEvent() throws Exception {
+        producerManager.registerProducer(group, clientInfo);
+        assertThat(producerManager.getGroupChannelTable().get(group).get(channel)).isNotNull();
+        producerManager.doChannelCloseEvent("127.0.0.1", channel);
+        assertThat(producerManager.getGroupChannelTable().get(group).get(channel)).isNull();
+    }
+
+    @Test
+    public void testRegisterProducer() throws Exception {
+        producerManager.registerProducer(group, clientInfo);
+        HashMap<Channel, ClientChannelInfo> channelMap = producerManager.getGroupChannelTable().get(group);
+        assertThat(channelMap).isNotNull();
+        assertThat(channelMap.get(channel)).isEqualTo(clientInfo);
+    }
+
+    @Test
+    public void unregisterProducer() throws Exception {
+        producerManager.registerProducer(group, clientInfo);
+        HashMap<Channel, ClientChannelInfo> channelMap = producerManager.getGroupChannelTable().get(group);
+        assertThat(channelMap).isNotNull();
+        assertThat(channelMap.get(channel)).isEqualTo(clientInfo);
+
+        producerManager.unregisterProducer(group, clientInfo);
+        channelMap = producerManager.getGroupChannelTable().get(group);
+        assertThat(channelMap).isNull();
+    }
+
+}
\ No newline at end of file


[05/31] incubator-rocketmq git commit: [ROCKETMQ-43] Remove NoWhitespaceBefore module in rmq_checkstyle.xml, closes apache/incubator-rocketmq#36

Posted by st...@apache.org.
[ROCKETMQ-43] Remove NoWhitespaceBefore module in rmq_checkstyle.xml, closes apache/incubator-rocketmq#36


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/62d811e3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/62d811e3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/62d811e3

Branch: refs/heads/ROCKETMQ-54
Commit: 62d811e354c937327fcad0cb9399fcc5dc322b94
Parents: 69361f6
Author: wu-sheng <wu...@foxmail.com>
Authored: Fri Jan 20 11:05:24 2017 +0800
Committer: yukon <yu...@apache.org>
Committed: Fri Jan 20 11:05:24 2017 +0800

----------------------------------------------------------------------
 style/rmq_checkstyle.xml | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/62d811e3/style/rmq_checkstyle.xml
----------------------------------------------------------------------
diff --git a/style/rmq_checkstyle.xml b/style/rmq_checkstyle.xml
index 776b305..2872eb7 100644
--- a/style/rmq_checkstyle.xml
+++ b/style/rmq_checkstyle.xml
@@ -121,7 +121,6 @@
         <!--whitespace-->
         <module name="GenericWhitespace"/>
         <module name="NoWhitespaceBefore"/>
-        <module name="WhitespaceAfter"/>
         <module name="NoWhitespaceAfter"/>
         <module name="WhitespaceAround">
             <property name="allowEmptyConstructors" value="true"/>


[17/31] incubator-rocketmq git commit: Polish remoting module's UT

Posted by st...@apache.org.
Polish remoting module's UT


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/b997c974
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/b997c974
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/b997c974

Branch: refs/heads/ROCKETMQ-54
Commit: b997c9743e155df8d330bad54479ac320e722a36
Parents: 63de56c
Author: vongosling <vo...@apache.org>
Authored: Fri Jan 20 19:01:29 2017 +0800
Committer: vongosling <vo...@apache.org>
Committed: Fri Jan 20 19:01:29 2017 +0800

----------------------------------------------------------------------
 .../remoting/netty/NettyRemotingServer.java     |   4 +-
 .../remoting/protocol/RemotingCommand.java      |  12 -
 .../remoting/protocol/RocketMQSerializable.java |  11 +-
 .../remoting/protocol/protocol.sevialize.txt    |  21 --
 .../rocketmq/remoting/protocol/protocol.txt     |  21 --
 .../org/apache/rocketmq/remoting/MixTest.java   |  30 ---
 .../apache/rocketmq/remoting/NettyRPCTest.java  | 233 -------------------
 .../rocketmq/remoting/RemotingServerTest.java   | 158 +++++++++++++
 .../protocol/RocketMQSerializableTest.java      |  16 +-
 .../rocketmq/subclass/TestSubClassAuto.java     |  27 ---
 10 files changed, 173 insertions(+), 360 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/b997c974/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingServer.java
----------------------------------------------------------------------
diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingServer.java b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingServer.java
index d21894b..6a6df37 100644
--- a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingServer.java
+++ b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/NettyRemotingServer.java
@@ -131,8 +131,8 @@ public class NettyRemotingServer extends NettyRemotingAbstract implements Remoti
 
     @Override
     public void start() {
-        this.defaultEventExecutorGroup = new DefaultEventExecutorGroup(//
-            nettyServerConfig.getServerWorkerThreads(), //
+        this.defaultEventExecutorGroup = new DefaultEventExecutorGroup(
+            nettyServerConfig.getServerWorkerThreads(),
             new ThreadFactory() {
 
                 private AtomicInteger threadIndex = new AtomicInteger(0);

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/b997c974/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RemotingCommand.java
----------------------------------------------------------------------
diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RemotingCommand.java b/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RemotingCommand.java
index 99c13fb..4f017ad 100644
--- a/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RemotingCommand.java
+++ b/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RemotingCommand.java
@@ -69,9 +69,6 @@ public class RemotingCommand {
         }
     }
 
-    /**
-
-     */
     private int code;
     private LanguageCode language = LanguageCode.JAVA;
     private int version = 0;
@@ -80,13 +77,9 @@ public class RemotingCommand {
     private String remark;
     private HashMap<String, String> extFields;
     private transient CommandCustomHeader customHeader;
-    /**
 
-     */
     private SerializeType serializeTypeCurrentRPC = serializeTypeConfigInThisServer;
-    /**
 
-     */
     private transient byte[] body;
 
     protected RemotingCommand() {
@@ -117,9 +110,6 @@ public class RemotingCommand {
         return createResponseCommand(RemotingSysResponseCode.SYSTEM_ERROR, "not set any response code", classHeader);
     }
 
-    /**
-
-     */
     public static RemotingCommand createResponseCommand(int code, String remark, Class<? extends CommandCustomHeader> classHeader) {
         RemotingCommand cmd = new RemotingCommand();
         cmd.markResponseType();
@@ -411,9 +401,7 @@ public class RemotingCommand {
         return encodeHeader(this.body != null ? this.body.length : 0);
     }
 
-    /**
 
-     */
     public ByteBuffer encodeHeader(final int bodyLength) {
         // 1> header length size
         int length = 4;

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/b997c974/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RocketMQSerializable.java
----------------------------------------------------------------------
diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RocketMQSerializable.java b/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RocketMQSerializable.java
index 86dab46..66119e0 100644
--- a/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RocketMQSerializable.java
+++ b/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/RocketMQSerializable.java
@@ -42,10 +42,8 @@ public class RocketMQSerializable {
             extLen = extFieldsBytes.length;
         }
 
-        // ################### cal total length
         int totalLen = calTotalLen(remarkLen, extLen);
 
-        // ################### content
         ByteBuffer headerBuffer = ByteBuffer.allocate(totalLen);
         // int code(~32767)
         headerBuffer.putShort((short) cmd.getCode());
@@ -77,7 +75,6 @@ public class RocketMQSerializable {
 
     public static byte[] mapSerialize(HashMap<String, String> map) {
         // keySize+key+valSize+val
-        // keySize+key+valSize+val
         if (null == map || map.isEmpty())
             return null;
 
@@ -174,10 +171,10 @@ public class RocketMQSerializable {
         HashMap<String, String> map = new HashMap<String, String>();
         ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
 
-        short keySize = 0;
-        byte[] keyContent = null;
-        int valSize = 0;
-        byte[] valContent = null;
+        short keySize;
+        byte[] keyContent;
+        int valSize;
+        byte[] valContent;
         while (byteBuffer.hasRemaining()) {
             keySize = byteBuffer.getShort();
             keyContent = new byte[keySize];

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/b997c974/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/protocol.sevialize.txt
----------------------------------------------------------------------
diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/protocol.sevialize.txt b/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/protocol.sevialize.txt
deleted file mode 100644
index 3dc5ba5..0000000
--- a/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/protocol.sevialize.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-//
-// Remoting protocol V0.1 draft
-//
-// protocol <length> <header length> <header data> <body data>
-//            1        2               3             4
-//

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/b997c974/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/protocol.txt
----------------------------------------------------------------------
diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/protocol.txt b/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/protocol.txt
deleted file mode 100644
index 3dc5ba5..0000000
--- a/remoting/src/main/java/org/apache/rocketmq/remoting/protocol/protocol.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-
-//
-// Remoting protocol V0.1 draft
-//
-// protocol <length> <header length> <header data> <body data>
-//            1        2               3             4
-//

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/b997c974/remoting/src/test/java/org/apache/rocketmq/remoting/MixTest.java
----------------------------------------------------------------------
diff --git a/remoting/src/test/java/org/apache/rocketmq/remoting/MixTest.java b/remoting/src/test/java/org/apache/rocketmq/remoting/MixTest.java
deleted file mode 100644
index 3c4dcfa..0000000
--- a/remoting/src/test/java/org/apache/rocketmq/remoting/MixTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-/**
- * $Id: MixTest.java 1831 2013-05-16 01:39:51Z vintagewang@apache.org $
- */
-package org.apache.rocketmq.remoting;
-
-import org.junit.Test;
-
-public class MixTest {
-    @Test
-    public void test_extFieldsValue() {
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/b997c974/remoting/src/test/java/org/apache/rocketmq/remoting/NettyRPCTest.java
----------------------------------------------------------------------
diff --git a/remoting/src/test/java/org/apache/rocketmq/remoting/NettyRPCTest.java b/remoting/src/test/java/org/apache/rocketmq/remoting/NettyRPCTest.java
deleted file mode 100644
index f9c83b6..0000000
--- a/remoting/src/test/java/org/apache/rocketmq/remoting/NettyRPCTest.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-/**
- * $Id: NettyRPCTest.java 1831 2013-05-16 01:39:51Z vintagewang@apache.org $
- */
-package org.apache.rocketmq.remoting;
-
-import io.netty.channel.ChannelHandlerContext;
-import java.util.concurrent.Executors;
-import org.apache.rocketmq.remoting.annotation.CFNullable;
-import org.apache.rocketmq.remoting.exception.RemotingCommandException;
-import org.apache.rocketmq.remoting.exception.RemotingConnectException;
-import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
-import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
-import org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException;
-import org.apache.rocketmq.remoting.netty.NettyClientConfig;
-import org.apache.rocketmq.remoting.netty.NettyRemotingClient;
-import org.apache.rocketmq.remoting.netty.NettyRemotingServer;
-import org.apache.rocketmq.remoting.netty.NettyRequestProcessor;
-import org.apache.rocketmq.remoting.netty.NettyServerConfig;
-import org.apache.rocketmq.remoting.netty.ResponseFuture;
-import org.apache.rocketmq.remoting.protocol.RemotingCommand;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import static org.junit.Assert.assertTrue;
-
-public class NettyRPCTest {
-    private static RemotingServer remotingServer;
-    private static RemotingClient remotingClient;
-
-    public static RemotingServer createRemotingServer() throws InterruptedException {
-        NettyServerConfig config = new NettyServerConfig();
-        RemotingServer remotingServer = new NettyRemotingServer(config);
-        remotingServer.registerProcessor(0, new NettyRequestProcessor() {
-            private int i = 0;
-
-            @Override
-            public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) {
-                System.out.println("processRequest=" + request + " " + (i++));
-                request.setRemark("hello, I am respponse " + ctx.channel().remoteAddress());
-                return request;
-            }
-
-            @Override
-            public boolean rejectRequest() {
-                return false;
-            }
-        }, Executors.newCachedThreadPool());
-        remotingServer.start();
-        return remotingServer;
-    }
-
-    public static RemotingClient createRemotingClient() {
-        NettyClientConfig config = new NettyClientConfig();
-        RemotingClient client = new NettyRemotingClient(config);
-        client.start();
-        return client;
-    }
-
-    @BeforeClass
-    public static void initialize() throws InterruptedException {
-        remotingServer = createRemotingServer();
-        remotingClient = createRemotingClient();
-    }
-
-    @AfterClass
-    public static void destroy() {
-        remotingClient.shutdown();
-        remotingServer.shutdown();
-    }
-
-    @Test
-    public void test_RPC_Sync() throws InterruptedException, RemotingConnectException,
-        RemotingSendRequestException, RemotingTimeoutException {
-
-        for (int i = 0; i < 100; i++) {
-            TestRequestHeader requestHeader = new TestRequestHeader();
-            requestHeader.setCount(i);
-            requestHeader.setMessageTitle("HelloMessageTitle");
-            RemotingCommand request = RemotingCommand.createRequestCommand(0, requestHeader);
-            RemotingCommand response = remotingClient.invokeSync("localhost:8888", request, 1000 * 3000);
-            System.out.println("invoke result = " + response);
-            assertTrue(response != null);
-        }
-    }
-
-    @Test
-    public void test_RPC_Oneway() throws InterruptedException, RemotingConnectException,
-        RemotingTimeoutException, RemotingTooMuchRequestException, RemotingSendRequestException {
-
-        for (int i = 0; i < 100; i++) {
-            RemotingCommand request = RemotingCommand.createRequestCommand(0, null);
-            request.setRemark(String.valueOf(i));
-            remotingClient.invokeOneway("localhost:8888", request, 1000 * 3);
-        }
-    }
-
-    @Test
-    public void test_RPC_Async() throws InterruptedException, RemotingConnectException,
-        RemotingTimeoutException, RemotingTooMuchRequestException, RemotingSendRequestException {
-
-        for (int i = 0; i < 100; i++) {
-            RemotingCommand request = RemotingCommand.createRequestCommand(0, null);
-            request.setRemark(String.valueOf(i));
-            remotingClient.invokeAsync("localhost:8888", request, 1000 * 3, new InvokeCallback() {
-                @Override
-                public void operationComplete(ResponseFuture responseFuture) {
-                    System.out.println(responseFuture.getResponseCommand());
-                }
-            });
-        }
-    }
-
-    @Test
-    public void test_server_call_client() throws InterruptedException, RemotingConnectException,
-        RemotingSendRequestException, RemotingTimeoutException {
-
-        remotingServer.registerProcessor(0, new NettyRequestProcessor() {
-            @Override
-            public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) {
-                try {
-                    return remotingServer.invokeSync(ctx.channel(), request, 1000 * 10);
-                } catch (InterruptedException | RemotingSendRequestException | RemotingTimeoutException e) {
-                    e.printStackTrace();
-                }
-
-                return null;
-            }
-
-            @Override
-            public boolean rejectRequest() {
-                return false;
-            }
-        }, Executors.newCachedThreadPool());
-
-        remotingClient.registerProcessor(0, new NettyRequestProcessor() {
-            @Override
-            public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) {
-                System.out.println("client receive server request = " + request);
-                request.setRemark("client remark");
-                return request;
-            }
-
-            @Override
-            public boolean rejectRequest() {
-                return false;
-            }
-        }, Executors.newCachedThreadPool());
-
-        for (int i = 0; i < 3; i++) {
-            RemotingCommand request = RemotingCommand.createRequestCommand(0, null);
-            RemotingCommand response = remotingClient.invokeSync("localhost:8888", request, 1000 * 3);
-            System.out.println("invoke result = " + response);
-            assertTrue(response != null);
-        }
-    }
-
-}
-
-class TestRequestHeader implements CommandCustomHeader {
-    @CFNullable
-    private Integer count;
-
-    @CFNullable
-    private String messageTitle;
-
-    @Override
-    public void checkFields() throws RemotingCommandException {
-    }
-
-    public Integer getCount() {
-        return count;
-    }
-
-    public void setCount(Integer count) {
-        this.count = count;
-    }
-
-    public String getMessageTitle() {
-        return messageTitle;
-    }
-
-    public void setMessageTitle(String messageTitle) {
-        this.messageTitle = messageTitle;
-    }
-}
-
-class TestResponseHeader implements CommandCustomHeader {
-    @CFNullable
-    private Integer count;
-
-    @CFNullable
-    private String messageTitle;
-
-    public Integer getCount() {
-        return count;
-    }
-
-    public void setCount(Integer count) {
-        this.count = count;
-    }
-
-    @Override
-    public void checkFields() throws RemotingCommandException {
-
-    }
-
-    public String getMessageTitle() {
-        return messageTitle;
-    }
-
-    public void setMessageTitle(String messageTitle) {
-        this.messageTitle = messageTitle;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/b997c974/remoting/src/test/java/org/apache/rocketmq/remoting/RemotingServerTest.java
----------------------------------------------------------------------
diff --git a/remoting/src/test/java/org/apache/rocketmq/remoting/RemotingServerTest.java b/remoting/src/test/java/org/apache/rocketmq/remoting/RemotingServerTest.java
new file mode 100644
index 0000000..31c2647
--- /dev/null
+++ b/remoting/src/test/java/org/apache/rocketmq/remoting/RemotingServerTest.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.remoting;
+
+import io.netty.channel.ChannelHandlerContext;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import org.apache.rocketmq.remoting.annotation.CFNullable;
+import org.apache.rocketmq.remoting.exception.RemotingCommandException;
+import org.apache.rocketmq.remoting.exception.RemotingConnectException;
+import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
+import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
+import org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException;
+import org.apache.rocketmq.remoting.netty.NettyClientConfig;
+import org.apache.rocketmq.remoting.netty.NettyRemotingClient;
+import org.apache.rocketmq.remoting.netty.NettyRemotingServer;
+import org.apache.rocketmq.remoting.netty.NettyRequestProcessor;
+import org.apache.rocketmq.remoting.netty.NettyServerConfig;
+import org.apache.rocketmq.remoting.netty.ResponseFuture;
+import org.apache.rocketmq.remoting.protocol.LanguageCode;
+import org.apache.rocketmq.remoting.protocol.RemotingCommand;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertTrue;
+
+public class RemotingServerTest {
+    private static RemotingServer remotingServer;
+    private static RemotingClient remotingClient;
+
+    public static RemotingServer createRemotingServer() throws InterruptedException {
+        NettyServerConfig config = new NettyServerConfig();
+        RemotingServer remotingServer = new NettyRemotingServer(config);
+        remotingServer.registerProcessor(0, new NettyRequestProcessor() {
+            @Override
+            public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) {
+                request.setRemark("Hi " + ctx.channel().remoteAddress());
+                return request;
+            }
+
+            @Override
+            public boolean rejectRequest() {
+                return false;
+            }
+        }, Executors.newCachedThreadPool());
+
+        remotingServer.start();
+
+        return remotingServer;
+    }
+
+    public static RemotingClient createRemotingClient() {
+        NettyClientConfig config = new NettyClientConfig();
+        RemotingClient client = new NettyRemotingClient(config);
+        client.start();
+        return client;
+    }
+
+    @BeforeClass
+    public static void setup() throws InterruptedException {
+        remotingServer = createRemotingServer();
+        remotingClient = createRemotingClient();
+    }
+
+    @AfterClass
+    public static void destroy() {
+        remotingClient.shutdown();
+        remotingServer.shutdown();
+    }
+
+    @Test
+    public void testInvokeSync() throws InterruptedException, RemotingConnectException,
+        RemotingSendRequestException, RemotingTimeoutException {
+        RequestHeader requestHeader = new RequestHeader();
+        requestHeader.setCount(1);
+        requestHeader.setMessageTitle("Welcome");
+        RemotingCommand request = RemotingCommand.createRequestCommand(0, requestHeader);
+        RemotingCommand response = remotingClient.invokeSync("localhost:8888", request, 1000 * 3);
+        assertTrue(response != null);
+        assertThat(response.getLanguage()).isEqualTo(LanguageCode.JAVA);
+        assertThat(response.getExtFields()).hasSize(2);
+
+    }
+
+    @Test
+    public void testInvokeOneway() throws InterruptedException, RemotingConnectException,
+        RemotingTimeoutException, RemotingTooMuchRequestException, RemotingSendRequestException {
+
+        RemotingCommand request = RemotingCommand.createRequestCommand(0, null);
+        request.setRemark("messi");
+        remotingClient.invokeOneway("localhost:8888", request, 1000 * 3);
+    }
+
+    @Test
+    public void testInvokeAsync() throws InterruptedException, RemotingConnectException,
+        RemotingTimeoutException, RemotingTooMuchRequestException, RemotingSendRequestException {
+
+        final CountDownLatch latch = new CountDownLatch(1);
+        RemotingCommand request = RemotingCommand.createRequestCommand(0, null);
+        request.setRemark("messi");
+        remotingClient.invokeAsync("localhost:8888", request, 1000 * 3, new InvokeCallback() {
+            @Override
+            public void operationComplete(ResponseFuture responseFuture) {
+                latch.countDown();
+                assertTrue(responseFuture != null);
+                assertThat(responseFuture.getResponseCommand().getLanguage()).isEqualTo(LanguageCode.JAVA);
+                assertThat(responseFuture.getResponseCommand().getExtFields()).hasSize(2);
+            }
+        });
+        latch.await();
+    }
+}
+
+class RequestHeader implements CommandCustomHeader {
+    @CFNullable
+    private Integer count;
+
+    @CFNullable
+    private String messageTitle;
+
+    @Override
+    public void checkFields() throws RemotingCommandException {
+    }
+
+    public Integer getCount() {
+        return count;
+    }
+
+    public void setCount(Integer count) {
+        this.count = count;
+    }
+
+    public String getMessageTitle() {
+        return messageTitle;
+    }
+
+    public void setMessageTitle(String messageTitle) {
+        this.messageTitle = messageTitle;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/b997c974/remoting/src/test/java/org/apache/rocketmq/remoting/protocol/RocketMQSerializableTest.java
----------------------------------------------------------------------
diff --git a/remoting/src/test/java/org/apache/rocketmq/remoting/protocol/RocketMQSerializableTest.java b/remoting/src/test/java/org/apache/rocketmq/remoting/protocol/RocketMQSerializableTest.java
index e49a0d7..f1db54f 100644
--- a/remoting/src/test/java/org/apache/rocketmq/remoting/protocol/RocketMQSerializableTest.java
+++ b/remoting/src/test/java/org/apache/rocketmq/remoting/protocol/RocketMQSerializableTest.java
@@ -26,9 +26,9 @@ public class RocketMQSerializableTest {
     public void testRocketMQProtocolEncodeAndDecode_WithoutRemarkWithoutExtFields() {
         System.setProperty(RemotingCommand.REMOTING_VERSION_KEY, "2333");
 
-        int code = 103; //org.apache.rocketmq.common.protocol.RequestCode.REGISTER_BROKER
-        RemotingCommand cmd = RemotingCommand.createRequestCommand(code,
-            new SampleCommandCustomHeader());
+        //org.apache.rocketmq.common.protocol.RequestCode.REGISTER_BROKER
+        int code = 103;
+        RemotingCommand cmd = RemotingCommand.createRequestCommand(code, new SampleCommandCustomHeader());
         cmd.setSerializeTypeCurrentRPC(SerializeType.ROCKETMQ);
 
         byte[] result = RocketMQSerializable.rocketMQProtocolEncode(cmd);
@@ -57,7 +57,8 @@ public class RocketMQSerializableTest {
     public void testRocketMQProtocolEncodeAndDecode_WithRemarkWithoutExtFields() {
         System.setProperty(RemotingCommand.REMOTING_VERSION_KEY, "2333");
 
-        int code = 103; //org.apache.rocketmq.common.protocol.RequestCode.REGISTER_BROKER
+        //org.apache.rocketmq.common.protocol.RequestCode.REGISTER_BROKER
+        int code = 103;
         RemotingCommand cmd = RemotingCommand.createRequestCommand(code,
             new SampleCommandCustomHeader());
         cmd.setSerializeTypeCurrentRPC(SerializeType.ROCKETMQ);
@@ -94,7 +95,8 @@ public class RocketMQSerializableTest {
     public void testRocketMQProtocolEncodeAndDecode_WithoutRemarkWithExtFields() {
         System.setProperty(RemotingCommand.REMOTING_VERSION_KEY, "2333");
 
-        int code = 103; //org.apache.rocketmq.common.protocol.RequestCode.REGISTER_BROKER
+        //org.apache.rocketmq.common.protocol.RequestCode.REGISTER_BROKER
+        int code = 103;
         RemotingCommand cmd = RemotingCommand.createRequestCommand(code,
             new SampleCommandCustomHeader());
         cmd.setSerializeTypeCurrentRPC(SerializeType.ROCKETMQ);
@@ -129,7 +131,7 @@ public class RocketMQSerializableTest {
 
     @Test
     public void testIsBlank_NotBlank() {
-        assertThat(RocketMQSerializable.isBlank("aeiou")).isFalse();
+        assertThat(RocketMQSerializable.isBlank("bar")).isFalse();
         assertThat(RocketMQSerializable.isBlank("  A  ")).isFalse();
     }
 
@@ -146,6 +148,6 @@ public class RocketMQSerializableTest {
 
     private int parseToInt(byte[] array, int index) {
         return array[index] * 16777216 + array[++index] * 65536 + array[++index] * 256
-               + array[++index];
+            + array[++index];
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/b997c974/remoting/src/test/java/org/apache/rocketmq/subclass/TestSubClassAuto.java
----------------------------------------------------------------------
diff --git a/remoting/src/test/java/org/apache/rocketmq/subclass/TestSubClassAuto.java b/remoting/src/test/java/org/apache/rocketmq/subclass/TestSubClassAuto.java
deleted file mode 100644
index b60ad0c..0000000
--- a/remoting/src/test/java/org/apache/rocketmq/subclass/TestSubClassAuto.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.rocketmq.subclass;
-
-import org.junit.Test;
-
-public class TestSubClassAuto {
-    @Test
-    public void test_sub() {
-
-    }
-}


[22/31] incubator-rocketmq git commit: [ROCKETMQ-57] Add unit test for DefaultMQAdminExt

Posted by st...@apache.org.
[ROCKETMQ-57] Add unit test for DefaultMQAdminExt


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/d9c398f8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/d9c398f8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/d9c398f8

Branch: refs/heads/ROCKETMQ-54
Commit: d9c398f883552a52f2790554ff136f760eee6fe1
Parents: b29c318
Author: stevenschew <st...@apache.org>
Authored: Sun Jan 22 14:39:09 2017 +0800
Committer: yukon <yu...@apache.org>
Committed: Sun Jan 22 14:39:09 2017 +0800

----------------------------------------------------------------------
 .../tools/admin/DefaultMQAdminExtTest.java      | 49 +++++++++++++++-----
 1 file changed, 37 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/d9c398f8/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java
----------------------------------------------------------------------
diff --git a/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java b/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java
index da3bd8c..bb80eb4 100644
--- a/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java
+++ b/tools/src/test/java/org/apache/rocketmq/tools/admin/DefaultMQAdminExtTest.java
@@ -16,18 +16,45 @@
  */
 package org.apache.rocketmq.tools.admin;
 
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
 import org.apache.rocketmq.client.ClientConfig;
 import org.apache.rocketmq.client.exception.MQBrokerException;
 import org.apache.rocketmq.client.exception.MQClientException;
 import org.apache.rocketmq.client.impl.MQClientAPIImpl;
 import org.apache.rocketmq.client.impl.MQClientManager;
 import org.apache.rocketmq.client.impl.factory.MQClientInstance;
-import org.apache.rocketmq.common.admin.*;
+import org.apache.rocketmq.common.admin.ConsumeStats;
+import org.apache.rocketmq.common.admin.OffsetWrapper;
+import org.apache.rocketmq.common.admin.TopicOffset;
+import org.apache.rocketmq.common.admin.TopicStatsTable;
 import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
 import org.apache.rocketmq.common.message.MessageExt;
 import org.apache.rocketmq.common.message.MessageQueue;
 import org.apache.rocketmq.common.namesrv.NamesrvUtil;
-import org.apache.rocketmq.common.protocol.body.*;
+import org.apache.rocketmq.common.protocol.body.ClusterInfo;
+import org.apache.rocketmq.common.protocol.body.Connection;
+import org.apache.rocketmq.common.protocol.body.ConsumeStatsList;
+import org.apache.rocketmq.common.protocol.body.ConsumeStatus;
+import org.apache.rocketmq.common.protocol.body.ConsumerConnection;
+import org.apache.rocketmq.common.protocol.body.ConsumerRunningInfo;
+import org.apache.rocketmq.common.protocol.body.GroupList;
+import org.apache.rocketmq.common.protocol.body.KVTable;
+import org.apache.rocketmq.common.protocol.body.ProcessQueueInfo;
+import org.apache.rocketmq.common.protocol.body.ProducerConnection;
+import org.apache.rocketmq.common.protocol.body.QueueTimeSpan;
+import org.apache.rocketmq.common.protocol.body.SubscriptionGroupWrapper;
+import org.apache.rocketmq.common.protocol.body.TopicList;
 import org.apache.rocketmq.common.protocol.heartbeat.ConsumeType;
 import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
 import org.apache.rocketmq.common.protocol.heartbeat.SubscriptionData;
@@ -35,7 +62,11 @@ import org.apache.rocketmq.common.protocol.route.BrokerData;
 import org.apache.rocketmq.common.protocol.route.QueueData;
 import org.apache.rocketmq.common.protocol.route.TopicRouteData;
 import org.apache.rocketmq.common.subscription.SubscriptionGroupConfig;
-import org.apache.rocketmq.remoting.exception.*;
+import org.apache.rocketmq.remoting.exception.RemotingCommandException;
+import org.apache.rocketmq.remoting.exception.RemotingConnectException;
+import org.apache.rocketmq.remoting.exception.RemotingException;
+import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
+import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;
 import org.apache.rocketmq.tools.admin.api.MessageTrack;
 import org.junit.After;
 import org.junit.Before;
@@ -43,13 +74,10 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.junit.MockitoJUnitRunner;
 
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.Field;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -88,7 +116,6 @@ public class DefaultMQAdminExtTest {
         topicList.setTopicList(topicSet);
         when(mQClientAPIImpl.getTopicListFromNameServer(anyLong())).thenReturn(topicList);
 
-
         List<BrokerData> brokerDatas = new ArrayList<>();
         HashMap<Long, String> brokerAddrs = new HashMap<>();
         brokerAddrs.put(1234l, "127.0.0.1:10911");
@@ -210,7 +237,6 @@ public class DefaultMQAdminExtTest {
         assertThat(result.getProperty("serverSocketRcvBufSize")).isEqualTo("655350");
     }
 
-
     @Test
     public void testFetchAllTopicList() throws RemotingException, MQClientException, InterruptedException {
         TopicList topicList = defaultMQAdminExtImpl.fetchAllTopicList();
@@ -296,7 +322,6 @@ public class DefaultMQAdminExtTest {
         assertThat(kvs.getTable().get("cluster-name")).isEqualTo("default-cluster");
     }
 
-
     @Test
     public void testQueryTopicConsumeByWho() throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
         GroupList groupList = defaultMQAdminExtImpl.queryTopicConsumeByWho("UnitTest");


[27/31] incubator-rocketmq git commit: [ROCKETMQ-54] Add unit test for ClusterTestRequestProcessor

Posted by st...@apache.org.
[ROCKETMQ-54] Add unit test for ClusterTestRequestProcessor


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/c77444ba
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/c77444ba
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/c77444ba

Branch: refs/heads/ROCKETMQ-54
Commit: c77444ba2ee0cecf612dbc1eaea2e3e64e503c97
Parents: e9a87ea
Author: stevenschew <st...@apache.org>
Authored: Sun Jan 22 17:57:19 2017 +0800
Committer: stevenschew <st...@apache.org>
Committed: Sun Jan 22 17:57:19 2017 +0800

----------------------------------------------------------------------
 .../ClusterTestRequestProcessorTest.java        | 112 +++++++++++++++++++
 1 file changed, 112 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/c77444ba/namesrv/src/test/java/org/apache/rocketmq/namesrv/processor/ClusterTestRequestProcessorTest.java
----------------------------------------------------------------------
diff --git a/namesrv/src/test/java/org/apache/rocketmq/namesrv/processor/ClusterTestRequestProcessorTest.java b/namesrv/src/test/java/org/apache/rocketmq/namesrv/processor/ClusterTestRequestProcessorTest.java
new file mode 100644
index 0000000..5a98cd7
--- /dev/null
+++ b/namesrv/src/test/java/org/apache/rocketmq/namesrv/processor/ClusterTestRequestProcessorTest.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.namesrv.processor;
+
+import io.netty.channel.ChannelHandlerContext;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import org.apache.rocketmq.client.ClientConfig;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.client.impl.MQClientAPIImpl;
+import org.apache.rocketmq.client.impl.MQClientManager;
+import org.apache.rocketmq.client.impl.factory.MQClientInstance;
+import org.apache.rocketmq.common.namesrv.NamesrvConfig;
+import org.apache.rocketmq.common.protocol.ResponseCode;
+import org.apache.rocketmq.common.protocol.route.BrokerData;
+import org.apache.rocketmq.common.protocol.route.TopicRouteData;
+import org.apache.rocketmq.namesrv.NamesrvController;
+import org.apache.rocketmq.remoting.CommandCustomHeader;
+import org.apache.rocketmq.remoting.exception.RemotingCommandException;
+import org.apache.rocketmq.remoting.exception.RemotingException;
+import org.apache.rocketmq.remoting.netty.NettyServerConfig;
+import org.apache.rocketmq.remoting.protocol.RemotingCommand;
+import org.apache.rocketmq.tools.admin.DefaultMQAdminExt;
+import org.apache.rocketmq.tools.admin.DefaultMQAdminExtImpl;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ClusterTestRequestProcessorTest {
+    private ClusterTestRequestProcessor clusterTestProcessor;
+    private DefaultMQAdminExtImpl defaultMQAdminExtImpl;
+    private MQClientInstance mqClientInstance = MQClientManager.getInstance().getAndCreateMQClientInstance(new ClientConfig());
+    private MQClientAPIImpl mQClientAPIImpl;
+    private ChannelHandlerContext ctx;
+
+    @Before
+    public void init() throws NoSuchFieldException, IllegalAccessException, RemotingException, MQClientException, InterruptedException {
+        NamesrvController namesrvController = new NamesrvController(
+            new NamesrvConfig(),
+            new NettyServerConfig()
+        );
+
+        clusterTestProcessor = new ClusterTestRequestProcessor(namesrvController, "default-producer");
+        mQClientAPIImpl = mock(MQClientAPIImpl.class);
+        DefaultMQAdminExt defaultMQAdminExt = new DefaultMQAdminExt();
+        defaultMQAdminExtImpl = new DefaultMQAdminExtImpl(defaultMQAdminExt, 1000);
+        ctx = mock(ChannelHandlerContext.class);
+
+        Field field = DefaultMQAdminExtImpl.class.getDeclaredField("mqClientInstance");
+        field.setAccessible(true);
+        field.set(defaultMQAdminExtImpl, mqClientInstance);
+        field = MQClientInstance.class.getDeclaredField("mQClientAPIImpl");
+        field.setAccessible(true);
+        field.set(mqClientInstance, mQClientAPIImpl);
+        field = ClusterTestRequestProcessor.class.getDeclaredField("adminExt");
+        field.setAccessible(true);
+        field.set(clusterTestProcessor, defaultMQAdminExt);
+
+        TopicRouteData topicRouteData = new TopicRouteData();
+        List<BrokerData> brokerDatas = new ArrayList<>();
+        HashMap<Long, String> brokerAddrs = new HashMap<>();
+        brokerAddrs.put(1234l, "127.0.0.1:10911");
+        BrokerData brokerData = new BrokerData();
+        brokerData.setCluster("default-cluster");
+        brokerData.setBrokerName("default-broker");
+        brokerData.setBrokerAddrs(brokerAddrs);
+        brokerDatas.add(brokerData);
+        topicRouteData.setBrokerDatas(brokerDatas);
+        when(mQClientAPIImpl.getTopicRouteInfoFromNameServer(anyString(), anyLong())).thenReturn(topicRouteData);
+    }
+
+    @After
+    public void terminate() {
+    }
+
+    @Test
+    public void testGetRouteInfoByTopic() throws RemotingCommandException {
+        RemotingCommand request = RemotingCommand.createRequestCommand(12, new CommandCustomHeader() {
+            @Override public void checkFields() throws RemotingCommandException {
+
+            }
+        });
+        RemotingCommand remoting = clusterTestProcessor.getRouteInfoByTopic(ctx, request);
+        assertThat(remoting.getCode()).isEqualTo(ResponseCode.TOPIC_NOT_EXIST);
+        assertThat(remoting.getBody()).isNull();
+        assertThat(remoting.getRemark()).isNotNull();
+    }
+
+}
\ No newline at end of file


[14/31] incubator-rocketmq git commit: [ROCKETMQ-54] Add test cases for DefaultRequestProcessor in namesrv module, closes apache/incubator-rocketmq#45

Posted by st...@apache.org.
[ROCKETMQ-54] Add test cases for DefaultRequestProcessor in namesrv module, closes apache/incubator-rocketmq#45


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/b4108d2d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/b4108d2d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/b4108d2d

Branch: refs/heads/ROCKETMQ-54
Commit: b4108d2d9d3b1522e45ac5e7ea37106f2135bfa0
Parents: 0661ac8
Author: iskl <sh...@kailai.me>
Authored: Fri Jan 20 13:57:59 2017 +0800
Committer: yukon <yu...@apache.org>
Committed: Fri Jan 20 13:57:59 2017 +0800

----------------------------------------------------------------------
 .../processor/DefaultRequestProcessorTest.java  | 246 +++++++++++++++++++
 1 file changed, 246 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/b4108d2d/namesrv/src/test/java/org/apache/rocketmq/namesrv/processor/DefaultRequestProcessorTest.java
----------------------------------------------------------------------
diff --git a/namesrv/src/test/java/org/apache/rocketmq/namesrv/processor/DefaultRequestProcessorTest.java b/namesrv/src/test/java/org/apache/rocketmq/namesrv/processor/DefaultRequestProcessorTest.java
new file mode 100644
index 0000000..861e284
--- /dev/null
+++ b/namesrv/src/test/java/org/apache/rocketmq/namesrv/processor/DefaultRequestProcessorTest.java
@@ -0,0 +1,246 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.namesrv.processor;
+
+import io.netty.channel.ChannelHandlerContext;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.rocketmq.common.namesrv.NamesrvConfig;
+import org.apache.rocketmq.common.protocol.RequestCode;
+import org.apache.rocketmq.common.protocol.ResponseCode;
+import org.apache.rocketmq.common.protocol.header.namesrv.DeleteKVConfigRequestHeader;
+import org.apache.rocketmq.common.protocol.header.namesrv.GetKVConfigRequestHeader;
+import org.apache.rocketmq.common.protocol.header.namesrv.GetKVConfigResponseHeader;
+import org.apache.rocketmq.common.protocol.header.namesrv.PutKVConfigRequestHeader;
+import org.apache.rocketmq.common.protocol.header.namesrv.RegisterBrokerRequestHeader;
+import org.apache.rocketmq.common.protocol.route.BrokerData;
+import org.apache.rocketmq.namesrv.NamesrvController;
+import org.apache.rocketmq.namesrv.routeinfo.RouteInfoManager;
+import org.apache.rocketmq.remoting.exception.RemotingCommandException;
+import org.apache.rocketmq.remoting.netty.NettyServerConfig;
+import org.apache.rocketmq.remoting.protocol.RemotingCommand;
+import org.assertj.core.util.Maps;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.*;
+
+public class DefaultRequestProcessorTest {
+    /** Test Target */
+    private DefaultRequestProcessor defaultRequestProcessor;
+
+    private NamesrvController       namesrvController;
+
+    private NamesrvConfig           namesrvConfig;
+
+    private NettyServerConfig       nettyServerConfig;
+
+    private Logger                  logger;
+
+    @Before
+    public void init() throws Exception {
+        namesrvConfig = new NamesrvConfig();
+        nettyServerConfig = new NettyServerConfig();
+
+        namesrvController = new NamesrvController(namesrvConfig, nettyServerConfig);
+        defaultRequestProcessor = new DefaultRequestProcessor(namesrvController);
+
+        logger = mock(Logger.class);
+        when(logger.isInfoEnabled()).thenReturn(false);
+        setFinalStatic(DefaultRequestProcessor.class.getDeclaredField("log"), logger);
+    }
+
+    @Test
+    public void testProcessRequest_PutKVConfig() throws RemotingCommandException {
+        PutKVConfigRequestHeader header = new PutKVConfigRequestHeader();
+        RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.PUT_KV_CONFIG,
+            header);
+        request.addExtField("namespace", "namespace");
+        request.addExtField("key", "key");
+        request.addExtField("value", "value");
+
+        RemotingCommand response = defaultRequestProcessor.processRequest(null, request);
+
+        assertThat(response.getCode()).isEqualTo(ResponseCode.SUCCESS);
+        assertThat(response.getRemark()).isNull();
+
+        assertThat(namesrvController.getKvConfigManager().getKVConfig("namespace", "key"))
+            .isEqualTo("value");
+    }
+
+    @Test
+    public void testProcessRequest_GetKVConfigReturnNotNull() throws RemotingCommandException {
+        namesrvController.getKvConfigManager().putKVConfig("namespace", "key", "value");
+
+        GetKVConfigRequestHeader header = new GetKVConfigRequestHeader();
+        RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.GET_KV_CONFIG,
+            header);
+        request.addExtField("namespace", "namespace");
+        request.addExtField("key", "key");
+
+        RemotingCommand response = defaultRequestProcessor.processRequest(null, request);
+
+        assertThat(response.getCode()).isEqualTo(ResponseCode.SUCCESS);
+        assertThat(response.getRemark()).isNull();
+
+        GetKVConfigResponseHeader responseHeader = (GetKVConfigResponseHeader) response
+            .readCustomHeader();
+
+        assertThat(responseHeader.getValue()).isEqualTo("value");
+    }
+
+    @Test
+    public void testProcessRequest_GetKVConfigReturnNull() throws RemotingCommandException {
+        GetKVConfigRequestHeader header = new GetKVConfigRequestHeader();
+        RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.GET_KV_CONFIG,
+            header);
+        request.addExtField("namespace", "namespace");
+        request.addExtField("key", "key");
+
+        RemotingCommand response = defaultRequestProcessor.processRequest(null, request);
+
+        assertThat(response.getCode()).isEqualTo(ResponseCode.QUERY_NOT_FOUND);
+        assertThat(response.getRemark()).isEqualTo("No config item, Namespace: namespace Key: key");
+
+        GetKVConfigResponseHeader responseHeader = (GetKVConfigResponseHeader) response
+            .readCustomHeader();
+
+        assertThat(responseHeader.getValue()).isNull();
+    }
+
+    @Test
+    public void testProcessRequest_DeleteKVConfig() throws RemotingCommandException {
+        namesrvController.getKvConfigManager().putKVConfig("namespace", "key", "value");
+
+        DeleteKVConfigRequestHeader header = new DeleteKVConfigRequestHeader();
+        RemotingCommand request = RemotingCommand.createRequestCommand(RequestCode.DELETE_KV_CONFIG,
+            header);
+        request.addExtField("namespace", "namespace");
+        request.addExtField("key", "key");
+
+        RemotingCommand response = defaultRequestProcessor.processRequest(null, request);
+
+        assertThat(response.getCode()).isEqualTo(ResponseCode.SUCCESS);
+        assertThat(response.getRemark()).isNull();
+
+        assertThat(namesrvController.getKvConfigManager().getKVConfig("namespace", "key"))
+            .isNull();
+    }
+
+    @Test
+    public void testProcessRequest_RegisterBroker() throws RemotingCommandException,
+                                                    NoSuchFieldException, IllegalAccessException {
+        RemotingCommand request = genSampleRegisterCmd(true);
+
+        ChannelHandlerContext ctx = mock(ChannelHandlerContext.class);
+        when(ctx.channel()).thenReturn(null);
+
+        RemotingCommand response = defaultRequestProcessor.processRequest(ctx, request);
+
+        assertThat(response.getCode()).isEqualTo(ResponseCode.SUCCESS);
+        assertThat(response.getRemark()).isNull();
+
+        RouteInfoManager routes = namesrvController.getRouteInfoManager();
+        Field brokerAddrTable = RouteInfoManager.class.getDeclaredField("brokerAddrTable");
+        brokerAddrTable.setAccessible(true);
+
+        BrokerData broker = new BrokerData();
+        broker.setBrokerName("broker");
+        broker.setBrokerAddrs((HashMap) Maps.newHashMap(new Long(2333), "10.10.1.1"));
+
+        assertThat((Map) brokerAddrTable.get(routes))
+            .contains(new HashMap.SimpleEntry("broker", broker));
+    }
+
+    @Test
+    public void testProcessRequest_RegisterBrokerWithFilterServer() throws RemotingCommandException,
+        NoSuchFieldException, IllegalAccessException {
+        RemotingCommand request = genSampleRegisterCmd(true);
+
+        // version >= MQVersion.Version.V3_0_11.ordinal() to register with filter server
+        request.setVersion(100); 
+
+        ChannelHandlerContext ctx = mock(ChannelHandlerContext.class);
+        when(ctx.channel()).thenReturn(null);
+
+        RemotingCommand response = defaultRequestProcessor.processRequest(ctx, request);
+
+        assertThat(response.getCode()).isEqualTo(ResponseCode.SUCCESS);
+        assertThat(response.getRemark()).isNull();
+
+        RouteInfoManager routes = namesrvController.getRouteInfoManager();
+        Field brokerAddrTable = RouteInfoManager.class.getDeclaredField("brokerAddrTable");
+        brokerAddrTable.setAccessible(true);
+
+        BrokerData broker = new BrokerData();
+        broker.setBrokerName("broker");
+        broker.setBrokerAddrs((HashMap) Maps.newHashMap(new Long(2333), "10.10.1.1"));
+
+        assertThat((Map) brokerAddrTable.get(routes))
+            .contains(new HashMap.SimpleEntry("broker", broker));
+    }
+
+    @Test
+    public void testProcessRequest_UnregisterBroker() throws RemotingCommandException, NoSuchFieldException, IllegalAccessException {
+        ChannelHandlerContext ctx = mock(ChannelHandlerContext.class);
+        when(ctx.channel()).thenReturn(null);
+
+        //Register broker
+        RemotingCommand regRequest = genSampleRegisterCmd(true);
+        defaultRequestProcessor.processRequest(ctx, regRequest);
+
+        //Unregister broker
+        RemotingCommand unregRequest = genSampleRegisterCmd(false);
+        RemotingCommand unregResponse = defaultRequestProcessor.processRequest(ctx, unregRequest);
+
+        assertThat(unregResponse.getCode()).isEqualTo(ResponseCode.SUCCESS);
+        assertThat(unregResponse.getRemark()).isNull();
+
+        RouteInfoManager routes = namesrvController.getRouteInfoManager();
+        Field brokerAddrTable = RouteInfoManager.class.getDeclaredField("brokerAddrTable");
+        brokerAddrTable.setAccessible(true);
+
+        assertThat((Map)brokerAddrTable.get(routes)).isEmpty();
+    }
+
+
+    private static RemotingCommand genSampleRegisterCmd(boolean reg) {
+        RegisterBrokerRequestHeader header = new RegisterBrokerRequestHeader();
+        header.setBrokerName("broker");
+        RemotingCommand request = RemotingCommand.createRequestCommand(
+            reg ? RequestCode.REGISTER_BROKER : RequestCode.UNREGISTER_BROKER, header);
+        request.addExtField("brokerName", "broker");
+        request.addExtField("brokerAddr", "10.10.1.1");
+        request.addExtField("clusterName", "cluster");
+        request.addExtField("haServerAddr", "10.10.2.1");
+        request.addExtField("brokerId", "2333");
+        return request;
+    }
+
+
+    private static void setFinalStatic(Field field, Object newValue) throws Exception {
+        field.setAccessible(true);
+        Field modifiersField = Field.class.getDeclaredField("modifiers");
+        modifiersField.setAccessible(true);
+        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
+        field.set(null, newValue);
+    }
+}
\ No newline at end of file


[02/31] incubator-rocketmq git commit: Merge branch 'ROCKETMQ-57' of https://git-wip-us.apache.org/repos/asf/incubator-rocketmq into ROCKETMQ-57

Posted by st...@apache.org.
Merge branch 'ROCKETMQ-57' of https://git-wip-us.apache.org/repos/asf/incubator-rocketmq into ROCKETMQ-57


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/83993896
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/83993896
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/83993896

Branch: refs/heads/ROCKETMQ-54
Commit: 83993896e223f6ef08b0573f98f50177c5463b79
Parents: b29ff37 626315a
Author: stevenschew <st...@apache.org>
Authored: Thu Jan 19 11:41:37 2017 +0800
Committer: stevenschew <st...@apache.org>
Committed: Thu Jan 19 11:41:37 2017 +0800

----------------------------------------------------------------------

----------------------------------------------------------------------



[09/31] incubator-rocketmq git commit: [RocketMQ-58] Add integration test for RocketMQ, also thanks @fenglianghfl for this commit, closes apache/incubator-rocketmq#46

Posted by st...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/tag/TagMessageWithMulConsumerIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/tag/TagMessageWithMulConsumerIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/tag/TagMessageWithMulConsumerIT.java
new file mode 100644
index 0000000..995bf41
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/tag/TagMessageWithMulConsumerIT.java
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.tag;
+
+import java.util.Collection;
+import java.util.List;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.factory.MQMessageFactory;
+import org.apache.rocketmq.test.factory.TagMessage;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class TagMessageWithMulConsumerIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(TagMessageWith1ConsumerIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        String consumerId = initConsumerGroup();
+        logger.info(String.format("use topic: %s; consumerId: %s !", topic, consumerId));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testSendTwoTag() {
+        String tag1 = "jueyin1";
+        String tag2 = "jueyin2";
+        int msgSize = 10;
+        RMQNormalConsumer consumerTag1 = getConsumer(nsAddr, topic, tag1,
+            new RMQNormalListner());
+        RMQNormalConsumer consumerTag2 = getConsumer(nsAddr, topic, tag2,
+            new RMQNormalListner());
+
+        List<Object> tag1Msgs = MQMessageFactory.getRMQMessage(tag1, topic, msgSize);
+        producer.send(tag1Msgs);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+        List<Object> tag2Msgs = MQMessageFactory.getRMQMessage(tag2, topic, msgSize);
+        producer.send(tag2Msgs);
+        Assert.assertEquals("Not all are sent", msgSize * 2, producer.getAllUndupMsgBody().size());
+
+        consumerTag1.getListner().waitForMessageConsume(MQMessageFactory.getMessageBody(tag1Msgs),
+            consumeTime);
+        consumerTag2.getListner().waitForMessageConsume(MQMessageFactory.getMessageBody(tag2Msgs),
+            consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumerTag1.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(MQMessageFactory.getMessageBody(tag1Msgs));
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumerTag2.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(MQMessageFactory.getMessageBody(tag2Msgs));
+    }
+
+    @Test
+    public void testSendMessagesWithTwoTag() {
+        String tags[] = {"jueyin1", "jueyin2"};
+        int msgSize = 10;
+
+        TagMessage tagMessage = new TagMessage(tags, topic, msgSize);
+        RMQNormalConsumer consumerTag1 = getConsumer(nsAddr, topic, tags[0],
+            new RMQNormalListner());
+        RMQNormalConsumer consumerTag2 = getConsumer(nsAddr, topic, tags[1],
+            new RMQNormalListner());
+
+        List<Object> tagMsgs = tagMessage.getMixedTagMessages();
+        producer.send(tagMsgs);
+        Assert.assertEquals("Not all are sent", msgSize * tags.length,
+            producer.getAllUndupMsgBody().size());
+
+        consumerTag1.getListner().waitForMessageConsume(tagMessage.getMessageBodyByTag(tags[0]),
+            consumeTime);
+        consumerTag2.getListner().waitForMessageConsume(tagMessage.getMessageBodyByTag(tags[1]),
+            consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumerTag1.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(tagMessage.getMessageBodyByTag(tags[0]));
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumerTag2.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(tagMessage.getMessageBodyByTag(tags[1]));
+    }
+
+    @Test
+    public void testTwoConsumerOneMatchOneOtherMatchAll() {
+        String tags[] = {"jueyin1", "jueyin2"};
+        String sub1 = String.format("%s||%s", tags[0], tags[1]);
+        String sub2 = String.format("%s|| noExist", tags[0]);
+        int msgSize = 10;
+
+        TagMessage tagMessage = new TagMessage(tags, topic, msgSize);
+        RMQNormalConsumer consumerTag1 = getConsumer(nsAddr, topic, sub1,
+            new RMQNormalListner());
+        RMQNormalConsumer consumerTag2 = getConsumer(nsAddr, topic, sub2,
+            new RMQNormalListner());
+
+        List<Object> tagMsgs = tagMessage.getMixedTagMessages();
+        producer.send(tagMsgs);
+        Assert.assertEquals("Not all are sent", msgSize * tags.length,
+            producer.getAllUndupMsgBody().size());
+
+        consumerTag1.getListner().waitForMessageConsume(tagMessage.getMessageBodyByTag(tags),
+            consumeTime);
+        consumerTag2.getListner().waitForMessageConsume(tagMessage.getMessageBodyByTag(tags[0]),
+            consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumerTag1.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(tagMessage.getAllTagMessageBody());
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumerTag2.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(tagMessage.getMessageBodyByTag(tags[0]));
+    }
+
+    @Test
+    public void testSubKindsOf() {
+        String tags[] = {"jueyin1", "jueyin2"};
+        String sub1 = String.format("%s||%s", tags[0], tags[1]);
+        String sub2 = String.format("%s|| noExist", tags[0]);
+        String sub3 = tags[0];
+        String sub4 = "*";
+        int msgSize = 10;
+
+        RMQNormalConsumer consumerSubTwoMatchAll = getConsumer(nsAddr, topic, sub1,
+            new RMQNormalListner());
+        RMQNormalConsumer consumerSubTwoMachieOne = getConsumer(nsAddr, topic, sub2,
+            new RMQNormalListner());
+        RMQNormalConsumer consumerSubTag1 = getConsumer(nsAddr, topic, sub3,
+            new RMQNormalListner());
+        RMQNormalConsumer consumerSubAll = getConsumer(nsAddr, topic, sub4,
+            new RMQNormalListner());
+
+        producer.send(msgSize);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+        Collection<Object> msgsWithNoTag = producer.getMsgBodysCopy();
+
+        TagMessage tagMessage = new TagMessage(tags, topic, msgSize);
+        List<Object> tagMsgs = tagMessage.getMixedTagMessages();
+        producer.send(tagMsgs);
+        Assert.assertEquals("Not all are sent", msgSize * 3, producer.getAllUndupMsgBody().size());
+
+        consumerSubTwoMatchAll.getListner()
+            .waitForMessageConsume(tagMessage.getMessageBodyByTag(tags), consumeTime);
+        consumerSubTwoMachieOne.getListner()
+            .waitForMessageConsume(tagMessage.getMessageBodyByTag(tags[0]), consumeTime);
+        consumerSubTag1.getListner().waitForMessageConsume(tagMessage.getMessageBodyByTag(tags[0]),
+            consumeTime);
+        consumerSubAll.getListner().waitForMessageConsume(
+            MQMessageFactory.getMessage(msgsWithNoTag, tagMessage.getAllTagMessageBody()),
+            consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumerSubTwoMatchAll.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(tagMessage.getAllTagMessageBody());
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumerSubTwoMachieOne.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(tagMessage.getMessageBodyByTag(tags[0]));
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumerSubTag1.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(tagMessage.getMessageBodyByTag(tags[0]));
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumerSubAll.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(MQMessageFactory.getMessage(msgsWithNoTag,
+                tagMessage.getAllTagMessageBody()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/tag/TagMessageWithSameGroupConsumerIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/tag/TagMessageWithSameGroupConsumerIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/tag/TagMessageWithSameGroupConsumerIT.java
new file mode 100644
index 0000000..03e81eb
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/tag/TagMessageWithSameGroupConsumerIT.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.tag;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.RandomUtils;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class TagMessageWithSameGroupConsumerIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(TagMessageWith1ConsumerIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s !", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testTwoConsumerWithSameGroup() {
+        String tag = "jueyin";
+        int msgSize = 20;
+        String originMsgDCName = RandomUtils.getStringByUUID();
+        String msgBodyDCName = RandomUtils.getStringByUUID();
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic, tag,
+            new RMQNormalListner(originMsgDCName, msgBodyDCName));
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), tag,
+            new RMQNormalListner(originMsgDCName, msgBodyDCName));
+        producer.send(tag, msgSize);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+        consumer1.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer1.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+
+    @Test
+    public void testConsumerStartWithInterval() {
+        String tag = "jueyin";
+        int msgSize = 100;
+        String originMsgDCName = RandomUtils.getStringByUUID();
+        String msgBodyDCName = RandomUtils.getStringByUUID();
+
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic, tag,
+            new RMQNormalListner(originMsgDCName, msgBodyDCName));
+        producer.send(tag, msgSize, 100);
+        TestUtils.waitForMonment(5);
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), tag,
+            new RMQNormalListner(originMsgDCName, msgBodyDCName));
+        TestUtils.waitForMonment(5);
+
+        consumer1.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer1.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+
+    @Test
+    public void testConsumerStartTwoAndCrashOnsAfterWhile() {
+        String tag = "jueyin";
+        int msgSize = 100;
+        String originMsgDCName = RandomUtils.getStringByUUID();
+        String msgBodyDCName = RandomUtils.getStringByUUID();
+
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic, tag,
+            new RMQNormalListner(originMsgDCName, msgBodyDCName));
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), tag,
+            new RMQNormalListner(originMsgDCName, msgBodyDCName));
+
+        producer.send(tag, msgSize, 100);
+        TestUtils.waitForMonment(5);
+        consumer2.shutdown();
+        mqClients.remove(1);
+        TestUtils.waitForMonment(5);
+
+        consumer1.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer1.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/topic/MulConsumerMulTopicIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/topic/MulConsumerMulTopicIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/topic/MulConsumerMulTopicIT.java
new file mode 100644
index 0000000..98d858b
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/topic/MulConsumerMulTopicIT.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.topic;
+
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.factory.MQMessageFactory;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.MQWait;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class MulConsumerMulTopicIT extends BaseConf {
+    private RMQNormalProducer producer = null;
+
+    @Before
+    public void setUp() {
+        producer = getProducer(nsAddr, null);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testSynSendMessage() {
+        int msgSize = 10;
+        String topic1 = initTopic();
+        String topic2 = initTopic();
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic1, "*", new RMQNormalListner());
+        consumer1.subscribe(topic2, "*");
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic1,
+            "*", new RMQNormalListner());
+        consumer2.subscribe(topic2, "*");
+
+        producer.send(MQMessageFactory.getMsg(topic1, msgSize));
+        producer.send(MQMessageFactory.getMsg(topic2, msgSize));
+        Assert.assertEquals("Not all sent succeeded", msgSize * 2, producer.getAllUndupMsgBody().size());
+
+        boolean recvAll = MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(),
+            consumer1.getListner(), consumer2.getListner());
+        assertThat(recvAll).isEqualTo(true);
+    }
+
+    @Test
+    public void testConsumeWithDiffTag() {
+        int msgSize = 10;
+        String topic1 = initTopic();
+        String topic2 = initTopic();
+        String tag = "jueyin_tag";
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic1, "*", new RMQNormalListner());
+        consumer1.subscribe(topic2, tag);
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic1,
+            "*", new RMQNormalListner());
+        consumer2.subscribe(topic2, tag);
+
+        producer.send(MQMessageFactory.getMsg(topic1, msgSize));
+        producer.send(MQMessageFactory.getMsg(topic2, msgSize, tag));
+        Assert.assertEquals("Not all sent succeeded", msgSize * 2, producer.getAllUndupMsgBody().size());
+
+        boolean recvAll = MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(),
+            consumer1.getListner(), consumer2.getListner());
+        assertThat(recvAll).isEqualTo(true);
+    }
+
+    @Test
+    public void testConsumeWithDiffTagAndFilter() {
+        int msgSize = 10;
+        String topic1 = initTopic();
+        String topic2 = initTopic();
+        String tag1 = "jueyin_tag_1";
+        String tag2 = "jueyin_tag_2";
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic1, "*", new RMQNormalListner());
+        consumer1.subscribe(topic2, tag1);
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, topic1, "*", new RMQNormalListner());
+        consumer2.subscribe(topic2, tag1);
+
+        producer.send(MQMessageFactory.getMsg(topic2, msgSize, tag2));
+        producer.clearMsg();
+        producer.send(MQMessageFactory.getMsg(topic1, msgSize));
+        producer.send(MQMessageFactory.getMsg(topic2, msgSize, tag1));
+
+        boolean recvAll = MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(),
+            consumer1.getListner(), consumer2.getListner());
+        assertThat(recvAll).isEqualTo(true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/consumer/topic/OneConsumerMulTopicIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/consumer/topic/OneConsumerMulTopicIT.java b/test/src/test/java/org/apache/rocketmq/test/client/consumer/topic/OneConsumerMulTopicIT.java
new file mode 100644
index 0000000..969fa79
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/consumer/topic/OneConsumerMulTopicIT.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.consumer.topic;
+
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.factory.MQMessageFactory;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class OneConsumerMulTopicIT extends BaseConf {
+    private RMQNormalProducer producer = null;
+
+    @Before
+    public void setUp() {
+        producer = getProducer(nsAddr, null);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testSynSendMessage() {
+        int msgSize = 10;
+        String topic1 = initTopic();
+        String topic2 = initTopic();
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic1, "*", new RMQNormalListner());
+        consumer.subscribe(topic2, "*");
+
+        producer.send(MQMessageFactory.getMsg(topic1, msgSize));
+        producer.send(MQMessageFactory.getMsg(topic2, msgSize));
+
+        Assert.assertEquals("Not all are sent", msgSize * 2, producer.getAllUndupMsgBody().size());
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+
+    @Test
+    public void testConsumeWithDiffTag() {
+        int msgSize = 10;
+        String topic1 = initTopic();
+        String topic2 = initTopic();
+        String tag = "jueyin_tag";
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic1, "*", new RMQNormalListner());
+        consumer.subscribe(topic2, tag);
+
+        producer.send(MQMessageFactory.getMsg(topic1, msgSize));
+        producer.send(MQMessageFactory.getMsg(topic2, msgSize, tag));
+
+        Assert.assertEquals("Not all are sent", msgSize * 2, producer.getAllUndupMsgBody().size());
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+
+    @Test
+    public void testConsumeWithDiffTagAndFilter() {
+        int msgSize = 10;
+        String topic1 = initTopic();
+        String topic2 = initTopic();
+        String tag1 = "jueyin_tag_1";
+        String tag2 = "jueyin_tag_2";
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic1, "*", new RMQNormalListner());
+        consumer.subscribe(topic2, tag1);
+
+        producer.send(MQMessageFactory.getMsg(topic2, msgSize, tag2));
+        producer.clearMsg();
+        producer.send(MQMessageFactory.getMsg(topic1, msgSize));
+        producer.send(MQMessageFactory.getMsg(topic2, msgSize, tag1));
+
+        Assert.assertEquals("Not all are sent", msgSize * 2, producer.getAllUndupMsgBody().size());
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/async/AsyncSendExceptionIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/async/AsyncSendExceptionIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/async/AsyncSendExceptionIT.java
new file mode 100644
index 0000000..4125433
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/async/AsyncSendExceptionIT.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.async;
+
+import java.util.List;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.client.producer.DefaultMQProducer;
+import org.apache.rocketmq.client.producer.MessageQueueSelector;
+import org.apache.rocketmq.client.producer.SendCallback;
+import org.apache.rocketmq.client.producer.SendResult;
+import org.apache.rocketmq.common.message.Message;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.consumer.tag.TagMessageWith1ConsumerIT;
+import org.apache.rocketmq.test.factory.ProducerFactory;
+import org.apache.rocketmq.test.factory.SendCallBackFactory;
+import org.apache.rocketmq.test.util.RandomUtils;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class AsyncSendExceptionIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(TagMessageWith1ConsumerIT.class);
+    private static boolean sendFail = false;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("user topic[%s]!", topic));
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testSendCallBackNull() throws Exception {
+        Message msg = new Message(topic, RandomUtils.getStringByUUID().getBytes());
+        DefaultMQProducer producer = ProducerFactory.getRMQProducer(nsAddr);
+        SendCallback sendCallback = null;
+        producer.send(msg, sendCallback);
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void testSendMQNull() throws Exception {
+        Message msg = new Message(topic, RandomUtils.getStringByUUID().getBytes());
+        DefaultMQProducer producer = ProducerFactory.getRMQProducer(nsAddr);
+        MessageQueue messageQueue = null;
+        producer.send(msg, messageQueue, SendCallBackFactory.getSendCallBack());
+    }
+
+    @Test(expected = org.apache.rocketmq.client.exception.MQClientException.class)
+    public void testSendSelectorNull() throws Exception {
+        Message msg = new Message(topic, RandomUtils.getStringByUUID().getBytes());
+        DefaultMQProducer producer = ProducerFactory.getRMQProducer(nsAddr);
+        MessageQueueSelector selector = null;
+        producer.send(msg, selector, 100, SendCallBackFactory.getSendCallBack());
+    }
+
+    @Test(expected = org.apache.rocketmq.client.exception.MQClientException.class)
+    public void testSelectorThrowsException() throws Exception {
+        Message msg = new Message(topic, RandomUtils.getStringByUUID().getBytes());
+        DefaultMQProducer producer = ProducerFactory.getRMQProducer(nsAddr);
+        producer.send(msg, new MessageQueueSelector() {
+            @Override
+            public MessageQueue select(List<MessageQueue> list, Message message, Object o) {
+                String str = null;
+                return list.get(str.length());
+            }
+        }, null, SendCallBackFactory.getSendCallBack());
+    }
+
+    @Test
+    public void testQueueIdBigThanQueueNum() throws Exception {
+        int queueId = 100;
+        sendFail = false;
+        MessageQueue mq = new MessageQueue(topic, broker1Name, queueId);
+        Message msg = new Message(topic, RandomUtils.getStringByUUID().getBytes());
+        DefaultMQProducer producer = ProducerFactory.getRMQProducer(nsAddr);
+
+        producer.send(msg, mq, new SendCallback() {
+            @Override
+            public void onSuccess(SendResult sendResult) {
+            }
+
+            @Override
+            public void onException(Throwable throwable) {
+                sendFail = true;
+            }
+        });
+
+        int checkNum = 50;
+        while (!sendFail && checkNum > 0) {
+            checkNum--;
+            TestUtils.waitForMonment(100);
+        }
+        producer.shutdown();
+        assertThat(sendFail).isEqualTo(true);
+    }
+
+    @Test
+    public void testQueueIdSmallZero() throws Exception {
+        int queueId = -100;
+        sendFail = true;
+        MessageQueue mq = new MessageQueue(topic, broker1Name, queueId);
+        Message msg = new Message(topic, RandomUtils.getStringByUUID().getBytes());
+        DefaultMQProducer producer = ProducerFactory.getRMQProducer(nsAddr);
+
+        producer.send(msg, mq, new SendCallback() {
+            @Override
+            public void onSuccess(SendResult sendResult) {
+                sendFail = false;
+            }
+
+            @Override
+            public void onException(Throwable throwable) {
+                sendFail = true;
+            }
+        });
+
+        int checkNum = 50;
+        while (sendFail && checkNum > 0) {
+            checkNum--;
+            TestUtils.waitForMonment(100);
+        }
+        producer.shutdown();
+        assertThat(sendFail).isEqualTo(false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/async/AsyncSendWithMessageQueueIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/async/AsyncSendWithMessageQueueIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/async/AsyncSendWithMessageQueueIT.java
new file mode 100644
index 0000000..53a992c
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/async/AsyncSendWithMessageQueueIT.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.async;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.consumer.tag.TagMessageWith1ConsumerIT;
+import org.apache.rocketmq.test.client.rmq.RMQAsyncSendProducer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class AsyncSendWithMessageQueueIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(TagMessageWith1ConsumerIT.class);
+    private static boolean sendFail = false;
+    private RMQAsyncSendProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("user topic[%s]!", topic));
+        producer = getAsyncProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testAsyncSendWithMQ() {
+        int msgSize = 20;
+        int queueId = 0;
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+        MessageQueue mq = new MessageQueue(topic, broker1Name, queueId);
+
+        producer.asyncSend(msgSize, mq);
+        producer.waitForResponse(5 * 1000);
+        assertThat(producer.getSuccessMsgCount()).isEqualTo(msgSize);
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+
+        VerifyUtils.verifyMessageQueueId(queueId, consumer.getListner().getAllOriginMsg());
+
+        producer.clearMsg();
+        consumer.clearMsg();
+
+        mq = new MessageQueue(topic, broker2Name, queueId);
+        producer.asyncSend(msgSize, mq);
+        producer.waitForResponse(5 * 1000);
+        assertThat(producer.getSuccessMsgCount()).isEqualTo(msgSize);
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+
+        VerifyUtils.verifyMessageQueueId(queueId, consumer.getListner().getAllOriginMsg());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/async/AsyncSendWithMessageQueueSelectorIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/async/AsyncSendWithMessageQueueSelectorIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/async/AsyncSendWithMessageQueueSelectorIT.java
new file mode 100644
index 0000000..68c2b0e
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/async/AsyncSendWithMessageQueueSelectorIT.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.async;
+
+import java.util.List;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.client.producer.MessageQueueSelector;
+import org.apache.rocketmq.common.message.Message;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.consumer.tag.TagMessageWith1ConsumerIT;
+import org.apache.rocketmq.test.client.rmq.RMQAsyncSendProducer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class AsyncSendWithMessageQueueSelectorIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(TagMessageWith1ConsumerIT.class);
+    private static boolean sendFail = false;
+    private RMQAsyncSendProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("user topic[%s]!", topic));
+        producer = getAsyncProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testSendWithSelector() {
+        int msgSize = 20;
+        final int queueId = 0;
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+
+        producer.asyncSend(msgSize, new MessageQueueSelector() {
+            @Override
+            public MessageQueue select(List<MessageQueue> list, Message message, Object o) {
+                for (MessageQueue mq : list) {
+                    if (mq.getQueueId() == queueId && mq.getBrokerName().equals(broker1Name)) {
+                        return mq;
+                    }
+                }
+                return list.get(0);
+            }
+        });
+        producer.waitForResponse(5 * 1000);
+        assertThat(producer.getSuccessMsgCount()).isEqualTo(msgSize);
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+
+        VerifyUtils.verifyMessageQueueId(queueId, consumer.getListner().getAllOriginMsg());
+
+        producer.clearMsg();
+        consumer.clearMsg();
+
+        producer.asyncSend(msgSize, new MessageQueueSelector() {
+            @Override
+            public MessageQueue select(List<MessageQueue> list, Message message, Object o) {
+                for (MessageQueue mq : list) {
+                    if (mq.getQueueId() == queueId && mq.getBrokerName().equals(broker2Name)) {
+                        return mq;
+                    }
+                }
+                return list.get(8);
+            }
+        });
+        producer.waitForResponse(5 * 1000);
+        assertThat(producer.getSuccessMsgCount()).isEqualTo(msgSize);
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+
+        VerifyUtils.verifyMessageQueueId(queueId, consumer.getListner().getAllOriginMsg());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/async/AsyncSendWithOnlySendCallBackIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/async/AsyncSendWithOnlySendCallBackIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/async/AsyncSendWithOnlySendCallBackIT.java
new file mode 100644
index 0000000..51aeef4
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/async/AsyncSendWithOnlySendCallBackIT.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.async;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.consumer.tag.TagMessageWith1ConsumerIT;
+import org.apache.rocketmq.test.client.rmq.RMQAsyncSendProducer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class AsyncSendWithOnlySendCallBackIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(TagMessageWith1ConsumerIT.class);
+    private RMQAsyncSendProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("user topic[%s]!", topic));
+        producer = getAsyncProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testSendWithOnlyCallBack() {
+        int msgSize = 20;
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+        producer.asyncSend(msgSize);
+        producer.waitForResponse(10 * 1000);
+        assertThat(producer.getSuccessMsgCount()).isEqualTo(msgSize);
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/exception/msg/ChinaPropIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/exception/msg/ChinaPropIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/exception/msg/ChinaPropIT.java
new file mode 100644
index 0000000..e524fb3
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/exception/msg/ChinaPropIT.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.exception.msg;
+
+import org.apache.rocketmq.client.producer.DefaultMQProducer;
+import org.apache.rocketmq.client.producer.SendResult;
+import org.apache.rocketmq.client.producer.SendStatus;
+import org.apache.rocketmq.common.message.Message;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.factory.MessageFactory;
+import org.apache.rocketmq.test.factory.ProducerFactory;
+import org.apache.rocketmq.test.util.RandomUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class ChinaPropIT extends BaseConf {
+    private static DefaultMQProducer producer = null;
+    private static String topic = null;
+
+    @Before
+    public void setUp() {
+        producer = ProducerFactory.getRMQProducer(nsAddr);
+        topic = initTopic();
+    }
+
+    @After
+    public void tearDown() {
+        producer.shutdown();
+    }
+
+    /**
+     * @since version3.4.6
+     */
+    @Test(expected = org.apache.rocketmq.client.exception.MQBrokerException.class)
+    public void testSend20kChinaPropMsg() throws Exception {
+        Message msg = MessageFactory.getRandomMessage(topic);
+        msg.putUserProperty("key", RandomUtils.getCheseWord(32 * 1024 + 1));
+        producer.send(msg);
+    }
+
+    /**
+     * @since version3.4.6
+     */
+    @Test
+    public void testSend10kChinaPropMsg() {
+
+        Message msg = MessageFactory.getRandomMessage(topic);
+        msg.putUserProperty("key", RandomUtils.getCheseWord(10 * 1024));
+        SendResult sendResult = null;
+        try {
+            sendResult = producer.send(msg);
+        } catch (Exception e) {
+        }
+        assertThat(sendResult.getSendStatus()).isEqualTo(SendStatus.SEND_OK);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/exception/msg/MessageExceptionIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/exception/msg/MessageExceptionIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/exception/msg/MessageExceptionIT.java
new file mode 100644
index 0000000..6fa8bd9
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/exception/msg/MessageExceptionIT.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.exception.msg;
+
+import org.apache.rocketmq.client.producer.DefaultMQProducer;
+import org.apache.rocketmq.client.producer.SendResult;
+import org.apache.rocketmq.client.producer.SendStatus;
+import org.apache.rocketmq.common.message.Message;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.factory.MessageFactory;
+import org.apache.rocketmq.test.factory.ProducerFactory;
+import org.apache.rocketmq.test.util.RandomUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class MessageExceptionIT extends BaseConf {
+    private static DefaultMQProducer producer = null;
+    private static String topic = null;
+
+    @Before
+    public void setUp() {
+        producer = ProducerFactory.getRMQProducer(nsAddr);
+        topic = initTopic();
+    }
+
+    @After
+    public void tearDown() {
+        producer.shutdown();
+    }
+
+    @Test
+    public void testProducerSmoke() {
+        Message msg = new Message(topic, RandomUtils.getStringByUUID().getBytes());
+        SendResult sendResult = null;
+        try {
+            sendResult = producer.send(msg);
+        } catch (Exception e) {
+        }
+
+        assertThat(sendResult).isNotEqualTo(null);
+        assertThat(sendResult.getSendStatus()).isEqualTo(SendStatus.SEND_OK);
+    }
+
+    @Test(expected = org.apache.rocketmq.client.exception.MQClientException.class)
+    public void testSynSendNullMessage() throws Exception {
+        producer.send(null);
+    }
+
+    @Test(expected = org.apache.rocketmq.client.exception.MQClientException.class)
+    public void testSynSendNullBodyMessage() throws Exception {
+        Message msg = new Message(topic, RandomUtils.getStringByUUID().getBytes());
+        msg.setBody(null);
+        producer.send(msg);
+    }
+
+    @Test(expected = org.apache.rocketmq.client.exception.MQClientException.class)
+    public void testSynSendZeroSizeBodyMessage() throws Exception {
+        Message msg = new Message(topic, RandomUtils.getStringByUUID().getBytes());
+        msg.setBody(new byte[0]);
+        producer.send(msg);
+    }
+
+    @Test(expected = org.apache.rocketmq.client.exception.MQClientException.class)
+    public void testSynSendOutOfSizeBodyMessage() throws Exception {
+        Message msg = new Message(topic, RandomUtils.getStringByUUID().getBytes());
+        msg.setBody(new byte[1024 * 1024 * 4 + 1]);
+        producer.send(msg);
+    }
+
+    @Test(expected = org.apache.rocketmq.client.exception.MQClientException.class)
+    public void testSynSendNullTopicMessage() throws Exception {
+        Message msg = new Message(null, RandomUtils.getStringByUUID().getBytes());
+        producer.send(msg);
+    }
+
+    @Test(expected = org.apache.rocketmq.client.exception.MQClientException.class)
+    public void testSynSendBlankTopicMessage() throws Exception {
+        Message msg = new Message("", RandomUtils.getStringByUUID().getBytes());
+        producer.send(msg);
+    }
+
+    @Test(expected = org.apache.rocketmq.client.exception.MQClientException.class)
+    public void testSend128kMsg() throws Exception {
+        Message msg = new Message(topic,
+            RandomUtils.getStringWithNumber(1024 * 1024 * 4 + 1).getBytes());
+        producer.send(msg);
+    }
+
+    @Test
+    public void testSendLess128kMsg() {
+        Message msg = new Message(topic, RandomUtils.getStringWithNumber(128 * 1024).getBytes());
+        SendResult sendResult = null;
+        try {
+            sendResult = producer.send(msg);
+        } catch (Exception e) {
+        }
+        assertThat(sendResult.getSendStatus()).isEqualTo(SendStatus.SEND_OK);
+    }
+
+    @Test
+    public void testSendMsgWithUserProperty() {
+        Message msg = MessageFactory.getRandomMessage(topic);
+        msg.putUserProperty("key", RandomUtils.getCheseWord(10 * 1024));
+        SendResult sendResult = null;
+        try {
+            sendResult = producer.send(msg);
+        } catch (Exception e) {
+        }
+        assertThat(sendResult.getSendStatus()).isEqualTo(SendStatus.SEND_OK);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/exception/msg/MessageUserPropIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/exception/msg/MessageUserPropIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/exception/msg/MessageUserPropIT.java
new file mode 100644
index 0000000..b5882df
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/exception/msg/MessageUserPropIT.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.exception.msg;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.common.message.Message;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.consumer.balance.NormalMsgStaticBalanceIT;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.factory.MessageFactory;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class MessageUserPropIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(NormalMsgStaticBalanceIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s !", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    /**
+     * @since version3.4.6
+     */
+    @Test
+    public void testSendEnglishUserProp() {
+        Message msg = MessageFactory.getRandomMessage(topic);
+        String msgKey = "jueyinKey";
+        String msgValue = "jueyinValue";
+        msg.putUserProperty(msgKey, msgValue);
+
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+
+        producer.send(msg, null);
+        assertThat(producer.getAllMsgBody().size()).isEqualTo(1);
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        Message sendMsg = (Message) producer.getFirstMsg();
+        Message recvMsg = (Message) consumer.getListner().getFirstMsg();
+        assertThat(recvMsg.getUserProperty(msgKey)).isEqualTo(sendMsg.getUserProperty(msgKey));
+    }
+
+    /**
+     * @since version3.4.6
+     */
+    @Test
+    public void testSendChinaUserProp() {
+        Message msg = MessageFactory.getRandomMessage(topic);
+        String msgKey = "jueyinKey";
+        String msgValue = "jueyinzhi";
+        msg.putUserProperty(msgKey, msgValue);
+
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+
+        producer.send(msg, null);
+        assertThat(producer.getAllMsgBody().size()).isEqualTo(1);
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        Message sendMsg = (Message) producer.getFirstMsg();
+        Message recvMsg = (Message) consumer.getListner().getFirstMsg();
+        assertThat(recvMsg.getUserProperty(msgKey)).isEqualTo(sendMsg.getUserProperty(msgKey));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/exception/producer/ProducerGroupAndInstanceNameValidityIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/exception/producer/ProducerGroupAndInstanceNameValidityIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/exception/producer/ProducerGroupAndInstanceNameValidityIT.java
new file mode 100644
index 0000000..fbaa3c2
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/exception/producer/ProducerGroupAndInstanceNameValidityIT.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.exception.producer;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.util.RandomUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class ProducerGroupAndInstanceNameValidityIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(ProducerGroupAndInstanceNameValidityIT.class);
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s !", topic));
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    /**
+     * @since version3.4.6
+     */
+    @Test
+    public void testTwoProducerSameGroupAndInstanceName() {
+        RMQNormalProducer producer1 = getProducer(nsAddr, topic);
+        assertThat(producer1.isStartSuccess()).isEqualTo(true);
+        RMQNormalProducer producer2 = getProducer(nsAddr, topic,
+            producer1.getProducerGroupName(), producer1.getProducerInstanceName());
+        assertThat(producer2.isStartSuccess()).isEqualTo(false);
+    }
+
+    /**
+     * @since version3.4.6
+     */
+    @Test
+    public void testTwoProducerSameGroup() {
+        RMQNormalProducer producer1 = getProducer(nsAddr, topic);
+        assertThat(producer1.isStartSuccess()).isEqualTo(true);
+        RMQNormalProducer producer2 = getProducer(nsAddr, topic,
+            producer1.getProducerGroupName(), RandomUtils.getStringByUUID());
+        assertThat(producer2.isStartSuccess()).isEqualTo(true);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/oneway/OneWaySendExceptionIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/oneway/OneWaySendExceptionIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/oneway/OneWaySendExceptionIT.java
new file mode 100644
index 0000000..19d8ca5
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/oneway/OneWaySendExceptionIT.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.oneway;
+
+import java.util.List;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.client.producer.DefaultMQProducer;
+import org.apache.rocketmq.client.producer.MessageQueueSelector;
+import org.apache.rocketmq.common.message.Message;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.consumer.tag.TagMessageWith1ConsumerIT;
+import org.apache.rocketmq.test.factory.ProducerFactory;
+import org.apache.rocketmq.test.util.RandomUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class OneWaySendExceptionIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(TagMessageWith1ConsumerIT.class);
+    private static boolean sendFail = false;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("user topic[%s]!", topic));
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test(expected = java.lang.NullPointerException.class)
+    public void testSendMQNull() throws Exception {
+        Message msg = new Message(topic, RandomUtils.getStringByUUID().getBytes());
+        DefaultMQProducer producer = ProducerFactory.getRMQProducer(nsAddr);
+        MessageQueue messageQueue = null;
+        producer.sendOneway(msg, messageQueue);
+    }
+
+    @Test(expected = org.apache.rocketmq.client.exception.MQClientException.class)
+    public void testSendSelectorNull() throws Exception {
+        Message msg = new Message(topic, RandomUtils.getStringByUUID().getBytes());
+        DefaultMQProducer producer = ProducerFactory.getRMQProducer(nsAddr);
+        MessageQueueSelector selector = null;
+        producer.sendOneway(msg, selector, 100);
+    }
+
+    @Test(expected = org.apache.rocketmq.client.exception.MQClientException.class)
+    public void testSelectorThrowsException() throws Exception {
+        Message msg = new Message(topic, RandomUtils.getStringByUUID().getBytes());
+        DefaultMQProducer producer = ProducerFactory.getRMQProducer(nsAddr);
+        producer.sendOneway(msg, new MessageQueueSelector() {
+            @Override
+            public MessageQueue select(List<MessageQueue> list, Message message, Object o) {
+                String str = null;
+                return list.get(str.length());
+            }
+        }, null);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/oneway/OneWaySendIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/oneway/OneWaySendIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/oneway/OneWaySendIT.java
new file mode 100644
index 0000000..37df4f8
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/oneway/OneWaySendIT.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.oneway;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.consumer.tag.TagMessageWith1ConsumerIT;
+import org.apache.rocketmq.test.client.rmq.RMQAsyncSendProducer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class OneWaySendIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(TagMessageWith1ConsumerIT.class);
+    private RMQAsyncSendProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("user topic[%s]!", topic));
+        producer = getAsyncProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testOneWaySendWithOnlyMsgAsParam() {
+        int msgSize = 20;
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+
+        producer.sendOneWay(msgSize);
+        producer.waitForResponse(5 * 1000);
+        assertThat(producer.getAllMsgBody().size()).isEqualTo(msgSize);
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/oneway/OneWaySendWithMQIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/oneway/OneWaySendWithMQIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/oneway/OneWaySendWithMQIT.java
new file mode 100644
index 0000000..a2b601b
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/oneway/OneWaySendWithMQIT.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.oneway;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.consumer.tag.TagMessageWith1ConsumerIT;
+import org.apache.rocketmq.test.client.rmq.RMQAsyncSendProducer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class OneWaySendWithMQIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(TagMessageWith1ConsumerIT.class);
+    private static boolean sendFail = false;
+    private RMQAsyncSendProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("user topic[%s]!", topic));
+        producer = getAsyncProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testAsyncSendWithMQ() {
+        int msgSize = 20;
+        int queueId = 0;
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+        MessageQueue mq = new MessageQueue(topic, broker1Name, queueId);
+
+        producer.sendOneWay(msgSize, mq);
+        producer.waitForResponse(5 * 1000);
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+
+        producer.clearMsg();
+        consumer.clearMsg();
+
+        mq = new MessageQueue(topic, broker2Name, queueId);
+        producer.asyncSend(msgSize, mq);
+        producer.waitForResponse(5 * 1000);
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/oneway/OneWaySendWithSelectorIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/oneway/OneWaySendWithSelectorIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/oneway/OneWaySendWithSelectorIT.java
new file mode 100644
index 0000000..aa70556
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/oneway/OneWaySendWithSelectorIT.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.oneway;
+
+import java.util.List;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.client.producer.MessageQueueSelector;
+import org.apache.rocketmq.common.message.Message;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.consumer.tag.TagMessageWith1ConsumerIT;
+import org.apache.rocketmq.test.client.rmq.RMQAsyncSendProducer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class OneWaySendWithSelectorIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(TagMessageWith1ConsumerIT.class);
+    private static boolean sendFail = false;
+    private RMQAsyncSendProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("user topic[%s]!", topic));
+        producer = getAsyncProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testSendWithSelector() {
+        int msgSize = 20;
+        final int queueId = 0;
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+
+        producer.sendOneWay(msgSize, new MessageQueueSelector() {
+            @Override
+            public MessageQueue select(List<MessageQueue> list, Message message, Object o) {
+                for (MessageQueue mq : list) {
+                    if (mq.getQueueId() == queueId && mq.getBrokerName().equals(broker1Name)) {
+                        return mq;
+                    }
+                }
+                return list.get(0);
+            }
+        });
+        assertThat(producer.getAllMsgBody().size()).isEqualTo(msgSize);
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+
+        VerifyUtils.verifyMessageQueueId(queueId, consumer.getListner().getAllOriginMsg());
+
+        producer.clearMsg();
+        consumer.clearMsg();
+
+        producer.sendOneWay(msgSize, new MessageQueueSelector() {
+            @Override
+            public MessageQueue select(List<MessageQueue> list, Message message, Object o) {
+                for (MessageQueue mq : list) {
+                    if (mq.getQueueId() == queueId && mq.getBrokerName().equals(broker2Name)) {
+                        return mq;
+                    }
+                }
+                return list.get(8);
+            }
+        });
+        assertThat(producer.getAllMsgBody().size()).isEqualTo(msgSize);
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+
+        VerifyUtils.verifyMessageQueueId(queueId, consumer.getListner().getAllOriginMsg());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/order/OrderMsgDynamicRebalanceIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/order/OrderMsgDynamicRebalanceIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/order/OrderMsgDynamicRebalanceIT.java
new file mode 100644
index 0000000..a6520b4
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/order/OrderMsgDynamicRebalanceIT.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.order;
+
+import java.util.List;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.consumer.balance.NormalMsgStaticBalanceIT;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.order.RMQOrderListener;
+import org.apache.rocketmq.test.message.MessageQueueMsg;
+import org.apache.rocketmq.test.util.MQWait;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class OrderMsgDynamicRebalanceIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(NormalMsgStaticBalanceIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s !", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testTwoConsumerAndCrashOne() {
+        int msgSize = 10;
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic, "*",
+            new RMQOrderListener("1"));
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQOrderListener("2"));
+
+        List<MessageQueue> mqs = producer.getMessageQueue();
+        MessageQueueMsg mqMsgs = new MessageQueueMsg(mqs, msgSize);
+        producer.send(mqMsgs.getMsgsWithMQ());
+
+        MQWait.waitConsumeAll(30 * 1000, producer.getAllMsgBody(), consumer1.getListner(),
+            consumer2.getListner());
+        consumer2.shutdown();
+
+        mqMsgs = new MessageQueueMsg(mqs, msgSize);
+        producer.send(mqMsgs.getMsgsWithMQ());
+
+        boolean recvAll = MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(),
+            consumer1.getListner(), consumer2.getListner());
+        assertThat(recvAll).isEqualTo(true);
+
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer1.getListner()).getMsgs()))
+            .isEqualTo(true);
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer2.getListner()).getMsgs()))
+            .isEqualTo(true);
+    }
+
+    @Test
+    public void testThreeConsumerAndCrashOne() {
+        int msgSize = 10;
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic, "*",
+            new RMQOrderListener("1"));
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQOrderListener("2"));
+        RMQNormalConsumer consumer3 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQOrderListener("3"));
+
+        List<MessageQueue> mqs = producer.getMessageQueue();
+        MessageQueueMsg mqMsgs = new MessageQueueMsg(mqs, msgSize);
+        producer.send(mqMsgs.getMsgsWithMQ());
+
+        MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(), consumer1.getListner(),
+            consumer2.getListner(), consumer3.getListner());
+        consumer3.shutdown();
+
+        mqMsgs = new MessageQueueMsg(mqs, msgSize);
+        producer.send(mqMsgs.getMsgsWithMQ());
+
+        boolean recvAll = MQWait.waitConsumeAll(30 * 1000, producer.getAllMsgBody(),
+            consumer1.getListner(), consumer2.getListner(), consumer3.getListner());
+        assertThat(recvAll).isEqualTo(true);
+
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer1.getListner()).getMsgs()))
+            .isEqualTo(true);
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer2.getListner()).getMsgs()))
+            .isEqualTo(true);
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer3.getListner()).getMsgs()))
+            .isEqualTo(true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/order/OrderMsgIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/order/OrderMsgIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/order/OrderMsgIT.java
new file mode 100644
index 0000000..006aaa1
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/order/OrderMsgIT.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.order;
+
+import java.util.List;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.factory.MQMessageFactory;
+import org.apache.rocketmq.test.listener.rmq.order.RMQOrderListener;
+import org.apache.rocketmq.test.message.MessageQueueMsg;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class OrderMsgIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(OrderMsgIT.class);
+    private RMQNormalProducer producer = null;
+    private RMQNormalConsumer consumer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s;", topic));
+        producer = getProducer(nsAddr, topic);
+        consumer = getConsumer(nsAddr, topic, "*", new RMQOrderListener());
+    }
+
+    @After
+    public void tearDown() {
+        shutDown();
+    }
+
+    @Test
+    public void testOrderMsg() {
+        int msgSize = 10;
+        List<MessageQueue> mqs = producer.getMessageQueue();
+        MessageQueueMsg mqMsgs = new MessageQueueMsg(mqs, msgSize);
+        producer.send(mqMsgs.getMsgsWithMQ());
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(mqMsgs.getMsgBodys());
+
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer.getListner()).getMsgs()))
+            .isEqualTo(true);
+    }
+
+    @Test
+    public void testSendOneQueue() {
+        int msgSize = 20;
+        List<MessageQueue> mqs = producer.getMessageQueue();
+        MessageQueueMsg mqMsgs = new MessageQueueMsg(MQMessageFactory.getMessageQueues(mqs.get(0)),
+            msgSize);
+        producer.send(mqMsgs.getMsgsWithMQ());
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(mqMsgs.getMsgBodys());
+
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer.getListner()).getMsgs()))
+            .isEqualTo(true);
+    }
+
+    @Test
+    public void testSendRandomQueues() {
+        int msgSize = 10;
+        List<MessageQueue> mqs = producer.getMessageQueue();
+        MessageQueueMsg mqMsgs = new MessageQueueMsg(
+            MQMessageFactory.getMessageQueues(mqs.get(0), mqs.get(1), mqs.get(mqs.size() - 1)),
+            msgSize);
+        producer.send(mqMsgs.getMsgsWithMQ());
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(mqMsgs.getMsgBodys());
+
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer.getListner()).getMsgs()))
+            .isEqualTo(true);
+    }
+}


[26/31] incubator-rocketmq git commit: [ROCKETMQ-56] Polish unit tests for rocketmq-store

Posted by st...@apache.org.
[ROCKETMQ-56] Polish unit tests for rocketmq-store


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/881aef5d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/881aef5d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/881aef5d

Branch: refs/heads/ROCKETMQ-54
Commit: 881aef5d3195b918c87043ea75a19a3fb805b2e0
Parents: e9a87ea
Author: yukon <yu...@apache.org>
Authored: Sun Jan 22 16:23:54 2017 +0800
Committer: yukon <yu...@apache.org>
Committed: Sun Jan 22 16:28:21 2017 +0800

----------------------------------------------------------------------
 .../rocketmq/store/DefaultMessageStoreTest.java |  65 +++-----
 .../rocketmq/store/MappedFileQueueTest.java     | 162 ++++++-------------
 .../apache/rocketmq/store/MappedFileTest.java   |  56 ++-----
 .../rocketmq/store/StoreCheckpointTest.java     |  21 +--
 .../rocketmq/store/index/IndexFileTest.java     |  26 ++-
 .../store/schedule/ScheduleMessageTest.java     | 133 ---------------
 6 files changed, 91 insertions(+), 372 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/881aef5d/store/src/test/java/org/apache/rocketmq/store/DefaultMessageStoreTest.java
----------------------------------------------------------------------
diff --git a/store/src/test/java/org/apache/rocketmq/store/DefaultMessageStoreTest.java b/store/src/test/java/org/apache/rocketmq/store/DefaultMessageStoreTest.java
index 477ac10..5c9c46f 100644
--- a/store/src/test/java/org/apache/rocketmq/store/DefaultMessageStoreTest.java
+++ b/store/src/test/java/org/apache/rocketmq/store/DefaultMessageStoreTest.java
@@ -24,42 +24,28 @@ import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.rocketmq.common.BrokerConfig;
 import org.apache.rocketmq.store.config.FlushDiskType;
 import org.apache.rocketmq.store.config.MessageStoreConfig;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
+import org.junit.Before;
 import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.assertTrue;
 
 public class DefaultMessageStoreTest {
-    private static final Logger logger = LoggerFactory.getLogger(DefaultMessageStoreTest.class);
-
-    private static final String StoreMessage = "Once, there was a chance for me!";
-
-    private static int QUEUE_TOTAL = 100;
-
-    private static AtomicInteger QueueId = new AtomicInteger(0);
-
-    private static SocketAddress BornHost;
-
-    private static SocketAddress StoreHost;
-
-    private static byte[] MessageBody;
-
-    @BeforeClass
-    public static void setUpBeforeClass() throws Exception {
+    private final String StoreMessage = "Once, there was a chance for me!";
+    private int QUEUE_TOTAL = 100;
+    private AtomicInteger QueueId = new AtomicInteger(0);
+    private SocketAddress BornHost;
+    private SocketAddress StoreHost;
+    private byte[] MessageBody;
+
+    @Before
+    public void init() throws Exception {
         StoreHost = new InetSocketAddress(InetAddress.getLocalHost(), 8123);
         BornHost = new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 0);
     }
 
-    @AfterClass
-    public static void tearDownAfterClass() throws Exception {
-    }
-
     @Test
-    public void test_write_read() throws Exception {
-        logger.debug("================================================================");
+    public void testWriteAndRead() throws Exception {
         long totalMsgs = 100;
         QUEUE_TOTAL = 1;
         MessageBody = StoreMessage.getBytes();
@@ -77,29 +63,23 @@ public class DefaultMessageStoreTest {
         master.start();
         try {
             for (long i = 0; i < totalMsgs; i++) {
-                PutMessageResult result = master.putMessage(buildMessage());
-                logger.debug(i + "\t" + result.getAppendMessageResult().getMsgId());
+                master.putMessage(buildMessage());
             }
 
             for (long i = 0; i < totalMsgs; i++) {
                 GetMessageResult result = master.getMessage("GROUP_A", "TOPIC_A", 0, i, 1024 * 1024, null);
-                if (result == null) {
-                    logger.debug("result == null " + i);
-                }
-                assertTrue(result != null);
+                assertThat(result).isNotNull();
                 result.release();
-                logger.debug("read " + i + " OK");
             }
         } finally {
             master.shutdown();
             master.destroy();
         }
-        logger.debug("================================================================");
     }
 
     public MessageExtBrokerInner buildMessage() {
         MessageExtBrokerInner msg = new MessageExtBrokerInner();
-        msg.setTopic("AAA");
+        msg.setTopic("FooBar");
         msg.setTags("TAG1");
         msg.setKeys("Hello");
         msg.setBody(MessageBody);
@@ -113,8 +93,7 @@ public class DefaultMessageStoreTest {
     }
 
     @Test
-    public void test_group_commit() throws Exception {
-        logger.debug("================================================================");
+    public void testGroupCommit() throws Exception {
         long totalMsgs = 100;
         QUEUE_TOTAL = 1;
         MessageBody = StoreMessage.getBytes();
@@ -128,32 +107,24 @@ public class DefaultMessageStoreTest {
         master.start();
         try {
             for (long i = 0; i < totalMsgs; i++) {
-                PutMessageResult result = master.putMessage(buildMessage());
-                logger.debug(i + "\t" + result.getAppendMessageResult().getMsgId());
+                master.putMessage(buildMessage());
             }
 
             for (long i = 0; i < totalMsgs; i++) {
                 GetMessageResult result = master.getMessage("GROUP_A", "TOPIC_A", 0, i, 1024 * 1024, null);
-                if (result == null) {
-                    logger.debug("result == null " + i);
-                }
-                assertTrue(result != null);
+                assertThat(result).isNotNull();
                 result.release();
-                logger.debug("read " + i + " OK");
 
             }
         } finally {
             master.shutdown();
             master.destroy();
         }
-        logger.debug("================================================================");
     }
 
     private class MyMessageArrivingListener implements MessageArrivingListener {
-
         @Override
         public void arriving(String topic, int queueId, long logicOffset, long tagsCode) {
-            // Do nothing here
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/881aef5d/store/src/test/java/org/apache/rocketmq/store/MappedFileQueueTest.java
----------------------------------------------------------------------
diff --git a/store/src/test/java/org/apache/rocketmq/store/MappedFileQueueTest.java b/store/src/test/java/org/apache/rocketmq/store/MappedFileQueueTest.java
index 2d6c112..f1f9c1f 100644
--- a/store/src/test/java/org/apache/rocketmq/store/MappedFileQueueTest.java
+++ b/store/src/test/java/org/apache/rocketmq/store/MappedFileQueueTest.java
@@ -15,70 +15,30 @@
  * limitations under the License.
  */
 
-/**
- * $Id: MappedFileQueueTest.java 1831 2013-05-16 01:39:51Z vintagewang@apache.org $
- */
 package org.apache.rocketmq.store;
 
 import java.nio.ByteBuffer;
 import java.util.Arrays;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
 import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.assertj.core.api.Assertions.assertThat;
 
 public class MappedFileQueueTest {
-    private static final Logger logger = LoggerFactory.getLogger(MappedFileQueueTest.class);
-
-    // private static final String StoreMessage =
-    // "Once, there was a chance for me! but I did not treasure it. if";
-
-    @BeforeClass
-    public static void setUpBeforeClass() throws Exception {
-    }
-
-    @AfterClass
-    public static void tearDownAfterClass() throws Exception {
-    }
-
-    @Before
-    public void setUp() throws Exception {
-    }
-
-    @After
-    public void tearDown() throws Exception {
-    }
-
     @Test
-    public void test_getLastMappedFile() {
+    public void testGetLastMappedFile() {
         final String fixedMsg = "0123456789abcdef";
 
-        logger.debug("================================================================");
         MappedFileQueue mappedFileQueue =
             new MappedFileQueue("target/unit_test_store/a/", 1024, null);
 
         for (int i = 0; i < 1024; i++) {
             MappedFile mappedFile = mappedFileQueue.getLastMappedFile(0);
-            assertTrue(mappedFile != null);
-
-            boolean result = mappedFile.appendMessage(fixedMsg.getBytes());
-            if (!result) {
-                logger.debug("appendMessage " + i);
-            }
-            assertTrue(result);
+            assertThat(mappedFile).isNotNull();
+            assertThat(mappedFile.appendMessage(fixedMsg.getBytes())).isTrue();
         }
 
         mappedFileQueue.shutdown(1000);
         mappedFileQueue.destroy();
-        logger.debug("MappedFileQueue.getLastMappedFile() OK");
     }
 
     @Test
@@ -86,162 +46,134 @@ public class MappedFileQueueTest {
         // four-byte string.
         final String fixedMsg = "abcd";
 
-        logger.debug("================================================================");
         MappedFileQueue mappedFileQueue =
             new MappedFileQueue("target/unit_test_store/b/", 1024, null);
 
         for (int i = 0; i < 1024; i++) {
             MappedFile mappedFile = mappedFileQueue.getLastMappedFile(0);
-            assertTrue(mappedFile != null);
-
-            boolean result = mappedFile.appendMessage(fixedMsg.getBytes());
-            assertTrue(result);
+            assertThat(mappedFile).isNotNull();
+            assertThat(mappedFile.appendMessage(fixedMsg.getBytes())).isTrue();
         }
 
-        assertEquals(fixedMsg.getBytes().length * 1024, mappedFileQueue.getMappedMemorySize());
+        assertThat(mappedFileQueue.getMappedMemorySize()).isEqualTo(fixedMsg.getBytes().length * 1024);
 
         MappedFile mappedFile = mappedFileQueue.findMappedFileByOffset(0);
-        assertTrue(mappedFile != null);
-        assertEquals(mappedFile.getFileFromOffset(), 0);
+        assertThat(mappedFile).isNotNull();
+        assertThat(mappedFile.getFileFromOffset()).isEqualTo(0);
 
         mappedFile = mappedFileQueue.findMappedFileByOffset(100);
-        assertTrue(mappedFile != null);
-        assertEquals(mappedFile.getFileFromOffset(), 0);
+        assertThat(mappedFile).isNotNull();
+        assertThat(mappedFile.getFileFromOffset()).isEqualTo(0);
 
         mappedFile = mappedFileQueue.findMappedFileByOffset(1024);
-        assertTrue(mappedFile != null);
-        assertEquals(mappedFile.getFileFromOffset(), 1024);
+        assertThat(mappedFile).isNotNull();
+        assertThat(mappedFile.getFileFromOffset()).isEqualTo(1024);
 
         mappedFile = mappedFileQueue.findMappedFileByOffset(1024 + 100);
-        assertTrue(mappedFile != null);
-        assertEquals(mappedFile.getFileFromOffset(), 1024);
+        assertThat(mappedFile).isNotNull();
+        assertThat(mappedFile.getFileFromOffset()).isEqualTo(1024);
 
         mappedFile = mappedFileQueue.findMappedFileByOffset(1024 * 2);
-        assertTrue(mappedFile != null);
-        assertEquals(mappedFile.getFileFromOffset(), 1024 * 2);
+        assertThat(mappedFile).isNotNull();
+        assertThat(mappedFile.getFileFromOffset()).isEqualTo(1024 * 2);
 
         mappedFile = mappedFileQueue.findMappedFileByOffset(1024 * 2 + 100);
-        assertTrue(mappedFile != null);
-        assertEquals(mappedFile.getFileFromOffset(), 1024 * 2);
+        assertThat(mappedFile).isNotNull();
+        assertThat(mappedFile.getFileFromOffset()).isEqualTo(1024 * 2);
 
         // over mapped memory size.
         mappedFile = mappedFileQueue.findMappedFileByOffset(1024 * 4);
-        assertTrue(mappedFile == null);
+        assertThat(mappedFile).isNull();
 
         mappedFile = mappedFileQueue.findMappedFileByOffset(1024 * 4 + 100);
-        assertTrue(mappedFile == null);
+        assertThat(mappedFile).isNull();
 
         mappedFileQueue.shutdown(1000);
         mappedFileQueue.destroy();
-        logger.debug("MappedFileQueue.findMappedFileByOffset() OK");
     }
 
     @Test
-    public void test_commit() {
+    public void testAppendMessage() {
         final String fixedMsg = "0123456789abcdef";
 
-        logger.debug("================================================================");
         MappedFileQueue mappedFileQueue =
             new MappedFileQueue("target/unit_test_store/c/", 1024, null);
 
         for (int i = 0; i < 1024; i++) {
             MappedFile mappedFile = mappedFileQueue.getLastMappedFile(0);
-            assertTrue(mappedFile != null);
-
-            boolean result = mappedFile.appendMessage(fixedMsg.getBytes());
-            assertTrue(result);
+            assertThat(mappedFile).isNotNull();
+            assertThat(mappedFile.appendMessage(fixedMsg.getBytes())).isTrue();
         }
 
-        boolean result = mappedFileQueue.flush(0);
-        assertFalse(result);
-        assertEquals(1024 * 1, mappedFileQueue.getFlushedWhere());
+        assertThat(mappedFileQueue.flush(0)).isFalse();
+        assertThat(mappedFileQueue.getFlushedWhere()).isEqualTo(1024);
 
-        result = mappedFileQueue.flush(0);
-        assertFalse(result);
-        assertEquals(1024 * 2, mappedFileQueue.getFlushedWhere());
+        assertThat(mappedFileQueue.flush(0)).isFalse();
+        assertThat(mappedFileQueue.getFlushedWhere()).isEqualTo(1024 * 2);
 
-        result = mappedFileQueue.flush(0);
-        assertFalse(result);
-        assertEquals(1024 * 3, mappedFileQueue.getFlushedWhere());
+        assertThat(mappedFileQueue.flush(0)).isFalse();
+        assertThat(mappedFileQueue.getFlushedWhere()).isEqualTo(1024 * 3);
 
-        result = mappedFileQueue.flush(0);
-        assertFalse(result);
-        assertEquals(1024 * 4, mappedFileQueue.getFlushedWhere());
+        assertThat(mappedFileQueue.flush(0)).isFalse();
+        assertThat(mappedFileQueue.getFlushedWhere()).isEqualTo(1024 * 4);
 
-        result = mappedFileQueue.flush(0);
-        assertFalse(result);
-        assertEquals(1024 * 5, mappedFileQueue.getFlushedWhere());
+        assertThat(mappedFileQueue.flush(0)).isFalse();
+        assertThat(mappedFileQueue.getFlushedWhere()).isEqualTo(1024 * 5);
 
-        result = mappedFileQueue.flush(0);
-        assertFalse(result);
-        assertEquals(1024 * 6, mappedFileQueue.getFlushedWhere());
+        assertThat(mappedFileQueue.flush(0)).isFalse();
+        assertThat(mappedFileQueue.getFlushedWhere()).isEqualTo(1024 * 6);
 
         mappedFileQueue.shutdown(1000);
         mappedFileQueue.destroy();
-        logger.debug("MappedFileQueue.flush() OK");
     }
 
     @Test
-    public void test_getMappedMemorySize() {
+    public void testGetMappedMemorySize() {
         final String fixedMsg = "abcd";
 
-        logger.debug("================================================================");
         MappedFileQueue mappedFileQueue =
             new MappedFileQueue("target/unit_test_store/d/", 1024, null);
 
         for (int i = 0; i < 1024; i++) {
             MappedFile mappedFile = mappedFileQueue.getLastMappedFile(0);
-            assertTrue(mappedFile != null);
-
-            boolean result = mappedFile.appendMessage(fixedMsg.getBytes());
-            assertTrue(result);
+            assertThat(mappedFile).isNotNull();
+            assertThat(mappedFile.appendMessage(fixedMsg.getBytes())).isTrue();
         }
 
-        assertEquals(fixedMsg.length() * 1024, mappedFileQueue.getMappedMemorySize());
-
+        assertThat(mappedFileQueue.getMappedMemorySize()).isEqualTo(fixedMsg.length() * 1024);
         mappedFileQueue.shutdown(1000);
         mappedFileQueue.destroy();
-        logger.debug("MappedFileQueue.getMappedMemorySize() OK");
     }
 
-
     @Test
-    public void test_deleteExpiredFileByOffset() {
-
-        logger.debug("================================================================");
+    public void testDeleteExpiredFileByOffset() {
         MappedFileQueue mappedFileQueue =
             new MappedFileQueue("target/unit_test_store/e", 5120, null);
 
         for (int i = 0; i < 2048; i++) {
             MappedFile mappedFile = mappedFileQueue.getLastMappedFile(0);
-            assertNotNull(mappedFile);
-
+            assertThat(mappedFile).isNotNull();
             ByteBuffer byteBuffer = ByteBuffer.allocate(ConsumeQueue.CQ_STORE_UNIT_SIZE);
             byteBuffer.putLong(i);
             byte[] padding = new byte[12];
-            Arrays.fill(padding, (byte)'0');
+            Arrays.fill(padding, (byte) '0');
             byteBuffer.put(padding);
             byteBuffer.flip();
 
-            boolean result = mappedFile.appendMessage(byteBuffer.array());
-
-            assertTrue(result);
+            assertThat(mappedFile.appendMessage(byteBuffer.array())).isTrue();
         }
 
         MappedFile first = mappedFileQueue.getFirstMappedFile();
         first.hold();
 
-        int count = mappedFileQueue.deleteExpiredFileByOffset(20480, ConsumeQueue.CQ_STORE_UNIT_SIZE);
-        assertEquals(0, count);
+        assertThat(mappedFileQueue.deleteExpiredFileByOffset(20480, ConsumeQueue.CQ_STORE_UNIT_SIZE)).isEqualTo(0);
         first.release();
 
-        count = mappedFileQueue.deleteExpiredFileByOffset(20480, ConsumeQueue.CQ_STORE_UNIT_SIZE);
-        assertTrue(count > 0);
+        assertThat(mappedFileQueue.deleteExpiredFileByOffset(20480, ConsumeQueue.CQ_STORE_UNIT_SIZE)).isGreaterThan(0);
         first = mappedFileQueue.getFirstMappedFile();
-        assertTrue(first.getFileFromOffset() > 0);
+        assertThat(first.getFileFromOffset()).isGreaterThan(0);
 
         mappedFileQueue.shutdown(1000);
         mappedFileQueue.destroy();
-        logger.debug("MappedFileQueue.deleteExpiredFileByOffset() OK");
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/881aef5d/store/src/test/java/org/apache/rocketmq/store/MappedFileTest.java
----------------------------------------------------------------------
diff --git a/store/src/test/java/org/apache/rocketmq/store/MappedFileTest.java b/store/src/test/java/org/apache/rocketmq/store/MappedFileTest.java
index 1dd2043..d2736ac 100644
--- a/store/src/test/java/org/apache/rocketmq/store/MappedFileTest.java
+++ b/store/src/test/java/org/apache/rocketmq/store/MappedFileTest.java
@@ -21,66 +21,30 @@
 package org.apache.rocketmq.store;
 
 import java.io.IOException;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
 import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-import static org.junit.Assert.assertTrue;
+import static org.assertj.core.api.Assertions.assertThat;
 
 public class MappedFileTest {
-
-    private static final Logger logger = LoggerFactory.getLogger(MappedFileTest.class);
-
-    private static final String StoreMessage = "Once, there was a chance for me!";
-
-    @BeforeClass
-    public static void setUpBeforeClass() throws Exception {
-
-    }
-
-    @AfterClass
-    public static void tearDownAfterClass() throws Exception {
-    }
+    private final String storeMessage = "Once, there was a chance for me!";
 
     @Test
-    public void test_write_read() throws IOException {
+    public void testSelectMappedBuffer() throws IOException {
         MappedFile mappedFile = new MappedFile("target/unit_test_store/MappedFileTest/000", 1024 * 64);
-        boolean result = mappedFile.appendMessage(StoreMessage.getBytes());
-        assertTrue(result);
-        logger.debug("write OK");
+        boolean result = mappedFile.appendMessage(storeMessage.getBytes());
+        assertThat(result).isTrue();
 
         SelectMappedBufferResult selectMappedBufferResult = mappedFile.selectMappedBuffer(0);
-        byte[] data = new byte[StoreMessage.length()];
+        byte[] data = new byte[storeMessage.length()];
         selectMappedBufferResult.getByteBuffer().get(data);
         String readString = new String(data);
 
-        logger.debug("Read: " + readString);
-        assertTrue(readString.equals(StoreMessage));
+        assertThat(readString).isEqualTo(storeMessage);
 
         mappedFile.shutdown(1000);
-        assertTrue(!mappedFile.isAvailable());
-        selectMappedBufferResult.release();
-        assertTrue(mappedFile.isCleanupOver());
-        assertTrue(mappedFile.destroy(1000));
-    }
-
-    @Ignore
-    public void test_jvm_crashed() throws IOException {
-        MappedFile mappedFile = new MappedFile("target/unit_test_store/MappedFileTest/10086", 1024 * 64);
-        boolean result = mappedFile.appendMessage(StoreMessage.getBytes());
-        assertTrue(result);
-        logger.debug("write OK");
-
-        SelectMappedBufferResult selectMappedBufferResult = mappedFile.selectMappedBuffer(0);
+        assertThat(mappedFile.isAvailable()).isFalse();
         selectMappedBufferResult.release();
-        mappedFile.shutdown(1000);
-
-        byte[] data = new byte[StoreMessage.length()];
-        selectMappedBufferResult.getByteBuffer().get(data);
-        String readString = new String(data);
-        logger.debug(readString);
+        assertThat(mappedFile.isCleanupOver()).isTrue();
+        assertThat(mappedFile.destroy(1000)).isTrue();
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/881aef5d/store/src/test/java/org/apache/rocketmq/store/StoreCheckpointTest.java
----------------------------------------------------------------------
diff --git a/store/src/test/java/org/apache/rocketmq/store/StoreCheckpointTest.java b/store/src/test/java/org/apache/rocketmq/store/StoreCheckpointTest.java
index e87da96..1af63d4 100644
--- a/store/src/test/java/org/apache/rocketmq/store/StoreCheckpointTest.java
+++ b/store/src/test/java/org/apache/rocketmq/store/StoreCheckpointTest.java
@@ -21,24 +21,13 @@
 package org.apache.rocketmq.store;
 
 import java.io.IOException;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
 import org.junit.Test;
 
-import static org.junit.Assert.assertTrue;
+import static org.assertj.core.api.Assertions.assertThat;
 
 public class StoreCheckpointTest {
-    @BeforeClass
-    public static void setUpBeforeClass() throws Exception {
-
-    }
-
-    @AfterClass
-    public static void tearDownAfterClass() throws Exception {
-    }
-
     @Test
-    public void test_write_read() throws IOException {
+    public void testWriteAndRead() throws IOException {
         StoreCheckpoint storeCheckpoint = new StoreCheckpoint("target/checkpoint_test/0000");
         long physicMsgTimestamp = 0xAABB;
         long logicsMsgTimestamp = 0xCCDD;
@@ -47,10 +36,10 @@ public class StoreCheckpointTest {
         storeCheckpoint.flush();
 
         long diff = physicMsgTimestamp - storeCheckpoint.getMinTimestamp();
-        assertTrue(diff == 3000);
+        assertThat(diff).isEqualTo(3000);
         storeCheckpoint.shutdown();
         storeCheckpoint = new StoreCheckpoint("target/checkpoint_test/0000");
-        assertTrue(physicMsgTimestamp == storeCheckpoint.getPhysicMsgTimestamp());
-        assertTrue(logicsMsgTimestamp == storeCheckpoint.getLogicsMsgTimestamp());
+        assertThat(storeCheckpoint.getPhysicMsgTimestamp()).isEqualTo(physicMsgTimestamp);
+        assertThat(storeCheckpoint.getLogicsMsgTimestamp()).isEqualTo(logicsMsgTimestamp);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/881aef5d/store/src/test/java/org/apache/rocketmq/store/index/IndexFileTest.java
----------------------------------------------------------------------
diff --git a/store/src/test/java/org/apache/rocketmq/store/index/IndexFileTest.java b/store/src/test/java/org/apache/rocketmq/store/index/IndexFileTest.java
index 956f867..f172e65 100644
--- a/store/src/test/java/org/apache/rocketmq/store/index/IndexFileTest.java
+++ b/store/src/test/java/org/apache/rocketmq/store/index/IndexFileTest.java
@@ -24,47 +24,43 @@ import java.util.ArrayList;
 import java.util.List;
 import org.junit.Test;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.assertj.core.api.Assertions.assertThat;
 
 public class IndexFileTest {
-    private static final int HASH_SLOT_NUM = 100;
-    private static final int INDEX_NUM = 400;
+    private final int HASH_SLOT_NUM = 100;
+    private final int INDEX_NUM = 400;
 
     @Test
-    public void test_put_index() throws Exception {
+    public void testPutKey() throws Exception {
         IndexFile indexFile = new IndexFile("100", HASH_SLOT_NUM, INDEX_NUM, 0, 0);
         for (long i = 0; i < (INDEX_NUM - 1); i++) {
             boolean putResult = indexFile.putKey(Long.toString(i), i, System.currentTimeMillis());
-            assertTrue(putResult);
+            assertThat(putResult).isTrue();
         }
 
         // put over index file capacity.
         boolean putResult = indexFile.putKey(Long.toString(400), 400, System.currentTimeMillis());
-        assertFalse(putResult);
-
+        assertThat(putResult).isFalse();
         indexFile.destroy(0);
     }
 
     @Test
-    public void test_put_get_index() throws Exception {
+    public void testSelectPhyOffset() throws Exception {
         IndexFile indexFile = new IndexFile("200", HASH_SLOT_NUM, INDEX_NUM, 0, 0);
 
         for (long i = 0; i < (INDEX_NUM - 1); i++) {
             boolean putResult = indexFile.putKey(Long.toString(i), i, System.currentTimeMillis());
-            assertTrue(putResult);
+            assertThat(putResult).isTrue();
         }
 
         // put over index file capacity.
         boolean putResult = indexFile.putKey(Long.toString(400), 400, System.currentTimeMillis());
-        assertFalse(putResult);
+        assertThat(putResult).isFalse();
 
         final List<Long> phyOffsets = new ArrayList<Long>();
         indexFile.selectPhyOffset(phyOffsets, "60", 10, 0, Long.MAX_VALUE, true);
-        assertFalse(phyOffsets.isEmpty());
-        assertEquals(1, phyOffsets.size());
-
+        assertThat(phyOffsets).isNotEmpty();
+        assertThat(phyOffsets.size()).isEqualTo(1);
         indexFile.destroy(0);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/881aef5d/store/src/test/java/org/apache/rocketmq/store/schedule/ScheduleMessageTest.java
----------------------------------------------------------------------
diff --git a/store/src/test/java/org/apache/rocketmq/store/schedule/ScheduleMessageTest.java b/store/src/test/java/org/apache/rocketmq/store/schedule/ScheduleMessageTest.java
deleted file mode 100644
index 692dfc0..0000000
--- a/store/src/test/java/org/apache/rocketmq/store/schedule/ScheduleMessageTest.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-/**
- * $Id: ScheduleMessageTest.java 1831 2013-05-16 01:39:51Z vintagewang@apache.org $
- */
-package org.apache.rocketmq.store.schedule;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.concurrent.atomic.AtomicInteger;
-import org.apache.rocketmq.store.DefaultMessageStore;
-import org.apache.rocketmq.store.GetMessageResult;
-import org.apache.rocketmq.store.MessageExtBrokerInner;
-import org.apache.rocketmq.store.MessageStore;
-import org.apache.rocketmq.store.PutMessageResult;
-import org.apache.rocketmq.store.config.MessageStoreConfig;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import static org.junit.Assert.assertTrue;
-
-@Ignore
-public class ScheduleMessageTest {
-    private static final String StoreMessage = "Once, there was a chance for me!";
-
-    private static int QUEUE_TOTAL = 100;
-
-    private static AtomicInteger QueueId = new AtomicInteger(0);
-
-    private static SocketAddress BornHost;
-
-    private static SocketAddress StoreHost;
-
-    private static byte[] MessageBody;
-
-    @BeforeClass
-    public static void setUpBeforeClass() throws Exception {
-        StoreHost = new InetSocketAddress(InetAddress.getLocalHost(), 8123);
-        BornHost = new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 0);
-    }
-
-    @AfterClass
-    public static void tearDownAfterClass() throws Exception {
-    }
-
-    @Test
-    public void test_delay_message() throws Exception {
-        System.out.println("================================================================");
-        long totalMsgs = 10000;
-        QUEUE_TOTAL = 32;
-
-        MessageBody = StoreMessage.getBytes();
-
-        MessageStoreConfig messageStoreConfig = new MessageStoreConfig();
-        messageStoreConfig.setMapedFileSizeCommitLog(1024 * 32);
-        messageStoreConfig.setMapedFileSizeConsumeQueue(1024 * 16);
-        messageStoreConfig.setMaxHashSlotNum(100);
-        messageStoreConfig.setMaxIndexNum(1000 * 10);
-
-        MessageStore master = new DefaultMessageStore(messageStoreConfig, null, null, null);
-
-        boolean load = master.load();
-        assertTrue(load);
-
-        master.start();
-        for (int i = 0; i < totalMsgs; i++) {
-            MessageExtBrokerInner msg = buildMessage();
-            msg.setDelayTimeLevel(i % 4);
-
-            PutMessageResult result = master.putMessage(msg);
-            System.out.println(i + "\t" + result.getAppendMessageResult().getMsgId());
-        }
-
-        System.out.println("write message over, wait time up");
-        Thread.sleep(1000 * 20);
-
-        for (long i = 0; i < totalMsgs; i++) {
-            try {
-                GetMessageResult result = master.getMessage("GROUP_A", "TOPIC_A", 0, i, 1024 * 1024, null);
-                if (result == null) {
-                    System.out.println("result == null " + i);
-                }
-                assertTrue(result != null);
-                result.release();
-                System.out.println("read " + i + " OK");
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-
-        }
-
-        Thread.sleep(1000 * 15);
-
-        master.shutdown();
-
-        master.destroy();
-        System.out.println("================================================================");
-    }
-
-    public MessageExtBrokerInner buildMessage() {
-        MessageExtBrokerInner msg = new MessageExtBrokerInner();
-        msg.setTopic("AAA");
-        msg.setTags("TAG1");
-        msg.setKeys("Hello");
-        msg.setBody(MessageBody);
-        msg.setKeys(String.valueOf(System.currentTimeMillis()));
-        msg.setQueueId(Math.abs(QueueId.getAndIncrement()) % QUEUE_TOTAL);
-        msg.setSysFlag(4);
-        msg.setBornTimestamp(System.currentTimeMillis());
-        msg.setStoreHost(StoreHost);
-        msg.setBornHost(BornHost);
-
-        return msg;
-    }
-}


[29/31] incubator-rocketmq git commit: [ROCKETMQ-54] Polish unit test for nameserver

Posted by st...@apache.org.
[ROCKETMQ-54] Polish unit test for nameserver


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/09439f7e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/09439f7e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/09439f7e

Branch: refs/heads/ROCKETMQ-54
Commit: 09439f7ef3cc8b36e0a438f66a8b158184ce6a31
Parents: b8ee0fb
Author: stevenschew <st...@apache.org>
Authored: Sun Jan 22 18:07:27 2017 +0800
Committer: stevenschew <st...@apache.org>
Committed: Sun Jan 22 18:07:27 2017 +0800

----------------------------------------------------------------------
 .../java/org/apache/rocketmq/namesrv/NamesrvControllerTest.java  | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/09439f7e/namesrv/src/test/java/org/apache/rocketmq/namesrv/NamesrvControllerTest.java
----------------------------------------------------------------------
diff --git a/namesrv/src/test/java/org/apache/rocketmq/namesrv/NamesrvControllerTest.java b/namesrv/src/test/java/org/apache/rocketmq/namesrv/NamesrvControllerTest.java
index 215d051..2c1807a 100644
--- a/namesrv/src/test/java/org/apache/rocketmq/namesrv/NamesrvControllerTest.java
+++ b/namesrv/src/test/java/org/apache/rocketmq/namesrv/NamesrvControllerTest.java
@@ -23,7 +23,7 @@ import org.junit.Test;
 import static org.assertj.core.api.Assertions.assertThat;
 
 public class NamesrvControllerTest {
-    private final int RESTART_NUM = 2;
+    private final static int RESTARTNUM = 2;
 
     /**
      * Tests if the controller can be properly stopped and started.
@@ -32,7 +32,7 @@ public class NamesrvControllerTest {
      */
     @Test
     public void testRestart() throws Exception {
-        for (int i = 0; i < RESTART_NUM; i++) {
+        for (int i = 0; i < RESTARTNUM; i++) {
             NamesrvController namesrvController = new NamesrvController(
                 new NamesrvConfig(),
                 new NettyServerConfig()


[08/31] incubator-rocketmq git commit: [RocketMQ-58] Add integration test for RocketMQ, also thanks @fenglianghfl for this commit, closes apache/incubator-rocketmq#46

Posted by st...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/order/OrderMsgRebalanceIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/order/OrderMsgRebalanceIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/order/OrderMsgRebalanceIT.java
new file mode 100644
index 0000000..57b69d2
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/order/OrderMsgRebalanceIT.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.order;
+
+import java.util.List;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.order.RMQOrderListener;
+import org.apache.rocketmq.test.message.MessageQueueMsg;
+import org.apache.rocketmq.test.util.MQWait;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class OrderMsgRebalanceIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(OrderMsgRebalanceIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s !", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testTwoConsumersBalance() {
+        int msgSize = 10;
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic, "*", new RMQOrderListener());
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQOrderListener());
+        TestUtils.waitForSeconds(waitTime);
+
+        List<MessageQueue> mqs = producer.getMessageQueue();
+        MessageQueueMsg mqMsgs = new MessageQueueMsg(mqs, msgSize);
+        producer.send(mqMsgs.getMsgsWithMQ());
+
+        boolean recvAll = MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(),
+            consumer1.getListner(), consumer2.getListner());
+        assertThat(recvAll).isEqualTo(true);
+
+        boolean balance = VerifyUtils.verifyBalance(producer.getAllMsgBody().size(),
+            VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+                consumer1.getListner().getAllUndupMsgBody()).size(),
+            VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+                consumer2.getListner().getAllUndupMsgBody()).size());
+        assertThat(balance).isEqualTo(true);
+
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer1.getListner()).getMsgs()))
+            .isEqualTo(true);
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer2.getListner()).getMsgs()))
+            .isEqualTo(true);
+    }
+
+    @Test
+    public void testFourConsuemrBalance() {
+        int msgSize = 20;
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic, "*", new RMQOrderListener());
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQOrderListener());
+        RMQNormalConsumer consumer3 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQOrderListener());
+        RMQNormalConsumer consumer4 = getConsumer(nsAddr, consumer1.getConsumerGroup(), topic,
+            "*", new RMQOrderListener());
+        TestUtils.waitForSeconds(waitTime);
+
+        List<MessageQueue> mqs = producer.getMessageQueue();
+        MessageQueueMsg mqMsgs = new MessageQueueMsg(mqs, msgSize);
+        producer.send(mqMsgs.getMsgsWithMQ());
+
+        boolean recvAll = MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(),
+            consumer1.getListner(), consumer2.getListner(), consumer3.getListner(),
+            consumer4.getListner());
+        assertThat(recvAll).isEqualTo(true);
+
+        boolean balance = VerifyUtils
+            .verifyBalance(producer.getAllMsgBody().size(),
+                VerifyUtils
+                    .getFilterdMessage(producer.getAllMsgBody(),
+                        consumer1.getListner().getAllUndupMsgBody())
+                    .size(),
+                VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+                    consumer2.getListner().getAllUndupMsgBody()).size(),
+                VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+                    consumer3.getListner().getAllUndupMsgBody()).size(),
+                VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+                    consumer4.getListner().getAllUndupMsgBody()).size());
+        logger.info(String.format("consumer1:%s;consumer2:%s;consumer3:%s,consumer4:%s",
+            consumer1.getListner().getAllMsgBody().size(),
+            consumer2.getListner().getAllMsgBody().size(),
+            consumer3.getListner().getAllMsgBody().size(),
+            consumer4.getListner().getAllMsgBody().size()));
+        assertThat(balance).isEqualTo(true);
+
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer1.getListner()).getMsgs()))
+            .isEqualTo(true);
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer2.getListner()).getMsgs()))
+            .isEqualTo(true);
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer3.getListner()).getMsgs()))
+            .isEqualTo(true);
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer4.getListner()).getMsgs()))
+            .isEqualTo(true);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/order/OrderMsgWithTagIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/order/OrderMsgWithTagIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/order/OrderMsgWithTagIT.java
new file mode 100644
index 0000000..7db77de
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/order/OrderMsgWithTagIT.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.order;
+
+import java.util.List;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.order.RMQOrderListener;
+import org.apache.rocketmq.test.message.MessageQueueMsg;
+import org.apache.rocketmq.test.util.MQWait;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class OrderMsgWithTagIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(OrderMsgIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s;", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        shutDown();
+    }
+
+    @Test
+    public void testOrderMsgWithTagSubAll() {
+        int msgSize = 10;
+        String tag = "jueyin_tag";
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, "*", new RMQOrderListener());
+
+        List<MessageQueue> mqs = producer.getMessageQueue();
+        MessageQueueMsg mqMsgs = new MessageQueueMsg(mqs, msgSize, tag);
+        producer.send(mqMsgs.getMsgsWithMQ());
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(mqMsgs.getMsgBodys());
+
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer.getListner()).getMsgs()))
+            .isEqualTo(true);
+    }
+
+    @Test
+    public void testOrderMsgWithTagSubTag() {
+        int msgSize = 5;
+        String tag = "jueyin_tag";
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, tag, new RMQOrderListener());
+
+        List<MessageQueue> mqs = producer.getMessageQueue();
+        MessageQueueMsg mqMsgs = new MessageQueueMsg(mqs, msgSize, tag);
+        producer.send(mqMsgs.getMsgsWithMQ());
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(mqMsgs.getMsgBodys());
+
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer.getListner()).getMsgs()))
+            .isEqualTo(true);
+    }
+
+    @Test
+    public void testOrderMsgWithTag1AndTag2SubTag1() {
+        int msgSize = 5;
+        String tag1 = "jueyin_tag_1";
+        String tag2 = "jueyin_tag_2";
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic, tag1, new RMQOrderListener());
+
+        List<MessageQueue> mqs = producer.getMessageQueue();
+
+        MessageQueueMsg mqMsgs = new MessageQueueMsg(mqs, msgSize, tag2);
+        producer.send(mqMsgs.getMsgsWithMQ());
+        producer.clearMsg();
+
+        mqMsgs = new MessageQueueMsg(mqs, msgSize, tag1);
+        producer.send(mqMsgs.getMsgsWithMQ());
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(mqMsgs.getMsgBodys());
+
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer.getListner()).getMsgs()))
+            .isEqualTo(true);
+    }
+
+    @Test
+    public void testTwoConsumerSubTag() {
+        int msgSize = 10;
+        String tag1 = "jueyin_tag_1";
+        String tag2 = "jueyin_tag_2";
+        RMQNormalConsumer consumer1 = getConsumer(nsAddr, topic, tag1,
+            new RMQOrderListener("consumer1"));
+        RMQNormalConsumer consumer2 = getConsumer(nsAddr, topic, tag2,
+            new RMQOrderListener("consumer2"));
+        List<MessageQueue> mqs = producer.getMessageQueue();
+
+        MessageQueueMsg mqMsgs = new MessageQueueMsg(mqs, msgSize, tag1);
+        producer.send(mqMsgs.getMsgsWithMQ());
+
+        mqMsgs = new MessageQueueMsg(mqs, msgSize, tag2);
+        producer.send(mqMsgs.getMsgsWithMQ());
+
+        boolean recvAll = MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(),
+            consumer1.getListner(), consumer2.getListner());
+        assertThat(recvAll).isEqualTo(true);
+
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer1.getListner()).getMsgs()))
+            .isEqualTo(true);
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer2.getListner()).getMsgs()))
+            .isEqualTo(true);
+    }
+
+    @Test
+    public void testConsumeTwoTag() {
+        int msgSize = 10;
+        String tag1 = "jueyin_tag_1";
+        String tag2 = "jueyin_tag_2";
+        RMQNormalConsumer consumer = getConsumer(nsAddr, topic,
+            String.format("%s||%s", tag1, tag2), new RMQOrderListener());
+
+        List<MessageQueue> mqs = producer.getMessageQueue();
+
+        MessageQueueMsg mqMsgs = new MessageQueueMsg(mqs, msgSize, tag1);
+        producer.send(mqMsgs.getMsgsWithMQ());
+
+        mqMsgs = new MessageQueueMsg(mqs, msgSize, tag2);
+        producer.send(mqMsgs.getMsgsWithMQ());
+
+        boolean recvAll = MQWait.waitConsumeAll(consumeTime, producer.getAllMsgBody(),
+            consumer.getListner());
+        assertThat(recvAll).isEqualTo(true);
+
+        assertThat(VerifyUtils.verifyOrder(((RMQOrderListener) consumer.getListner()).getMsgs()))
+            .isEqualTo(true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/querymsg/QueryMsgByIdExceptionIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/querymsg/QueryMsgByIdExceptionIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/querymsg/QueryMsgByIdExceptionIT.java
new file mode 100644
index 0000000..a1520a0
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/querymsg/QueryMsgByIdExceptionIT.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.querymsg;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class QueryMsgByIdExceptionIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(QueryMsgByKeyIT.class);
+    private static RMQNormalProducer producer = null;
+    private static String topic = null;
+
+    @BeforeClass
+    public static void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s;", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @AfterClass
+    public static void tearDown() {
+        shutDown();
+    }
+
+    @Test
+    public void testQueryMsgByErrorMsgId() {
+        producer.clearMsg();
+        int msgSize = 20;
+        String errorMsgId = "errorMsgId";
+        producer.send(msgSize);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+
+        MessageExt queryMsg = null;
+        try {
+            queryMsg = producer.getProducer().viewMessage(errorMsgId);
+        } catch (Exception e) {
+        }
+
+        assertThat(queryMsg).isNull();
+    }
+
+    @Test
+    public void testQueryMsgByNullMsgId() {
+        producer.clearMsg();
+        int msgSize = 20;
+        String errorMsgId = null;
+        producer.send(msgSize);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+
+        MessageExt queryMsg = null;
+        try {
+            queryMsg = producer.getProducer().viewMessage(errorMsgId);
+        } catch (Exception e) {
+        }
+
+        assertThat(queryMsg).isNull();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/querymsg/QueryMsgByIdIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/querymsg/QueryMsgByIdIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/querymsg/QueryMsgByIdIT.java
new file mode 100644
index 0000000..92c40c7
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/querymsg/QueryMsgByIdIT.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.querymsg;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.common.message.MessageClientExt;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class QueryMsgByIdIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(QueryMsgByIdIT.class);
+    private RMQNormalProducer producer = null;
+    private RMQNormalConsumer consumer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s;", topic));
+        producer = getProducer(nsAddr, topic);
+        consumer = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+    }
+
+    @After
+    public void tearDown() {
+        shutDown();
+    }
+
+    @Test
+    public void testQueryMsg() {
+        int msgSize = 20;
+        producer.send(msgSize);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        Assert.assertEquals("Not all are consumed", 0, VerifyUtils.verify(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()));
+
+        MessageExt recvMsg = (MessageExt) consumer.getListner().getFirstMsg();
+        MessageExt queryMsg = null;
+        try {
+            TestUtils.waitForMonment(3000);
+            queryMsg = producer.getProducer().viewMessage(((MessageClientExt) recvMsg).getOffsetMsgId());
+        } catch (Exception e) {
+        }
+
+        assertThat(queryMsg).isNotNull();
+        assertThat(new String(queryMsg.getBody())).isEqualTo(new String(recvMsg.getBody()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/client/producer/querymsg/QueryMsgByKeyIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/client/producer/querymsg/QueryMsgByKeyIT.java b/test/src/test/java/org/apache/rocketmq/test/client/producer/querymsg/QueryMsgByKeyIT.java
new file mode 100644
index 0000000..ec45a29
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/client/producer/querymsg/QueryMsgByKeyIT.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.client.producer.querymsg;
+
+import java.util.List;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.factory.MQMessageFactory;
+import org.apache.rocketmq.test.util.TestUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class QueryMsgByKeyIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(QueryMsgByKeyIT.class);
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s;", topic));
+        producer = getProducer(nsAddr, topic);
+    }
+
+    @After
+    public void tearDown() {
+        shutDown();
+    }
+
+    @Test
+    public void testQueryMsg() {
+        int msgSize = 20;
+        String key = "jueyin";
+        long begin = System.currentTimeMillis();
+        List<Object> msgs = MQMessageFactory.getKeyMsg(topic, key, msgSize);
+        producer.send(msgs);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+
+        List<MessageExt> queryMsgs = null;
+        try {
+            TestUtils.waitForMonment(500 * 3);
+            queryMsgs = producer.getProducer().queryMessage(topic, key, msgSize, begin - 5000,
+                System.currentTimeMillis() + 5000).getMessageList();
+        } catch (Exception e) {
+        }
+
+        assertThat(queryMsgs).isNotNull();
+        assertThat(queryMsgs.size()).isEqualTo(msgSize);
+    }
+
+    @Test
+    public void testQueryMax() {
+        int msgSize = 500;
+        int max = 64 * brokerNum;
+        String key = "jueyin";
+        long begin = System.currentTimeMillis();
+        List<Object> msgs = MQMessageFactory.getKeyMsg(topic, key, msgSize);
+        producer.send(msgs);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+
+        List<MessageExt> queryMsgs = null;
+        try {
+            queryMsgs = producer.getProducer().queryMessage(topic, key, msgSize, begin - 15000,
+                System.currentTimeMillis() + 15000).getMessageList();
+
+            int i = 3;
+            while (queryMsgs == null || queryMsgs.size() != brokerNum) {
+                i--;
+                queryMsgs = producer.getProducer().queryMessage(topic, key, msgSize, begin - 15000,
+                    System.currentTimeMillis() + 15000).getMessageList();
+                TestUtils.waitForMonment(1000);
+
+                if (i == 0 || (queryMsgs != null && queryMsgs.size() == max)) {
+                    break;
+                }
+            }
+        } catch (Exception e) {
+        }
+
+        assertThat(queryMsgs).isNotNull();
+        assertThat(queryMsgs.size()).isEqualTo(max);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/delay/DelayConf.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/delay/DelayConf.java b/test/src/test/java/org/apache/rocketmq/test/delay/DelayConf.java
new file mode 100644
index 0000000..6c23473
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/delay/DelayConf.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.delay;
+
+import org.apache.rocketmq.test.base.BaseConf;
+
+public class DelayConf extends BaseConf {
+    protected static final int[] DELAY_LEVEL = {
+        1, 5, 10, 30, 1 * 60, 5 * 60, 10 * 60,
+        30 * 60, 1 * 3600, 2 * 3600, 6 * 3600, 12 * 3600, 1 * 24 * 3600};
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/delay/NormalMsgDelayIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/delay/NormalMsgDelayIT.java b/test/src/test/java/org/apache/rocketmq/test/delay/NormalMsgDelayIT.java
new file mode 100644
index 0000000..5206dcb
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/delay/NormalMsgDelayIT.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.delay;
+
+import java.util.List;
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.client.consumer.balance.NormalMsgStaticBalanceIT;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.factory.MQMessageFactory;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQDelayListner;
+import org.apache.rocketmq.test.listener.rmq.order.RMQOrderListener;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class NormalMsgDelayIT extends DelayConf {
+    private static Logger logger = Logger.getLogger(NormalMsgStaticBalanceIT.class);
+    protected int msgSize = 100;
+    private RMQNormalProducer producer = null;
+    private RMQNormalConsumer consumer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s;", topic));
+        producer = getProducer(nsAddr, topic);
+        consumer = getConsumer(nsAddr, topic, "*", new RMQOrderListener());
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testDelayLevell() {
+        int delayLevel = 1;
+        List<Object> delayMsgs = MQMessageFactory.getDelayMsg(topic, delayLevel, msgSize);
+        producer.send(delayMsgs);
+        Assert.assertEquals("Not all sent succeeded", msgSize, producer.getAllUndupMsgBody().size());
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        Assert.assertEquals("Not all are consumed", 0, VerifyUtils.verify(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()));
+        Assert.assertEquals("Timer is not correct", true,
+            VerifyUtils.verifyDelay(DELAY_LEVEL[delayLevel - 1] * 1000,
+                ((RMQDelayListner) consumer.getListner()).getMsgDelayTimes()));
+    }
+
+    @Test
+    public void testDelayLevel2() {
+        int delayLevel = 2;
+        List<Object> delayMsgs = MQMessageFactory.getDelayMsg(topic, delayLevel, msgSize);
+        producer.send(delayMsgs);
+        Assert.assertEquals("Not all sent succeeded", msgSize, producer.getAllUndupMsgBody().size());
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(),
+            DELAY_LEVEL[delayLevel - 1] * 1000 * 2);
+        Assert.assertEquals("Not all are consumed", 0, VerifyUtils.verify(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()));
+        Assert.assertEquals("Timer is not correct", true,
+            VerifyUtils.verifyDelay(DELAY_LEVEL[delayLevel - 1] * 1000,
+                ((RMQDelayListner) consumer.getListner()).getMsgDelayTimes()));
+    }
+
+    @Test
+    public void testDelayLevel3() {
+        int delayLevel = 3;
+        List<Object> delayMsgs = MQMessageFactory.getDelayMsg(topic, delayLevel, msgSize);
+        producer.send(delayMsgs);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(),
+            DELAY_LEVEL[delayLevel - 1] * 1000 * 2);
+        Assert.assertEquals("Not all are consumed", 0, VerifyUtils.verify(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()));
+        Assert.assertEquals("Timer is not correct", true,
+            VerifyUtils.verifyDelay(DELAY_LEVEL[delayLevel - 1] * 1000,
+                ((RMQDelayListner) consumer.getListner()).getMsgDelayTimes()));
+    }
+
+    @Test
+    public void testDelayLevel4() {
+        int delayLevel = 4;
+        List<Object> delayMsgs = MQMessageFactory.getDelayMsg(topic, delayLevel, msgSize);
+        producer.send(delayMsgs);
+        Assert.assertEquals("Not all are sent", msgSize, producer.getAllUndupMsgBody().size());
+
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(),
+            DELAY_LEVEL[delayLevel - 1] * 1000 * 2);
+        Assert.assertEquals("Not all are consumed", 0, VerifyUtils.verify(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()));
+        Assert.assertEquals("Timer is not correct", true,
+            VerifyUtils.verifyDelay(DELAY_LEVEL[delayLevel - 1] * 1000,
+                ((RMQDelayListner) consumer.getListner()).getMsgDelayTimes()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/java/org/apache/rocketmq/test/smoke/NormalMessageSendAndRecvIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/rocketmq/test/smoke/NormalMessageSendAndRecvIT.java b/test/src/test/java/org/apache/rocketmq/test/smoke/NormalMessageSendAndRecvIT.java
new file mode 100644
index 0000000..c422501
--- /dev/null
+++ b/test/src/test/java/org/apache/rocketmq/test/smoke/NormalMessageSendAndRecvIT.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.test.smoke;
+
+import org.apache.log4j.Logger;
+import org.apache.rocketmq.test.base.BaseConf;
+import org.apache.rocketmq.test.client.rmq.RMQNormalConsumer;
+import org.apache.rocketmq.test.client.rmq.RMQNormalProducer;
+import org.apache.rocketmq.test.listener.rmq.concurrent.RMQNormalListner;
+import org.apache.rocketmq.test.util.VerifyUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class NormalMessageSendAndRecvIT extends BaseConf {
+    private static Logger logger = Logger.getLogger(NormalMessageSendAndRecvIT.class);
+    private RMQNormalConsumer consumer = null;
+    private RMQNormalProducer producer = null;
+    private String topic = null;
+
+    @Before
+    public void setUp() {
+        topic = initTopic();
+        logger.info(String.format("use topic: %s;", topic));
+        producer = getProducer(nsAddr, topic);
+        consumer = getConsumer(nsAddr, topic, "*", new RMQNormalListner());
+    }
+
+    @After
+    public void tearDown() {
+        super.shutDown();
+    }
+
+    @Test
+    public void testSynSendMessage() {
+        int msgSize = 10;
+        producer.send(msgSize);
+        Assert.assertEquals("Not all sent succeeded", msgSize, producer.getAllUndupMsgBody().size());
+        consumer.getListner().waitForMessageConsume(producer.getAllMsgBody(), consumeTime);
+        assertThat(VerifyUtils.getFilterdMessage(producer.getAllMsgBody(),
+            consumer.getListner().getAllMsgBody()))
+            .containsExactlyElementsIn(producer.getAllMsgBody());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/resources/log4j.xml
----------------------------------------------------------------------
diff --git a/test/src/test/resources/log4j.xml b/test/src/test/resources/log4j.xml
new file mode 100644
index 0000000..3031095
--- /dev/null
+++ b/test/src/test/resources/log4j.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You 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.
+  -->
+
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+        <layout class="org.apache.log4j.PatternLayout">
+            <param name="ConversionPattern" value="%d %p [%F %M %L]: %m%n"/>
+        </layout>
+        <filter class="org.apache.log4j.varia.LevelRangeFilter">
+            <param name="LevelMax" value="ERROR"/>
+            <param name="LevelMin" value="TRACE"/>
+        </filter>
+    </appender>
+
+    <appender name="TOTAL" class="org.apache.log4j.RollingFileAppender">
+        <param name="File" value="it_test.log"/>
+        <param name="append" value="false"/>
+        <param name="MaxFileSize" value="10240000"/>
+        <param name="MaxBackupIndex" value="10"/>
+        <layout class="org.apache.log4j.PatternLayout">
+            <param name="ConversionPattern" value="%d - %c -%-4r [%t] %-5p %x - %m%n"/>
+        </layout>
+    </appender>
+
+    <root>
+        <level value="OFF"/>
+        <appender-ref ref="TOTAL"/>
+    </root>
+</log4j:configuration>

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/788771a8/test/src/test/resources/logback-test.xml
----------------------------------------------------------------------
diff --git a/test/src/test/resources/logback-test.xml b/test/src/test/resources/logback-test.xml
new file mode 100644
index 0000000..eb12a9a
--- /dev/null
+++ b/test/src/test/resources/logback-test.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You 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.
+  -->
+
+<configuration>
+
+    <appender name="DefaultAppender" class="ch.qos.logback.core.ConsoleAppender">
+        <append>true</append>
+        <encoder>
+            <pattern>%d{yyy-MM-dd HH\:mm\:ss,GMT+8} %p %t - %m%n</pattern>
+            <charset class="java.nio.charset.Charset">UTF-8</charset>
+        </encoder>
+    </appender>
+
+    <root>
+        <level value="OFF"/>
+        <appender-ref ref="DefaultAppender"/>
+    </root>
+</configuration>



[24/31] incubator-rocketmq git commit: [ROCKETMQ-54] Add unit tests for rocketmq-namesrv

Posted by st...@apache.org.
[ROCKETMQ-54] Add unit tests for rocketmq-namesrv


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/e447bd01
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/e447bd01
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/e447bd01

Branch: refs/heads/ROCKETMQ-54
Commit: e447bd01759da37cff2358ded09d8349e143c818
Parents: 11ff542
Author: stevenschew <st...@apache.org>
Authored: Sun Jan 22 15:04:32 2017 +0800
Committer: yukon <yu...@apache.org>
Committed: Sun Jan 22 15:09:30 2017 +0800

----------------------------------------------------------------------
 .../namesrv/NameServerInstanceTest.java         |  47 +++++++++
 .../rocketmq/namesrv/NamesrvControllerTest.java |  47 +++++++++
 .../namesrv/kvconfig/KVConfigManagerTest.java   |  54 ++++++++++
 .../kvconfig/KVConfigSerializeWrapperTest.java  |  53 ++++++++++
 .../processor/DefaultRequestProcessorTest.java  |  19 ++--
 .../namesrv/routeinfo/RouteInfoManagerTest.java | 103 +++++++++++++++++++
 6 files changed, 313 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/e447bd01/namesrv/src/test/java/org/apache/rocketmq/namesrv/NameServerInstanceTest.java
----------------------------------------------------------------------
diff --git a/namesrv/src/test/java/org/apache/rocketmq/namesrv/NameServerInstanceTest.java b/namesrv/src/test/java/org/apache/rocketmq/namesrv/NameServerInstanceTest.java
new file mode 100644
index 0000000..83ab103
--- /dev/null
+++ b/namesrv/src/test/java/org/apache/rocketmq/namesrv/NameServerInstanceTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.namesrv;
+
+import org.apache.rocketmq.common.namesrv.NamesrvConfig;
+import org.apache.rocketmq.remoting.netty.NettyServerConfig;
+import org.junit.After;
+import org.junit.Before;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class NameServerInstanceTest {
+    protected NamesrvController nameSrvController = null;
+    protected NettyServerConfig nettyServerConfig = new NettyServerConfig();
+    protected NamesrvConfig namesrvConfig = new NamesrvConfig();
+
+    @Before
+    public void startup() throws Exception {
+        nettyServerConfig.setListenPort(9876);
+        nameSrvController = new NamesrvController(namesrvConfig, nettyServerConfig);
+        boolean initResult = nameSrvController.initialize();
+        assertThat(initResult).isTrue();
+        nameSrvController.start();
+    }
+
+    @After
+    public void shutdown() throws Exception {
+        if (nameSrvController != null) {
+            nameSrvController.shutdown();
+        }
+        //maybe need to clean the file store. But we do not suggest deleting anything.
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/e447bd01/namesrv/src/test/java/org/apache/rocketmq/namesrv/NamesrvControllerTest.java
----------------------------------------------------------------------
diff --git a/namesrv/src/test/java/org/apache/rocketmq/namesrv/NamesrvControllerTest.java b/namesrv/src/test/java/org/apache/rocketmq/namesrv/NamesrvControllerTest.java
new file mode 100644
index 0000000..215d051
--- /dev/null
+++ b/namesrv/src/test/java/org/apache/rocketmq/namesrv/NamesrvControllerTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.namesrv;
+
+import org.apache.rocketmq.common.namesrv.NamesrvConfig;
+import org.apache.rocketmq.remoting.netty.NettyServerConfig;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class NamesrvControllerTest {
+    private final int RESTART_NUM = 2;
+
+    /**
+     * Tests if the controller can be properly stopped and started.
+     *
+     * @throws Exception If fails.
+     */
+    @Test
+    public void testRestart() throws Exception {
+        for (int i = 0; i < RESTART_NUM; i++) {
+            NamesrvController namesrvController = new NamesrvController(
+                new NamesrvConfig(),
+                new NettyServerConfig()
+            );
+            boolean initResult = namesrvController.initialize();
+            assertThat(initResult).isEqualTo(true);
+            namesrvController.start();
+            namesrvController.shutdown();
+        }
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/e447bd01/namesrv/src/test/java/org/apache/rocketmq/namesrv/kvconfig/KVConfigManagerTest.java
----------------------------------------------------------------------
diff --git a/namesrv/src/test/java/org/apache/rocketmq/namesrv/kvconfig/KVConfigManagerTest.java b/namesrv/src/test/java/org/apache/rocketmq/namesrv/kvconfig/KVConfigManagerTest.java
new file mode 100644
index 0000000..8efa536
--- /dev/null
+++ b/namesrv/src/test/java/org/apache/rocketmq/namesrv/kvconfig/KVConfigManagerTest.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.namesrv.kvconfig;
+
+import org.apache.rocketmq.common.namesrv.NamesrvUtil;
+import org.apache.rocketmq.namesrv.NameServerInstanceTest;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class KVConfigManagerTest extends NameServerInstanceTest {
+    private KVConfigManager kvConfigManager;
+
+    @Before
+    public void setup() throws Exception {
+        kvConfigManager = new KVConfigManager(nameSrvController);
+    }
+
+    @Test
+    public void testPutKVConfig() {
+        kvConfigManager.load();
+        kvConfigManager.putKVConfig(NamesrvUtil.NAMESPACE_ORDER_TOPIC_CONFIG, "UnitTest", "test");
+        byte[] kvConfig = kvConfigManager.getKVListByNamespace(NamesrvUtil.NAMESPACE_ORDER_TOPIC_CONFIG);
+        assertThat(kvConfig).isNotNull();
+        String value = kvConfigManager.getKVConfig(NamesrvUtil.NAMESPACE_ORDER_TOPIC_CONFIG, "UnitTest");
+        assertThat(value).isEqualTo("test");
+    }
+
+    @Test
+    public void testDeleteKVConfig() {
+        kvConfigManager.deleteKVConfig(NamesrvUtil.NAMESPACE_ORDER_TOPIC_CONFIG, "UnitTest");
+        byte[] kvConfig = kvConfigManager.getKVListByNamespace(NamesrvUtil.NAMESPACE_ORDER_TOPIC_CONFIG);
+        assertThat(kvConfig).isNull();
+        Assert.assertTrue(kvConfig == null);
+        String value = kvConfigManager.getKVConfig(NamesrvUtil.NAMESPACE_ORDER_TOPIC_CONFIG, "UnitTest");
+        assertThat(value).isNull();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/e447bd01/namesrv/src/test/java/org/apache/rocketmq/namesrv/kvconfig/KVConfigSerializeWrapperTest.java
----------------------------------------------------------------------
diff --git a/namesrv/src/test/java/org/apache/rocketmq/namesrv/kvconfig/KVConfigSerializeWrapperTest.java b/namesrv/src/test/java/org/apache/rocketmq/namesrv/kvconfig/KVConfigSerializeWrapperTest.java
new file mode 100644
index 0000000..a24d86d
--- /dev/null
+++ b/namesrv/src/test/java/org/apache/rocketmq/namesrv/kvconfig/KVConfigSerializeWrapperTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.namesrv.kvconfig;
+
+import java.util.HashMap;
+import org.apache.rocketmq.common.namesrv.NamesrvUtil;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class KVConfigSerializeWrapperTest {
+    private KVConfigSerializeWrapper kvConfigSerializeWrapper;
+
+    @Before
+    public void setup() throws Exception {
+        kvConfigSerializeWrapper = new KVConfigSerializeWrapper();
+    }
+
+    @Test
+    public void testEncodeAndDecode() {
+        HashMap<String, HashMap<String, String>> result = new HashMap<>();
+        HashMap<String, String> kvs = new HashMap<>();
+        kvs.put("broker-name", "default-broker");
+        kvs.put("topic-name", "default-topic");
+        kvs.put("cid", "default-consumer-name");
+        result.put(NamesrvUtil.NAMESPACE_ORDER_TOPIC_CONFIG, kvs);
+        kvConfigSerializeWrapper.setConfigTable(result);
+        byte[] serializeByte = KVConfigSerializeWrapper.encode(kvConfigSerializeWrapper);
+        assertThat(serializeByte).isNotNull();
+
+        KVConfigSerializeWrapper deserializeObject = KVConfigSerializeWrapper.decode(serializeByte, KVConfigSerializeWrapper.class);
+        assertThat(deserializeObject.getConfigTable()).containsKey(NamesrvUtil.NAMESPACE_ORDER_TOPIC_CONFIG);
+        assertThat(deserializeObject.getConfigTable().get(NamesrvUtil.NAMESPACE_ORDER_TOPIC_CONFIG).get("broker-name")).isEqualTo("default-broker");
+        assertThat(deserializeObject.getConfigTable().get(NamesrvUtil.NAMESPACE_ORDER_TOPIC_CONFIG).get("topic-name")).isEqualTo("default-topic");
+        assertThat(deserializeObject.getConfigTable().get(NamesrvUtil.NAMESPACE_ORDER_TOPIC_CONFIG).get("cid")).isEqualTo("default-consumer-name");
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/e447bd01/namesrv/src/test/java/org/apache/rocketmq/namesrv/processor/DefaultRequestProcessorTest.java
----------------------------------------------------------------------
diff --git a/namesrv/src/test/java/org/apache/rocketmq/namesrv/processor/DefaultRequestProcessorTest.java b/namesrv/src/test/java/org/apache/rocketmq/namesrv/processor/DefaultRequestProcessorTest.java
index 861e284..80d968f 100644
--- a/namesrv/src/test/java/org/apache/rocketmq/namesrv/processor/DefaultRequestProcessorTest.java
+++ b/namesrv/src/test/java/org/apache/rocketmq/namesrv/processor/DefaultRequestProcessorTest.java
@@ -41,19 +41,20 @@ import org.junit.Test;
 import org.slf4j.Logger;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class DefaultRequestProcessorTest {
     /** Test Target */
     private DefaultRequestProcessor defaultRequestProcessor;
 
-    private NamesrvController       namesrvController;
+    private NamesrvController namesrvController;
 
-    private NamesrvConfig           namesrvConfig;
+    private NamesrvConfig namesrvConfig;
 
-    private NettyServerConfig       nettyServerConfig;
+    private NettyServerConfig nettyServerConfig;
 
-    private Logger                  logger;
+    private Logger logger;
 
     @Before
     public void init() throws Exception {
@@ -147,7 +148,7 @@ public class DefaultRequestProcessorTest {
 
     @Test
     public void testProcessRequest_RegisterBroker() throws RemotingCommandException,
-                                                    NoSuchFieldException, IllegalAccessException {
+        NoSuchFieldException, IllegalAccessException {
         RemotingCommand request = genSampleRegisterCmd(true);
 
         ChannelHandlerContext ctx = mock(ChannelHandlerContext.class);
@@ -176,7 +177,7 @@ public class DefaultRequestProcessorTest {
         RemotingCommand request = genSampleRegisterCmd(true);
 
         // version >= MQVersion.Version.V3_0_11.ordinal() to register with filter server
-        request.setVersion(100); 
+        request.setVersion(100);
 
         ChannelHandlerContext ctx = mock(ChannelHandlerContext.class);
         when(ctx.channel()).thenReturn(null);
@@ -218,10 +219,9 @@ public class DefaultRequestProcessorTest {
         Field brokerAddrTable = RouteInfoManager.class.getDeclaredField("brokerAddrTable");
         brokerAddrTable.setAccessible(true);
 
-        assertThat((Map)brokerAddrTable.get(routes)).isEmpty();
+        assertThat((Map) brokerAddrTable.get(routes)).isEmpty();
     }
 
-
     private static RemotingCommand genSampleRegisterCmd(boolean reg) {
         RegisterBrokerRequestHeader header = new RegisterBrokerRequestHeader();
         header.setBrokerName("broker");
@@ -235,7 +235,6 @@ public class DefaultRequestProcessorTest {
         return request;
     }
 
-
     private static void setFinalStatic(Field field, Object newValue) throws Exception {
         field.setAccessible(true);
         Field modifiersField = Field.class.getDeclaredField("modifiers");

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/e447bd01/namesrv/src/test/java/org/apache/rocketmq/namesrv/routeinfo/RouteInfoManagerTest.java
----------------------------------------------------------------------
diff --git a/namesrv/src/test/java/org/apache/rocketmq/namesrv/routeinfo/RouteInfoManagerTest.java b/namesrv/src/test/java/org/apache/rocketmq/namesrv/routeinfo/RouteInfoManagerTest.java
new file mode 100644
index 0000000..cd6c50c
--- /dev/null
+++ b/namesrv/src/test/java/org/apache/rocketmq/namesrv/routeinfo/RouteInfoManagerTest.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.namesrv.routeinfo;
+
+import io.netty.channel.Channel;
+import java.util.ArrayList;
+import org.apache.rocketmq.common.namesrv.RegisterBrokerResult;
+import org.apache.rocketmq.common.protocol.body.TopicConfigSerializeWrapper;
+import org.apache.rocketmq.common.protocol.route.TopicRouteData;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+public class RouteInfoManagerTest {
+
+    private RouteInfoManager routeInfoManager;
+
+    @Before
+    public void setup() {
+        routeInfoManager = new RouteInfoManager();
+    }
+
+    @Test
+    public void testGetAllClusterInfo() {
+        byte[] clusterInfo = routeInfoManager.getAllClusterInfo();
+        assertThat(clusterInfo).isNotNull();
+    }
+
+    @Test
+    public void testGetAllTopicList() {
+        byte[] topicInfo = routeInfoManager.getAllTopicList();
+        Assert.assertTrue(topicInfo != null);
+        assertThat(topicInfo).isNotNull();
+    }
+
+    @Test
+    public void testRegisterBroker() {
+        TopicConfigSerializeWrapper topicConfigSerializeWrapper = mock(TopicConfigSerializeWrapper.class);
+        Channel channel = mock(Channel.class);
+        RegisterBrokerResult registerBrokerResult = routeInfoManager.registerBroker("default-cluster", "127.0.0.1:10911", "default-broker", 1234, "127.0.0.1:1001",
+            topicConfigSerializeWrapper, new ArrayList<String>(), channel);
+        assertThat(registerBrokerResult).isNotNull();
+    }
+
+    @Test
+    public void testWipeWritePermOfBrokerByLock() {
+        int result = routeInfoManager.wipeWritePermOfBrokerByLock("default-broker-name");
+        assertThat(result).isEqualTo(0);
+    }
+
+    @Test
+    public void testPickupTopicRouteData() {
+        TopicRouteData result = routeInfoManager.pickupTopicRouteData("unit_test");
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void testGetSystemTopicList() {
+        byte[] topicList = routeInfoManager.getSystemTopicList();
+        assertThat(topicList).isNotNull();
+    }
+
+    @Test
+    public void testGetTopicsByCluster() {
+        byte[] topicList = routeInfoManager.getTopicsByCluster("default-cluster");
+        assertThat(topicList).isNotNull();
+    }
+
+    @Test
+    public void testGetUnitTopics() {
+        byte[] topicList = routeInfoManager.getUnitTopics();
+        assertThat(topicList).isNotNull();
+    }
+
+    @Test
+    public void testGetHasUnitSubTopicList() {
+        byte[] topicList = routeInfoManager.getHasUnitSubTopicList();
+        assertThat(topicList).isNotNull();
+    }
+
+    @Test
+    public void testGetHasUnitSubUnUnitTopicList() {
+        byte[] topicList = routeInfoManager.getHasUnitSubUnUnitTopicList();
+        assertThat(topicList).isNotNull();
+    }
+}
\ No newline at end of file


[18/31] incubator-rocketmq git commit: [ROCKETMQ-51] Add unit tests for SendMessageProcessor

Posted by st...@apache.org.
[ROCKETMQ-51] Add unit tests for SendMessageProcessor


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/264a0560
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/264a0560
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/264a0560

Branch: refs/heads/ROCKETMQ-54
Commit: 264a05607c088b638fc65ca4074e5ebefbeeb199
Parents: b997c97
Author: yukon <yu...@apache.org>
Authored: Fri Jan 20 10:50:43 2017 +0800
Committer: yukon <yu...@apache.org>
Committed: Sat Jan 21 23:14:06 2017 +0800

----------------------------------------------------------------------
 .../rocketmq/broker/BrokerControllerTest.java   |  20 +-
 .../processor/SendMessageProcessorTest.java     | 200 +++++++++++++++++++
 2 files changed, 205 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/264a0560/broker/src/test/java/org/apache/rocketmq/broker/BrokerControllerTest.java
----------------------------------------------------------------------
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/BrokerControllerTest.java b/broker/src/test/java/org/apache/rocketmq/broker/BrokerControllerTest.java
index 4a19c0c..86b9c4e 100644
--- a/broker/src/test/java/org/apache/rocketmq/broker/BrokerControllerTest.java
+++ b/broker/src/test/java/org/apache/rocketmq/broker/BrokerControllerTest.java
@@ -21,37 +21,27 @@ import org.apache.rocketmq.common.BrokerConfig;
 import org.apache.rocketmq.remoting.netty.NettyClientConfig;
 import org.apache.rocketmq.remoting.netty.NettyServerConfig;
 import org.apache.rocketmq.store.config.MessageStoreConfig;
-import org.junit.Assert;
 import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-public class BrokerControllerTest {
-    private static final int RESTART_NUM = 3;
-    protected Logger logger = LoggerFactory.getLogger(BrokerControllerTest.class);
+import static org.assertj.core.api.Assertions.assertThat;
 
+public class BrokerControllerTest {
     /**
      * Tests if the controller can be properly stopped and started.
      *
      * @throws Exception If fails.
      */
     @Test
-    public void testRestart() throws Exception {
-
-        for (int i = 0; i < RESTART_NUM; i++) {
+    public void testBrokerRestart() throws Exception {
+        for (int i = 0; i < 2; i++) {
             BrokerController brokerController = new BrokerController(//
                 new BrokerConfig(), //
                 new NettyServerConfig(), //
                 new NettyClientConfig(), //
                 new MessageStoreConfig());
-            boolean initResult = brokerController.initialize();
-            Assert.assertTrue(initResult);
-            logger.info("Broker is initialized " + initResult);
+            assertThat(brokerController.initialize());
             brokerController.start();
-            logger.info("Broker is started");
-
             brokerController.shutdown();
-            logger.info("Broker is stopped");
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/264a0560/broker/src/test/java/org/apache/rocketmq/broker/processor/SendMessageProcessorTest.java
----------------------------------------------------------------------
diff --git a/broker/src/test/java/org/apache/rocketmq/broker/processor/SendMessageProcessorTest.java b/broker/src/test/java/org/apache/rocketmq/broker/processor/SendMessageProcessorTest.java
new file mode 100644
index 0000000..d41d03a
--- /dev/null
+++ b/broker/src/test/java/org/apache/rocketmq/broker/processor/SendMessageProcessorTest.java
@@ -0,0 +1,200 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.broker.processor;
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import java.net.InetSocketAddress;
+import org.apache.rocketmq.broker.BrokerController;
+import org.apache.rocketmq.common.BrokerConfig;
+import org.apache.rocketmq.common.MixAll;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.apache.rocketmq.common.protocol.RequestCode;
+import org.apache.rocketmq.common.protocol.ResponseCode;
+import org.apache.rocketmq.common.protocol.header.ConsumerSendMsgBackRequestHeader;
+import org.apache.rocketmq.common.protocol.header.SendMessageRequestHeader;
+import org.apache.rocketmq.remoting.exception.RemotingCommandException;
+import org.apache.rocketmq.remoting.netty.NettyClientConfig;
+import org.apache.rocketmq.remoting.netty.NettyServerConfig;
+import org.apache.rocketmq.remoting.protocol.RemotingCommand;
+import org.apache.rocketmq.store.AppendMessageResult;
+import org.apache.rocketmq.store.AppendMessageStatus;
+import org.apache.rocketmq.store.MessageExtBrokerInner;
+import org.apache.rocketmq.store.MessageStore;
+import org.apache.rocketmq.store.PutMessageResult;
+import org.apache.rocketmq.store.PutMessageStatus;
+import org.apache.rocketmq.store.config.MessageStoreConfig;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.mockito.stubbing.Answer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class SendMessageProcessorTest {
+    private SendMessageProcessor sendMessageProcessor;
+    @Mock
+    private ChannelHandlerContext handlerContext;
+    @Spy
+    private BrokerController brokerController = new BrokerController(new BrokerConfig(), new NettyServerConfig(), new NettyClientConfig(), new MessageStoreConfig());
+    @Mock
+    private MessageStore messageStore;
+
+    @Before
+    public void init() {
+        brokerController.setMessageStore(messageStore);
+        when(messageStore.now()).thenReturn(System.currentTimeMillis());
+        Channel mockChannel = mock(Channel.class);
+        when(mockChannel.remoteAddress()).thenReturn(new InetSocketAddress(1024));
+        when(handlerContext.channel()).thenReturn(mockChannel);
+        when(messageStore.lookMessageByOffset(anyLong())).thenReturn(new MessageExt());
+    }
+
+    @Test
+    public void testProcessRequest() throws RemotingCommandException {
+        when(messageStore.putMessage(any(MessageExtBrokerInner.class))).thenReturn(new PutMessageResult(PutMessageStatus.PUT_OK, new AppendMessageResult(AppendMessageStatus.PUT_OK)));
+        assertPutResult(ResponseCode.SUCCESS);
+    }
+
+
+    @Test
+    public void testProcessRequest_FlushTimeOut() throws RemotingCommandException {
+        when(messageStore.putMessage(any(MessageExtBrokerInner.class))).thenReturn(new PutMessageResult(PutMessageStatus.FLUSH_DISK_TIMEOUT, new AppendMessageResult(AppendMessageStatus.UNKNOWN_ERROR)));
+        assertPutResult(ResponseCode.FLUSH_DISK_TIMEOUT);
+    }
+
+    @Test
+    public void testProcessRequest_MessageIllegal() throws RemotingCommandException {
+        when(messageStore.putMessage(any(MessageExtBrokerInner.class))).thenReturn(new PutMessageResult(PutMessageStatus.MESSAGE_ILLEGAL, new AppendMessageResult(AppendMessageStatus.UNKNOWN_ERROR)));
+        assertPutResult(ResponseCode.MESSAGE_ILLEGAL);
+    }
+
+    @Test
+    public void testProcessRequest_CreateMappedFileFailed() throws RemotingCommandException {
+        when(messageStore.putMessage(any(MessageExtBrokerInner.class))).thenReturn(new PutMessageResult(PutMessageStatus.CREATE_MAPEDFILE_FAILED, new AppendMessageResult(AppendMessageStatus.UNKNOWN_ERROR)));
+        assertPutResult(ResponseCode.SYSTEM_ERROR);
+    }
+
+    @Test
+    public void testProcessRequest_FlushSlaveTimeout() throws RemotingCommandException {
+        when(messageStore.putMessage(any(MessageExtBrokerInner.class))).thenReturn(new PutMessageResult(PutMessageStatus.FLUSH_SLAVE_TIMEOUT, new AppendMessageResult(AppendMessageStatus.UNKNOWN_ERROR)));
+        assertPutResult(ResponseCode.FLUSH_SLAVE_TIMEOUT);
+    }
+
+    @Test
+    public void testProcessRequest_PageCacheBusy() throws RemotingCommandException {
+        when(messageStore.putMessage(any(MessageExtBrokerInner.class))).thenReturn(new PutMessageResult(PutMessageStatus.OS_PAGECACHE_BUSY, new AppendMessageResult(AppendMessageStatus.UNKNOWN_ERROR)));
+        assertPutResult(ResponseCode.SYSTEM_ERROR);
+    }
+
+    @Test
+    public void testProcessRequest_PropertiesTooLong() throws RemotingCommandException {
+        when(messageStore.putMessage(any(MessageExtBrokerInner.class))).thenReturn(new PutMessageResult(PutMessageStatus.PROPERTIES_SIZE_EXCEEDED, new AppendMessageResult(AppendMessageStatus.UNKNOWN_ERROR)));
+        assertPutResult(ResponseCode.MESSAGE_ILLEGAL);
+    }
+
+    @Test
+    public void testProcessRequest_ServiceNotAvailable() throws RemotingCommandException {
+        when(messageStore.putMessage(any(MessageExtBrokerInner.class))).thenReturn(new PutMessageResult(PutMessageStatus.SERVICE_NOT_AVAILABLE, new AppendMessageResult(AppendMessageStatus.UNKNOWN_ERROR)));
+        assertPutResult(ResponseCode.SERVICE_NOT_AVAILABLE);
+    }
+
+    @Test
+    public void testProcessRequest_SlaveNotAvailable() throws RemotingCommandException {
+        when(messageStore.putMessage(any(MessageExtBrokerInner.class))).thenReturn(new PutMessageResult(PutMessageStatus.SLAVE_NOT_AVAILABLE, new AppendMessageResult(AppendMessageStatus.UNKNOWN_ERROR)));
+        assertPutResult(ResponseCode.SLAVE_NOT_AVAILABLE);
+    }
+
+    @Test
+    public void testProcessRequest_WithMsgBack() throws RemotingCommandException {
+        when(messageStore.putMessage(any(MessageExtBrokerInner.class))).thenReturn(new PutMessageResult(PutMessageStatus.PUT_OK, new AppendMessageResult(AppendMessageStatus.PUT_OK)));
+        final RemotingCommand request = createSendMsgBackCommand(RequestCode.CONSUMER_SEND_MSG_BACK);
+
+        sendMessageProcessor = new SendMessageProcessor(brokerController);
+        final RemotingCommand response = sendMessageProcessor.processRequest(handlerContext, request);
+        assertThat(response).isNotNull();
+        assertThat(response.getCode()).isEqualTo(ResponseCode.SUCCESS);
+    }
+
+    private RemotingCommand createSendMsgCommand(int requestCode) {
+        SendMessageRequestHeader requestHeader = new SendMessageRequestHeader();
+        requestHeader.setProducerGroup("FooBar_PID");
+        requestHeader.setTopic("FooBar");
+        requestHeader.setDefaultTopic(MixAll.DEFAULT_TOPIC);
+        requestHeader.setDefaultTopicQueueNums(3);
+        requestHeader.setQueueId(1);
+        requestHeader.setSysFlag(0);
+        requestHeader.setBornTimestamp(System.currentTimeMillis());
+        requestHeader.setFlag(124);
+        requestHeader.setReconsumeTimes(0);
+
+        RemotingCommand request = RemotingCommand.createRequestCommand(requestCode, requestHeader);
+        request.addExtField("queueId", String.valueOf(requestHeader.getQueueId()));
+        request.addExtField("topic", String.valueOf(requestHeader.getTopic()));
+        request.addExtField("defaultTopicQueueNums", String.valueOf(requestHeader.getDefaultTopicQueueNums()));
+        request.addExtField("defaultTopic", requestHeader.getDefaultTopic());
+        request.addExtField("sysFlag", String.valueOf(requestHeader.getSysFlag()));
+        request.addExtField("flag", String.valueOf(requestHeader.getFlag()));
+        request.addExtField("bornTimestamp", String.valueOf(requestHeader.getBornTimestamp()));
+        return request;
+    }
+
+    private RemotingCommand createSendMsgBackCommand(int requestCode) {
+        ConsumerSendMsgBackRequestHeader requestHeader = new ConsumerSendMsgBackRequestHeader();
+
+        requestHeader.setMaxReconsumeTimes(3);
+        requestHeader.setDelayLevel(4);
+        requestHeader.setGroup("FooBar_PID");
+        requestHeader.setOffset(123L);
+
+        RemotingCommand request = RemotingCommand.createRequestCommand(requestCode, requestHeader);
+        request.addExtField("group", requestHeader.getGroup());
+        request.addExtField("offset", String.valueOf(requestHeader.getOffset()));
+        request.addExtField("delayLevel", String.valueOf(requestHeader.getDelayLevel()));
+        return request;
+    }
+
+    private void assertPutResult(int responseCode) throws RemotingCommandException {
+        final RemotingCommand request = createSendMsgCommand(RequestCode.SEND_MESSAGE);
+        final RemotingCommand[] response = new RemotingCommand[1];
+        doAnswer(new Answer() {
+            @Override public Object answer(InvocationOnMock invocation) throws Throwable {
+                response[0] = invocation.getArgument(0);
+                return null;
+            }
+        }).when(handlerContext).writeAndFlush(any(Object.class));
+
+        sendMessageProcessor = new SendMessageProcessor(brokerController);
+        RemotingCommand responseToReturn = sendMessageProcessor.processRequest(handlerContext, request);
+        if (responseToReturn != null) {
+            assertThat(response[0]).isNull();
+            response[0] = responseToReturn;
+        }
+        assertThat(response[0].getCode()).isEqualTo(responseCode);
+        assertThat(response[0].getOpaque()).isEqualTo(request.getOpaque());
+    }
+}
\ No newline at end of file


[23/31] incubator-rocketmq git commit: [ROCKETMQ-45]Delete hanged consume queue files

Posted by st...@apache.org.
[ROCKETMQ-45]Delete hanged consume queue files


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/11ff542c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/11ff542c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/11ff542c

Branch: refs/heads/ROCKETMQ-54
Commit: 11ff542c4382faf3bb7a74a80329f1fcab6a07a6
Parents: d9c398f
Author: Zhanhui Li <li...@apache.org>
Authored: Thu Jan 12 15:02:26 2017 +0800
Committer: Zhanhui Li <li...@apache.org>
Committed: Sun Jan 22 14:48:16 2017 +0800

----------------------------------------------------------------------
 .../org/apache/rocketmq/store/ConsumeQueue.java | 28 +++++------
 .../rocketmq/store/DefaultMessageStore.java     | 14 +++---
 .../org/apache/rocketmq/store/MappedFile.java   | 22 ++++-----
 .../apache/rocketmq/store/MappedFileQueue.java  |  4 ++
 .../store/schedule/ScheduleMessageService.java  |  2 +-
 .../rocketmq/store/MappedFileQueueTest.java     | 50 ++++++++++++++++++--
 6 files changed, 84 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/11ff542c/store/src/main/java/org/apache/rocketmq/store/ConsumeQueue.java
----------------------------------------------------------------------
diff --git a/store/src/main/java/org/apache/rocketmq/store/ConsumeQueue.java b/store/src/main/java/org/apache/rocketmq/store/ConsumeQueue.java
index c5e38db..dc1c96c 100644
--- a/store/src/main/java/org/apache/rocketmq/store/ConsumeQueue.java
+++ b/store/src/main/java/org/apache/rocketmq/store/ConsumeQueue.java
@@ -77,19 +77,19 @@ public class ConsumeQueue {
             if (index < 0)
                 index = 0;
 
-            int mapedFileSizeLogics = this.mappedFileSize;
+            int mappedFileSizeLogics = this.mappedFileSize;
             MappedFile mappedFile = mappedFiles.get(index);
             ByteBuffer byteBuffer = mappedFile.sliceByteBuffer();
             long processOffset = mappedFile.getFileFromOffset();
-            long mapedFileOffset = 0;
+            long mappedFileOffset = 0;
             while (true) {
-                for (int i = 0; i < mapedFileSizeLogics; i += CQ_STORE_UNIT_SIZE) {
+                for (int i = 0; i < mappedFileSizeLogics; i += CQ_STORE_UNIT_SIZE) {
                     long offset = byteBuffer.getLong();
                     int size = byteBuffer.getInt();
                     long tagsCode = byteBuffer.getLong();
 
                     if (offset >= 0 && size > 0) {
-                        mapedFileOffset = i + CQ_STORE_UNIT_SIZE;
+                        mappedFileOffset = i + CQ_STORE_UNIT_SIZE;
                         this.maxPhysicOffset = offset;
                     } else {
                         log.info("recover current consume queue file over,  " + mappedFile.getFileName() + " "
@@ -98,7 +98,7 @@ public class ConsumeQueue {
                     }
                 }
 
-                if (mapedFileOffset == mapedFileSizeLogics) {
+                if (mappedFileOffset == mappedFileSizeLogics) {
                     index++;
                     if (index >= mappedFiles.size()) {
 
@@ -109,17 +109,17 @@ public class ConsumeQueue {
                         mappedFile = mappedFiles.get(index);
                         byteBuffer = mappedFile.sliceByteBuffer();
                         processOffset = mappedFile.getFileFromOffset();
-                        mapedFileOffset = 0;
+                        mappedFileOffset = 0;
                         log.info("recover next consume queue file, " + mappedFile.getFileName());
                     }
                 } else {
                     log.info("recover current consume queue queue over " + mappedFile.getFileName() + " "
-                        + (processOffset + mapedFileOffset));
+                        + (processOffset + mappedFileOffset));
                     break;
                 }
             }
 
-            processOffset += mapedFileOffset;
+            processOffset += mappedFileOffset;
             this.mappedFileQueue.setFlushedWhere(processOffset);
             this.mappedFileQueue.setCommittedWhere(processOffset);
             this.mappedFileQueue.truncateDirtyFiles(processOffset);
@@ -310,7 +310,7 @@ public class ConsumeQueue {
 
                         if (offsetPy >= phyMinOffset) {
                             this.minLogicOffset = result.getMappedFile().getFileFromOffset() + i;
-                            log.info("compute logics min offset: " + this.getMinOffsetInQuque() + ", topic: "
+                            log.info("compute logics min offset: " + this.getMinOffsetInQueue() + ", topic: "
                                 + this.topic + ", queueId: " + this.queueId);
                             break;
                         }
@@ -324,7 +324,7 @@ public class ConsumeQueue {
         }
     }
 
-    public long getMinOffsetInQuque() {
+    public long getMinOffsetInQueue() {
         return this.minLogicOffset / CQ_STORE_UNIT_SIZE;
     }
 
@@ -435,8 +435,8 @@ public class ConsumeQueue {
     }
 
     public long rollNextFile(final long index) {
-        int mapedFileSize = this.mappedFileSize;
-        int totalUnitsInFile = mapedFileSize / CQ_STORE_UNIT_SIZE;
+        int mappedFileSize = this.mappedFileSize;
+        int totalUnitsInFile = mappedFileSize / CQ_STORE_UNIT_SIZE;
         return index + totalUnitsInFile - index % totalUnitsInFile;
     }
 
@@ -463,10 +463,10 @@ public class ConsumeQueue {
     }
 
     public long getMessageTotalInQueue() {
-        return this.getMaxOffsetInQuque() - this.getMinOffsetInQuque();
+        return this.getMaxOffsetInQueue() - this.getMinOffsetInQueue();
     }
 
-    public long getMaxOffsetInQuque() {
+    public long getMaxOffsetInQueue() {
         return this.mappedFileQueue.getMaxOffset() / CQ_STORE_UNIT_SIZE;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/11ff542c/store/src/main/java/org/apache/rocketmq/store/DefaultMessageStore.java
----------------------------------------------------------------------
diff --git a/store/src/main/java/org/apache/rocketmq/store/DefaultMessageStore.java b/store/src/main/java/org/apache/rocketmq/store/DefaultMessageStore.java
index 3a43c21..2594ef3 100644
--- a/store/src/main/java/org/apache/rocketmq/store/DefaultMessageStore.java
+++ b/store/src/main/java/org/apache/rocketmq/store/DefaultMessageStore.java
@@ -376,8 +376,8 @@ public class DefaultMessageStore implements MessageStore {
 
         ConsumeQueue consumeQueue = findConsumeQueue(topic, queueId);
         if (consumeQueue != null) {
-            minOffset = consumeQueue.getMinOffsetInQuque();
-            maxOffset = consumeQueue.getMaxOffsetInQuque();
+            minOffset = consumeQueue.getMinOffsetInQueue();
+            maxOffset = consumeQueue.getMaxOffsetInQueue();
 
             if (maxOffset == 0) {
                 status = GetMessageStatus.NO_MESSAGE_IN_QUEUE;
@@ -499,7 +499,7 @@ public class DefaultMessageStore implements MessageStore {
     public long getMaxOffsetInQuque(String topic, int queueId) {
         ConsumeQueue logic = this.findConsumeQueue(topic, queueId);
         if (logic != null) {
-            long offset = logic.getMaxOffsetInQuque();
+            long offset = logic.getMaxOffsetInQueue();
             return offset;
         }
 
@@ -512,7 +512,7 @@ public class DefaultMessageStore implements MessageStore {
     public long getMinOffsetInQuque(String topic, int queueId) {
         ConsumeQueue logic = this.findConsumeQueue(topic, queueId);
         if (logic != null) {
-            return logic.getMinOffsetInQuque();
+            return logic.getMinOffsetInQueue();
         }
 
         return -1;
@@ -878,8 +878,8 @@ public class DefaultMessageStore implements MessageStore {
 
         ConsumeQueue consumeQueue = findConsumeQueue(topic, queueId);
         if (consumeQueue != null) {
-            minOffset = Math.max(minOffset, consumeQueue.getMinOffsetInQuque());
-            maxOffset = Math.min(maxOffset, consumeQueue.getMaxOffsetInQuque());
+            minOffset = Math.max(minOffset, consumeQueue.getMinOffsetInQueue());
+            maxOffset = Math.min(maxOffset, consumeQueue.getMaxOffsetInQueue());
 
             if (maxOffset == 0) {
                 return messageIds;
@@ -1220,7 +1220,7 @@ public class DefaultMessageStore implements MessageStore {
         for (ConcurrentHashMap<Integer, ConsumeQueue> maps : this.consumeQueueTable.values()) {
             for (ConsumeQueue logic : maps.values()) {
                 String key = logic.getTopic() + "-" + logic.getQueueId();
-                table.put(key, logic.getMaxOffsetInQuque());
+                table.put(key, logic.getMaxOffsetInQueue());
                 logic.correctMinOffset(minPhyOffset);
             }
         }

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/11ff542c/store/src/main/java/org/apache/rocketmq/store/MappedFile.java
----------------------------------------------------------------------
diff --git a/store/src/main/java/org/apache/rocketmq/store/MappedFile.java b/store/src/main/java/org/apache/rocketmq/store/MappedFile.java
index cd4b57b..feb505d 100644
--- a/store/src/main/java/org/apache/rocketmq/store/MappedFile.java
+++ b/store/src/main/java/org/apache/rocketmq/store/MappedFile.java
@@ -43,9 +43,9 @@ public class MappedFile extends ReferenceResource {
     public static final int OS_PAGE_SIZE = 1024 * 4;
     protected static final Logger log = LoggerFactory.getLogger(LoggerName.STORE_LOGGER_NAME);
 
-    private static final AtomicLong TOTAL_MAPED_VITUAL_MEMORY = new AtomicLong(0);
+    private static final AtomicLong TOTAL_MAPPED_VIRTUAL_MEMORY = new AtomicLong(0);
 
-    private static final AtomicInteger TOTAL_MAPED_FILES = new AtomicInteger(0);
+    private static final AtomicInteger TOTAL_MAPPED_FILES = new AtomicInteger(0);
     protected final AtomicInteger wrotePosition = new AtomicInteger(0);
     //ADD BY ChenYang
     protected final AtomicInteger committedPosition = new AtomicInteger(0);
@@ -132,12 +132,12 @@ public class MappedFile extends ReferenceResource {
             return viewed(viewedBuffer);
     }
 
-    public static int getTotalmapedfiles() {
-        return TOTAL_MAPED_FILES.get();
+    public static int getTotalMappedFiles() {
+        return TOTAL_MAPPED_FILES.get();
     }
 
-    public static long getTotalMapedVitualMemory() {
-        return TOTAL_MAPED_VITUAL_MEMORY.get();
+    public static long getTotalMappedVirtualMemory() {
+        return TOTAL_MAPPED_VIRTUAL_MEMORY.get();
     }
 
     public void init(final String fileName, final int fileSize, final TransientStorePool transientStorePool) throws IOException {
@@ -158,8 +158,8 @@ public class MappedFile extends ReferenceResource {
         try {
             this.fileChannel = new RandomAccessFile(this.file, "rw").getChannel();
             this.mappedByteBuffer = this.fileChannel.map(MapMode.READ_WRITE, 0, fileSize);
-            TOTAL_MAPED_VITUAL_MEMORY.addAndGet(fileSize);
-            TOTAL_MAPED_FILES.incrementAndGet();
+            TOTAL_MAPPED_VIRTUAL_MEMORY.addAndGet(fileSize);
+            TOTAL_MAPPED_FILES.incrementAndGet();
             ok = true;
         } catch (FileNotFoundException e) {
             log.error("create file channel " + this.fileName + " Failed. ", e);
@@ -405,8 +405,8 @@ public class MappedFile extends ReferenceResource {
         }
 
         clean(this.mappedByteBuffer);
-        TOTAL_MAPED_VITUAL_MEMORY.addAndGet(this.fileSize * (-1));
-        TOTAL_MAPED_FILES.decrementAndGet();
+        TOTAL_MAPPED_VIRTUAL_MEMORY.addAndGet(this.fileSize * (-1));
+        TOTAL_MAPPED_FILES.decrementAndGet();
         log.info("unmap file[REF:" + currentRef + "] " + this.fileName + " OK");
         return true;
     }
@@ -431,7 +431,7 @@ public class MappedFile extends ReferenceResource {
 
             return true;
         } else {
-            log.warn("destroy maped file[REF:" + this.getRefCount() + "] " + this.fileName
+            log.warn("destroy mapped file[REF:" + this.getRefCount() + "] " + this.fileName
                 + " Failed. cleanupOver: " + this.cleanupOver);
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/11ff542c/store/src/main/java/org/apache/rocketmq/store/MappedFileQueue.java
----------------------------------------------------------------------
diff --git a/store/src/main/java/org/apache/rocketmq/store/MappedFileQueue.java b/store/src/main/java/org/apache/rocketmq/store/MappedFileQueue.java
index f98b26a..5c6c62c 100644
--- a/store/src/main/java/org/apache/rocketmq/store/MappedFileQueue.java
+++ b/store/src/main/java/org/apache/rocketmq/store/MappedFileQueue.java
@@ -397,11 +397,15 @@ public class MappedFileQueue {
                         log.info("physic min offset " + offset + ", logics in current mappedFile max offset "
                             + maxOffsetInLogicQueue + ", delete it");
                     }
+                } else if (!mappedFile.isAvailable()) { // Handle hanged file.
+                    log.warn("Found a hanged consume queue file, attempting to delete it.");
+                    destroy = true;
                 } else {
                     log.warn("this being not executed forever.");
                     break;
                 }
 
+                // TODO: Externalize this hardcoded value
                 if (destroy && mappedFile.destroy(1000 * 60)) {
                     files.add(mappedFile);
                     deleteCount++;

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/11ff542c/store/src/main/java/org/apache/rocketmq/store/schedule/ScheduleMessageService.java
----------------------------------------------------------------------
diff --git a/store/src/main/java/org/apache/rocketmq/store/schedule/ScheduleMessageService.java b/store/src/main/java/org/apache/rocketmq/store/schedule/ScheduleMessageService.java
index 5b42082..e08a6f5 100644
--- a/store/src/main/java/org/apache/rocketmq/store/schedule/ScheduleMessageService.java
+++ b/store/src/main/java/org/apache/rocketmq/store/schedule/ScheduleMessageService.java
@@ -324,7 +324,7 @@ public class ScheduleMessageService extends ConfigManager {
 
 
                      */
-                    long cqMinOffset = cq.getMinOffsetInQuque();
+                    long cqMinOffset = cq.getMinOffsetInQueue();
                     if (offset < cqMinOffset) {
                         failScheduleOffset = cqMinOffset;
                         log.error("schedule CQ offset invalid. offset=" + offset + ", cqMinOffset="

http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/11ff542c/store/src/test/java/org/apache/rocketmq/store/MappedFileQueueTest.java
----------------------------------------------------------------------
diff --git a/store/src/test/java/org/apache/rocketmq/store/MappedFileQueueTest.java b/store/src/test/java/org/apache/rocketmq/store/MappedFileQueueTest.java
index 90fbbd3..2d6c112 100644
--- a/store/src/test/java/org/apache/rocketmq/store/MappedFileQueueTest.java
+++ b/store/src/test/java/org/apache/rocketmq/store/MappedFileQueueTest.java
@@ -20,6 +20,8 @@
  */
 package org.apache.rocketmq.store;
 
+import java.nio.ByteBuffer;
+import java.util.Arrays;
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -30,6 +32,7 @@ import org.slf4j.LoggerFactory;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 public class MappedFileQueueTest {
@@ -55,7 +58,7 @@ public class MappedFileQueueTest {
     }
 
     @Test
-    public void test_getLastMapedFile() {
+    public void test_getLastMappedFile() {
         final String fixedMsg = "0123456789abcdef";
 
         logger.debug("================================================================");
@@ -79,7 +82,7 @@ public class MappedFileQueueTest {
     }
 
     @Test
-    public void test_findMapedFileByOffset() {
+    public void test_findMappedFileByOffset() {
         // four-byte string.
         final String fixedMsg = "abcd";
 
@@ -179,7 +182,7 @@ public class MappedFileQueueTest {
     }
 
     @Test
-    public void test_getMapedMemorySize() {
+    public void test_getMappedMemorySize() {
         final String fixedMsg = "abcd";
 
         logger.debug("================================================================");
@@ -200,4 +203,45 @@ public class MappedFileQueueTest {
         mappedFileQueue.destroy();
         logger.debug("MappedFileQueue.getMappedMemorySize() OK");
     }
+
+
+    @Test
+    public void test_deleteExpiredFileByOffset() {
+
+        logger.debug("================================================================");
+        MappedFileQueue mappedFileQueue =
+            new MappedFileQueue("target/unit_test_store/e", 5120, null);
+
+        for (int i = 0; i < 2048; i++) {
+            MappedFile mappedFile = mappedFileQueue.getLastMappedFile(0);
+            assertNotNull(mappedFile);
+
+            ByteBuffer byteBuffer = ByteBuffer.allocate(ConsumeQueue.CQ_STORE_UNIT_SIZE);
+            byteBuffer.putLong(i);
+            byte[] padding = new byte[12];
+            Arrays.fill(padding, (byte)'0');
+            byteBuffer.put(padding);
+            byteBuffer.flip();
+
+            boolean result = mappedFile.appendMessage(byteBuffer.array());
+
+            assertTrue(result);
+        }
+
+        MappedFile first = mappedFileQueue.getFirstMappedFile();
+        first.hold();
+
+        int count = mappedFileQueue.deleteExpiredFileByOffset(20480, ConsumeQueue.CQ_STORE_UNIT_SIZE);
+        assertEquals(0, count);
+        first.release();
+
+        count = mappedFileQueue.deleteExpiredFileByOffset(20480, ConsumeQueue.CQ_STORE_UNIT_SIZE);
+        assertTrue(count > 0);
+        first = mappedFileQueue.getFirstMappedFile();
+        assertTrue(first.getFileFromOffset() > 0);
+
+        mappedFileQueue.shutdown(1000);
+        mappedFileQueue.destroy();
+        logger.debug("MappedFileQueue.deleteExpiredFileByOffset() OK");
+    }
 }


[07/31] incubator-rocketmq git commit: [ROCKETMQ-64] Remove duplication code line in BrokerOuterAPI.registerBroker method, thanks @naughtybear, closes apache/incubator-rocketmq#44

Posted by st...@apache.org.
[ROCKETMQ-64] Remove duplication code line in BrokerOuterAPI.registerBroker method, thanks @naughtybear, closes apache/incubator-rocketmq#44


Project: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/commit/581039be
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/tree/581039be
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/diff/581039be

Branch: refs/heads/ROCKETMQ-54
Commit: 581039bef2b6a628ec1611f24880b87d8a8d6fd7
Parents: 457bb61
Author: yukon <yu...@apache.org>
Authored: Fri Jan 20 11:23:31 2017 +0800
Committer: yukon <yu...@apache.org>
Committed: Fri Jan 20 11:23:31 2017 +0800

----------------------------------------------------------------------
 .../main/java/org/apache/rocketmq/broker/out/BrokerOuterAPI.java    | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/581039be/broker/src/main/java/org/apache/rocketmq/broker/out/BrokerOuterAPI.java
----------------------------------------------------------------------
diff --git a/broker/src/main/java/org/apache/rocketmq/broker/out/BrokerOuterAPI.java b/broker/src/main/java/org/apache/rocketmq/broker/out/BrokerOuterAPI.java
index 8726c69..039c942 100644
--- a/broker/src/main/java/org/apache/rocketmq/broker/out/BrokerOuterAPI.java
+++ b/broker/src/main/java/org/apache/rocketmq/broker/out/BrokerOuterAPI.java
@@ -173,7 +173,6 @@ public class BrokerOuterAPI {
                 RegisterBrokerResult result = new RegisterBrokerResult();
                 result.setMasterAddr(responseHeader.getMasterAddr());
                 result.setHaServerAddr(responseHeader.getHaServerAddr());
-                result.setHaServerAddr(responseHeader.getHaServerAddr());
                 if (response.getBody() != null) {
                     result.setKvTable(KVTable.decode(response.getBody(), KVTable.class));
                 }