winfsp unit tests and fixes

This commit is contained in:
Scott E. Graves 2024-10-31 10:43:41 -05:00
parent 11c58c4afb
commit 4c4db56a82
5 changed files with 71 additions and 39 deletions

View File

@ -104,8 +104,11 @@ auto winfsp_drive::winfsp_service::OnStart(ULONG /*Argc*/, PWSTR * /*Argv*/)
if ((drive_letter && not utils::file::directory(mount_location).exists())) {
auto unicode_mount_location = utils::string::from_utf8(mount_location);
host_.SetFileSystemName(unicode_mount_location.data());
if (config_.get_enable_mount_manager()) {
unicode_mount_location =
std::wstring(L"\\\\.\\") + unicode_mount_location[0U] + L":";
}
ret = host_.Mount(unicode_mount_location.data());
} else {
std::cerr << (drive_letter ? "Mount location in use: "
@ -555,7 +558,7 @@ auto winfsp_drive::Init(PVOID host) -> NTSTATUS {
std::wstring(file_system_host->FileSystemName()).substr(0, 1))
.data());
}
file_system_host->SetFileSystemName(std::wstring{REPERTORY_W}.data());
file_system_host->SetFlushAndPurgeOnCleanup(TRUE);
file_system_host->SetReparsePoints(FALSE);
file_system_host->SetReparsePointsAccessCheck(FALSE);

View File

