This is an automated email from the ASF dual-hosted git repository.

jinrongtong pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/rocketmq-e2e.git


The following commit(s) were added to refs/heads/master by this push:
     new caacf39  [ISSUE #40] Finish producer and consumer features in client, 
2 sql filter features and a tag filter feature. And fix some bugs (#41)
caacf39 is described below

commit caacf398023fb858cb19f1e8cd9fe4677d99d606
Author: alani <[email protected]>
AuthorDate: Fri Jun 9 11:10:44 2023 +0800

    [ISSUE #40] Finish producer and consumer features in client, 2 sql filter 
features and a tag filter feature. And fix some bugs (#41)
    
    * features
    
    * Delete ConsumerGroup.feature
    
    * features
    
    * Delete bdd/src/main/resources/consumer directory
    
    * features
    
    * features
    
    * finish consumer and producer features in client, 2 sql filter features 
and a tag filter feature
    
    * fix a problem in SimpleConsumerInitTest.java
    
    * fix some problems in features
    
    * update
    
    * Delete PushConsumerRetry.feature
    
    * Delete SimpleAck.feature
    
    * Delete SimpleOrderParam.feature
    
    ---------
    
    Co-authored-by: alani <[email protected]>
---
 .../org/apache/rocketmq/ClientInitStepdefs.java    | 199 +++++++++++++++++++++
 .../client/consumer/ConsumerGroup.feature          |  38 ++++
 .../client/consumer/PushConsumerInit.feature       |  73 ++++++++
 .../client/consumer/SimpleConsumerInit.feature     |  95 ++++++++++
 .../message/MessageBodyContent.feature}            |  22 ++-
 .../resources/client/message/MessageKey.feature    |  61 +++++++
 .../client/message/MessageProperties.feature       |  57 ++++++
 .../resources/client/message/MessageSize.feature   | 105 +++++++++++
 .../resources/client/message/MessageTag.feature    |  62 +++++++
 .../client/message/MessageUserProperty.feature     | 113 ++++++++++++
 .../resources/client/producer/ProducerInit.feature |  97 ++++++++++
 .../main/resources/filter.push/SqlFilter.feature   |  59 ++++++
 .../filter.push/SqlFilterWithOrderMsg.feature      |  47 +++++
 .../main/resources/filter.push/TagFilter.feature   | 153 ++++++++++++++++
 bdd/src/main/resources/{ => server}/delay.feature  |   0
 bdd/src/main/resources/{ => server}/normal.feature |   0
 bdd/src/main/resources/{ => server}/order.feature  |   0
 .../resources/{ => server}/transaction.feature     |   2 +-
 .../client/consumer/SimpleConsumerInitTest.java    |  18 +-
 19 files changed, 1183 insertions(+), 18 deletions(-)

diff --git a/bdd/src/main/java/org/apache/rocketmq/ClientInitStepdefs.java 
b/bdd/src/main/java/org/apache/rocketmq/ClientInitStepdefs.java
index 021186c..1e46a77 100644
--- a/bdd/src/main/java/org/apache/rocketmq/ClientInitStepdefs.java
+++ b/bdd/src/main/java/org/apache/rocketmq/ClientInitStepdefs.java
@@ -218,4 +218,203 @@ public class ClientInitStepdefs {
     @And("Set messageProperty {string} to {string} and {string} to {string}")
     public void setMessagePropertyToAndTo(String arg0, String arg1, String 
arg2, String arg3) {
     }
+
+    @When("Create a PushConsumer, set the Endpoint\\({string}), 
ConsumerGroup\\({string}), Topic\\({string}), 
filterExpression\\(SubExpression:{string}, FilterExpressionType:{string}), and 
MessageListener\\({string})")
+    public void 
createAPushConsumerSetTheEndpointConsumerGroupTopicFilterExpressionSubExpressionFilterExpressionTypeAndMessageListener(String
 arg0, String arg1, String arg2, String arg3, String arg4, String arg5) {
+        
+    }
+
+    @Then("Create a message, including the Topic\\({string}), Tag\\({string}), 
Key\\({string}), Body\\({string}), and msgProps\\(regionId:{string}, 
price:{string})")
+    public void 
createAMessageIncludingTheTopicTagKeyBodyAndMsgPropsRegionIdPrice(String arg0, 
String arg1, String arg2, String arg3, String arg4, String arg5) {
+        
+    }
+
+    @And("Send {string} messages with msgProps\\(price:{string}) {string}")
+    public void sendMessagesWithMsgPropsPrice(String arg0, String arg1, String 
arg2) {
+        
+    }
+
+    @Then("Check only all messages with msgProps\\(price:{string}) are 
consumed")
+    public void checkOnlyAllMessagesWithMsgPropsPriceAreConsumed(String arg0) {
+        
+    }
+
+    @And("Check PushConsumer consumes {int} messages")
+    public void checkPushConsumerConsumesMessages(int arg0) {
+        
+    }
+
+    @Then("Create a message, including the Topic\\({string}), 
Body\\({string}), messageGroup\\({string}), and msgProps\\(regionId:{string}, 
price:{string})")
+    public void 
createAMessageIncludingTheTopicBodyMessageGroupAndMsgPropsRegionIdPrice(String 
arg0, String arg1, String arg2, String arg3, String arg4) {
+        
+    }
+
+    @And("Check the order of received messages consistent with the order of 
pre-sent messages")
+    public void 
checkTheOrderOfReceivedMessagesConsistentWithTheOrderOfPreSentMessages() {
+        
+    }
+
+    @When("Create a PushConsumer, set the Endpoint\\({string}), 
ConsumerGroup\\({string}), Topic\\({string}), filterExpression\\({string}), and 
MessageListener\\({string})")
+    public void 
createAPushConsumerSetTheEndpointConsumerGroupTopicFilterExpressionAndMessageListener(String
 arg0, String arg1, String arg2, String arg3, String arg4) {
+        
+    }
+
+    @And("Send {string} messages with Tag\\({string}) {string}")
+    public void sendMessagesWithTag(String arg0, String arg1, String arg2) {
+        
+    }
+
+    @And("Create a SimpleConsumer, set the Endpoint\\({string}), 
Topic\\({string}), ConsumerGroup\\({string}), FilterExpressions\\({string}), 
Duration\\({string})")
+    public void 
createASimpleConsumerSetTheEndpointTopicConsumerGroupFilterExpressionsDuration(String
 arg0, String arg1, String arg2, String arg3, String arg4) {
+        
+    }
+
+    @Then("Check SimpleConsumer pull a message once")
+    public void checkSimpleConsumerPullAMessageOnce() {
+        
+    }
+
+    @And("SimpleConsumer invokes receive method {string} and returns acks 
{string}")
+    public void simpleconsumerInvokesReceiveMethodAndReturnsAcks(String arg0, 
String arg1) {
+        
+    }
+
+    @Then("Check all messages are pulled by SimpleConsumer {string}")
+    public void checkAllMessagesArePulledBySimpleConsumer(String arg0) {
+        
+    }
+
+    @When("Create a {string}, set the 
ClientConfiguration\\(Endpoint:{string}), ConsumerGroup\\({string}), 
AwaitDuration\\({string}), SubscriptionExpressions\\(NULL)")
+    public void 
createASetTheClientConfigurationEndpointConsumerGroupAwaitDurationSubscriptionExpressionsNULL(String
 arg0, String arg1, String arg2, String arg3) {
+        
+    }
+
+    @When("Create a {string}, set the 
ClientConfiguration\\(Endpoint:{string}), ConsumerGroup\\({string}), 
AwaitDuration\\({string}), SubscriptionExpressions\\({string}, {string})")
+    public void 
createASetTheClientConfigurationEndpointConsumerGroupAwaitDurationSubscriptionExpressions(String
 arg0, String arg1, String arg2, String arg3, String arg4, String arg5) {
+        
+    }
+
+    @Then("Consumer invoke receive\\(maxMessageNum:{int}, 
invisibleDuration:{int}s)")
+    public void consumerInvokeReceiveMaxMessageNumInvisibleDurationS(int arg0, 
int arg1) {
+        
+    }
+
+    @Then("Check {string} receive messages successfully")
+    public void checkReceiveMessagesSuccessfully(String arg0) {
+        
+    }
+
+    @And("Check the message request return duration between {int}s and {int}s")
+    public void checkTheMessageRequestReturnDurationBetweenSAndS(int arg0, int 
arg1) {
+        
+    }
+
+    @Then("Check build {string} successfully")
+    public void checkBuildSuccessfully(String arg0) {
+        
+    }
+
+    @When("Create a {string}, set the ConsumerGroup\\({string}), 
AwaitDuration\\({string}), SubscriptionExpressions\\({string}, {string})")
+    public void 
createASetTheConsumerGroupAwaitDurationSubscriptionExpressions(String arg0, 
String arg1, String arg2, String arg3, String arg4) {
+        
+    }
+
+    @When("Create a {string}, set the 
ClientConfiguration\\(Endpoint:{string}), AwaitDuration\\({string}), 
SubscriptionExpressions\\({string}, {string})")
+    public void 
createASetTheClientConfigurationEndpointAwaitDurationSubscriptionExpressions(String
 arg0, String arg1, String arg2, String arg3, String arg4) {
+        
+    }
+
+    @When("Create a {string}, set the 
ClientConfiguration\\(Endpoint:{string}), ConsumerGroup\\({string}), 
AwaitDuration\\({string})")
+    public void 
createASetTheClientConfigurationEndpointConsumerGroupAwaitDuration(String arg0, 
String arg1, String arg2, String arg3) {
+        
+    }
+
+    @When("Create a {string}, set the 
ClientConfiguration\\(Endpoint:{string}), ConsumerGroup\\({string}), 
SubscriptionExpressions\\({string}, {string})")
+    public void 
createASetTheClientConfigurationEndpointConsumerGroupSubscriptionExpressions(String
 arg0, String arg1, String arg2, String arg3, String arg4) {
+        
+    }
+
+    @Given("Create a {string}, set the 
ClientConfiguration\\(Endpoint:{string}), ConsumerGroup\\({string}), 
SubscriptionExpressions\\({string}, {string}), ConsumptionThreadCount\\({int}), 
MaxCacheMessageCount\\({int}), MaxCacheMessageSizeInBytes\\({int}M), 
MessageListener\\({string})")
+    public void 
createASetTheClientConfigurationEndpointConsumerGroupSubscriptionExpressionsConsumptionThreadCountMaxCacheMessageCountMaxCacheMessageSizeInBytesMMessageListener(String
 arg0, String arg1, String arg2, String arg3, String arg4, int arg5, int arg6, 
int arg7, String arg8) {
+        
+    }
+
+    @When("Create a {string}, set the ConsumerGroup\\({string}), 
SubscriptionExpressions\\({string}, {string}), MessageListener\\({string})")
+    public void 
createASetTheConsumerGroupSubscriptionExpressionsMessageListener(String arg0, 
String arg1, String arg2, String arg3, String arg4) {
+        
+    }
+
+    @And("Set {string} ClientConfiguration\\(Endpoint:{string}, 
AccessKey:{string}, SecretKey:{string})")
+    public void setClientConfigurationEndpointAccessKeySecretKey(String arg0, 
String arg1, String arg2, String arg3) {
+        
+    }
+
+    @When("Create a {string}, set the 
ClientConfiguration\\(Endpoint:{string}), ConsumerGroup\\({string}), 
SubscriptionExpressions\\({string}, {string}), MessageListener\\({string})")
+    public void 
createASetTheClientConfigurationEndpointConsumerGroupSubscriptionExpressionsMessageListener(String
 arg0, String arg1, String arg2, String arg3, String arg4, String arg5) {
+        
+    }
+
+    @When("Create a {string}, set the 
ClientConfiguration\\(Endpoint:{string}), SubscriptionExpressions\\({string}, 
{string}), MessageListener\\({string})")
+    public void 
createASetTheClientConfigurationEndpointSubscriptionExpressionsMessageListener(String
 arg0, String arg1, String arg2, String arg3, String arg4) {
+        
+    }
+
+    @When("Create a {string}, set the 
ClientConfiguration\\(Endpoint:{string}), ConsumerGroup\\({string}), 
MessageListener\\({string})")
+    public void 
createASetTheClientConfigurationEndpointConsumerGroupMessageListener(String 
arg0, String arg1, String arg2, String arg3) {
+        
+    }
+
+    @When("Create a {string}, set the 
ClientConfiguration\\(Endpoint:{string}), ConsumerGroup\\({string}), 
SubscriptionExpressions\\(NULL), MessageListener\\({string})")
+    public void 
createASetTheClientConfigurationEndpointConsumerGroupSubscriptionExpressionsNULLMessageListener(String
 arg0, String arg1, String arg2, String arg3) {
+        
+    }
+
+    @Given("Create a {string} ConsumerGroup if not exist")
+    public void createAConsumerGroupIfNotExist(String arg0) {
+        
+    }
+
+    @When("Create a {string}, set the Endpoint\\({string}), 
ConsumerGroup\\({string}), AwaitDuration\\({string}), 
SubscriptionExpressions\\({string}, {string})")
+    public void 
createASetTheEndpointConsumerGroupAwaitDurationSubscriptionExpressions(String 
arg0, String arg1, String arg2, String arg3, String arg4, String arg5) {
+        
+    }
+
+    @When("Create a {string}, set the 
ClientConfiguration\\(Endpoint:{string}), Topics\\({string}), and 
MaxAttempts\\({int})")
+    public void 
createASetTheClientConfigurationEndpointTopicsAndMaxAttempts(String arg0, 
String arg1, String arg2, int arg3) {
+        
+    }
+
+    @When("Create a {string}, set the Topics\\({string})")
+    public void createASetTheTopics(String arg0, String arg1) {
+        
+    }
+
+    @And("Set {string} ClientConfiguration\\(Endpoint:{string}, 
AccessKey:NULL, SecretKey:{string})")
+    public void setClientConfigurationEndpointAccessKeyNULLSecretKey(String 
arg0, String arg1, String arg2) {
+        
+    }
+
+    @And("Set {string} ClientConfiguration\\(Endpoint:{string}, 
AccessKey:{string}, SecretKey:NULL)")
+    public void setClientConfigurationEndpointAccessKeySecretKeyNULL(String 
arg0, String arg1, String arg2) {
+        
+    }
+
+    @When("Create a {string}, set the ClientConfiguration\\(NULL), 
Topics\\({string}), and MaxAttempts\\({int})")
+    public void 
createASetTheClientConfigurationNULLTopicsAndMaxAttempts(String arg0, String 
arg1, int arg2) {
+        
+    }
+
+    @When("Create a {string}, set the 
ClientConfiguration\\(Endpoint:{string}), Topics\\({string}, {string}), and 
MaxAttempts\\({int})")
+    public void 
createASetTheClientConfigurationEndpointTopicsAndMaxAttempts(String arg0, 
String arg1, String arg2, String arg3, int arg4) {
+        
+    }
+
+    @When("Create a {string}, set the Topics\\({string}), and 
MaxAttempts\\({int})")
+    public void createASetTheTopicsAndMaxAttempts(String arg0, String arg1, 
int arg2) {
+        
+    }
+
+    @When("Create a {string}, set the 
ClientConfiguration\\(Endpoint:{string}), and MaxAttempts\\({int})")
+    public void createASetTheClientConfigurationEndpointAndMaxAttempts(String 
arg0, String arg1, int arg2) {
+    }
 }
diff --git a/bdd/src/main/resources/client/consumer/ConsumerGroup.feature 
b/bdd/src/main/resources/client/consumer/ConsumerGroup.feature
new file mode 100644
index 0000000..1083ff7
--- /dev/null
+++ b/bdd/src/main/resources/client/consumer/ConsumerGroup.feature
@@ -0,0 +1,38 @@
+# 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.
+
+Feature: Test System inner ConsumerGroup
+
+  Scenario Outline: Use the built-in ConsumerGroup to consume messages and 
expect consume failed
+    Given Create a "Concurrently" ConsumerGroup if not exist
+    When Create a "SimpleConsumer", set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("<RmqSystemGroupConstant>"), AwaitDuration("10s"), 
SubscriptionExpressions("random-topic", "random-filterExpression")
+    Then Consumer invoke receive(maxMessageNum:32, invisibleDuration:10s)
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+    Examples:
+      | RmqSystemGroupConstant       |
+      | GROUP_DEFAULT_CONSUMER       |
+      | GROUP_TOOLS_CONSUMER         |
+      | GROUP_FILTERSRV_CONSUMER     |
+      | GROUP_MONITOR_CONSUMER       |
+      | GROUP_CLIENT_INNER_PRODUCER  |
+      | GROUP_SELF_TEST_P_GROUP      |
+      | GROUP_SELF_TEST_C_GROUP      |
+      | GROUP_CID_ONS_HTTP_PROXY     |
+      | GROUP_CID_ONSAPI_PERMISSION  |
+      | GROUP_CID_ONSAPI_OWNER       |
+      | GROUP_CID_ONSAPI_PULL        |
+      | GROUP_CID_RMQ_SYS_TRANS      |
\ No newline at end of file
diff --git a/bdd/src/main/resources/client/consumer/PushConsumerInit.feature 
b/bdd/src/main/resources/client/consumer/PushConsumerInit.feature
new file mode 100644
index 0000000..0e8cf2e
--- /dev/null
+++ b/bdd/src/main/resources/client/consumer/PushConsumerInit.feature
@@ -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.
+
+Feature: Test PushConsumer Initialization Parameters
+
+  Scenario: PushConsumer all parameters are set properly, expect start 
successfully
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    Given Create a "PushConsumer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), ConsumerGroup("random-group"), 
SubscriptionExpressions("random-topic", "random-filterExpression"), 
ConsumptionThreadCount(20), MaxCacheMessageCount(1000), 
MaxCacheMessageSizeInBytes(4M), MessageListener("default")
+    Then Check build "PushConsumer" successfully
+    And Shutdown the producer and consumer if they are started
+
+  Scenario Outline: Error setting the ClientConfiguration(including Endpoint 
and CredentialProvider), expect start failed
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a "PushConsumer", set the ConsumerGroup("random-group"), 
SubscriptionExpressions("random-topic", "random-filterExpression"), 
MessageListener("default")
+    And Set "PushConsumer" ClientConfiguration(Endpoint:"<Endpoint>", 
AccessKey:"<AccessKey>", SecretKey:"<SecretKey>")
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+    Examples:
+      | Endpoint               | AccessKey | SecretKey |
+      | 127.0.0.1:9876         | errorAk   | accountSK |
+      | 127.0.0.1:9876         | accountAk | errorSK   |
+      | https://www.aliyun.com | accountAk | accountSK |
+
+  Scenario: Error setting the 'Topic' of the consumer client, expect start 
failed
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a "PushConsumer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), ConsumerGroup("random-group"), 
SubscriptionExpressions("topicNotExist", "random-filterExpression"), 
MessageListener("default")
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Without setting 'ConsumerGroup' of the consumer client, expect 
start failed
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a "PushConsumer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), 
SubscriptionExpressions("random-topic", "random-filterExpression"), 
MessageListener("default")
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Without setting 'SubscriptionExpressions' of the consumer client, 
expect start failed
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a "PushConsumer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), ConsumerGroup("random-group"), 
MessageListener("default")
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Error setting an empty 'SubscriptionExpressions' of the consumer 
client, expect start failed
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a "PushConsumer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), ConsumerGroup("random-group"), 
SubscriptionExpressions(NULL), MessageListener("default")
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Without setting 'ClientConfiguration' of the consumer client, 
expect start failed
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a "PushConsumer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), 
SubscriptionExpressions("random-topic", "random-filterExpression"), 
MessageListener("default")
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Without setting 'MessageListener' of the consumer client, expect 
start failed
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a "PushConsumer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), ConsumerGroup("random-group"), 
SubscriptionExpressions("random-topic", "random-filterExpression")
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+
diff --git a/bdd/src/main/resources/client/consumer/SimpleConsumerInit.feature 
b/bdd/src/main/resources/client/consumer/SimpleConsumerInit.feature
new file mode 100644
index 0000000..0affc15
--- /dev/null
+++ b/bdd/src/main/resources/client/consumer/SimpleConsumerInit.feature
@@ -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.
+
+Feature: Test SimpleConsumer Initialization Parameters
+
+  Scenario: SimpleConsumer all parameters are set properly, expect start 
successfully
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a "SimpleConsumer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), ConsumerGroup("random-group"), 
AwaitDuration("10s"), SubscriptionExpressions("random-topic", 
"random-filterExpression")
+    Then Check build "SimpleConsumer" successfully
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Without setting 'ClientConfiguration' of the consumer client, 
expect start failed
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a "SimpleConsumer", set the ConsumerGroup("random-group"), 
AwaitDuration("10s"), SubscriptionExpressions("random-topic", 
"random-filterExpression")
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Without setting 'ConsumerGroup' of the consumer client, expect 
start failed
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a "SimpleConsumer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), AwaitDuration("10s"), 
SubscriptionExpressions("random-topic", "random-filterExpression")
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Without setting 'Subscription' of the consumer client, expect 
start failed
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a "SimpleConsumer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), ConsumerGroup("random-group"), 
AwaitDuration("10s")
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Without setting 'AwaitDuration' of the consumer client, expect 
start failed
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a "SimpleConsumer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), ConsumerGroup("random-group"), 
SubscriptionExpressions("random-topic", "random-filterExpression")
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Error setting 'SubscriptionExpressions' empty of the consumer 
client, expect start failed
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a "SimpleConsumer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), ConsumerGroup("random-group"), 
AwaitDuration("10s"), SubscriptionExpressions(NULL)
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Error setting 'AwaitDuration=0' of the consumer client, expect 
start failed
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a "SimpleConsumer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), ConsumerGroup("random-group"), 
AwaitDuration("0"), SubscriptionExpressions("random-topic", 
"random-filterExpression")
+    Then Consumer invoke receive(maxMessageNum:32, invisibleDuration:10s)
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Error setting 'MaxMessageNum=0' of the consumer client, expect 
start failed
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a "SimpleConsumer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), ConsumerGroup("random-group"), 
AwaitDuration("15s"), SubscriptionExpressions("random-topic", 
"random-filterExpression")
+    Then Consumer invoke receive(maxMessageNum:0, invisibleDuration:20s)
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Setting 'MaxMessageNum=100000', expect start successfully
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a "SimpleConsumer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), ConsumerGroup("random-group"), 
AwaitDuration("15s"), SubscriptionExpressions("random-topic", 
"random-filterExpression")
+    Then Consumer invoke receive(maxMessageNum:1000, invisibleDuration:20s)
+    Then Check "SimpleConsumer" receive messages successfully
+    And Shutdown the producer and consumer if they are started
+
+  Scenario Outline: Error setting invisibleDuration shorter than 10000ms or 
longer than 43200000ms, expect start failed
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a "SimpleConsumer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), ConsumerGroup("random-group"), 
AwaitDuration("<IllegalInvisibleDuration>"), 
SubscriptionExpressions("random-topic", "random-filterExpression")
+    Then Consumer invoke receive(maxMessageNum:1, invisibleDuration:20s)
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+    Examples:
+      | IllegalInvisibleDuration |
+      | 9999ms                    |
+      | 43200001ms               |
+
+  Scenario: Setting 'AwaitDuration=10s', expect the empty pull message request 
to return between 10s and 20s
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a "SimpleConsumer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), ConsumerGroup("random-group"), 
AwaitDuration("10s"), SubscriptionExpressions("random-topic", 
"random-filterExpression")
+    Then Consumer invoke receive(maxMessageNum:100000, invisibleDuration:10s)
+    Then Check "SimpleConsumer" receive messages successfully
+    And Check the message request return duration between 10s and 20s
+    And Shutdown the producer and consumer if they are started
+
+
diff --git a/bdd/src/main/resources/normal.feature 
b/bdd/src/main/resources/client/message/MessageBodyContent.feature
similarity index 72%
copy from bdd/src/main/resources/normal.feature
copy to bdd/src/main/resources/client/message/MessageBodyContent.feature
index 0ba6c3d..1d98e97 100644
--- a/bdd/src/main/resources/normal.feature
+++ b/bdd/src/main/resources/client/message/MessageBodyContent.feature
@@ -13,18 +13,24 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
-Feature: Test the message transfer mode
+Feature: Test message body contents
 
-  Scenario Outline:  10 normal messages are sent synchronously and are 
expected to be received
+  Scenario Outline: Send normal message, setting message body, expect send and 
consume success
     Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
     When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Tag("TagA"), Topic("random-topic"), 
MessageListener("default")
     And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
-    Then Create a message, including the Topic("random-topic"), Tag("TagA"), 
Key("Key"), and Body("Body")
-    And  Send "10" messages "<TransmissionMode>"
-    Then Check all messages that can be consumed within 60s
+    Then Create a message, including the Topic("random-topic"), Tag("TagA"), 
Key("Key"), and Body("<MessageBodyContent>")
+    And  Send "a" messages "synchronous"
+    Then  Check all messages that can be consumed within 60s
+    And Check the subscribed message body is equal to "<MessageBodyContent>"
     And Shutdown the producer and consumer if they are started
 
     Examples:
-      | TransmissionMode |
-      | synchronous      |
-      | asynchronous     |
+      | MessageBodyContent |
+      |                    |
+      |       中文字符       |
+      |         😱         |
+
+
+
+
diff --git a/bdd/src/main/resources/client/message/MessageKey.feature 
b/bdd/src/main/resources/client/message/MessageKey.feature
new file mode 100644
index 0000000..6345a0a
--- /dev/null
+++ b/bdd/src/main/resources/client/message/MessageKey.feature
@@ -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.
+
+Feature: Test message key
+
+  Scenario: Message Key beyond 16KB, expect throw exception
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), 
Tag("random-tag"), Key("size:16kB+1"), and Body("random-body")
+    And  Send "a" messages "synchronous"
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Message Key beyond 16KB, expect throw exception
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), 
Tag("random-tag"), Key("\u0000"), and Body("random-body")
+    And  Send "a" messages "synchronous"
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Message Key equals 16KB, expect send and consume success
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Tag("TagA"), Topic("random-topic"), 
MessageListener("default")
+    And Create a message, including the Topic("random-topic"), 
Tag("random-tag"), Key("size:16KB"), and Body("random-body")
+    And  Send "a" messages "synchronous"
+    Then  Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Message key contains Chinese, expect send and consume success
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Tag("TagA"), Topic("random-topic"), 
MessageListener("default")
+    And Create a message, including the Topic("random-topic"), 
Tag("random-tag"), Key("中文字符"), and Body("random-body")
+    And  Send "a" messages "synchronous"
+    Then  Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: The message contains multiple keys, expect send and consume success
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Tag("TagA"), Topic("random-topic"), 
MessageListener("default")
+    And Create a message, including the Topic("random-topic"), 
Tag("random-tag"), Key("random-key1", "random-key2"), and Body("random-body")
+    And  Send "a" messages "synchronous"
+    Then  Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+
diff --git a/bdd/src/main/resources/client/message/MessageProperties.feature 
b/bdd/src/main/resources/client/message/MessageProperties.feature
new file mode 100644
index 0000000..106c935
--- /dev/null
+++ b/bdd/src/main/resources/client/message/MessageProperties.feature
@@ -0,0 +1,57 @@
+# 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.
+
+Feature: Test message properties
+
+  Scenario: producer invoke send(messageBody=null), expect build message throw 
exception
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), 
Tag("random-tag"), Key("Key"), and Body(null)
+    And  Send "a" messages "synchronous"
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: producer invoke send(topic=""), expect throw exception
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a message, including the Topic(""), Tag("random-tag"), 
Key("Key"), and Body("Body")
+    And  Send "a" messages "synchronous"
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: producer invoke send(topic=null), expect throw exception
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a message, including the Topic(null), Tag("random-tag"), 
Key("Key"), and Body("Body")
+    And  Send "a" messages "synchronous"
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: producer invoke send(tag=null), expect throw exception
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), Tag(null), 
Key("Key"), and Body("Body")
+    And  Send "a" messages "synchronous"
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: producer invoke send(tag=""), expect throw exception
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), Tag(" "), 
Key("Key"), and Body("Body")
+    And  Send "a" messages "synchronous"
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
diff --git a/bdd/src/main/resources/client/message/MessageSize.feature 
b/bdd/src/main/resources/client/message/MessageSize.feature
new file mode 100644
index 0000000..7960d34
--- /dev/null
+++ b/bdd/src/main/resources/client/message/MessageSize.feature
@@ -0,0 +1,105 @@
+# 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.
+
+Feature: Test message size
+
+  Scenario Outline: Send normal/transaction messages with the body size of 
4M+1, expect send failed
+    Given Create a "<MessageType>" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), 
Tag("random-tag"), and Body("size:4M+1")
+    And  Send "a" messages "synchronous"
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+    Examples:
+      | MessageType   |
+      |   Normal      |
+      | Transaction   |
+
+  Scenario: Send delay messages with the body size of 4M+1, expect send failed
+    Given Create a "delay" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), 
Tag("random-tag"), Body("size:4M+1"), deliveryTimestamp("10L")
+    And  Send "a" messages "synchronous"
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Send FIFO messages with the body size of 4M+1, expect send failed
+    Given Create a "FIFO" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), 
Tag("random-tag"), Body("size:4M+1"), messageGroup("a")
+    And  Send "a" messages "synchronous"
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario Outline: Send normal/transaction messages with the body size of 4M, 
expect send and consume success
+    Given Create a "<MessageType>" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Tag("TagA"), Topic("random-topic"), 
MessageListener("default")
+    And Create a message, including the Topic("random-topic"), 
Tag("random-tag"), and Body("size:4M")
+    And  Send "a" messages "synchronous"
+    Then  Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+    Examples:
+      | MessageType   |
+      |   Normal      |
+      | Transaction   |
+
+  Scenario: Send delay messages with the body size of 4M, expect send and 
consume success
+    Given Create a "delay" topic:"random-topic" if not exist, a "Concurrently" 
group:"random-group"
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Tag("TagA"), Topic("random-topic"), 
MessageListener("default")
+    And Create a message, including the Topic("random-topic"), 
Tag("random-tag"), Body("size:4M"), deliveryTimestamp("10s")
+    And  Send "a" messages "synchronous"
+    Then  Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Send FIFO messages with the body size of 4M, expect send and 
consume success
+    Given Create a "FIFO" topic:"random-topic" if not exist, a "Concurrently" 
group:"random-group"
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Tag("TagA"), Topic("random-topic"), 
MessageListener("default")
+    And Create a message, including the Topic("random-topic"), 
Tag("random-tag"), Body("size:4M"), messageGroup("a")
+    And  Send "a" messages "synchronous"
+    Then  Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Send normal messages with the body size of 4M and the property 
size of 16KB, expect send and consume success
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Tag("TagA"), Topic("random-topic"), 
MessageListener("default")
+    And Create a message, including the Topic("random-topic"), 
Body("size:4M"), and messageProperty("size:16kB")
+    And  Send "a" messages "synchronous"
+    Then  Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Send FIFO messages with the body size of 4M and the property size 
of 16KB, expect send and consume success
+    Given Create a "FIFO" topic:"random-topic" if not exist, a "Concurrently" 
group:"random-group"
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Tag("TagA"), Topic("random-topic"), 
MessageListener("default")
+    And Create a message, including the Topic("random-topic"), 
Body("size:4M"), messageGroup("a"), and messageProperty("size:16kB")
+    And  Send "a" messages "synchronous"
+    Then  Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+
+
+
+
+
+
+
+
+
diff --git a/bdd/src/main/resources/client/message/MessageTag.feature 
b/bdd/src/main/resources/client/message/MessageTag.feature
new file mode 100644
index 0000000..7c1692d
--- /dev/null
+++ b/bdd/src/main/resources/client/message/MessageTag.feature
@@ -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.
+
+Feature: Test message tag
+
+  Scenario: Message Tag beyond 16KB, expect throw exception
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), 
Tag("size:16kB+1"), and Body("random-body")
+    And  Send "a" messages "synchronous"
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Message Tag equals 16KB, expect send and consume success
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Tag("TagA"), Topic("random-topic"), 
MessageListener("default")
+    And Create a message, including the Topic("random-topic"), 
Tag("size:16kB"), and Body("random-body")
+    And  Send "a" messages "synchronous"
+    Then  Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Message Tag contains invisible characters \u0000, expect throw 
exception
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), Tag("\u0000"), 
and Body("random-body")
+    And  Send "a" messages "synchronous"
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Message Tag contains | , expect throw exception
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), Tag("tag|"), 
and Body("random-body")
+    And  Send "a" messages "synchronous"
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Message Tag contains Chinese, expect send and consume success
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Tag("TagA"), Topic("random-topic"), 
MessageListener("default")
+    And Create a message, including the Topic("random-topic"), Tag("中文字符"), 
and Body("random-body")
+    And  Send "a" messages "synchronous"
+    Then  Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+
+
+
diff --git a/bdd/src/main/resources/client/message/MessageUserProperty.feature 
b/bdd/src/main/resources/client/message/MessageUserProperty.feature
new file mode 100644
index 0000000..8828e00
--- /dev/null
+++ b/bdd/src/main/resources/client/message/MessageUserProperty.feature
@@ -0,0 +1,113 @@
+# 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.
+
+Feature: Test message property
+
+  Scenario: Message property beyond limit 128 ,expect throw exception
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), 
Body("random-body"), and messageProperty("random-messageProperty")
+    And Set message "messageProperty" "129" times
+    And  Send "a" messages "synchronous"
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: The number of message properties equals limit 128, expect send and 
consume success
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Tag("TagA"), Topic("random-topic"), 
MessageListener("default")
+    And Create a message, including the Topic("random-topic"), 
Body("random-body"), and messageProperty("random-messageProperty")
+    And Set message "messageProperty" "128" times
+    And  Send "a" messages "synchronous"
+    Then  Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Message property equals 16KB, expect send and consume success
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Tag("TagA"), Topic("random-topic"), 
MessageListener("default")
+    And Create a message, including the Topic("random-topic"), 
Body("random-body"), and messageProperty("size:16kB")
+    And  Send "a" messages "synchronous"
+    Then  Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+
+  Scenario: Message property beyond 16KB, expect throw exception
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), 
Body("random-body"), and messageProperty("size:16kB+1")
+    And  Send "a" messages "synchronous"
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario Outline: Message property contains invisible character \u0000 / use 
SystemKey UNIQ_KEY ,expect throw exception
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), and 
messageProperty("<KeyContent>", "<ValueContent>")
+    And  Send "a" messages "synchronous"
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+    Examples:
+      | KeyContent | ValueContent |
+      | \u0000     | value        |
+      | UNIQ_KEY   | value        |
+
+  Scenario: Message property ,key and tag beyond 16KB ,expect throw exception
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), 
Tag("size:4kB"), Key("size:4kB"), Value("size:4kB"), Body("size:4M"), 
msgKey("size:4kB+1")
+    And  Send "a" messages "synchronous"
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Message property ,key and tag equals 16KB, expect send and consume 
success
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Tag("TagA"), Topic("random-topic"), 
MessageListener("default")
+    And Create a message, including the Topic("random-topic"), 
Tag("size:4kB"), Key("size:4kB"), Value("size:4kB"), Body("size:4M"), 
msgKey("size:4kB")
+    And  Send "a" messages "synchronous"
+    Then  Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Message property ,key and tag equals 64B, expect send and consume 
success
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), 
Tag("size:64B"), Key("size:64B"), Value("size:64B"), Body("size:64B"), 
msgKey("size:64B")
+    And  Send "a" messages "synchronous"
+    Then  Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Message property is the visible character, expect send and consume 
success
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("10s"), Topic("random-topic")
+    And Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Tag("TagA"), Topic("random-topic"), 
MessageListener("default")
+    And Create a message, including the Topic("random-topic"), 
Tag("random-tag"), Key("中文"), Value("中文"), Body("random-body"), 
msgKey("random-msgkey")
+    And Set messageProperty "Key" to "_" and "Value" to "_"
+    And Set messageProperty "Key" to "%" and "Value" to "%"
+    And Set messageProperty "Key" to "。" and "Value" to "。"
+    And Set messageProperty "Key" to "|" and "Value" to "|"
+    And Set messageProperty "Key" to "&&" and "Value" to "&&"
+    And Set messageProperty "Key" to "🏷" and "Value" to "🏷"
+    And  Send "a" messages "synchronous"
+    Then  Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+
+
+
+
+
+
diff --git a/bdd/src/main/resources/client/producer/ProducerInit.feature 
b/bdd/src/main/resources/client/producer/ProducerInit.feature
new file mode 100644
index 0000000..8b46d6d
--- /dev/null
+++ b/bdd/src/main/resources/client/producer/ProducerInit.feature
@@ -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.
+
+Feature: Test Producer Initialization Parameters
+
+  Scenario: Producer is normally set, expected start successfully
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a "Producer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), Topics("random-topic"), and 
MaxAttempts(3)
+    Then Check build "Producer" successfully
+    And Shutdown the producer and consumer if they are started
+
+  Scenario Outline: Error setting the ClientConfiguration(including Endpoint 
and CredentialProvider) of Producer, expect start failed
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a "Producer", set the Topics("random-topic")
+    And Set "Producer" ClientConfiguration(Endpoint:"<Endpoint>", 
AccessKey:"<AccessKey>", SecretKey:"<SecretKey>")
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+    Examples:
+      | Endpoint               | AccessKey | SecretKey |
+      | 127.0.0.1:9876         | errorAk   | accountSK |
+      | 127.0.0.1:9876         | accountAk | errorSK   |
+      | https://www.aliyun.com | accountAk | accountSK |
+
+  Scenario: Without setting the 'AccessKey' of Producer, expect start failed
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a "Producer", set the Topics("random-topic")
+    And Set "Producer" ClientConfiguration(Endpoint:"127.0.0.1:9876", 
AccessKey:NULL, SecretKey:"accountSK")
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Without setting the 'SecretKey' of Producer, expect start failed
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a "Producer", set the Topics("random-topic")
+    And Set "Producer" ClientConfiguration(Endpoint:"127.0.0.1:9876", 
AccessKey:"accountAK", SecretKey:NULL)
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Without setting the properties(including Endpoints, AccessKey, 
SecretKey) in 'ClientConfiguration' of Producer, expect start failed
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a "Producer", set the ClientConfiguration(NULL), 
Topics("random-topic"), and MaxAttempts(3)
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Set the 'MaxAttempts' of Producer to 0, expect start successfully
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a "Producer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), Topics("random-topic"), and 
MaxAttempts(0)
+    Then Check build "Producer" successfully
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Error setting the 'MaxAttempts' of Producer, expect start failed
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a "Producer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), Topics("random-topic"), and 
MaxAttempts(-1)
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Error setting the 'Topic' of the Producer to non-existent topic, 
expect start failed
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a "Producer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), Topics("topicNotExist"), and 
MaxAttempts(3)
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Error setting the same 'Topics' of the producer, expect start 
failed
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a "Producer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), Topics("topic1", "topic1"), and 
MaxAttempts(3)
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Set more topics of the Producer, one of which does not exist, 
expect start failed
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a "Producer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), Topics("random-topic", 
"topicNotExist"), and MaxAttempts(3)
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Without setting 'ClientConfiguration' of Producer, expect start 
failed
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a "Producer", set the Topics("random-topic"), and 
MaxAttempts(3)
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Without setting 'Topics' of Producer, expect start successfully
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a "Producer", set the 
ClientConfiguration(Endpoint:"127.0.0.1:9876"), and MaxAttempts(3)
+    Then Check build "Producer" successfully
+    And Shutdown the producer and consumer if they are started
diff --git a/bdd/src/main/resources/filter.push/SqlFilter.feature 
b/bdd/src/main/resources/filter.push/SqlFilter.feature
new file mode 100644
index 0000000..2fa164d
--- /dev/null
+++ b/bdd/src/main/resources/filter.push/SqlFilter.feature
@@ -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.
+
+Feature: Test SQL filtering
+
+  Scenario: Send 10 messages synchronously, then filter the messages without 
any attribute filtering, expect to consume 10 messages
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Topic("random-topic"), 
filterExpression(SubExpression:"TRUE", FilterExpressionType:"SQL92"), and 
MessageListener("default")
+    And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    Then Create a message, including the Topic("random-topic"), Tag("TagA"), 
Key("Key"), Body("Body"), and msgProps(regionId:"cn-hangzhou", price:"30")
+    And Send "10" messages "synchronous"
+    Then Check all messages send "successfully"
+    And Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Send 10 messages with messageProperty attribute 'price=10' and 
another 10 messages with 'price=30', then use 'price>20' to filter the 
messages, expect to consume 10 messages with 'price=30'
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Topic("random-topic"), 
filterExpression(SubExpression:"price>20", FilterExpressionType:"SQL92"), and 
MessageListener("default")
+    And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    Then Create a message, including the Topic("random-topic"), Tag("TagA"), 
Key("Key"), Body("Body"), and msgProps(regionId:"cn-hangzhou", price:"30")
+    And Send "10" messages with msgProps(price:"30") "synchronously"
+    And Create a message, including the Topic("random-topic"), Tag("TagA"), 
Key("Key"), Body("Body"), and msgProps(regionId:"cn-hangzhou", price:"10")
+    And Send "10" messages with msgProps(price:"10") "synchronously"
+    Then Check only all messages with msgProps(price:"30") are consumed
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Send 10 messages synchronously, then use the attribute 
'between{a,b}' to filter messages, expect to consume 10 messages
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Topic("random-topic"), 
filterExpression(SubExpression:"(price BETWEEN 10 AND 100) AND regionId IS NOT 
NUll", FilterExpressionType:"SQL92"), and MessageListener("default")
+    And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    Then Create a message, including the Topic("random-topic"), Tag("TagA"), 
Key("Key"), Body("Body"), and msgProps(regionId:"cn-hangzhou", price:"30")
+    And Send "10" messages "synchronous"
+    Then Check all messages send "successfully"
+    And Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Send 10 messages synchronously, then use unknown attributes to 
filter messages, expect to consume 0 messages
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Topic("random-topic"), 
filterExpression(SubExpression:"product = 'MQ'", FilterExpressionType:"SQL92"), 
and MessageListener("default")
+    And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    Then Create a message, including the Topic("random-topic"), Tag("TagA"), 
Key("Key"), Body("Body"), and msgProps(regionId:"cn-hangzhou", price:"30")
+    And Send "10" messages "synchronous"
+    And Check PushConsumer consumes 0 messages
+    And Shutdown the producer and consumer if they are started
+
+
+
diff --git a/bdd/src/main/resources/filter.push/SqlFilterWithOrderMsg.feature 
b/bdd/src/main/resources/filter.push/SqlFilterWithOrderMsg.feature
new file mode 100644
index 0000000..c0c838d
--- /dev/null
+++ b/bdd/src/main/resources/filter.push/SqlFilterWithOrderMsg.feature
@@ -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.
+
+Feature: Test SQL filtering with order messages
+
+  Scenario: Send 10 order messages synchronously, then filter the messages 
without any attribute filtering, expect to consume 10 messages
+    Given Create a "FIFO" topic:"random-topic" if not exist, a "Concurrently" 
group:"random-group"
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Topic("random-topic"), 
filterExpression(SubExpression:"TRUE", FilterExpressionType:"SQL92"), and 
MessageListener("default")
+    And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    Then Create a message, including the Topic("random-topic"), Body("Body"), 
messageGroup("messageGroup"), and msgProps(regionId:"cn-hangzhou", price:"30")
+    And Send "10" messages "synchronous"
+    Then Check all messages send "successfully"
+    And Check all messages that can be consumed within 60s
+    And Check the order of received messages consistent with the order of 
pre-sent messages
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Send 10 order messages synchronously, then use the attribute 
'between{a,b}' to filter messages, expect to consume 10 messages
+    Given Create a "FIFO" topic:"random-topic" if not exist, a "Concurrently" 
group:"random-group"
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Topic("random-topic"), 
filterExpression(SubExpression:"(price BETWEEN 10 AND 100) AND regionId IS NOT 
NUll", FilterExpressionType:"SQL92"), and MessageListener("default")
+    And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    Then Create a message, including the Topic("random-topic"), Body("Body"), 
messageGroup("messageGroup"), and msgProps(regionId:"cn-hangzhou", price:"30")
+    And Send "10" messages "synchronous"
+    Then Check all messages send "successfully"
+    And Check all messages that can be consumed within 60s
+    And Check the order of received messages consistent with the order of 
pre-sent messages
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Send 10 order messages synchronously, then use unknown attributes 
to filter messages, expect to consume 0 messages
+    Given Create a "FIFO" topic:"random-topic" if not exist, a "Concurrently" 
group:"random-group"
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Topic("random-topic"), 
filterExpression(SubExpression:"product = 'MQ'", FilterExpressionType:"SQL92"), 
and MessageListener("default")
+    And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    Then Create a message, including the Topic("random-topic"), Body("Body"), 
messageGroup("messageGroup"), and msgProps(regionId:"cn-hangzhou", price:"30")
+    And Send "10" messages "synchronous"
+    And Check PushConsumer consumes 0 messages
+    And Shutdown the producer and consumer if they are started
\ No newline at end of file
diff --git a/bdd/src/main/resources/filter.push/TagFilter.feature 
b/bdd/src/main/resources/filter.push/TagFilter.feature
new file mode 100644
index 0000000..862b36c
--- /dev/null
+++ b/bdd/src/main/resources/filter.push/TagFilter.feature
@@ -0,0 +1,153 @@
+# 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.
+
+Feature: Test Tag filtering
+
+  Scenario: Use Tag='TagA' to send 10 messages, then use 'TagA||TagB' to 
filter messages, expect to consume 10 messages
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Topic("random-topic"), 
filterExpression("TagA||TagB"), and MessageListener("default")
+    And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    Then Create a message, including the Topic("random-topic"), Tag("TagA"), 
Key("Key"), and Body("Body")
+    And Send "10" messages "synchronous"
+    Then Check all messages send "successfully"
+    And Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Use Tag='TagA' to send 10 messages, and use Tag='TagB' to send 
another 10 messages, then use 'TagA||TagB' to filter messages, expect to 
consume 20 messages
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Topic("random-topic"), 
filterExpression("TagA||TagB"), and MessageListener("default")
+    And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    Then Create a message, including the Topic("random-topic"), Tag("TagA"), 
Key("Key"), and Body("Body")
+    Then Send "10" messages with Tag("TagA") "synchronous"
+    And Create a message, including the Topic("random-topic"), Tag("TagB"), 
Key("Key"), and Body("Body")
+    And Send "10" messages with Tag("TagB") "synchronous"
+    Then Check all messages send "successfully"
+    And Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Use Tag='TagA' to send 10 messages, and use Tag='TagB' to send 
another 10 messages, then use '*' to filter messages, expect to consume 20 
messages
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Topic("random-topic"), filterExpression("*"), 
and MessageListener("default")
+    And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    Then Create a message, including the Topic("random-topic"), Tag("TagA"), 
Key("Key"), and Body("Body")
+    And Send "10" messages with Tag("TagA") "synchronous"
+    And Create a message, including the Topic("random-topic"), Tag("TagB"), 
Key("Key"), and Body("Body")
+    And Send "10" messages with Tag("TagB") "synchronous"
+    Then Check all messages send "successfully"
+    And Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Use Tag='TagA' to send 10 messages, then use Tag='TagB' to filter 
messages, expect to consume 0 message
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Topic("random-topic"), filterExpression("TagB"), 
and MessageListener("default")
+    And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    Then Create a message, including the Topic("random-topic"), Tag("TagA"), 
Key("Key"), and Body("Body")
+    Then Send "10" messages "synchronous"
+    Then Check all messages send "successfully"
+    And Check PushConsumer consumes 0 messages
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Use Tag='TagA' to send 10 messages, then use Tag='TagA' to filter 
messages, expect to consume 10 messages
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Topic("random-topic"), filterExpression("TagA"), 
and MessageListener("default")
+    And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    Then Create a message, including the Topic("random-topic"), Tag("TagA"), 
Key("Key"), and Body("Body")
+    Then Send "10" messages "synchronous"
+    Then Check all messages send "successfully"
+    And Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Use a very long Tag to send 10 messages, expect to consume 10 
messages
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Topic("random-topic"), filterExpression("Tag"), 
and MessageListener("default")
+    And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    Then Create a message, including the Topic("random-topic"), 
Tag("TagSize:10kB"), Key("Key"), and Body("Body")
+    Then Send "10" messages "synchronous"
+    Then Check all messages send "successfully"
+    And Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Use Tag='TagA' to send 10 messages, and use Tag='TagB' to send 
another 10 messages, then use a tag which adds space on both sides of sent tags 
to filter messages, expect to consume 20 messages
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Topic("random-topic"), filterExpression(" 
TagA||TagB "), and MessageListener("default")
+    And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    Then Create a message, including the Topic("random-topic"), Tag("TagA"), 
Key("Key"), and Body("Body")
+    And Send "10" messages with Tag("TagA") "synchronous"
+    And Create a message, including the Topic("random-topic"), Tag("TagB"), 
Key("Key"), and Body("Body")
+    And Send "10" messages with Tag("TagB") "synchronous"
+    Then Check all messages send "successfully"
+    And Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Use Tag='|@' to send 10 messages, expect to start failed (tags are 
not allowed to contain '|')
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), Tag("|@"), 
Key("Key"), and Body("Body")
+    Then Send "10" messages "synchronous"
+    And Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Use Tag='*' to send 10 messages, then use '*' to filter messages, 
expect to consume 10 messages
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Topic("random-topic"), filterExpression("*"), 
and MessageListener("default")
+    And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    Then Create a message, including the Topic("random-topic"), Tag("*"), 
Key("Key"), and Body("Body")
+    Then Send "10" messages "synchronous"
+    Then Check all messages send "successfully"
+    And Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Use Tag='TagA' to send 10 messages, and use Tag='TagB' to send 
another 10 messages, then use use || separators between two tags to filter 
messages, expect to consume 20 messages
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Topic("random-topic"), 
filterExpression("TagA||||TagB"), and MessageListener("default")
+    And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    Then Create a message, including the Topic("random-topic"), Tag("TagA"), 
Key("Key"), and Body("Body")
+    And Send "10" messages with Tag("TagA") "synchronous"
+    And Create a message, including the Topic("random-topic"), Tag("TagB"), 
Key("Key"), and Body("Body")
+    And Send "10" messages with Tag("TagB") "synchronous"
+    Then Check all messages send "successfully"
+    And Check all messages that can be consumed within 60s
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Use Tag="" to send 10 messages, and use Tag=" " to send another 10 
messages, expect to start failed
+    Given Create a "Normal" topic:"random-topic" if not exist
+    When Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), Tag(""), 
Key("Key"), and Body("Body")
+    And Send "10" messages with Tag("") "synchronous"
+    And Create a message, including the Topic("random-topic"), Tag(" "), 
Key("Key"), and Body("Body")
+    And Send "10" messages with Tag(" ") "synchronous"
+    Then Check exceptions can be thrown
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Use two Tags='BB' and 'Aa' with the same hash value to send 10 
messages, respectively, then use 'BB' to filter messages, expect to consume 10 
messages with Tag='BB'
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Topic("random-topic"), filterExpression("BB"), 
and MessageListener("default")
+    And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), Tag("BB"), 
Key("Key"), and Body("Body")
+    Then Check all messages that can be consumed within 60s
+    And Create a message, including the Topic("random-topic"), Tag("Aa"), 
Key("Key"), and Body("Body")
+    And Check PushConsumer consumes 0 messages
+    And Shutdown the producer and consumer if they are started
+
+  Scenario: Use Tag='BB' to send 10 messages, and use Tag='bb' to send another 
10 messages, expect to consume messages with tag='BB'
+    Given Create a "Normal" topic:"random-topic" if not exist, a 
"Concurrently" group:"random-group"
+    When Create a PushConsumer, set the Endpoint("127.0.0.1:9876"), 
ConsumerGroup("random-group"), Topic("random-topic"), filterExpression("BB"), 
and MessageListener("default")
+    And Create a Producer, set the Endpoint("127.0.0.1:9876"), 
RequestTimeout:("random-group"), Topic("random-topic")
+    And Create a message, including the Topic("random-topic"), Tag("BB"), 
Key("Key"), and Body("Body")
+    Then Check all messages that can be consumed within 60s
+    And Create a message, including the Topic("random-topic"), Tag("bb"), 
Key("Key"), and Body("Body")
+    And Check PushConsumer consumes 0 messages
+    And Shutdown the producer and consumer if they are started
+
diff --git a/bdd/src/main/resources/delay.feature 
b/bdd/src/main/resources/server/delay.feature
similarity index 100%
rename from bdd/src/main/resources/delay.feature
rename to bdd/src/main/resources/server/delay.feature
diff --git a/bdd/src/main/resources/normal.feature 
b/bdd/src/main/resources/server/normal.feature
similarity index 100%
rename from bdd/src/main/resources/normal.feature
rename to bdd/src/main/resources/server/normal.feature
diff --git a/bdd/src/main/resources/order.feature 
b/bdd/src/main/resources/server/order.feature
similarity index 100%
rename from bdd/src/main/resources/order.feature
rename to bdd/src/main/resources/server/order.feature
diff --git a/bdd/src/main/resources/transaction.feature 
b/bdd/src/main/resources/server/transaction.feature
similarity index 97%
rename from bdd/src/main/resources/transaction.feature
rename to bdd/src/main/resources/server/transaction.feature
index f4e13eb..23a3da4 100644
--- a/bdd/src/main/resources/transaction.feature
+++ b/bdd/src/main/resources/server/transaction.feature
@@ -23,7 +23,7 @@ Feature: Test the message transfer mode
     Then Create a message, including the Topic("random-topic"), Tag("TagA"), 
Key("Key"), and Body("Body")
     And  Send a half message
     And  Execute transaction:"<TransactionExecutor>"
-    Then Check all messages send "success"
+    Then Check all messages send "successfully"
     And Check all messages that can be consumed within 60s
     And Shutdown the producer and consumer if they are started
 
diff --git 
a/java/e2e/src/test/java/org/apache/rocketmq/broker/client/consumer/SimpleConsumerInitTest.java
 
b/java/e2e/src/test/java/org/apache/rocketmq/broker/client/consumer/SimpleConsumerInitTest.java
index 6fe84a9..7965b97 100644
--- 
a/java/e2e/src/test/java/org/apache/rocketmq/broker/client/consumer/SimpleConsumerInitTest.java
+++ 
b/java/e2e/src/test/java/org/apache/rocketmq/broker/client/consumer/SimpleConsumerInitTest.java
@@ -83,7 +83,7 @@ public class SimpleConsumerInitTest extends BaseOperate {
     }
 
     @Test
-    @DisplayName("SimpleConsumer client start without setting 
'ClientConfiguration', expect throw exception")
+    @DisplayName("Without setting 'ClientConfiguration' of the consumer 
client, expect start failed")
     public void testNoClientConfiguration() {
         assertThrows(NullPointerException.class, () -> {
             SimpleConsumer simpleConsumer = provider.newSimpleConsumerBuilder()
@@ -95,7 +95,7 @@ public class SimpleConsumerInitTest extends BaseOperate {
     }
 
     @Test
-    @DisplayName("SimpleConsumer client start without setting 'ConsumerGroup', 
expect throw exception")
+    @DisplayName("Without setting 'ConsumerGroup' of the consumer client, 
expect start failed")
     public void testNoConsumerGroup() {
         assertThrows(Exception.class, () -> {
             SimpleConsumer simpleConsumer = provider.newSimpleConsumerBuilder()
@@ -107,7 +107,7 @@ public class SimpleConsumerInitTest extends BaseOperate {
     }
 
     @Test
-    @DisplayName("SimpleConsumer client start without setting 'Subscription', 
expect throw exception")
+    @DisplayName("Without setting 'Subscription' of the consumer client, 
expect start failed")
     public void testNoSubscription() {
         assertThrows(Exception.class, () -> {
             SimpleConsumer simpleConsumer = provider.newSimpleConsumerBuilder()
@@ -119,7 +119,7 @@ public class SimpleConsumerInitTest extends BaseOperate {
     }
 
     @Test
-    @DisplayName("SimpleConsumer client start without setting 'AwaitDuration', 
expect throw exception ")
+    @DisplayName("Without setting 'AwaitDuration' of the consumer client, 
expect start failed")
     public void testNoAwaitDuration() {
         assertThrows(Exception.class, () -> {
             SimpleConsumer simpleConsumer = provider.newSimpleConsumerBuilder()
@@ -131,7 +131,7 @@ public class SimpleConsumerInitTest extends BaseOperate {
     }
 
     @Test
-    @DisplayName("SimpleConsumer client start setting empty 'AwaitDuration', 
expect throw exception ")
+    @DisplayName("Error setting 'SubscriptionExpressions' empty of the 
consumer client, except start failed")
     public void testEmptySubscription() {
         assertThrows(Exception.class, () -> {
             SimpleConsumer simpleConsumer = provider.newSimpleConsumerBuilder()
@@ -144,7 +144,7 @@ public class SimpleConsumerInitTest extends BaseOperate {
     }
 
     @Test
-    @DisplayName("SimpleConsumer client start setting 'AwaitDuration=0', 
except invoke 'receive()' throw exception")
+    @DisplayName("Error setting 'MaxMessageNum=0' of the consumer client, 
except start failed")
     public void testAwaitDurationIs0s() {
         SimpleConsumer simpleConsumer = null;
         try {
@@ -180,7 +180,7 @@ public class SimpleConsumerInitTest extends BaseOperate {
     }
 
     @Test
-    @DisplayName("SimpleConsumer client start setting 'MaxMessageNum=100000', 
except success")
+    @DisplayName("Setting 'MaxMessageNum=100000', except start success")
     public void testReceiveMaxMessageNumMore100000() {
         SimpleConsumer simpleConsumer = null;
         try {
@@ -197,8 +197,8 @@ public class SimpleConsumerInitTest extends BaseOperate {
     }
 
     @Test
-    @DisplayName("SimpleConsumer client start setting 
'invisibleDuration<1000ms', except throw exception")
-    public void testReceiveInvisibleDurationLess1000ms() {
+    @DisplayName("SimpleConsumer client start setting 
'invisibleDuration<10000ms', except throw exception")
+    public void testReceiveInvisibleDurationLess10000ms() {
         SimpleConsumer simpleConsumer = null;
         try {
             simpleConsumer = provider.newSimpleConsumerBuilder()


Reply via email to