561 lines
20 KiB
C++
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();
|
|
} |