From 8fa8724803d1adb91cd5bcf78aef0f488f844205 Mon Sep 17 00:00:00 2001 From: Stefan Chivu Date: Thu, 10 Nov 2022 10:28:53 +0200 Subject: [PATCH] test/dokan: Added dokan max path test Signed-off-by: Stefan Chivu --- src/test/dokan/dokan.cc | 118 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/src/test/dokan/dokan.cc b/src/test/dokan/dokan.cc index 9ff7894e54f1e..1a1d39580e6dd 100644 --- a/src/test/dokan/dokan.cc +++ b/src/test/dokan/dokan.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include "gtest/gtest.h" @@ -139,6 +140,28 @@ void map_dokan_read_only( << std::endl; } +void map_dokan_with_maxpath( + SubProcess** mount, + const char* mountpoint, + uint64_t max_path_len) +{ + SubProcess* new_mount = new SubProcess("ceph-dokan"); + new_mount->add_cmd_args("map", "--debug", "--dokan-stderr", + "--win-vol-name", "TestCeph", + "--win-vol-serial", TEST_VOL_SERIAL, + "--max-path-len", + (std::to_string(max_path_len)).c_str(), + "-l", mountpoint, NULL); + + *mount = new_mount; + ASSERT_EQ(new_mount->spawn(), 0); + if (256 <= max_path_len && max_path_len <= 4096) { + ASSERT_EQ(wait_for_mount(mountpoint), 0); + } else { + ASSERT_NE(wait_for_mount(mountpoint), 0); + } +} + void unmap_dokan(SubProcess* mount, const char* mountpoint) { std::string ret = run_cmd("ceph-dokan", "unmap", "-l", mountpoint, (char*)NULL); @@ -149,6 +172,28 @@ void unmap_dokan(SubProcess* mount, const char* mountpoint) { ASSERT_EQ(mount->join(), 0); } +int get_volume_max_path(std::string mountpoint){ + char volume_name[MAX_PATH + 1] = { 0 }; + char file_system_name[MAX_PATH + 1] = { 0 }; + DWORD serial_number = 0; + DWORD max_component_len = 0; + DWORD file_system_flags = 0; + if (GetVolumeInformation( + mountpoint.c_str(), + volume_name, + sizeof(volume_name), + &serial_number, + &max_component_len, + &file_system_flags, + file_system_name, + sizeof(file_system_name)) != TRUE) { + std::cerr << "GetVolumeInformation() failed, error: " + << GetLastError() << std::endl; + } + + return max_component_len; +} + static SubProcess* shared_mount = nullptr; class DokanTests : public testing::Test @@ -353,6 +398,79 @@ TEST_F(DokanTests, test_move_file) { ASSERT_NE(fs::remove_all(dir2_path),0); } +TEST_F(DokanTests, test_max_path) { + std::string mountpoint = "P:\\"; + std::string extended_mountpoint = "\\\\?\\" + mountpoint; + SubProcess* mount = nullptr; + char dir[200] = { 0 }; + char file[200] = { 0 }; + std::string data = "abcd1234"; + + memset(dir, 'd', sizeof(dir) - 1); + memset(file, 'f', sizeof(file) - 1); + + uint64_t max_path_len = 4096; + + map_dokan_with_maxpath(&mount, + mountpoint.c_str(), + max_path_len); + EXPECT_EQ(get_volume_max_path(extended_mountpoint), + max_path_len); + + std::string long_dir_path = extended_mountpoint; + + std::string dir_names[15]; + + for (int i = 0; i < 15; i++) { + std::string crt_dir = std::string(dir) + "_" + + get_uuid() + "\\"; + long_dir_path.append(crt_dir); + int stat = _mkdir(long_dir_path.c_str()); + ASSERT_EQ(stat, 0) << "Error creating directory " << i + << ": " << GetLastError() << std::endl; + dir_names[i] = crt_dir; + } + std::string file_path = long_dir_path + "\\" + std::string(file) + + "_" + get_uuid(); + + check_write_file(file_path, data); + + // clean-up + // fs::remove is unable to handle long Windows paths + EXPECT_NE(DeleteFileA(file_path.c_str()), 0); + + for (int i = 14; i >= 0; i--) { + std::string remove_dir = extended_mountpoint; + for (int j = 0; j <= i; j++) { + remove_dir.append(dir_names[j]); + } + + EXPECT_NE(RemoveDirectoryA(remove_dir.c_str()), 0); + } + + unmap_dokan(mount, mountpoint.c_str()); + + // value exceeds 32767, so a failure is expected + max_path_len = 32770; + map_dokan_with_maxpath(&mount, + mountpoint.c_str(), + max_path_len); + ASSERT_FALSE(fs::exists(mountpoint)); + + // value is below 256, so a failure is expected + max_path_len = 150; + map_dokan_with_maxpath(&mount, + mountpoint.c_str(), + max_path_len); + ASSERT_FALSE(fs::exists(mountpoint)); + + // default value + map_dokan(&mount, mountpoint.c_str()); + EXPECT_EQ(get_volume_max_path(mountpoint.c_str()), 256); + + unmap_dokan(mount, mountpoint.c_str()); +} + TEST_F(DokanTests, test_set_eof) { std::string file_path = DEFAULT_MOUNTPOINT"test_eof_" + get_uuid(); -- 2.39.5