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