memgraph/tests/unit/property_value_store.cpp
Teon Banek ed802073f6 Make PropertyValue constructors explicit
Summary: Depends on D2332

Reviewers: ipaljak, mferencevic

Reviewed By: ipaljak

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D2333
2019-09-02 12:31:53 +02:00

386 lines
12 KiB
C++

#include <unistd.h>
#include <vector>
#include <gflags/gflags.h>
#include <gtest/gtest.h>
#include "storage/common/types/property_value.hpp"
#include "storage/common/types/property_value_store.hpp"
#include "utils/file.hpp"
using Location = storage::Location;
namespace fs = std::filesystem;
DECLARE_string(durability_directory);
DECLARE_string(properties_on_disk);
class PropertyValueStoreTest : public ::testing::Test {
protected:
PropertyValueStore props_;
void SetUp() override {
// we need this to test the copy constructor
FLAGS_properties_on_disk = "not empty";
auto durability_path = fs::temp_directory_path() /
("unit_property_value_store_durability_" +
std::to_string(static_cast<int>(getpid())));
FLAGS_durability_directory = durability_path.string();
utils::EnsureDir(fs::path(FLAGS_durability_directory));
}
template <class TValue>
void Set(int key, Location location, const TValue &value) {
props_.set(storage::Property(key, location), PropertyValue(value));
}
PropertyValue At(int key, Location location) {
return props_.at(storage::Property(key, location));
}
auto Erase(int key, Location location) {
return props_.erase(storage::Property(key, location));
}
auto Begin() { return props_.begin(); }
auto End() { return props_.end(); }
void TearDown() override {
props_.clear();
fs::remove_all(fs::path(FLAGS_durability_directory));
}
};
TEST_F(PropertyValueStoreTest, AtMemory) {
std::string some_string = "something";
EXPECT_EQ(PropertyValue(At(0, Location::Memory)).type(),
PropertyValue::Type::Null);
Set(0, Location::Memory, some_string);
EXPECT_EQ(PropertyValue(At(0, Location::Memory)).ValueString(),
some_string);
Set(120, Location::Memory, 42);
EXPECT_EQ(PropertyValue(At(120, Location::Memory)).ValueInt(), 42);
}
TEST_F(PropertyValueStoreTest, AtDisk) {
std::string some_string = "something";
EXPECT_EQ(PropertyValue(At(0, Location::Disk)).type(),
PropertyValue::Type::Null);
Set(0, Location::Disk, some_string);
EXPECT_EQ(PropertyValue(At(0, Location::Disk)).ValueString(),
some_string);
Set(120, Location::Disk, 42);
EXPECT_EQ(PropertyValue(At(120, Location::Disk)).ValueInt(), 42);
}
TEST_F(PropertyValueStoreTest, AtNull) {
EXPECT_EQ(At(0, Location::Memory).type(), PropertyValue::Type::Null);
EXPECT_EQ(At(100, Location::Memory).type(), PropertyValue::Type::Null);
EXPECT_EQ(At(0, Location::Disk).type(), PropertyValue::Type::Null);
EXPECT_EQ(At(100, Location::Disk).type(), PropertyValue::Type::Null);
// set one prop and test it's not null
Set(0, Location::Memory, true);
EXPECT_NE(At(0, Location::Memory).type(), PropertyValue::Type::Null);
EXPECT_EQ(At(100, Location::Memory).type(), PropertyValue::Type::Null);
Set(0, Location::Disk, true);
EXPECT_NE(At(0, Location::Disk).type(), PropertyValue::Type::Null);
EXPECT_EQ(At(100, Location::Disk).type(), PropertyValue::Type::Null);
}
TEST_F(PropertyValueStoreTest, SetNull) {
Set(11, Location::Memory, PropertyValue());
EXPECT_EQ(0, props_.size());
Set(100, Location::Disk, PropertyValue());
EXPECT_EQ(0, props_.size());
}
TEST_F(PropertyValueStoreTest, RemoveMemory) {
// set some props
Set(11, Location::Memory, "a");
Set(30, Location::Memory, "b");
EXPECT_NE(At(11, Location::Memory).type(), PropertyValue::Type::Null);
EXPECT_NE(At(30, Location::Memory).type(), PropertyValue::Type::Null);
EXPECT_EQ(props_.size(), 2);
Erase(11, Location::Memory);
EXPECT_EQ(props_.size(), 1);
EXPECT_EQ(At(11, Location::Memory).type(), PropertyValue::Type::Null);
EXPECT_EQ(Erase(30, Location::Memory), 1);
EXPECT_EQ(props_.size(), 0);
EXPECT_EQ(At(30, Location::Memory).type(), PropertyValue::Type::Null);
EXPECT_EQ(Erase(1000, Location::Memory), 1);
}
TEST_F(PropertyValueStoreTest, RemoveDisk) {
// set some props
Set(11, Location::Disk, "a");
Set(30, Location::Disk, "b");
EXPECT_NE(At(11, Location::Disk).type(), PropertyValue::Type::Null);
EXPECT_NE(At(30, Location::Disk).type(), PropertyValue::Type::Null);
EXPECT_EQ(props_.size(), 2);
Erase(11, Location::Disk);
EXPECT_EQ(props_.size(), 1);
EXPECT_EQ(At(11, Location::Disk).type(), PropertyValue::Type::Null);
EXPECT_EQ(Erase(30, Location::Disk), 1);
EXPECT_EQ(props_.size(), 0);
EXPECT_EQ(At(30, Location::Disk).type(), PropertyValue::Type::Null);
EXPECT_EQ(Erase(1000, Location::Disk), 1);
}
TEST_F(PropertyValueStoreTest, ClearMemory) {
EXPECT_EQ(props_.size(), 0);
Set(11, Location::Memory, "a");
Set(30, Location::Memory, "b");
EXPECT_EQ(props_.size(), 2);
}
TEST_F(PropertyValueStoreTest, ClearDisk) {
EXPECT_EQ(props_.size(), 0);
Set(11, Location::Disk, "a");
Set(30, Location::Disk, "b");
EXPECT_EQ(props_.size(), 2);
}
TEST_F(PropertyValueStoreTest, ReplaceMemory) {
Set(10, Location::Memory, 42);
EXPECT_EQ(At(10, Location::Memory).ValueInt(), 42);
Set(10, Location::Memory, 0.25f);
EXPECT_EQ(At(10, Location::Memory).type(), PropertyValue::Type::Double);
EXPECT_FLOAT_EQ(At(10, Location::Memory).ValueDouble(), 0.25);
}
TEST_F(PropertyValueStoreTest, ReplaceDisk) {
Set(10, Location::Disk, 42);
EXPECT_EQ(At(10, Location::Disk).ValueInt(), 42);
Set(10, Location::Disk, 0.25f);
EXPECT_EQ(At(10, Location::Disk).type(), PropertyValue::Type::Double);
EXPECT_FLOAT_EQ(At(10, Location::Disk).ValueDouble(), 0.25);
}
TEST_F(PropertyValueStoreTest, SizeMemory) {
EXPECT_EQ(props_.size(), 0);
Set(0, Location::Memory, "something");
EXPECT_EQ(props_.size(), 1);
Set(0, Location::Memory, true);
EXPECT_EQ(props_.size(), 1);
Set(1, Location::Memory, true);
EXPECT_EQ(props_.size(), 2);
for (int i = 0; i < 100; ++i) Set(i + 20, Location::Memory, true);
EXPECT_EQ(props_.size(), 102);
Erase(0, Location::Memory);
EXPECT_EQ(props_.size(), 101);
Erase(0, Location::Memory);
EXPECT_EQ(props_.size(), 101);
Erase(1, Location::Memory);
EXPECT_EQ(props_.size(), 100);
}
TEST_F(PropertyValueStoreTest, SizeDisk) {
EXPECT_EQ(props_.size(), 0);
Set(0, Location::Disk, "something");
EXPECT_EQ(props_.size(), 1);
Set(0, Location::Disk, true);
EXPECT_EQ(props_.size(), 1);
Set(1, Location::Disk, true);
EXPECT_EQ(props_.size(), 2);
for (int i = 0; i < 100; ++i) Set(i + 20, Location::Disk, true);
EXPECT_EQ(props_.size(), 102);
Erase(0, Location::Disk);
EXPECT_EQ(props_.size(), 101);
Erase(0, Location::Disk);
EXPECT_EQ(props_.size(), 101);
Erase(1, Location::Disk);
EXPECT_EQ(props_.size(), 100);
}
TEST_F(PropertyValueStoreTest, Size) {
EXPECT_EQ(props_.size(), 0);
for (int i = 0; i < 100; ++i) Set(i, Location::Disk, true);
EXPECT_EQ(props_.size(), 100);
for (int i = 0; i < 200; ++i) Set(i + 100, Location::Memory, true);
EXPECT_EQ(props_.size(), 300);
Erase(0, Location::Disk);
EXPECT_EQ(props_.size(), 299);
Erase(99, Location::Disk);
EXPECT_EQ(props_.size(), 298);
Erase(100, Location::Memory);
EXPECT_EQ(props_.size(), 297);
Erase(299, Location::Memory);
EXPECT_EQ(props_.size(), 296);
}
TEST_F(PropertyValueStoreTest, InsertRetrieveListMemory) {
Set(0, Location::Memory,
std::vector<PropertyValue>{PropertyValue(1), PropertyValue(true),
PropertyValue(2.5), PropertyValue("something"),
PropertyValue()});
auto p = At(0, Location::Memory);
EXPECT_EQ(p.type(), PropertyValue::Type::List);
auto l = p.ValueList();
EXPECT_EQ(l.size(), 5);
EXPECT_EQ(l[0].type(), PropertyValue::Type::Int);
EXPECT_EQ(l[0].ValueInt(), 1);
EXPECT_EQ(l[1].type(), PropertyValue::Type::Bool);
EXPECT_EQ(l[1].ValueBool(), true);
EXPECT_EQ(l[2].type(), PropertyValue::Type::Double);
EXPECT_EQ(l[2].ValueDouble(), 2.5);
EXPECT_EQ(l[3].type(), PropertyValue::Type::String);
EXPECT_EQ(l[3].ValueString(), "something");
EXPECT_EQ(l[4].type(), PropertyValue::Type::Null);
}
TEST_F(PropertyValueStoreTest, InsertRetrieveListDisk) {
Set(0, Location::Disk,
std::vector<PropertyValue>{PropertyValue(1), PropertyValue(true),
PropertyValue(2.5), PropertyValue("something"),
PropertyValue()});
auto p = At(0, Location::Disk);
EXPECT_EQ(p.type(), PropertyValue::Type::List);
auto l = p.ValueList();
EXPECT_EQ(l.size(), 5);
EXPECT_EQ(l[0].type(), PropertyValue::Type::Int);
EXPECT_EQ(l[0].ValueInt(), 1);
EXPECT_EQ(l[1].type(), PropertyValue::Type::Bool);
EXPECT_EQ(l[1].ValueBool(), true);
EXPECT_EQ(l[2].type(), PropertyValue::Type::Double);
EXPECT_EQ(l[2].ValueDouble(), 2.5);
EXPECT_EQ(l[3].type(), PropertyValue::Type::String);
EXPECT_EQ(l[3].ValueString(), "something");
EXPECT_EQ(l[4].type(), PropertyValue::Type::Null);
}
TEST_F(PropertyValueStoreTest, InsertRetrieveMap) {
Set(0, Location::Memory,
std::map<std::string, PropertyValue>{{"a", PropertyValue(1)},
{"b", PropertyValue(true)},
{"c", PropertyValue("something")}});
auto p = At(0, Location::Memory);
EXPECT_EQ(p.type(), PropertyValue::Type::Map);
auto m = p.ValueMap();
EXPECT_EQ(m.size(), 3);
auto get = [&m](const std::string &prop_name) {
return m.find(prop_name)->second;
};
EXPECT_EQ(get("a").type(), PropertyValue::Type::Int);
EXPECT_EQ(get("a").ValueInt(), 1);
EXPECT_EQ(get("b").type(), PropertyValue::Type::Bool);
EXPECT_EQ(get("b").ValueBool(), true);
EXPECT_EQ(get("c").type(), PropertyValue::Type::String);
EXPECT_EQ(get("c").ValueString(), "something");
}
TEST_F(PropertyValueStoreTest, InsertRetrieveMapDisk) {
Set(0, Location::Disk,
std::map<std::string, PropertyValue>{{"a", PropertyValue(1)},
{"b", PropertyValue(true)},
{"c", PropertyValue("something")}});
auto p = At(0, Location::Disk);
EXPECT_EQ(p.type(), PropertyValue::Type::Map);
auto m = p.ValueMap();
EXPECT_EQ(m.size(), 3);
auto get = [&m](const std::string &prop_name) {
return m.find(prop_name)->second;
};
EXPECT_EQ(get("a").type(), PropertyValue::Type::Int);
EXPECT_EQ(get("a").ValueInt(), 1);
EXPECT_EQ(get("b").type(), PropertyValue::Type::Bool);
EXPECT_EQ(get("b").ValueBool(), true);
EXPECT_EQ(get("c").type(), PropertyValue::Type::String);
EXPECT_EQ(get("c").ValueString(), "something");
}
TEST_F(PropertyValueStoreTest, Iterator) {
Set(0, Location::Memory, "a");
Set(1, Location::Memory, 1);
Set(2, Location::Disk, "b");
Set(3, Location::Disk, 2);
auto it = Begin();
ASSERT_TRUE(it != End());
EXPECT_EQ(it->first.Id(), 0);
EXPECT_EQ((*it).second.ValueString(), "a");
++it;
ASSERT_TRUE(it != End());
EXPECT_EQ((*it).first.Id(), 1);
EXPECT_EQ(it->second.ValueInt(), 1);
++it;
ASSERT_TRUE(it != End());
EXPECT_EQ(it->first.Id(), 2);
EXPECT_EQ((*it).second.ValueString(), "b");
++it;
ASSERT_TRUE(it != End());
EXPECT_EQ((*it).first.Id(), 3);
EXPECT_EQ(it->second.ValueInt(), 2);
++it;
ASSERT_TRUE(it == End());
}
TEST_F(PropertyValueStoreTest, CopyConstructor) {
PropertyValueStore props;
for (int i = 1; i <= 3; ++i)
props.set(storage::Property(i, Location::Memory),
PropertyValue("mem_" + std::to_string(i)));
for (int i = 4; i <= 5; ++i)
props.set(storage::Property(i, Location::Disk),
PropertyValue("disk_" + std::to_string(i)));
PropertyValueStore new_props = props;
for (int i = 1; i <= 3; ++i)
EXPECT_EQ(
new_props.at(storage::Property(i, Location::Memory)).ValueString(),
"mem_" + std::to_string(i));
for (int i = 4; i <= 5; ++i)
EXPECT_EQ(new_props.at(storage::Property(i, Location::Disk)).ValueString(),
"disk_" + std::to_string(i));
props.set(storage::Property(1, Location::Memory),
PropertyValue("mem_1_update"));
EXPECT_EQ(new_props.at(storage::Property(1, Location::Memory)).ValueString(),
"mem_1");
new_props.set(storage::Property(2, Location::Memory),
PropertyValue("mem_2_update"));
EXPECT_EQ(props.at(storage::Property(2, Location::Memory)).ValueString(),
"mem_2");
props.set(storage::Property(4, Location::Disk),
PropertyValue("disk_4_update"));
EXPECT_EQ(new_props.at(storage::Property(4, Location::Disk)).ValueString(),
"disk_4");
new_props.set(storage::Property(5, Location::Disk),
PropertyValue("disk_5_update"));
EXPECT_EQ(props.at(storage::Property(5, Location::Disk)).ValueString(),
"disk_5");
}