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; | ||||
|       } | ||||
|  | ||||
|       ScaffoldMessenger.of(context).showSnackBar( | ||||
|         const SnackBar( | ||||
|           content: Text('Invalid username or password'), | ||||
|           behavior: SnackBarBehavior.floating, | ||||
|         ), | ||||
|       ); | ||||
|       displayErrorMessage(context, 'Invalid username or password', clear: true); | ||||
|     } | ||||
|  | ||||
|     return Scaffold( | ||||
|   | ||||
| @@ -116,6 +116,7 @@ class AppDropdownFormField<T> extends StatelessWidget { | ||||
|       decoration: createCommonDecoration( | ||||
|         scheme, | ||||
|         labelText ?? "", | ||||
|         filled: true, | ||||
|         icon: prefixIcon, | ||||
|       ), | ||||
|       dropdownColor: dropdownColor ?? effectiveFill, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user