Add LOCK DATA DIRECTORY query (#68)
This commit is contained in:
committed by
Antonio Andelic
parent
8f5b88f24a
commit
a84ffe86c1
@@ -27,7 +27,7 @@ class FileLockerTest : public ::testing::Test {
|
||||
std::filesystem::current_path(testing_directory);
|
||||
|
||||
for (auto i = 1; i <= files_number; ++i) {
|
||||
std::ofstream file(fmt::format("{}", i));
|
||||
std::ofstream(fmt::format("{}", i));
|
||||
}
|
||||
|
||||
std::filesystem::current_path(save_path);
|
||||
@@ -40,52 +40,158 @@ class FileLockerTest : public ::testing::Test {
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(FileLockerTest, DeleteWhileLocking) {
|
||||
// Test are parameterized based on the type of path used for locking and
|
||||
// deleting. We test all of the combinations for absolute/relative paths for
|
||||
// locking path and absolute/relative paths for deleting
|
||||
// Parameter is represented by tuple (lock_absolute, delete_absolute).
|
||||
class FileLockerParameterizedTest
|
||||
: public FileLockerTest,
|
||||
public ::testing::WithParamInterface<std::tuple<bool, bool>> {};
|
||||
|
||||
TEST_P(FileLockerParameterizedTest, DeleteWhileLocking) {
|
||||
CreateFiles(1);
|
||||
utils::FileRetainer file_retainer;
|
||||
auto t1 = std::thread([&]() {
|
||||
const auto save_path = std::filesystem::current_path();
|
||||
std::filesystem::current_path(testing_directory);
|
||||
const auto file = std::filesystem::path("1");
|
||||
const auto file_absolute = std::filesystem::absolute(file);
|
||||
const auto [lock_absolute, delete_absolute] = GetParam();
|
||||
{
|
||||
auto locker = file_retainer.AddLocker();
|
||||
{
|
||||
auto acc = locker.Access();
|
||||
std::this_thread::sleep_for(100ms);
|
||||
file_retainer.DeleteFile(delete_absolute ? file_absolute : file);
|
||||
ASSERT_TRUE(std::filesystem::exists(file));
|
||||
}
|
||||
});
|
||||
const auto file = testing_directory / "1";
|
||||
auto t2 = std::thread([&]() {
|
||||
std::this_thread::sleep_for(50ms);
|
||||
file_retainer.DeleteFile(file);
|
||||
ASSERT_TRUE(std::filesystem::exists(file));
|
||||
});
|
||||
|
||||
t1.join();
|
||||
t2.join();
|
||||
}
|
||||
ASSERT_FALSE(std::filesystem::exists(file));
|
||||
|
||||
std::filesystem::current_path(save_path);
|
||||
}
|
||||
|
||||
TEST_F(FileLockerTest, DeleteWhileInLocker) {
|
||||
TEST_P(FileLockerParameterizedTest, DeleteWhileInLocker) {
|
||||
CreateFiles(1);
|
||||
utils::FileRetainer file_retainer;
|
||||
const auto file = testing_directory / "1";
|
||||
auto t1 = std::thread([&]() {
|
||||
const auto save_path = std::filesystem::current_path();
|
||||
std::filesystem::current_path(testing_directory);
|
||||
const auto file = std::filesystem::path("1");
|
||||
const auto file_absolute = std::filesystem::absolute(file);
|
||||
const auto [lock_absolute, delete_absolute] = GetParam();
|
||||
{
|
||||
auto locker = file_retainer.AddLocker();
|
||||
{
|
||||
auto acc = locker.Access();
|
||||
acc.AddFile(file);
|
||||
acc.AddPath(lock_absolute ? file_absolute : file);
|
||||
}
|
||||
std::this_thread::sleep_for(100ms);
|
||||
});
|
||||
|
||||
auto t2 = std::thread([&]() {
|
||||
std::this_thread::sleep_for(50ms);
|
||||
file_retainer.DeleteFile(file);
|
||||
file_retainer.DeleteFile(delete_absolute ? file_absolute : file);
|
||||
ASSERT_TRUE(std::filesystem::exists(file));
|
||||
});
|
||||
}
|
||||
|
||||
t1.join();
|
||||
t2.join();
|
||||
ASSERT_FALSE(std::filesystem::exists(file));
|
||||
std::filesystem::current_path(save_path);
|
||||
}
|
||||
|
||||
TEST_P(FileLockerParameterizedTest, DirectoryLock) {
|
||||
utils::FileRetainer file_retainer;
|
||||
// For this test we create the following file structure
|
||||
// testing_directory
|
||||
// 1
|
||||
// additional
|
||||
// 2
|
||||
// We check 2 cases:
|
||||
// - locking the subdirectory "additional", only "2" should be preserved
|
||||
// - locking the directory testing_directory, all of the files shold be
|
||||
// preserved
|
||||
ASSERT_TRUE(std::filesystem::create_directory(testing_directory));
|
||||
const auto save_path = std::filesystem::current_path();
|
||||
std::filesystem::current_path(testing_directory);
|
||||
|
||||
// Create additional directory inside the testing directory with a single file
|
||||
const auto additional_directory = std::filesystem::path("additional");
|
||||
ASSERT_TRUE(std::filesystem::create_directory(additional_directory));
|
||||
|
||||
const auto nested_file =
|
||||
std::filesystem::path(fmt::format("{}/2", additional_directory.string()));
|
||||
const auto nested_file_absolute = std::filesystem::absolute(nested_file);
|
||||
|
||||
const auto file = std::filesystem::path("1");
|
||||
const auto file_absolute = std::filesystem::absolute(file);
|
||||
const auto directory_lock_test = [&](const bool lock_nested_directory) {
|
||||
const auto directory_to_lock =
|
||||
lock_nested_directory ? additional_directory : testing_directory;
|
||||
const auto [lock_absolute, delete_absolute] = GetParam();
|
||||
std::ofstream(file.string());
|
||||
std::ofstream(nested_file.string());
|
||||
{
|
||||
auto locker = file_retainer.AddLocker();
|
||||
{
|
||||
auto acc = locker.Access();
|
||||
acc.AddPath(lock_absolute ? std::filesystem::absolute(directory_to_lock)
|
||||
: directory_to_lock);
|
||||
}
|
||||
|
||||
file_retainer.DeleteFile(delete_absolute ? file_absolute : file);
|
||||
ASSERT_NE(std::filesystem::exists(file), lock_nested_directory);
|
||||
file_retainer.DeleteFile(delete_absolute ? nested_file_absolute
|
||||
: nested_file);
|
||||
ASSERT_TRUE(std::filesystem::exists(nested_file));
|
||||
}
|
||||
ASSERT_FALSE(std::filesystem::exists(file));
|
||||
ASSERT_FALSE(std::filesystem::exists(nested_file));
|
||||
};
|
||||
|
||||
directory_lock_test(true);
|
||||
directory_lock_test(false);
|
||||
|
||||
std::filesystem::current_path(save_path);
|
||||
}
|
||||
|
||||
TEST_P(FileLockerParameterizedTest, RemovePath) {
|
||||
utils::FileRetainer file_retainer;
|
||||
ASSERT_TRUE(std::filesystem::create_directory(testing_directory));
|
||||
const auto save_path = std::filesystem::current_path();
|
||||
std::filesystem::current_path(testing_directory);
|
||||
const auto file = std::filesystem::path("1");
|
||||
const auto file_absolute = std::filesystem::absolute(file);
|
||||
auto remove_path_test = [&](const bool delete_explicitly_file) {
|
||||
const auto [lock_absolute, delete_absolute] = GetParam();
|
||||
// Create the file
|
||||
std::ofstream(file.string());
|
||||
auto locker = file_retainer.AddLocker();
|
||||
{
|
||||
auto acc = locker.Access();
|
||||
acc.AddPath(lock_absolute ? file_absolute : file);
|
||||
}
|
||||
|
||||
file_retainer.DeleteFile(delete_absolute ? file_absolute : file);
|
||||
ASSERT_TRUE(std::filesystem::exists(file));
|
||||
|
||||
{
|
||||
auto acc = locker.Access();
|
||||
// If absolute was sent to AddPath method, use relative now
|
||||
// to test those combinations.
|
||||
acc.RemovePath(lock_absolute ? file : file_absolute);
|
||||
}
|
||||
if (delete_explicitly_file) {
|
||||
file_retainer.DeleteFile(delete_absolute ? file_absolute : file);
|
||||
} else {
|
||||
file_retainer.CleanQueue();
|
||||
}
|
||||
ASSERT_FALSE(std::filesystem::exists(file));
|
||||
};
|
||||
|
||||
remove_path_test(true);
|
||||
remove_path_test(false);
|
||||
std::filesystem::current_path(save_path);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(FileLockerPathVariantTests, FileLockerParameterizedTest,
|
||||
::testing::Values(std::make_tuple(false, false),
|
||||
std::make_tuple(false, true),
|
||||
std::make_tuple(true, false),
|
||||
std::make_tuple(true, true)));
|
||||
|
||||
TEST_F(FileLockerTest, MultipleLockers) {
|
||||
CreateFiles(3);
|
||||
utils::FileRetainer file_retainer;
|
||||
@@ -97,17 +203,18 @@ TEST_F(FileLockerTest, MultipleLockers) {
|
||||
auto locker = file_retainer.AddLocker();
|
||||
{
|
||||
auto acc = locker.Access();
|
||||
acc.AddFile(file1);
|
||||
acc.AddFile(common_file);
|
||||
acc.AddPath(file1);
|
||||
acc.AddPath(common_file);
|
||||
}
|
||||
std::this_thread::sleep_for(200ms);
|
||||
});
|
||||
|
||||
auto t2 = std::thread([&]() {
|
||||
auto locker = file_retainer.AddLocker();
|
||||
{
|
||||
auto acc = locker.Access();
|
||||
acc.AddFile(file2);
|
||||
acc.AddFile(common_file);
|
||||
acc.AddPath(file2);
|
||||
acc.AddPath(common_file);
|
||||
}
|
||||
std::this_thread::sleep_for(200ms);
|
||||
});
|
||||
@@ -117,7 +224,7 @@ TEST_F(FileLockerTest, MultipleLockers) {
|
||||
file_retainer.DeleteFile(file1);
|
||||
file_retainer.DeleteFile(file2);
|
||||
file_retainer.DeleteFile(common_file);
|
||||
ASSERT_FALSE(std::filesystem::exists(file1));
|
||||
ASSERT_TRUE(std::filesystem::exists(file1));
|
||||
ASSERT_TRUE(std::filesystem::exists(file2));
|
||||
ASSERT_TRUE(std::filesystem::exists(common_file));
|
||||
});
|
||||
@@ -168,7 +275,7 @@ TEST_F(FileLockerTest, MultipleLockersAndDeleters) {
|
||||
auto acc = locker.Access();
|
||||
for (auto i = 0; i < file_access_num; ++i) {
|
||||
auto file = random_file();
|
||||
if (acc.AddFile(file)) {
|
||||
if (acc.AddPath(file)) {
|
||||
ASSERT_TRUE(std::filesystem::exists(file));
|
||||
locked_files.emplace_back(std::move(file));
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user