forked from mooncake-track/Mooncake
173 lines
5.2 KiB
C++
173 lines
5.2 KiB
C++
#include <glog/logging.h>
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "serializer.h"
|
|
|
|
namespace mooncake::test {
|
|
|
|
// Example class implementing serialization following the usage documentation
|
|
class ExampleClass {
|
|
public:
|
|
ExampleClass() : id_(0), value_(0.0), name_("") {}
|
|
|
|
ExampleClass(int id, double value, const std::string& name)
|
|
: id_(id), value_(value), name_(name) {}
|
|
|
|
// Serialization method (works with both counter and writer)
|
|
template <typename T>
|
|
void serialize_to(T& serializer) const {
|
|
serializer.write(&id_, sizeof(id_));
|
|
serializer.write(&value_, sizeof(value_));
|
|
|
|
// Serialize string length first, then string data
|
|
size_t name_length = name_.length();
|
|
serializer.write(&name_length, sizeof(name_length));
|
|
if (!name_.empty()) {
|
|
serializer.write(name_.data(), name_.length());
|
|
}
|
|
}
|
|
|
|
// Deserialization method
|
|
template <typename T>
|
|
static std::shared_ptr<ExampleClass> deserialize_from(T& serializer) {
|
|
try {
|
|
auto obj = std::make_shared<ExampleClass>();
|
|
|
|
// Deserialize basic members
|
|
serializer.read(&obj->id_, sizeof(obj->id_));
|
|
serializer.read(&obj->value_, sizeof(obj->value_));
|
|
|
|
// Deserialize string
|
|
size_t name_length;
|
|
serializer.read(&name_length, sizeof(name_length));
|
|
if (name_length > 0) {
|
|
obj->name_.resize(name_length);
|
|
serializer.read(&obj->name_[0], name_length);
|
|
}
|
|
|
|
return obj;
|
|
} catch (const std::exception& e) {
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
// Getters for testing
|
|
int getId() const { return id_; }
|
|
double getValue() const { return value_; }
|
|
const std::string& getName() const { return name_; }
|
|
|
|
// Equality operator for testing
|
|
bool operator==(const ExampleClass& other) const {
|
|
return id_ == other.id_ && value_ == other.value_ &&
|
|
name_ == other.name_;
|
|
}
|
|
|
|
protected:
|
|
int id_;
|
|
double value_;
|
|
std::string name_;
|
|
};
|
|
|
|
class ExampleClassWithException {
|
|
public:
|
|
ExampleClassWithException() : value_(0) {}
|
|
ExampleClassWithException(int value) : value_(value) {}
|
|
|
|
template <typename T>
|
|
void serialize_to(T& serializer) const {
|
|
serializer.write(&value_, sizeof(value_));
|
|
}
|
|
|
|
template <typename T>
|
|
static std::shared_ptr<ExampleClassWithException> deserialize_from(
|
|
T& serializer) {
|
|
throw std::runtime_error("throw_exception");
|
|
}
|
|
|
|
private:
|
|
int value_;
|
|
};
|
|
|
|
class SerializerTest : public ::testing::Test {
|
|
protected:
|
|
void SetUp() override {
|
|
google::InitGoogleLogging("SerializerTest");
|
|
FLAGS_logtostderr = true;
|
|
}
|
|
|
|
void TearDown() override { google::ShutdownGoogleLogging(); }
|
|
};
|
|
|
|
TEST_F(SerializerTest, ExampleClassSerialization) {
|
|
// Create an example object
|
|
ExampleClass original(42, 3.14159, "Test Object");
|
|
|
|
// Test serialization
|
|
std::vector<SerializedByte> buffer;
|
|
ASSERT_EQ(serialize_to(original, buffer), ErrorCode::OK);
|
|
ASSERT_FALSE(buffer.empty());
|
|
|
|
// Test deserialization
|
|
auto restored = deserialize_from<ExampleClass>(buffer);
|
|
ASSERT_NE(restored, nullptr);
|
|
|
|
// Verify the deserialized object matches the original
|
|
EXPECT_EQ(restored->getId(), original.getId());
|
|
EXPECT_DOUBLE_EQ(restored->getValue(), original.getValue());
|
|
EXPECT_EQ(restored->getName(), original.getName());
|
|
EXPECT_TRUE(*restored == original);
|
|
}
|
|
|
|
TEST_F(SerializerTest, ExampleClassSerializationWithSharedPtr) {
|
|
// Test with shared_ptr
|
|
auto original =
|
|
std::make_shared<ExampleClass>(777, 2.718, "Shared Pointer Test");
|
|
|
|
std::vector<SerializedByte> buffer;
|
|
ASSERT_EQ(serialize_to(original, buffer), ErrorCode::OK);
|
|
|
|
auto restored = deserialize_from<ExampleClass>(buffer);
|
|
ASSERT_NE(restored, nullptr);
|
|
EXPECT_TRUE(*restored == *original);
|
|
}
|
|
|
|
TEST_F(SerializerTest, ExampleClassSerializationNullPointer) {
|
|
// Test with null shared_ptr
|
|
std::shared_ptr<ExampleClass> null_ptr = nullptr;
|
|
|
|
std::vector<SerializedByte> buffer;
|
|
ASSERT_EQ(serialize_to(null_ptr, buffer), ErrorCode::INVALID_PARAMS);
|
|
}
|
|
|
|
TEST_F(SerializerTest, ExampleClassDeserializationCorruptedBuffer) {
|
|
// Create a valid object and serialize it
|
|
ExampleClass original(1, 1.0, "Test");
|
|
std::vector<SerializedByte> buffer;
|
|
ASSERT_EQ(serialize_to(original, buffer), ErrorCode::OK);
|
|
|
|
// Corrupt the buffer by removing the last byte
|
|
buffer.pop_back();
|
|
|
|
// Try to deserialize corrupted buffer
|
|
auto restored = deserialize_from<ExampleClass>(buffer);
|
|
EXPECT_EQ(restored, nullptr);
|
|
}
|
|
|
|
TEST_F(SerializerTest, ExampleClassDeserializationWithException) {
|
|
// Create a valid object and serialize it
|
|
ExampleClassWithException original(1);
|
|
std::vector<SerializedByte> buffer;
|
|
ASSERT_EQ(serialize_to(original, buffer), ErrorCode::OK);
|
|
|
|
// Try to deserialize the buffer, the deserialization method will throw an
|
|
// exception.
|
|
auto restored = deserialize_from<ExampleClassWithException>(buffer);
|
|
EXPECT_EQ(restored, nullptr);
|
|
}
|
|
|
|
} // namespace mooncake::test
|
|
|
|
int main(int argc, char** argv) {
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
} |