339 lines
11 KiB
C++
339 lines
11 KiB
C++
// ================================================================================================
|
||
// 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();
|
||
} |