[unit test] Complete FUSE unit tests #22

This commit is contained in:
2025-09-20 08:52:30 -05:00
parent f7d4fe00ba
commit 29648af9ba

View File

@@ -84,102 +84,90 @@ TYPED_TEST(fuse_test, truncate_fails_if_path_is_directory) {
this->rmdir_and_test(src); this->rmdir_and_test(src);
} }
/* TYPED_TEST(fuse_test, truncate_fails_if_file_is_read_only) {
TYPED_TEST(fuse_test, truncate_readonly_file_eacces_or_eperm_or_erofs_skip) {
if (this->current_provider != provider_type::sia)
return;
std::string name{"trunc_ro"}; std::string name{"trunc_ro"};
std::string p = this->create_file_and_test(name); auto src = this->create_file_and_test(name);
this->overwrite_text(p, "DATA"); this->overwrite_text(src, "DATA");
ASSERT_EQ(0, ::chmod(p.c_str(), 0444)) << std::strerror(errno); ASSERT_EQ(0, ::chmod(src.c_str(), 0444));
errno = 0; errno = 0;
int res = ::truncate(p.c_str(), 2); int res = ::truncate(src.c_str(), 2);
if (res == -1 && errno == EROFS) { if (res == -1 && errno == EROFS) {
ASSERT_EQ(0, ::chmod(p.c_str(), 0644)); ASSERT_EQ(0, ::chmod(src.c_str(), 0644));
this->unlink_file_and_test(p); this->unlink_file_and_test(src);
GTEST_SKIP() << "read-only mount; truncate returns EROFS"; GTEST_SKIP();
return;
} }
EXPECT_EQ(-1, res); EXPECT_EQ(-1, res);
EXPECT_TRUE(errno == EACCES || errno == EPERM) EXPECT_TRUE(errno == EACCES || errno == EPERM);
<< "errno=" << errno << " " << std::strerror(errno);
ASSERT_EQ(0, ::chmod(p.c_str(), 0644)); ASSERT_EQ(0, ::chmod(src.c_str(), 0644));
this->unlink_file_and_test(p); this->unlink_file_and_test(src);
} }
// ========== ftruncate(2) ========== TYPED_TEST(fuse_test, ftruncate_can_shrink_file) {
std::string name{"ftruncate"};
auto src = this->create_file_and_test(name);
this->overwrite_text(src, "HELLOWORLD");
TYPED_TEST(fuse_test, ftruncate_shrink_open_fd) { auto desc = ::open(src.c_str(), O_RDWR);
if (this->current_provider != provider_type::sia) ASSERT_NE(desc, -1);
return;
std::string name{"ftrunc_shrink"};
std::string p = this->create_file_and_test(name);
this->overwrite_text(p, "HELLOWORLD"); // 10 bytes
int fd = ::open(p.c_str(), O_RDWR);
ASSERT_NE(fd, -1) << "open failed: " << std::strerror(errno);
errno = 0; errno = 0;
ASSERT_EQ(0, ::ftruncate(fd, 4)) << std::strerror(errno); ASSERT_EQ(0, ::ftruncate(desc, 4));
::close(fd); ::close(desc);
EXPECT_EQ(4, this->stat_size(p)); EXPECT_EQ(4, this->stat_size(src));
EXPECT_EQ("HELL", this->slurp(p)); EXPECT_EQ("HELL", this->slurp(src));
this->unlink_file_and_test(p); this->unlink_file_and_test(src);
} }
TYPED_TEST(fuse_test, ftruncate_expand_open_fd_zero_fills) { TYPED_TEST(fuse_test, ftruncate_expand_file_is_zero_filled) {
if (this->current_provider != provider_type::sia) std::string name{"ftruncate"};
return; auto src = this->create_file_and_test(name);
this->overwrite_text(src, "AA");
std::string name{"ftrunc_expand"}; auto desc = ::open(src.c_str(), O_RDWR);
std::string p = this->create_file_and_test(name); ASSERT_NE(desc, -1);
this->overwrite_text(p, "AA"); // 2 bytes
int fd = ::open(p.c_str(), O_RDWR);
ASSERT_NE(fd, -1);
errno = 0; errno = 0;
ASSERT_EQ(0, ::ftruncate(fd, 6)) << std::strerror(errno); ASSERT_EQ(0, ::ftruncate(desc, 6));
::close(fd); ::close(desc);
EXPECT_EQ(6, this->stat_size(p)); EXPECT_EQ(6, this->stat_size(src));
auto s = this->slurp(p); auto data = this->slurp(src);
ASSERT_EQ(6u, s.size()); ASSERT_EQ(6U, data.size());
EXPECT_EQ('A', s[0]); EXPECT_EQ('A', data.at(0U));
EXPECT_EQ('A', s[1]); EXPECT_EQ('A', data.at(1U));
for (size_t i = 2; i < s.size(); ++i) { for (std::size_t idx = 2; idx < data.size(); ++idx) {
EXPECT_EQ('\0', s[i]) << "byte " << i << " not zero"; EXPECT_EQ('\0', data[idx]);
} }
this->unlink_file_and_test(p); this->unlink_file_and_test(src);
} }
TYPED_TEST(fuse_test, ftruncate_readonly_fd_ebadf) { TYPED_TEST(fuse_test, ftruncate_fails_if_file_is_read_only) {
if (this->current_provider != provider_type::sia) std::string name{"ftruncate"};
return; auto src = this->create_file_and_test(name);
this->overwrite_text(src, "RW");
std::string name{"ftrunc_rofd"}; auto desc = ::open(src.c_str(), O_RDONLY);
std::string p = this->create_file_and_test(name); ASSERT_NE(desc, -1);
this->overwrite_text(p, "RW");
int fd = ::open(p.c_str(), O_RDONLY);
ASSERT_NE(fd, -1);
errno = 0; errno = 0;
EXPECT_EQ(-1, ::ftruncate(fd, 1)); EXPECT_EQ(-1, ::ftruncate(desc, 1));
EXPECT_EQ(EBADF, errno); EXPECT_EQ(EBADF, errno);
::close(fd); ::close(desc);
this->unlink_file_and_test(p); this->unlink_file_and_test(src);
} }
/*
// TODO revisit tests
TYPED_TEST(fuse_test, ftruncate_on_ro_mount_erofs_or_skip) { TYPED_TEST(fuse_test, ftruncate_on_ro_mount_erofs_or_skip) {
if (this->current_provider != provider_type::sia) if (this->current_provider != provider_type::sia)
return; return;
@@ -188,27 +176,26 @@ TYPED_TEST(fuse_test, ftruncate_on_ro_mount_erofs_or_skip) {
std::string p = this->create_file_and_test(name); std::string p = this->create_file_and_test(name);
this->overwrite_text(p, "X"); this->overwrite_text(p, "X");
int fd = ::open(p.c_str(), O_RDWR); int desc = ::open(p.c_str(), O_RDWR);
if (fd == -1) { if (desc == -1) {
this->unlink_file_and_test(p); this->unlink_file_and_test(p);
GTEST_SKIP() << "cannot open O_RDWR; probable RO mount"; GTEST_SKIP() << "cannot open O_RDWR; probable RO mount";
} }
errno = 0; errno = 0;
int res = ::ftruncate(fd, 0); int res = ::ftruncate(desc, 0);
if (res == -1 && errno == EROFS) { if (res == -1 && errno == EROFS) {
::close(fd); ::close(desc);
this->unlink_file_and_test(p); this->unlink_file_and_test(p);
GTEST_SKIP() << "read-only mount; ftruncate returns EROFS"; GTEST_SKIP() << "read-only mount; ftruncate returns EROFS";
} }
ASSERT_EQ(0, res) << std::strerror(errno); ASSERT_EQ(0, res) << std::strerror(errno);
::close(fd); ::close(desc);
this->unlink_file_and_test(p); this->unlink_file_and_test(p);
} }
*/ */
} // namespace repertory } // namespace repertory
#endif // !defined(_WIN32) #endif // !defined(_WIN32)