This commit is contained in:
531
repertory/repertory_test/include/fixtures/drive_fixture.hpp
Normal file
531
repertory/repertory_test/include/fixtures/drive_fixture.hpp
Normal file
@@ -0,0 +1,531 @@
|
|||||||
|
/*
|
||||||
|
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
#ifndef REPERTORY_TEST_INCLUDE_FIXTURES_PLATFORM_FIXTURE_HPP
|
||||||
|
#define REPERTORY_TEST_INCLUDE_FIXTURES_PLATFORM_FIXTURE_HPP
|
||||||
|
|
||||||
|
#include "test_common.hpp"
|
||||||
|
|
||||||
|
#include "app_config.hpp"
|
||||||
|
#include "platform/platform.hpp"
|
||||||
|
#include "types/repertory.hpp"
|
||||||
|
#include "utils/file_utils.hpp"
|
||||||
|
#include "utils/path.hpp"
|
||||||
|
#include "utils/utils.hpp"
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#include "drives/winfsp/remotewinfsp/remote_winfsp_drive.hpp"
|
||||||
|
#include "drives/winfsp/winfsp_drive.hpp"
|
||||||
|
#include "providers/i_provider.hpp"
|
||||||
|
#include "providers/s3/s3_provider.hpp"
|
||||||
|
#include "providers/sia/sia_provider.hpp"
|
||||||
|
#else
|
||||||
|
#include "comm/curl/curl_comm.hpp"
|
||||||
|
#include "db/i_meta_db.hpp"
|
||||||
|
#include "db/meta_db.hpp"
|
||||||
|
#include "drives/fuse/fuse_drive.hpp"
|
||||||
|
#include "providers/encrypt/encrypt_provider.hpp"
|
||||||
|
#include "providers/s3/s3_provider.hpp"
|
||||||
|
#include "providers/sia/sia_provider.hpp"
|
||||||
|
#if !defined(ACCESSPERMS)
|
||||||
|
#define ACCESSPERMS (S_IRWXU | S_IRWXG | S_IRWXO) /* 0777 */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
std::atomic<std::size_t> provider_idx{0U};
|
||||||
|
constexpr auto SLEEP_SECONDS{1.5s};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace repertory {
|
||||||
|
struct local_s3_no_encryption final {
|
||||||
|
static constexpr provider_type type{provider_type::s3};
|
||||||
|
static constexpr provider_type type2{provider_type::s3};
|
||||||
|
static constexpr std::uint16_t remote_port{41000U};
|
||||||
|
static constexpr bool force_legacy_encryption{false};
|
||||||
|
static constexpr std::string_view encryption_token{""};
|
||||||
|
};
|
||||||
|
struct local_s3_encryption final {
|
||||||
|
static constexpr provider_type type{provider_type::s3};
|
||||||
|
static constexpr provider_type type2{provider_type::s3};
|
||||||
|
static constexpr std::uint16_t remote_port{41000U};
|
||||||
|
static constexpr bool force_legacy_encryption{false};
|
||||||
|
static constexpr std::string_view encryption_token{"encryption_token"};
|
||||||
|
};
|
||||||
|
struct local_s3_legacy_encryption final {
|
||||||
|
static constexpr provider_type type{provider_type::s3};
|
||||||
|
static constexpr provider_type type2{provider_type::s3};
|
||||||
|
static constexpr std::uint16_t remote_port{41000U};
|
||||||
|
static constexpr bool force_legacy_encryption{true};
|
||||||
|
static constexpr std::string_view encryption_token{"encryption_token"};
|
||||||
|
};
|
||||||
|
struct remote_s3_no_encryption final {
|
||||||
|
static constexpr provider_type type{provider_type::remote};
|
||||||
|
static constexpr provider_type type2{provider_type::s3};
|
||||||
|
static constexpr std::uint16_t remote_port{41000U};
|
||||||
|
static constexpr bool force_legacy_encryption{false};
|
||||||
|
static constexpr std::string_view encryption_token{""};
|
||||||
|
};
|
||||||
|
struct remote_s3_encryption final {
|
||||||
|
static constexpr provider_type type{provider_type::remote};
|
||||||
|
static constexpr provider_type type2{provider_type::s3};
|
||||||
|
static constexpr std::uint16_t remote_port{41000U};
|
||||||
|
static constexpr bool force_legacy_encryption{false};
|
||||||
|
static constexpr std::string_view encryption_token{"encryption_token"};
|
||||||
|
};
|
||||||
|
struct remote_s3_legacy_encryption final {
|
||||||
|
static constexpr provider_type type{provider_type::remote};
|
||||||
|
static constexpr provider_type type2{provider_type::s3};
|
||||||
|
static constexpr std::uint16_t remote_port{41000U};
|
||||||
|
static constexpr bool force_legacy_encryption{true};
|
||||||
|
static constexpr std::string_view encryption_token{"encryption_token"};
|
||||||
|
};
|
||||||
|
struct local_sia final {
|
||||||
|
static constexpr provider_type type{provider_type::sia};
|
||||||
|
static constexpr provider_type type2{provider_type::sia};
|
||||||
|
static constexpr std::uint16_t remote_port{41001U};
|
||||||
|
static constexpr bool force_legacy_encryption{false};
|
||||||
|
static constexpr std::string_view encryption_token{""};
|
||||||
|
};
|
||||||
|
struct remote_sia final {
|
||||||
|
static constexpr provider_type type{provider_type::remote};
|
||||||
|
static constexpr provider_type type2{provider_type::sia};
|
||||||
|
static constexpr std::uint16_t remote_port{41001U};
|
||||||
|
static constexpr bool force_legacy_encryption{false};
|
||||||
|
static constexpr std::string_view encryption_token{""};
|
||||||
|
};
|
||||||
|
struct remote_winfsp_to_linux final {
|
||||||
|
static constexpr provider_type type{provider_type::remote};
|
||||||
|
static constexpr provider_type type2{provider_type::unknown};
|
||||||
|
static constexpr std::uint16_t remote_port{41002U};
|
||||||
|
static constexpr bool force_legacy_encryption{false};
|
||||||
|
static constexpr std::string_view encryption_token{""};
|
||||||
|
};
|
||||||
|
struct remote_linux_to_winfsp final {
|
||||||
|
static constexpr provider_type type{provider_type::remote};
|
||||||
|
static constexpr provider_type type2{provider_type::unknown};
|
||||||
|
static constexpr std::uint16_t remote_port{41002U};
|
||||||
|
static constexpr bool force_legacy_encryption{false};
|
||||||
|
static constexpr std::string_view encryption_token{""};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct platform_ops {
|
||||||
|
static void ensure_process_cwd() {
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
EXPECT_TRUE(utils::file::change_to_process_directory());
|
||||||
|
#endif // !defined(_WIN32)
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string build_cmd(const std::string &args_joined, bool is_mount) {
|
||||||
|
#if defined(_WIN32)
|
||||||
|
if (is_mount) {
|
||||||
|
return "start .\\repertory.exe -f " + args_joined;
|
||||||
|
}
|
||||||
|
return ".\\repertory.exe " + args_joined;
|
||||||
|
#else // !defined(_WIN32)
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
constexpr const char *kBin = "./repertory.app/Contents/MacOS/repertory ";
|
||||||
|
#else // !defined(__APPLE__)
|
||||||
|
constexpr const char *kBin = "./repertory ";
|
||||||
|
#endif // defined(__APPLE__)
|
||||||
|
return std::string(kBin) + args_joined;
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
}
|
||||||
|
|
||||||
|
static void execute_mount(std::vector<std::string> args_without_location,
|
||||||
|
const std::string &location) {
|
||||||
|
ensure_process_cwd();
|
||||||
|
args_without_location.emplace_back(location);
|
||||||
|
|
||||||
|
const auto cmd = build_cmd(utils::string::join(args_without_location, ' '),
|
||||||
|
/*is_mount*/ true);
|
||||||
|
std::cout << "mount command: " << cmd << std::endl;
|
||||||
|
|
||||||
|
ASSERT_EQ(0, system(cmd.c_str()));
|
||||||
|
std::this_thread::sleep_for(5s);
|
||||||
|
ASSERT_TRUE(utils::file::directory{location}.exists());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void execute_unmount(std::vector<std::string> args_without_unmount,
|
||||||
|
const std::string &location) {
|
||||||
|
ensure_process_cwd();
|
||||||
|
args_without_unmount.emplace_back("-unmount");
|
||||||
|
|
||||||
|
const auto cmd = build_cmd(utils::string::join(args_without_unmount, ' '),
|
||||||
|
/*is_mount*/ false);
|
||||||
|
std::cout << "unmount command: " << cmd << std::endl;
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
std::this_thread::sleep_for(10s);
|
||||||
|
bool unmounted = false;
|
||||||
|
for (int i = 0; !unmounted && i < 6; ++i) {
|
||||||
|
(void)system(cmd.c_str());
|
||||||
|
unmounted = !utils::file::directory{location}.exists();
|
||||||
|
if (!unmounted)
|
||||||
|
std::this_thread::sleep_for(5s);
|
||||||
|
}
|
||||||
|
ASSERT_TRUE(unmounted);
|
||||||
|
#else // !defined(_WIN32)
|
||||||
|
auto res = system(cmd.c_str());
|
||||||
|
EXPECT_EQ(0, res);
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename provider_t> class drive_fixture : public ::testing::Test {
|
||||||
|
public:
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
static std::unique_ptr<app_config> config;
|
||||||
|
static std::unique_ptr<i_meta_db> meta;
|
||||||
|
#endif // !defined(_WIN32)
|
||||||
|
static std::filesystem::path current_directory;
|
||||||
|
static provider_type current_provider;
|
||||||
|
static std::vector<std::string> drive_args;
|
||||||
|
static std::vector<std::string> drive_args2;
|
||||||
|
static std::string mount_location;
|
||||||
|
static std::string mount_location2;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void SetUpTestCase() {
|
||||||
|
current_directory = std::filesystem::current_path();
|
||||||
|
|
||||||
|
const auto make_test_dir = [](std::string_view suite,
|
||||||
|
std::string_view sub) {
|
||||||
|
return utils::path::combine(test::get_test_output_dir(),
|
||||||
|
{std::string(suite), std::string(sub)});
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto make_cfg_dir = [](const std::string &root,
|
||||||
|
std::string_view name) {
|
||||||
|
auto cfg = utils::path::combine(root, {std::string(name)});
|
||||||
|
ASSERT_TRUE(utils::file::directory(cfg).create_directory());
|
||||||
|
return cfg;
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto configure_s3 = [](app_config &cfg_obj) {
|
||||||
|
app_config src_cfg{
|
||||||
|
provider_type::s3,
|
||||||
|
utils::path::combine(test::get_test_config_dir(), {"s3"})};
|
||||||
|
auto cfg = src_cfg.get_s3_config();
|
||||||
|
cfg.force_legacy_encryption = provider_t::force_legacy_encryption;
|
||||||
|
cfg.encryption_token = provider_t::encryption_token;
|
||||||
|
|
||||||
|
cfg_obj.set_enable_drive_events(true);
|
||||||
|
cfg_obj.set_event_level(event_level::trace);
|
||||||
|
cfg_obj.set_s3_config(cfg);
|
||||||
|
|
||||||
|
auto r = cfg_obj.get_remote_mount();
|
||||||
|
r.enable = true;
|
||||||
|
r.api_port = provider_t::remote_port;
|
||||||
|
cfg_obj.set_remote_mount(r);
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto configure_sia = [](app_config &cfg_obj) {
|
||||||
|
app_config src_cfg{
|
||||||
|
provider_type::sia,
|
||||||
|
utils::path::combine(test::get_test_config_dir(), {"sia"})};
|
||||||
|
|
||||||
|
cfg_obj.set_enable_drive_events(true);
|
||||||
|
cfg_obj.set_event_level(event_level::trace);
|
||||||
|
cfg_obj.set_host_config(src_cfg.get_host_config());
|
||||||
|
cfg_obj.set_sia_config(src_cfg.get_sia_config());
|
||||||
|
|
||||||
|
auto r = cfg_obj.get_remote_mount();
|
||||||
|
r.enable = true;
|
||||||
|
r.api_port = provider_t::remote_port;
|
||||||
|
cfg_obj.set_remote_mount(r);
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto mount_local_s3 = [&](bool as_remote) {
|
||||||
|
const auto test_dir = make_test_dir(
|
||||||
|
#if defined(_WIN32)
|
||||||
|
"winfsp_test",
|
||||||
|
#else // !defined(_WIN32)
|
||||||
|
"fuse_test",
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
fmt::format("{}_{}", app_config::get_provider_name(current_provider),
|
||||||
|
as_remote));
|
||||||
|
#if defined(_WIN32)
|
||||||
|
mount_location = utils::string::to_lower(std::string{"U:"});
|
||||||
|
#else // !defined(_WIN32)
|
||||||
|
mount_location = utils::path::combine(test_dir, {"mount"});
|
||||||
|
ASSERT_TRUE(utils::file::directory(mount_location).create_directory());
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
|
auto cfg_dir = make_cfg_dir(test_dir, "cfg");
|
||||||
|
auto cfg = std::make_unique<app_config>(provider_type::s3, cfg_dir);
|
||||||
|
configure_s3(*cfg);
|
||||||
|
|
||||||
|
drive_args = {"-dd", cfg->get_data_directory(), "-s3", "-na", "s3"};
|
||||||
|
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
cfg->set_database_type(database_type::sqlite);
|
||||||
|
config = std::move(cfg);
|
||||||
|
meta = create_meta_db(*config);
|
||||||
|
#endif // !defined(_WIN32)
|
||||||
|
|
||||||
|
platform_ops::execute_mount(drive_args, mount_location);
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto mount_local_sia = [&](bool as_remote) {
|
||||||
|
const auto test_dir = make_test_dir(
|
||||||
|
#if defined(_WIN32)
|
||||||
|
"winfsp_test",
|
||||||
|
#else // !defined(_WIN32)
|
||||||
|
"fuse_test",
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
fmt::format("{}_{}", app_config::get_provider_name(current_provider),
|
||||||
|
as_remote));
|
||||||
|
#if defined(_WIN32)
|
||||||
|
mount_location = utils::string::to_lower(std::string{"U:"});
|
||||||
|
#else // !defined(_WIN32)
|
||||||
|
mount_location = utils::path::combine(test_dir, {"mount"});
|
||||||
|
ASSERT_TRUE(utils::file::directory(mount_location).create_directory());
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
|
auto cfg_dir = make_cfg_dir(test_dir, "cfg");
|
||||||
|
auto cfg = std::make_unique<app_config>(provider_type::sia, cfg_dir);
|
||||||
|
configure_sia(*cfg);
|
||||||
|
|
||||||
|
drive_args = {"-dd", cfg->get_data_directory(), "-na", "sia"};
|
||||||
|
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
cfg->set_database_type(database_type::sqlite);
|
||||||
|
config = std::move(cfg);
|
||||||
|
meta = create_meta_db(*config);
|
||||||
|
#endif // !defined(_WIN32)
|
||||||
|
|
||||||
|
platform_ops::execute_mount(drive_args, mount_location);
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto mount_remote = [&] {
|
||||||
|
const auto test_dir = make_test_dir(
|
||||||
|
#if defined(_WIN32)
|
||||||
|
"winfsp_test",
|
||||||
|
#else // !defined(_WIN32)
|
||||||
|
"fuse_test",
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
fmt::format("{}_{}_{}",
|
||||||
|
app_config::get_provider_name(provider_t::type),
|
||||||
|
app_config::get_provider_name(provider_t::type2),
|
||||||
|
provider_t::remote_port));
|
||||||
|
|
||||||
|
mount_location2 = mount_location;
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
mount_location = utils::string::to_lower(std::string{"V:"});
|
||||||
|
#else // !defined(_WIN32)
|
||||||
|
mount_location = utils::path::combine(test_dir, {"mount"});
|
||||||
|
ASSERT_TRUE(utils::file::directory(mount_location).create_directory());
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
|
auto cfg_dir2 = make_cfg_dir(test_dir, "cfg2");
|
||||||
|
auto cfg2 = std::make_unique<app_config>(provider_type::remote, cfg_dir2);
|
||||||
|
cfg2->set_enable_drive_events(true);
|
||||||
|
cfg2->set_event_level(event_level::trace);
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
cfg2->set_database_type(database_type::sqlite);
|
||||||
|
#endif // !defined(_WIN32)
|
||||||
|
|
||||||
|
drive_args2 = {"-dd", cfg2->get_data_directory(), "-rm",
|
||||||
|
fmt::format("localhost:{}", provider_t::remote_port)};
|
||||||
|
|
||||||
|
platform_ops::execute_mount(drive_args2, mount_location);
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (provider_t::type) {
|
||||||
|
case provider_type::s3: {
|
||||||
|
mount_local_s3(false);
|
||||||
|
} break;
|
||||||
|
case provider_type::sia: {
|
||||||
|
mount_local_sia(false);
|
||||||
|
} break;
|
||||||
|
case provider_type::remote: {
|
||||||
|
switch (provider_t::type2) {
|
||||||
|
case provider_type::s3:
|
||||||
|
mount_local_s3(true);
|
||||||
|
break;
|
||||||
|
case provider_type::sia:
|
||||||
|
mount_local_sia(true);
|
||||||
|
break;
|
||||||
|
case provider_type::unknown:
|
||||||
|
mount_remote();
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("remote provider type is not implemented");
|
||||||
|
}
|
||||||
|
mount_remote();
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("provider type is not implemented");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TearDownTestCase() {
|
||||||
|
if (provider_t::type == provider_type::remote) {
|
||||||
|
platform_ops::execute_unmount(drive_args2, mount_location);
|
||||||
|
if (provider_t::type2 != provider_type::unknown) {
|
||||||
|
platform_ops::execute_unmount(drive_args, mount_location2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
platform_ops::execute_unmount(drive_args, mount_location);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
meta.reset();
|
||||||
|
config.reset();
|
||||||
|
#endif // !defined(_WIN32)
|
||||||
|
std::filesystem::current_path(current_directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
public:
|
||||||
|
static auto create_file_path(std::string &file_name) {
|
||||||
|
file_name += std::to_string(++provider_idx);
|
||||||
|
return utils::path::combine(mount_location, {file_name});
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto create_file_and_test(std::string &file_name, mode_t perms)
|
||||||
|
-> std::string {
|
||||||
|
file_name += std::to_string(++provider_idx);
|
||||||
|
auto file_path = utils::path::combine(mount_location, {file_name});
|
||||||
|
|
||||||
|
auto handle = open(file_path.c_str(), O_CREAT | O_EXCL | O_RDWR, perms);
|
||||||
|
EXPECT_LE(1, handle);
|
||||||
|
|
||||||
|
auto opt_size = utils::file::file{file_path}.size();
|
||||||
|
EXPECT_TRUE(opt_size.has_value());
|
||||||
|
if (opt_size.has_value()) {
|
||||||
|
EXPECT_EQ(0U, opt_size.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ(0, close(handle));
|
||||||
|
|
||||||
|
EXPECT_TRUE(utils::file::file(file_path).exists());
|
||||||
|
EXPECT_FALSE(utils::file::directory(file_path).exists());
|
||||||
|
|
||||||
|
struct stat64 u_stat{};
|
||||||
|
EXPECT_EQ(0, stat64(file_path.c_str(), &u_stat));
|
||||||
|
EXPECT_EQ(getgid(), u_stat.st_gid);
|
||||||
|
EXPECT_EQ(getuid(), u_stat.st_uid);
|
||||||
|
|
||||||
|
return file_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto create_file_and_test(std::string &file_name) -> std::string {
|
||||||
|
return create_file_and_test(file_name, ACCESSPERMS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto create_directory_and_test(std::string &dir_name, mode_t perms)
|
||||||
|
-> std::string {
|
||||||
|
dir_name += std::to_string(++provider_idx);
|
||||||
|
|
||||||
|
auto dir_path = utils::path::combine(mount_location, {dir_name});
|
||||||
|
mkdir(dir_path.c_str(), perms);
|
||||||
|
|
||||||
|
EXPECT_TRUE(utils::file::directory(dir_path).exists());
|
||||||
|
EXPECT_EQ(0U, utils::file::directory(dir_path).count(false));
|
||||||
|
EXPECT_EQ(0U, utils::file::directory(dir_path).count(true));
|
||||||
|
EXPECT_FALSE(utils::file::file(dir_path).exists());
|
||||||
|
|
||||||
|
struct stat64 u_stat{};
|
||||||
|
EXPECT_EQ(0, stat64(dir_path.c_str(), &u_stat));
|
||||||
|
EXPECT_EQ(getgid(), u_stat.st_gid);
|
||||||
|
EXPECT_EQ(getuid(), u_stat.st_uid);
|
||||||
|
|
||||||
|
return dir_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto create_directory_and_test(std::string &dir_name) -> std::string {
|
||||||
|
return create_directory_and_test(dir_name, ACCESSPERMS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto create_root_file(std::string &file_name) -> std::string {
|
||||||
|
auto file_path = create_file_and_test(file_name);
|
||||||
|
auto api_path = utils::path::create_api_path(file_name);
|
||||||
|
|
||||||
|
[[maybe_unused]] auto res =
|
||||||
|
meta->set_item_meta(api_path, {{META_UID, "0"}, {META_GID, "0"}});
|
||||||
|
std::this_thread::sleep_for(SLEEP_SECONDS);
|
||||||
|
|
||||||
|
return file_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rmdir_and_test(std::string_view dir_path) {
|
||||||
|
EXPECT_TRUE(utils::file::directory(dir_path).remove());
|
||||||
|
EXPECT_FALSE(utils::file::directory(dir_path).exists());
|
||||||
|
EXPECT_FALSE(utils::file::file(dir_path).exists());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unlink_file_and_test(std::string_view file_path) {
|
||||||
|
EXPECT_TRUE(utils::file::file(file_path).remove());
|
||||||
|
EXPECT_FALSE(utils::file::file(file_path).exists());
|
||||||
|
EXPECT_FALSE(utils::file::directory(file_path).exists());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unlink_root_file(const std::string &file_path) {
|
||||||
|
auto api_path = utils::path::create_api_path(
|
||||||
|
utils::path::strip_to_file_name(file_path));
|
||||||
|
|
||||||
|
[[maybe_unused]] auto res =
|
||||||
|
meta->set_item_meta(api_path, {{META_UID, std::to_string(getuid())},
|
||||||
|
{ META_GID,
|
||||||
|
std::to_string(getgid()) }});
|
||||||
|
std::this_thread::sleep_for(SLEEP_SECONDS);
|
||||||
|
|
||||||
|
unlink_file_and_test(file_path);
|
||||||
|
}
|
||||||
|
#endif // !defined(_WIN32)
|
||||||
|
};
|
||||||
|
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
template <typename provider_t>
|
||||||
|
std::unique_ptr<app_config> drive_fixture<provider_t>::config;
|
||||||
|
template <typename provider_t>
|
||||||
|
std::unique_ptr<i_meta_db> drive_fixture<provider_t>::meta{};
|
||||||
|
#endif // !defined(_WIN32)
|
||||||
|
|
||||||
|
template <typename provider_t>
|
||||||
|
std::filesystem::path drive_fixture<provider_t>::current_directory;
|
||||||
|
template <typename provider_t>
|
||||||
|
provider_type drive_fixture<provider_t>::current_provider{provider_t::type2};
|
||||||
|
template <typename provider_t>
|
||||||
|
std::vector<std::string> drive_fixture<provider_t>::drive_args;
|
||||||
|
template <typename provider_t>
|
||||||
|
std::vector<std::string> drive_fixture<provider_t>::drive_args2;
|
||||||
|
template <typename provider_t>
|
||||||
|
std::string drive_fixture<provider_t>::mount_location;
|
||||||
|
template <typename provider_t>
|
||||||
|
std::string drive_fixture<provider_t>::mount_location2;
|
||||||
|
|
||||||
|
using platform_provider_types =
|
||||||
|
::testing::Types<local_s3_no_encryption, local_s3_encryption,
|
||||||
|
local_s3_legacy_encryption, remote_s3_no_encryption,
|
||||||
|
remote_s3_encryption, remote_s3_legacy_encryption,
|
||||||
|
local_sia, remote_sia>;
|
||||||
|
#if defined(_WIN32)
|
||||||
|
using winfsp_test = drive_fixture;
|
||||||
|
#else
|
||||||
|
using fuse_test = drive_fixture;
|
||||||
|
#endif
|
||||||
|
} // namespace repertory
|
||||||
|
|
||||||
|
#endif // REPERTORY_TEST_INCLUDE_FIXTURES_PLATFORM_FIXTURE_HPP
|
@@ -60,12 +60,7 @@ class _AuthScreenState extends State<AuthScreen> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
displayErrorMessage(context, 'Invalid username or password', clear: true);
|
||||||
const SnackBar(
|
|
||||||
content: Text('Invalid username or password'),
|
|
||||||
behavior: SnackBarBehavior.floating,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
@@ -116,6 +116,7 @@ class AppDropdownFormField<T> extends StatelessWidget {
|
|||||||
decoration: createCommonDecoration(
|
decoration: createCommonDecoration(
|
||||||
scheme,
|
scheme,
|
||||||
labelText ?? "",
|
labelText ?? "",
|
||||||
|
filled: true,
|
||||||
icon: prefixIcon,
|
icon: prefixIcon,
|
||||||
),
|
),
|
||||||
dropdownColor: dropdownColor ?? effectiveFill,
|
dropdownColor: dropdownColor ?? effectiveFill,
|
||||||
|
Reference in New Issue
Block a user