Changeset View
Changeset View
Standalone View
Standalone View
head/tests/sys/fs/fusefs/rmdir.cc
Show All 36 Lines | |||||
#include "mockfs.hh" | #include "mockfs.hh" | ||||
#include "utils.hh" | #include "utils.hh" | ||||
using namespace testing; | using namespace testing; | ||||
class Rmdir: public FuseTest { | class Rmdir: public FuseTest { | ||||
public: | public: | ||||
void expect_getattr(uint64_t ino, mode_t mode) | |||||
{ | |||||
EXPECT_CALL(*m_mock, process( | |||||
ResultOf([=](auto in) { | |||||
return (in.header.opcode == FUSE_GETATTR && | |||||
in.header.nodeid == ino); | |||||
}, Eq(true)), | |||||
_) | |||||
).WillOnce(Invoke(ReturnImmediate([=](auto i __unused, auto& out) { | |||||
SET_OUT_HEADER_LEN(out, attr); | |||||
out.body.attr.attr.ino = ino; // Must match nodeid | |||||
out.body.attr.attr.mode = mode; | |||||
out.body.attr.attr_valid = UINT64_MAX; | |||||
}))); | |||||
} | |||||
void expect_lookup(const char *relpath, uint64_t ino, int times=1) | void expect_lookup(const char *relpath, uint64_t ino, int times=1) | ||||
{ | { | ||||
EXPECT_LOOKUP(FUSE_ROOT_ID, relpath) | EXPECT_LOOKUP(FUSE_ROOT_ID, relpath) | ||||
.Times(times) | .Times(times) | ||||
.WillRepeatedly(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { | .WillRepeatedly(Invoke(ReturnImmediate([=](auto in __unused, auto& out) { | ||||
SET_OUT_HEADER_LEN(out, entry); | SET_OUT_HEADER_LEN(out, entry); | ||||
out.body.entry.attr_valid = UINT64_MAX; | out.body.entry.attr_valid = UINT64_MAX; | ||||
out.body.entry.attr.mode = S_IFDIR | 0755; | out.body.entry.attr.mode = S_IFDIR | 0755; | ||||
Show All 21 Lines | |||||
*/ | */ | ||||
TEST_F(Rmdir, parent_attr_cache) | TEST_F(Rmdir, parent_attr_cache) | ||||
{ | { | ||||
const char FULLPATH[] = "mountpoint/some_dir"; | const char FULLPATH[] = "mountpoint/some_dir"; | ||||
const char RELPATH[] = "some_dir"; | const char RELPATH[] = "some_dir"; | ||||
struct stat sb; | struct stat sb; | ||||
sem_t sem; | sem_t sem; | ||||
uint64_t ino = 42; | uint64_t ino = 42; | ||||
Sequence seq; | |||||
ASSERT_EQ(0, sem_init(&sem, 0, 0)) << strerror(errno); | ASSERT_EQ(0, sem_init(&sem, 0, 0)) << strerror(errno); | ||||
expect_lookup(RELPATH, ino); | |||||
EXPECT_CALL(*m_mock, process( | EXPECT_CALL(*m_mock, process( | ||||
ResultOf([=](auto in) { | ResultOf([=](auto in) { | ||||
return (in.header.opcode == FUSE_RMDIR && | |||||
0 == strcmp(RELPATH, in.body.rmdir) && | |||||
in.header.nodeid == FUSE_ROOT_ID); | |||||
}, Eq(true)), | |||||
_) | |||||
).InSequence(seq) | |||||
.WillOnce(Invoke(ReturnErrno(0))); | |||||
expect_forget(ino, 1, &sem); | |||||
EXPECT_CALL(*m_mock, process( | |||||
ResultOf([=](auto in) { | |||||
return (in.header.opcode == FUSE_GETATTR && | return (in.header.opcode == FUSE_GETATTR && | ||||
in.header.nodeid == FUSE_ROOT_ID); | in.header.nodeid == FUSE_ROOT_ID); | ||||
}, Eq(true)), | }, Eq(true)), | ||||
_) | _) | ||||
).Times(2) | ).InSequence(seq) | ||||
.WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto& out) { | .WillRepeatedly(Invoke(ReturnImmediate([=](auto i __unused, auto& out) { | ||||
SET_OUT_HEADER_LEN(out, attr); | SET_OUT_HEADER_LEN(out, attr); | ||||
out.body.attr.attr.ino = ino; // Must match nodeid | out.body.attr.attr.ino = FUSE_ROOT_ID; | ||||
out.body.attr.attr.mode = S_IFDIR | 0755; | out.body.attr.attr.mode = S_IFDIR | 0755; | ||||
out.body.attr.attr_valid = UINT64_MAX; | out.body.attr.attr_valid = UINT64_MAX; | ||||
}))); | }))); | ||||
expect_lookup(RELPATH, ino); | |||||
expect_rmdir(FUSE_ROOT_ID, RELPATH, 0); | |||||
expect_forget(ino, 1, &sem); | |||||
ASSERT_EQ(0, rmdir(FULLPATH)) << strerror(errno); | ASSERT_EQ(0, rmdir(FULLPATH)) << strerror(errno); | ||||
EXPECT_EQ(0, stat("mountpoint", &sb)) << strerror(errno); | EXPECT_EQ(0, stat("mountpoint", &sb)) << strerror(errno); | ||||
sem_wait(&sem); | sem_wait(&sem); | ||||
sem_destroy(&sem); | sem_destroy(&sem); | ||||
} | } | ||||
TEST_F(Rmdir, enotempty) | TEST_F(Rmdir, enotempty) | ||||
{ | { | ||||
const char FULLPATH[] = "mountpoint/some_dir"; | const char FULLPATH[] = "mountpoint/some_dir"; | ||||
const char RELPATH[] = "some_dir"; | const char RELPATH[] = "some_dir"; | ||||
uint64_t ino = 42; | uint64_t ino = 42; | ||||
expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755); | |||||
expect_lookup(RELPATH, ino); | expect_lookup(RELPATH, ino); | ||||
expect_rmdir(FUSE_ROOT_ID, RELPATH, ENOTEMPTY); | expect_rmdir(FUSE_ROOT_ID, RELPATH, ENOTEMPTY); | ||||
ASSERT_NE(0, rmdir(FULLPATH)); | ASSERT_NE(0, rmdir(FULLPATH)); | ||||
ASSERT_EQ(ENOTEMPTY, errno); | ASSERT_EQ(ENOTEMPTY, errno); | ||||
} | } | ||||
/* Removing a directory should expire its entry cache */ | /* Removing a directory should expire its entry cache */ | ||||
TEST_F(Rmdir, entry_cache) | TEST_F(Rmdir, entry_cache) | ||||
{ | { | ||||
const char FULLPATH[] = "mountpoint/some_dir"; | const char FULLPATH[] = "mountpoint/some_dir"; | ||||
const char RELPATH[] = "some_dir"; | const char RELPATH[] = "some_dir"; | ||||
sem_t sem; | sem_t sem; | ||||
uint64_t ino = 42; | uint64_t ino = 42; | ||||
expect_getattr(1, S_IFDIR | 0755); | |||||
expect_lookup(RELPATH, ino, 2); | expect_lookup(RELPATH, ino, 2); | ||||
expect_rmdir(FUSE_ROOT_ID, RELPATH, 0); | expect_rmdir(FUSE_ROOT_ID, RELPATH, 0); | ||||
expect_forget(ino, 1, &sem); | expect_forget(ino, 1, &sem); | ||||
ASSERT_EQ(0, rmdir(FULLPATH)) << strerror(errno); | ASSERT_EQ(0, rmdir(FULLPATH)) << strerror(errno); | ||||
ASSERT_EQ(0, access(FULLPATH, F_OK)) << strerror(errno); | ASSERT_EQ(0, access(FULLPATH, F_OK)) << strerror(errno); | ||||
sem_wait(&sem); | sem_wait(&sem); | ||||
sem_destroy(&sem); | sem_destroy(&sem); | ||||
} | } | ||||
TEST_F(Rmdir, ok) | TEST_F(Rmdir, ok) | ||||
{ | { | ||||
const char FULLPATH[] = "mountpoint/some_dir"; | const char FULLPATH[] = "mountpoint/some_dir"; | ||||
const char RELPATH[] = "some_dir"; | const char RELPATH[] = "some_dir"; | ||||
sem_t sem; | sem_t sem; | ||||
uint64_t ino = 42; | uint64_t ino = 42; | ||||
ASSERT_EQ(0, sem_init(&sem, 0, 0)) << strerror(errno); | ASSERT_EQ(0, sem_init(&sem, 0, 0)) << strerror(errno); | ||||
expect_getattr(FUSE_ROOT_ID, S_IFDIR | 0755); | |||||
expect_lookup(RELPATH, ino); | expect_lookup(RELPATH, ino); | ||||
expect_rmdir(FUSE_ROOT_ID, RELPATH, 0); | expect_rmdir(FUSE_ROOT_ID, RELPATH, 0); | ||||
expect_forget(ino, 1, &sem); | expect_forget(ino, 1, &sem); | ||||
ASSERT_EQ(0, rmdir(FULLPATH)) << strerror(errno); | ASSERT_EQ(0, rmdir(FULLPATH)) << strerror(errno); | ||||
sem_wait(&sem); | sem_wait(&sem); | ||||
sem_destroy(&sem); | sem_destroy(&sem); | ||||
} | } |