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

339 lines
11 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 <gtest/gtest.h>
#include <gmock/gmock.h>
#include "communication/core/serializer.h"
#include "communication/core/message.h"
#include "tests/common/test_fixtures.h"
#include <memory>
#include <vector>
#include <string>
using namespace audio_backend;
using namespace audio_backend::communication;
// 自定义测试消息类
class SerializerTestMessage : public Message {
public:
SerializerTestMessage() : Message("SerializerTest") {}
SerializerTestMessage(int32_t id, const std::string& name, double value)
: Message("SerializerTest"), id_(id), name_(name), value_(value) {}
// 访问器
int32_t id() const { return id_; }
void set_id(int32_t id) { id_ = id; }
const std::string& name() const { return name_; }
void set_name(const std::string& name) { name_ = name; }
double value() const { return value_; }
void set_value(double value) { value_ = value; }
// 实现虚函数
size_t estimated_size() const override { return sizeof(*this) + name_.size(); }
Priority priority() const override { return Priority::Normal; }
TransportChannel preferred_channel() const override { return TransportChannel::ZeroMQ; }
// 重写equals来比较内容
bool equals(const IMessage* other) const {
if (!other || other->message_type() != message_type()) {
return false;
}
const SerializerTestMessage* typed_other =
dynamic_cast<const SerializerTestMessage*>(other);
if (!typed_other) {
return false;
}
return id_ == typed_other->id_ &&
name_ == typed_other->name_ &&
std::abs(value_ - typed_other->value_) < 1e-9;
}
// Protobuf转换函数(模拟)
void to_protobuf(/* 这里应该是protobuf对象 */) const {
// 这里只是为测试提供接口,实际实现应由具体序列化实现
}
void from_protobuf(/* 这里应该是protobuf对象 */) {
// 这里只是为测试提供接口,实际实现应由具体序列化实现
}
private:
int32_t id_ = 0;
std::string name_;
double value_ = 0.0;
};
// 实现一个测试序列化器
class MockSerializer : public ISerializer {
public:
MockSerializer() = default;
virtual ~MockSerializer() = default;
SerializationError serialize(const IMessage& message, std::vector<uint8_t>& output) override {
const SerializerTestMessage* typed_message =
dynamic_cast<const SerializerTestMessage*>(&message);
if (!typed_message) {
return SerializationError::TypeMismatch;
}
// 非常简单的序列化示例存储类型字符串、ID、名称长度、名称、值
output.clear();
// 添加消息类型
std::string type = message.message_type();
output.insert(output.end(), type.begin(), type.end());
output.push_back(0); // 字符串终止符
// 添加ID
int32_t id = typed_message->id();
uint8_t* id_bytes = reinterpret_cast<uint8_t*>(&id);
output.insert(output.end(), id_bytes, id_bytes + sizeof(id));
// 添加名称
std::string name = typed_message->name();
uint32_t name_length = static_cast<uint32_t>(name.length());
uint8_t* len_bytes = reinterpret_cast<uint8_t*>(&name_length);
output.insert(output.end(), len_bytes, len_bytes + sizeof(name_length));
output.insert(output.end(), name.begin(), name.end());
// 添加值
double value = typed_message->value();
uint8_t* value_bytes = reinterpret_cast<uint8_t*>(&value);
output.insert(output.end(), value_bytes, value_bytes + sizeof(value));
return SerializationError::Success;
}
SerializationError deserialize(const std::vector<uint8_t>& input,
std::unique_ptr<IMessage>& output) override {
if (input.empty()) {
return SerializationError::InvalidData;
}
// 解析消息类型
std::string type;
size_t pos = 0;
while (pos < input.size() && input[pos] != 0) {
type.push_back(static_cast<char>(input[pos++]));
}
if (pos >= input.size() || type != "SerializerTest") {
return SerializationError::TypeMismatch;
}
pos++; // 跳过字符串终止符
if (pos + sizeof(int32_t) + sizeof(uint32_t) > input.size()) {
return SerializationError::InvalidData;
}
// 解析ID
int32_t id;
std::memcpy(&id, input.data() + pos, sizeof(id));
pos += sizeof(id);
// 解析名称长度
uint32_t name_length;
std::memcpy(&name_length, input.data() + pos, sizeof(name_length));
pos += sizeof(name_length);
if (pos + name_length + sizeof(double) > input.size()) {
return SerializationError::InvalidData;
}
// 解析名称
std::string name(input.begin() + pos, input.begin() + pos + name_length);
pos += name_length;
// 解析值
double value;
std::memcpy(&value, input.data() + pos, sizeof(value));
// 创建消息
output = std::make_unique<SerializerTestMessage>(id, name, value);
return SerializationError::Success;
}
};
// 序列化器测试固定装置
class SerializerTest : public test::CommunicationTest {
protected:
void SetUp() override {
test::CommunicationTest::SetUp();
// 创建测试序列化器
serializer_ = std::make_unique<MockSerializer>();
// 注册消息工厂
message_factory_.register_message<SerializerTestMessage>("SerializerTest");
}
void TearDown() override {
serializer_.reset();
test::CommunicationTest::TearDown();
}
std::unique_ptr<ISerializer> serializer_;
MessageFactory message_factory_;
};
// 测试基本序列化和反序列化
TEST_F(SerializerTest, BasicSerializationDeserialization) {
// 创建测试消息
SerializerTestMessage original(42, "测试序列化", 3.14159);
// 序列化
std::vector<uint8_t> serialized_data;
SerializationError serialize_result =
serializer_->serialize(original, serialized_data);
EXPECT_EQ(serialize_result, SerializationError::Success);
EXPECT_FALSE(serialized_data.empty());
// 反序列化
std::unique_ptr<IMessage> deserialized;
SerializationError deserialize_result =
serializer_->deserialize(serialized_data, deserialized);
EXPECT_EQ(deserialize_result, SerializationError::Success);
EXPECT_NE(deserialized.get(), nullptr);
// 检查类型和内容
EXPECT_EQ(deserialized->message_type(), "SerializerTest");
SerializerTestMessage* typed_result =
dynamic_cast<SerializerTestMessage*>(deserialized.get());
ASSERT_NE(typed_result, nullptr);
EXPECT_EQ(typed_result->id(), 42);
EXPECT_EQ(typed_result->name(), "测试序列化");
EXPECT_DOUBLE_EQ(typed_result->value(), 3.14159);
}
// 测试空消息序列化
TEST_F(SerializerTest, EmptyMessageSerialization) {
// 创建空消息
SerializerTestMessage empty_message(0, "", 0.0);
// 序列化
std::vector<uint8_t> serialized_data;
SerializationError serialize_result =
serializer_->serialize(empty_message, serialized_data);
EXPECT_EQ(serialize_result, SerializationError::Success);
EXPECT_FALSE(serialized_data.empty());
// 反序列化
std::unique_ptr<IMessage> deserialized;
SerializationError deserialize_result =
serializer_->deserialize(serialized_data, deserialized);
EXPECT_EQ(deserialize_result, SerializationError::Success);
EXPECT_NE(deserialized.get(), nullptr);
// 检查内容
SerializerTestMessage* typed_result =
dynamic_cast<SerializerTestMessage*>(deserialized.get());
ASSERT_NE(typed_result, nullptr);
EXPECT_EQ(typed_result->id(), 0);
EXPECT_EQ(typed_result->name(), "");
EXPECT_DOUBLE_EQ(typed_result->value(), 0.0);
}
// 测试错误情况
TEST_F(SerializerTest, ErrorHandling) {
// 测试无效数据
std::vector<uint8_t> invalid_data = {0x01, 0x02, 0x03}; // 太短无法解析
std::unique_ptr<IMessage> output;
SerializationError result = serializer_->deserialize(invalid_data, output);
EXPECT_EQ(result, SerializationError::InvalidData);
EXPECT_EQ(output.get(), nullptr);
// 测试空数据
std::vector<uint8_t> empty_data;
result = serializer_->deserialize(empty_data, output);
EXPECT_EQ(result, SerializationError::InvalidData);
EXPECT_EQ(output.get(), nullptr);
}
// 测试类型不匹配
TEST_F(SerializerTest, TypeMismatch) {
// 创建不同类型的消息
class OtherMessage : public Message {
public:
OtherMessage() : Message("OtherMessage") {}
size_t estimated_size() const override { return sizeof(*this); }
Priority priority() const override { return Priority::Normal; }
TransportChannel preferred_channel() const override { return TransportChannel::ZeroMQ; }
};
OtherMessage other_message;
// 尝试序列化不支持的类型
std::vector<uint8_t> serialized_data;
SerializationError serialize_result =
serializer_->serialize(other_message, serialized_data);
EXPECT_EQ(serialize_result, SerializationError::TypeMismatch);
}
// 测试Protobuf序列化器
TEST_F(SerializerTest, ProtobufSerializer) {
// 创建Protobuf序列化器
ProtobufSerializer protobuf_serializer;
// 注意由于没有实际的Protobuf实现这里主要测试接口和类型检查
EXPECT_EQ(protobuf_serializer.get_serializer_name(), "protobuf");
// 创建测试消息
SerializerTestMessage test_message(42, "测试Protobuf", 3.14159);
// 序列化这可能会失败因为我们没有实际的Protobuf实现
std::vector<uint8_t> serialized_data;
SerializationError serialize_result =
protobuf_serializer.serialize(test_message, serialized_data);
// 这里我们不做具体的断言,因为实际实现可能有所不同
}
// 测试序列化器工厂
TEST_F(SerializerTest, SerializerFactory) {
// 创建序列化器工厂
SerializerFactory factory;
// 注册序列化器
auto mock_serializer = std::make_unique<MockSerializer>();
factory.register_serializer("mock", std::move(mock_serializer));
// 获取序列化器
auto serializer = factory.get_serializer("mock");
EXPECT_NE(serializer, nullptr);
// 获取不存在的序列化器
auto nonexistent = factory.get_serializer("nonexistent");
EXPECT_EQ(nonexistent, nullptr);
}
// 测试单例实例
TEST_F(SerializerTest, SingletonInstance) {
auto& factory1 = SerializerFactory::instance();
auto& factory2 = SerializerFactory::instance();
// 验证是同一实例
EXPECT_EQ(&factory1, &factory2);
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}