fuse unit tests and fixes
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
This commit is contained in:
parent
d7d9199f8e
commit
74546807f4
@ -81,8 +81,8 @@ auto fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid,
|
||||
struct fuse_file_info * /*file_info*/)
|
||||
-> api_error {
|
||||
#else
|
||||
auto fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid)
|
||||
-> api_error {
|
||||
auto fuse_drive::chown_impl(std::string api_path, uid_t uid,
|
||||
gid_t gid) -> api_error {
|
||||
#endif
|
||||
return check_and_perform(
|
||||
api_path, X_OK, [&](api_meta_map &meta) -> api_error {
|
||||
@ -116,18 +116,15 @@ auto fuse_drive::create_impl(std::string api_path, mode_t mode,
|
||||
struct fuse_file_info *file_info) -> api_error {
|
||||
file_info->fh = 0U;
|
||||
|
||||
const auto is_directory_op =
|
||||
((file_info->flags & O_DIRECTORY) == O_DIRECTORY);
|
||||
const auto is_create_op = ((file_info->flags & O_CREAT) == O_CREAT);
|
||||
const auto is_truncate_op = (((file_info->flags & O_TRUNC) != 0) &&
|
||||
(((file_info->flags & O_WRONLY) != 0) ||
|
||||
((file_info->flags & O_RDWR) != 0)));
|
||||
auto is_create_op = ((file_info->flags & O_CREAT) == O_CREAT);
|
||||
auto is_directory_op = ((file_info->flags & O_DIRECTORY) == O_DIRECTORY);
|
||||
auto is_truncate_op = ((file_info->flags & O_TRUNC) == O_TRUNC);
|
||||
|
||||
if (((file_info->flags & O_WRONLY) != 0) ||
|
||||
((file_info->flags & O_RDWR) != 0)) {
|
||||
const auto res = provider_.is_file_writeable(api_path)
|
||||
? api_error::success
|
||||
: api_error::permission_denied;
|
||||
auto res = provider_.is_file_writeable(api_path)
|
||||
? api_error::success
|
||||
: api_error::permission_denied;
|
||||
if (res != api_error::success) {
|
||||
return res;
|
||||
}
|
||||
@ -167,21 +164,26 @@ auto fuse_drive::create_impl(std::string api_path, mode_t mode,
|
||||
if (res != api_error::success) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (not(is_directory_op ? dir_exists : file_exists)) {
|
||||
return (is_directory_op ? api_error::directory_not_found
|
||||
: api_error::item_not_found);
|
||||
}
|
||||
|
||||
if (is_truncate_op && not file_exists) {
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
}
|
||||
|
||||
std::uint64_t handle{};
|
||||
{
|
||||
std::shared_ptr<i_open_file> open_file;
|
||||
if (is_create_op) {
|
||||
const auto now = utils::time::get_time_now();
|
||||
auto now = utils::time::get_time_now();
|
||||
#if defined(__APPLE__)
|
||||
const auto osx_flags = static_cast<std::uint32_t>(file_info->flags);
|
||||
auto osx_flags = static_cast<std::uint32_t>(file_info->flags);
|
||||
#else // !defined(__APPLE__)
|
||||
const auto osx_flags = 0U;
|
||||
auto osx_flags = 0U;
|
||||
#endif // defined(__APPLE__)
|
||||
|
||||
auto meta = create_meta_attributes(
|
||||
@ -388,8 +390,8 @@ api_error fuse_drive::ftruncate_impl(std::string /*api_path*/, off_t size,
|
||||
return api_error::invalid_handle;
|
||||
}
|
||||
|
||||
const auto res = check_writeable(f->get_open_data(file_info->fh),
|
||||
api_error::invalid_handle);
|
||||
auto res = check_writeable(f->get_open_data(file_info->fh),
|
||||
api_error::invalid_handle);
|
||||
if (res != api_error::success) {
|
||||
return res;
|
||||
}
|
||||
@ -440,7 +442,7 @@ auto fuse_drive::get_item_meta(const std::string &api_path,
|
||||
const std::string &name,
|
||||
std::string &value) const -> api_error {
|
||||
api_meta_map meta{};
|
||||
const auto ret = get_item_meta(api_path, meta);
|
||||
auto ret = get_item_meta(api_path, meta);
|
||||
if (ret == api_error::success) {
|
||||
value = meta[name];
|
||||
}
|
||||
@ -453,10 +455,10 @@ auto fuse_drive::getattr_impl(std::string api_path, struct stat *st,
|
||||
struct fuse_file_info * /*file_info*/)
|
||||
-> api_error {
|
||||
#else
|
||||
auto fuse_drive::getattr_impl(std::string api_path, struct stat *st)
|
||||
-> api_error {
|
||||
auto fuse_drive::getattr_impl(std::string api_path,
|
||||
struct stat *st) -> api_error {
|
||||
#endif
|
||||
const auto parent = utils::path::get_parent_api_path(api_path);
|
||||
auto parent = utils::path::get_parent_api_path(api_path);
|
||||
|
||||
auto res = check_parent_access(api_path, X_OK);
|
||||
if (res != api_error::success) {
|
||||
@ -536,8 +538,8 @@ auto fuse_drive::getxtimes_impl(std::string api_path, struct timespec *bkuptime,
|
||||
#endif // __APPLE__
|
||||
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
auto fuse_drive::init_impl(struct fuse_conn_info *conn, struct fuse_config *cfg)
|
||||
-> void * {
|
||||
auto fuse_drive::init_impl(struct fuse_conn_info *conn,
|
||||
struct fuse_config *cfg) -> void * {
|
||||
#else
|
||||
void *fuse_drive::init_impl(struct fuse_conn_info *conn) {
|
||||
#endif
|
||||
@ -617,7 +619,7 @@ auto fuse_drive::mkdir_impl(std::string api_path, mode_t mode) -> api_error {
|
||||
return res;
|
||||
}
|
||||
|
||||
const auto now = utils::time::get_time_now();
|
||||
auto now = utils::time::get_time_now();
|
||||
auto meta = create_meta_attributes(now, FILE_ATTRIBUTE_DIRECTORY, now, now,
|
||||
true, get_effective_gid(), "", mode, now,
|
||||
0U, 0U, 0U, "", get_effective_uid(), now);
|
||||
@ -656,8 +658,7 @@ auto fuse_drive::open_impl(std::string api_path,
|
||||
|
||||
auto fuse_drive::opendir_impl(std::string api_path,
|
||||
struct fuse_file_info *file_info) -> api_error {
|
||||
const auto mask =
|
||||
(O_RDONLY != (file_info->flags & O_ACCMODE) ? W_OK : R_OK) | X_OK;
|
||||
auto mask = (O_RDONLY != (file_info->flags & O_ACCMODE) ? W_OK : R_OK) | X_OK;
|
||||
auto res = check_access(api_path, mask);
|
||||
if (res != api_error::success) {
|
||||
return res;
|
||||
@ -762,9 +763,8 @@ auto fuse_drive::release_impl(std::string /*api_path*/,
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
auto fuse_drive::releasedir_impl(std::string /*api_path*/,
|
||||
struct fuse_file_info *file_info)
|
||||
-> api_error {
|
||||
auto fuse_drive::releasedir_impl(
|
||||
std::string /*api_path*/, struct fuse_file_info *file_info) -> api_error {
|
||||
auto iter = directory_cache_->get_directory(file_info->fh);
|
||||
if (iter == nullptr) {
|
||||
return api_error::invalid_handle;
|
||||
@ -776,15 +776,15 @@ auto fuse_drive::releasedir_impl(std::string /*api_path*/,
|
||||
|
||||
auto fuse_drive::rename_directory(const std::string &from_api_path,
|
||||
const std::string &to_api_path) -> int {
|
||||
const auto res = fm_->rename_directory(from_api_path, to_api_path);
|
||||
auto res = fm_->rename_directory(from_api_path, to_api_path);
|
||||
errno = std::abs(utils::from_api_error(res));
|
||||
return (res == api_error::success) ? 0 : -1;
|
||||
}
|
||||
|
||||
auto fuse_drive::rename_file(const std::string &from_api_path,
|
||||
const std::string &to_api_path, bool overwrite)
|
||||
-> int {
|
||||
const auto res = fm_->rename_file(from_api_path, to_api_path, overwrite);
|
||||
const std::string &to_api_path,
|
||||
bool overwrite) -> int {
|
||||
auto res = fm_->rename_file(from_api_path, to_api_path, overwrite);
|
||||
errno = std::abs(utils::from_api_error(res));
|
||||
return (res == api_error::success) ? 0 : -1;
|
||||
}
|
||||
@ -793,8 +793,8 @@ auto fuse_drive::rename_file(const std::string &from_api_path,
|
||||
auto fuse_drive::rename_impl(std::string from_api_path, std::string to_api_path,
|
||||
unsigned int /*flags*/) -> api_error {
|
||||
#else
|
||||
auto fuse_drive::rename_impl(std::string from_api_path, std::string to_api_path)
|
||||
-> api_error {
|
||||
auto fuse_drive::rename_impl(std::string from_api_path,
|
||||
std::string to_api_path) -> api_error {
|
||||
#endif
|
||||
auto res = check_parent_access(to_api_path, W_OK | X_OK);
|
||||
if (res != api_error::success) {
|
||||
@ -874,7 +874,7 @@ auto fuse_drive::getxattr_common(std::string api_path, const char *name,
|
||||
((res = provider_.get_item_meta(api_path, meta)) == api_error::success)) {
|
||||
res = api_error::xattr_not_found;
|
||||
if (meta.find(attribute_name) != meta.end()) {
|
||||
const auto data = macaron::Base64::Decode(meta[attribute_name]);
|
||||
auto data = macaron::Base64::Decode(meta[attribute_name]);
|
||||
if ((position == nullptr) || (*position < data.size())) {
|
||||
res = api_error::success;
|
||||
attribute_size = static_cast<int>(data.size());
|
||||
@ -901,16 +901,16 @@ auto fuse_drive::getxattr_impl(std::string api_path, const char *name,
|
||||
}
|
||||
#else // __APPLE__
|
||||
auto fuse_drive::getxattr_impl(std::string api_path, const char *name,
|
||||
char *value, size_t size, int &attribute_size)
|
||||
-> api_error {
|
||||
char *value, size_t size,
|
||||
int &attribute_size) -> api_error {
|
||||
return getxattr_common(api_path, name, value, size, attribute_size, nullptr);
|
||||
}
|
||||
#endif // __APPLE__
|
||||
|
||||
auto fuse_drive::listxattr_impl(std::string api_path, char *buffer, size_t size,
|
||||
int &required_size, bool &return_size)
|
||||
-> api_error {
|
||||
const auto check_size = (size == 0);
|
||||
int &required_size,
|
||||
bool &return_size) -> api_error {
|
||||
auto check_size = (size == 0);
|
||||
|
||||
auto res = check_parent_access(api_path, X_OK);
|
||||
if (res != api_error::success) {
|
||||
@ -925,7 +925,7 @@ auto fuse_drive::listxattr_impl(std::string api_path, char *buffer, size_t size,
|
||||
#if defined(__APPLE__)
|
||||
if (attribute_name != G_KAUTH_FILESEC_XATTR) {
|
||||
#endif
|
||||
const auto attribute_name_size = strlen(attribute_name.c_str()) + 1U;
|
||||
auto attribute_name_size = strlen(attribute_name.c_str()) + 1U;
|
||||
if (size >= attribute_name_size) {
|
||||
std::memcpy(&buffer[required_size], attribute_name.data(),
|
||||
attribute_name_size);
|
||||
@ -948,8 +948,8 @@ auto fuse_drive::listxattr_impl(std::string api_path, char *buffer, size_t size,
|
||||
return res;
|
||||
}
|
||||
|
||||
auto fuse_drive::removexattr_impl(std::string api_path, const char *name)
|
||||
-> api_error {
|
||||
auto fuse_drive::removexattr_impl(std::string api_path,
|
||||
const char *name) -> api_error {
|
||||
std::string attribute_name;
|
||||
#if defined(__APPLE__)
|
||||
auto res = parse_xattr_parameters(name, 0, attribute_name, api_path);
|
||||
@ -977,8 +977,8 @@ auto fuse_drive::setxattr_impl(std::string api_path, const char *name,
|
||||
uint32_t position) -> api_error {
|
||||
#else // __APPLE__
|
||||
auto fuse_drive::setxattr_impl(std::string api_path, const char *name,
|
||||
const char *value, size_t size, int flags)
|
||||
-> api_error {
|
||||
const char *value, size_t size,
|
||||
int flags) -> api_error {
|
||||
#endif
|
||||
std::string attribute_name;
|
||||
#if defined(__APPLE__)
|
||||
@ -992,7 +992,7 @@ auto fuse_drive::setxattr_impl(std::string api_path, const char *name,
|
||||
return res;
|
||||
}
|
||||
|
||||
const auto attribute_namespace =
|
||||
auto attribute_namespace =
|
||||
utils::string::contains(attribute_name, ".")
|
||||
? utils::string::split(attribute_name, '.', false)[0U]
|
||||
: "";
|
||||
@ -1053,8 +1053,8 @@ void fuse_drive::set_item_meta(const std::string &api_path,
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
auto fuse_drive::setattr_x_impl(std::string api_path, struct setattr_x *attr)
|
||||
-> api_error {
|
||||
auto fuse_drive::setattr_x_impl(std::string api_path,
|
||||
struct setattr_x *attr) -> api_error {
|
||||
bool exists{};
|
||||
auto res = provider_.is_file(api_path, exists);
|
||||
if (res != api_error::success) {
|
||||
@ -1108,7 +1108,7 @@ auto fuse_drive::setattr_x_impl(std::string api_path, struct setattr_x *attr)
|
||||
ts[0].tv_sec = attr->acctime.tv_sec;
|
||||
ts[0].tv_nsec = attr->acctime.tv_nsec;
|
||||
} else {
|
||||
struct timeval tv{};
|
||||
struct timeval tv {};
|
||||
gettimeofday(&tv, NULL);
|
||||
ts[0].tv_sec = tv.tv_sec;
|
||||
ts[0].tv_nsec = tv.tv_usec * 1000;
|
||||
@ -1153,13 +1153,12 @@ auto fuse_drive::setattr_x_impl(std::string api_path, struct setattr_x *attr)
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
auto fuse_drive::setbkuptime_impl(std::string api_path,
|
||||
const struct timespec *bkuptime)
|
||||
-> api_error {
|
||||
auto fuse_drive::setbkuptime_impl(
|
||||
std::string api_path, const struct timespec *bkuptime) -> api_error {
|
||||
return check_and_perform(
|
||||
api_path, X_OK, [&](api_meta_map &meta) -> api_error {
|
||||
const auto nanos = bkuptime->tv_nsec +
|
||||
(bkuptime->tv_nsec * utils::time::NANOS_PER_SECOND);
|
||||
auto nanos = bkuptime->tv_nsec +
|
||||
(bkuptime->tv_nsec * utils::time::NANOS_PER_SECOND);
|
||||
return provider_.set_item_meta(api_path, META_BACKUP,
|
||||
std::to_string(nanos));
|
||||
});
|
||||
@ -1169,8 +1168,8 @@ auto fuse_drive::setchgtime_impl(std::string api_path,
|
||||
const struct timespec *chgtime) -> api_error {
|
||||
return check_and_perform(
|
||||
api_path, X_OK, [&](api_meta_map &meta) -> api_error {
|
||||
const auto nanos = chgtime->tv_nsec +
|
||||
(chgtime->tv_nsec * utils::time::NANOS_PER_SECOND);
|
||||
auto nanos = chgtime->tv_nsec +
|
||||
(chgtime->tv_nsec * utils::time::NANOS_PER_SECOND);
|
||||
return provider_.set_item_meta(api_path, META_CHANGED,
|
||||
std::to_string(nanos));
|
||||
});
|
||||
@ -1180,7 +1179,7 @@ auto fuse_drive::setcrtime_impl(std::string api_path,
|
||||
const struct timespec *crtime) -> api_error {
|
||||
return check_and_perform(
|
||||
api_path, X_OK, [&](api_meta_map &meta) -> api_error {
|
||||
const auto nanos =
|
||||
auto nanos =
|
||||
crtime->tv_nsec + (crtime->tv_nsec * utils::time::NANOS_PER_SECOND);
|
||||
return provider_.set_item_meta(api_path, META_CREATION,
|
||||
std::to_string(nanos));
|
||||
@ -1191,15 +1190,15 @@ auto fuse_drive::setvolname_impl(const char * /*volname*/) -> api_error {
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
auto fuse_drive::statfs_x_impl(std::string /*api_path*/, struct statfs *stbuf)
|
||||
-> api_error {
|
||||
auto fuse_drive::statfs_x_impl(std::string /*api_path*/,
|
||||
struct statfs *stbuf) -> api_error {
|
||||
if (statfs(&config_.get_cache_directory()[0], stbuf) != 0) {
|
||||
return api_error::os_error;
|
||||
}
|
||||
|
||||
const auto total_bytes = provider_.get_total_drive_space();
|
||||
const auto total_used = provider_.get_used_drive_space();
|
||||
const auto used_blocks = utils::divide_with_ceiling(
|
||||
auto total_bytes = provider_.get_total_drive_space();
|
||||
auto total_used = provider_.get_used_drive_space();
|
||||
auto used_blocks = utils::divide_with_ceiling(
|
||||
total_used, static_cast<std::uint64_t>(stbuf->f_bsize));
|
||||
stbuf->f_blocks = utils::divide_with_ceiling(
|
||||
total_bytes, static_cast<std::uint64_t>(stbuf->f_bsize));
|
||||
@ -1217,16 +1216,15 @@ auto fuse_drive::statfs_x_impl(std::string /*api_path*/, struct statfs *stbuf)
|
||||
return api_error::success;
|
||||
}
|
||||
#else // __APPLE__
|
||||
auto fuse_drive::statfs_impl(std::string /*api_path*/, struct statvfs *stbuf)
|
||||
-> api_error {
|
||||
auto fuse_drive::statfs_impl(std::string /*api_path*/,
|
||||
struct statvfs *stbuf) -> api_error {
|
||||
if (statvfs(config_.get_cache_directory().data(), stbuf) != 0) {
|
||||
return api_error::os_error;
|
||||
}
|
||||
|
||||
const auto total_bytes = provider_.get_total_drive_space();
|
||||
const auto total_used = provider_.get_used_drive_space();
|
||||
const auto used_blocks =
|
||||
utils::divide_with_ceiling(total_used, stbuf->f_frsize);
|
||||
auto total_bytes = provider_.get_total_drive_space();
|
||||
auto total_used = provider_.get_used_drive_space();
|
||||
auto used_blocks = utils::divide_with_ceiling(total_used, stbuf->f_frsize);
|
||||
stbuf->f_files = 4294967295;
|
||||
stbuf->f_blocks = utils::divide_with_ceiling(total_bytes, stbuf->f_frsize);
|
||||
stbuf->f_bavail = stbuf->f_bfree =
|
||||
@ -1299,8 +1297,8 @@ auto fuse_drive::utimens_impl(std::string api_path, const struct timespec tv[2],
|
||||
struct fuse_file_info * /*file_info*/)
|
||||
-> api_error {
|
||||
#else
|
||||
auto fuse_drive::utimens_impl(std::string api_path, const struct timespec tv[2])
|
||||
-> api_error {
|
||||
auto fuse_drive::utimens_impl(std::string api_path,
|
||||
const struct timespec tv[2]) -> api_error {
|
||||
#endif
|
||||
api_meta_map meta;
|
||||
auto res = provider_.get_item_meta(api_path, meta);
|
||||
|
@ -71,7 +71,42 @@ TYPED_TEST(fuse_test, create_can_create_file) {
|
||||
this->unlink_file_and_test(file_path);
|
||||
}
|
||||
|
||||
TYPED_TEST(fuse_test, create_can_create_and_truncate_file) {
|
||||
TYPED_TEST(fuse_test, create_can_create_with_truncate_file) {
|
||||
std::string file_name{"create_test"};
|
||||
auto file_path = this->create_file_path(file_name);
|
||||
|
||||
auto handle = open(file_path.c_str(), O_CREAT | O_TRUNC, ACCESSPERMS);
|
||||
EXPECT_LE(1, handle);
|
||||
close(handle);
|
||||
|
||||
auto size = utils::file::file{file_path}.size();
|
||||
EXPECT_TRUE(size.has_value());
|
||||
EXPECT_EQ(0U, *size);
|
||||
|
||||
this->unlink_file_and_test(file_path);
|
||||
}
|
||||
|
||||
TYPED_TEST(fuse_test, create_can_create_or_open_and_truncate_existing_file) {
|
||||
std::string file_name{"create_test"};
|
||||
auto file_path = this->create_file_and_test(file_name);
|
||||
EXPECT_EQ(0, truncate(file_path.c_str(), 24U));
|
||||
|
||||
auto size = utils::file::file{file_path}.size();
|
||||
EXPECT_TRUE(size.has_value());
|
||||
EXPECT_EQ(24U, *size);
|
||||
|
||||
auto handle = open(file_path.c_str(), O_CREAT | O_TRUNC, ACCESSPERMS);
|
||||
EXPECT_LE(1, handle);
|
||||
close(handle);
|
||||
|
||||
size = utils::file::file{file_path}.size();
|
||||
EXPECT_TRUE(size.has_value());
|
||||
EXPECT_EQ(0U, *size);
|
||||
|
||||
this->unlink_file_and_test(file_path);
|
||||
}
|
||||
|
||||
TYPED_TEST(fuse_test, create_can_open_and_truncate_existing_file) {
|
||||
std::string file_name{"create_test"};
|
||||
auto file_path = this->create_file_and_test(file_name);
|
||||
EXPECT_EQ(0, truncate(file_path.c_str(), 24U));
|
||||
|
Loading…
x
Reference in New Issue
Block a user