From eb4c8c6cc0a821d41a61c1c41ddba769a07f1c45 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sun, 10 Nov 2024 10:13:02 -0600 Subject: [PATCH] fuse unit tests and fixes --- .../src/drives/fuse/fuse_drive_base.cpp | 26 ++++--- .../src/fuse_drive_access_test.cpp | 77 +++++++++++++++++++ 2 files changed, 91 insertions(+), 12 deletions(-) create mode 100644 repertory/repertory_test/src/fuse_drive_access_test.cpp diff --git a/repertory/librepertory/src/drives/fuse/fuse_drive_base.cpp b/repertory/librepertory/src/drives/fuse/fuse_drive_base.cpp index 507f1720..82aa05ea 100644 --- a/repertory/librepertory/src/drives/fuse/fuse_drive_base.cpp +++ b/repertory/librepertory/src/drives/fuse/fuse_drive_base.cpp @@ -23,6 +23,7 @@ #include "drives/fuse/fuse_drive_base.hpp" +#include "events/events.hpp" #include "platform/platform.hpp" #include "providers/i_provider.hpp" #include "utils/common.hpp" @@ -35,8 +36,10 @@ auto fuse_drive_base::access_impl(std::string api_path, int mask) -> api_error { auto fuse_drive_base::check_access(const std::string &api_path, int mask) const -> api_error { + REPERTORY_USES_FUNCTION_NAME(); + api_meta_map meta; - const auto res = get_item_meta(api_path, meta); + auto res = get_item_meta(api_path, meta); if (res != api_error::success) { return res; } @@ -48,7 +51,7 @@ auto fuse_drive_base::check_access(const std::string &api_path, } // Always allow forced user - if (forced_uid_.has_value() || (current_uid == get_effective_uid())) { + if (forced_uid_.has_value() && (current_uid == get_effective_uid())) { return api_error::success; } @@ -57,9 +60,9 @@ auto fuse_drive_base::check_access(const std::string &api_path, return api_error::success; } - const auto effective_uid = + auto effective_uid = (forced_uid_.has_value() ? forced_uid_.value() : get_uid_from_meta(meta)); - const auto effective_gid = + auto effective_gid = (forced_gid_.has_value() ? forced_gid_.value() : get_gid_from_meta(meta)); // Create file mode @@ -73,10 +76,9 @@ auto fuse_drive_base::check_access(const std::string &api_path, if (current_uid == effective_uid) { active_mask |= S_IRWXU; } - if (get_current_gid() == effective_gid) { - active_mask |= S_IRWXG; - } - if (utils::is_uid_member_of_group(current_uid, effective_gid)) { + + if (get_current_gid() == effective_gid || + utils::is_uid_member_of_group(current_uid, effective_gid)) { active_mask |= S_IRWXG; } @@ -194,7 +196,7 @@ auto fuse_drive_base::check_parent_access(const std::string &api_path, auto fuse_drive_base::check_readable(int flags, const api_error &fail_error) -> api_error { - const auto mode = (flags & O_ACCMODE); + auto mode = (flags & O_ACCMODE); return ((mode == O_WRONLY) ? fail_error : api_error::success); } @@ -320,9 +322,9 @@ void fuse_drive_base::populate_stat(const std::string &api_path, st->st_size = static_cast(size_or_count); static const auto block_size_stat = static_cast(512U); static const auto block_size = static_cast(4096U); - const auto size = utils::divide_with_ceiling( - static_cast(st->st_size), block_size) * - block_size; + auto size = utils::divide_with_ceiling( + static_cast(st->st_size), block_size) * + block_size; st->st_blocks = static_cast( std::max(block_size / block_size_stat, utils::divide_with_ceiling(size, block_size_stat))); diff --git a/repertory/repertory_test/src/fuse_drive_access_test.cpp b/repertory/repertory_test/src/fuse_drive_access_test.cpp new file mode 100644 index 00000000..34ccdfa5 --- /dev/null +++ b/repertory/repertory_test/src/fuse_drive_access_test.cpp @@ -0,0 +1,77 @@ +/* + 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. +*/ +#if !defined(_WIN32) + +#include "fixtures/fuse_fixture.hpp" + +namespace repertory { +TYPED_TEST_CASE(fuse_test, fuse_provider_types); + +TYPED_TEST(fuse_test, access_can_check_if_item_does_not_exist) { + EXPECT_EQ( + -1, + access(utils::path::combine(this->mount_location, {"test_dir"}).c_str(), + F_OK)); + EXPECT_EQ(ENOENT, utils::get_last_error_code()); +} + +TYPED_TEST(fuse_test, access_can_check_if_directory_exists) { + std::string dir_name{"access_test"}; + auto dir_path = this->create_directory_and_test(dir_name); + + EXPECT_EQ(0, access(dir_path.c_str(), F_OK)); + + this->rmdir_and_test(dir_path); +} + +TYPED_TEST(fuse_test, access_can_check_directory_read_access) { + std::string dir_name{"access_test"}; + auto dir_path = this->create_directory_and_test(dir_name); + + EXPECT_EQ(0, access(dir_path.c_str(), R_OK)); + + this->rmdir_and_test(dir_path); +} + +TYPED_TEST(fuse_test, access_can_check_directory_does_not_have_read_access) { + std::string dir_name{"access_test"}; + auto dir_path = this->create_directory_and_test(dir_name); + + EXPECT_EQ(0, chmod(dir_path.c_str(), 0000)); + + EXPECT_EQ(-1, access(dir_path.c_str(), R_OK)); + EXPECT_EQ(EACCES, utils::get_last_error_code()); + + this->rmdir_and_test(dir_path); +} + +TYPED_TEST(fuse_test, access_can_check_if_file_exists) { + std::string file_name{"access_test"}; + auto file_path = this->create_file_and_test(file_name); + + EXPECT_EQ(0, access(file_path.c_str(), F_OK)); + + this->unlink_file_and_test(file_path); +} +} // namespace repertory + +#endif // !defined(_WIN32)