From 2234f69d2de9e2feedf987bfbef827dddec6e399 Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Sun, 1 Jan 2023 14:48:19 +0100 Subject: [PATCH] add readdir test --- CMakeLists.txt | 1 + src/webfuse/provider.cpp | 1 + test-src/integration/test_access.cpp | 28 ++++++-- test-src/integration/test_readdir.cpp | 97 +++++++++++++++++++++++++++ 4 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 test-src/integration/test_readdir.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 359d3f5..f522418 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,7 @@ if(NOT(WITHOUT_TEST)) test-src/integration/webfuse/test/process.cpp test-src/integration/webfuse/test/daemon.cpp test-src/integration/test_access.cpp + test-src/integration/test_readdir.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 1c544e7..cc1eef6 100644 --- a/src/webfuse/provider.cpp +++ b/src/webfuse/provider.cpp @@ -63,6 +63,7 @@ public: break; case request_type::readdir: fs_readdir(reader, writer); + break; default: std::cout << "unknown request: " << ((int) req_type) << std::endl; break; diff --git a/test-src/integration/test_access.cpp b/test-src/integration/test_access.cpp index 68dd7f4..6486c01 100644 --- a/test-src/integration/test_access.cpp +++ b/test-src/integration/test_access.cpp @@ -36,16 +36,36 @@ int fs_getattr (std::string const & path, struct stat * attr) } } -TEST(access, ok_NO_MEMCHECK) +TEST(readdir, existing_file) { webfuse::filesystem_mock fs; EXPECT_CALL(fs, access("/",_)).Times(AnyNumber()).WillRepeatedly(Return(0)); - EXPECT_CALL(fs, access("/foo",_)).WillOnce(Return(0)); + EXPECT_CALL(fs, access("/foo", F_OK)).WillOnce(Return(0)); + EXPECT_CALL(fs, access("/foo", R_OK)).WillOnce(Return(0)); + EXPECT_CALL(fs, access("/foo", W_OK)).WillOnce(Return(0)); + EXPECT_CALL(fs, access("/foo", X_OK)).WillOnce(Return(-EACCES)); EXPECT_CALL(fs, getattr(_,_)).WillRepeatedly(Invoke(fs_getattr)); webfuse::fixture fixture(fs); auto const path = fixture.get_path() + "/foo"; - int const rc = ::access(path.c_str(), F_OK); - ASSERT_EQ(0, rc); + ASSERT_EQ(0, ::access(path.c_str(), F_OK)); + ASSERT_EQ(0, ::access(path.c_str(), R_OK)); + ASSERT_EQ(0, ::access(path.c_str(), W_OK)); + ASSERT_EQ(-1, ::access(path.c_str(), X_OK)); + ASSERT_EQ(EACCES, errno); +} + +TEST(access, non_existing_file) +{ + webfuse::filesystem_mock fs; + EXPECT_CALL(fs, access("/",_)).Times(AnyNumber()).WillRepeatedly(Return(0)); + EXPECT_CALL(fs, access("/foo", F_OK)).WillOnce(Return(-ENOENT)); + EXPECT_CALL(fs, getattr(_,_)).WillRepeatedly(Invoke(fs_getattr)); + + webfuse::fixture fixture(fs); + auto const path = fixture.get_path() + "/foo"; + + ASSERT_EQ(-1, ::access(path.c_str(), F_OK)); + ASSERT_EQ(ENOENT, errno); } diff --git a/test-src/integration/test_readdir.cpp b/test-src/integration/test_readdir.cpp new file mode 100644 index 0000000..638192d --- /dev/null +++ b/test-src/integration/test_readdir.cpp @@ -0,0 +1,97 @@ +#include "webfuse/webfuse.hpp" +#include "webfuse/test/fixture.hpp" +#include "webfuse/test/filesystem_mock.hpp" +#include "webfuse/test/daemon.hpp" + +#include +#include +#include + +#include +#include + +using testing::_; +using testing::Return; +using testing::Invoke; +using testing::AnyNumber; + +TEST(readdir, existing_dir) +{ + webfuse::filesystem_mock fs; + EXPECT_CALL(fs, access("/",_)).Times(AnyNumber()).WillRepeatedly(Return(0)); + EXPECT_CALL(fs, getattr(_,_)).WillRepeatedly(Invoke([](auto const & path, auto * attr){ + memset(reinterpret_cast(attr),0, sizeof(struct stat)); + + if ((path == "/") or (path == "/some_dir")) + { + attr->st_nlink = 1; + attr->st_mode = S_IFDIR | 0755; + return 0; + } + else + { + return -ENOENT; + } + })); + EXPECT_CALL(fs, readdir("/some_dir",_,_)).WillOnce(Invoke([](auto const & path, auto & entries, auto handle) { + entries.push_back("foo"); + return 0; + })); + + webfuse::fixture fixture(fs); + auto const path = fixture.get_path() + "/some_dir"; + + std::unordered_map expected_entries = { + {".", false}, + {"..", false}, + {"foo", false}, + }; + + DIR * dir = opendir(path.c_str()); + ASSERT_NE(nullptr, dir); + dirent * entry = readdir(dir); + int count = 0; + while (nullptr != entry) + { + count++; + + auto it = expected_entries.find(entry->d_name); + ASSERT_NE(expected_entries.end(), it); + ASSERT_FALSE(it->second); + it->second = true; + + entry = readdir(dir); + } + closedir(dir); + + ASSERT_EQ(3, count); +} + +TEST(readdir, non_existing_dir) +{ + webfuse::filesystem_mock fs; + EXPECT_CALL(fs, access("/",_)).Times(AnyNumber()).WillRepeatedly(Return(0)); + EXPECT_CALL(fs, getattr(_,_)).WillRepeatedly(Invoke([](auto const & path, auto * attr){ + memset(reinterpret_cast(attr),0, sizeof(struct stat)); + + if (path == "/") + { + attr->st_nlink = 1; + attr->st_mode = S_IFDIR | 0755; + return 0; + } + else + { + return -ENOENT; + } + })); + EXPECT_CALL(fs, readdir("/some_dir",_,_)).Times(0); + + webfuse::fixture fixture(fs); + auto const path = fixture.get_path() + "/some_dir"; + + DIR * dir = opendir(path.c_str()); + ASSERT_EQ(nullptr, dir); + ASSERT_EQ(ENOENT, errno); +} +