diff --git a/cmake/unit_tests.cmake b/cmake/unit_tests.cmake index b5ae7ad..1301b15 100644 --- a/cmake/unit_tests.cmake +++ b/cmake/unit_tests.cmake @@ -7,6 +7,7 @@ include(GoogleTest) pkg_check_modules(GMOCK gmock) add_executable(alltests + test/tempdir.cc test/msleep.cc test/die_if.cc test/mock_authenticator.cc @@ -27,6 +28,7 @@ add_executable(alltests test/adapter/test_authenticator.cc test/adapter/test_authenticators.cc test/adapter/test_mountpoint.cc + test/adapter/test_uuid_mountpoint.cc test/adapter/test_fuse_req.cc test/adapter/jsonrpc/test_util.cc test/adapter/jsonrpc/test_is_request.cc diff --git a/lib/webfuse/adapter/impl/uuid_mountpoint.c b/lib/webfuse/adapter/impl/uuid_mountpoint.c index 1b0cd8a..eafa444 100644 --- a/lib/webfuse/adapter/impl/uuid_mountpoint.c +++ b/lib/webfuse/adapter/impl/uuid_mountpoint.c @@ -82,11 +82,11 @@ wf_impl_uuid_mountpoint_data_dispose( rmdir(data->full_path); - if (wf_impl_filesystem_is_link_broken(data->default_path, data->id)) + if (wf_impl_uuid_mountpoint_is_link_broken(data->default_path, data->id)) { unlink(data->default_path); - bool const success = wf_impl_filesystem_link_first_subdir(data->default_path, data->filesystem_path); + bool const success = wf_impl_uuid_mountpoint_link_first_subdir(data->default_path, data->filesystem_path); if (!success) { rmdir(data->filesystem_path); @@ -110,13 +110,13 @@ wf_impl_uuid_mountpoint_create( mkdir(data->filesystem_path, 0755); data->id = wf_impl_uuid_mountpoint_create_id(); - char * full_path = wf_create_string("%s/%s/%s", root_path, filesystem, data->id); + data->full_path = wf_create_string("%s/%s/%s", root_path, filesystem, data->id); mkdir(data->full_path, 0755); - data->default_path = wf_create_string("%s/%s/default", root_path, data->filesystem_path); + data->default_path = wf_create_string("%s/%s/default", root_path, filesystem); symlink(data->id, data->default_path); - struct wf_mountpoint * mountpoint = wf_impl_mountpoint_create(full_path); + struct wf_mountpoint * mountpoint = wf_impl_mountpoint_create(data->full_path); wf_impl_mountpoint_set_userdata(mountpoint, data, &wf_impl_uuid_mountpoint_data_dispose); return mountpoint; diff --git a/test/adapter/test_uuid_mountpoint.cc b/test/adapter/test_uuid_mountpoint.cc new file mode 100644 index 0000000..cfa4000 --- /dev/null +++ b/test/adapter/test_uuid_mountpoint.cc @@ -0,0 +1,102 @@ +#include + +#include +#include +#include + +#include "tempdir.hpp" +#include "webfuse_adapter.h" +#include "webfuse/adapter/impl/uuid_mountpoint.h" + +#include + +using webfuse_test::TempDir; + +namespace +{ + bool is_dir(std::string const & path) + { + struct stat info; + int rc = stat(path.c_str(), &info); + + return (0 == rc) && (S_ISDIR(info.st_mode)); + } + + bool is_symlink(std::string const & path) + { + struct stat info; + int rc = lstat(path.c_str(), &info); + + return (0 == rc) && (S_ISLNK(info.st_mode)); + } + + bool is_same_path(std::string const & path, std::string const & other) + { + struct stat info; + int rc = stat(path.c_str(), &info); + + struct stat info_other; + int rc_other = stat(other.c_str(), &info_other); + + return (0 == rc) && (0 == rc_other) && (info.st_ino == info_other.st_ino); + } +} + +TEST(uuid_mountpoint, create) +{ + TempDir temp("uuid_mountpoint"); + + std::string filesystem_path = std::string(temp.path()) + "/dummy"; + std::string default_path = std::string(temp.path()) + "/dummy/default"; + + wf_mountpoint * mountpoint = wf_impl_uuid_mountpoint_create(temp.path(), "dummy"); + std::string path = wf_mountpoint_get_path(mountpoint); + ASSERT_NE(nullptr, mountpoint); + ASSERT_TRUE(is_dir(filesystem_path)); + ASSERT_TRUE(is_symlink(default_path)); + ASSERT_TRUE(is_dir(default_path)); + ASSERT_TRUE(is_dir(path)); + ASSERT_TRUE(is_same_path(default_path, path)); + + wf_mountpoint_dispose(mountpoint); + ASSERT_FALSE(is_dir(filesystem_path)); + ASSERT_FALSE(is_symlink(default_path)); + ASSERT_FALSE(is_dir(default_path)); + ASSERT_FALSE(is_dir(path)); +} + +TEST(uuid_mountpoint, relink_default) +{ + TempDir temp("uuid_mountpoint"); + + std::string filesystem_path = std::string(temp.path()) + "/dummy"; + std::string default_path = std::string(temp.path()) + "/dummy/default"; + + wf_mountpoint * mountpoint_a = wf_impl_uuid_mountpoint_create(temp.path(), "dummy"); + std::string path_a = wf_mountpoint_get_path(mountpoint_a); + + wf_mountpoint * mountpoint_b = wf_impl_uuid_mountpoint_create(temp.path(), "dummy"); + std::string path_b = wf_mountpoint_get_path(mountpoint_b); + + ASSERT_TRUE(is_dir(filesystem_path)); + ASSERT_TRUE(is_symlink(default_path)); + ASSERT_TRUE(is_dir(default_path)); + ASSERT_TRUE(is_dir(path_a)); + ASSERT_TRUE(is_dir(path_b)); + ASSERT_TRUE(is_same_path(default_path, path_a)); + + wf_mountpoint_dispose(mountpoint_a); + ASSERT_TRUE(is_dir(filesystem_path)); + ASSERT_TRUE(is_symlink(default_path)); + ASSERT_TRUE(is_dir(default_path)); + ASSERT_FALSE(is_dir(path_a)); + ASSERT_TRUE(is_dir(path_b)); + ASSERT_TRUE(is_same_path(default_path, path_b)); + + wf_mountpoint_dispose(mountpoint_b); + ASSERT_FALSE(is_dir(filesystem_path)); + ASSERT_FALSE(is_symlink(default_path)); + ASSERT_FALSE(is_dir(default_path)); + ASSERT_FALSE(is_dir(path_a)); + ASSERT_FALSE(is_dir(path_b)); +} diff --git a/test/tempdir.cc b/test/tempdir.cc new file mode 100644 index 0000000..040aed1 --- /dev/null +++ b/test/tempdir.cc @@ -0,0 +1,33 @@ +#include "webfuse/core/string.h" +#include "tempdir.hpp" + +#include +#include +#include + +namespace webfuse_test +{ + +TempDir::TempDir(char const * prefix) +: path_(wf_create_string("/tmp/%s_XXXXXX", prefix)) +{ + char * result = mkdtemp(path_); + if (NULL == result) + { + throw std::runtime_error("unable to create temp dir"); + } +} + +TempDir::~TempDir() +{ + rmdir(path_); + free(path_); +} + +char const * TempDir::path() +{ + return path_; +} + + +} \ No newline at end of file diff --git a/test/tempdir.hpp b/test/tempdir.hpp new file mode 100644 index 0000000..0c28a80 --- /dev/null +++ b/test/tempdir.hpp @@ -0,0 +1,21 @@ +#ifndef WF_TEST_TEMPDIR_HPP +#define WF_TEST_TEMPDIR_HPP + +namespace webfuse_test +{ + +class TempDir +{ + TempDir(TempDir const &) = delete; + TempDir & operator=(TempDir const &) = delete; +public: + TempDir(char const * prefix); + ~TempDir(); + char const * path(); +private: + char * path_; +}; + +} + +#endif