3 Commits

Author SHA1 Message Date
a7580d9272 [Unit Test] Complete all providers unit tests #12
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2025-02-16 08:36:20 -06:00
56072da7a6 [Unit Test] Complete all providers unit tests #12 2025-02-16 08:27:28 -06:00
5cf6948c03 [Unit Test] Complete all providers unit tests #12 2025-02-16 08:19:50 -06:00
6 changed files with 115 additions and 38 deletions

View File

@ -330,7 +330,6 @@ struct directory_item final {
bool directory{false}; bool directory{false};
std::uint64_t size{}; std::uint64_t size{};
api_meta_map meta; api_meta_map meta;
bool resolved{false};
}; };
struct encrypt_config final { struct encrypt_config final {

View File

@ -285,8 +285,15 @@ auto base_provider::get_directory_items(const std::string &api_path,
if (res != api_error::success) { if (res != api_error::success) {
return res; return res;
} }
if (not exists) { if (not exists) {
return api_error::directory_not_found; res = is_file(api_path, exists);
if (res != api_error::success) {
utils::error::raise_api_path_error(
function_name, api_path, res, "failed to determine if file exists");
}
return exists ? api_error::item_exists : api_error::directory_not_found;
} }
res = get_directory_items_impl(api_path, list); res = get_directory_items_impl(api_path, list);

View File

@ -263,7 +263,6 @@ auto encrypt_provider::get_directory_items(const std::string &api_path,
dir_item.api_parent = file.api_parent; dir_item.api_parent = file.api_parent;
dir_item.api_path = file.api_path; dir_item.api_path = file.api_path;
dir_item.directory = dir_entry->is_directory_item(); dir_item.directory = dir_entry->is_directory_item();
dir_item.resolved = true;
dir_item.size = file.file_size; dir_item.size = file.file_size;
create_item_meta(dir_item.meta, dir_item.directory, file); create_item_meta(dir_item.meta, dir_item.directory, file);

View File

@ -43,9 +43,9 @@
#include "utils/time.hpp" #include "utils/time.hpp"
namespace { namespace {
[[nodiscard]] auto [[nodiscard]] auto set_request_path(auto &request,
set_request_path(auto &request, const std::string &object_name)
const std::string &object_name) -> repertory::api_error { -> repertory::api_error {
request.path = object_name; request.path = object_name;
if (request.path.substr(1U).size() > repertory::max_s3_object_name_length) { if (request.path.substr(1U).size() > repertory::max_s3_object_name_length) {
return repertory::api_error::name_too_long; return repertory::api_error::name_too_long;
@ -59,8 +59,9 @@ namespace repertory {
s3_provider::s3_provider(app_config &config, i_http_comm &comm) s3_provider::s3_provider(app_config &config, i_http_comm &comm)
: base_provider(config, comm) {} : base_provider(config, comm) {}
auto s3_provider::add_if_not_found( auto s3_provider::add_if_not_found(api_file &file,
api_file &file, const std::string &object_name) const -> api_error { const std::string &object_name) const
-> api_error {
api_meta_map meta{}; api_meta_map meta{};
auto res{get_item_meta(file.api_path, meta)}; auto res{get_item_meta(file.api_path, meta)};
if (res == api_error::item_not_found) { if (res == api_error::item_not_found) {
@ -88,7 +89,7 @@ auto s3_provider::convert_api_date(std::string_view date) -> std::uint64_t {
1000000UL, 1000000UL,
}; };
struct tm tm1 {}; struct tm tm1{};
#if defined(_WIN32) #if defined(_WIN32)
utils::time::strptime(date_time.c_str(), "%Y-%m-%dT%T", &tm1); utils::time::strptime(date_time.c_str(), "%Y-%m-%dT%T", &tm1);
return nanos + utils::time::windows_time_t_to_unix_time(_mkgmtime(&tm1)); return nanos + utils::time::windows_time_t_to_unix_time(_mkgmtime(&tm1));
@ -157,8 +158,9 @@ auto s3_provider::create_directory_impl(const std::string &api_path,
utils::path::create_api_path(is_encrypted ? meta[META_KEY] : api_path)); utils::path::create_api_path(is_encrypted ? meta[META_KEY] : api_path));
} }
auto s3_provider::create_directory_paths( auto s3_provider::create_directory_paths(const std::string &api_path,
const std::string &api_path, const std::string &key) const -> api_error { const std::string &key) const
-> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
if (api_path == "/") { if (api_path == "/") {
@ -321,8 +323,9 @@ auto s3_provider::get_directory_item_count(const std::string &api_path) const
return 0U; return 0U;
} }
auto s3_provider::get_directory_items_impl( auto s3_provider::get_directory_items_impl(const std::string &api_path,
const std::string &api_path, directory_item_list &list) const -> api_error { directory_item_list &list) const
-> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
const auto &cfg{get_s3_config()}; const auto &cfg{get_s3_config()};
@ -480,8 +483,8 @@ auto s3_provider::get_directory_items_impl(
return api_error::success; return api_error::success;
} }
auto s3_provider::get_file(const std::string &api_path, auto s3_provider::get_file(const std::string &api_path, api_file &file) const
api_file &file) const -> api_error { -> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
@ -521,8 +524,8 @@ auto s3_provider::get_file(const std::string &api_path,
return api_error::error; return api_error::error;
} }
auto s3_provider::get_file_list(api_file_list &list, auto s3_provider::get_file_list(api_file_list &list, std::string &marker) const
std::string &marker) const -> api_error { -> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
@ -612,8 +615,9 @@ auto s3_provider::get_file_list(api_file_list &list,
return api_error::error; return api_error::error;
} }
auto s3_provider::get_last_modified( auto s3_provider::get_last_modified(bool directory,
bool directory, const std::string &api_path) const -> std::uint64_t { const std::string &api_path) const
-> std::uint64_t {
bool is_encrypted{}; bool is_encrypted{};
std::string object_name; std::string object_name;
head_object_result result{}; head_object_result result{};
@ -623,9 +627,10 @@ auto s3_provider::get_last_modified(
: utils::time::get_time_now(); : utils::time::get_time_now();
} }
auto s3_provider::get_object_info( auto s3_provider::get_object_info(bool directory, const std::string &api_path,
bool directory, const std::string &api_path, bool &is_encrypted, bool &is_encrypted, std::string &object_name,
std::string &object_name, head_object_result &result) const -> api_error { head_object_result &result) const
-> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
@ -685,10 +690,12 @@ auto s3_provider::get_object_info(
return api_error::error; return api_error::error;
} }
auto s3_provider::get_object_list( auto s3_provider::get_object_list(std::string &response_data,
std::string &response_data, long &response_code, long &response_code,
std::optional<std::string> delimiter, std::optional<std::string> prefix, std::optional<std::string> delimiter,
std::optional<std::string> token) const -> bool { std::optional<std::string> prefix,
std::optional<std::string> token) const
-> bool {
curl::requests::http_get get{}; curl::requests::http_get get{};
get.allow_timeout = true; get.allow_timeout = true;
get.aws_service = "aws:amz:" + get_s3_config().region + ":s3"; get.aws_service = "aws:amz:" + get_s3_config().region + ":s3";
@ -716,8 +723,8 @@ auto s3_provider::get_total_drive_space() const -> std::uint64_t {
return std::numeric_limits<std::int64_t>::max() / std::int64_t(2); return std::numeric_limits<std::int64_t>::max() / std::int64_t(2);
} }
auto s3_provider::is_directory(const std::string &api_path, auto s3_provider::is_directory(const std::string &api_path, bool &exists) const
bool &exists) const -> api_error { -> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
@ -745,8 +752,8 @@ auto s3_provider::is_directory(const std::string &api_path,
return api_error::error; return api_error::error;
} }
auto s3_provider::is_file(const std::string &api_path, auto s3_provider::is_file(const std::string &api_path, bool &exists) const
bool &exists) const -> api_error { -> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
@ -1004,8 +1011,8 @@ auto s3_provider::rename_file(const std::string & /* from_api_path */,
return api_error::not_implemented; return api_error::not_implemented;
} }
auto s3_provider::set_meta_key(const std::string &api_path, auto s3_provider::set_meta_key(const std::string &api_path, api_meta_map &meta)
api_meta_map &meta) -> api_error { -> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
const auto &cfg{get_s3_config()}; const auto &cfg{get_s3_config()};

View File

@ -185,7 +185,6 @@ auto sia_provider::get_directory_items_impl(const std::string &api_path,
dir_item.api_path = file.api_path; dir_item.api_path = file.api_path;
dir_item.directory = directory; dir_item.directory = directory;
dir_item.meta = meta; dir_item.meta = meta;
dir_item.resolved = true;
dir_item.size = file.file_size; dir_item.size = file.file_size;
list.emplace_back(std::move(dir_item)); list.emplace_back(std::move(dir_item));
} catch (const std::exception &e) { } catch (const std::exception &e) {

View File

@ -440,17 +440,32 @@ static void get_directory_item_count(const app_config & /* cfg */,
provider.get_api_path_from_source(source_path, api_path)); provider.get_api_path_from_source(source_path, api_path));
EXPECT_EQ(std::size_t(1U), provider.get_directory_item_count(api_path)); EXPECT_EQ(std::size_t(1U), provider.get_directory_item_count(api_path));
} }
create_file(provider, "/pt01.txt");
create_file(provider, "/pt02.txt");
create_directory(provider, "/dir01");
create_directory(provider, "/dir02");
directory_item_list list{};
EXPECT_EQ(api_error::success, provider.get_directory_items("/", list));
check_forced_dirs(list);
EXPECT_GE(list.size(), std::size_t(6U));
EXPECT_EQ(api_error::success, provider.remove_file("/pt01.txt"));
EXPECT_EQ(api_error::success, provider.remove_file("/pt02.txt"));
EXPECT_EQ(api_error::success, provider.remove_directory("/dir01"));
EXPECT_EQ(api_error::success, provider.remove_directory("/dir02"));
} }
static void get_directory_items(const app_config &cfg, i_provider &provider) { static void get_directory_items(const app_config &cfg, i_provider &provider) {
fmt::println("testing|{}|{}", fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()), app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__); __FUNCTION__);
directory_item_list list{};
EXPECT_EQ(api_error::success, provider.get_directory_items("/", list));
check_forced_dirs(list);
if (provider.get_provider_type() == provider_type::encrypt) { if (provider.get_provider_type() == provider_type::encrypt) {
directory_item_list list{};
EXPECT_EQ(api_error::success, provider.get_directory_items("/", list));
check_forced_dirs(list);
EXPECT_EQ(std::size_t(4U), list.size()); EXPECT_EQ(std::size_t(4U), list.size());
directory_item_list list_decrypted{list.begin() + 2U, list.end()}; directory_item_list list_decrypted{list.begin() + 2U, list.end()};
@ -511,6 +526,49 @@ static void get_directory_items(const app_config &cfg, i_provider &provider) {
EXPECT_EQ(std::size_t(45U), file2->size); EXPECT_EQ(std::size_t(45U), file2->size);
#endif #endif
} }
create_file(provider, "/pt01.txt");
create_file(provider, "/pt02.txt");
create_directory(provider, "/dir01");
create_directory(provider, "/dir02");
directory_item_list list{};
EXPECT_EQ(api_error::success, provider.get_directory_items("/", list));
check_forced_dirs(list);
EXPECT_GE(list.size(), std::size_t(6U));
auto iter = std::ranges::find_if(
list, [](auto &&item) -> bool { return item.api_path == "/pt01.txt"; });
EXPECT_NE(iter, list.end());
EXPECT_STREQ("/", (*iter).api_parent.c_str());
EXPECT_FALSE((*iter).directory);
EXPECT_EQ(std::uint64_t{0U}, (*iter).size);
iter = std::ranges::find_if(
list, [](auto &&item) -> bool { return item.api_path == "/pt02.txt"; });
EXPECT_NE(iter, list.end());
EXPECT_STREQ("/", (*iter).api_parent.c_str());
EXPECT_FALSE((*iter).directory);
EXPECT_EQ(std::uint64_t{0U}, (*iter).size);
iter = std::ranges::find_if(
list, [](auto &&item) -> bool { return item.api_path == "/dir01"; });
EXPECT_NE(iter, list.end());
EXPECT_STREQ("/", (*iter).api_parent.c_str());
EXPECT_TRUE((*iter).directory);
EXPECT_EQ(std::uint64_t{0U}, (*iter).size);
iter = std::ranges::find_if(
list, [](auto &&item) -> bool { return item.api_path == "/dir02"; });
EXPECT_NE(iter, list.end());
EXPECT_STREQ("/", (*iter).api_parent.c_str());
EXPECT_TRUE((*iter).directory);
EXPECT_EQ(std::uint64_t{0U}, (*iter).size);
EXPECT_EQ(api_error::success, provider.remove_file("/pt01.txt"));
EXPECT_EQ(api_error::success, provider.remove_file("/pt02.txt"));
EXPECT_EQ(api_error::success, provider.remove_directory("/dir01"));
EXPECT_EQ(api_error::success, provider.remove_directory("/dir02"));
} }
static void static void
@ -542,6 +600,14 @@ static void get_directory_items_fails_if_item_is_file(const app_config &cfg,
provider.get_directory_items(api_path, list)); provider.get_directory_items(api_path, list));
EXPECT_TRUE(list.empty()); EXPECT_TRUE(list.empty());
} }
create_file(provider, "/pt01.txt");
directory_item_list list{};
EXPECT_EQ(api_error::item_exists,
provider.get_directory_items("/pt01.txt", list));
EXPECT_EQ(api_error::success, provider.remove_file("/pt01.txt"));
} }
static void get_file(const app_config &cfg, i_provider &provider) { static void get_file(const app_config &cfg, i_provider &provider) {
@ -646,13 +712,13 @@ static void run_tests(const app_config &cfg, i_provider &provider) {
get_api_path_from_source(cfg, provider); get_api_path_from_source(cfg, provider);
get_api_path_from_source_fails_if_file_not_found(cfg, provider); get_api_path_from_source_fails_if_file_not_found(cfg, provider);
// TODO: continue here
get_directory_items(cfg, provider); get_directory_items(cfg, provider);
get_directory_items_fails_if_directory_not_found(provider); get_directory_items_fails_if_directory_not_found(provider);
get_directory_items_fails_if_item_is_file(cfg, provider); get_directory_items_fails_if_item_is_file(cfg, provider);
get_directory_item_count(cfg, provider); get_directory_item_count(cfg, provider);
// TODO continue here
get_file(cfg, provider); get_file(cfg, provider);
get_file_fails_if_file_not_found(provider); get_file_fails_if_file_not_found(provider);
get_file_fails_if_item_is_directory(cfg, provider); get_file_fails_if_item_is_directory(cfg, provider);