Files
Alicho/tests/unit/communication/communication_manager_test.cpp
2025-10-28 10:27:49 +08:00

561 lines
20 KiB
C++

// ================================================================================================
// Audio Backend - 通信管理器测试
// ================================================================================================
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "communication/manager/communication_manager.h"
#include "tests/common/test_fixtures.h"
#include <thread>
#include <chrono>
#include <vector>
#include <string>
#include <mutex>
#include <condition_variable>
#include <atomic>
using namespace audio_backend;
using namespace audio_backend::communication;
using namespace std::chrono_literals;
// 测试消息类
class TestCommMessage : public Message {
public:
TestCommMessage(const std::string& content = "")
: Message("TestCommMessage"), content_(content) {}
void set_content(const std::string& content) { content_ = content; }
const std::string& content() const { return content_; }
// 实现虚函数
size_t estimated_size() const override { return sizeof(*this) + content_.size(); }
Priority priority() const override { return Priority::Normal; }
TransportChannel preferred_channel() const override { return TransportChannel::ZeroMQ; }
private:
std::string content_;
};
// 高优先级测试消息
class HighPriorityMessage : public Message {
public:
HighPriorityMessage(const std::string& content = "")
: Message("HighPriorityMessage"), content_(content) {}
void set_content(const std::string& content) { content_ = content; }
const std::string& content() const { return content_; }
// 实现虚函数
size_t estimated_size() const override { return sizeof(*this) + content_.size(); }
Priority priority() const override { return Priority::High; }
TransportChannel preferred_channel() const override { return TransportChannel::Direct; }
private:
std::string content_;
};
// 共享内存优先消息
class SharedMemoryMessage : public Message {
public:
SharedMemoryMessage(const std::string& content = "")
: Message("SharedMemoryMessage"), content_(content) {}
void set_content(const std::string& content) { content_ = content; }
const std::string& content() const { return content_; }
// 实现虚函数
size_t estimated_size() const override { return sizeof(*this) + content_.size(); }
Priority priority() const override { return Priority::Normal; }
TransportChannel preferred_channel() const override { return TransportChannel::SharedMemory; }
private:
std::string content_;
};
// 通信管理器测试固定装置
class CommunicationManagerTest : public test::CommunicationTest {
protected:
void SetUp() override {
test::CommunicationTest::SetUp();
// 注册测试消息类型
message_factory_.register_message<TestCommMessage>("TestCommMessage");
message_factory_.register_message<HighPriorityMessage>("HighPriorityMessage");
message_factory_.register_message<SharedMemoryMessage>("SharedMemoryMessage");
// 创建基本配置
CommunicationConfig config;
config.process_name = "test_process";
config.routing_strategy = RoutingStrategy::Auto;
config.enable_zmq = true;
config.enable_shm = true;
config.serializer_name = "protobuf";
// ZeroMQ配置
ZmqConfig zmq_config;
zmq_config.endpoint = "tcp://127.0.0.1:5555";
zmq_config.socket_type = ZMQ_REP;
zmq_config.bind_instead_of_connect = true;
config.zmq_configs.push_back(zmq_config);
// 共享内存配置
config.shm_config.segment_name = "test_shm_segment";
config.shm_config.segment_size = 1024 * 1024;
config.shm_config.create_if_not_exists = true;
config.shm_config.remove_on_destroy = true;
// 创建通信管理器
manager_ = std::make_unique<CommunicationManager>(config, message_factory_);
}
void TearDown() override {
// 关闭管理器
if (manager_ && manager_->is_initialized()) {
manager_->shutdown();
}
manager_.reset();
client_manager_.reset();
test::CommunicationTest::TearDown();
}
// 创建客户端通信管理器
std::unique_ptr<CommunicationManager> create_client_manager() {
CommunicationConfig config;
config.process_name = "test_client";
config.routing_strategy = RoutingStrategy::Auto;
config.enable_zmq = true;
config.enable_shm = true;
config.serializer_name = "protobuf";
// ZeroMQ配置 (客户端使用REQ模式连接到服务器)
ZmqConfig zmq_config;
zmq_config.endpoint = "tcp://127.0.0.1:5555";
zmq_config.socket_type = ZMQ_REQ;
zmq_config.bind_instead_of_connect = false;
config.zmq_configs.push_back(zmq_config);
// 共享内存配置
config.shm_config.segment_name = "test_shm_segment";
config.shm_config.segment_size = 1024 * 1024;
config.shm_config.create_if_not_exists = false; // 客户端不创建共享内存
config.shm_config.remove_on_destroy = false;
return std::make_unique<CommunicationManager>(config, message_factory_);
}
protected:
MessageFactory message_factory_;
std::unique_ptr<CommunicationManager> manager_;
std::unique_ptr<CommunicationManager> client_manager_;
};
// 测试创建和初始化
TEST_F(CommunicationManagerTest, CreateAndInitialize) {
// 验证创建状态
EXPECT_FALSE(manager_->is_initialized());
// 验证配置
const auto& config = manager_->config();
EXPECT_EQ(config.process_name, "test_process");
EXPECT_EQ(config.routing_strategy, RoutingStrategy::Auto);
EXPECT_TRUE(config.enable_zmq);
EXPECT_TRUE(config.enable_shm);
// 初始化
EXPECT_EQ(manager_->initialize(), CommError::Success);
EXPECT_TRUE(manager_->is_initialized());
// 获取统计信息
const auto& stats = manager_->get_statistics();
EXPECT_EQ(stats.total_messages_sent.load(), 0);
EXPECT_EQ(stats.total_messages_received.load(), 0);
// 关闭
EXPECT_EQ(manager_->shutdown(), CommError::Success);
EXPECT_FALSE(manager_->is_initialized());
}
// 测试消息路由注册和查找
TEST_F(CommunicationManagerTest, MessageRouting) {
// 初始化管理器
ASSERT_EQ(manager_->initialize(), CommError::Success);
// 添加路由规则
MessageRoute route;
route.message_type = "TestCommMessage";
route.destination = "tcp://localhost:5555";
route.strategy = RoutingStrategy::ZeroMQOnly;
route.qos = QoS::Reliable;
route.priority = 100;
manager_->add_route(route);
// 获取路由列表
auto routes = manager_->get_routes();
EXPECT_EQ(routes.size(), 1);
EXPECT_EQ(routes[0].message_type, "TestCommMessage");
EXPECT_EQ(routes[0].destination, "tcp://localhost:5555");
// 移除路由
manager_->remove_route("TestCommMessage");
routes = manager_->get_routes();
EXPECT_EQ(routes.size(), 0);
// 关闭
EXPECT_EQ(manager_->shutdown(), CommError::Success);
}
// 测试消息处理器注册
TEST_F(CommunicationManagerTest, MessageHandlerRegistration) {
// 初始化管理器
ASSERT_EQ(manager_->initialize(), CommError::Success);
// 创建消息处理器
bool handler_called = false;
std::string received_content;
auto handler = [&](std::unique_ptr<IMessage> message) {
auto* test_message = dynamic_cast<TestCommMessage*>(message.get());
if (test_message) {
handler_called = true;
received_content = test_message->content();
}
};
// 注册消息处理器
EXPECT_EQ(manager_->register_message_handler("TestCommMessage", handler), CommError::Success);
// 创建测试消息
auto message = std::make_unique<TestCommMessage>("测试消息内容");
// 手动调用处理逻辑(模拟接收消息)
manager_->handle_received_message(std::move(message));
// 验证处理器被调用
EXPECT_TRUE(handler_called);
EXPECT_EQ(received_content, "测试消息内容");
// 注销处理器
EXPECT_EQ(manager_->unregister_message_handler("TestCommMessage"), CommError::Success);
// 尝试注销不存在的处理器
EXPECT_NE(manager_->unregister_message_handler("NonExistentMessage"), CommError::Success);
// 关闭
EXPECT_EQ(manager_->shutdown(), CommError::Success);
}
// 测试事件监听器
TEST_F(CommunicationManagerTest, EventListeners) {
// 初始化管理器
ASSERT_EQ(manager_->initialize(), CommError::Success);
// 创建事件监听器
class TestEventListener : public ICommunicationEventListener {
public:
void on_message_sent(const std::string& message_type, size_t size, const std::string& transport) override {
messages_sent_++;
last_sent_type_ = message_type;
}
void on_message_received(const std::string& message_type, size_t size, const std::string& transport) override {
messages_received_++;
last_received_type_ = message_type;
}
void on_transport_connected(const std::string& transport_name) override {
transports_connected_++;
last_connected_transport_ = transport_name;
}
void on_transport_disconnected(const std::string& transport_name) override {
transports_disconnected_++;
last_disconnected_transport_ = transport_name;
}
void on_communication_error(CommError error, const std::string& description) override {
errors_++;
last_error_ = error;
last_error_description_ = description;
}
void on_statistics_updated(const CommunicationStatistics& stats) override {
statistics_updates_++;
last_stats_ = stats;
}
// 测试计数器
int messages_sent_ = 0;
int messages_received_ = 0;
int transports_connected_ = 0;
int transports_disconnected_ = 0;
int errors_ = 0;
int statistics_updates_ = 0;
// 最后一次事件信息
std::string last_sent_type_;
std::string last_received_type_;
std::string last_connected_transport_;
std::string last_disconnected_transport_;
CommError last_error_ = CommError::Success;
std::string last_error_description_;
CommunicationStatistics last_stats_;
};
auto listener = std::make_shared<TestEventListener>();
// 添加事件监听器
manager_->add_event_listener(listener);
// 手动触发事件
manager_->notify_message_sent("TestCommMessage", 100, "ZeroMQ");
manager_->notify_message_received("TestCommMessage", 100, "ZeroMQ");
manager_->notify_transport_connected("ZeroMQ");
manager_->notify_transport_disconnected("ZeroMQ");
manager_->notify_communication_error(CommError::SendFailed, "发送失败测试");
// 验证事件被正确接收
EXPECT_EQ(listener->messages_sent_, 1);
EXPECT_EQ(listener->messages_received_, 1);
EXPECT_EQ(listener->transports_connected_, 1);
EXPECT_EQ(listener->transports_disconnected_, 1);
EXPECT_EQ(listener->errors_, 1);
EXPECT_EQ(listener->last_sent_type_, "TestCommMessage");
EXPECT_EQ(listener->last_received_type_, "TestCommMessage");
EXPECT_EQ(listener->last_connected_transport_, "ZeroMQ");
EXPECT_EQ(listener->last_disconnected_transport_, "ZeroMQ");
EXPECT_EQ(listener->last_error_, CommError::SendFailed);
EXPECT_EQ(listener->last_error_description_, "发送失败测试");
// 移除监听器
manager_->remove_event_listener(listener);
// 再次触发事件,计数器不应该增加
manager_->notify_message_sent("TestCommMessage", 100, "ZeroMQ");
EXPECT_EQ(listener->messages_sent_, 1); // 应该保持不变
// 关闭
EXPECT_EQ(manager_->shutdown(), CommError::Success);
}
// 测试统计信息
TEST_F(CommunicationManagerTest, Statistics) {
// 初始化管理器
ASSERT_EQ(manager_->initialize(), CommError::Success);
// 获取初始统计信息
const auto& stats = manager_->get_statistics();
EXPECT_EQ(stats.total_messages_sent.load(), 0);
EXPECT_EQ(stats.total_messages_received.load(), 0);
// 模拟发送和接收消息
manager_->notify_message_sent("TestCommMessage", 100, "ZeroMQ");
manager_->notify_message_sent("TestCommMessage", 200, "ZeroMQ");
manager_->notify_message_received("TestCommMessage", 150, "ZeroMQ");
// 验证统计更新
EXPECT_EQ(stats.total_messages_sent.load(), 2);
EXPECT_EQ(stats.total_bytes_sent.load(), 300);
EXPECT_EQ(stats.total_messages_received.load(), 1);
EXPECT_EQ(stats.total_bytes_received.load(), 150);
// 重置统计信息
manager_->reset_statistics();
EXPECT_EQ(stats.total_messages_sent.load(), 0);
EXPECT_EQ(stats.total_bytes_sent.load(), 0);
EXPECT_EQ(stats.total_messages_received.load(), 0);
EXPECT_EQ(stats.total_bytes_received.load(), 0);
// 关闭
EXPECT_EQ(manager_->shutdown(), CommError::Success);
}
// 测试客户端-服务器通信
TEST_F(CommunicationManagerTest, ClientServerCommunication) {
// 初始化服务器
ASSERT_EQ(manager_->initialize(), CommError::Success);
// 设置服务器消息处理器
std::mutex mtx;
std::condition_variable cv;
bool server_received = false;
std::string server_received_content;
manager_->register_message_handler("TestCommMessage", [&](std::unique_ptr<IMessage> message) {
auto* test_message = dynamic_cast<TestCommMessage*>(message.get());
if (test_message) {
std::lock_guard<std::mutex> lock(mtx);
server_received = true;
server_received_content = test_message->content();
// 创建回复
auto reply = std::make_unique<TestCommMessage>("服务器回复");
manager_->send_message(*reply);
cv.notify_one();
}
});
// 创建客户端
client_manager_ = create_client_manager();
ASSERT_EQ(client_manager_->initialize(), CommError::Success);
// 设置客户端消息处理器
bool client_received = false;
std::string client_received_content;
client_manager_->register_message_handler("TestCommMessage", [&](std::unique_ptr<IMessage> message) {
auto* test_message = dynamic_cast<TestCommMessage*>(message.get());
if (test_message) {
std::lock_guard<std::mutex> lock(mtx);
client_received = true;
client_received_content = test_message->content();
cv.notify_one();
}
});
// 创建客户端消息
auto client_message = std::make_unique<TestCommMessage>("客户端消息");
// 发送消息
EXPECT_EQ(client_manager_->send_message(*client_message), CommError::Success);
// 等待服务器接收
{
std::unique_lock<std::mutex> lock(mtx);
EXPECT_TRUE(cv.wait_for(lock, 1000ms, [&] { return server_received; }));
}
// 验证服务器接收到的内容
EXPECT_EQ(server_received_content, "客户端消息");
// 等待客户端接收服务器回复
{
std::unique_lock<std::mutex> lock(mtx);
EXPECT_TRUE(cv.wait_for(lock, 1000ms, [&] { return client_received; }));
}
// 验证客户端接收到的内容
EXPECT_EQ(client_received_content, "服务器回复");
// 关闭连接
EXPECT_EQ(client_manager_->shutdown(), CommError::Success);
EXPECT_EQ(manager_->shutdown(), CommError::Success);
}
// 测试不同消息类型的路由策略
TEST_F(CommunicationManagerTest, RoutingStrategies) {
// 初始化管理器
ASSERT_EQ(manager_->initialize(), CommError::Success);
// 添加路由规则
MessageRoute zmq_route;
zmq_route.message_type = "TestCommMessage";
zmq_route.strategy = RoutingStrategy::ZeroMQOnly;
manager_->add_route(zmq_route);
MessageRoute shm_route;
shm_route.message_type = "SharedMemoryMessage";
shm_route.strategy = RoutingStrategy::SharedMemoryOnly;
manager_->add_route(shm_route);
// 创建消息处理器检查路由通道
std::string zmq_transport_used = "";
std::string shm_transport_used = "";
auto event_listener = std::make_shared<test::NiceMock<MockCommunicationEventListener>>();
// 设置事件监听器
ON_CALL(*event_listener, on_message_sent(::testing::_, ::testing::_, ::testing::_))
.WillByDefault([&](const std::string& message_type, size_t size, const std::string& transport) {
if (message_type == "TestCommMessage") {
zmq_transport_used = transport;
} else if (message_type == "SharedMemoryMessage") {
shm_transport_used = transport;
}
});
manager_->add_event_listener(event_listener);
// 发送ZMQ消息
auto zmq_message = std::make_unique<TestCommMessage>("ZMQ路由消息");
manager_->send_message(*zmq_message);
// 发送SHM消息
auto shm_message = std::make_unique<SharedMemoryMessage>("共享内存路由消息");
manager_->send_message(*shm_message);
// 验证路由选择
EXPECT_EQ(zmq_transport_used, "ZeroMQ");
EXPECT_EQ(shm_transport_used, "SharedMemory");
// 关闭
EXPECT_EQ(manager_->shutdown(), CommError::Success);
}
// 测试工厂方法创建管理器
TEST_F(CommunicationManagerTest, FactoryCreation) {
// 测试默认管理器创建
auto default_manager = CommunicationManagerFactory::create_default("test_factory");
ASSERT_NE(default_manager, nullptr);
EXPECT_EQ(default_manager->config().process_name, "test_factory");
EXPECT_EQ(default_manager->config().routing_strategy, RoutingStrategy::Auto);
// 测试ZeroMQ专用管理器创建
ZmqConfig zmq_config;
zmq_config.endpoint = "tcp://localhost:5556";
zmq_config.socket_type = ZMQ_REQ;
auto zmq_manager = CommunicationManagerFactory::create_zmq_only("test_zmq", {zmq_config});
ASSERT_NE(zmq_manager, nullptr);
EXPECT_EQ(zmq_manager->config().routing_strategy, RoutingStrategy::ZeroMQOnly);
EXPECT_TRUE(zmq_manager->config().enable_zmq);
EXPECT_FALSE(zmq_manager->config().enable_shm);
// 测试共享内存专用管理器创建
ShmConfig shm_config;
shm_config.segment_name = "test_shm_only";
shm_config.segment_size = 1024 * 1024;
auto shm_manager = CommunicationManagerFactory::create_shm_only("test_shm", shm_config);
ASSERT_NE(shm_manager, nullptr);
EXPECT_EQ(shm_manager->config().routing_strategy, RoutingStrategy::SharedMemoryOnly);
EXPECT_FALSE(shm_manager->config().enable_zmq);
EXPECT_TRUE(shm_manager->config().enable_shm);
// 测试混合模式管理器创建
auto hybrid_manager = CommunicationManagerFactory::create_hybrid("test_hybrid", {zmq_config}, shm_config);
ASSERT_NE(hybrid_manager, nullptr);
EXPECT_EQ(hybrid_manager->config().routing_strategy, RoutingStrategy::Hybrid);
EXPECT_TRUE(hybrid_manager->config().enable_zmq);
EXPECT_TRUE(hybrid_manager->config().enable_shm);
}
// 测试错误处理
TEST_F(CommunicationManagerTest, ErrorHandling) {
// 禁用ZeroMQ和共享内存
CommunicationConfig invalid_config;
invalid_config.process_name = "invalid_test";
invalid_config.enable_zmq = false;
invalid_config.enable_shm = false;
auto invalid_manager = std::make_unique<CommunicationManager>(invalid_config, message_factory_);
// 初始化应该失败,因为没有启用任何传输机制
EXPECT_EQ(invalid_manager->initialize(), CommError::InvalidConfiguration);
// 测试未初始化时的操作
auto message = std::make_unique<TestCommMessage>("测试消息");
EXPECT_EQ(invalid_manager->send_message(*message), CommError::InitializationFailed);
// 注册处理器应该失败
EXPECT_EQ(invalid_manager->register_message_handler("TestCommMessage", [](auto){} ),
CommError::InitializationFailed);
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}