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

411 lines
15 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ================================================================================================
// Audio Backend - 通信系统测试
// ================================================================================================
// 描述: 通信系统基本功能验证和使用示例
// ================================================================================================
#include "communication.h"
#include <gtest/gtest.h>
#include <thread>
#include <chrono>
#include <memory>
using namespace audio_backend;
// ================================================================================================
// 测试消息类型
// ================================================================================================
class TestMessage : public communication::Message {
public:
TestMessage() : Message("TestMessage") {}
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 CommunicationTest : public ::testing::Test {
protected:
void SetUp() override {
// 初始化通信系统
communication_init::initialize_communication_system();
}
void TearDown() override {
// 清理通信系统
communication_init::shutdown_communication_system();
}
};
// ================================================================================================
// 1. 通信管理器创建和初始化测试
// ================================================================================================
TEST_F(CommunicationTest, CreateAndInitializeManager) {
// 创建通信管理器
auto manager = communication_utils::create_communication_manager("test_process");
ASSERT_NE(manager, nullptr);
// 初始化
auto result = manager->initialize();
EXPECT_EQ(result, 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);
// 关闭
result = manager->shutdown();
EXPECT_EQ(result, CommError::Success);
EXPECT_FALSE(manager->is_initialized());
}
// ================================================================================================
// 2. 消息序列化测试
// ================================================================================================
TEST_F(CommunicationTest, MessageSerialization) {
// 创建序列化器
auto serializer = std::make_unique<ProtobufSerializer>();
// 创建测试消息
auto original_message = std::make_unique<TestMessage>();
original_message->set_content("Hello, World!");
// 序列化
std::vector<uint8_t> serialized_data;
auto serialize_result = serializer->serialize(*original_message, serialized_data);
EXPECT_EQ(serialize_result, SerializeError::Success);
EXPECT_FALSE(serialized_data.empty());
// 反序列化
std::unique_ptr<IMessage> deserialized_message;
auto deserialize_result = serializer->deserialize(serialized_data, deserialized_message);
EXPECT_EQ(deserialize_result, SerializeError::Success);
ASSERT_NE(deserialized_message, nullptr);
// 验证消息类型
EXPECT_EQ(deserialized_message->message_type(), "TestMessage");
}
// ================================================================================================
// 3. 共享内存管理器测试
// ================================================================================================
TEST_F(CommunicationTest, SharedMemoryManager) {
// 配置共享内存
ShmConfig config;
config.segment_name = "test_shm";
config.segment_size = 1024 * 1024; // 1MB
config.create_if_not_exists = true;
config.remove_on_destroy = true;
// 创建共享内存管理器
auto shm_manager = std::make_unique<ShmManager>(config);
ASSERT_NE(shm_manager, nullptr);
// 初始化
auto result = shm_manager->initialize();
EXPECT_EQ(result, ShmError::Success);
EXPECT_TRUE(shm_manager->is_initialized());
// 分配和查找对象
int* test_int = shm_manager->allocate_object<int>("test_int");
ASSERT_NE(test_int, nullptr);
*test_int = 42;
int* found_int = shm_manager->find_object<int>("test_int");
ASSERT_NE(found_int, nullptr);
EXPECT_EQ(*found_int, 42);
// 获取统计信息
auto stats = shm_manager->get_statistics();
EXPECT_GT(stats.total_size, 0);
EXPECT_LT(stats.used_size, stats.total_size);
// 清理
bool deallocated = shm_manager->deallocate_object<int>("test_int");
EXPECT_TRUE(deallocated);
// 关闭
result = shm_manager->shutdown();
EXPECT_EQ(result, ShmError::Success);
}
// ================================================================================================
// 4. 无锁环形缓冲区测试
// ================================================================================================
TEST_F(CommunicationTest, LockFreeRingBuffer) {
// 配置共享内存
ShmConfig config;
config.segment_name = "test_ring_buffer";
config.segment_size = 1024 * 1024;
config.create_if_not_exists = true;
config.remove_on_destroy = true;
auto shm_manager = std::make_unique<ShmManager>(config);
ASSERT_EQ(shm_manager->initialize(), ShmError::Success);
// 创建环形缓冲区
const size_t buffer_capacity = 1024;
RingBuffer<float> ring_buffer(*shm_manager, "audio_samples", buffer_capacity);
EXPECT_TRUE(ring_buffer.empty());
EXPECT_FALSE(ring_buffer.full());
EXPECT_EQ(ring_buffer.capacity(), buffer_capacity);
EXPECT_EQ(ring_buffer.size(), 0);
// 测试单个元素推入和弹出
float test_sample = 0.5f;
EXPECT_TRUE(ring_buffer.try_push(test_sample));
EXPECT_FALSE(ring_buffer.empty());
EXPECT_EQ(ring_buffer.size(), 1);
float output_sample;
EXPECT_TRUE(ring_buffer.try_pop(output_sample));
EXPECT_EQ(output_sample, test_sample);
EXPECT_TRUE(ring_buffer.empty());
// 测试批量操作
std::vector<float> input_samples(100);
for (size_t i = 0; i < input_samples.size(); ++i) {
input_samples[i] = static_cast<float>(i) / 100.0f;
}
size_t pushed = ring_buffer.try_push_batch(input_samples.data(), input_samples.size());
EXPECT_EQ(pushed, input_samples.size());
EXPECT_EQ(ring_buffer.size(), input_samples.size());
std::vector<float> output_samples(input_samples.size());
size_t popped = ring_buffer.try_pop_batch(output_samples.data(), output_samples.size());
EXPECT_EQ(popped, input_samples.size());
for (size_t i = 0; i < input_samples.size(); ++i) {
EXPECT_FLOAT_EQ(output_samples[i], input_samples[i]);
}
shm_manager->shutdown();
}
// ================================================================================================
// 5. 三缓冲机制测试
// ================================================================================================
TEST_F(CommunicationTest, TripleBuffer) {
// 配置共享内存
ShmConfig config;
config.segment_name = "test_triple_buffer";
config.segment_size = 1024 * 1024;
config.create_if_not_exists = true;
config.remove_on_destroy = true;
auto shm_manager = std::make_unique<ShmManager>(config);
ASSERT_EQ(shm_manager->initialize(), ShmError::Success);
// 创建三缓冲区(用于存储音频帧数据)
TripleBuffer<std::array<float, 512>> triple_buffer(*shm_manager, "audio_frames");
EXPECT_FALSE(triple_buffer.has_new_data());
// 生产者写入数据
auto* write_buffer = triple_buffer.get_write_buffer();
ASSERT_NE(write_buffer, nullptr);
// 填充测试数据
for (size_t i = 0; i < write_buffer->size(); ++i) {
(*write_buffer)[i] = static_cast<float>(i) / 512.0f;
}
// 提交写入
triple_buffer.commit_write();
EXPECT_TRUE(triple_buffer.has_new_data());
// 消费者读取数据
const auto* read_buffer = triple_buffer.get_read_buffer();
ASSERT_NE(read_buffer, nullptr);
// 验证数据
for (size_t i = 0; i < read_buffer->size(); ++i) {
EXPECT_FLOAT_EQ((*read_buffer)[i], static_cast<float>(i) / 512.0f);
}
// 提交读取
triple_buffer.commit_read();
EXPECT_FALSE(triple_buffer.has_new_data());
shm_manager->shutdown();
}
// ================================================================================================
// 6. 通信事件监听器测试
// ================================================================================================
class TestEventListener : public ICommunicationEventListener {
public:
void on_message_sent(const std::string& message_type, size_t size, const std::string& transport) override {
messages_sent_++;
}
void on_message_received(const std::string& message_type, size_t size, const std::string& transport) override {
messages_received_++;
}
void on_transport_connected(const std::string& transport_name) override {
transports_connected_++;
}
void on_transport_disconnected(const std::string& transport_name) override {
transports_disconnected_++;
}
void on_communication_error(CommError error, const std::string& description) override {
errors_++;
}
void on_statistics_updated(const CommunicationStatistics& stats) override {
statistics_updates_++;
}
// 测试计数器
std::atomic<int> messages_sent_{0};
std::atomic<int> messages_received_{0};
std::atomic<int> transports_connected_{0};
std::atomic<int> transports_disconnected_{0};
std::atomic<int> errors_{0};
std::atomic<int> statistics_updates_{0};
};
TEST_F(CommunicationTest, EventListener) {
auto manager = communication_utils::create_communication_manager("test_events");
auto listener = std::make_shared<TestEventListener>();
// 添加事件监听器
manager->add_event_listener(listener);
// 初始化管理器(应该触发连接事件)
auto result = manager->initialize();
EXPECT_EQ(result, CommError::Success);
// 简单等待,让事件处理完成
std::this_thread::sleep_for(std::chrono::milliseconds(100));
// 验证事件是否被触发
// 注意由于ZeroMQ传输可能初始化失败没有实际的服务器
// 这里主要验证监听器机制是否工作
// 移除监听器
manager->remove_event_listener(listener);
manager->shutdown();
}
// ================================================================================================
// 7. 消息路由测试
// ================================================================================================
TEST_F(CommunicationTest, MessageRouting) {
auto manager = communication_utils::create_communication_manager("test_routing");
ASSERT_EQ(manager->initialize(), CommError::Success);
// 添加路由规则
MessageRoute route;
route.message_type = "TestMessage";
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, "TestMessage");
EXPECT_EQ(routes[0].destination, "tcp://localhost:5555");
// 移除路由
manager->remove_route("TestMessage");
routes = manager->get_routes();
EXPECT_EQ(routes.size(), 0);
manager->shutdown();
}
// ================================================================================================
// 8. 统计信息测试
// ================================================================================================
TEST_F(CommunicationTest, Statistics) {
auto manager = communication_utils::create_communication_manager("test_stats");
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->reset_statistics();
EXPECT_EQ(stats.total_messages_sent.load(), 0);
EXPECT_EQ(stats.total_messages_received.load(), 0);
// 打印统计信息(测试打印功能)
manager->print_statistics();
manager->shutdown();
}
// ================================================================================================
// 9. 工厂方法测试
// ================================================================================================
TEST_F(CommunicationTest, FactoryMethods) {
// 测试默认管理器创建
auto default_manager = CommManagerFactory::create_default("test_default");
ASSERT_NE(default_manager, nullptr);
EXPECT_EQ(default_manager->config().process_name, "test_default");
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 = CommManagerFactory::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 = CommManagerFactory::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 = CommManagerFactory::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);
}
// ================================================================================================
// 主函数
// ================================================================================================
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}