First stage 1 (#83)

Add unit test for message
diff --git a/include/CCommon.h b/include/CCommon.h
index 85c5aaf..63615d5 100644
--- a/include/CCommon.h
+++ b/include/CCommon.h
@@ -36,7 +36,7 @@
     PRODUCER_SEND_SYNC_FAILED = 11,
     PRODUCER_SEND_ONEWAY_FAILED = 12,
     PRODUCER_SEND_ORDERLY_FAILED = 13,
-    PRODUCER_SEND_ASYNC_FAILED = 14,
+	PRODUCER_SEND_ASYNC_FAILED = 14,
 
     PUSHCONSUMER_ERROR_CODE_START = 20,
     PUSHCONSUMER_START_FAILED = 20,
diff --git a/include/MQClientException.h b/include/MQClientException.h
index 513621d..0adb805 100755
--- a/include/MQClientException.h
+++ b/include/MQClientException.h
@@ -25,6 +25,7 @@
 #include "RocketMQClient.h"
 #include "CCommon.h"
 
+
 namespace rocketmq {
 //<!***************************************************************************
 class ROCKETMQCLIENT_API MQException : public std::exception {
@@ -69,6 +70,7 @@
   std::string m_type;
 };
 
+
 inline std::ostream& operator<<(std::ostream& os, const MQException& e) {
   os << "Type: " << e.GetType() << " , " << e.what();
   return os;
diff --git a/include/MQMessage.h b/include/MQMessage.h
index e03c664..2ea30f4 100755
--- a/include/MQMessage.h
+++ b/include/MQMessage.h
@@ -76,8 +76,9 @@
 
   const std::string toString() const {
     std::stringstream ss;
+    std::string tags = getTags();
     ss << "Message [topic=" << m_topic << ", flag=" << m_flag
-       << ", tag=" << getTags() << "]";
+       << ", tag=" << tags << "]";
     return ss.str();
   }
 
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index f00f66c..8fcd892 100755
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -54,30 +54,45 @@
 message(status "ROCKETMQ_LIBRARIES ${ROCKETMQ_LIBRARIES}")
 
 set(CMAKE_BUILD_TYPE "Debug")
-file(GLOB files "src/*.c*")
-foreach(file ${files})
-    get_filename_component(basename ${file} NAME_WE)
-    add_executable(${basename} ${file})
-    if(MSVC)
-        if(CMAKE_CONFIGURATION_TYPES STREQUAL "Release")
-            set_target_properties( ${basename} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT" )
-        else()
-            set_target_properties( ${basename} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMTD" )
-        endif()
-    endif()
 
-    if (MSVC) 
-    	if (BUILD_ROCKETMQ_SHARED)
-        	target_link_libraries (${basename}  rocketmq_shared ${deplibs}
-        	${Boost_LIBRARIES} ${LIBEVENT_LIBRARIES} ${JSONCPP_LIBRARIES} ${x`})
-    	else()
-        	target_link_libraries (${basename}  rocketmq_static ${deplibs}
-        	${Boost_LIBRARIES} ${LIBEVENT_LIBRARIES} ${JSONCPP_LIBRARIES} ${Gtest_LIBRARIES})
-        endif()
-    else()
-            target_link_libraries (${basename}  rocketmq_shared ${deplibs})
-            target_link_libraries (${basename}  rocketmq_shared ${Gtest_LIBRARIES})
-            target_link_libraries (${basename}  rocketmq_shared ${Gmock_LIBRARIES})
-    endif()
-    
+
+function(compile files)
+	foreach(file ${files})
+	    get_filename_component(basename ${file} NAME_WE)
+	    add_executable(${basename} ${file})
+	    if(MSVC)
+	        if(CMAKE_CONFIGURATION_TYPES STREQUAL "Release")
+	            set_target_properties( ${basename} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT" )
+	        else()
+	            set_target_properties( ${basename} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMTD" )
+	        endif()
+	    endif()
+	
+	    if (MSVC) 
+	    	if (BUILD_ROCKETMQ_SHARED)
+	        	target_link_libraries (${basename}  rocketmq_shared ${deplibs}
+	        	${Boost_LIBRARIES} ${LIBEVENT_LIBRARIES} ${JSONCPP_LIBRARIES} ${x`})
+	    	else()
+	        	target_link_libraries (${basename}  rocketmq_static ${deplibs}
+	        	${Boost_LIBRARIES} ${LIBEVENT_LIBRARIES} ${JSONCPP_LIBRARIES} ${Gtest_LIBRARIES})
+	        endif()
+	    else()
+	            target_link_libraries (${basename}  rocketmq_shared ${deplibs})
+	            target_link_libraries (${basename}  rocketmq_shared ${Gtest_LIBRARIES})
+	            target_link_libraries (${basename}  rocketmq_shared ${Gmock_LIBRARIES})
+	    endif()
+	    
+	endforeach()
+endfunction()
+
+file(GLOB files "src/*.c*")
+compile("${files}")
+
+file(GLOB files "src/*")
+foreach(file ${files})
+	if(IS_DIRECTORY ${file})
+		 file(GLOB filess "${file}/*.c*")
+		 compile("${filess}")
+	endif()
 endforeach()
+
diff --git a/test/src/UrlTest.cpp b/test/src/UrlTest.cpp
index 571c8e5..c9d929a 100644
--- a/test/src/UrlTest.cpp
+++ b/test/src/UrlTest.cpp
@@ -27,6 +27,15 @@
 #include <unistd.h>
 #include <stdio.h>
 
+#include <stdio.h>
+
+#include "CProducer.h"
+#include "CCommon.h"
+#include "CMessage.h"
+#include "CSendResult.h"
+#include "CMQException.h"
+#include <unistd.h>
+
 using namespace std;
 using ::testing::InitGoogleTest;
 using ::testing::InitGoogleMock;
@@ -58,11 +67,11 @@
     cout << nums << endl;
 }
 
+
+
 int main(int argc, char* argv[]) {
     InitGoogleMock(&argc, argv);
-
-    testing::GTEST_FLAG(filter) = "Url.Url";
-    int itestts = RUN_ALL_TESTS();
-    printf("RUN_ALL_TESTS return %d" , itestts);
+	testing::GTEST_FLAG(filter) = "Url.Url";
+	int itestts = RUN_ALL_TESTS();;
     return itestts;
 }
diff --git a/test/src/message/MQDecoderTest.cpp b/test/src/message/MQDecoderTest.cpp
new file mode 100644
index 0000000..61195e6
--- /dev/null
+++ b/test/src/message/MQDecoderTest.cpp
@@ -0,0 +1,208 @@
+/*
+ * 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.
+ */
+#include "string.h"
+
+#include <stdio.h>
+#include <vector>
+#include <string>
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+#include "MemoryOutputStream.h"
+#include "MemoryInputStream.h"
+
+#include "MessageSysFlag.h"
+#include "MQMessage.h"
+#include "MQMessageExt.h"
+#include "MQMessageId.h"
+#include "MQDecoder.h"
+#include "CommandHeader.h"
+#include "UtilAll.h"
+#include "RemotingCommand.h"
+
+using namespace std;
+
+using ::testing::InitGoogleTest;
+using ::testing::InitGoogleMock;
+using testing::Return;
+
+using rocketmq::MessageSysFlag;
+using rocketmq::MQMessage;
+using rocketmq::MQMessageExt;
+using rocketmq::MQMessageId;
+using rocketmq::MQDecoder;
+using rocketmq::SendMessageRequestHeader;
+using rocketmq::RemotingCommand;
+using rocketmq::UtilAll;
+using rocketmq::MemoryInputStream;
+using rocketmq::MemoryOutputStream;
+using rocketmq::MemoryBlock;
+
+TEST(decoder, messageId) {
+	int host;
+	int port;
+	string msgIdStr = MQDecoder::createMessageId(
+			rocketmq::IPPort2socketAddress(inet_addr("127.0.0.1"), 10091),
+			(int64) 1024);
+	MQMessageId msgId = MQDecoder::decodeMessageId(msgIdStr);
+
+	EXPECT_EQ(msgId.getOffset(), 1024);
+
+	rocketmq::socketAddress2IPPort(msgId.getAddress(), host, port);
+	EXPECT_EQ(host, inet_addr("127.0.0.1"));
+	EXPECT_EQ(port, 10091);
+}
+
+TEST( decoder , decoder ) {
+
+	MQMessageExt mext;
+	MemoryOutputStream *memoryOut = new MemoryOutputStream(1024);
+
+	// 1 TOTALSIZE 4
+	memoryOut->writeIntBigEndian(107);
+	mext.setStoreSize(107);
+
+	// 2 MAGICCODE sizeof(int)  8=4+4
+	memoryOut->writeIntBigEndian(14);
+
+	// 3 BODYCRC  12=8+4
+	memoryOut->writeIntBigEndian(24);
+	mext.setBodyCRC(24);
+	// 4 QUEUEID 16=12+4
+	memoryOut->writeIntBigEndian(4);
+	mext.setQueueId(4);
+	// 5 FLAG    20=16+4
+	memoryOut->writeIntBigEndian(4);
+	mext.setFlag(4);
+	// 6 QUEUEOFFSET  28 = 20+8
+	memoryOut->writeInt64BigEndian((int64) 1024);
+	mext.setQueueOffset(1024);
+	// 7 PHYSICALOFFSET 36=28+8
+	memoryOut->writeInt64BigEndian((int64) 2048);
+	mext.setCommitLogOffset(2048);
+	// 8 SYSFLAG  40=36+4
+	memoryOut->writeIntBigEndian(0);
+	mext.setSysFlag(0);
+	// 9 BORNTIMESTAMP 48 = 40+8
+	memoryOut->writeInt64BigEndian((int64) 4096);
+	mext.setBornTimestamp(4096);
+	// 10 BORNHOST 56= 48+8
+	memoryOut->writeIntBigEndian(inet_addr("127.0.0.1"));
+	memoryOut->writeIntBigEndian(10091);
+	mext.setBornHost(rocketmq::IPPort2socketAddress(inet_addr("127.0.0.1"), 10091));
+	// 11 STORETIMESTAMP 64 =56+8
+	memoryOut->writeInt64BigEndian((int64) 4096);
+	mext.setStoreTimestamp(4096);
+	// 12 STOREHOST 72 = 64+8
+	memoryOut->writeIntBigEndian(inet_addr("127.0.0.2"));
+	memoryOut->writeIntBigEndian(10092);
+	mext.setStoreHost(rocketmq::IPPort2socketAddress(inet_addr("127.0.0.2"), 10092));
+	// 13 RECONSUMETIMES 76 = 72+4
+	mext.setReconsumeTimes(111111);
+	memoryOut->writeIntBigEndian(mext.getReconsumeTimes());
+	// 14 Prepared Transaction Offset 84 = 76+8
+	memoryOut->writeInt64BigEndian((int64) 12);
+	mext.setPreparedTransactionOffset(12);
+	// 15 BODY 88 = 84+4   10
+	string *body = new string("1234567890");
+	mext.setBody(body->c_str());
+	memoryOut->writeIntBigEndian(10);
+	memoryOut->write(body->c_str(), body->size());
+
+	// 16 TOPIC
+	memoryOut->writeByte(10);
+	memoryOut->write(body->c_str(), body->size());
+	mext.setTopic(body->c_str());
+
+	//17 PROPERTIES
+	memoryOut->writeShortBigEndian(0);
+
+	mext.setMsgId(MQDecoder::createMessageId(mext.getStoreHost(),(int64)mext.getCommitLogOffset()));
+
+	vector<MQMessageExt> mqvec;
+	MemoryBlock block = memoryOut->getMemoryBlock();
+	MQDecoder::decodes(&block, mqvec);
+	EXPECT_EQ(mqvec.size(), 1);
+	std::cout<< mext.toString()<<"\n";
+	std::cout<< mqvec[0].toString()<<"\n";
+	EXPECT_EQ(mqvec[0].toString() , mext.toString());
+
+	mqvec.clear();
+	MQDecoder::decodes(&block, mqvec , false);
+	EXPECT_FALSE(mqvec[0].getBody().size());
+
+//===============================================================
+	// 8 SYSFLAG  40=36+4
+	mext.setSysFlag(0 | MessageSysFlag::CompressedFlag);
+	memoryOut->setPosition(36);
+	memoryOut->writeIntBigEndian( mext.getSysFlag());
+
+	//15 Body 84
+	string outBody;
+	string boody("123123123");
+	UtilAll::deflate(boody, outBody, 5);
+	mext.setBody(outBody);
+
+	memoryOut->setPosition(84);
+	memoryOut->writeIntBigEndian(outBody.size());
+	memoryOut->write(outBody.c_str(), outBody.size());
+
+	// 16 TOPIC
+	memoryOut->writeByte(10);
+	memoryOut->write(body->c_str(), body->size());
+	mext.setTopic(body->c_str());
+
+	//17 PROPERTIES
+	map<string, string> properties;
+	properties["RocketMQ"] = "cpp-client";
+	properties[MQMessage::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX] = "123456";
+	mext.setProperties(properties);
+	mext.setMsgId("123456");
+
+	string proString = MQDecoder::messageProperties2String(properties);
+
+	memoryOut->writeShortBigEndian(proString.size());
+	memoryOut->write(proString.c_str(), proString.size());
+
+	mext.setStoreSize( memoryOut->getDataSize());
+	memoryOut->setPosition(0);
+	memoryOut->writeIntBigEndian( mext.getStoreSize() );
+
+
+	block = memoryOut->getMemoryBlock();
+	MQDecoder::decodes(&block, mqvec);
+	EXPECT_EQ(mqvec[0].toString() , mext.toString());
+
+}
+
+TEST(decoder , messagePropertiesAndToString){
+	map<string, string> properties;
+	properties["RocketMQ"] = "cpp-client";
+	string proString = MQDecoder::messageProperties2String(properties);
+
+	map<string, string> newProperties;
+	MQDecoder::string2messageProperties(proString ,newProperties );
+	EXPECT_EQ(properties , newProperties);
+}
+
+int main(int argc, char* argv[]) {
+	InitGoogleMock(&argc, argv);
+
+	testing::GTEST_FLAG(filter) = "decoder.*";
+	int itestts = RUN_ALL_TESTS();
+	return itestts;
+}
diff --git a/test/src/message/MQMessageExtTest.cpp b/test/src/message/MQMessageExtTest.cpp
new file mode 100644
index 0000000..f4b70c1
--- /dev/null
+++ b/test/src/message/MQMessageExtTest.cpp
@@ -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.
+ */
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+#include "SocketUtil.h"
+#include "TopicFilterType.h"
+#include "MessageSysFlag.h"
+#include "MQMessageExt.h"
+
+using ::testing::InitGoogleTest;
+using ::testing::InitGoogleMock;
+using testing::Return;
+
+using rocketmq::MQMessageExt;
+using rocketmq::TopicFilterType;
+using rocketmq::MessageSysFlag;
+
+
+
+
+TEST(messageExt, init){
+	MQMessageExt messageExt;
+	EXPECT_EQ(messageExt.getQueueOffset() , 0);
+	EXPECT_EQ(messageExt.getCommitLogOffset() , 0);
+	EXPECT_EQ(messageExt.getBornTimestamp() , 0);
+	EXPECT_EQ(messageExt.getStoreTimestamp() , 0);
+	EXPECT_EQ(messageExt.getPreparedTransactionOffset() , 0);
+	EXPECT_EQ(messageExt.getQueueId(), 0 );
+	EXPECT_EQ(messageExt.getStoreSize() , 0);
+	EXPECT_EQ(messageExt.getReconsumeTimes() , 3);
+	EXPECT_EQ(messageExt.getBodyCRC() , 0);
+	EXPECT_EQ(messageExt.getMsgId() , "");
+	EXPECT_EQ(messageExt.getOffsetMsgId() , "");
+
+
+	messageExt.setQueueOffset(1);
+	EXPECT_EQ(messageExt.getQueueOffset() , 1);
+
+	messageExt.setCommitLogOffset(1024);
+	EXPECT_EQ(messageExt.getCommitLogOffset() , 1024);
+
+	messageExt.setBornTimestamp(1024);
+	EXPECT_EQ(messageExt.getBornTimestamp() , 1024);
+
+	messageExt.setStoreTimestamp(2048);
+	EXPECT_EQ(messageExt.getStoreTimestamp() , 2048);
+
+	messageExt.setPreparedTransactionOffset(4096);
+	EXPECT_EQ(messageExt.getPreparedTransactionOffset() , 4096);
+
+	messageExt.setQueueId(2);
+	EXPECT_EQ(messageExt.getQueueId(), 2 );
+
+	messageExt.setStoreSize(12);
+	EXPECT_EQ(messageExt.getStoreSize() , 12);
+
+	messageExt.setReconsumeTimes(48);
+	EXPECT_EQ(messageExt.getReconsumeTimes() , 48);
+
+	messageExt.setBodyCRC(32);
+	EXPECT_EQ(messageExt.getBodyCRC() , 32);
+
+	messageExt.setMsgId("MsgId");
+	EXPECT_EQ(messageExt.getMsgId() , "MsgId");
+
+	messageExt.setOffsetMsgId("offsetMsgId");
+	EXPECT_EQ(messageExt.getOffsetMsgId() , "offsetMsgId");
+
+	messageExt.setBornTimestamp(1111);
+	EXPECT_EQ(messageExt.getBornTimestamp( ) ,1111);
+
+	messageExt.setStoreTimestamp(2222);
+	EXPECT_EQ(messageExt.getStoreTimestamp() , 2222);
+
+
+
+	struct sockaddr_in sa;
+	sa.sin_family = AF_INET;
+	sa.sin_port = htons(10091);
+	sa.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+	sockaddr bornHost;
+	memcpy(&bornHost, &sa, sizeof(sockaddr));
+
+	messageExt.setBornHost(bornHost);
+	EXPECT_EQ(messageExt.getBornHostNameString() , rocketmq::getHostName(bornHost));
+	EXPECT_EQ(messageExt.getBornHostString() , rocketmq::socketAddress2String(bornHost));
+
+	struct sockaddr_in storeSa;
+	storeSa.sin_family = AF_INET;
+	storeSa.sin_port = htons(10092);
+	storeSa.sin_addr.s_addr = inet_addr("127.0.0.2");
+
+	sockaddr storeHost;
+	memcpy(&storeHost, &storeSa, sizeof(sockaddr));
+	messageExt.setStoreHost(storeHost);
+	EXPECT_EQ(messageExt.getStoreHostString() , rocketmq::socketAddress2String(storeHost));
+
+
+	MQMessageExt twoMessageExt(2 , 1024 , bornHost , 2048 , storeHost , "msgId");
+	EXPECT_EQ(twoMessageExt.getQueueOffset() , 0);
+	EXPECT_EQ(twoMessageExt.getCommitLogOffset() , 0);
+	EXPECT_EQ(twoMessageExt.getBornTimestamp() , 1024);
+	EXPECT_EQ(twoMessageExt.getStoreTimestamp() , 2048);
+	EXPECT_EQ(twoMessageExt.getPreparedTransactionOffset() , 0);
+	EXPECT_EQ(twoMessageExt.getQueueId(), 2 );
+	EXPECT_EQ(twoMessageExt.getStoreSize() , 0);
+	EXPECT_EQ(twoMessageExt.getReconsumeTimes() , 3);
+	EXPECT_EQ(twoMessageExt.getBodyCRC() , 0);
+	EXPECT_EQ(twoMessageExt.getMsgId() , "msgId");
+	EXPECT_EQ(twoMessageExt.getOffsetMsgId() , "");
+
+	EXPECT_EQ(twoMessageExt.getBornHostNameString() , rocketmq::getHostName(bornHost));
+	EXPECT_EQ(twoMessageExt.getBornHostString() , rocketmq::socketAddress2String(bornHost));
+
+	EXPECT_EQ(twoMessageExt.getStoreHostString() , rocketmq::socketAddress2String(storeHost));
+
+	EXPECT_EQ(MQMessageExt::parseTopicFilterType(MessageSysFlag::MultiTagsFlag) , TopicFilterType::MULTI_TAG);
+
+	EXPECT_EQ(MQMessageExt::parseTopicFilterType(0) , TopicFilterType::SINGLE_TAG);
+
+}
+
+
+int main(int argc, char* argv[]) {
+	InitGoogleMock(&argc, argv);
+
+	testing::GTEST_FLAG(filter) = "messageExt.init";
+	int itestts = RUN_ALL_TESTS();
+	return itestts;
+}
diff --git a/test/src/message/MQMessageIdTest.cpp b/test/src/message/MQMessageIdTest.cpp
new file mode 100644
index 0000000..e19e0ba
--- /dev/null
+++ b/test/src/message/MQMessageIdTest.cpp
@@ -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.
+ */
+#include <stdio.h>
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include "MQMessageId.h"
+
+using namespace std;
+using ::testing::InitGoogleTest;
+using ::testing::InitGoogleMock;
+using testing::Return;
+
+using rocketmq::MQMessageId;
+
+
+
+TEST(messageId , id) {
+	int host;
+	int port;
+	sockaddr addr = rocketmq::IPPort2socketAddress(inet_addr("127.0.0.1") , 10091);
+    MQMessageId id(addr, 1024);
+
+	rocketmq::socketAddress2IPPort(id.getAddress() ,host , port );
+	EXPECT_EQ(host , inet_addr("127.0.0.1"));
+	EXPECT_EQ(port , 10091);
+	EXPECT_EQ(id.getOffset() , 1024);
+
+	id.setAddress(rocketmq::IPPort2socketAddress(inet_addr("127.0.0.2") , 10092));
+	id.setOffset(2048);
+
+	rocketmq::socketAddress2IPPort(id.getAddress() ,host , port );
+	EXPECT_EQ(host , inet_addr("127.0.0.2"));
+	EXPECT_EQ(port , 10092);
+	EXPECT_EQ(id.getOffset() , 2048);
+}
+
+
+int main(int argc, char* argv[]) {
+	InitGoogleMock(&argc, argv);
+
+	testing::GTEST_FLAG(filter) = "messageId.id";
+	int itestts = RUN_ALL_TESTS();
+	return itestts;
+}
diff --git a/test/src/message/MQMessageQueueTest.cpp b/test/src/message/MQMessageQueueTest.cpp
new file mode 100644
index 0000000..cfedca0
--- /dev/null
+++ b/test/src/message/MQMessageQueueTest.cpp
@@ -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.
+ */
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+#include "MQMessageQueue.h"
+
+using ::testing::InitGoogleTest;
+using ::testing::InitGoogleMock;
+using testing::Return;
+
+using rocketmq::MQMessageQueue;
+
+TEST(messageQueue, init){
+	MQMessageQueue messageQueue;
+	EXPECT_EQ(messageQueue.getBrokerName() , "");
+	EXPECT_EQ(messageQueue.getTopic()      , "");
+	EXPECT_EQ(messageQueue.getQueueId() , -1);
+
+	MQMessageQueue twoMessageQueue("testTopic" ,"testBroker" , 1);
+	EXPECT_EQ(twoMessageQueue.getBrokerName() ,"testBroker");
+	EXPECT_EQ(twoMessageQueue.getTopic(), "testTopic");
+	EXPECT_EQ(twoMessageQueue.getQueueId() , 1);
+
+	MQMessageQueue threeMessageQueue("threeTestTopic" ,"threeTestBroker" , 2);
+	MQMessageQueue frouMessageQueue(threeMessageQueue);
+	EXPECT_EQ(frouMessageQueue.getBrokerName() ,"threeTestBroker");
+	EXPECT_EQ(frouMessageQueue.getTopic(), "threeTestTopic");
+	EXPECT_EQ(frouMessageQueue.getQueueId() , 2);
+
+	frouMessageQueue = twoMessageQueue;
+	EXPECT_EQ(frouMessageQueue.getBrokerName() ,"testBroker");
+	EXPECT_EQ(frouMessageQueue.getTopic() , "testTopic");
+	EXPECT_EQ(frouMessageQueue.getQueueId() , 1);
+
+	frouMessageQueue.setBrokerName("frouTestBroker");
+	frouMessageQueue.setTopic("frouTestTopic");
+	frouMessageQueue.setQueueId(4);
+	EXPECT_EQ(frouMessageQueue.getBrokerName() ,"frouTestBroker");
+	EXPECT_EQ(frouMessageQueue.getTopic() , "frouTestTopic");
+	EXPECT_EQ(frouMessageQueue.getQueueId() , 4);
+}
+
+TEST(messageQueue , operators ){
+	MQMessageQueue messageQueue;
+	EXPECT_EQ(messageQueue , messageQueue);
+	EXPECT_EQ(messageQueue.compareTo(messageQueue) , 0);
+
+
+	MQMessageQueue twoMessageQueue;
+	EXPECT_EQ(messageQueue , twoMessageQueue);
+	EXPECT_EQ(messageQueue.compareTo(twoMessageQueue) , 0);
+
+	twoMessageQueue.setTopic("testTopic");
+	EXPECT_FALSE(messageQueue == twoMessageQueue);
+	EXPECT_FALSE(messageQueue.compareTo(twoMessageQueue) == 0);
+
+
+	twoMessageQueue.setQueueId(1);
+	EXPECT_FALSE(messageQueue == twoMessageQueue);
+	EXPECT_FALSE(messageQueue.compareTo(twoMessageQueue) == 0);
+
+	twoMessageQueue.setBrokerName("testBroker");
+	EXPECT_FALSE(messageQueue == twoMessageQueue);
+	EXPECT_FALSE(messageQueue.compareTo(twoMessageQueue) == 0);
+
+
+}
+
+int main(int argc, char* argv[]) {
+	InitGoogleMock(&argc, argv);
+
+	testing::GTEST_FLAG(filter) = "messageQueue.*";
+	int itestts = RUN_ALL_TESTS();
+	return itestts;
+}
diff --git a/test/src/message/MQMessageTest.cpp b/test/src/message/MQMessageTest.cpp
new file mode 100644
index 0000000..4ab38be
--- /dev/null
+++ b/test/src/message/MQMessageTest.cpp
@@ -0,0 +1,157 @@
+/*
+ * 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.
+ */
+#include <stdio.h>
+
+#include <map>
+#include <string>
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include "MQMessage.h"
+
+using namespace std;
+
+using ::testing::InitGoogleTest;
+using ::testing::InitGoogleMock;
+using testing::Return;
+
+using rocketmq::MQMessage;
+
+
+TEST(message, Init){
+
+	MQMessage messageOne;
+	EXPECT_EQ(messageOne.getTopic(), "");
+	EXPECT_EQ(messageOne.getBody() , "");
+	//EXPECT_EQ(messageOne.getTags() , "");
+	EXPECT_EQ(messageOne.getFlag() , 0);
+
+	MQMessage messageTwo("test" , "testBody");
+	EXPECT_EQ(messageTwo.getTopic(), "test");
+	EXPECT_EQ(messageTwo.getBody() , "testBody");
+	//EXPECT_EQ(messageTwo.getTags() , "");
+	EXPECT_EQ(messageTwo.getFlag() , 0);
+
+	MQMessage messageThree("test" ,"tagTest" ,"testBody");
+	EXPECT_EQ(messageThree.getTopic(), "test");
+	EXPECT_EQ(messageThree.getBody() , "testBody");
+	//EXPECT_EQ(messageThree.getTags() , "tagTest");
+	EXPECT_EQ(messageThree.getFlag() , 0);
+
+
+	MQMessage messageFour("test" ,"tagTest" , "testKey" , "testBody");
+	EXPECT_EQ(messageFour.getTopic(), "test");
+	EXPECT_EQ(messageFour.getBody() , "testBody");
+	//EXPECT_EQ(messageFour.getTags() , "tagTest");
+	EXPECT_EQ(messageFour.getKeys() , "testKey");
+	EXPECT_EQ(messageFour.getFlag() , 0);
+
+
+	MQMessage messageFive("test" ,"tagTest" , "testKey" , 1,"testBody" , 2);
+	EXPECT_EQ(messageFive.getTopic(), "test");
+	EXPECT_EQ(messageFive.getBody() , "testBody");
+	//EXPECT_EQ(messageFive.getTags() , "tagTest");
+	EXPECT_EQ(messageFive.getKeys() , "testKey");
+	EXPECT_EQ(messageFive.getFlag() , 1);
+
+	MQMessage messageSix(messageFive);
+	EXPECT_EQ(messageSix.getTopic(), "test");
+	EXPECT_EQ(messageSix.getBody() , "testBody");
+	//EXPECT_EQ(messageSix.getTags() , "tagTest");
+	EXPECT_EQ(messageSix.getKeys() , "testKey");
+	EXPECT_EQ(messageSix.getFlag() , 1);
+}
+
+
+TEST(message , info){
+	MQMessage message;
+
+	EXPECT_EQ(message.getTopic(), "");
+	message.setTopic("testTopic");
+	EXPECT_EQ(message.getTopic(), "testTopic");
+	char *topic = "testTopic";
+	message.setTopic(topic , 5);
+	EXPECT_EQ(message.getTopic(), "testT");
+
+	EXPECT_EQ(message.getBody() , "");
+	message.setBody("testBody");
+	EXPECT_EQ(message.getBody() , "testBody");
+
+	char *body = "testBody";
+	message.setBody(body , 5);
+	EXPECT_EQ(message.getBody(), "testB");
+
+	string tags (message.getTags());
+	EXPECT_EQ(tags , "");
+	EXPECT_EQ(message.getFlag() , 0);
+	message.setFlag(2);
+	EXPECT_EQ(message.getFlag() , 2);
+
+	EXPECT_EQ(message.isWaitStoreMsgOK(), true);
+	message.setWaitStoreMsgOK(false);
+	EXPECT_EQ(message.isWaitStoreMsgOK(), false);
+	message.setWaitStoreMsgOK(true);
+	EXPECT_EQ(message.isWaitStoreMsgOK(), true);
+
+	string keys (message.getTags());
+	EXPECT_EQ(keys , "");
+	message.setKeys("testKeys");
+	EXPECT_EQ(message.getKeys() , "testKeys");
+
+	EXPECT_EQ(message.getDelayTimeLevel() ,0);
+	message.setDelayTimeLevel(1);
+	EXPECT_EQ(message.getDelayTimeLevel() ,1);
+
+	message.setSysFlag(1);
+	EXPECT_EQ(message.getSysFlag() ,1);
+}
+
+TEST(message , properties){
+	MQMessage message;
+	EXPECT_EQ(message.getProperties().size() , 1);
+	EXPECT_STREQ(message.getProperty(MQMessage::PROPERTY_TRANSACTION_PREPARED ).c_str() , "");
+
+	message.setProperty(MQMessage::PROPERTY_TRANSACTION_PREPARED , "true");
+	EXPECT_EQ(message.getProperties().size() , 2);
+	EXPECT_EQ(message.getSysFlag() , 4);
+	EXPECT_EQ(message.getProperty(MQMessage::PROPERTY_TRANSACTION_PREPARED ) , "true");
+
+	message.setProperty(MQMessage::PROPERTY_TRANSACTION_PREPARED , "false");
+	EXPECT_EQ(message.getProperties().size() , 2);
+	EXPECT_EQ(message.getSysFlag() , 0);
+	EXPECT_EQ(message.getProperty(MQMessage::PROPERTY_TRANSACTION_PREPARED ) , "false");
+
+	map<string, string> newProperties ;
+
+	newProperties[MQMessage::PROPERTY_TRANSACTION_PREPARED]="true";
+	message.setProperties(newProperties);
+	EXPECT_EQ(message.getSysFlag() , 4);
+	EXPECT_EQ(message.getProperty(MQMessage::PROPERTY_TRANSACTION_PREPARED ) , "true");
+
+	newProperties[MQMessage::PROPERTY_TRANSACTION_PREPARED]="false";
+	message.setProperties(newProperties);
+	EXPECT_EQ(message.getSysFlag() , 0);
+	EXPECT_EQ(message.getProperty(MQMessage::PROPERTY_TRANSACTION_PREPARED ) , "false");
+}
+
+int main(int argc, char* argv[]) {
+	InitGoogleMock(&argc, argv);
+
+	testing::GTEST_FLAG(filter) = "message.info";
+	int itestts = RUN_ALL_TESTS();
+	return itestts;
+}