@ -36,6 +36,7 @@
#include "utils/polling.hpp"
#include "utils/string.hpp"
#include "utils/time.hpp"
#include <utils/config.hpp>
namespace repertory {
s3_provider::s3_provider(app_config &config, i_http_comm &comm)
@ -283,6 +284,8 @@ auto s3_provider::get_directory_item_count(const std::string &api_path) const
auto s3_provider::get_directory_items_impl(const std::string &api_path,
directory_item_list &list) const
-> api_error {
REPERTORY_USES_FUNCTION_NAME();
const auto cfg = get_config().get_s3_config();
const auto is_encrypted = not cfg.encryption_token.empty();
@ -313,6 +316,8 @@ auto s3_provider::get_directory_items_impl(const std::string &api_path,
}
if (response_code != http_error_codes::ok) {
utils::error::raise_api_path_error(function_name, api_path, response_code,
"failed to get directory items");
return api_error::comm_error;
}
@ -430,6 +435,8 @@ auto s3_provider::get_file(const std::string &api_path, api_file &file) const
}
auto s3_provider::get_file_list(api_file_list &list) const -> api_error {
REPERTORY_USES_FUNCTION_NAME();
std::string response_data;
long response_code{};
if (not get_object_list(response_data, response_code)) {
@ -437,12 +444,16 @@ auto s3_provider::get_file_list(api_file_list &list) const -> api_error {
}
if (response_code != http_error_codes::ok) {
utils::error::raise_error(function_name, response_code,
"failed to get file list");
return api_error::comm_error;
}
pugi::xml_document doc;
auto res = doc.load_string(response_data.c_str());
if (res.status != pugi::xml_parse_status::status_ok) {
utils::error::raise_error(function_name, res.status,
"failed to parse xml document");
return api_error::comm_error;
}
@ -538,6 +549,8 @@ auto s3_provider::get_object_info(bool directory, const std::string &api_path,
}
if (response_code != http_error_codes::ok) {
utils::error::raise_api_path_error(function_name, api_path, response_code,
"failed to get object info");
return api_error::comm_error;
}
@ -885,6 +898,8 @@ void s3_provider::stop() {
auto s3_provider::upload_file_impl(const std::string &api_path,
const std::string &source_path,
stop_type &stop_requested) -> api_error {
REPERTORY_USES_FUNCTION_NAME();
std::uint64_t file_size{};
if (utils::file::file{source_path}.exists()) {
auto opt_size = utils::file::file{source_path}.size();
@ -926,6 +941,8 @@ auto s3_provider::upload_file_impl(const std::string &api_path,
}
if (response_code != http_error_codes::ok) {
utils::error::raise_api_path_error(function_name, api_path, response_code,
"failed to get upload file");
return api_error::comm_error;
}

View File

@ -54,6 +54,7 @@ public:
static std::string cfg_directory;
static std::unique_ptr<app_config> config;
static std::filesystem::path current_directory;
static provider_type current_provider;
static std::unique_ptr<fuse_drive> drive;
static std::vector<std::string> drive_args;
static std::unique_ptr<meta_db> meta;
@ -68,7 +69,7 @@ protected:
test::get_test_output_dir(),
{
"fuse_test",
std::to_string(static_cast<std::uint8_t>(provider_t::type)),
app_config::get_provider_name(current_provider),
});
mount_location = utils::path::combine(test_directory, {"mount"});
@ -77,9 +78,9 @@ protected:
cfg_directory = utils::path::combine(test_directory, {"cfg"});
ASSERT_TRUE(utils::file::directory(cfg_directory).create_directory());
config = std::make_unique<app_config>(provider_t::type, cfg_directory);
config = std::make_unique<app_config>(current_provider, cfg_directory);
switch (provider_t::type) {
switch (current_provider) {
case provider_type::s3: {
{
app_config src_cfg{
@ -232,6 +233,9 @@ std::unique_ptr<app_config> fuse_test<provider_t>::config{};
template <typename provider_t>
std::filesystem::path fuse_test<provider_t>::current_directory{};
template <typename provider_t>
provider_type winfsp_test<provider_t>::current_provider{provider_t::type};
template <typename provider_t>
std::unique_ptr<fuse_drive> fuse_test<provider_t>::drive{};

View File

@ -53,6 +53,7 @@ public:
static std::string mount_location;
static std::unique_ptr<i_provider> provider;
static std::string test_directory;
static provider_type current_provider;
protected:
static void SetUpTestCase() {
@ -62,7 +63,7 @@ protected:
test::get_test_output_dir(),
{
"winfsp_test",
std::to_string(static_cast<std::uint8_t>(provider_t::type)),
app_config::get_provider_name(current_provider),
});
mount_location = "U:";
@ -70,9 +71,9 @@ protected:
cfg_directory = utils::path::combine(test_directory, {"cfg"});
ASSERT_TRUE(utils::file::directory(cfg_directory).create_directory());
config = std::make_unique<app_config>(provider_t::type, cfg_directory);
config = std::make_unique<app_config>(current_provider, cfg_directory);
switch (provider_t::type) {
switch (current_provider) {
case provider_type::s3: {
{
app_config src_cfg{
@ -230,6 +231,9 @@ std::unique_ptr<app_config> winfsp_test<provider_t>::config;
template <typename provider_t>
std::filesystem::path winfsp_test<provider_t>::current_directory;
template <typename provider_t>
provider_type winfsp_test<provider_t>::current_provider{provider_t::type};
template <typename provider_t>
std::unique_ptr<winfsp_drive> winfsp_test<provider_t>::drive;

View File

@ -31,31 +31,11 @@ namespace repertory {
TYPED_TEST_CASE(winfsp_test, winfsp_provider_types);
TYPED_TEST(winfsp_test, cr8_nl_can_create_file_of_max_component_length) {
if (this->current_provider != provider_type::s3) {
DWORD max_length{};
EXPECT_TRUE(::GetVolumeInformationA(this->mount_location.c_str(), nullptr, 0,
nullptr, &max_length, nullptr, nullptr,
0));
EXPECT_EQ(255U, max_length);
auto file_path = utils::path::combine(this->mount_location,
{
std::string(max_length - 1U, 'a'),
});
auto handle =
::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
EXPECT_NE(INVALID_HANDLE_VALUE, handle);
EXPECT_TRUE(::CloseHandle(handle));
}
TYPED_TEST(winfsp_test,
cr8_nl_can_not_create_file_greater_than_max_component_length) {
DWORD max_length{};
EXPECT_TRUE(::GetVolumeInformationA(this->mount_location.c_str(), nullptr, 0,
nullptr, &max_length, nullptr, nullptr,
0));
EXPECT_TRUE(::GetVolumeInformationA(this->mount_location.c_str(), nullptr,
0, nullptr, &max_length, nullptr,
nullptr, 0));
EXPECT_EQ(255U, max_length);
auto file_path = utils::path::combine(this->mount_location,
@ -63,12 +43,36 @@ TYPED_TEST(winfsp_test,
std::string(max_length, 'a'),
});
auto handle =
::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
EXPECT_NE(INVALID_HANDLE_VALUE, handle);
EXPECT_TRUE(::CloseHandle(handle));
}
}
TYPED_TEST(winfsp_test,
cr8_nl_can_not_create_file_greater_than_max_component_length) {
if (this->current_provider != provider_type::s3) {
DWORD max_length{};
EXPECT_TRUE(::GetVolumeInformationA(this->mount_location.c_str(), nullptr,
0, nullptr, &max_length, nullptr,
nullptr, 0));
EXPECT_EQ(255U, max_length);
auto file_path = utils::path::combine(this->mount_location,
{
std::string(max_length + 1U, 'a'),
});
auto handle =
::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, 0);
EXPECT_EQ(INVALID_HANDLE_VALUE, handle);
EXPECT_EQ(ERROR_INVALID_NAME, ::GetLastError());
}
}
} // namespace repertory