From 4c4db56a8272159968f4e87c836a76df7825b1fb Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Thu, 31 Oct 2024 10:43:41 -0500 Subject: [PATCH] winfsp unit tests and fixes --- .../src/drives/winfsp/winfsp_drive.cpp | 9 ++- .../src/providers/s3/s3_provider.cpp | 17 +++++ .../include/fixtures/fuse_fixture.hpp | 10 ++- .../include/fixtures/winfsp_fixture.hpp | 10 ++- .../src/winfsp_drive_create_nl_test.cpp | 64 ++++++++++--------- 5 files changed, 71 insertions(+), 39 deletions(-) diff --git a/repertory/librepertory/src/drives/winfsp/winfsp_drive.cpp b/repertory/librepertory/src/drives/winfsp/winfsp_drive.cpp index 8964bb9e..9d4c3fb3 100644 --- a/repertory/librepertory/src/drives/winfsp/winfsp_drive.cpp +++ b/repertory/librepertory/src/drives/winfsp/winfsp_drive.cpp @@ -104,8 +104,11 @@ auto winfsp_drive::winfsp_service::OnStart(ULONG /*Argc*/, PWSTR * /*Argv*/) if ((drive_letter && not utils::file::directory(mount_location).exists())) { auto unicode_mount_location = utils::string::from_utf8(mount_location); host_.SetFileSystemName(unicode_mount_location.data()); - unicode_mount_location = - std::wstring(L"\\\\.\\") + unicode_mount_location[0U] + L":"; + + if (config_.get_enable_mount_manager()) { + unicode_mount_location = + std::wstring(L"\\\\.\\") + unicode_mount_location[0U] + L":"; + } ret = host_.Mount(unicode_mount_location.data()); } else { std::cerr << (drive_letter ? "Mount location in use: " @@ -555,7 +558,7 @@ auto winfsp_drive::Init(PVOID host) -> NTSTATUS { std::wstring(file_system_host->FileSystemName()).substr(0, 1)) .data()); } - file_system_host->SetFileSystemName(std::wstring{REPERTORY_W}.data()); + file_system_host->SetFlushAndPurgeOnCleanup(TRUE); file_system_host->SetReparsePoints(FALSE); file_system_host->SetReparsePointsAccessCheck(FALSE); diff --git a/repertory/librepertory/src/providers/s3/s3_provider.cpp b/repertory/librepertory/src/providers/s3/s3_provider.cpp index 09f99a12..61e9a965 100644 --- a/repertory/librepertory/src/providers/s3/s3_provider.cpp +++ b/repertory/librepertory/src/providers/s3/s3_provider.cpp @@ -36,6 +36,7 @@ #include "utils/polling.hpp" #include "utils/string.hpp" #include "utils/time.hpp" +#include namespace repertory { s3_provider::s3_provider(app_config &config, i_http_comm &comm) @@ -283,6 +284,8 @@ auto s3_provider::get_directory_item_count(const std::string &api_path) const auto s3_provider::get_directory_items_impl(const std::string &api_path, directory_item_list &list) const -> api_error { + REPERTORY_USES_FUNCTION_NAME(); + const auto cfg = get_config().get_s3_config(); const auto is_encrypted = not cfg.encryption_token.empty(); @@ -313,6 +316,8 @@ auto s3_provider::get_directory_items_impl(const std::string &api_path, } if (response_code != http_error_codes::ok) { + utils::error::raise_api_path_error(function_name, api_path, response_code, + "failed to get directory items"); return api_error::comm_error; } @@ -430,6 +435,8 @@ auto s3_provider::get_file(const std::string &api_path, api_file &file) const } auto s3_provider::get_file_list(api_file_list &list) const -> api_error { + REPERTORY_USES_FUNCTION_NAME(); + std::string response_data; long response_code{}; if (not get_object_list(response_data, response_code)) { @@ -437,12 +444,16 @@ auto s3_provider::get_file_list(api_file_list &list) const -> api_error { } if (response_code != http_error_codes::ok) { + utils::error::raise_error(function_name, response_code, + "failed to get file list"); return api_error::comm_error; } pugi::xml_document doc; auto res = doc.load_string(response_data.c_str()); if (res.status != pugi::xml_parse_status::status_ok) { + utils::error::raise_error(function_name, res.status, + "failed to parse xml document"); return api_error::comm_error; } @@ -538,6 +549,8 @@ auto s3_provider::get_object_info(bool directory, const std::string &api_path, } if (response_code != http_error_codes::ok) { + utils::error::raise_api_path_error(function_name, api_path, response_code, + "failed to get object info"); return api_error::comm_error; } @@ -885,6 +898,8 @@ void s3_provider::stop() { auto s3_provider::upload_file_impl(const std::string &api_path, const std::string &source_path, stop_type &stop_requested) -> api_error { + REPERTORY_USES_FUNCTION_NAME(); + std::uint64_t file_size{}; if (utils::file::file{source_path}.exists()) { auto opt_size = utils::file::file{source_path}.size(); @@ -926,6 +941,8 @@ auto s3_provider::upload_file_impl(const std::string &api_path, } if (response_code != http_error_codes::ok) { + utils::error::raise_api_path_error(function_name, api_path, response_code, + "failed to get upload file"); return api_error::comm_error; } diff --git a/repertory/repertory_test/include/fixtures/fuse_fixture.hpp b/repertory/repertory_test/include/fixtures/fuse_fixture.hpp index d796b2f1..84e5eafe 100644 --- a/repertory/repertory_test/include/fixtures/fuse_fixture.hpp +++ b/repertory/repertory_test/include/fixtures/fuse_fixture.hpp @@ -54,6 +54,7 @@ public: static std::string cfg_directory; static std::unique_ptr config; static std::filesystem::path current_directory; + static provider_type current_provider; static std::unique_ptr drive; static std::vector drive_args; static std::unique_ptr meta; @@ -68,7 +69,7 @@ protected: test::get_test_output_dir(), { "fuse_test", - std::to_string(static_cast(provider_t::type)), + app_config::get_provider_name(current_provider), }); mount_location = utils::path::combine(test_directory, {"mount"}); @@ -77,9 +78,9 @@ protected: cfg_directory = utils::path::combine(test_directory, {"cfg"}); ASSERT_TRUE(utils::file::directory(cfg_directory).create_directory()); - config = std::make_unique(provider_t::type, cfg_directory); + config = std::make_unique(current_provider, cfg_directory); - switch (provider_t::type) { + switch (current_provider) { case provider_type::s3: { { app_config src_cfg{ @@ -232,6 +233,9 @@ std::unique_ptr fuse_test::config{}; template std::filesystem::path fuse_test::current_directory{}; +template +provider_type winfsp_test::current_provider{provider_t::type}; + template std::unique_ptr fuse_test::drive{}; diff --git a/repertory/repertory_test/include/fixtures/winfsp_fixture.hpp b/repertory/repertory_test/include/fixtures/winfsp_fixture.hpp index 277691f6..3be4c49c 100644 --- a/repertory/repertory_test/include/fixtures/winfsp_fixture.hpp +++ b/repertory/repertory_test/include/fixtures/winfsp_fixture.hpp @@ -53,6 +53,7 @@ public: static std::string mount_location; static std::unique_ptr provider; static std::string test_directory; + static provider_type current_provider; protected: static void SetUpTestCase() { @@ -62,7 +63,7 @@ protected: test::get_test_output_dir(), { "winfsp_test", - std::to_string(static_cast(provider_t::type)), + app_config::get_provider_name(current_provider), }); mount_location = "U:"; @@ -70,9 +71,9 @@ protected: cfg_directory = utils::path::combine(test_directory, {"cfg"}); ASSERT_TRUE(utils::file::directory(cfg_directory).create_directory()); - config = std::make_unique(provider_t::type, cfg_directory); + config = std::make_unique(current_provider, cfg_directory); - switch (provider_t::type) { + switch (current_provider) { case provider_type::s3: { { app_config src_cfg{ @@ -230,6 +231,9 @@ std::unique_ptr winfsp_test::config; template std::filesystem::path winfsp_test::current_directory; +template +provider_type winfsp_test::current_provider{provider_t::type}; + template std::unique_ptr winfsp_test::drive; diff --git a/repertory/repertory_test/src/winfsp_drive_create_nl_test.cpp b/repertory/repertory_test/src/winfsp_drive_create_nl_test.cpp index 91af72f0..7322574e 100644 --- a/repertory/repertory_test/src/winfsp_drive_create_nl_test.cpp +++ b/repertory/repertory_test/src/winfsp_drive_create_nl_test.cpp @@ -31,44 +31,48 @@ namespace repertory { TYPED_TEST_CASE(winfsp_test, winfsp_provider_types); TYPED_TEST(winfsp_test, cr8_nl_can_create_file_of_max_component_length) { - DWORD max_length{}; - EXPECT_TRUE(::GetVolumeInformationA(this->mount_location.c_str(), nullptr, 0, - nullptr, &max_length, nullptr, nullptr, - 0)); - EXPECT_EQ(255U, max_length); + if (this->current_provider != provider_type::s3) { + DWORD max_length{}; + EXPECT_TRUE(::GetVolumeInformationA(this->mount_location.c_str(), nullptr, + 0, nullptr, &max_length, nullptr, + nullptr, 0)); + EXPECT_EQ(255U, max_length); - auto file_path = utils::path::combine(this->mount_location, - { - std::string(max_length - 1U, 'a'), - }); + auto file_path = utils::path::combine(this->mount_location, + { + std::string(max_length, 'a'), + }); - auto handle = - ::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0); - EXPECT_NE(INVALID_HANDLE_VALUE, handle); - EXPECT_TRUE(::CloseHandle(handle)); + auto handle = + ::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0); + EXPECT_NE(INVALID_HANDLE_VALUE, handle); + EXPECT_TRUE(::CloseHandle(handle)); + } } TYPED_TEST(winfsp_test, cr8_nl_can_not_create_file_greater_than_max_component_length) { - DWORD max_length{}; - EXPECT_TRUE(::GetVolumeInformationA(this->mount_location.c_str(), nullptr, 0, - nullptr, &max_length, nullptr, nullptr, - 0)); - EXPECT_EQ(255U, max_length); + if (this->current_provider != provider_type::s3) { + DWORD max_length{}; + EXPECT_TRUE(::GetVolumeInformationA(this->mount_location.c_str(), nullptr, + 0, nullptr, &max_length, nullptr, + nullptr, 0)); + EXPECT_EQ(255U, max_length); - auto file_path = utils::path::combine(this->mount_location, - { - std::string(max_length, 'a'), - }); + auto file_path = utils::path::combine(this->mount_location, + { + std::string(max_length + 1U, 'a'), + }); - auto handle = - ::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0); - EXPECT_EQ(INVALID_HANDLE_VALUE, handle); - EXPECT_EQ(ERROR_INVALID_NAME, ::GetLastError()); + auto handle = + ::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0); + EXPECT_EQ(INVALID_HANDLE_VALUE, handle); + EXPECT_EQ(ERROR_INVALID_NAME, ::GetLastError()); + } } } // namespace repertory