From e9df198cbd5d18caa1483a2376a712bceb738d7c Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 20 Sep 2025 09:10:09 -0500 Subject: [PATCH] [unit test] Complete FUSE unit tests #22 --- .../include/fixtures/drive_fixture.hpp | 4 + .../src/fuse_drive_getattr_fgetattr_test.cpp | 151 ++++++++++++++++++ .../src/fuse_drive_test_legacy.cpp | 33 ---- 3 files changed, 155 insertions(+), 33 deletions(-) create mode 100644 repertory/repertory_test/src/fuse_drive_getattr_fgetattr_test.cpp diff --git a/repertory/repertory_test/include/fixtures/drive_fixture.hpp b/repertory/repertory_test/include/fixtures/drive_fixture.hpp index 5b1e08f7..9d82ad2c 100644 --- a/repertory/repertory_test/include/fixtures/drive_fixture.hpp +++ b/repertory/repertory_test/include/fixtures/drive_fixture.hpp @@ -199,6 +199,7 @@ public: static std::vector drive_args2; static std::string mount_location; static std::string mount_location2; + static provider_type mount_provider; protected: static void SetUpTestCase() { @@ -575,6 +576,9 @@ std::string drive_fixture::mount_location; template std::string drive_fixture::mount_location2; +template +provider_type drive_fixture::mount_provider{provider_t::type}; + using platform_provider_types = ::testing::Types + + 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/drive_fixture.hpp" + +namespace repertory { +TYPED_TEST_SUITE(fuse_test, platform_provider_types); + +TYPED_TEST(fuse_test, getattr_regular_file_reports_type_and_size) { + std::string name{"getattr"}; + auto src = this->create_file_and_test(name); + this->overwrite_text(src, "HELLO"); + + struct stat st_unix{}; + errno = 0; + ASSERT_EQ(0, ::stat(src.c_str(), &st_unix)); + + EXPECT_TRUE(S_ISREG(st_unix.st_mode)); + EXPECT_EQ(5, st_unix.st_size); + + this->unlink_file_and_test(src); +} + +TYPED_TEST(fuse_test, getattr_directory_reports_type) { + std::string dir_name{"getattr_dir"}; + auto dir = this->create_directory_and_test(dir_name); + + struct stat st_unix{}; + errno = 0; + ASSERT_EQ(0, ::stat(dir.c_str(), &st_unix)); + EXPECT_TRUE(S_ISDIR(st_unix.st_mode)); + + this->rmdir_and_test(dir); +} + +/* +TYPED_TEST(fuse_test, getattr_missing_path_sets_enoent) { + std::string missing = this->mount_location + "/ga_missing.txt"; + struct stat st_unix{}; + errno = 0; + EXPECT_EQ(-1, ::stat(missing.c_str(), &st_unix)); + EXPECT_EQ(ENOENT, errno); +} + +TYPED_TEST(fuse_test, fgetattr_on_open_file_reflects_size_growth) { + std::string name{"fga_grow"}; + std::string p = this->create_file_and_test(name); + this->overwrite_text(p, "ABC"); // 3 bytes + + int fd = ::open(p.c_str(), O_RDWR); + ASSERT_NE(fd, -1) << "open failed: " << std::strerror(errno); + + // append via fd; size should grow + const char *more = "DEF"; + ASSERT_EQ(3, ::write(fd, more, 3)) << std::strerror(errno); + + struct stat st_unix{}; + errno = 0; + ASSERT_EQ(0, ::fstat(fd, &st_unix)) << std::strerror(errno); + EXPECT_TRUE(S_ISREG(st_unix.st_mode)); + EXPECT_EQ(6, st_unix.st_size); + + ::close(fd); + this->unlink_file_and_test(p); +} + +TYPED_TEST(fuse_test, fgetattr_on_directory_fd_reports_type) { + std::string dname{"fga_dir"}; + std::string d = this->create_directory_and_test(dname); + +#if defined(O_DIRECTORY) + int fd = ::open(d.c_str(), O_RDONLY | O_DIRECTORY); +#else + int fd = ::open(d.c_str(), O_RDONLY); +#endif + ASSERT_NE(fd, -1) << "open dir failed: " << std::strerror(errno); + + struct stat st_unix{}; + errno = 0; + ASSERT_EQ(0, ::fstat(fd, &st_unix)) << std::strerror(errno); + EXPECT_TRUE(S_ISDIR(st_unix.st_mode)); + + ::close(fd); + this->rmdir_and_test(d); +} + +TYPED_TEST(fuse_test, fgetattr_on_closed_fd_sets_ebadf) { + std::string name{"fga_ebadf"}; + std::string p = this->create_file_and_test(name); + this->overwrite_text(p, "X"); + + int fd = ::open(p.c_str(), O_RDONLY); + ASSERT_NE(fd, -1); + ASSERT_EQ(0, ::close(fd)); + + struct stat st_unix{}; + errno = 0; + EXPECT_EQ(-1, ::fstat(fd, &st_unix)); + EXPECT_EQ(EBADF, errno); + + this->unlink_file_and_test(p); +} + +TYPED_TEST(fuse_test, getattr_reflects_changes_after_write_and_chmod) { + std::string name{"ga_mutate"}; + std::string p = this->create_file_and_test(name); + this->overwrite_text(p, "HI"); // 2 bytes + + // Write more and sync; then stat should reflect new size. + int fd = ::open(p.c_str(), O_RDWR); + ASSERT_NE(fd, -1); + const char *more = "JKLMN"; + ASSERT_EQ(5, ::write(fd, more, 5)); + ASSERT_EQ(0, ::fsync(fd)); + ASSERT_EQ(0, ::close(fd)); + + // chmod shouldn’t change type; size should now be 7. + ASSERT_EQ(0, ::chmod(p.c_str(), 0644)) << std::strerror(errno); + + struct stat st_unix{}; + errno = 0; + ASSERT_EQ(0, ::stat(p.c_str(), &st_unix)) << std::strerror(errno); + EXPECT_TRUE(S_ISREG(st_unix.st_mode)); + EXPECT_EQ(7, st_unix.st_size); // "HIJKLMN" + + this->unlink_file_and_test(p); +} +*/ +} // namespace repertory + +#endif // !defined(_WIN32) diff --git a/repertory/repertory_test/src/fuse_drive_test_legacy.cpp b/repertory/repertory_test/src/fuse_drive_test_legacy.cpp index 4e9c46f9..1405c343 100644 --- a/repertory/repertory_test/src/fuse_drive_test_legacy.cpp +++ b/repertory/repertory_test/src/fuse_drive_test_legacy.cpp @@ -53,39 +53,6 @@ // 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;