307 lines
9.3 KiB
C++
307 lines
9.3 KiB
C++
// ================================================================================================
|
|
// Audio Backend - 环形缓冲区测试
|
|
// ================================================================================================
|
|
|
|
#include <gtest/gtest.h>
|
|
#include "engine/audio_buffer.h"
|
|
#include "tests/common/test_fixtures.h"
|
|
#include "tests/common/test_utils.h"
|
|
#include <thread>
|
|
#include <atomic>
|
|
#include <vector>
|
|
|
|
using namespace audio_backend;
|
|
using namespace audio_backend::engine;
|
|
|
|
// 环形缓冲区测试固定装置
|
|
class RingBufferTest : public test::BaseTest {
|
|
protected:
|
|
void SetUp() override {
|
|
test::BaseTest::SetUp();
|
|
}
|
|
|
|
void TearDown() override {
|
|
test::BaseTest::TearDown();
|
|
}
|
|
|
|
// 测试不同类型的环形缓冲区
|
|
template<typename T>
|
|
void test_basic_operations(size_t capacity) {
|
|
RingBuffer<T> buffer(capacity);
|
|
|
|
// 初始状态
|
|
EXPECT_EQ(buffer.capacity(), capacity);
|
|
EXPECT_EQ(buffer.available(), 0);
|
|
EXPECT_EQ(buffer.space(), capacity);
|
|
EXPECT_TRUE(buffer.empty());
|
|
EXPECT_FALSE(buffer.full());
|
|
}
|
|
|
|
template<typename T>
|
|
void test_single_element_operations(size_t capacity, const std::vector<T>& test_data) {
|
|
RingBuffer<T> buffer(capacity);
|
|
|
|
// 推入和弹出单个元素
|
|
for (const T& value : test_data) {
|
|
EXPECT_TRUE(buffer.write(&value, 1));
|
|
EXPECT_EQ(buffer.available(), 1);
|
|
|
|
T output;
|
|
EXPECT_TRUE(buffer.read(&output, 1));
|
|
EXPECT_EQ(buffer.available(), 0);
|
|
EXPECT_EQ(output, value);
|
|
}
|
|
}
|
|
|
|
template<typename T>
|
|
void test_batch_operations(size_t capacity, const std::vector<T>& test_data) {
|
|
RingBuffer<T> buffer(capacity);
|
|
|
|
// 批量写入
|
|
size_t batch_size = std::min(test_data.size(), capacity);
|
|
size_t written = buffer.write(test_data.data(), batch_size);
|
|
EXPECT_EQ(written, batch_size);
|
|
EXPECT_EQ(buffer.available(), batch_size);
|
|
|
|
// 批量读取
|
|
std::vector<T> output(batch_size);
|
|
size_t read = buffer.read(output.data(), batch_size);
|
|
EXPECT_EQ(read, batch_size);
|
|
EXPECT_EQ(buffer.available(), 0);
|
|
|
|
for (size_t i = 0; i < batch_size; ++i) {
|
|
EXPECT_EQ(output[i], test_data[i]);
|
|
}
|
|
}
|
|
|
|
template<typename T>
|
|
void test_wrap_around(size_t capacity, const std::vector<T>& test_data) {
|
|
RingBuffer<T> buffer(capacity);
|
|
|
|
// 填充一半
|
|
size_t half = capacity / 2;
|
|
EXPECT_EQ(buffer.write(test_data.data(), half), half);
|
|
|
|
// 读取一半
|
|
std::vector<T> output(half);
|
|
EXPECT_EQ(buffer.read(output.data(), half), half);
|
|
|
|
// 现在写入超过一半,测试环绕
|
|
size_t to_write = std::min(test_data.size(), capacity - half + half);
|
|
EXPECT_EQ(buffer.write(test_data.data(), to_write), to_write);
|
|
|
|
// 读取全部
|
|
output.resize(to_write);
|
|
EXPECT_EQ(buffer.read(output.data(), to_write), to_write);
|
|
|
|
for (size_t i = 0; i < to_write; ++i) {
|
|
EXPECT_EQ(output[i], test_data[i]);
|
|
}
|
|
}
|
|
};
|
|
|
|
// 测试基本的Float类型RingBuffer操作
|
|
TEST_F(RingBufferTest, FloatBasicOperations) {
|
|
test_basic_operations<float>(1024);
|
|
}
|
|
|
|
// 测试基本的Int16类型RingBuffer操作
|
|
TEST_F(RingBufferTest, Int16BasicOperations) {
|
|
test_basic_operations<int16_t>(1024);
|
|
}
|
|
|
|
// 测试单元素Float操作
|
|
TEST_F(RingBufferTest, FloatSingleElementOperations) {
|
|
std::vector<float> test_data = {0.1f, 0.2f, 0.3f, 0.4f, 0.5f};
|
|
test_single_element_operations<float>(16, test_data);
|
|
}
|
|
|
|
// 测试单元素Int16操作
|
|
TEST_F(RingBufferTest, Int16SingleElementOperations) {
|
|
std::vector<int16_t> test_data = {100, 200, 300, 400, 500};
|
|
test_single_element_operations<int16_t>(16, test_data);
|
|
}
|
|
|
|
// 测试批量Float操作
|
|
TEST_F(RingBufferTest, FloatBatchOperations) {
|
|
std::vector<float> test_data(128);
|
|
for (size_t i = 0; i < test_data.size(); ++i) {
|
|
test_data[i] = static_cast<float>(i) / 100.0f;
|
|
}
|
|
test_batch_operations<float>(256, test_data);
|
|
}
|
|
|
|
// 测试批量Int16操作
|
|
TEST_F(RingBufferTest, Int16BatchOperations) {
|
|
std::vector<int16_t> test_data(128);
|
|
for (size_t i = 0; i < test_data.size(); ++i) {
|
|
test_data[i] = static_cast<int16_t>(i * 10);
|
|
}
|
|
test_batch_operations<int16_t>(256, test_data);
|
|
}
|
|
|
|
// 测试环绕逻辑
|
|
TEST_F(RingBufferTest, FloatWrapAround) {
|
|
std::vector<float> test_data(256);
|
|
for (size_t i = 0; i < test_data.size(); ++i) {
|
|
test_data[i] = static_cast<float>(i) / 100.0f;
|
|
}
|
|
test_wrap_around<float>(128, test_data);
|
|
}
|
|
|
|
// 测试环绕逻辑
|
|
TEST_F(RingBufferTest, Int16WrapAround) {
|
|
std::vector<int16_t> test_data(256);
|
|
for (size_t i = 0; i < test_data.size(); ++i) {
|
|
test_data[i] = static_cast<int16_t>(i * 10);
|
|
}
|
|
test_wrap_around<int16_t>(128, test_data);
|
|
}
|
|
|
|
// 测试缓冲区容量边界
|
|
TEST_F(RingBufferTest, CapacityBoundaries) {
|
|
// 零容量
|
|
RingBuffer<float> zero_buffer(0);
|
|
EXPECT_EQ(zero_buffer.capacity(), 0);
|
|
EXPECT_TRUE(zero_buffer.empty());
|
|
EXPECT_TRUE(zero_buffer.full()); // 零容量缓冲区应该同时是空的和满的
|
|
|
|
float value = 1.0f;
|
|
EXPECT_EQ(zero_buffer.write(&value, 1), 0); // 无法写入
|
|
|
|
// 最小容量
|
|
RingBuffer<float> min_buffer(1);
|
|
EXPECT_EQ(min_buffer.capacity(), 1);
|
|
EXPECT_TRUE(min_buffer.empty());
|
|
EXPECT_FALSE(min_buffer.full());
|
|
|
|
// 写入一个元素,缓冲区应该是满的
|
|
EXPECT_EQ(min_buffer.write(&value, 1), 1);
|
|
EXPECT_FALSE(min_buffer.empty());
|
|
EXPECT_TRUE(min_buffer.full());
|
|
|
|
// 再写入应该失败
|
|
EXPECT_EQ(min_buffer.write(&value, 1), 0);
|
|
}
|
|
|
|
// 测试清空操作
|
|
TEST_F(RingBufferTest, ClearOperation) {
|
|
RingBuffer<float> buffer(128);
|
|
|
|
// 填充一些数据
|
|
std::vector<float> test_data(64);
|
|
for (size_t i = 0; i < test_data.size(); ++i) {
|
|
test_data[i] = static_cast<float>(i) / 100.0f;
|
|
}
|
|
|
|
EXPECT_EQ(buffer.write(test_data.data(), test_data.size()), test_data.size());
|
|
EXPECT_EQ(buffer.available(), test_data.size());
|
|
|
|
// 清空
|
|
buffer.clear();
|
|
EXPECT_EQ(buffer.available(), 0);
|
|
EXPECT_EQ(buffer.space(), buffer.capacity());
|
|
EXPECT_TRUE(buffer.empty());
|
|
EXPECT_FALSE(buffer.full());
|
|
}
|
|
|
|
// 测试尝试写入超过容量
|
|
TEST_F(RingBufferTest, WriteBeyondCapacity) {
|
|
const size_t capacity = 128;
|
|
RingBuffer<float> buffer(capacity);
|
|
|
|
std::vector<float> test_data(capacity * 2); // 两倍容量
|
|
for (size_t i = 0; i < test_data.size(); ++i) {
|
|
test_data[i] = static_cast<float>(i) / 100.0f;
|
|
}
|
|
|
|
// 应该只写入容量大小
|
|
size_t written = buffer.write(test_data.data(), test_data.size());
|
|
EXPECT_EQ(written, capacity);
|
|
EXPECT_EQ(buffer.available(), capacity);
|
|
EXPECT_TRUE(buffer.full());
|
|
}
|
|
|
|
// 测试并发安全性
|
|
TEST_F(RingBufferTest, ConcurrentAccess) {
|
|
const size_t capacity = 1024;
|
|
const size_t iterations = 1000;
|
|
|
|
RingBuffer<int> buffer(capacity);
|
|
std::atomic<bool> done(false);
|
|
std::atomic<size_t> producer_count(0);
|
|
std::atomic<size_t> consumer_count(0);
|
|
|
|
// 生产者线程
|
|
auto producer = [&]() {
|
|
for (size_t i = 0; i < iterations; ++i) {
|
|
int value = static_cast<int>(i);
|
|
if (buffer.write(&value, 1) == 1) {
|
|
producer_count++;
|
|
}
|
|
}
|
|
};
|
|
|
|
// 消费者线程
|
|
auto consumer = [&]() {
|
|
while (!done || buffer.available() > 0) {
|
|
int value;
|
|
if (buffer.read(&value, 1) == 1) {
|
|
consumer_count++;
|
|
} else {
|
|
// 给生产者一些时间
|
|
std::this_thread::yield();
|
|
}
|
|
}
|
|
};
|
|
|
|
// 启动线程
|
|
std::thread producer_thread(producer);
|
|
std::thread consumer_thread(consumer);
|
|
|
|
// 等待生产者完成
|
|
producer_thread.join();
|
|
done = true;
|
|
|
|
// 等待消费者完成
|
|
consumer_thread.join();
|
|
|
|
// 验证所有数据都被正确处理
|
|
EXPECT_EQ(producer_count.load(), iterations);
|
|
EXPECT_EQ(consumer_count.load(), iterations);
|
|
EXPECT_TRUE(buffer.empty());
|
|
}
|
|
|
|
// 测试调整大小
|
|
TEST_F(RingBufferTest, Resize) {
|
|
RingBuffer<float> buffer(128);
|
|
|
|
// 填充一些数据
|
|
std::vector<float> test_data(64);
|
|
for (size_t i = 0; i < test_data.size(); ++i) {
|
|
test_data[i] = static_cast<float>(i) / 100.0f;
|
|
}
|
|
|
|
EXPECT_EQ(buffer.write(test_data.data(), test_data.size()), test_data.size());
|
|
|
|
// 调整大小(会清空缓冲区)
|
|
buffer.resize(256);
|
|
EXPECT_EQ(buffer.capacity(), 256);
|
|
EXPECT_EQ(buffer.available(), 0);
|
|
EXPECT_EQ(buffer.space(), 256);
|
|
|
|
// 再次写入
|
|
EXPECT_EQ(buffer.write(test_data.data(), test_data.size()), test_data.size());
|
|
EXPECT_EQ(buffer.available(), test_data.size());
|
|
|
|
// 调整到更小(会清空缓冲区)
|
|
buffer.resize(32);
|
|
EXPECT_EQ(buffer.capacity(), 32);
|
|
EXPECT_EQ(buffer.available(), 0);
|
|
EXPECT_EQ(buffer.space(), 32);
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
} |