From 61b97f19aa05158b2f10a4cb140d21509ffd2bc4 Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Mon, 2 Jan 2023 19:47:29 +0100 Subject: [PATCH] add test for fsync --- CMakeLists.txt | 1 + src/webfuse/provider.cpp | 42 ++++++++++++++++++++++ src/webfuse/ws/messagereader.cpp | 5 +++ src/webfuse/ws/messagereader.hpp | 1 + test-src/integration/test_fsync.cpp | 56 +++++++++++++++++++++++++++++ 5 files changed, 105 insertions(+) create mode 100644 test-src/integration/test_fsync.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d7a5868..612b79e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,6 +80,7 @@ if(NOT(WITHOUT_TEST)) test-src/integration/test_chmod.cpp test-src/integration/test_chown.cpp test-src/integration/test_truncate.cpp + test-src/integration/test_fsync.cpp ) target_include_directories(integration_tests PRIVATE test-src/integration ${GTEST_INCLUDE_DIRS} ${GMOCK_INCLUDE_DIRS}) diff --git a/src/webfuse/provider.cpp b/src/webfuse/provider.cpp index 5a22771..512baac 100644 --- a/src/webfuse/provider.cpp +++ b/src/webfuse/provider.cpp @@ -82,6 +82,15 @@ public: case request_type::truncate: fs_truncate(reader, writer); break; + case request_type::fsync: + fs_fsync(reader, writer); + break; + case request_type::create: + fs_create(reader, writer); + break; + case request_type::release: + fs_release(reader, writer); + break; case request_type::readdir: fs_readdir(reader, writer); break; @@ -185,6 +194,39 @@ private: writer.write_i32(result); } + void fs_fsync(messagereader & reader, messagewriter & writer) + { + auto const path = reader.read_str(); + auto const is_datasync = reader.read_bool(); + auto const handle = reader.read_u64(); + + auto const result = fs_.fsync(path, is_datasync, handle); + writer.write_i32(result); + } + + void fs_create(messagereader & reader, messagewriter & writer) + { + auto const path = reader.read_str(); + auto const mode = reader.read_mode(); + uint64_t handle = static_cast(-1); + + auto const result = fs_.create(path, mode, handle); + writer.write_i32(result); + if (result == 0) + { + writer.write_u64(handle); + } + } + + void fs_release(messagereader & reader, messagewriter & writer) + { + auto const path = reader.read_str(); + auto const handle = reader.read_u64(); + + auto const result = fs_.release(path, handle); + writer.write_i32(result); + } + void fs_readdir(messagereader & reader, messagewriter & writer) { auto const path = reader.read_str(); diff --git a/src/webfuse/ws/messagereader.cpp b/src/webfuse/ws/messagereader.cpp index 620fec9..6b28a67 100644 --- a/src/webfuse/ws/messagereader.cpp +++ b/src/webfuse/ws/messagereader.cpp @@ -83,6 +83,11 @@ mode_t messagereader::read_mode() return mode.to_mode(); } +bool messagereader::read_bool() +{ + return (1 == read_u8()); +} + uint8_t messagereader::read_u8() { diff --git a/src/webfuse/ws/messagereader.hpp b/src/webfuse/ws/messagereader.hpp index f1b6105..f7c490f 100644 --- a/src/webfuse/ws/messagereader.hpp +++ b/src/webfuse/ws/messagereader.hpp @@ -29,6 +29,7 @@ public: int read_access_mode(); mode_t read_mode(); + bool read_bool(); uint8_t read_u8(); uint32_t read_u32(); uint64_t read_u64(); diff --git a/test-src/integration/test_fsync.cpp b/test-src/integration/test_fsync.cpp new file mode 100644 index 0000000..9117f52 --- /dev/null +++ b/test-src/integration/test_fsync.cpp @@ -0,0 +1,56 @@ +#include "webfuse/webfuse.hpp" +#include "webfuse/test/fixture.hpp" +#include "webfuse/test/filesystem_mock.hpp" + +#include + +#include + +using testing::_; +using testing::Return; +using testing::Invoke; +using testing::AnyNumber; +using testing::AtMost; + +TEST(fsync, success) +{ + bool file_created = false; + + webfuse::filesystem_mock fs; + EXPECT_CALL(fs, access("/",_)).Times(AnyNumber()).WillRepeatedly(Return(0)); + EXPECT_CALL(fs, getattr(_,_)).WillRepeatedly(Invoke([&file_created](std::string const & path, struct stat * attr){ + memset(reinterpret_cast(attr),0, sizeof(struct stat)); + + if (path == "/") + { + attr->st_nlink = 1; + attr->st_mode = S_IFDIR | 0755; + return 0; + } + if ((path == "/some_file") && (file_created)) + { + attr->st_nlink = 1; + attr->st_mode = S_IFREG | 0644; + attr->st_size = 0; + return 0; + } + else + { + return -ENOENT; + } + })); + EXPECT_CALL(fs, create("/some_file", _, _)).WillOnce(Invoke([&file_created](auto const &, auto const, auto &){ + file_created = true; + return 0; + })); + EXPECT_CALL(fs, fsync("/some_file", _, _)).WillOnce(Return(0)); + EXPECT_CALL(fs, release("/some_file", _)).Times(AtMost(1)).WillOnce(Return(0)); + + webfuse::fixture fixture(fs); + auto const path = fixture.get_path() + "/some_file"; + + int fd = creat(path.c_str(), 0644); + ASSERT_LT(0, fd); + ASSERT_EQ(0, ::fsync(fd)); + close(fd); +}