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

479 lines
16 KiB
C++

// ================================================================================================
// Audio Backend - 共享内存测试
// ================================================================================================
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "communication/shm/shared_memory.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 SharedMemoryTest : public test::CommunicationTest {
protected:
void SetUp() override {
test::CommunicationTest::SetUp();
// 创建基本配置
base_config_.segment_name = "audio_backend_test_shm";
base_config_.segment_size = 1024 * 1024; // 1MB
base_config_.create_if_not_exists = true;
base_config_.remove_on_destroy = true;
}
void TearDown() override {
// 确保共享内存管理器被销毁
shm_manager_.reset();
test::CommunicationTest::TearDown();
}
// 创建共享内存管理器
std::unique_ptr<SharedMemoryManager> create_shm_manager(bool creating = true) {
ShmConfig config = base_config_;
// 如果不是创建者,就不要移除共享内存
if (!creating) {
config.remove_on_destroy = false;
}
return std::make_unique<SharedMemoryManager>(config);
}
protected:
ShmConfig base_config_;
std::unique_ptr<SharedMemoryManager> shm_manager_;
};
// 测试创建和初始化
TEST_F(SharedMemoryTest, CreateAndInitialize) {
// 创建共享内存管理器
shm_manager_ = create_shm_manager();
// 验证创建状态
EXPECT_FALSE(shm_manager_->is_initialized());
// 验证配置
const auto& config = shm_manager_->get_config();
EXPECT_EQ(config.segment_name, base_config_.segment_name);
EXPECT_EQ(config.segment_size, base_config_.segment_size);
EXPECT_TRUE(config.create_if_not_exists);
EXPECT_TRUE(config.remove_on_destroy);
// 初始化
EXPECT_EQ(shm_manager_->initialize(), ShmError::Success);
EXPECT_TRUE(shm_manager_->is_initialized());
// 获取统计信息
const auto& stats = shm_manager_->get_statistics();
EXPECT_EQ(stats.total_size, base_config_.segment_size);
EXPECT_GT(stats.used_size, 0); // 至少有一些元数据
EXPECT_LT(stats.used_size, stats.total_size); // 但不会全部用完
EXPECT_EQ(stats.allocation_count, 0); // 还没有分配任何对象
}
// 测试对象分配和释放
TEST_F(SharedMemoryTest, AllocateAndDeallocate) {
// 创建和初始化共享内存管理器
shm_manager_ = create_shm_manager();
ASSERT_EQ(shm_manager_->initialize(), ShmError::Success);
// 分配简单对象
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);
// 验证统计信息
const auto& stats_after_alloc = shm_manager_->get_statistics();
EXPECT_EQ(stats_after_alloc.allocation_count, 1);
EXPECT_GT(stats_after_alloc.used_size, sizeof(int)); // 包括元数据和对象
// 修改值并验证共享状态
*test_int = 100;
EXPECT_EQ(*found_int, 100);
// 释放对象
bool deallocated = shm_manager_->deallocate_object<int>("test_int");
EXPECT_TRUE(deallocated);
// 释放后应找不到对象
int* not_found = shm_manager_->find_object<int>("test_int");
EXPECT_EQ(not_found, nullptr);
// 验证统计信息
const auto& stats_after_dealloc = shm_manager_->get_statistics();
EXPECT_EQ(stats_after_dealloc.allocation_count, 0);
EXPECT_EQ(stats_after_dealloc.used_size, stats_after_dealloc.used_size); // 应该回到初始状态
}
// 测试多个共享内存管理器访问相同的共享内存段
TEST_F(SharedMemoryTest, MultipleManagers) {
// 创建第一个管理器(创建共享内存段)
auto manager1 = create_shm_manager(true); // 创建者
ASSERT_EQ(manager1->initialize(), ShmError::Success);
// 分配一些对象
int* int_obj = manager1->allocate_object<int>("shared_int");
ASSERT_NE(int_obj, nullptr);
*int_obj = 42;
float* float_obj = manager1->allocate_object<float>("shared_float");
ASSERT_NE(float_obj, nullptr);
*float_obj = 3.14159f;
// 创建第二个管理器(访问现有共享内存段)
auto manager2 = create_shm_manager(false); // 非创建者
ASSERT_EQ(manager2->initialize(), ShmError::Success);
// 查找和验证对象
int* found_int = manager2->find_object<int>("shared_int");
ASSERT_NE(found_int, nullptr);
EXPECT_EQ(*found_int, 42);
float* found_float = manager2->find_object<float>("shared_float");
ASSERT_NE(found_float, nullptr);
EXPECT_FLOAT_EQ(*found_float, 3.14159f);
// 通过第二个管理器修改值
*found_int = 100;
*found_float = 2.71828f;
// 验证第一个管理器是否看到更改
EXPECT_EQ(*int_obj, 100);
EXPECT_FLOAT_EQ(*float_obj, 2.71828f);
}
// 测试复杂对象和结构体
TEST_F(SharedMemoryTest, ComplexStructures) {
// 创建和初始化共享内存管理器
shm_manager_ = create_shm_manager();
ASSERT_EQ(shm_manager_->initialize(), ShmError::Success);
// 定义复杂结构
struct ComplexStruct {
int id;
float values[10];
double ratio;
char name[64];
};
// 分配结构
ComplexStruct* complex_obj = shm_manager_->allocate_object<ComplexStruct>("complex_struct");
ASSERT_NE(complex_obj, nullptr);
// 初始化结构
complex_obj->id = 123;
for (int i = 0; i < 10; i++) {
complex_obj->values[i] = i * 1.5f;
}
complex_obj->ratio = 16.0 / 9.0;
strcpy(complex_obj->name, "音频后端测试结构");
// 查找和验证
ComplexStruct* found_struct = shm_manager_->find_object<ComplexStruct>("complex_struct");
ASSERT_NE(found_struct, nullptr);
EXPECT_EQ(found_struct->id, 123);
for (int i = 0; i < 10; i++) {
EXPECT_FLOAT_EQ(found_struct->values[i], i * 1.5f);
}
EXPECT_DOUBLE_EQ(found_struct->ratio, 16.0 / 9.0);
EXPECT_STREQ(found_struct->name, "音频后端测试结构");
}
// 测试环形缓冲区
TEST_F(SharedMemoryTest, RingBufferTest) {
// 创建和初始化共享内存管理器
shm_manager_ = create_shm_manager();
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.available(), 0);
// 测试单个元素推入和弹出
float test_sample = 0.5f;
EXPECT_TRUE(ring_buffer.write(&test_sample, 1));
EXPECT_FALSE(ring_buffer.empty());
EXPECT_EQ(ring_buffer.available(), 1);
float output_sample;
EXPECT_TRUE(ring_buffer.read(&output_sample, 1));
EXPECT_FLOAT_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.write(input_samples.data(), input_samples.size());
EXPECT_EQ(pushed, input_samples.size());
EXPECT_EQ(ring_buffer.available(), input_samples.size());
std::vector<float> output_samples(input_samples.size());
size_t popped = ring_buffer.read(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]);
}
}
// 测试三缓冲机制
TEST_F(SharedMemoryTest, TripleBufferTest) {
// 创建和初始化共享内存管理器
shm_manager_ = create_shm_manager();
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());
}
// 测试共享内存的并发安全性
TEST_F(SharedMemoryTest, ConcurrentAccess) {
// 创建和初始化共享内存管理器
shm_manager_ = create_shm_manager();
ASSERT_EQ(shm_manager_->initialize(), ShmError::Success);
// 创建环形缓冲区
const size_t buffer_capacity = 1024;
RingBuffer<int> ring_buffer(*shm_manager_, "concurrent_test", buffer_capacity);
// 创建多个线程同时访问
const int num_producers = 4;
const int num_consumers = 4;
const int items_per_producer = 1000;
std::atomic<int> total_produced(0);
std::atomic<int> total_consumed(0);
// 创建生产者
std::vector<std::thread> producers;
for (int p = 0; p < num_producers; ++p) {
producers.emplace_back([&, p]() {
for (int i = 0; i < items_per_producer; ++i) {
int value = p * items_per_producer + i;
while (!ring_buffer.write(&value, 1)) {
// 缓冲区满,等待一下
std::this_thread::yield();
}
total_produced++;
}
});
}
// 创建消费者
std::vector<std::thread> consumers;
std::vector<std::set<int>> consumed_values(num_consumers);
for (int c = 0; c < num_consumers; ++c) {
consumers.emplace_back([&, c]() {
while (total_consumed < num_producers * items_per_producer) {
int value;
if (ring_buffer.read(&value, 1)) {
consumed_values[c].insert(value);
total_consumed++;
} else {
// 缓冲区空,等待一下
std::this_thread::yield();
}
}
});
}
// 等待所有生产者完成
for (auto& t : producers) {
t.join();
}
// 等待所有消费者完成
for (auto& t : consumers) {
t.join();
}
// 验证所有的项都被消费了
EXPECT_EQ(total_produced.load(), num_producers * items_per_producer);
EXPECT_EQ(total_consumed.load(), num_producers * items_per_producer);
// 合并所有消费者的集合
std::set<int> all_consumed;
for (const auto& set : consumed_values) {
all_consumed.insert(set.begin(), set.end());
}
// 验证每个项只被消费了一次
EXPECT_EQ(all_consumed.size(), num_producers * items_per_producer);
// 验证所有项都被消费了
for (int p = 0; p < num_producers; ++p) {
for (int i = 0; i < items_per_producer; ++i) {
int value = p * items_per_producer + i;
EXPECT_TRUE(all_consumed.find(value) != all_consumed.end());
}
}
}
// 测试错误处理
TEST_F(SharedMemoryTest, ErrorHandling) {
// 创建配置,但不创建共享内存
ShmConfig config = base_config_;
config.create_if_not_exists = false; // 不创建新的
// 尝试访问不存在的共享内存
auto manager = std::make_unique<SharedMemoryManager>(config);
EXPECT_NE(manager->initialize(), ShmError::Success);
// 正确初始化
shm_manager_ = create_shm_manager();
ASSERT_EQ(shm_manager_->initialize(), ShmError::Success);
// 尝试查找不存在的对象
int* not_found = shm_manager_->find_object<int>("non_existent_object");
EXPECT_EQ(not_found, nullptr);
// 尝试释放不存在的对象
bool deallocated = shm_manager_->deallocate_object<int>("non_existent_object");
EXPECT_FALSE(deallocated);
// 创建对象然后分配同名对象(应失败)
int* obj1 = shm_manager_->allocate_object<int>("duplicate");
ASSERT_NE(obj1, nullptr);
*obj1 = 42;
int* obj2 = shm_manager_->allocate_object<int>("duplicate");
EXPECT_EQ(obj2, nullptr);
// 检查第一个对象是否还完好
int* check = shm_manager_->find_object<int>("duplicate");
ASSERT_NE(check, nullptr);
EXPECT_EQ(*check, 42);
}
// 测试性能和资源利用
TEST_F(SharedMemoryTest, PerformanceAndResource) {
// 创建更大的共享内存段
ShmConfig large_config = base_config_;
large_config.segment_size = 10 * 1024 * 1024; // 10MB
auto large_manager = std::make_unique<SharedMemoryManager>(large_config);
ASSERT_EQ(large_manager->initialize(), ShmError::Success);
// 获取初始统计信息
const auto& initial_stats = large_manager->get_statistics();
// 分配大量小对象
const int num_objects = 1000;
std::vector<int*> objects;
for (int i = 0; i < num_objects; ++i) {
std::string name = "obj_" + std::to_string(i);
int* obj = large_manager->allocate_object<int>(name);
ASSERT_NE(obj, nullptr);
*obj = i;
objects.push_back(obj);
}
// 验证统计信息
const auto& after_alloc_stats = large_manager->get_statistics();
EXPECT_EQ(after_alloc_stats.allocation_count, num_objects);
EXPECT_GT(after_alloc_stats.used_size, initial_stats.used_size);
// 验证所有对象的值
for (int i = 0; i < num_objects; ++i) {
EXPECT_EQ(*objects[i], i);
}
// 释放一半对象
for (int i = 0; i < num_objects / 2; ++i) {
std::string name = "obj_" + std::to_string(i);
bool deallocated = large_manager->deallocate_object<int>(name);
EXPECT_TRUE(deallocated);
}
// 验证统计信息
const auto& after_dealloc_stats = large_manager->get_statistics();
EXPECT_EQ(after_dealloc_stats.allocation_count, num_objects / 2);
EXPECT_LT(after_dealloc_stats.used_size, after_alloc_stats.used_size);
// 确保我们可以再次分配这些对象
for (int i = 0; i < num_objects / 2; ++i) {
std::string name = "obj_" + std::to_string(i);
int* obj = large_manager->allocate_object<int>(name);
ASSERT_NE(obj, nullptr);
*obj = i + 1000; // 使用不同的值
}
// 验证所有对象的值
for (int i = 0; i < num_objects / 2; ++i) {
std::string name = "obj_" + std::to_string(i);
int* obj = large_manager->find_object<int>(name);
ASSERT_NE(obj, nullptr);
EXPECT_EQ(*obj, i + 1000);
}
// 验证另一半对象的值
for (int i = num_objects / 2; i < num_objects; ++i) {
std::string name = "obj_" + std::to_string(i);
int* obj = large_manager->find_object<int>(name);
ASSERT_NE(obj, nullptr);
EXPECT_EQ(*obj, i);
}
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}