This is an automated email from the ASF dual-hosted git repository.
lizhanhui pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/rocketmq-clients.git
The following commit(s) were added to refs/heads/master by this push:
new cf00205 Add back tests (#154)
cf00205 is described below
commit cf00205687d38d0de9fe5e22f76433f6c061c9e3
Author: Zhanhui Li <[email protected]>
AuthorDate: Mon Aug 15 16:22:02 2022 +0800
Add back tests (#154)
---
cpp/source/client/mocks/BUILD.bazel | 2 +-
cpp/source/client/mocks/include/ClientMock.h | 19 +-
cpp/source/client/tests/BUILD.bazel | 75 +++++++
cpp/source/client/tests/ClientManagerTest.cpp | 226 +++++++++++++++++++++
.../ClientTest.cpp} | 28 ++-
cpp/source/client/tests/RpcClientTest.cpp | 82 ++++++++
.../TlsHelperTest.cpp} | 19 +-
.../client/tests/TopicAssignmentInfoTest.cpp | 117 +++++++++++
cpp/source/client/tests/TracingUtilityTest.cpp | 50 +++++
9 files changed, 599 insertions(+), 19 deletions(-)
diff --git a/cpp/source/client/mocks/BUILD.bazel
b/cpp/source/client/mocks/BUILD.bazel
index a551c15..34140e5 100644
--- a/cpp/source/client/mocks/BUILD.bazel
+++ b/cpp/source/client/mocks/BUILD.bazel
@@ -24,6 +24,6 @@ cc_library(
strip_include_prefix = "//source/client/mocks/include",
deps = [
"//source/client:client_library",
- "//external:gtest",
+ "@com_google_googletest//:gtest",
],
)
\ No newline at end of file
diff --git a/cpp/source/client/mocks/include/ClientMock.h
b/cpp/source/client/mocks/include/ClientMock.h
index b88e3c8..7fc39f2 100644
--- a/cpp/source/client/mocks/include/ClientMock.h
+++ b/cpp/source/client/mocks/include/ClientMock.h
@@ -18,11 +18,16 @@
#include "Client.h"
#include "RpcClient.h"
+#include "gmock/gmock.h"
ROCKETMQ_NAMESPACE_BEGIN
class ClientMock : virtual public Client {
public:
+ MOCK_METHOD(rmq::Settings, clientSettings, (), (override));
+
+ MOCK_METHOD(ClientConfig&, config, (), (override));
+
MOCK_METHOD(void, endpointsInUse, (absl::flat_hash_set<std::string>&),
(override));
MOCK_METHOD(void, heartbeat, (), (override));
@@ -31,16 +36,22 @@ public:
MOCK_METHOD(void, onRemoteEndpointRemoval, (const
std::vector<std::string>&), (override));
- MOCK_METHOD(void, schedule, (const std::string&, const
std::function<void()>&, std::chrono::milliseconds),
+ MOCK_METHOD(void,
+ schedule,
+ (const std::string&, const std::function<void()>&,
std::chrono::milliseconds),
(override));
- MOCK_METHOD(void, createSession, (const std::string&), (override));
+ MOCK_METHOD(void, createSession, (const std::string&, bool), (override));
MOCK_METHOD(void, notifyClientTermination, (), (override));
- MOCK_METHOD(void, verify, (VerifyMessageCommand,
(std::function<void(TelemetryCommand)>)), (override));
+ MOCK_METHOD(void, verify, (MessageConstSharedPtr,
(std::function<void(TelemetryCommand)>)), (override));
+
+ MOCK_METHOD(void, recoverOrphanedTransaction, (MessageConstSharedPtr),
(override));
+
+ MOCK_METHOD(void, withCredentialsProvider,
(std::shared_ptr<CredentialsProvider>), (override));
- MOCK_METHOD(void, recoverOrphanedTransaction, (const
RecoverOrphanedTransactionCommand&), (override));
+ MOCK_METHOD(std::shared_ptr<ClientManager>, manager, (), (const, override));
};
ROCKETMQ_NAMESPACE_END
diff --git a/cpp/source/client/tests/BUILD.bazel
b/cpp/source/client/tests/BUILD.bazel
new file mode 100644
index 0000000..e88b4f5
--- /dev/null
+++ b/cpp/source/client/tests/BUILD.bazel
@@ -0,0 +1,75 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+load("@rules_cc//cc:defs.bzl", "cc_test")
+cc_test(
+ name = "tls_helper_test",
+ srcs = [
+ "TlsHelperTest.cpp",
+ ],
+ deps = [
+ "//source/admin:admin_server_library",
+ "//source/client:client_library",
+ "@com_google_googletest//:gtest_main",
+ "@boringssl//:ssl",
+ ],
+)
+
+cc_test(
+ name = "rpc_client_test",
+ srcs = [
+ "RpcClientTest.cpp",
+ ],
+ deps = [
+ "//source/client:client_library",
+ "//source/client/mocks:client_mocks",
+ "@com_google_googletest//:gtest_main",
+ "@boringssl//:ssl",
+ ],
+)
+
+cc_test(
+ name = "client_test",
+ srcs = [
+ "ClientTest.cpp",
+ ],
+ deps = [
+ "//source/client/mocks:client_mocks",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_test(
+ name = "client_manager_test",
+ srcs = [
+ "ClientManagerTest.cpp",
+ ],
+ deps = [
+ "//source/client/mocks:client_mocks",
+ "@com_google_googletest//:gtest_main",
+ ]
+)
+
+cc_test(
+ name = "topic_assignment_info_test",
+ srcs = [
+ "TopicAssignmentInfoTest.cpp",
+ ],
+ deps = [
+ "//source/client:client_library",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
\ No newline at end of file
diff --git a/cpp/source/client/tests/ClientManagerTest.cpp
b/cpp/source/client/tests/ClientManagerTest.cpp
new file mode 100644
index 0000000..1eb64e7
--- /dev/null
+++ b/cpp/source/client/tests/ClientManagerTest.cpp
@@ -0,0 +1,226 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <apache/rocketmq/v2/definition.pb.h>
+
+#include <memory>
+#include <system_error>
+
+#include "ClientManagerImpl.h"
+#include "RpcClientMock.h"
+#include "gtest/gtest.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+class ClientManagerTest : public testing::Test {
+public:
+ void SetUp() override {
+ client_manager_ = std::make_shared<ClientManagerImpl>(resource_namespace_);
+ client_manager_->start();
+ rpc_client_ = std::make_shared<testing::NiceMock<RpcClientMock>>();
+ ON_CALL(*rpc_client_, ok).WillByDefault(testing::Return(true));
+ client_manager_->addRpcClient(target_host_, rpc_client_);
+ metadata_.insert({"foo", "bar"});
+ metadata_.insert({"name", "Donald.J.Trump"});
+ }
+
+ void TearDown() override {
+ client_manager_->shutdown();
+ }
+
+protected:
+ std::string resource_namespace_{"mq://test"};
+ std::string topic_{"TestTopic"};
+ std::string target_host_{"ipv4:10.0.0.0:10911"};
+ std::shared_ptr<ClientManagerImpl> client_manager_;
+ std::shared_ptr<testing::NiceMock<RpcClientMock>> rpc_client_;
+ absl::Duration io_timeout_{absl::Seconds(3)};
+ Metadata metadata_;
+ std::string message_body_{"Message body"};
+ std::string tag_{"TagA"};
+ std::string key_{"key-0"};
+};
+
+TEST_F(ClientManagerTest, testBasic) {
+ // Ensure that start/shutdown works well.
+}
+
+TEST_F(ClientManagerTest, testResolveRoute) {
+ auto rpc_cb = [](const QueryRouteRequest& request,
InvocationContext<QueryRouteResponse>* invocation_context) {
+ auto partition = new rmq::MessageQueue();
+
partition->mutable_topic()->set_resource_namespace(request.topic().resource_namespace());
+ partition->mutable_topic()->set_name(request.topic().name());
+ partition->mutable_broker()->set_name("broker-0");
+ partition->mutable_broker()->set_id(0);
+ auto address = new rmq::Address();
+ address->set_host("10.0.0.1");
+ address->set_port(10911);
+
partition->mutable_broker()->mutable_endpoints()->set_scheme(rmq::AddressScheme::IPv4);
+
partition->mutable_broker()->mutable_endpoints()->mutable_addresses()->AddAllocated(address);
+
invocation_context->response.mutable_message_queues()->AddAllocated(partition);
+
+ invocation_context->onCompletion(true);
+ };
+ EXPECT_CALL(*rpc_client_,
asyncQueryRoute).Times(testing::AtLeast(1)).WillRepeatedly(testing::Invoke(rpc_cb));
+
+ bool completed = false;
+ absl::Mutex mtx;
+ absl::CondVar cv;
+
+ QueryRouteRequest request;
+ request.mutable_topic()->set_resource_namespace(resource_namespace_);
+ request.mutable_topic()->set_name(topic_);
+ auto callback = [&](const std::error_code& ec, const TopicRouteDataPtr&) {
+ absl::MutexLock lk(&mtx);
+ completed = true;
+ cv.SignalAll();
+ };
+ client_manager_->resolveRoute(target_host_, metadata_, request,
absl::ToChronoMilliseconds(io_timeout_), callback);
+ {
+ absl::MutexLock lk(&mtx);
+ cv.WaitWithDeadline(&mtx, absl::Now() + absl::Seconds(3));
+ }
+ EXPECT_TRUE(completed);
+}
+
+TEST_F(ClientManagerTest, testQueryAssignment) {
+ bool completed = false;
+ absl::Mutex mtx;
+ absl::CondVar cv;
+
+ auto mock_query_assignment = [&](const QueryAssignmentRequest& request,
+ InvocationContext<QueryAssignmentResponse>*
invocation_context) {
+ absl::MutexLock lk(&mtx);
+ completed = true;
+ cv.SignalAll();
+ invocation_context->onCompletion(true);
+ };
+
+ EXPECT_CALL(*rpc_client_, asyncQueryAssignment)
+ .Times(testing::AtLeast(1))
+ .WillRepeatedly(testing::Invoke(mock_query_assignment));
+ QueryAssignmentRequest request;
+ bool callback_invoked = false;
+ auto callback = [&](const std::error_code& ec, const
QueryAssignmentResponse& response) { callback_invoked = true; };
+
+ client_manager_->queryAssignment(target_host_, metadata_, request,
absl::ToChronoMilliseconds(io_timeout_), callback);
+
+ {
+ absl::MutexLock lk(&mtx);
+ if (!completed) {
+ cv.WaitWithDeadline(&mtx, absl::Now() + absl::Seconds(3));
+ }
+ }
+ EXPECT_TRUE(completed);
+ EXPECT_TRUE(callback_invoked);
+}
+
+TEST_F(ClientManagerTest, testAck) {
+ bool completed = false;
+ absl::Mutex mtx;
+ absl::CondVar cv;
+
+ auto mock_ack = [&](const AckMessageRequest& request,
InvocationContext<AckMessageResponse>* invocation_context) {
+ absl::MutexLock lk(&mtx);
+ completed = true;
+ cv.SignalAll();
+ invocation_context->onCompletion(true);
+ };
+
+ EXPECT_CALL(*rpc_client_,
asyncAck).Times(testing::AtLeast(1)).WillRepeatedly(testing::Invoke(mock_ack));
+ AckMessageRequest request;
+ bool callback_invoked = false;
+ auto callback = [&](const std::error_code& ec) { callback_invoked = true; };
+
+ client_manager_->ack(target_host_, metadata_, request,
absl::ToChronoMilliseconds(io_timeout_), callback);
+
+ {
+ absl::MutexLock lk(&mtx);
+ if (!completed) {
+ cv.WaitWithDeadline(&mtx, absl::Now() + absl::Seconds(3));
+ }
+ }
+ EXPECT_TRUE(completed);
+ EXPECT_TRUE(callback_invoked);
+}
+
+TEST_F(ClientManagerTest, testForwardMessageToDeadLetterQueue) {
+ bool completed = false;
+ absl::Mutex mtx;
+ absl::CondVar cv;
+
+ auto mock_forward = [&](const ForwardMessageToDeadLetterQueueRequest&
request,
+
InvocationContext<ForwardMessageToDeadLetterQueueResponse>* invocation_context)
{
+ absl::MutexLock lk(&mtx);
+ completed = true;
+ cv.SignalAll();
+ invocation_context->onCompletion(true);
+ };
+
+ EXPECT_CALL(*rpc_client_, asyncForwardMessageToDeadLetterQueue)
+ .Times(testing::AtLeast(1))
+ .WillRepeatedly(testing::Invoke(mock_forward));
+ ForwardMessageToDeadLetterQueueRequest request;
+ bool callback_invoked = false;
+ auto callback = [&](const std::error_code& ec) { callback_invoked = true; };
+
+ client_manager_->forwardMessageToDeadLetterQueue(target_host_, metadata_,
request,
+
absl::ToChronoMilliseconds(io_timeout_), callback);
+ {
+ absl::MutexLock lk(&mtx);
+ if (!completed) {
+ cv.WaitWithDeadline(&mtx, absl::Now() + absl::Seconds(3));
+ }
+ }
+ EXPECT_TRUE(completed);
+ EXPECT_TRUE(callback_invoked);
+}
+
+TEST_F(ClientManagerTest, testMultiplexingCall) {
+}
+
+TEST_F(ClientManagerTest, testEndTransaction) {
+ bool completed = false;
+ absl::Mutex mtx;
+ absl::CondVar cv;
+
+ auto mock_end_transaction = [&](const EndTransactionRequest& request,
+ InvocationContext<EndTransactionResponse>*
invocation_context) {
+ absl::MutexLock lk(&mtx);
+ completed = true;
+ cv.SignalAll();
+ invocation_context->onCompletion(true);
+ };
+
+ EXPECT_CALL(*rpc_client_, asyncEndTransaction)
+ .Times(testing::AtLeast(1))
+ .WillRepeatedly(testing::Invoke(mock_end_transaction));
+ EndTransactionRequest request;
+ bool callback_invoked = false;
+ auto callback = [&](const std::error_code& ec, const EndTransactionResponse&
response) { callback_invoked = true; };
+
+ client_manager_->endTransaction(target_host_, metadata_, request,
absl::ToChronoMilliseconds(io_timeout_), callback);
+ {
+ absl::MutexLock lk(&mtx);
+ if (!completed) {
+ cv.WaitWithDeadline(&mtx, absl::Now() + absl::Seconds(3));
+ }
+ }
+ EXPECT_TRUE(completed);
+ EXPECT_TRUE(callback_invoked);
+}
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/client/mocks/include/ReceiveMessageCallbackMock.h
b/cpp/source/client/tests/ClientTest.cpp
similarity index 59%
copy from cpp/source/client/mocks/include/ReceiveMessageCallbackMock.h
copy to cpp/source/client/tests/ClientTest.cpp
index 02c9588..c2be3d6 100644
--- a/cpp/source/client/mocks/include/ReceiveMessageCallbackMock.h
+++ b/cpp/source/client/tests/ClientTest.cpp
@@ -14,17 +14,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#pragma once
+#include <iostream>
+#include <memory>
+#include "ClientMock.h"
#include "gmock/gmock.h"
-
-#include "ReceiveMessageCallback.h"
+#include "gtest/gtest.h"
+#include "rocketmq/RocketMQ.h"
ROCKETMQ_NAMESPACE_BEGIN
-class ReceiveMessageCallbackMock : public ReceiveMessageCallback {
+class ClientTest : public testing::Test {
public:
- MOCK_METHOD(void, onCompletion, (const std::error_code&, const
ReceiveMessageResult&), (override));
+ void SetUp() override {
+ client_ = std::make_shared<testing::NiceMock<ClientMock>>();
+ ON_CALL(*client_, active).WillByDefault(testing::Invoke([]() {
+ std::cout << "active() is invoked" << std::endl;
+ return true;
+ }));
+ }
+
+ void TearDown() override {
+ }
+
+protected:
+ std::shared_ptr<testing::NiceMock<ClientMock>> client_;
};
+TEST_F(ClientTest, testActive) {
+ EXPECT_TRUE(client_->active());
+}
+
ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/client/tests/RpcClientTest.cpp
b/cpp/source/client/tests/RpcClientTest.cpp
new file mode 100644
index 0000000..6af7c24
--- /dev/null
+++ b/cpp/source/client/tests/RpcClientTest.cpp
@@ -0,0 +1,82 @@
+/*
+ * 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 "RpcClientMock.h"
+#include "apache/rocketmq/v2/definition.pb.h"
+#include "google/rpc/code.pb.h"
+#include "grpcpp/impl/grpc_library.h"
+#include "gtest/gtest.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+namespace ut {
+
+class RpcClientTest : public testing::Test {
+public:
+ void SetUp() override {
+ grpc::internal::GrpcLibraryInitializer initializer;
+ }
+
+ static void mockQueryRouteInfo(const QueryRouteRequest& request,
+ InvocationContext<QueryRouteResponse>*
invocation_context) {
+ invocation_context->response.mutable_status()->set_code(rmq::Code::OK);
+ for (int i = 0; i < 3; ++i) {
+ auto message_queue = new rmq::MessageQueue;
+ message_queue->mutable_topic()->set_name(request.topic().name());
+ message_queue->mutable_broker()->set_name(fmt::format("broker-{}", i));
+ message_queue->mutable_broker()->set_id(0);
+ auto endpoint = message_queue->mutable_broker()->mutable_endpoints();
+ auto address = new rmq::Address;
+ address->set_host(fmt::format("10.0.0.{}", i));
+ address->set_port(10911);
+ endpoint->mutable_addresses()->AddAllocated(address);
+
invocation_context->response.mutable_message_queues()->AddAllocated(message_queue);
+ }
+
+ invocation_context->onCompletion(true);
+ }
+};
+
+TEST_F(RpcClientTest, testMockedGetRouteInfo) {
+ RpcClientMock rpc_client_mock;
+ ON_CALL(rpc_client_mock, asyncQueryRoute(testing::_,
testing::_)).WillByDefault(testing::Invoke(mockQueryRouteInfo));
+ std::string topic = "sample_topic";
+ QueryRouteRequest request;
+ request.mutable_topic()->set_name(topic);
+ absl::flat_hash_map<std::string, std::string> metadata;
+ auto invocation_context = new InvocationContext<QueryRouteResponse>();
+ absl::Mutex mtx;
+ absl::CondVar cv;
+ bool completed = false;
+ auto callback = [&](const InvocationContext<QueryRouteResponse>*
invocation_context) {
+ EXPECT_TRUE(invocation_context->status.ok());
+ EXPECT_EQ(rmq::Code::OK, invocation_context->response.status().code());
+ EXPECT_EQ(3, invocation_context->response.message_queues().size());
+ absl::MutexLock lk(&mtx);
+ completed = true;
+ cv.SignalAll();
+ };
+ invocation_context->callback = callback;
+ rpc_client_mock.asyncQueryRoute(request, invocation_context);
+ while (!completed) {
+ absl::MutexLock lk(&mtx);
+ cv.Wait(&mtx);
+ }
+}
+
+} // namespace ut
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/client/mocks/include/ReceiveMessageCallbackMock.h
b/cpp/source/client/tests/TlsHelperTest.cpp
similarity index 66%
rename from cpp/source/client/mocks/include/ReceiveMessageCallbackMock.h
rename to cpp/source/client/tests/TlsHelperTest.cpp
index 02c9588..89745de 100644
--- a/cpp/source/client/mocks/include/ReceiveMessageCallbackMock.h
+++ b/cpp/source/client/tests/TlsHelperTest.cpp
@@ -14,17 +14,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#pragma once
-
-#include "gmock/gmock.h"
-
-#include "ReceiveMessageCallback.h"
+#include "TlsHelper.h"
+#include <gtest/gtest.h>
+#include <string>
ROCKETMQ_NAMESPACE_BEGIN
-class ReceiveMessageCallbackMock : public ReceiveMessageCallback {
-public:
- MOCK_METHOD(void, onCompletion, (const std::error_code&, const
ReceiveMessageResult&), (override));
-};
+TEST(TlsHelperTest, testSign) {
+ const char* data = "some random data for test purpose only";
+ const char* access_secret = "arbitrary-access-key";
+ const std::string& signature = TlsHelper::sign(access_secret, data);
+ const char* expect = "567868dc8e81f1e8095f88958edff1e07db4290e";
+ EXPECT_STRCASEEQ(expect, signature.c_str());
+}
ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/client/tests/TopicAssignmentInfoTest.cpp
b/cpp/source/client/tests/TopicAssignmentInfoTest.cpp
new file mode 100644
index 0000000..f406c7f
--- /dev/null
+++ b/cpp/source/client/tests/TopicAssignmentInfoTest.cpp
@@ -0,0 +1,117 @@
+/*
+ * 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 <apache/rocketmq/v2/definition.pb.h>
+
+#include <iostream>
+
+#include "TopicAssignmentInfo.h"
+#include "gtest/gtest.h"
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+class QueryAssignmentInfoTest : public testing::Test {
+protected:
+ std::string resource_namespace_{"mq://test"};
+ std::string topic_{"TopicTest"};
+ std::string broker_name_{"broker-a"};
+ int broker_id_ = 0;
+ int total_ = 16;
+};
+
+TEST_F(QueryAssignmentInfoTest, testCtor) {
+ QueryAssignmentResponse response;
+ for (int i = 0; i < total_; i++) {
+ auto assignment = new rmq::Assignment;
+
assignment->mutable_message_queue()->mutable_topic()->set_resource_namespace(resource_namespace_);
+ assignment->mutable_message_queue()->mutable_topic()->set_name(topic_);
+ assignment->mutable_message_queue()->set_id(i);
+ assignment->mutable_message_queue()->set_permission(rmq::Permission::READ);
+ auto broker = assignment->mutable_message_queue()->mutable_broker();
+ broker->set_name(broker_name_);
+ broker->set_id(broker_id_);
+ broker->mutable_endpoints()->set_scheme(rmq::AddressScheme::IPv4);
+
+ auto address = new rmq::Address;
+ address->set_host("10.0.0.1");
+ address->set_port(10911);
+ broker->mutable_endpoints()->mutable_addresses()->AddAllocated(address);
+ response.mutable_assignments()->AddAllocated(assignment);
+ }
+ response.mutable_status()->set_code(rmq::Code::OK);
+
+ TopicAssignment assignment(response);
+ EXPECT_EQ(total_, assignment.assignmentList().size());
+ const auto& item = *assignment.assignmentList().begin();
+ EXPECT_EQ(item.message_queue().broker().name(), broker_name_);
+ EXPECT_EQ(item.message_queue().topic().name(), topic_);
+ EXPECT_TRUE(item.message_queue().id() < 16);
+}
+
+TEST_F(QueryAssignmentInfoTest, testCtor2) {
+ QueryAssignmentResponse response;
+ for (int i = 0; i < total_; i++) {
+ auto assignment = new rmq::Assignment;
+
assignment->mutable_message_queue()->mutable_topic()->set_resource_namespace(resource_namespace_);
+ assignment->mutable_message_queue()->mutable_topic()->set_name(topic_);
+ assignment->mutable_message_queue()->set_id(i);
+
assignment->mutable_message_queue()->set_permission(rmq::Permission::READ_WRITE);
+ auto broker = assignment->mutable_message_queue()->mutable_broker();
+ broker->set_name(broker_name_);
+ broker->set_id(broker_id_);
+ broker->mutable_endpoints()->set_scheme(rmq::AddressScheme::IPv4);
+
+ auto address = new rmq::Address;
+ address->set_host("10.0.0.1");
+ address->set_port(10911);
+ broker->mutable_endpoints()->mutable_addresses()->AddAllocated(address);
+ response.mutable_assignments()->AddAllocated(assignment);
+ }
+ response.mutable_status()->set_code(rmq::Code::OK);
+
+ TopicAssignment assignment(response);
+ EXPECT_EQ(total_, assignment.assignmentList().size());
+ const auto& item = *assignment.assignmentList().begin();
+ EXPECT_EQ(item.message_queue().broker().name(), broker_name_);
+ EXPECT_EQ(item.message_queue().topic().name(), topic_);
+ EXPECT_TRUE(item.message_queue().id() < 16);
+}
+
+TEST_F(QueryAssignmentInfoTest, testCtor3) {
+ QueryAssignmentResponse response;
+ for (int i = 0; i < total_; i++) {
+ auto assignment = new rmq::Assignment;
+
assignment->mutable_message_queue()->mutable_topic()->set_resource_namespace(resource_namespace_);
+ assignment->mutable_message_queue()->mutable_topic()->set_name(topic_);
+ assignment->mutable_message_queue()->set_id(i);
+ assignment->mutable_message_queue()->set_permission(rmq::Permission::NONE);
+ auto broker = assignment->mutable_message_queue()->mutable_broker();
+ broker->set_name(broker_name_);
+ broker->set_id(broker_id_);
+ broker->mutable_endpoints()->set_scheme(rmq::AddressScheme::IPv4);
+
+ auto address = new rmq::Address;
+ address->set_host("10.0.0.1");
+ address->set_port(10911);
+ broker->mutable_endpoints()->mutable_addresses()->AddAllocated(address);
+ response.mutable_assignments()->AddAllocated(assignment);
+ }
+ response.mutable_status()->set_code(rmq::Code::OK);
+ TopicAssignment assignment(response);
+ EXPECT_TRUE(assignment.assignmentList().empty());
+}
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file
diff --git a/cpp/source/client/tests/TracingUtilityTest.cpp
b/cpp/source/client/tests/TracingUtilityTest.cpp
new file mode 100644
index 0000000..42b6cf0
--- /dev/null
+++ b/cpp/source/client/tests/TracingUtilityTest.cpp
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "TracingUtility.h"
+#include "gtest/gtest.h"
+#include <iostream>
+
+using namespace opentelemetry::trace;
+
+ROCKETMQ_NAMESPACE_BEGIN
+
+template <typename T>
+static std::string hex(const T& id_item) {
+ char buf[T::kSize * 2];
+ id_item.ToLowerBase16(buf);
+ return std::string(buf, sizeof(buf));
+}
+
+TEST(TracingUtilityTest, testInject) {
+ constexpr uint8_t buf_span[] = {1, 2, 3, 4, 5, 6, 7, 8};
+ constexpr uint8_t buf_trace[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16};
+ SpanContext span_context{TraceId{buf_trace}, SpanId{buf_span},
TraceFlags{true}, true};
+ EXPECT_EQ(TracingUtility::injectSpanContextToTraceParent(span_context),
+ "00-0102030405060708090a0b0c0d0e0f10-0102030405060708-01");
+}
+
+TEST(TracingUtilityTest, testExtract) {
+ SpanContext span_context =
+
TracingUtility::extractContextFromTraceParent("00-0102030405060708090a0b0c0d0e0f10-0102030405060708-01");
+
+ EXPECT_EQ(hex(span_context.trace_id()), "0102030405060708090a0b0c0d0e0f10");
+ EXPECT_EQ(hex(span_context.span_id()), "0102030405060708");
+ EXPECT_TRUE(span_context.IsSampled());
+ EXPECT_TRUE(span_context.IsRemote());
+}
+
+ROCKETMQ_NAMESPACE_END
\ No newline at end of file