238 lines
7.1 KiB
C++
238 lines
7.1 KiB
C++
// Copyright 2023 Memgraph Ltd.
|
|
//
|
|
// Use of this software is governed by the Business Source License
|
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
|
// License, and you may not use this file except in compliance with the Business Source License.
|
|
//
|
|
// As of the Change Date specified in that file, in accordance with
|
|
// the Business Source License, use of this software will be governed
|
|
// by the Apache License, Version 2.0, included in the file
|
|
// licenses/APL.txt.
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "kvstore/kvstore.hpp"
|
|
#include "utils/file.hpp"
|
|
|
|
namespace fs = std::filesystem;
|
|
|
|
class KVStore : public ::testing::Test {
|
|
protected:
|
|
void SetUp() override { memgraph::utils::EnsureDir(test_folder_); }
|
|
|
|
void TearDown() override { fs::remove_all(test_folder_); }
|
|
|
|
fs::path test_folder_{fs::temp_directory_path() /
|
|
("unit_kvstore_test_" + std::to_string(static_cast<int>(getpid())))};
|
|
};
|
|
|
|
TEST_F(KVStore, PutGet) {
|
|
memgraph::kvstore::KVStore kvstore(test_folder_ / "PutGet");
|
|
ASSERT_TRUE(kvstore.Put("key", "value"));
|
|
ASSERT_EQ(kvstore.Get("key").value(), "value");
|
|
}
|
|
|
|
TEST_F(KVStore, PutMultipleGet) {
|
|
memgraph::kvstore::KVStore kvstore(test_folder_ / "PutMultipleGet");
|
|
ASSERT_TRUE(kvstore.PutMultiple({{"key1", "value1"}, {"key2", "value2"}}));
|
|
ASSERT_EQ(kvstore.Get("key1").value(), "value1");
|
|
ASSERT_EQ(kvstore.Get("key2").value(), "value2");
|
|
}
|
|
|
|
TEST_F(KVStore, PutGetDeleteGet) {
|
|
memgraph::kvstore::KVStore kvstore(test_folder_ / "PutGetDeleteGet");
|
|
ASSERT_TRUE(kvstore.Put("key", "value"));
|
|
ASSERT_EQ(kvstore.Get("key").value(), "value");
|
|
ASSERT_TRUE(kvstore.Delete("key"));
|
|
ASSERT_FALSE(static_cast<bool>(kvstore.Get("key")));
|
|
}
|
|
|
|
TEST_F(KVStore, PutMultipleGetDeleteMultipleGet) {
|
|
memgraph::kvstore::KVStore kvstore(test_folder_ / "PutMultipleGetDeleteMultipleGet");
|
|
ASSERT_TRUE(kvstore.PutMultiple({{"key1", "value1"}, {"key2", "value2"}}));
|
|
ASSERT_EQ(kvstore.Get("key1").value(), "value1");
|
|
ASSERT_EQ(kvstore.Get("key2").value(), "value2");
|
|
ASSERT_TRUE(kvstore.DeleteMultiple({"key1", "key2", "key3"}));
|
|
ASSERT_FALSE(static_cast<bool>(kvstore.Get("key1")));
|
|
ASSERT_FALSE(static_cast<bool>(kvstore.Get("key2")));
|
|
ASSERT_FALSE(static_cast<bool>(kvstore.Get("key3")));
|
|
}
|
|
|
|
TEST_F(KVStore, PutMultipleGetPutAndDeleteMultipleGet) {
|
|
memgraph::kvstore::KVStore kvstore(test_folder_ / "PutMultipleGetPutAndDeleteMultipleGet");
|
|
ASSERT_TRUE(kvstore.PutMultiple({{"key1", "value1"}, {"key2", "value2"}}));
|
|
ASSERT_EQ(kvstore.Get("key1").value(), "value1");
|
|
ASSERT_EQ(kvstore.Get("key2").value(), "value2");
|
|
ASSERT_TRUE(kvstore.PutAndDeleteMultiple({{"key3", "value3"}}, {"key1", "key2"}));
|
|
ASSERT_FALSE(static_cast<bool>(kvstore.Get("key1")));
|
|
ASSERT_FALSE(static_cast<bool>(kvstore.Get("key2")));
|
|
ASSERT_EQ(kvstore.Get("key3").value(), "value3");
|
|
}
|
|
|
|
TEST_F(KVStore, Durability) {
|
|
{
|
|
memgraph::kvstore::KVStore kvstore(test_folder_ / "Durability");
|
|
ASSERT_TRUE(kvstore.Put("key", "value"));
|
|
}
|
|
{
|
|
memgraph::kvstore::KVStore kvstore(test_folder_ / "Durability");
|
|
ASSERT_EQ(kvstore.Get("key").value(), "value");
|
|
}
|
|
}
|
|
|
|
TEST_F(KVStore, Size) {
|
|
memgraph::kvstore::KVStore kvstore(test_folder_ / "Size");
|
|
|
|
ASSERT_TRUE(kvstore.Put("prefix_1", "jedan"));
|
|
ASSERT_TRUE(kvstore.Put("prefix_2", "dva"));
|
|
ASSERT_TRUE(kvstore.Put("prefix_3", "tri"));
|
|
ASSERT_TRUE(kvstore.Put("prefix_4", "cetiri"));
|
|
ASSERT_TRUE(kvstore.Put("prefix_5", "pet"));
|
|
|
|
EXPECT_EQ(kvstore.Size("a"), 0);
|
|
EXPECT_EQ(kvstore.Size(), 5);
|
|
EXPECT_EQ(kvstore.Size("prefix_"), 5);
|
|
EXPECT_EQ(kvstore.Size("prefix_1"), 1);
|
|
|
|
ASSERT_TRUE(kvstore.Put("predmetak_1", "jedan"));
|
|
ASSERT_TRUE(kvstore.Put("predmetak_2", "dva"));
|
|
ASSERT_TRUE(kvstore.Put("predmetak_3", "tri"));
|
|
ASSERT_TRUE(kvstore.Put("predmetak_4", "cetiri"));
|
|
|
|
EXPECT_EQ(kvstore.Size("a"), 0);
|
|
EXPECT_EQ(kvstore.Size(), 9);
|
|
EXPECT_EQ(kvstore.Size("prefix_"), 5);
|
|
EXPECT_EQ(kvstore.Size("predmetak_"), 4);
|
|
EXPECT_EQ(kvstore.Size("p"), 9);
|
|
EXPECT_EQ(kvstore.Size("pre"), 9);
|
|
EXPECT_EQ(kvstore.Size("pred"), 4);
|
|
EXPECT_EQ(kvstore.Size("pref"), 5);
|
|
EXPECT_EQ(kvstore.Size("prex"), 0);
|
|
}
|
|
|
|
TEST_F(KVStore, DeletePrefix) {
|
|
memgraph::kvstore::KVStore kvstore(test_folder_ / "DeletePrefix");
|
|
|
|
ASSERT_TRUE(kvstore.Put("prefix_1", "jedan"));
|
|
ASSERT_TRUE(kvstore.Put("prefix_2", "dva"));
|
|
ASSERT_TRUE(kvstore.Put("prefix_3", "tri"));
|
|
ASSERT_TRUE(kvstore.Put("prefix_4", "cetiri"));
|
|
ASSERT_TRUE(kvstore.Put("prefix_5", "pet"));
|
|
|
|
EXPECT_EQ(kvstore.Size(), 5);
|
|
|
|
ASSERT_TRUE(kvstore.DeletePrefix("prefix_5"));
|
|
|
|
EXPECT_EQ(kvstore.Size(), 4);
|
|
EXPECT_EQ(kvstore.Size("prefix_"), 4);
|
|
EXPECT_EQ(kvstore.Size("prefix_1"), 1);
|
|
|
|
ASSERT_TRUE(kvstore.Put("predmetak_1", "jedan"));
|
|
ASSERT_TRUE(kvstore.Put("predmetak_2", "dva"));
|
|
ASSERT_TRUE(kvstore.Put("predmetak_3", "tri"));
|
|
ASSERT_TRUE(kvstore.Put("predmetak_4", "cetiri"));
|
|
|
|
EXPECT_EQ(kvstore.Size(), 8);
|
|
|
|
ASSERT_TRUE(kvstore.DeletePrefix("predmetak_1"));
|
|
EXPECT_EQ(kvstore.Size(), 7);
|
|
|
|
ASSERT_TRUE(kvstore.DeletePrefix("prefix_"));
|
|
EXPECT_EQ(kvstore.Size(), 3);
|
|
|
|
ASSERT_TRUE(kvstore.DeletePrefix("predmetak_"));
|
|
EXPECT_EQ(kvstore.Size(), 0);
|
|
|
|
ASSERT_TRUE(kvstore.DeletePrefix("whatever"));
|
|
EXPECT_EQ(kvstore.Size(), 0);
|
|
EXPECT_EQ(kvstore.Size("any_prefix"), 0);
|
|
}
|
|
|
|
TEST_F(KVStore, Iterator) {
|
|
memgraph::kvstore::KVStore kvstore(test_folder_ / "Iterator");
|
|
|
|
for (int i = 1; i <= 4; ++i) ASSERT_TRUE(kvstore.Put("key" + std::to_string(i), "value" + std::to_string(i)));
|
|
|
|
auto it = kvstore.begin();
|
|
ASSERT_TRUE(it.IsValid());
|
|
EXPECT_EQ(it->first, "key1");
|
|
EXPECT_EQ((*it).second, "value1");
|
|
|
|
++it;
|
|
ASSERT_TRUE(it.IsValid());
|
|
EXPECT_EQ((*it).first, "key2");
|
|
EXPECT_EQ(it->second, "value2");
|
|
|
|
++it;
|
|
ASSERT_TRUE(it.IsValid());
|
|
EXPECT_EQ(it->first, "key3");
|
|
EXPECT_EQ((*it).second, "value3");
|
|
|
|
++it;
|
|
ASSERT_TRUE(it.IsValid());
|
|
EXPECT_EQ((*it).first, "key4");
|
|
EXPECT_EQ(it->second, "value4");
|
|
|
|
++it;
|
|
ASSERT_FALSE(it.IsValid());
|
|
}
|
|
|
|
TEST_F(KVStore, IteratorPrefix) {
|
|
memgraph::kvstore::KVStore kvstore(test_folder_ / "Iterator");
|
|
|
|
ASSERT_TRUE(kvstore.Put("a_1", "value1"));
|
|
ASSERT_TRUE(kvstore.Put("a_2", "value2"));
|
|
|
|
ASSERT_TRUE(kvstore.Put("aa_1", "value1"));
|
|
ASSERT_TRUE(kvstore.Put("aa_2", "value2"));
|
|
|
|
ASSERT_TRUE(kvstore.Put("b_1", "value1"));
|
|
ASSERT_TRUE(kvstore.Put("b_2", "value2"));
|
|
|
|
auto it = kvstore.begin("a");
|
|
ASSERT_TRUE(it.IsValid());
|
|
EXPECT_EQ(it->first, "a_1");
|
|
|
|
++it;
|
|
ASSERT_TRUE(it.IsValid());
|
|
EXPECT_EQ(it->first, "a_2");
|
|
|
|
++it;
|
|
ASSERT_TRUE(it.IsValid());
|
|
EXPECT_EQ(it->first, "aa_1");
|
|
|
|
++it;
|
|
ASSERT_TRUE(it.IsValid());
|
|
EXPECT_EQ(it->first, "aa_2");
|
|
|
|
++it;
|
|
ASSERT_FALSE(it.IsValid());
|
|
|
|
it = kvstore.begin("aa_");
|
|
ASSERT_TRUE(it.IsValid());
|
|
EXPECT_EQ(it->first, "aa_1");
|
|
|
|
++it;
|
|
ASSERT_TRUE(it.IsValid());
|
|
EXPECT_EQ(it->first, "aa_2");
|
|
|
|
++it;
|
|
ASSERT_FALSE(it.IsValid());
|
|
|
|
it = kvstore.begin("b_");
|
|
ASSERT_TRUE(it.IsValid());
|
|
EXPECT_EQ(it->first, "b_1");
|
|
|
|
++it;
|
|
ASSERT_TRUE(it.IsValid());
|
|
EXPECT_EQ(it->first, "b_2");
|
|
|
|
++it;
|
|
ASSERT_FALSE(it.IsValid());
|
|
|
|
it = kvstore.begin("unexisting_prefix");
|
|
ASSERT_FALSE(it.IsValid());
|
|
}
|