/
smychkov
/
SStorage
Обзор
Документация
Войти
/
smychkov
/
SStorage
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
tests/test_database.cpp
187 строк
5 KB
Андрей Смычков
feat: Database facade + Config + CLI
25 апр 2026, 09:16
25 апр 2026, 09:16
411df24
Код
Авторство
О чём код?
//============================================================================ // Тесты для Database facade //============================================================================ #include "../src/core/database.hpp" #include <cstdlib> #include <filesystem> #include <iostream> #include <string> #include <sys/stat.h> #include <unistd.h> 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) static std::string makeTempDir(const std::string& prefix) { std::string p = "/tmp/sstorage_db_" + prefix + "_" + std::to_string(::getpid()) + "_" + std::to_string(rand()); ::mkdir(p.c_str(), 0755); return p; } static void cleanupDir(const std::string& dir) { std::error_code ec; std::filesystem::remove_all(dir, ec); } int main() { // 1. Базовый put/get/remove { auto dir = makeTempDir("basic"); Config cfg; cfg.setDataDirectory(dir); Database db(cfg); CHECK(db.open()); CHECK(db.put("hello", "world")); auto v = db.get("hello"); CHECK(v.has_value() && *v == "world"); CHECK(db.remove("hello")); CHECK(!db.get("hello").has_value()); db.close(); cleanupDir(dir); } // 2. Валидация: пустой ключ запрещён { auto dir = makeTempDir("empty_key"); Config cfg; cfg.setDataDirectory(dir); Database db(cfg); db.open(); CHECK(!db.put("", "value")); CHECK(!db.get("").has_value()); CHECK(!db.remove("")); db.close(); cleanupDir(dir); } // 3. Валидация: слишком большой ключ/значение { auto dir = makeTempDir("size_limit"); Config cfg; cfg.setDataDirectory(dir); cfg.setMaxKeySize(10); cfg.setMaxValueSize(20); Database db(cfg); db.open(); CHECK(!db.put(std::string(11, 'k'), "ok")); CHECK(!db.put("ok", std::string(21, 'v'))); CHECK(db.put(std::string(10, 'k'), std::string(20, 'v'))); db.close(); cleanupDir(dir); } // 4. Нельзя вызывать put до open() { auto dir = makeTempDir("not_open"); Config cfg; cfg.setDataDirectory(dir); Database db(cfg); CHECK(!db.put("k", "v")); CHECK(!db.get("k").has_value()); CHECK(!db.remove("k")); cleanupDir(dir); } // 5. Persistence через close/open { auto dir = makeTempDir("persist"); { Config cfg; cfg.setDataDirectory(dir); Database db(cfg); db.open(); for (int i = 0; i < 100; ++i) { db.put("key" + std::to_string(i), "value" + std::to_string(i)); } db.close(); } { Config cfg; cfg.setDataDirectory(dir); Database db(cfg); CHECK(db.open()); int found = 0; for (int i = 0; i < 100; ++i) { auto v = db.get("key" + std::to_string(i)); if (v.has_value() && *v == "value" + std::to_string(i)) ++found; } CHECK(found == 100); db.close(); } cleanupDir(dir); } // 6. scan { auto dir = makeTempDir("scan"); Config cfg; cfg.setDataDirectory(dir); Database db(cfg); db.open(); for (int i = 0; i < 50; ++i) { char k[16]; std::snprintf(k, sizeof(k), "key_%03d", i); db.put(k, "val_" + std::to_string(i)); } auto res = db.scan("key_010", "key_020", 0); CHECK(res.size() == 11); CHECK(res.front().first == "key_010"); CHECK(res.back().first == "key_020"); db.close(); cleanupDir(dir); } // 7. Stats { auto dir = makeTempDir("stats"); Config cfg; cfg.setDataDirectory(dir); Database db(cfg); db.open(); for (int i = 0; i < 10; ++i) { db.put("k" + std::to_string(i), "v"); } auto s = db.stats(); CHECK(s.memtableSize > 0); db.close(); cleanupDir(dir); } // 8. flush / compact — не падают на пустой БД { auto dir = makeTempDir("admin"); Config cfg; cfg.setDataDirectory(dir); Database db(cfg); db.open(); CHECK(db.flush()); CHECK(db.compact()); db.close(); cleanupDir(dir); } std::cout << "test_database: passed=" << g_passed << " failed=" << g_failed << "\n"; return g_failed == 0 ? 0 : 1; }