Use FUSE_STAT on Dokan
This commit is contained in:
parent
61451069e8
commit
a866fda3a9
@ -11,6 +11,7 @@
|
|||||||
#else
|
#else
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include "stat_compatibility.h"
|
||||||
|
|
||||||
namespace fspp {
|
namespace fspp {
|
||||||
namespace fuse {
|
namespace fuse {
|
||||||
@ -23,8 +24,8 @@ public:
|
|||||||
virtual int openFile(const boost::filesystem::path &path, int flags) = 0;
|
virtual int openFile(const boost::filesystem::path &path, int flags) = 0;
|
||||||
virtual void flush(int descriptor) = 0;
|
virtual void flush(int descriptor) = 0;
|
||||||
virtual void closeFile(int descriptor) = 0;
|
virtual void closeFile(int descriptor) = 0;
|
||||||
virtual void lstat(const boost::filesystem::path &path, struct ::stat *stbuf) = 0;
|
virtual void lstat(const boost::filesystem::path &path, fspp::fuse::STAT *stbuf) = 0;
|
||||||
virtual void fstat(int descriptor, struct ::stat *stbuf) = 0;
|
virtual void fstat(int descriptor, fspp::fuse::STAT *stbuf) = 0;
|
||||||
//TODO Test chmod
|
//TODO Test chmod
|
||||||
virtual void chmod(const boost::filesystem::path &path, ::mode_t mode) = 0;
|
virtual void chmod(const boost::filesystem::path &path, ::mode_t mode) = 0;
|
||||||
//TODO Test chown
|
//TODO Test chown
|
||||||
|
@ -31,12 +31,12 @@ bool is_valid_fspp_path(const bf::path& path) {
|
|||||||
//#define FSPP_LOG 1
|
//#define FSPP_LOG 1
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
int fusepp_getattr(const char *path, struct stat *stbuf) {
|
int fusepp_getattr(const char *path, fspp::fuse::STAT *stbuf) {
|
||||||
int rs = FUSE_OBJ->getattr(bf::path(path), stbuf);
|
int rs = FUSE_OBJ->getattr(bf::path(path), stbuf);
|
||||||
return rs;
|
return rs;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fusepp_fgetattr(const char *path, struct stat *stbuf, fuse_file_info *fileinfo) {
|
int fusepp_fgetattr(const char *path, fspp::fuse::STAT *stbuf, fuse_file_info *fileinfo) {
|
||||||
return FUSE_OBJ->fgetattr(bf::path(path), stbuf, fileinfo);
|
return FUSE_OBJ->fgetattr(bf::path(path), stbuf, fileinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,7 +309,7 @@ void Fuse::stop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Fuse::getattr(const bf::path &path, struct stat *stbuf) {
|
int Fuse::getattr(const bf::path &path, fspp::fuse::STAT *stbuf) {
|
||||||
#ifdef FSPP_LOG
|
#ifdef FSPP_LOG
|
||||||
LOG(DEBUG, "getattr({}, _, _)", path);
|
LOG(DEBUG, "getattr({}, _, _)", path);
|
||||||
#endif
|
#endif
|
||||||
@ -331,7 +331,7 @@ int Fuse::getattr(const bf::path &path, struct stat *stbuf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Fuse::fgetattr(const bf::path &path, struct stat *stbuf, fuse_file_info *fileinfo) {
|
int Fuse::fgetattr(const bf::path &path, fspp::fuse::STAT *stbuf, fuse_file_info *fileinfo) {
|
||||||
#ifdef FSPP_LOG
|
#ifdef FSPP_LOG
|
||||||
LOG(DEBUG, "fgetattr({}, _, _)\n", path);
|
LOG(DEBUG, "fgetattr({}, _, _)\n", path);
|
||||||
#endif
|
#endif
|
||||||
@ -801,7 +801,7 @@ int Fuse::readdir(const bf::path &path, void *buf, fuse_fill_dir_t filler, int64
|
|||||||
try {
|
try {
|
||||||
ASSERT(is_valid_fspp_path(path), "has to be an absolute path");
|
ASSERT(is_valid_fspp_path(path), "has to be an absolute path");
|
||||||
auto entries = _fs->readDir(path);
|
auto entries = _fs->readDir(path);
|
||||||
struct stat stbuf{};
|
fspp::fuse::STAT stbuf{};
|
||||||
for (const auto &entry : *entries) {
|
for (const auto &entry : *entries) {
|
||||||
//We could pass more file metadata to filler() in its third parameter,
|
//We could pass more file metadata to filler() in its third parameter,
|
||||||
//but it doesn't help performance since fuse ignores everything in stbuf
|
//but it doesn't help performance since fuse ignores everything in stbuf
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <cpp-utils/macros.h>
|
#include <cpp-utils/macros.h>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include "stat_compatibility.h"
|
||||||
|
|
||||||
namespace fspp {
|
namespace fspp {
|
||||||
class Device;
|
class Device;
|
||||||
@ -27,8 +28,8 @@ public:
|
|||||||
bool running() const;
|
bool running() const;
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
int getattr(const boost::filesystem::path &path, struct stat *stbuf);
|
int getattr(const boost::filesystem::path &path, fspp::fuse::STAT *stbuf);
|
||||||
int fgetattr(const boost::filesystem::path &path, struct stat *stbuf, fuse_file_info *fileinfo);
|
int fgetattr(const boost::filesystem::path &path, fspp::fuse::STAT *stbuf, fuse_file_info *fileinfo);
|
||||||
int readlink(const boost::filesystem::path &path, char *buf, size_t size);
|
int readlink(const boost::filesystem::path &path, char *buf, size_t size);
|
||||||
int mknod(const boost::filesystem::path &path, ::mode_t mode, dev_t rdev);
|
int mknod(const boost::filesystem::path &path, ::mode_t mode, dev_t rdev);
|
||||||
int mkdir(const boost::filesystem::path &path, ::mode_t mode);
|
int mkdir(const boost::filesystem::path &path, ::mode_t mode);
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#include <fuse.h>
|
#include <fuse.h>
|
||||||
#elif __APPLE__
|
#elif __APPLE__
|
||||||
#include <osxfuse/fuse.h>
|
#include <osxfuse/fuse.h>
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#include <fuse.h> // Dokany fuse
|
||||||
#else
|
#else
|
||||||
#error System not supported
|
#error System not supported
|
||||||
#endif
|
#endif
|
||||||
|
27
src/fspp/fuse/stat_compatibility.h
Normal file
27
src/fspp/fuse/stat_compatibility.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef MESSMER_FSPP_FUSE_STATCOMPATIBILITY_H
|
||||||
|
#define MESSMER_FSPP_FUSE_STATCOMPATIBILITY_H
|
||||||
|
|
||||||
|
namespace fspp {
|
||||||
|
namespace fuse {
|
||||||
|
|
||||||
|
// Dokan has a different "struct stat" called "fspp::fuse::STAT", but it's compatible.
|
||||||
|
// To make our code work with both, we use "STAT" everywhere instead of "stat"
|
||||||
|
// and define it here to the correct type
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
|
||||||
|
#include <fuse.h>
|
||||||
|
typedef struct FUSE_STAT STAT;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
typedef struct ::stat STAT;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -139,7 +139,7 @@ void FilesystemImpl::closeFile(int descriptor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void convert_stat_info_(const fspp::Node::stat_info& input, struct ::stat *output) {
|
void convert_stat_info_(const fspp::Node::stat_info& input, fspp::fuse::STAT *output) {
|
||||||
output->st_nlink = input.nlink;
|
output->st_nlink = input.nlink;
|
||||||
output->st_mode = input.mode.value();
|
output->st_mode = input.mode.value();
|
||||||
output->st_uid = input.uid.value();
|
output->st_uid = input.uid.value();
|
||||||
@ -152,7 +152,7 @@ void convert_stat_info_(const fspp::Node::stat_info& input, struct ::stat *outpu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilesystemImpl::lstat(const bf::path &path, struct ::stat *stbuf) {
|
void FilesystemImpl::lstat(const bf::path &path, fspp::fuse::STAT *stbuf) {
|
||||||
PROFILE(_lstatNanosec);
|
PROFILE(_lstatNanosec);
|
||||||
auto node = _device->Load(path);
|
auto node = _device->Load(path);
|
||||||
if(node == none) {
|
if(node == none) {
|
||||||
@ -163,7 +163,7 @@ void FilesystemImpl::lstat(const bf::path &path, struct ::stat *stbuf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilesystemImpl::fstat(int descriptor, struct ::stat *stbuf) {
|
void FilesystemImpl::fstat(int descriptor, fspp::fuse::STAT *stbuf) {
|
||||||
PROFILE(_fstatNanosec);
|
PROFILE(_fstatNanosec);
|
||||||
auto stat_info = _open_files.get(descriptor)->stat();
|
auto stat_info = _open_files.get(descriptor)->stat();
|
||||||
convert_stat_info_(stat_info, stbuf);
|
convert_stat_info_(stat_info, stbuf);
|
||||||
|
@ -27,8 +27,8 @@ public:
|
|||||||
int openFile(const boost::filesystem::path &path, int flags) override;
|
int openFile(const boost::filesystem::path &path, int flags) override;
|
||||||
void flush(int descriptor) override;
|
void flush(int descriptor) override;
|
||||||
void closeFile(int descriptor) override;
|
void closeFile(int descriptor) override;
|
||||||
void lstat(const boost::filesystem::path &path, struct ::stat *stbuf) override;
|
void lstat(const boost::filesystem::path &path, fspp::fuse::STAT *stbuf) override;
|
||||||
void fstat(int descriptor, struct ::stat *stbuf) override;
|
void fstat(int descriptor, fspp::fuse::STAT *stbuf) override;
|
||||||
void chmod(const boost::filesystem::path &path, ::mode_t mode) override;
|
void chmod(const boost::filesystem::path &path, ::mode_t mode) override;
|
||||||
void chown(const boost::filesystem::path &path, ::uid_t uid, ::gid_t gid) override;
|
void chown(const boost::filesystem::path &path, ::uid_t uid, ::gid_t gid) override;
|
||||||
void truncate(const boost::filesystem::path &path, fspp::num_bytes_t size) override;
|
void truncate(const boost::filesystem::path &path, fspp::num_bytes_t size) override;
|
||||||
|
@ -6,7 +6,7 @@ using ::testing::Values;
|
|||||||
|
|
||||||
class FuseLstatReturnATimeTest: public FuseLstatReturnTest<time_t>, public WithParamInterface<time_t> {
|
class FuseLstatReturnATimeTest: public FuseLstatReturnTest<time_t>, public WithParamInterface<time_t> {
|
||||||
private:
|
private:
|
||||||
void set(struct stat *stat, time_t value) override {
|
void set(fspp::fuse::STAT *stat, time_t value) override {
|
||||||
stat->st_atim.tv_sec = value;
|
stat->st_atim.tv_sec = value;
|
||||||
stat->st_atim.tv_nsec = 0;
|
stat->st_atim.tv_nsec = 0;
|
||||||
}
|
}
|
||||||
@ -19,13 +19,13 @@ INSTANTIATE_TEST_CASE_P(FuseLstatReturnATimeTest, FuseLstatReturnATimeTest, Valu
|
|||||||
));
|
));
|
||||||
|
|
||||||
TEST_P(FuseLstatReturnATimeTest, ReturnedFileAtimeIsCorrect) {
|
TEST_P(FuseLstatReturnATimeTest, ReturnedFileAtimeIsCorrect) {
|
||||||
struct ::stat result = CallFileLstatWithValue(GetParam());
|
fspp::fuse::STAT result = CallFileLstatWithValue(GetParam());
|
||||||
EXPECT_EQ(GetParam(), result.st_atim.tv_sec);
|
EXPECT_EQ(GetParam(), result.st_atim.tv_sec);
|
||||||
EXPECT_EQ(0, result.st_atim.tv_nsec);
|
EXPECT_EQ(0, result.st_atim.tv_nsec);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(FuseLstatReturnATimeTest, ReturnedDirAtimeIsCorrect) {
|
TEST_P(FuseLstatReturnATimeTest, ReturnedDirAtimeIsCorrect) {
|
||||||
struct ::stat result = CallDirLstatWithValue(GetParam());
|
fspp::fuse::STAT result = CallDirLstatWithValue(GetParam());
|
||||||
EXPECT_EQ(GetParam(), result.st_atim.tv_sec);
|
EXPECT_EQ(GetParam(), result.st_atim.tv_sec);
|
||||||
EXPECT_EQ(0, result.st_atim.tv_nsec);
|
EXPECT_EQ(0, result.st_atim.tv_nsec);
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ using ::testing::Values;
|
|||||||
|
|
||||||
class FuseLstatReturnCtimeTest: public FuseLstatReturnTest<time_t>, public WithParamInterface<time_t> {
|
class FuseLstatReturnCtimeTest: public FuseLstatReturnTest<time_t>, public WithParamInterface<time_t> {
|
||||||
private:
|
private:
|
||||||
void set(struct stat *stat, time_t value) override {
|
void set(fspp::fuse::STAT *stat, time_t value) override {
|
||||||
stat->st_ctim.tv_sec = value;
|
stat->st_ctim.tv_sec = value;
|
||||||
stat->st_ctim.tv_nsec = 0;
|
stat->st_ctim.tv_nsec = 0;
|
||||||
}
|
}
|
||||||
@ -19,13 +19,13 @@ INSTANTIATE_TEST_CASE_P(FuseLstatReturnCtimeTest, FuseLstatReturnCtimeTest, Valu
|
|||||||
));
|
));
|
||||||
|
|
||||||
TEST_P(FuseLstatReturnCtimeTest, ReturnedFileCtimeIsCorrect) {
|
TEST_P(FuseLstatReturnCtimeTest, ReturnedFileCtimeIsCorrect) {
|
||||||
struct ::stat result = CallFileLstatWithValue(GetParam());
|
fspp::fuse::STAT result = CallFileLstatWithValue(GetParam());
|
||||||
EXPECT_EQ(GetParam(), result.st_ctim.tv_sec);
|
EXPECT_EQ(GetParam(), result.st_ctim.tv_sec);
|
||||||
EXPECT_EQ(0, result.st_ctim.tv_nsec);
|
EXPECT_EQ(0, result.st_ctim.tv_nsec);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(FuseLstatReturnCtimeTest, ReturnedDirCtimeIsCorrect) {
|
TEST_P(FuseLstatReturnCtimeTest, ReturnedDirCtimeIsCorrect) {
|
||||||
struct ::stat result = CallDirLstatWithValue(GetParam());
|
fspp::fuse::STAT result = CallDirLstatWithValue(GetParam());
|
||||||
EXPECT_EQ(GetParam(), result.st_ctim.tv_sec);
|
EXPECT_EQ(GetParam(), result.st_ctim.tv_sec);
|
||||||
EXPECT_EQ(0, result.st_ctim.tv_nsec);
|
EXPECT_EQ(0, result.st_ctim.tv_nsec);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ using ::testing::Values;
|
|||||||
|
|
||||||
class FuseLstatReturnGidTest: public FuseLstatReturnTest<gid_t>, public WithParamInterface<gid_t> {
|
class FuseLstatReturnGidTest: public FuseLstatReturnTest<gid_t>, public WithParamInterface<gid_t> {
|
||||||
private:
|
private:
|
||||||
void set(struct stat *stat, gid_t value) override {
|
void set(fspp::fuse::STAT *stat, gid_t value) override {
|
||||||
stat->st_gid = value;
|
stat->st_gid = value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -15,11 +15,11 @@ INSTANTIATE_TEST_CASE_P(FuseLstatReturnGidTest, FuseLstatReturnGidTest, Values(
|
|||||||
));
|
));
|
||||||
|
|
||||||
TEST_P(FuseLstatReturnGidTest, ReturnedFileGidIsCorrect) {
|
TEST_P(FuseLstatReturnGidTest, ReturnedFileGidIsCorrect) {
|
||||||
struct ::stat result = CallFileLstatWithValue(GetParam());
|
fspp::fuse::STAT result = CallFileLstatWithValue(GetParam());
|
||||||
EXPECT_EQ(GetParam(), result.st_gid);
|
EXPECT_EQ(GetParam(), result.st_gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(FuseLstatReturnGidTest, ReturnedDirGidIsCorrect) {
|
TEST_P(FuseLstatReturnGidTest, ReturnedDirGidIsCorrect) {
|
||||||
struct ::stat result = CallDirLstatWithValue(GetParam());
|
fspp::fuse::STAT result = CallDirLstatWithValue(GetParam());
|
||||||
EXPECT_EQ(GetParam(), result.st_gid);
|
EXPECT_EQ(GetParam(), result.st_gid);
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@ using ::testing::Values;
|
|||||||
|
|
||||||
class FuseLstatReturnModeTest: public FuseLstatTest, public WithParamInterface<mode_t> {
|
class FuseLstatReturnModeTest: public FuseLstatTest, public WithParamInterface<mode_t> {
|
||||||
public:
|
public:
|
||||||
struct stat CallLstatWithValue(mode_t mode) {
|
fspp::fuse::STAT CallLstatWithValue(mode_t mode) {
|
||||||
return CallLstatWithImpl([mode] (struct stat *stat) {
|
return CallLstatWithImpl([mode] (fspp::fuse::STAT *stat) {
|
||||||
stat->st_mode = mode;
|
stat->st_mode = mode;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -19,6 +19,6 @@ INSTANTIATE_TEST_CASE_P(FuseLstatReturnModeTest, FuseLstatReturnModeTest, Values
|
|||||||
));
|
));
|
||||||
|
|
||||||
TEST_P(FuseLstatReturnModeTest, ReturnedModeIsCorrect) {
|
TEST_P(FuseLstatReturnModeTest, ReturnedModeIsCorrect) {
|
||||||
struct ::stat result = CallLstatWithValue(GetParam());
|
fspp::fuse::STAT result = CallLstatWithValue(GetParam());
|
||||||
EXPECT_EQ(GetParam(), result.st_mode);
|
EXPECT_EQ(GetParam(), result.st_mode);
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ using ::testing::Values;
|
|||||||
|
|
||||||
class FuseLstatReturnMtimeTest: public FuseLstatReturnTest<time_t>, public WithParamInterface<time_t> {
|
class FuseLstatReturnMtimeTest: public FuseLstatReturnTest<time_t>, public WithParamInterface<time_t> {
|
||||||
private:
|
private:
|
||||||
void set(struct stat *stat, time_t value) override {
|
void set(fspp::fuse::STAT *stat, time_t value) override {
|
||||||
stat->st_mtim.tv_sec = value;
|
stat->st_mtim.tv_sec = value;
|
||||||
stat->st_mtim.tv_nsec = 0;
|
stat->st_mtim.tv_nsec = 0;
|
||||||
}
|
}
|
||||||
@ -19,13 +19,13 @@ INSTANTIATE_TEST_CASE_P(FuseLstatReturnMtimeTest, FuseLstatReturnMtimeTest, Valu
|
|||||||
));
|
));
|
||||||
|
|
||||||
TEST_P(FuseLstatReturnMtimeTest, ReturnedFileMtimeIsCorrect) {
|
TEST_P(FuseLstatReturnMtimeTest, ReturnedFileMtimeIsCorrect) {
|
||||||
struct ::stat result = CallFileLstatWithValue(GetParam());
|
fspp::fuse::STAT result = CallFileLstatWithValue(GetParam());
|
||||||
EXPECT_EQ(GetParam(), result.st_mtim.tv_sec);
|
EXPECT_EQ(GetParam(), result.st_mtim.tv_sec);
|
||||||
EXPECT_EQ(0, result.st_mtim.tv_nsec);
|
EXPECT_EQ(0, result.st_mtim.tv_nsec);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(FuseLstatReturnMtimeTest, ReturnedDirMtimeIsCorrect) {
|
TEST_P(FuseLstatReturnMtimeTest, ReturnedDirMtimeIsCorrect) {
|
||||||
struct ::stat result = CallDirLstatWithValue(GetParam());
|
fspp::fuse::STAT result = CallDirLstatWithValue(GetParam());
|
||||||
EXPECT_EQ(GetParam(), result.st_mtim.tv_sec);
|
EXPECT_EQ(GetParam(), result.st_mtim.tv_sec);
|
||||||
EXPECT_EQ(0, result.st_mtim.tv_nsec);
|
EXPECT_EQ(0, result.st_mtim.tv_nsec);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ using ::testing::Values;
|
|||||||
|
|
||||||
class FuseLstatReturnNlinkTest: public FuseLstatReturnTest<nlink_t>, public WithParamInterface<nlink_t> {
|
class FuseLstatReturnNlinkTest: public FuseLstatReturnTest<nlink_t>, public WithParamInterface<nlink_t> {
|
||||||
private:
|
private:
|
||||||
void set(struct stat *stat, nlink_t value) override {
|
void set(fspp::fuse::STAT *stat, nlink_t value) override {
|
||||||
stat->st_nlink = value;
|
stat->st_nlink = value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -17,12 +17,12 @@ INSTANTIATE_TEST_CASE_P(FuseLstatReturnNlinkTest, FuseLstatReturnNlinkTest, Valu
|
|||||||
));
|
));
|
||||||
|
|
||||||
TEST_P(FuseLstatReturnNlinkTest, ReturnedFileNlinkIsCorrect) {
|
TEST_P(FuseLstatReturnNlinkTest, ReturnedFileNlinkIsCorrect) {
|
||||||
struct ::stat result = CallDirLstatWithValue(GetParam());
|
fspp::fuse::STAT result = CallDirLstatWithValue(GetParam());
|
||||||
EXPECT_EQ(GetParam(), result.st_nlink);
|
EXPECT_EQ(GetParam(), result.st_nlink);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(FuseLstatReturnNlinkTest, ReturnedDirNlinkIsCorrect) {
|
TEST_P(FuseLstatReturnNlinkTest, ReturnedDirNlinkIsCorrect) {
|
||||||
struct ::stat result = CallDirLstatWithValue(GetParam());
|
fspp::fuse::STAT result = CallDirLstatWithValue(GetParam());
|
||||||
EXPECT_EQ(GetParam(), result.st_nlink);
|
EXPECT_EQ(GetParam(), result.st_nlink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ using ::testing::Values;
|
|||||||
|
|
||||||
class FuseLstatReturnSizeTest: public FuseLstatReturnTest<fspp::num_bytes_t>, public WithParamInterface<fspp::num_bytes_t> {
|
class FuseLstatReturnSizeTest: public FuseLstatReturnTest<fspp::num_bytes_t>, public WithParamInterface<fspp::num_bytes_t> {
|
||||||
private:
|
private:
|
||||||
void set(struct stat *stat, fspp::num_bytes_t value) override {
|
void set(fspp::fuse::STAT *stat, fspp::num_bytes_t value) override {
|
||||||
stat->st_size = value.value();
|
stat->st_size = value.value();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -17,11 +17,11 @@ INSTANTIATE_TEST_CASE_P(FuseLstatReturnSizeTest, FuseLstatReturnSizeTest, Values
|
|||||||
));
|
));
|
||||||
|
|
||||||
TEST_P(FuseLstatReturnSizeTest, ReturnedFileSizeIsCorrect) {
|
TEST_P(FuseLstatReturnSizeTest, ReturnedFileSizeIsCorrect) {
|
||||||
struct ::stat result = CallDirLstatWithValue(GetParam());
|
fspp::fuse::STAT result = CallDirLstatWithValue(GetParam());
|
||||||
EXPECT_EQ(GetParam(), fspp::num_bytes_t(result.st_size));
|
EXPECT_EQ(GetParam(), fspp::num_bytes_t(result.st_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(FuseLstatReturnSizeTest, ReturnedDirSizeIsCorrect) {
|
TEST_P(FuseLstatReturnSizeTest, ReturnedDirSizeIsCorrect) {
|
||||||
struct ::stat result = CallDirLstatWithValue(GetParam());
|
fspp::fuse::STAT result = CallDirLstatWithValue(GetParam());
|
||||||
EXPECT_EQ(GetParam(), fspp::num_bytes_t(result.st_size));
|
EXPECT_EQ(GetParam(), fspp::num_bytes_t(result.st_size));
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ using ::testing::Values;
|
|||||||
|
|
||||||
class FuseLstatReturnUidTest: public FuseLstatReturnTest<uid_t>, public WithParamInterface<uid_t> {
|
class FuseLstatReturnUidTest: public FuseLstatReturnTest<uid_t>, public WithParamInterface<uid_t> {
|
||||||
private:
|
private:
|
||||||
void set(struct stat *stat, uid_t value) override {
|
void set(fspp::fuse::STAT *stat, uid_t value) override {
|
||||||
stat->st_uid = value;
|
stat->st_uid = value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -15,11 +15,11 @@ INSTANTIATE_TEST_CASE_P(FuseLstatReturnUidTest, FuseLstatReturnUidTest, Values(
|
|||||||
));
|
));
|
||||||
|
|
||||||
TEST_P(FuseLstatReturnUidTest, ReturnedFileUidIsCorrect) {
|
TEST_P(FuseLstatReturnUidTest, ReturnedFileUidIsCorrect) {
|
||||||
struct ::stat result = CallFileLstatWithValue(GetParam());
|
fspp::fuse::STAT result = CallFileLstatWithValue(GetParam());
|
||||||
EXPECT_EQ(GetParam(), result.st_uid);
|
EXPECT_EQ(GetParam(), result.st_uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(FuseLstatReturnUidTest, ReturnedDirUidIsCorrect) {
|
TEST_P(FuseLstatReturnUidTest, ReturnedDirUidIsCorrect) {
|
||||||
struct ::stat result = CallDirLstatWithValue(GetParam());
|
fspp::fuse::STAT result = CallDirLstatWithValue(GetParam());
|
||||||
EXPECT_EQ(GetParam(), result.st_uid);
|
EXPECT_EQ(GetParam(), result.st_uid);
|
||||||
}
|
}
|
||||||
|
@ -4,37 +4,37 @@
|
|||||||
|
|
||||||
#include "FuseLstatTest.h"
|
#include "FuseLstatTest.h"
|
||||||
|
|
||||||
// This class offers test helpers for testing (struct stat) entries. We return them from
|
// This class offers test helpers for testing (fspp::fuse::STAT) entries. We return them from
|
||||||
// our mock filesystem, set up a temporary filesystem, call lstat syscall on it, and
|
// our mock filesystem, set up a temporary filesystem, call lstat syscall on it, and
|
||||||
// then check the return value.
|
// then check the return value.
|
||||||
template<typename Property>
|
template<typename Property>
|
||||||
class FuseLstatReturnTest: public FuseLstatTest {
|
class FuseLstatReturnTest: public FuseLstatTest {
|
||||||
public:
|
public:
|
||||||
// Set the specified (struct stat) entry to the given value, and test whether it is correctly returned from the syscall.
|
// Set the specified (fspp::fuse::STAT) entry to the given value, and test whether it is correctly returned from the syscall.
|
||||||
// The CallFile[...] version tests it on a file node of the filesystem, the CallDir[...] version on a dir node.
|
// The CallFile[...] version tests it on a file node of the filesystem, the CallDir[...] version on a dir node.
|
||||||
struct stat CallFileLstatWithValue(Property value);
|
fspp::fuse::STAT CallFileLstatWithValue(Property value);
|
||||||
struct stat CallDirLstatWithValue(Property value);
|
fspp::fuse::STAT CallDirLstatWithValue(Property value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::function<void(struct stat*)> SetPropertyImpl(Property value);
|
std::function<void(fspp::fuse::STAT*)> SetPropertyImpl(Property value);
|
||||||
|
|
||||||
// Override this function to specify, how to set the specified (struct stat) entry on the passed (struct stat *) object.
|
// Override this function to specify, how to set the specified (fspp::fuse::STAT) entry on the passed (fspp::fuse::STAT *) object.
|
||||||
virtual void set(struct stat *stat, Property value) = 0;
|
virtual void set(fspp::fuse::STAT *stat, Property value) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Property>
|
template<typename Property>
|
||||||
struct stat FuseLstatReturnTest<Property>::CallFileLstatWithValue(Property value) {
|
FUSE_STAT FuseLstatReturnTest<Property>::CallFileLstatWithValue(Property value) {
|
||||||
return CallFileLstatWithImpl(SetPropertyImpl(value));
|
return CallFileLstatWithImpl(SetPropertyImpl(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Property>
|
template<typename Property>
|
||||||
struct stat FuseLstatReturnTest<Property>::CallDirLstatWithValue(Property value) {
|
FUSE_STAT FuseLstatReturnTest<Property>::CallDirLstatWithValue(Property value) {
|
||||||
return CallDirLstatWithImpl(SetPropertyImpl(value));
|
return CallDirLstatWithImpl(SetPropertyImpl(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Property>
|
template<typename Property>
|
||||||
std::function<void(struct stat*)> FuseLstatReturnTest<Property>::SetPropertyImpl(Property value) {
|
std::function<void(fspp::fuse::STAT*)> FuseLstatReturnTest<Property>::SetPropertyImpl(Property value) {
|
||||||
return [this, value] (struct stat *stat) {
|
return [this, value] (fspp::fuse::STAT *stat) {
|
||||||
set(stat, value);
|
set(stat, value);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -6,21 +6,21 @@ using ::testing::_;
|
|||||||
using ::testing::Invoke;
|
using ::testing::Invoke;
|
||||||
|
|
||||||
void FuseLstatTest::LstatPath(const std::string &path) {
|
void FuseLstatTest::LstatPath(const std::string &path) {
|
||||||
struct stat dummy{};
|
fspp::fuse::STAT dummy{};
|
||||||
LstatPath(path, &dummy);
|
LstatPath(path, &dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FuseLstatTest::LstatPathReturnError(const std::string &path) {
|
int FuseLstatTest::LstatPathReturnError(const std::string &path) {
|
||||||
struct stat dummy{};
|
fspp::fuse::STAT dummy{};
|
||||||
return LstatPathReturnError(path, &dummy);
|
return LstatPathReturnError(path, &dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FuseLstatTest::LstatPath(const std::string &path, struct stat *result) {
|
void FuseLstatTest::LstatPath(const std::string &path, fspp::fuse::STAT *result) {
|
||||||
int error = LstatPathReturnError(path, result);
|
int error = LstatPathReturnError(path, result);
|
||||||
EXPECT_EQ(0, error) << "lstat syscall failed. errno: " << error;
|
EXPECT_EQ(0, error) << "lstat syscall failed. errno: " << error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FuseLstatTest::LstatPathReturnError(const std::string &path, struct stat *result) {
|
int FuseLstatTest::LstatPathReturnError(const std::string &path, fspp::fuse::STAT *result) {
|
||||||
auto fs = TestFS();
|
auto fs = TestFS();
|
||||||
|
|
||||||
auto realpath = fs->mountDir() / path;
|
auto realpath = fs->mountDir() / path;
|
||||||
@ -32,27 +32,27 @@ int FuseLstatTest::LstatPathReturnError(const std::string &path, struct stat *re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stat FuseLstatTest::CallFileLstatWithImpl(function<void(struct stat*)> implementation) {
|
fspp::fuse::STAT FuseLstatTest::CallFileLstatWithImpl(function<void(fspp::fuse::STAT*)> implementation) {
|
||||||
return CallLstatWithModeAndImpl(S_IFREG, implementation);
|
return CallLstatWithModeAndImpl(S_IFREG, implementation);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stat FuseLstatTest::CallDirLstatWithImpl(function<void(struct stat*)> implementation) {
|
fspp::fuse::STAT FuseLstatTest::CallDirLstatWithImpl(function<void(fspp::fuse::STAT*)> implementation) {
|
||||||
return CallLstatWithModeAndImpl(S_IFDIR, implementation);
|
return CallLstatWithModeAndImpl(S_IFDIR, implementation);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stat FuseLstatTest::CallLstatWithImpl(function<void(struct stat*)> implementation) {
|
fspp::fuse::STAT FuseLstatTest::CallLstatWithImpl(function<void(fspp::fuse::STAT*)> implementation) {
|
||||||
EXPECT_CALL(fsimpl, lstat(StrEq(FILENAME), _)).WillRepeatedly(Invoke([implementation](const char*, struct ::stat *stat) {
|
EXPECT_CALL(fsimpl, lstat(StrEq(FILENAME), _)).WillRepeatedly(Invoke([implementation](const char*, fspp::fuse::STAT *stat) {
|
||||||
implementation(stat);
|
implementation(stat);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
struct stat result{};
|
fspp::fuse::STAT result{};
|
||||||
LstatPath(FILENAME, &result);
|
LstatPath(FILENAME, &result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stat FuseLstatTest::CallLstatWithModeAndImpl(mode_t mode, function<void(struct stat*)> implementation) {
|
fspp::fuse::STAT FuseLstatTest::CallLstatWithModeAndImpl(mode_t mode, function<void(fspp::fuse::STAT*)> implementation) {
|
||||||
return CallLstatWithImpl([mode, implementation] (struct stat *stat) {
|
return CallLstatWithImpl([mode, implementation] (fspp::fuse::STAT *stat) {
|
||||||
stat->st_mode = mode;
|
stat->st_mode = mode;
|
||||||
implementation(stat);
|
implementation(stat);
|
||||||
});
|
});
|
||||||
|
@ -17,27 +17,27 @@ protected:
|
|||||||
// and call the lstat syscall on the given (filesystem-relative) path.
|
// and call the lstat syscall on the given (filesystem-relative) path.
|
||||||
void LstatPath(const std::string &path);
|
void LstatPath(const std::string &path);
|
||||||
// Same as LstatPath above, but also return the result of the lstat syscall.
|
// Same as LstatPath above, but also return the result of the lstat syscall.
|
||||||
void LstatPath(const std::string &path, struct stat *result);
|
void LstatPath(const std::string &path, fspp::fuse::STAT *result);
|
||||||
|
|
||||||
// These two functions are the same as LstatPath above, but they don't fail the test when the lstat syscall
|
// These two functions are the same as LstatPath above, but they don't fail the test when the lstat syscall
|
||||||
// crashes. Instead, they return the value of errno after calling ::lstat.
|
// crashes. Instead, they return the value of errno after calling ::lstat.
|
||||||
int LstatPathReturnError(const std::string &path);
|
int LstatPathReturnError(const std::string &path);
|
||||||
int LstatPathReturnError(const std::string &path, struct stat *result);
|
int LstatPathReturnError(const std::string &path, fspp::fuse::STAT *result);
|
||||||
|
|
||||||
// You can specify an implementation, which can modify the (struct stat *) result,
|
// You can specify an implementation, which can modify the (fspp::fuse::STAT *) result,
|
||||||
// our fuse mock filesystem implementation will then return this to fuse on an lstat call.
|
// our fuse mock filesystem implementation will then return this to fuse on an lstat call.
|
||||||
// This functions then set up a temporary filesystem with this mock, call lstat on a filesystem node
|
// This functions then set up a temporary filesystem with this mock, call lstat on a filesystem node
|
||||||
// and return the (struct stat) returned from an lstat syscall to this filesystem.
|
// and return the (fspp::fuse::STAT) returned from an lstat syscall to this filesystem.
|
||||||
struct stat CallLstatWithImpl(std::function<void(struct stat*)> implementation);
|
fspp::fuse::STAT CallLstatWithImpl(std::function<void(fspp::fuse::STAT*)> implementation);
|
||||||
|
|
||||||
// These two functions are like CallLstatWithImpl, but they also modify the (struct stat).st_mode
|
// These two functions are like CallLstatWithImpl, but they also modify the (fspp::fuse::STAT).st_mode
|
||||||
// field, so the node accessed is specified to be a file/directory.
|
// field, so the node accessed is specified to be a file/directory.
|
||||||
struct stat CallFileLstatWithImpl(std::function<void(struct stat*)> implementation);
|
fspp::fuse::STAT CallFileLstatWithImpl(std::function<void(fspp::fuse::STAT*)> implementation);
|
||||||
struct stat CallDirLstatWithImpl(std::function<void(struct stat*)> implementation);
|
fspp::fuse::STAT CallDirLstatWithImpl(std::function<void(fspp::fuse::STAT*)> implementation);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct stat CallLstatWithModeAndImpl(mode_t mode, std::function<void(struct stat*)> implementation);
|
fspp::fuse::STAT CallLstatWithModeAndImpl(mode_t mode, std::function<void(fspp::fuse::STAT*)> implementation);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -65,8 +65,8 @@ const bf::path &FuseTest::TempTestFS::mountDir() const {
|
|||||||
return _mountDir.path();
|
return _mountDir.path();
|
||||||
}
|
}
|
||||||
|
|
||||||
Action<void(const char*, struct ::stat*)> FuseTest::ReturnIsFileWithSize(fspp::num_bytes_t size) {
|
Action<void(const char*, fspp::fuse::STAT*)> FuseTest::ReturnIsFileWithSize(fspp::num_bytes_t size) {
|
||||||
return Invoke([size](const char*, struct ::stat* result) {
|
return Invoke([size](const char*, fspp::fuse::STAT* result) {
|
||||||
result->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH;
|
result->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH;
|
||||||
result->st_nlink = 1;
|
result->st_nlink = 1;
|
||||||
result->st_size = size.value();
|
result->st_size = size.value();
|
||||||
@ -74,15 +74,15 @@ Action<void(const char*, struct ::stat*)> FuseTest::ReturnIsFileWithSize(fspp::n
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO Combine ReturnIsFile and ReturnIsFileFstat. This should be possible in gmock by either (a) using ::testing::Undefined as parameter type or (b) using action macros
|
//TODO Combine ReturnIsFile and ReturnIsFileFstat. This should be possible in gmock by either (a) using ::testing::Undefined as parameter type or (b) using action macros
|
||||||
Action<void(const char*, struct ::stat*)> FuseTest::ReturnIsFile = ReturnIsFileWithSize(fspp::num_bytes_t(0));
|
Action<void(const char*, fspp::fuse::STAT*)> FuseTest::ReturnIsFile = ReturnIsFileWithSize(fspp::num_bytes_t(0));
|
||||||
|
|
||||||
Action<void(int, struct ::stat*)> FuseTest::ReturnIsFileFstat =
|
Action<void(int, fspp::fuse::STAT*)> FuseTest::ReturnIsFileFstat =
|
||||||
Invoke([](int, struct ::stat* result) {
|
Invoke([](int, fspp::fuse::STAT* result) {
|
||||||
result->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH;
|
result->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH;
|
||||||
result->st_nlink = 1;
|
result->st_nlink = 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
Action<void(int, struct ::stat*)> FuseTest::ReturnIsFileFstatWithSize(fspp::num_bytes_t size) {
|
Action<void(int, fspp::fuse::STAT*)> FuseTest::ReturnIsFileFstatWithSize(fspp::num_bytes_t size) {
|
||||||
return Invoke([size](int, struct ::stat *result) {
|
return Invoke([size](int, struct ::stat *result) {
|
||||||
result->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH;
|
result->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH;
|
||||||
result->st_nlink = 1;
|
result->st_nlink = 1;
|
||||||
@ -91,13 +91,13 @@ Action<void(int, struct ::stat*)> FuseTest::ReturnIsFileFstatWithSize(fspp::num_
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Action<void(const char*, struct ::stat*)> FuseTest::ReturnIsDir =
|
Action<void(const char*, fspp::fuse::STAT*)> FuseTest::ReturnIsDir =
|
||||||
Invoke([](const char*, struct ::stat* result) {
|
Invoke([](const char*, fspp::fuse::STAT* result) {
|
||||||
result->st_mode = S_IFDIR | S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH;
|
result->st_mode = S_IFDIR | S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||||
result->st_nlink = 1;
|
result->st_nlink = 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
Action<void(const char*, struct ::stat*)> FuseTest::ReturnDoesntExist = Throw(fspp::fuse::FuseErrnoException(ENOENT));
|
Action<void(const char*, fspp::fuse::STAT*)> FuseTest::ReturnDoesntExist = Throw(fspp::fuse::FuseErrnoException(ENOENT));
|
||||||
|
|
||||||
void FuseTest::OnOpenReturnFileDescriptor(const char *filename, int descriptor) {
|
void FuseTest::OnOpenReturnFileDescriptor(const char *filename, int descriptor) {
|
||||||
EXPECT_CALL(fsimpl, openFile(StrEq(filename), _)).Times(1).WillOnce(Return(descriptor));
|
EXPECT_CALL(fsimpl, openFile(StrEq(filename), _)).Times(1).WillOnce(Return(descriptor));
|
||||||
|
@ -46,8 +46,8 @@ public:
|
|||||||
|
|
||||||
MOCK_PATH_METHOD2(openFile, int, int);
|
MOCK_PATH_METHOD2(openFile, int, int);
|
||||||
MOCK_METHOD1(closeFile, void(int));
|
MOCK_METHOD1(closeFile, void(int));
|
||||||
MOCK_PATH_METHOD2(lstat, void, struct ::stat*);
|
MOCK_PATH_METHOD2(lstat, void, fspp::fuse::STAT*);
|
||||||
MOCK_METHOD2(fstat, void(int, struct ::stat*));
|
MOCK_METHOD2(fstat, void(int, fspp::fuse::STAT*));
|
||||||
MOCK_PATH_METHOD2(truncate, void, fspp::num_bytes_t);
|
MOCK_PATH_METHOD2(truncate, void, fspp::num_bytes_t);
|
||||||
MOCK_METHOD2(ftruncate, void(int, fspp::num_bytes_t));
|
MOCK_METHOD2(ftruncate, void(int, fspp::num_bytes_t));
|
||||||
MOCK_METHOD4(read, fspp::num_bytes_t(int, void*, fspp::num_bytes_t, fspp::num_bytes_t));
|
MOCK_METHOD4(read, fspp::num_bytes_t(int, void*, fspp::num_bytes_t, fspp::num_bytes_t));
|
||||||
@ -106,12 +106,12 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
//TODO Combine ReturnIsFile and ReturnIsFileFstat. This should be possible in gmock by either (a) using ::testing::Undefined as parameter type or (b) using action macros
|
//TODO Combine ReturnIsFile and ReturnIsFileFstat. This should be possible in gmock by either (a) using ::testing::Undefined as parameter type or (b) using action macros
|
||||||
static ::testing::Action<void(const char*, struct ::stat*)> ReturnIsFile;
|
static ::testing::Action<void(const char*, fspp::fuse::STAT*)> ReturnIsFile;
|
||||||
static ::testing::Action<void(const char*, struct ::stat*)> ReturnIsFileWithSize(fspp::num_bytes_t size);
|
static ::testing::Action<void(const char*, fspp::fuse::STAT*)> ReturnIsFileWithSize(fspp::num_bytes_t size);
|
||||||
static ::testing::Action<void(int, struct ::stat*)> ReturnIsFileFstat;
|
static ::testing::Action<void(int, fspp::fuse::STAT*)> ReturnIsFileFstat;
|
||||||
static ::testing::Action<void(int, struct ::stat*)> ReturnIsFileFstatWithSize(fspp::num_bytes_t size);
|
static ::testing::Action<void(int, fspp::fuse::STAT*)> ReturnIsFileFstatWithSize(fspp::num_bytes_t size);
|
||||||
static ::testing::Action<void(const char*, struct ::stat*)> ReturnIsDir;
|
static ::testing::Action<void(const char*, fspp::fuse::STAT*)> ReturnIsDir;
|
||||||
static ::testing::Action<void(const char*, struct ::stat*)> ReturnDoesntExist;
|
static ::testing::Action<void(const char*, fspp::fuse::STAT*)> ReturnDoesntExist;
|
||||||
|
|
||||||
void ReturnIsFileOnLstat(const boost::filesystem::path &path);
|
void ReturnIsFileOnLstat(const boost::filesystem::path &path);
|
||||||
void ReturnIsFileOnLstatWithSize(const boost::filesystem::path &path, fspp::num_bytes_t size);
|
void ReturnIsFileOnLstatWithSize(const boost::filesystem::path &path, fspp::num_bytes_t size);
|
||||||
|
Loading…
Reference in New Issue
Block a user