diff --git a/repertory/librepertory/include/providers/encrypt/encrypt_provider.hpp b/repertory/librepertory/include/providers/encrypt/encrypt_provider.hpp index a57af6b6..18351f57 100644 --- a/repertory/librepertory/include/providers/encrypt/encrypt_provider.hpp +++ b/repertory/librepertory/include/providers/encrypt/encrypt_provider.hpp @@ -29,6 +29,9 @@ namespace repertory { class encrypt_provider final : public i_provider { +public: + static const constexpr auto type{provider_type::encrypt}; + public: explicit encrypt_provider(app_config &config); @@ -81,74 +84,68 @@ public: [[nodiscard]] auto create_directory(const std::string &api_path, api_meta_map &meta) -> api_error override; - [[nodiscard]] auto - create_directory_clone_source_meta(const std::string & /*source_api_path*/, - const std::string & /*api_path*/) - -> api_error override { - return api_error::not_implemented; - } - - [[nodiscard]] auto create_file(const std::string & /*api_path*/, - api_meta_map & /*meta*/) - -> api_error override { + [[nodiscard]] auto create_directory_clone_source_meta( + const std::string & /*source_api_path*/, + const std::string & /*api_path*/) -> api_error override { return api_error::not_implemented; } [[nodiscard]] auto - get_api_path_from_source(const std::string & /*source_path*/, - std::string & /*api_path*/) const - -> api_error override; + create_file(const std::string & /*api_path*/, + api_meta_map & /*meta*/) -> api_error override { + return api_error::not_implemented; + } + + [[nodiscard]] auto get_api_path_from_source( + const std::string & /*source_path*/, + std::string & /*api_path*/) const -> api_error override; [[nodiscard]] auto get_directory_item_count(const std::string &api_path) const -> std::uint64_t override; - [[nodiscard]] auto get_directory_items(const std::string &api_path, - directory_item_list &list) const - -> api_error override; + [[nodiscard]] auto + get_directory_items(const std::string &api_path, + directory_item_list &list) const -> api_error override; - [[nodiscard]] auto get_file(const std::string &api_path, api_file &file) const - -> api_error override; - - [[nodiscard]] auto get_file_list(api_file_list &list) const - -> api_error override; - - [[nodiscard]] auto get_file_size(const std::string &api_path, - std::uint64_t &file_size) const - -> api_error override; - - [[nodiscard]] auto get_filesystem_item(const std::string &api_path, - bool directory, - filesystem_item &fsi) const - -> api_error override; - - [[nodiscard]] auto get_filesystem_item_and_file(const std::string &api_path, - api_file &file, - filesystem_item &fsi) const - -> api_error override; + [[nodiscard]] auto get_file(const std::string &api_path, + api_file &file) const -> api_error override; [[nodiscard]] auto - get_filesystem_item_from_source_path(const std::string &source_path, - filesystem_item &fsi) const - -> api_error override; + get_file_list(api_file_list &list) const -> api_error override; - [[nodiscard]] auto get_pinned_files() const - -> std::vector override; + [[nodiscard]] auto + get_file_size(const std::string &api_path, + std::uint64_t &file_size) const -> api_error override; - [[nodiscard]] auto get_item_meta(const std::string &api_path, - api_meta_map &meta) const - -> api_error override; + [[nodiscard]] auto + get_filesystem_item(const std::string &api_path, bool directory, + filesystem_item &fsi) const -> api_error override; - [[nodiscard]] auto get_item_meta(const std::string &api_path, - const std::string &key, - std::string &value) const - -> api_error override; + [[nodiscard]] auto get_filesystem_item_and_file( + const std::string &api_path, api_file &file, + filesystem_item &fsi) const -> api_error override; + + [[nodiscard]] auto get_filesystem_item_from_source_path( + const std::string &source_path, + filesystem_item &fsi) const -> api_error override; + + [[nodiscard]] auto + get_pinned_files() const -> std::vector override; + + [[nodiscard]] auto + get_item_meta(const std::string &api_path, + api_meta_map &meta) const -> api_error override; + + [[nodiscard]] auto + get_item_meta(const std::string &api_path, const std::string &key, + std::string &value) const -> api_error override; [[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override; [[nodiscard]] auto get_total_item_count() const -> std::uint64_t override; [[nodiscard]] auto get_provider_type() const -> provider_type override { - return provider_type::encrypt; + return type; } [[nodiscard]] auto get_used_drive_space() const -> std::uint64_t override; @@ -158,54 +155,52 @@ public: [[nodiscard]] auto is_directory(const std::string &api_path, bool &exists) const -> api_error override; - [[nodiscard]] auto is_file(const std::string &api_path, bool &exists) const - -> api_error override; + [[nodiscard]] auto is_file(const std::string &api_path, + bool &exists) const -> api_error override; - [[nodiscard]] auto is_file_writeable(const std::string &api_path) const - -> bool override; + [[nodiscard]] auto + is_file_writeable(const std::string &api_path) const -> bool override; [[nodiscard]] auto is_online() const -> bool override; [[nodiscard]] auto is_rename_supported() const -> bool override; - [[nodiscard]] auto read_file_bytes(const std::string &api_path, - std::size_t size, std::uint64_t offset, - data_buffer &data, - stop_type &stop_requested) - -> api_error override; + [[nodiscard]] auto + read_file_bytes(const std::string &api_path, std::size_t size, + std::uint64_t offset, data_buffer &data, + stop_type &stop_requested) -> api_error override; - [[nodiscard]] auto remove_directory(const std::string & /*api_path*/) - -> api_error override { + [[nodiscard]] auto + remove_directory(const std::string & /*api_path*/) -> api_error override { return api_error::not_implemented; } - [[nodiscard]] auto remove_file(const std::string & /*api_path*/) - -> api_error override { + [[nodiscard]] auto + remove_file(const std::string & /*api_path*/) -> api_error override { return api_error::not_implemented; } - [[nodiscard]] auto remove_item_meta(const std::string & /*api_path*/, - const std::string & /*key*/) - -> api_error override { + [[nodiscard]] auto + remove_item_meta(const std::string & /*api_path*/, + const std::string & /*key*/) -> api_error override { return api_error::success; } - [[nodiscard]] auto rename_file(const std::string & /*from_api_path*/, - const std::string & /*to_api_path*/) - -> api_error override { + [[nodiscard]] auto + rename_file(const std::string & /*from_api_path*/, + const std::string & /*to_api_path*/) -> api_error override { return api_error::not_implemented; } - [[nodiscard]] auto set_item_meta(const std::string & /*api_path*/, - const std::string & /*key*/, - const std::string & /*value*/) - -> api_error override { + [[nodiscard]] auto + set_item_meta(const std::string & /*api_path*/, const std::string & /*key*/, + const std::string & /*value*/) -> api_error override { return api_error::success; } - [[nodiscard]] auto set_item_meta(const std::string & /*api_path*/, - const api_meta_map & /*meta*/) - -> api_error override { + [[nodiscard]] auto + set_item_meta(const std::string & /*api_path*/, + const api_meta_map & /*meta*/) -> api_error override { return api_error::success; } @@ -214,10 +209,10 @@ public: void stop() override; - [[nodiscard]] auto upload_file(const std::string & /*api_path*/, - const std::string & /*source_path*/, - stop_type & /*stop_requested*/) - -> api_error override { + [[nodiscard]] auto + upload_file(const std::string & /*api_path*/, + const std::string & /*source_path*/, + stop_type & /*stop_requested*/) -> api_error override { return api_error::not_implemented; } }; diff --git a/repertory/librepertory/include/providers/s3/s3_provider.hpp b/repertory/librepertory/include/providers/s3/s3_provider.hpp index 0d8643fd..2a770fbb 100644 --- a/repertory/librepertory/include/providers/s3/s3_provider.hpp +++ b/repertory/librepertory/include/providers/s3/s3_provider.hpp @@ -32,6 +32,9 @@ class i_http_comm; struct head_object_result; class s3_provider final : public base_provider { +public: + static const constexpr auto type{provider_type::s3}; + public: s3_provider(app_config &config, i_http_comm &comm); @@ -104,7 +107,7 @@ public: [[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override; [[nodiscard]] auto get_provider_type() const -> provider_type override { - return provider_type::s3; + return type; } [[nodiscard]] auto is_direct_only() const -> bool override { return false; } diff --git a/repertory/librepertory/include/providers/sia/sia_provider.hpp b/repertory/librepertory/include/providers/sia/sia_provider.hpp index 3d7a30c0..9213e747 100644 --- a/repertory/librepertory/include/providers/sia/sia_provider.hpp +++ b/repertory/librepertory/include/providers/sia/sia_provider.hpp @@ -31,6 +31,9 @@ class i_file_manager; class i_http_comm; class sia_provider : public base_provider { +public: + static const constexpr auto type{provider_type::sia}; + public: sia_provider(app_config &config, i_http_comm &comm); @@ -50,40 +53,39 @@ private: nlohmann::json &object_list) const -> bool; protected: - [[nodiscard]] auto create_directory_impl(const std::string &api_path, - api_meta_map &meta) - -> api_error override; + [[nodiscard]] auto + create_directory_impl(const std::string &api_path, + api_meta_map &meta) -> api_error override; [[nodiscard]] auto get_directory_items_impl(const std::string &api_path, directory_item_list &list) const -> api_error override; - [[nodiscard]] auto get_used_drive_space_impl() const - -> std::uint64_t override; + [[nodiscard]] auto + get_used_drive_space_impl() const -> std::uint64_t override; - [[nodiscard]] auto remove_directory_impl(const std::string &api_path) - -> api_error override; + [[nodiscard]] auto + remove_directory_impl(const std::string &api_path) -> api_error override; - [[nodiscard]] auto remove_file_impl(const std::string &api_path) - -> api_error override; + [[nodiscard]] auto + remove_file_impl(const std::string &api_path) -> api_error override; - [[nodiscard]] auto upload_file_impl(const std::string &api_path, - const std::string &source_path, - stop_type &stop_requested) - -> api_error override; + [[nodiscard]] auto + upload_file_impl(const std::string &api_path, const std::string &source_path, + stop_type &stop_requested) -> api_error override; public: [[nodiscard]] auto get_directory_item_count(const std::string &api_path) const -> std::uint64_t override; - [[nodiscard]] auto get_file(const std::string &api_path, api_file &file) const - -> api_error override; + [[nodiscard]] auto get_file(const std::string &api_path, + api_file &file) const -> api_error override; - [[nodiscard]] auto get_file_list(api_file_list &list) const - -> api_error override; + [[nodiscard]] auto + get_file_list(api_file_list &list) const -> api_error override; [[nodiscard]] auto get_provider_type() const -> provider_type override { - return provider_type::sia; + return type; } [[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override; @@ -93,8 +95,8 @@ public: [[nodiscard]] auto is_directory(const std::string &api_path, bool &exists) const -> api_error override; - [[nodiscard]] auto is_file(const std::string &api_path, bool &exists) const - -> api_error override; + [[nodiscard]] auto is_file(const std::string &api_path, + bool &exists) const -> api_error override; [[nodiscard]] auto is_online() const -> bool override; @@ -102,15 +104,14 @@ public: return true; } - [[nodiscard]] auto read_file_bytes(const std::string &api_path, - std::size_t size, std::uint64_t offset, - data_buffer &buffer, - stop_type &stop_requested) - -> api_error override; + [[nodiscard]] auto + read_file_bytes(const std::string &api_path, std::size_t size, + std::uint64_t offset, data_buffer &buffer, + stop_type &stop_requested) -> api_error override; - [[nodiscard]] auto rename_file(const std::string &from_api_path, - const std::string &to_api_path) - -> api_error override; + [[nodiscard]] auto + rename_file(const std::string &from_api_path, + const std::string &to_api_path) -> api_error override; [[nodiscard]] auto start(api_item_added_callback api_item_added, i_file_manager *mgr) -> bool override; diff --git a/repertory/repertory_test/include/fixtures/fuse_fixture.hpp b/repertory/repertory_test/include/fixtures/fuse_fixture.hpp new file mode 100644 index 00000000..706b88d9 --- /dev/null +++ b/repertory/repertory_test/include/fixtures/fuse_fixture.hpp @@ -0,0 +1,235 @@ +/* + Copyright <2018-2024> + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +#ifndef REPERTORY_TEST_INCLUDE_FIXTURES_FUSE_FIXTURE_HPP +#define REPERTORY_TEST_INCLUDE_FIXTURES_FUSE_FIXTURE_HPP +#if !defined(_WIN32) + +#include "test_common.hpp" + +#include "app_config.hpp" +#include "comm/curl/curl_comm.hpp" +#include "drives/fuse/fuse_drive.hpp" +#include "platform/platform.hpp" +#include "providers/encrypt/encrypt_provider.hpp" +#include "providers/s3/s3_provider.hpp" +#include "providers/sia/sia_provider.hpp" +#include "utils/file_utils.hpp" +#include "utils/path.hpp" + +#if !defined(ACCESSPERMS) +#define ACCESSPERMS (S_IRWXU | S_IRWXG | S_IRWXO) /* 0777 */ +#endif + +namespace repertory { +inline constexpr const auto SLEEP_SECONDS{1.5s}; + +template class fuse_test : public ::testing::Test { +public: + static std::string cfg_directory; + static std::unique_ptr comm; + static std::unique_ptr config; + static std::filesystem::path current_directory; + static std::unique_ptr drive; + static lock_data lock_data_; + static std::string mount_location; + static std::unique_ptr provider; + static std::string test_directory; + +protected: + static void SetUpTestCase() { + current_directory = std::filesystem::current_path(); + + test_directory = utils::path::combine( + test::get_test_output_dir(), + { + "fuse_test", + std::to_string(static_cast(provider_t::type)), + }); + + ASSERT_TRUE(utils::file::remove_directory(test_directory, true)); + + mount_location = utils::path::combine(test_directory, {"mount"}); + ASSERT_TRUE(utils::file::create_directories(mount_location)); + + cfg_directory = utils::path::combine(test_directory, {"cfg"}); + ASSERT_TRUE(utils::file::create_directories(cfg_directory)); + + config = std::make_unique(provider_t::type, cfg_directory); + + std::vector drive_args{}; + switch (provider_t::type) { + case provider_type::s3: { + { + app_config src_cfg{ + provider_type::s3, + utils::path::combine(test::get_test_input_dir(), {"storj"}), + }; + config->set_enable_drive_events(true); + config->set_event_level(event_level::trace); + config->set_s3_config(src_cfg.get_s3_config()); + } + + comm = std::make_unique(config->get_s3_config()); + drive_args = std::vector({ + "-s3", + "-na", + "storj", + }); + } break; + + case provider_type::sia: { + { + app_config src_cfg{ + provider_type::sia, + utils::path::combine(test::get_test_input_dir(), {"sia"}), + }; + config->set_enable_drive_events(true); + config->set_event_level(event_level::debug); + config->set_host_config(src_cfg.get_host_config()); + } + + comm = std::make_unique(config->get_host_config()); + } break; + // case 0U: { + // config = + // std::make_unique(provider_type::encrypt, + // cfg_directory); + // { + // app_config src_cfg( + // provider_type::s3, + // utils::path::combine(test::get_test_input_dir(), {"encrypt"})); + // config->set_enable_drive_events(true); + // config->set_event_level(event_level::trace); + // config->set_s3_config(src_cfg.get_s3_config()); + // } + // + // comm = std::make_unique(config->get_s3_config()); + // provider = std::make_unique(*config, *comm); + // drive_args = std::vector({"-en"}); + // } break; + + default: + throw std::runtime_error("provider type is not implemented"); + return; + } + + provider = std::make_unique(*config, *comm); + drive_args.push_back(mount_location); + execute_mount(drive_args); + } + + static void TearDownTestCase() { + execute_unmount(); + std::filesystem::current_path(current_directory); + + [[maybe_unused]] auto ret = + utils::file::remove_directory(test_directory, true); + } + +public: + static auto create_file_and_test(std::string name) -> std::string { + auto file_path = utils::path::combine(mount_location, {name}); + + auto fd = + open(file_path.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP); + EXPECT_LE(1, fd); + + EXPECT_TRUE(utils::file::is_file(file_path)); + EXPECT_FALSE(utils::file::is_directory(file_path)); + + std::uint64_t file_size{}; + EXPECT_TRUE(utils::file::get_file_size(file_path, file_size)); + EXPECT_EQ(0U, file_size); + + EXPECT_EQ(0, close(fd)); + std::this_thread::sleep_for(SLEEP_SECONDS); + + return file_path; + } + + static void execute_mount(auto &&drive_args) { + auto mount_cmd = "./repertory -dd \"" + config->get_data_directory() + + "\"" + " " + utils::string::join(drive_args, ' '); + std::cout << "mount command: " << mount_cmd << std::endl; + ASSERT_EQ(0, system(mount_cmd.c_str())); + std::this_thread::sleep_for(5s); + EXPECT_EQ(0, system(("mount|grep \"" + mount_location + "\"").c_str())); + } + + static void execute_unmount() { + auto unmounted{false}; + for (int i = 0; not unmounted && (i < 50); i++) { + unmounted = (fuse_base::unmount(mount_location) == 0); + if (not unmounted) { + std::this_thread::sleep_for(100ms); + } + } + + EXPECT_TRUE(unmounted); + } + + static void unlink_file_and_test(const std::string &file_path) { + int ret = 0; + for (auto i = 0; ((ret = unlink(file_path.c_str())) != 0) && (i < 20); + i++) { + std::this_thread::sleep_for(100ms); + } + + EXPECT_EQ(0, ret); + + std::this_thread::sleep_for(SLEEP_SECONDS); + EXPECT_FALSE(utils::file::is_directory(file_path)); + EXPECT_FALSE(utils::file::is_file(file_path)); + } +}; + +template +std::string fuse_test::cfg_directory{}; + +template +std::unique_ptr fuse_test::comm{}; + +template +std::unique_ptr fuse_test::config{}; + +template +std::filesystem::path fuse_test::current_directory{}; + +template +std::unique_ptr fuse_test::drive{}; + +template lock_data fuse_test::lock_data_{}; + +template +std::string fuse_test::mount_location{}; + +template +std::unique_ptr fuse_test::provider{}; + +template +std::string fuse_test::test_directory; + +typedef ::testing::Types fuse_provider_types; +} // namespace repertory + +#endif // !defined(_WIN32) +#endif // REPERTORY_TEST_INCLUDE_FIXTURES_FUSE_FIXTURE_HPP diff --git a/repertory/repertory_test/src/fuse_drive_test.cpp b/repertory/repertory_test/src/fuse_drive_test.cpp index b389e067..1767b0d6 100644 --- a/repertory/repertory_test/src/fuse_drive_test.cpp +++ b/repertory/repertory_test/src/fuse_drive_test.cpp @@ -21,115 +21,515 @@ */ #if !defined(_WIN32) -#include "test_common.hpp" +#include "fixtures/fuse_fixture.hpp" -#include "app_config.hpp" -#include "comm/curl/curl_comm.hpp" -#include "drives/fuse/fuse_drive.hpp" -#include "platform/platform.hpp" -#include "providers/s3/s3_provider.hpp" -#include "providers/sia/sia_provider.hpp" -#include "types/repertory.hpp" -#include "utils/event_capture.hpp" -#include "utils/file_utils.hpp" -#include "utils/utils.hpp" - -#if !defined(ACCESSPERMS) -#define ACCESSPERMS (S_IRWXU | S_IRWXG | S_IRWXO) /* 0777 */ -#endif - -static constexpr const auto SLEEP_SECONDS = 1.5s; +// #include "app_config.hpp" +// #include "comm/curl/curl_comm.hpp" +// #include "drives/fuse/fuse_drive.hpp" +// #include "platform/platform.hpp" +// #include "providers/s3/s3_provider.hpp" +// #include "providers/sia/sia_provider.hpp" +// #include "types/repertory.hpp" +// #include "utils/event_capture.hpp" +// #include "utils/file_utils.hpp" +// #include "utils/utils.hpp" namespace repertory { -static void execute_mount(const std::string &data_directory, - const std::vector &drive_args, - std::thread &mount_thread) { - auto cmd = "./repertory -dd \"" + data_directory + "\"" + " " + - utils::string::join(drive_args, ' '); - std::cout << cmd << std::endl; - EXPECT_EQ(0, system(cmd.c_str())); - mount_thread.join(); -} +// static void rmdir_and_test(const std::string &directory_path) { +// std::cout << __FUNCTION__ << std::endl; +// int ret = 0; +// for (auto i = 0; ((ret = rmdir(directory_path.c_str())) != 0) && (i < 20); +// i++) { +// std::this_thread::sleep_for(100ms); +// } +// +// EXPECT_EQ(0, ret); +// std::this_thread::sleep_for(SLEEP_SECONDS); +// +// EXPECT_FALSE(utils::file::is_directory(directory_path)); +// EXPECT_FALSE(utils::file::is_file(directory_path)); +// } +// +// static void test_mkdir(const std::string & /* api_path */, +// const std::string &directory_path) { +// std::cout << __FUNCTION__ << std::endl; +// EXPECT_EQ(0, mkdir(directory_path.c_str(), +// S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP)); +// +// EXPECT_TRUE(utils::file::is_directory(directory_path)); +// EXPECT_FALSE(utils::file::is_file(directory_path)); +// +// struct stat64 unix_st {}; +// stat64(directory_path.c_str(), &unix_st); +// +// EXPECT_EQ(getuid(), unix_st.st_uid); +// EXPECT_EQ(getgid(), unix_st.st_gid); +// +// EXPECT_EQ(static_cast(S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP +// | +// S_IXGRP), +// ACCESSPERMS & unix_st.st_mode); +// } +// +// static void test_write_and_read(const std::string & /* api_path */, +// const std::string &file_path) { +// std::cout << __FUNCTION__ << std::endl; +// auto fd = +// open(file_path.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP); +// EXPECT_LE(1, fd); +// +// std::string data = "TestData"; +// EXPECT_EQ(data.size(), +// static_cast(write(fd, data.data(), data.size()))); +// EXPECT_EQ(0, lseek(fd, 0, SEEK_SET)); +// fsync(fd); +// +// data_buffer read_data; +// read_data.resize(data.size()); +// EXPECT_EQ(data.size(), static_cast( +// read(fd, read_data.data(), read_data.size()))); +// +// EXPECT_EQ(0, memcmp(data.data(), read_data.data(), data.size())); +// +// EXPECT_EQ(0, close(fd)); +// +// std::this_thread::sleep_for(SLEEP_SECONDS); +// +// std::uint64_t file_size{}; +// EXPECT_TRUE(utils::file::get_file_size(file_path, file_size)); +// EXPECT_EQ(data.size(), file_size); +// +// // filesystem_item fsi{}; +// // EXPECT_EQ(api_error::success, +// // provider.get_filesystem_item(api_path, false, fsi)); +// // EXPECT_TRUE(utils::file::get_file_size(fsi.source_path, file_size)); +// // EXPECT_EQ(data.size(), file_size); +// } +// +// static void test_rename_file(const std::string &from_file_path, +// const std::string &to_file_path, +// bool is_rename_supported) { +// std::cout << __FUNCTION__ << std::endl; +// auto fd = open(from_file_path.c_str(), O_RDWR, S_IRUSR | S_IWUSR | +// S_IRGRP); EXPECT_LE(1, fd); close(fd); +// +// std::this_thread::sleep_for(SLEEP_SECONDS); +// +// if (is_rename_supported) { +// EXPECT_EQ(0, rename(from_file_path.c_str(), to_file_path.c_str())); +// EXPECT_FALSE(utils::file::is_file(from_file_path)); +// EXPECT_TRUE(utils::file::is_file(to_file_path)); +// } else { +// EXPECT_EQ(-1, rename(from_file_path.c_str(), to_file_path.c_str())); +// EXPECT_TRUE(utils::file::is_file(from_file_path)); +// EXPECT_FALSE(utils::file::is_file(to_file_path)); +// } +// } +// +// static void test_rename_directory(const std::string &from_dir_path, +// const std::string &to_dir_path, +// bool is_rename_supported) { +// std::cout << __FUNCTION__ << std::endl; +// EXPECT_EQ(0, mkdir(from_dir_path.c_str(), +// S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP)); +// std::this_thread::sleep_for(SLEEP_SECONDS); +// +// EXPECT_TRUE(utils::file::is_directory(from_dir_path)); +// if (is_rename_supported) { +// EXPECT_EQ(0, rename(from_dir_path.c_str(), to_dir_path.c_str())); +// EXPECT_FALSE(utils::file::is_directory(from_dir_path)); +// EXPECT_TRUE(utils::file::is_directory(to_dir_path)); +// } else { +// EXPECT_EQ(-1, rename(from_dir_path.c_str(), to_dir_path.c_str())); +// EXPECT_TRUE(utils::file::is_directory(from_dir_path)); +// EXPECT_FALSE(utils::file::is_directory(to_dir_path)); +// } +// } +// +// static void test_truncate(const std::string &file_path) { +// std::cout << __FUNCTION__ << std::endl; +// EXPECT_EQ(0, truncate(file_path.c_str(), 10u)); +// +// std::uint64_t file_size{}; +// EXPECT_TRUE(utils::file::get_file_size(file_path, file_size)); +// +// EXPECT_EQ(std::uint64_t(10u), file_size); +// } +// +// static void test_ftruncate(const std::string &file_path) { +// std::cout << __FUNCTION__ << std::endl; +// auto fd = open(file_path.c_str(), O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP); +// EXPECT_LE(1, fd); +// +// EXPECT_EQ(0, ftruncate(fd, 10u)); +// +// std::uint64_t file_size{}; +// EXPECT_TRUE(utils::file::get_file_size(file_path, file_size)); +// +// EXPECT_EQ(std::uint64_t(10u), file_size); +// +// close(fd); +// } +// +// #if !defined(__APPLE__) +// static void test_fallocate(const std::string & /* api_path */, +// const std::string &file_path) { +// std::cout << __FUNCTION__ << std::endl; +// auto file = +// open(file_path.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP); +// EXPECT_LE(1, file); +// EXPECT_EQ(0, fallocate(file, 0, 0, 16)); +// +// std::uint64_t file_size{}; +// EXPECT_TRUE(utils::file::get_file_size(file_path, file_size)); +// EXPECT_EQ(16U, file_size); +// +// EXPECT_EQ(0, close(file)); +// +// file_size = 0U; +// EXPECT_TRUE(utils::file::get_file_size(file_path, file_size)); +// EXPECT_EQ(16U, file_size); +// } +// #endif +// +// static void test_file_getattr(const std::string & /* api_path */, +// const std::string &file_path) { +// std::cout << __FUNCTION__ << std::endl; +// auto fd = +// open(file_path.c_str(), O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR | +// S_IRGRP); +// EXPECT_LE(1, fd); +// +// EXPECT_EQ(0, close(fd)); +// +// struct stat64 unix_st {}; +// EXPECT_EQ(0, stat64(file_path.c_str(), &unix_st)); +// EXPECT_EQ(static_cast(S_IRUSR | S_IWUSR | S_IRGRP), +// ACCESSPERMS & unix_st.st_mode); +// EXPECT_FALSE(S_ISDIR(unix_st.st_mode)); +// EXPECT_TRUE(S_ISREG(unix_st.st_mode)); +// } +// +// static void test_directory_getattr(const std::string & /* api_path */, +// const std::string &directory_path) { +// std::cout << __FUNCTION__ << std::endl; +// EXPECT_EQ(0, mkdir(directory_path.c_str(), +// S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP)); +// +// struct stat64 unix_st {}; +// EXPECT_EQ(0, stat64(directory_path.c_str(), &unix_st)); +// EXPECT_EQ(static_cast(S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP +// | +// S_IXGRP), +// ACCESSPERMS & unix_st.st_mode); +// EXPECT_TRUE(S_ISDIR(unix_st.st_mode)); +// EXPECT_FALSE(S_ISREG(unix_st.st_mode)); +// } +// +// static void +// test_write_operations_fail_if_read_only(const std::string & /* api_path */, +// const std::string &file_path) { +// std::cout << __FUNCTION__ << std::endl; +// auto fd = +// open(file_path.c_str(), O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR | +// S_IRGRP); +// EXPECT_LE(1, fd); +// +// std::string data = "TestData"; +// EXPECT_EQ(-1, write(fd, data.data(), data.size())); +// +// EXPECT_EQ(-1, ftruncate(fd, 9u)); +// +// #if !defined(__APPLE__) +// EXPECT_EQ(-1, fallocate(fd, 0, 0, 16)); +// #endif +// +// EXPECT_EQ(0, close(fd)); +// +// std::this_thread::sleep_for(SLEEP_SECONDS); +// +// std::uint64_t file_size{}; +// EXPECT_TRUE(utils::file::get_file_size(file_path, file_size)); +// EXPECT_EQ(std::size_t(0u), file_size); +// +// // filesystem_item fsi{}; +// // EXPECT_EQ(api_error::success, +// // provider.get_filesystem_item(api_path, false, fsi)); +// // EXPECT_TRUE(utils::file::get_file_size(fsi.source_path, file_size)); +// // EXPECT_EQ(std::size_t(0u), file_size); +// } +// +// #if !__APPLE__ && HAS_SETXATTR +// static void test_xattr_invalid_parameters(const std::string &file_path) { +// std::cout << __FUNCTION__ << std::endl; +// std::string attr = "moose"; +// EXPECT_EQ(-1, setxattr(nullptr, "user.test_attr", attr.data(), attr.size(), +// XATTR_CREATE)); +// EXPECT_EQ(errno, EFAULT); +// EXPECT_EQ(-1, setxattr(file_path.c_str(), nullptr, attr.data(), +// attr.size(), +// XATTR_CREATE)); +// EXPECT_EQ(errno, EFAULT); +// EXPECT_EQ(-1, setxattr(file_path.c_str(), "user.test_attr", nullptr, +// attr.size(), XATTR_CREATE)); +// EXPECT_EQ(errno, EFAULT); +// EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", nullptr, 0, +// XATTR_CREATE)); +// } +// +// static void test_xattr_create_and_get(const std::string &file_path) { +// std::cout << __FUNCTION__ << std::endl; +// std::string attr = "moose"; +// EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", attr.data(), +// attr.size(), XATTR_CREATE)); +// +// std::string val; +// val.resize(attr.size()); +// EXPECT_EQ(attr.size(), +// static_cast(getxattr( +// file_path.c_str(), "user.test_attr", val.data(), +// val.size()))); +// EXPECT_STREQ(attr.c_str(), val.c_str()); +// } +// +// static void test_xattr_listxattr(const std::string &file_path) { +// std::cout << __FUNCTION__ << std::endl; +// std::string attr = "moose"; +// EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", attr.data(), +// attr.size(), XATTR_CREATE)); +// EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr2", attr.data(), +// attr.size(), XATTR_CREATE)); +// +// std::string val; +// val.resize(attr.size()); +// EXPECT_EQ(attr.size(), +// static_cast(getxattr( +// file_path.c_str(), "user.test_attr", val.data(), +// val.size()))); +// EXPECT_STREQ(attr.c_str(), val.c_str()); +// +// std::string data; +// auto size = listxattr(file_path.c_str(), data.data(), 0U); +// EXPECT_EQ(31, size); +// +// data.resize(static_cast(size)); +// EXPECT_EQ(size, listxattr(file_path.c_str(), data.data(), +// static_cast(size))); +// +// auto *ptr = data.data(); +// EXPECT_STREQ("user.test_attr", ptr); +// +// ptr += strlen(ptr) + 1; +// EXPECT_STREQ("user.test_attr2", ptr); +// } +// +// static void test_xattr_replace(const std::string &file_path) { +// std::cout << __FUNCTION__ << std::endl; +// std::string attr = "moose"; +// EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", attr.data(), +// attr.size(), XATTR_CREATE)); +// +// attr = "cow"; +// EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", attr.data(), +// attr.size(), XATTR_REPLACE)); +// +// std::string val; +// val.resize(attr.size()); +// EXPECT_EQ(attr.size(), +// static_cast(getxattr( +// file_path.c_str(), "user.test_attr", val.data(), +// val.size()))); +// EXPECT_STREQ(attr.c_str(), val.c_str()); +// } +// +// static void test_xattr_default_create(const std::string &file_path) { +// std::cout << __FUNCTION__ << std::endl; +// std::string attr = "moose"; +// EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", attr.data(), +// attr.size(), 0)); +// +// std::string val; +// val.resize(attr.size()); +// EXPECT_EQ(attr.size(), +// static_cast(getxattr( +// file_path.c_str(), "user.test_attr", val.data(), +// val.size()))); +// EXPECT_STREQ(attr.c_str(), val.c_str()); +// } +// +// static void test_xattr_default_replace(const std::string &file_path) { +// std::cout << __FUNCTION__ << std::endl; +// std::string attr = "moose"; +// EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", attr.data(), +// attr.size(), 0)); +// +// attr = "cow"; +// EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", attr.data(), +// attr.size(), 0)); +// +// std::string val; +// val.resize(attr.size()); +// EXPECT_EQ(attr.size(), +// static_cast(getxattr( +// file_path.c_str(), "user.test_attr", val.data(), +// val.size()))); +// EXPECT_STREQ(attr.c_str(), val.c_str()); +// } +// +// static void test_xattr_create_fails_if_exists(const std::string &file_path) { +// std::cout << __FUNCTION__ << std::endl; +// std::string attr = "moose"; +// EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", attr.data(), +// attr.size(), 0)); +// EXPECT_EQ(-1, setxattr(file_path.c_str(), "user.test_attr", attr.data(), +// attr.size(), XATTR_CREATE)); +// EXPECT_EQ(EEXIST, errno); +// } +// +// static void +// test_xattr_create_fails_if_not_exists(const std::string &file_path) { +// std::cout << __FUNCTION__ << std::endl; +// std::string attr = "moose"; +// EXPECT_EQ(-1, setxattr(file_path.c_str(), "user.test_attr", attr.data(), +// attr.size(), XATTR_REPLACE)); +// EXPECT_EQ(ENODATA, errno); +// } +// +// static void test_xattr_removexattr(const std::string &file_path) { +// std::cout << __FUNCTION__ << std::endl; +// std::string attr = "moose"; +// EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", attr.data(), +// attr.size(), XATTR_CREATE)); +// +// EXPECT_EQ(0, removexattr(file_path.c_str(), "user.test_attr")); +// +// std::string val; +// val.resize(attr.size()); +// EXPECT_EQ(-1, getxattr(file_path.c_str(), "user.test_attr", val.data(), +// val.size())); +// EXPECT_EQ(ENODATA, errno); +// } +// #endif +// +// // file_path = create_file_and_test(mount_location, "chown_test"); +// // test_chown(utils::path::create_api_path("chown_test"), file_path); +// // unlink_file_and_test(file_path); +// // +// // file_path = utils::path::combine(mount_location, {"mkdir_test"}); +// // test_mkdir(utils::path::create_api_path("mkdir_test"), file_path); +// // rmdir_and_test(file_path); +// // +// // file_path = create_file_and_test(mount_location, +// // "write_read_test"); +// // test_write_and_read(utils::path::create_api_path("write_read_test"), +// // file_path); +// // unlink_file_and_test(file_path); +// // +// // file_path = +// // create_file_and_test(mount_location, "from_rename_file_test"); +// // auto to_file_path = +// // utils::path::combine(mount_location, {"to_rename_file_test"}); +// // test_rename_file(file_path, to_file_path, +// // provider_ptr->is_rename_supported()); +// // EXPECT_TRUE(utils::file::retry_delete_file(file_path)); +// // EXPECT_TRUE(utils::file::retry_delete_file(to_file_path)); +// // +// // file_path = +// // utils::path::combine(mount_location, +// {"from_rename_dir_test"}); +// // to_file_path = +// // utils::path::combine(mount_location, {"to_rename_dir_test"}); +// // test_rename_directory(file_path, to_file_path, +// // provider_ptr->is_rename_supported()); +// // EXPECT_TRUE(utils::file::retry_delete_directory(file_path.c_str())); +// // EXPECT_TRUE(utils::file::retry_delete_directory(to_file_path.c_str())); +// // +// // file_path = create_file_and_test(mount_location, +// // "truncate_file_test"); test_truncate(file_path); +// // unlink_file_and_test(file_path); +// // +// // file_path = create_file_and_test(mount_location, +// // "ftruncate_file_test"); test_ftruncate(file_path); +// // unlink_file_and_test(file_path); +// // +// // #if !defined(__APPLE__) +// // file_path = create_file_and_test(mount_location, +// // "fallocate_file_test"); +// // test_fallocate(utils::path::create_api_path("fallocate_file_test"), +// // file_path); +// // unlink_file_and_test(file_path); +// // #endif +// // +// // file_path = create_file_and_test(mount_location, +// // "write_fails_ro_test"); test_write_operations_fail_if_read_only( +// // utils::path::create_api_path("write_fails_ro_test"), +// // file_path); +// // unlink_file_and_test(file_path); +// // +// // file_path = create_file_and_test(mount_location, "getattr.txt"); +// // test_file_getattr(utils::path::create_api_path("getattr.txt"), +// // file_path); +// // unlink_file_and_test(file_path); +// // +// // file_path = utils::path::combine(mount_location, {"getattr_dir"}); +// // test_directory_getattr(utils::path::create_api_path("getattr_dir"), +// // file_path); +// // rmdir_and_test(file_path); +// // +// // #if !__APPLE__ && HAS_SETXATTR +// // file_path = +// // create_file_and_test(mount_location, +// // "xattr_invalid_names_test"); +// // test_xattr_invalid_parameters(file_path); +// // unlink_file_and_test(file_path); +// // +// // file_path = +// // create_file_and_test(mount_location, "xattr_create_get_test"); +// // test_xattr_create_and_get(file_path); +// // unlink_file_and_test(file_path); +// // +// // file_path = +// // create_file_and_test(mount_location, "xattr_listxattr_test"); +// // test_xattr_listxattr(file_path); +// // unlink_file_and_test(file_path); +// // +// // file_path = create_file_and_test(mount_location, +// // "xattr_replace_test"); test_xattr_replace(file_path); +// // unlink_file_and_test(file_path); +// // +// // file_path = +// // create_file_and_test(mount_location, +// // "xattr_default_create_test"); +// // test_xattr_default_create(file_path); +// // unlink_file_and_test(file_path); +// // +// // file_path = +// // create_file_and_test(mount_location, +// // "xattr_default_replace_test"); +// // test_xattr_default_replace(file_path); +// // unlink_file_and_test(file_path); +// // +// // file_path = create_file_and_test(mount_location, +// // "xattr_create_fails_exists_test"); +// // test_xattr_create_fails_if_exists(file_path); +// // unlink_file_and_test(file_path); +// // +// // file_path = create_file_and_test(mount_location, +// // "xattr_create_fails_not_exists_test"); +// // test_xattr_create_fails_if_not_exists(file_path); +// // unlink_file_and_test(file_path); +// // +// // file_path = +// // create_file_and_test(mount_location, +// "xattr_removexattr_test"); +// // test_xattr_removexattr(file_path); +// // unlink_file_and_test(file_path); +// // #endif -static void execute_unmount(const std::string &mount_location) { - // filesystem_item fsi{}; - // EXPECT_EQ(api_error::success, provider.get_filesystem_item("/", true, - // fsi)); EXPECT_STREQ("/", fsi.api_path.c_str()); - // EXPECT_TRUE(fsi.api_parent.empty()); - // EXPECT_TRUE(fsi.directory); - // EXPECT_EQ(std::uint64_t(0u), fsi.size); - // EXPECT_TRUE(fsi.source_path.empty()); - // - // api_meta_map meta{}; - // EXPECT_EQ(api_error::success, provider.get_item_meta("/", meta)); - // for (const auto &kv : meta) { - // std::cout << kv.first << '=' << kv.second << std::endl; - // } +TYPED_TEST_CASE(fuse_test, fuse_provider_types); - auto unmounted = false; - for (int i = 0; not unmounted && (i < 50); i++) { - unmounted = (fuse_base::unmount(mount_location) == 0); - if (not unmounted) { - std::this_thread::sleep_for(100ms); - } - } - - EXPECT_TRUE(unmounted); -} - -static auto create_file_and_test(const std::string &mount_location, - std::string name) -> std::string { - std::cout << __FUNCTION__ << std::endl; - auto file_path = utils::path::combine(mount_location, {name}); - - auto fd = - open(file_path.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP); - EXPECT_LE(1, fd); - EXPECT_TRUE(utils::file::is_file(file_path)); - EXPECT_FALSE(utils::file::is_directory(file_path)); - - std::uint64_t file_size{}; - EXPECT_TRUE(utils::file::get_file_size(file_path, file_size)); - EXPECT_EQ(0u, file_size); - - EXPECT_EQ(0, close(fd)); - std::this_thread::sleep_for(SLEEP_SECONDS); - - return file_path; -} - -static void rmdir_and_test(const std::string &directory_path) { - std::cout << __FUNCTION__ << std::endl; - int ret = 0; - for (auto i = 0; ((ret = rmdir(directory_path.c_str())) != 0) && (i < 20); - i++) { - std::this_thread::sleep_for(100ms); - } - - EXPECT_EQ(0, ret); - std::this_thread::sleep_for(SLEEP_SECONDS); - - EXPECT_FALSE(utils::file::is_directory(directory_path)); - EXPECT_FALSE(utils::file::is_file(directory_path)); -} - -static void unlink_file_and_test(const std::string &file_path) { - std::cout << __FUNCTION__ << std::endl; - int ret = 0; - for (auto i = 0; ((ret = unlink(file_path.c_str())) != 0) && (i < 20); i++) { - std::this_thread::sleep_for(100ms); - } - - EXPECT_EQ(0, ret); - - std::this_thread::sleep_for(SLEEP_SECONDS); - EXPECT_FALSE(utils::file::is_directory(file_path)); - EXPECT_FALSE(utils::file::is_file(file_path)); -} - -static void test_chmod(const std::string & /* api_path */, - const std::string &file_path) { - std::cout << __FUNCTION__ << std::endl; +TYPED_TEST(fuse_test, chmod) { + auto file_path = this->create_file_and_test("chmod_test"); EXPECT_EQ(0, chmod(file_path.c_str(), S_IRUSR | S_IWUSR)); std::this_thread::sleep_for(SLEEP_SECONDS); @@ -137,11 +537,11 @@ static void test_chmod(const std::string & /* api_path */, stat64(file_path.c_str(), &unix_st); EXPECT_EQ(static_cast(S_IRUSR | S_IWUSR), ACCESSPERMS & unix_st.st_mode); + this->unlink_file_and_test(file_path); } -static void test_chown(const std::string & /* api_path */, - const std::string &file_path) { - std::cout << __FUNCTION__ << std::endl; +TYPED_TEST(fuse_test, chown) { + auto file_path = this->create_file_and_test("chown_test"); EXPECT_EQ(0, chown(file_path.c_str(), static_cast(-1), 0)); std::this_thread::sleep_for(SLEEP_SECONDS); @@ -154,550 +554,9 @@ static void test_chown(const std::string & /* api_path */, stat64(file_path.c_str(), &unix_st); EXPECT_EQ(0U, unix_st.st_gid); -} -static void test_mkdir(const std::string & /* api_path */, - const std::string &directory_path) { - std::cout << __FUNCTION__ << std::endl; - EXPECT_EQ(0, mkdir(directory_path.c_str(), - S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP)); - - EXPECT_TRUE(utils::file::is_directory(directory_path)); - EXPECT_FALSE(utils::file::is_file(directory_path)); - - struct stat64 unix_st {}; - stat64(directory_path.c_str(), &unix_st); - - EXPECT_EQ(getuid(), unix_st.st_uid); - EXPECT_EQ(getgid(), unix_st.st_gid); - - EXPECT_EQ(static_cast(S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | - S_IXGRP), - ACCESSPERMS & unix_st.st_mode); -} - -static void test_write_and_read(const std::string & /* api_path */, - const std::string &file_path) { - std::cout << __FUNCTION__ << std::endl; - auto fd = - open(file_path.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP); - EXPECT_LE(1, fd); - - std::string data = "TestData"; - EXPECT_EQ(data.size(), - static_cast(write(fd, data.data(), data.size()))); - EXPECT_EQ(0, lseek(fd, 0, SEEK_SET)); - fsync(fd); - - data_buffer read_data; - read_data.resize(data.size()); - EXPECT_EQ(data.size(), static_cast( - read(fd, read_data.data(), read_data.size()))); - - EXPECT_EQ(0, memcmp(data.data(), read_data.data(), data.size())); - - EXPECT_EQ(0, close(fd)); - - std::this_thread::sleep_for(SLEEP_SECONDS); - - std::uint64_t file_size{}; - EXPECT_TRUE(utils::file::get_file_size(file_path, file_size)); - EXPECT_EQ(data.size(), file_size); - - // filesystem_item fsi{}; - // EXPECT_EQ(api_error::success, - // provider.get_filesystem_item(api_path, false, fsi)); - // EXPECT_TRUE(utils::file::get_file_size(fsi.source_path, file_size)); - // EXPECT_EQ(data.size(), file_size); -} - -static void test_rename_file(const std::string &from_file_path, - const std::string &to_file_path, - bool is_rename_supported) { - std::cout << __FUNCTION__ << std::endl; - auto fd = open(from_file_path.c_str(), O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP); - EXPECT_LE(1, fd); - close(fd); - - std::this_thread::sleep_for(SLEEP_SECONDS); - - if (is_rename_supported) { - EXPECT_EQ(0, rename(from_file_path.c_str(), to_file_path.c_str())); - EXPECT_FALSE(utils::file::is_file(from_file_path)); - EXPECT_TRUE(utils::file::is_file(to_file_path)); - } else { - EXPECT_EQ(-1, rename(from_file_path.c_str(), to_file_path.c_str())); - EXPECT_TRUE(utils::file::is_file(from_file_path)); - EXPECT_FALSE(utils::file::is_file(to_file_path)); - } -} - -static void test_rename_directory(const std::string &from_dir_path, - const std::string &to_dir_path, - bool is_rename_supported) { - std::cout << __FUNCTION__ << std::endl; - EXPECT_EQ(0, mkdir(from_dir_path.c_str(), - S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP)); - std::this_thread::sleep_for(SLEEP_SECONDS); - - EXPECT_TRUE(utils::file::is_directory(from_dir_path)); - if (is_rename_supported) { - EXPECT_EQ(0, rename(from_dir_path.c_str(), to_dir_path.c_str())); - EXPECT_FALSE(utils::file::is_directory(from_dir_path)); - EXPECT_TRUE(utils::file::is_directory(to_dir_path)); - } else { - EXPECT_EQ(-1, rename(from_dir_path.c_str(), to_dir_path.c_str())); - EXPECT_TRUE(utils::file::is_directory(from_dir_path)); - EXPECT_FALSE(utils::file::is_directory(to_dir_path)); - } -} - -static void test_truncate(const std::string &file_path) { - std::cout << __FUNCTION__ << std::endl; - EXPECT_EQ(0, truncate(file_path.c_str(), 10u)); - - std::uint64_t file_size{}; - EXPECT_TRUE(utils::file::get_file_size(file_path, file_size)); - - EXPECT_EQ(std::uint64_t(10u), file_size); -} - -static void test_ftruncate(const std::string &file_path) { - std::cout << __FUNCTION__ << std::endl; - auto fd = open(file_path.c_str(), O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP); - EXPECT_LE(1, fd); - - EXPECT_EQ(0, ftruncate(fd, 10u)); - - std::uint64_t file_size{}; - EXPECT_TRUE(utils::file::get_file_size(file_path, file_size)); - - EXPECT_EQ(std::uint64_t(10u), file_size); - - close(fd); -} - -#if !defined(__APPLE__) -static void test_fallocate(const std::string & /* api_path */, - const std::string &file_path) { - std::cout << __FUNCTION__ << std::endl; - auto file = - open(file_path.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP); - EXPECT_LE(1, file); - EXPECT_EQ(0, fallocate(file, 0, 0, 16)); - - std::uint64_t file_size{}; - EXPECT_TRUE(utils::file::get_file_size(file_path, file_size)); - EXPECT_EQ(16U, file_size); - - EXPECT_EQ(0, close(file)); - - file_size = 0U; - EXPECT_TRUE(utils::file::get_file_size(file_path, file_size)); - EXPECT_EQ(16U, file_size); -} -#endif - -static void test_file_getattr(const std::string & /* api_path */, - const std::string &file_path) { - std::cout << __FUNCTION__ << std::endl; - auto fd = - open(file_path.c_str(), O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR | S_IRGRP); - EXPECT_LE(1, fd); - - EXPECT_EQ(0, close(fd)); - - struct stat64 unix_st {}; - EXPECT_EQ(0, stat64(file_path.c_str(), &unix_st)); - EXPECT_EQ(static_cast(S_IRUSR | S_IWUSR | S_IRGRP), - ACCESSPERMS & unix_st.st_mode); - EXPECT_FALSE(S_ISDIR(unix_st.st_mode)); - EXPECT_TRUE(S_ISREG(unix_st.st_mode)); -} - -static void test_directory_getattr(const std::string & /* api_path */, - const std::string &directory_path) { - std::cout << __FUNCTION__ << std::endl; - EXPECT_EQ(0, mkdir(directory_path.c_str(), - S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP)); - - struct stat64 unix_st {}; - EXPECT_EQ(0, stat64(directory_path.c_str(), &unix_st)); - EXPECT_EQ(static_cast(S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | - S_IXGRP), - ACCESSPERMS & unix_st.st_mode); - EXPECT_TRUE(S_ISDIR(unix_st.st_mode)); - EXPECT_FALSE(S_ISREG(unix_st.st_mode)); -} - -static void -test_write_operations_fail_if_read_only(const std::string & /* api_path */, - const std::string &file_path) { - std::cout << __FUNCTION__ << std::endl; - auto fd = - open(file_path.c_str(), O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR | S_IRGRP); - EXPECT_LE(1, fd); - - std::string data = "TestData"; - EXPECT_EQ(-1, write(fd, data.data(), data.size())); - - EXPECT_EQ(-1, ftruncate(fd, 9u)); - -#if !defined(__APPLE__) - EXPECT_EQ(-1, fallocate(fd, 0, 0, 16)); -#endif - - EXPECT_EQ(0, close(fd)); - - std::this_thread::sleep_for(SLEEP_SECONDS); - - std::uint64_t file_size{}; - EXPECT_TRUE(utils::file::get_file_size(file_path, file_size)); - EXPECT_EQ(std::size_t(0u), file_size); - - // filesystem_item fsi{}; - // EXPECT_EQ(api_error::success, - // provider.get_filesystem_item(api_path, false, fsi)); - // EXPECT_TRUE(utils::file::get_file_size(fsi.source_path, file_size)); - // EXPECT_EQ(std::size_t(0u), file_size); -} - -#if !__APPLE__ && HAS_SETXATTR -static void test_xattr_invalid_parameters(const std::string &file_path) { - std::cout << __FUNCTION__ << std::endl; - std::string attr = "moose"; - EXPECT_EQ(-1, setxattr(nullptr, "user.test_attr", attr.data(), attr.size(), - XATTR_CREATE)); - EXPECT_EQ(errno, EFAULT); - EXPECT_EQ(-1, setxattr(file_path.c_str(), nullptr, attr.data(), attr.size(), - XATTR_CREATE)); - EXPECT_EQ(errno, EFAULT); - EXPECT_EQ(-1, setxattr(file_path.c_str(), "user.test_attr", nullptr, - attr.size(), XATTR_CREATE)); - EXPECT_EQ(errno, EFAULT); - EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", nullptr, 0, - XATTR_CREATE)); -} - -static void test_xattr_create_and_get(const std::string &file_path) { - std::cout << __FUNCTION__ << std::endl; - std::string attr = "moose"; - EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", attr.data(), - attr.size(), XATTR_CREATE)); - - std::string val; - val.resize(attr.size()); - EXPECT_EQ(attr.size(), - static_cast(getxattr( - file_path.c_str(), "user.test_attr", val.data(), val.size()))); - EXPECT_STREQ(attr.c_str(), val.c_str()); -} - -static void test_xattr_listxattr(const std::string &file_path) { - std::cout << __FUNCTION__ << std::endl; - std::string attr = "moose"; - EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", attr.data(), - attr.size(), XATTR_CREATE)); - EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr2", attr.data(), - attr.size(), XATTR_CREATE)); - - std::string val; - val.resize(attr.size()); - EXPECT_EQ(attr.size(), - static_cast(getxattr( - file_path.c_str(), "user.test_attr", val.data(), val.size()))); - EXPECT_STREQ(attr.c_str(), val.c_str()); - - std::string data; - auto size = listxattr(file_path.c_str(), data.data(), 0U); - EXPECT_EQ(31, size); - - data.resize(static_cast(size)); - EXPECT_EQ(size, listxattr(file_path.c_str(), data.data(), - static_cast(size))); - - auto *ptr = data.data(); - EXPECT_STREQ("user.test_attr", ptr); - - ptr += strlen(ptr) + 1; - EXPECT_STREQ("user.test_attr2", ptr); -} - -static void test_xattr_replace(const std::string &file_path) { - std::cout << __FUNCTION__ << std::endl; - std::string attr = "moose"; - EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", attr.data(), - attr.size(), XATTR_CREATE)); - - attr = "cow"; - EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", attr.data(), - attr.size(), XATTR_REPLACE)); - - std::string val; - val.resize(attr.size()); - EXPECT_EQ(attr.size(), - static_cast(getxattr( - file_path.c_str(), "user.test_attr", val.data(), val.size()))); - EXPECT_STREQ(attr.c_str(), val.c_str()); -} - -static void test_xattr_default_create(const std::string &file_path) { - std::cout << __FUNCTION__ << std::endl; - std::string attr = "moose"; - EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", attr.data(), - attr.size(), 0)); - - std::string val; - val.resize(attr.size()); - EXPECT_EQ(attr.size(), - static_cast(getxattr( - file_path.c_str(), "user.test_attr", val.data(), val.size()))); - EXPECT_STREQ(attr.c_str(), val.c_str()); -} - -static void test_xattr_default_replace(const std::string &file_path) { - std::cout << __FUNCTION__ << std::endl; - std::string attr = "moose"; - EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", attr.data(), - attr.size(), 0)); - - attr = "cow"; - EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", attr.data(), - attr.size(), 0)); - - std::string val; - val.resize(attr.size()); - EXPECT_EQ(attr.size(), - static_cast(getxattr( - file_path.c_str(), "user.test_attr", val.data(), val.size()))); - EXPECT_STREQ(attr.c_str(), val.c_str()); -} - -static void test_xattr_create_fails_if_exists(const std::string &file_path) { - std::cout << __FUNCTION__ << std::endl; - std::string attr = "moose"; - EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", attr.data(), - attr.size(), 0)); - EXPECT_EQ(-1, setxattr(file_path.c_str(), "user.test_attr", attr.data(), - attr.size(), XATTR_CREATE)); - EXPECT_EQ(EEXIST, errno); -} - -static void -test_xattr_create_fails_if_not_exists(const std::string &file_path) { - std::cout << __FUNCTION__ << std::endl; - std::string attr = "moose"; - EXPECT_EQ(-1, setxattr(file_path.c_str(), "user.test_attr", attr.data(), - attr.size(), XATTR_REPLACE)); - EXPECT_EQ(ENODATA, errno); -} - -static void test_xattr_removexattr(const std::string &file_path) { - std::cout << __FUNCTION__ << std::endl; - std::string attr = "moose"; - EXPECT_EQ(0, setxattr(file_path.c_str(), "user.test_attr", attr.data(), - attr.size(), XATTR_CREATE)); - - EXPECT_EQ(0, removexattr(file_path.c_str(), "user.test_attr")); - - std::string val; - val.resize(attr.size()); - EXPECT_EQ(-1, getxattr(file_path.c_str(), "user.test_attr", val.data(), - val.size())); - EXPECT_EQ(ENODATA, errno); -} -#endif - -TEST(fuse_drive, all_tests) { - auto current_directory = std::filesystem::current_path(); - - for (std::size_t idx = 0U; idx < 2U; idx++) { - std::filesystem::current_path(current_directory); - - const auto test_directory = utils::path::combine( - test::get_test_output_dir(), {"fuse_drive" + std::to_string(idx)}); - EXPECT_TRUE(utils::file::remove_directory(test_directory, true)); - - const auto mount_location = - utils::path::combine(test_directory, {"mount", std::to_string(idx)}); - - EXPECT_TRUE(utils::file::create_directories(mount_location)); - { - std::unique_ptr config_ptr{}; - std::unique_ptr comm_ptr{}; - std::unique_ptr provider_ptr{}; - - const auto cfg_directory = - utils::path::combine(test_directory, {"cfg", std::to_string(idx)}); - EXPECT_TRUE(utils::file::create_directories(cfg_directory)); - - std::vector drive_args{}; - - switch (idx) { - case 0U: { - config_ptr = - std::make_unique(provider_type::s3, cfg_directory); - { - app_config src_cfg( - provider_type::s3, - utils::path::combine(test::get_test_input_dir(), {"storj"})); - config_ptr->set_enable_drive_events(true); - config_ptr->set_event_level(event_level::trace); - config_ptr->set_s3_config(src_cfg.get_s3_config()); - } - - comm_ptr = std::make_unique(config_ptr->get_s3_config()); - provider_ptr = std::make_unique(*config_ptr, *comm_ptr); - drive_args = std::vector({"-s3", "-na", "storj"}); - } break; - - case 1U: { - config_ptr = - std::make_unique(provider_type::sia, cfg_directory); - { - app_config src_cfg( - provider_type::sia, - utils::path::combine(test::get_test_input_dir(), {"sia"})); - config_ptr->set_enable_drive_events(true); - config_ptr->set_event_level(event_level::debug); - config_ptr->set_host_config(src_cfg.get_host_config()); - } - - comm_ptr = std::make_unique(config_ptr->get_host_config()); - provider_ptr = std::make_unique(*config_ptr, *comm_ptr); - } break; - - default: - std::cerr << "provider at index " << idx << " is not implemented" - << std::endl; - continue; - } - - std::thread th([&] { - std::this_thread::sleep_for(5s); - EXPECT_EQ(0, system(("mount|grep \"" + mount_location + "\"").c_str())); - - auto file_path = create_file_and_test(mount_location, "chmod_test"); - test_chmod(utils::path::create_api_path("chmod_test"), file_path); - unlink_file_and_test(file_path); - - file_path = create_file_and_test(mount_location, "chown_test"); - test_chown(utils::path::create_api_path("chown_test"), file_path); - unlink_file_and_test(file_path); - - file_path = utils::path::combine(mount_location, {"mkdir_test"}); - test_mkdir(utils::path::create_api_path("mkdir_test"), file_path); - rmdir_and_test(file_path); - - file_path = create_file_and_test(mount_location, "write_read_test"); - test_write_and_read(utils::path::create_api_path("write_read_test"), - file_path); - unlink_file_and_test(file_path); - - file_path = - create_file_and_test(mount_location, "from_rename_file_test"); - auto to_file_path = - utils::path::combine(mount_location, {"to_rename_file_test"}); - test_rename_file(file_path, to_file_path, - provider_ptr->is_rename_supported()); - EXPECT_TRUE(utils::file::retry_delete_file(file_path)); - EXPECT_TRUE(utils::file::retry_delete_file(to_file_path)); - - file_path = - utils::path::combine(mount_location, {"from_rename_dir_test"}); - to_file_path = - utils::path::combine(mount_location, {"to_rename_dir_test"}); - test_rename_directory(file_path, to_file_path, - provider_ptr->is_rename_supported()); - EXPECT_TRUE(utils::file::retry_delete_directory(file_path.c_str())); - EXPECT_TRUE(utils::file::retry_delete_directory(to_file_path.c_str())); - - file_path = create_file_and_test(mount_location, "truncate_file_test"); - test_truncate(file_path); - unlink_file_and_test(file_path); - - file_path = create_file_and_test(mount_location, "ftruncate_file_test"); - test_ftruncate(file_path); - unlink_file_and_test(file_path); - -#if !defined(__APPLE__) - file_path = create_file_and_test(mount_location, "fallocate_file_test"); - test_fallocate(utils::path::create_api_path("fallocate_file_test"), - file_path); - unlink_file_and_test(file_path); -#endif - - file_path = create_file_and_test(mount_location, "write_fails_ro_test"); - test_write_operations_fail_if_read_only( - utils::path::create_api_path("write_fails_ro_test"), file_path); - unlink_file_and_test(file_path); - - file_path = create_file_and_test(mount_location, "getattr.txt"); - test_file_getattr(utils::path::create_api_path("getattr.txt"), - file_path); - unlink_file_and_test(file_path); - - file_path = utils::path::combine(mount_location, {"getattr_dir"}); - test_directory_getattr(utils::path::create_api_path("getattr_dir"), - file_path); - rmdir_and_test(file_path); - -#if !__APPLE__ && HAS_SETXATTR - file_path = - create_file_and_test(mount_location, "xattr_invalid_names_test"); - test_xattr_invalid_parameters(file_path); - unlink_file_and_test(file_path); - - file_path = - create_file_and_test(mount_location, "xattr_create_get_test"); - test_xattr_create_and_get(file_path); - unlink_file_and_test(file_path); - - file_path = - create_file_and_test(mount_location, "xattr_listxattr_test"); - test_xattr_listxattr(file_path); - unlink_file_and_test(file_path); - - file_path = create_file_and_test(mount_location, "xattr_replace_test"); - test_xattr_replace(file_path); - unlink_file_and_test(file_path); - - file_path = - create_file_and_test(mount_location, "xattr_default_create_test"); - test_xattr_default_create(file_path); - unlink_file_and_test(file_path); - - file_path = - create_file_and_test(mount_location, "xattr_default_replace_test"); - test_xattr_default_replace(file_path); - unlink_file_and_test(file_path); - - file_path = create_file_and_test(mount_location, - "xattr_create_fails_exists_test"); - test_xattr_create_fails_if_exists(file_path); - unlink_file_and_test(file_path); - - file_path = create_file_and_test(mount_location, - "xattr_create_fails_not_exists_test"); - test_xattr_create_fails_if_not_exists(file_path); - unlink_file_and_test(file_path); - - file_path = - create_file_and_test(mount_location, "xattr_removexattr_test"); - test_xattr_removexattr(file_path); - unlink_file_and_test(file_path); -#endif - - execute_unmount(mount_location); - }); - - drive_args.push_back(mount_location); - execute_mount(config_ptr->get_data_directory(), drive_args, th); - } - } - - std::filesystem::current_path(current_directory); + this->unlink_file_and_test(file_path); } } // namespace repertory -#endif +#endif // !defined(_WIN32) diff --git a/scripts/make_common.sh b/scripts/make_common.sh index e612ac5c..1ae6b863 100755 --- a/scripts/make_common.sh +++ b/scripts/make_common.sh @@ -15,6 +15,8 @@ if [ -f "${PROJECT_SOURCE_DIR}/pre_build.sh" ]; then "${PROJECT_SOURCE_DIR}/pre_build.sh" fi +ln -sf "${PROJECT_BUILD_DIR}/build/compile_commands.json" "${PROJECT_SOURCE_DIR}/compile_commands.json" + pushd "${PROJECT_BUILD_DIR}" cmake "${PROJECT_SOURCE_DIR}" \ -G"Unix Makefiles" \ @@ -80,8 +82,6 @@ if [ "${PROJECT_IS_MINGW}" == "1" ]; then . "${PROJECT_SCRIPTS_DIR}/copy_mingw64_deps.sh" "$1" "$2" "$3" "$4" "$5" fi -ln -sf "${PROJECT_BUILD_DIR}/build/compile_commands.json" "${PROJECT_SOURCE_DIR}/compile_commands.json" - if [ -f "${PROJECT_SOURCE_DIR}/post_build.sh" ]; then "${PROJECT_SOURCE_DIR}/post_build.sh" fi