mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Test with long paths on Windows
Long paths can be greater than 260 characters long, but each path component is still limited to 255 characters. The latter is also commonly the component length limit on Linux. Support for long paths requires Windows 10 1607 or later and a Registry value to be set[1], so to make the cause of test failures clearer when that isn't the case, there's one test that checks that Registry value is set, and long paths are not used in the other tests if it isn't set, so only that one test should failed if the system isn't configured as expected. GitHub Action's Windows runners do have the Registry value set[2]. This doesn't set the manifest for the Rust tests because it seems to be very difficult to set a manifest for only the tests, and it's not worth the effort when the only tests that fail are those that try to create a symlink, especially since those cases are also covered by the C++ tests. [1]: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry#enable-long-paths-in-windows-10-version-1607-and-later [2]: https://github.com/actions/runner-images/blob/releases/win22/20250921/images/windows/scripts/build/Configure-BaseImage.ps1#L73
This commit is contained in:
@@ -66,6 +66,9 @@ set(LIBLOOT_INTERFACE_TESTS_ALL_SOURCES
|
||||
"${PROJECT_SOURCE_DIR}/src/tests/test_helpers.h"
|
||||
"${PROJECT_SOURCE_DIR}/src/tests/printers.h")
|
||||
|
||||
if(MSVC)
|
||||
list(APPEND LIBLOOT_INTERFACE_TESTS_ALL_SOURCES "${PROJECT_SOURCE_DIR}/src/tests/libloot_tests.manifest")
|
||||
endif()
|
||||
|
||||
##############################
|
||||
# Define Targets
|
||||
|
||||
@@ -113,6 +113,12 @@ TEST(Filesystem, u8pathConvertsCharacterEncodingFromUtf8ToNative) {
|
||||
EXPECT_EQ(utf16, path.u16string());
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
TEST(WindowsRegistry, hasLongPathsEnabled) {
|
||||
EXPECT_TRUE(loot::test::windowsHasLongPathsEnabled());
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace loot {
|
||||
namespace test {
|
||||
void testLoggingCallback(LogLevel, std::string_view) {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version='1.0' encoding='utf-8' standalone='yes'?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
|
||||
<ws2:longPathAware>true</ws2:longPathAware>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
||||
@@ -31,6 +31,10 @@ along with LOOT. If not, see
|
||||
|
||||
#include "loot/enum/game_type.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
namespace loot::test {
|
||||
bool supportsLightPlugins(GameType gameType) {
|
||||
return gameType == GameType::tes5se || gameType == GameType::tes5vr ||
|
||||
@@ -63,6 +67,22 @@ std::filesystem::path getSourceArchivesPath(GameType gameType) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
bool windowsHasLongPathsEnabled() {
|
||||
DWORD value = 0;
|
||||
DWORD valueSize = sizeof(value);
|
||||
LONG ret = RegGetValue(HKEY_LOCAL_MACHINE,
|
||||
L"SYSTEM\\CurrentControlSet\\Control\\FileSystem",
|
||||
L"LongPathsEnabled",
|
||||
RRF_RT_REG_DWORD,
|
||||
NULL,
|
||||
&value,
|
||||
&valueSize);
|
||||
|
||||
return ret == ERROR_SUCCESS && value == 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::filesystem::path getRootTestPath() {
|
||||
std::random_device randomDevice;
|
||||
std::default_random_engine prng(randomDevice());
|
||||
@@ -77,8 +97,16 @@ std::filesystem::path getRootTestPath() {
|
||||
directoryName.push_back(static_cast<char>(dist(prng)));
|
||||
}
|
||||
|
||||
return std::filesystem::absolute(std::filesystem::temp_directory_path() /
|
||||
std::filesystem::u8path(directoryName));
|
||||
auto tempPath = std::filesystem::temp_directory_path() /
|
||||
std::filesystem::u8path(directoryName);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (windowsHasLongPathsEnabled()) {
|
||||
tempPath /= std::filesystem::u8path(std::string(255, 'a'));
|
||||
}
|
||||
#endif
|
||||
|
||||
return std::filesystem::absolute(tempPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user