diff --git a/src/fspp/fuse/Filesystem.h b/src/fspp/fuse/Filesystem.h index 015e3cff..075b88b8 100644 --- a/src/fspp/fuse/Filesystem.h +++ b/src/fspp/fuse/Filesystem.h @@ -26,8 +26,8 @@ public: virtual void fsync(int descriptor) = 0; virtual void fdatasync(int descriptor) = 0; virtual void access(const boost::filesystem::path &path, int mask) = 0; - //TODO Unit-Tests for all functions below virtual void mkdir(const boost::filesystem::path &path, mode_t mode) = 0; + //TODO Unit-Tests for all functions below virtual void rmdir(const boost::filesystem::path &path) = 0; virtual void unlink(const boost::filesystem::path &path) = 0; virtual void rename(const boost::filesystem::path &from, const boost::filesystem::path &to) = 0; diff --git a/src/test/fspp/fuse/mkdir/FuseMkdirDirnameTest.cpp b/src/test/fspp/fuse/mkdir/FuseMkdirDirnameTest.cpp new file mode 100644 index 00000000..3d064c94 --- /dev/null +++ b/src/test/fspp/fuse/mkdir/FuseMkdirDirnameTest.cpp @@ -0,0 +1,46 @@ +#include "testutils/FuseMkdirTest.h" +#include "gtest/gtest.h" +#include "gmock/gmock.h" + + +using ::testing::_; +using ::testing::StrEq; +using ::testing::Return; +using ::testing::Invoke; +using ::testing::Action; + +class FuseMkdirDirnameTest: public FuseMkdirTest { +}; + +TEST_F(FuseMkdirDirnameTest, Mkdir) { + ReturnDoesntExistOnLstat("/mydir"); + EXPECT_CALL(fsimpl, mkdir(StrEq("/mydir"), _)) + // After mkdir was called, lstat should return that it is a dir. + // This is needed to make the ::mkdir() syscall pass. + .Times(1).WillOnce(FromNowOnReturnIsDirOnLstat()); + + Mkdir("/mydir", 0); +} + +TEST_F(FuseMkdirDirnameTest, MkdirNested) { + ReturnIsDirOnLstat("/mydir"); + ReturnDoesntExistOnLstat("/mydir/mysubdir"); + EXPECT_CALL(fsimpl, mkdir(StrEq("/mydir/mysubdir"), _)) + // After mkdir was called, lstat should return that it is a dir. + // This is needed to make the ::mkdir() syscall pass. + .Times(1).WillOnce(FromNowOnReturnIsDirOnLstat()); + + Mkdir("/mydir/mysubdir", 0); +} + +TEST_F(FuseMkdirDirnameTest, MkdirNested2) { + ReturnIsDirOnLstat("/mydir"); + ReturnIsDirOnLstat("/mydir/mydir2"); + ReturnDoesntExistOnLstat("/mydir/mydir2/mydir3"); + EXPECT_CALL(fsimpl, mkdir(StrEq("/mydir/mydir2/mydir3"), _)) + // After mkdir was called, lstat should return that it is a dir. + // This is needed to make the ::mkdir() syscall pass. + .Times(1).WillOnce(FromNowOnReturnIsDirOnLstat()); + + Mkdir("/mydir/mydir2/mydir3", 0); +} diff --git a/src/test/fspp/fuse/mkdir/FuseMkdirErrorTest.cpp b/src/test/fspp/fuse/mkdir/FuseMkdirErrorTest.cpp new file mode 100644 index 00000000..0e4d03a4 --- /dev/null +++ b/src/test/fspp/fuse/mkdir/FuseMkdirErrorTest.cpp @@ -0,0 +1,27 @@ +#include "testutils/FuseMkdirTest.h" +#include "gtest/gtest.h" +#include "gmock/gmock.h" + +#include "fspp/fuse/FuseErrnoException.h" + +using ::testing::_; +using ::testing::StrEq; +using ::testing::Throw; +using ::testing::WithParamInterface; +using ::testing::Values; + +using namespace fspp::fuse; + +class FuseMkdirErrorTest: public FuseMkdirTest, public WithParamInterface { +}; +INSTANTIATE_TEST_CASE_P(FuseMkdirErrorTest, FuseMkdirErrorTest, Values(EACCES, EDQUOT, EEXIST, EFAULT, ELOOP, EMLINK, ENAMETOOLONG, ENOENT, ENOMEM, ENOSPC, ENOTDIR, EPERM, EROFS, EBADF)); + +TEST_P(FuseMkdirErrorTest, ReturnedErrorIsCorrect) { + ReturnDoesntExistOnLstat(DIRNAME); + EXPECT_CALL(fsimpl, mkdir(StrEq(DIRNAME), _)) + .Times(1).WillOnce(Throw(FuseErrnoException(GetParam()))); + + int retval = MkdirAllowError(DIRNAME, 0); + EXPECT_EQ(GetParam(), errno); + EXPECT_EQ(-1, retval); +} diff --git a/src/test/fspp/fuse/mkdir/FuseMkdirModeTest.cpp b/src/test/fspp/fuse/mkdir/FuseMkdirModeTest.cpp new file mode 100644 index 00000000..46368f03 --- /dev/null +++ b/src/test/fspp/fuse/mkdir/FuseMkdirModeTest.cpp @@ -0,0 +1,23 @@ +#include "testutils/FuseMkdirTest.h" +#include "gtest/gtest.h" +#include "gmock/gmock.h" + + +using ::testing::_; +using ::testing::StrEq; +using ::testing::Return; +using ::testing::WithParamInterface; +using ::testing::Values; + +class FuseMkdirModeTest: public FuseMkdirTest, public WithParamInterface { +}; +INSTANTIATE_TEST_CASE_P(FuseMkdirModeTest, FuseMkdirModeTest, Values(0, S_IRUSR, S_IRGRP, S_IXOTH, S_IRUSR|S_IRGRP|S_IROTH|S_IRGRP)); + + +TEST_P(FuseMkdirModeTest, Mkdir) { + ReturnDoesntExistOnLstat(DIRNAME); + EXPECT_CALL(fsimpl, mkdir(StrEq(DIRNAME), GetParam())) + .Times(1).WillOnce(FromNowOnReturnIsDirOnLstat()); + + Mkdir(DIRNAME, GetParam()); +} diff --git a/src/test/fspp/fuse/mkdir/testutils/FuseMkdirTest.cpp b/src/test/fspp/fuse/mkdir/testutils/FuseMkdirTest.cpp new file mode 100644 index 00000000..33f5dc45 --- /dev/null +++ b/src/test/fspp/fuse/mkdir/testutils/FuseMkdirTest.cpp @@ -0,0 +1,22 @@ +#include + +using ::testing::Action; +using ::testing::Invoke; + +void FuseMkdirTest::Mkdir(const char *dirname, mode_t mode) { + int retval = MkdirAllowError(dirname, mode); + EXPECT_EQ(0, retval); +} + +int FuseMkdirTest::MkdirAllowError(const char *dirname, mode_t mode) { + auto fs = TestFS(); + + auto realpath = fs->mountDir() / dirname; + return ::mkdir(realpath.c_str(), mode); +} + +Action FuseMkdirTest::FromNowOnReturnIsDirOnLstat() { + return Invoke([this](const char *filename, mode_t) { + ReturnIsDirOnLstat(filename); + }); +} diff --git a/src/test/fspp/fuse/mkdir/testutils/FuseMkdirTest.h b/src/test/fspp/fuse/mkdir/testutils/FuseMkdirTest.h new file mode 100644 index 00000000..ec861a90 --- /dev/null +++ b/src/test/fspp/fuse/mkdir/testutils/FuseMkdirTest.h @@ -0,0 +1,17 @@ +#pragma once +#ifndef TEST_FSPP_FUSE_MKDIR_TESTUTILS_FUSEMKDIRTEST_H_ +#define TEST_FSPP_FUSE_MKDIR_TESTUTILS_FUSEMKDIRTEST_H_ + +#include "test/testutils/FuseTest.h" + +class FuseMkdirTest: public FuseTest { +public: + const char *DIRNAME = "/mydir"; + + void Mkdir(const char *dirname, mode_t mode); + int MkdirAllowError(const char *dirname, mode_t mode); + + ::testing::Action FromNowOnReturnIsDirOnLstat(); +}; + +#endif