/
smychkov
/
SStorage
Обзор
Документация
Войти
/
smychkov
/
SStorage
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
tests/test_record.cpp
137 строк
4 KB
Андрей Смычков
feat: Record class (bytes key/value, seqNo, tombstone)
25 апр 2026, 09:00
25 апр 2026, 09:00
f7ec976
Код
Авторство
О чём код?
//============================================================================ // Тесты для класса Record //============================================================================ #include "../src/core/record.hpp" #include <iostream> #include <string> #include <vector> using namespace sstorage; static int g_passed = 0; static int g_failed = 0; #define CHECK(cond) do { \ if (cond) { ++g_passed; } \ else { ++g_failed; std::cerr << "FAIL: " #cond " at line " << __LINE__ << "\n"; } \ } while (0) // Проверка roundtrip: serialize -> deserialize -> должно совпасть static void checkRoundtrip(const Record& r) { std::string buf; r.serialize(buf); CHECK(buf.size() == r.serializedSize()); size_t consumed; auto decoded = Record::deserialize(buf.data(), buf.size(), consumed); CHECK(decoded.has_value()); CHECK(consumed == buf.size()); CHECK(*decoded == r); } int main() { // Обычная запись checkRoundtrip(Record("hello", "world", 1)); // Пустой key checkRoundtrip(Record("", "value", 42)); // Пустой value checkRoundtrip(Record("key", "", 100)); // Оба пустые checkRoundtrip(Record("", "", 0)); // Tombstone checkRoundtrip(Record::makeTombstone("deleted_key", 5)); // Большой key + value { std::string big_key(1000, 'k'); std::string big_value(10000, 'v'); checkRoundtrip(Record(big_key, big_value, 999999)); } // Бинарные данные в key/value (не ASCII) { std::string binary_key; for (int i = 0; i < 256; ++i) binary_key.push_back(static_cast<char>(i)); std::string binary_value = "\x00\x01\x02\xFF"; checkRoundtrip(Record(binary_key, binary_value, 1)); } // Проверка свойств { Record r("foo", "bar", 10); CHECK(r.key() == "foo"); CHECK(r.value() == "bar"); CHECK(r.seqNo() == 10); CHECK(!r.isTombstone()); CHECK(r.approximateSize() > 0); } // Tombstone properties { auto t = Record::makeTombstone("k", 5); CHECK(t.key() == "k"); CHECK(t.value() == ""); CHECK(t.seqNo() == 5); CHECK(t.isTombstone()); } // Упорядочивание: ключи по ASC { Record a("aaa", "v", 1); Record b("bbb", "v", 1); CHECK(a < b); CHECK(!(b < a)); } // Упорядочивание: равные ключи → seqNo DESC (новые впереди) { Record old_rec("key", "v1", 1); Record new_rec("key", "v2", 2); CHECK(new_rec < old_rec); // новее (higher seqNo) впереди в сортировке CHECK(!(old_rec < new_rec)); } // Поломанный буфер: слишком короткий { size_t consumed; auto r = Record::deserialize("", 0, consumed); CHECK(!r.has_value()); } // Поломанный буфер: keyLen больше доступного { std::string buf; // varint = 100 (длина ключа), но реальных байт нет buf.push_back(100); size_t consumed; auto r = Record::deserialize(buf.data(), buf.size(), consumed); CHECK(!r.has_value()); } // Множественные записи подряд — consumed правильный { Record a("key1", "val1", 1); Record b("key2", "val2", 2); std::string buf; a.serialize(buf); b.serialize(buf); size_t consumed; auto decoded_a = Record::deserialize(buf.data(), buf.size(), consumed); CHECK(decoded_a.has_value()); CHECK(*decoded_a == a); size_t first_size = consumed; auto decoded_b = Record::deserialize(buf.data() + first_size, buf.size() - first_size, consumed); CHECK(decoded_b.has_value()); CHECK(*decoded_b == b); } std::cout << "test_record: passed=" << g_passed << " failed=" << g_failed << "\n"; return g_failed == 0 ? 0 : 1; }