From 9c5b4a5e4add852cc384f38efdc429283842ce03 Mon Sep 17 00:00:00 2001 From: Feng Wang Date: Thu, 4 Jun 2026 15:12:03 +0800 Subject: [PATCH 1/7] download to a sub folder under temp to avoid winrt quirk --- src/windows/common/wslutil.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/windows/common/wslutil.cpp b/src/windows/common/wslutil.cpp index 03decb3e15..562e3ed459 100644 --- a/src/windows/common/wslutil.cpp +++ b/src/windows/common/wslutil.cpp @@ -368,8 +368,17 @@ std::wstring wsl::windows::common::wslutil::DownloadFileImpl( Filename = Url.substr(lastSlash + 1); } - const auto downloadFolder = - winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(std::filesystem::temp_directory_path().wstring()).get(); + // GetFolderFromPathAsync does not accept hidden or system path. + // To avoid the temp path having those attributes (mainly hidden), + // we need to create a subfolder without those attributes. + auto downloadFolderPath = std::filesystem::temp_directory_path() / L"wsl-downloads"; + std::filesystem::create_directories(downloadFolderPath); + + const auto attributes = GetFileAttributesW(downloadFolderPath.c_str()); + THROW_LAST_ERROR_IF(attributes == INVALID_FILE_ATTRIBUTES); + THROW_IF_WIN32_BOOL_FALSE(SetFileAttributesW(downloadFolderPath.c_str(), attributes & ~(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))); + + const auto downloadFolder = winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(downloadFolderPath.wstring()).get(); const auto file = downloadFolder.CreateFileAsync(Filename, winrt::Windows::Storage::CreationCollisionOption::GenerateUniqueName).get(); From 45e2df722f7306d5751e35b62d3cd305efb288d9 Mon Sep 17 00:00:00 2001 From: Feng Wang Date: Thu, 4 Jun 2026 15:39:06 +0800 Subject: [PATCH 2/7] add unit test --- test/windows/UnitTests.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/test/windows/UnitTests.cpp b/test/windows/UnitTests.cpp index b9d54b3690..d681ac9e0d 100644 --- a/test/windows/UnitTests.cpp +++ b/test/windows/UnitTests.cpp @@ -5143,7 +5143,7 @@ Error code: Wsl/Service/RegisterDistro/E_INVALIDARG\r\n"; wsl::shared::string::MultiByteToWide("01:23:45:67:89:AB")); } - TEST_METHOD(ModernDistroInstall) + static void ModernDistroInstallImpl() { auto tarPath = "file://" + wsl::shared::string::WideToMultiByte(EscapePath(g_testDistroPath)); @@ -5779,6 +5779,24 @@ Error code: Wsl/InstallDistro/WSL_E_INVALID_JSON\r\n", } } + TEST_METHOD(ModernDistroInstall) + { + ModernDistroInstallImpl(); + } + + TEST_METHOD(ModernDistroInstallWithHiddenTempFolder) + { + const auto tempFolder = std::filesystem::temp_directory_path(); + const auto originalAttributes = GetFileAttributesW(tempFolder.c_str()); + VERIFY_IS_TRUE(originalAttributes != INVALID_FILE_ATTRIBUTES); + VERIFY_IS_TRUE(SetFileAttributesW(tempFolder.c_str(), originalAttributes | FILE_ATTRIBUTE_HIDDEN)); + + auto restoreAttributes = wil::scope_exit_log( + WI_DIAGNOSTICS_INFO, [&] { SetFileAttributesW(tempFolder.c_str(), originalAttributes); }); + + ModernDistroInstallImpl(); + } + TEST_METHOD(ModernInstallEndToEnd) { constexpr auto tarName = L"end2end.tar"; From d63c68c71fce2830d69de2fefc01478a7967ec0c Mon Sep 17 00:00:00 2001 From: Feng Wang Date: Thu, 4 Jun 2026 16:18:03 +0800 Subject: [PATCH 3/7] avoid modifying the real temp folder for testing --- test/windows/Common.cpp | 23 +++++++++++++++++++++-- test/windows/Common.h | 10 +++++----- test/windows/UnitTests.cpp | 17 ++++++++++++----- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/test/windows/Common.cpp b/test/windows/Common.cpp index f5aa3b1a0e..07c45892e3 100644 --- a/test/windows/Common.cpp +++ b/test/windows/Common.cpp @@ -2474,14 +2474,33 @@ void Trim(std::wstring& string) std::erase_if(string, [](auto c) { return !isalnum(c); }); } -ScopedEnvVariable::ScopedEnvVariable(const std::wstring& Name, const std::wstring& Value) : m_name(Name) +ScopedEnvVariable::ScopedEnvVariable(const std::wstring& Name, const std::wstring& Value, bool restore) : + m_name(Name), m_restore(restore) { + if (m_restore) + { + std::wstring value; + const auto result = wil::GetEnvironmentVariableW(Name.c_str(), value); + if (result != HRESULT_FROM_WIN32(ERROR_ENVVAR_NOT_FOUND)) + { + VERIFY_SUCCEEDED(result); + m_originalValue = std::move(value); + } + } + VERIFY_IS_TRUE(SetEnvironmentVariable(Name.c_str(), Value.c_str())); } ScopedEnvVariable::~ScopedEnvVariable() { - VERIFY_IS_TRUE(SetEnvironmentVariable(m_name.c_str(), nullptr)); + if (m_restore && m_originalValue.has_value()) + { + VERIFY_IS_TRUE(SetEnvironmentVariable(m_name.c_str(), m_originalValue->c_str())); + } + else + { + VERIFY_IS_TRUE(SetEnvironmentVariable(m_name.c_str(), nullptr)); + } } UniqueWebServer::UniqueWebServer(LPCWSTR Endpoint, LPCWSTR Content) diff --git a/test/windows/Common.h b/test/windows/Common.h index ad2706ebf2..2b84910cf7 100644 --- a/test/windows/Common.h +++ b/test/windows/Common.h @@ -309,16 +309,16 @@ class RegistryKeyChange class ScopedEnvVariable { public: - ScopedEnvVariable(const std::wstring& Name, const std::wstring& Value); + ScopedEnvVariable(const std::wstring& Name, const std::wstring& Value, bool restore = false); ~ScopedEnvVariable(); - ScopedEnvVariable(const WslConfigChange&) = delete; - ScopedEnvVariable(WslConfigChange&&) = delete; - const ScopedEnvVariable& operator=(ScopedEnvVariable&&) = delete; - const ScopedEnvVariable& operator=(ScopedEnvVariable&) = delete; + NON_COPYABLE(ScopedEnvVariable); + NON_MOVABLE(ScopedEnvVariable); private: std::wstring m_name; + bool m_restore; + std::optional m_originalValue{std::nullopt}; }; class UniqueWebServer diff --git a/test/windows/UnitTests.cpp b/test/windows/UnitTests.cpp index d681ac9e0d..a0c46530fe 100644 --- a/test/windows/UnitTests.cpp +++ b/test/windows/UnitTests.cpp @@ -5786,13 +5786,20 @@ Error code: Wsl/InstallDistro/WSL_E_INVALID_JSON\r\n", TEST_METHOD(ModernDistroInstallWithHiddenTempFolder) { - const auto tempFolder = std::filesystem::temp_directory_path(); - const auto originalAttributes = GetFileAttributesW(tempFolder.c_str()); + // Avoid contaminating the real temp folder. + const auto testTempFolder = std::filesystem::temp_directory_path() / L"wsl-install-test"; + std::filesystem::create_directories(testTempFolder); + auto cleanupTempFolder = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&] { + std::error_code error; + std::filesystem::remove_all(testTempFolder, error); + }); + + const auto originalAttributes = GetFileAttributesW(testTempFolder.c_str()); VERIFY_IS_TRUE(originalAttributes != INVALID_FILE_ATTRIBUTES); - VERIFY_IS_TRUE(SetFileAttributesW(tempFolder.c_str(), originalAttributes | FILE_ATTRIBUTE_HIDDEN)); + VERIFY_IS_TRUE(SetFileAttributesW(testTempFolder.c_str(), originalAttributes | FILE_ATTRIBUTE_HIDDEN)); - auto restoreAttributes = wil::scope_exit_log( - WI_DIAGNOSTICS_INFO, [&] { SetFileAttributesW(tempFolder.c_str(), originalAttributes); }); + ScopedEnvVariable temp(L"TEMP", testTempFolder.wstring(), true); + ScopedEnvVariable tmp(L"TMP", testTempFolder.wstring(), true); ModernDistroInstallImpl(); } From 68625107d3842446c9f2184ec2e3f02add12624b Mon Sep 17 00:00:00 2001 From: Feng Wang Date: Thu, 4 Jun 2026 16:22:52 +0800 Subject: [PATCH 4/7] simplify logic --- test/windows/Common.cpp | 7 +++---- test/windows/Common.h | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/test/windows/Common.cpp b/test/windows/Common.cpp index 07c45892e3..fedb76f930 100644 --- a/test/windows/Common.cpp +++ b/test/windows/Common.cpp @@ -2474,10 +2474,9 @@ void Trim(std::wstring& string) std::erase_if(string, [](auto c) { return !isalnum(c); }); } -ScopedEnvVariable::ScopedEnvVariable(const std::wstring& Name, const std::wstring& Value, bool restore) : - m_name(Name), m_restore(restore) +ScopedEnvVariable::ScopedEnvVariable(const std::wstring& Name, const std::wstring& Value, bool restore) : m_name(Name) { - if (m_restore) + if (restore) { std::wstring value; const auto result = wil::GetEnvironmentVariableW(Name.c_str(), value); @@ -2493,7 +2492,7 @@ ScopedEnvVariable::ScopedEnvVariable(const std::wstring& Name, const std::wstrin ScopedEnvVariable::~ScopedEnvVariable() { - if (m_restore && m_originalValue.has_value()) + if (m_originalValue.has_value()) { VERIFY_IS_TRUE(SetEnvironmentVariable(m_name.c_str(), m_originalValue->c_str())); } diff --git a/test/windows/Common.h b/test/windows/Common.h index 2b84910cf7..0746991660 100644 --- a/test/windows/Common.h +++ b/test/windows/Common.h @@ -317,7 +317,6 @@ class ScopedEnvVariable private: std::wstring m_name; - bool m_restore; std::optional m_originalValue{std::nullopt}; }; From 7242bb5045a60b917070d8972165d06dbc268a1f Mon Sep 17 00:00:00 2001 From: Feng Wang Date: Fri, 5 Jun 2026 10:25:34 +0800 Subject: [PATCH 5/7] avoid redundant operation --- src/windows/common/wslutil.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/windows/common/wslutil.cpp b/src/windows/common/wslutil.cpp index 562e3ed459..f43f7450e4 100644 --- a/src/windows/common/wslutil.cpp +++ b/src/windows/common/wslutil.cpp @@ -376,7 +376,10 @@ std::wstring wsl::windows::common::wslutil::DownloadFileImpl( const auto attributes = GetFileAttributesW(downloadFolderPath.c_str()); THROW_LAST_ERROR_IF(attributes == INVALID_FILE_ATTRIBUTES); - THROW_IF_WIN32_BOOL_FALSE(SetFileAttributesW(downloadFolderPath.c_str(), attributes & ~(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))); + if (attributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) + { + THROW_IF_WIN32_BOOL_FALSE(SetFileAttributesW(downloadFolderPath.c_str(), attributes & ~(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))); + } const auto downloadFolder = winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(downloadFolderPath.wstring()).get(); From 38e3427591ba33b65c6533cc678a18e3f2b9f403 Mon Sep 17 00:00:00 2001 From: Feng Wang Date: Thu, 11 Jun 2026 15:07:17 +0800 Subject: [PATCH 6/7] avoid GetFolderFromPathAsync --- src/windows/common/wslutil.cpp | 55 +++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/src/windows/common/wslutil.cpp b/src/windows/common/wslutil.cpp index f43f7450e4..712e8e4d17 100644 --- a/src/windows/common/wslutil.cpp +++ b/src/windows/common/wslutil.cpp @@ -368,26 +368,45 @@ std::wstring wsl::windows::common::wslutil::DownloadFileImpl( Filename = Url.substr(lastSlash + 1); } - // GetFolderFromPathAsync does not accept hidden or system path. - // To avoid the temp path having those attributes (mainly hidden), - // we need to create a subfolder without those attributes. - auto downloadFolderPath = std::filesystem::temp_directory_path() / L"wsl-downloads"; - std::filesystem::create_directories(downloadFolderPath); - - const auto attributes = GetFileAttributesW(downloadFolderPath.c_str()); - THROW_LAST_ERROR_IF(attributes == INVALID_FILE_ATTRIBUTES); - if (attributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) + // GetFodlerFromPathAsync won't work if the folder is hidden or system. + auto downloadFolderPath = std::filesystem::temp_directory_path(); + auto filenameStem = std::filesystem::path(Filename).stem().wstring(); + auto filenameExtension = std::filesystem::path(Filename).extension().wstring(); + std::wstring filePath{}; + winrt::Windows::Storage::Streams::IRandomAccessStream outputStream{}; + for (int suffix = 1; outputStream == nullptr; suffix++) { - THROW_IF_WIN32_BOOL_FALSE(SetFileAttributesW(downloadFolderPath.c_str(), attributes & ~(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))); + if (suffix == 1) + { + filePath = (downloadFolderPath / Filename).wstring(); + } + else + { + filePath = (downloadFolderPath / std::format(L"{} ({}){}", filenameStem, suffix, filenameExtension)).wstring(); + } + try + { + outputStream = winrt::Windows::Storage::Streams::FileRandomAccessStream::OpenAsync( + filePath, + winrt::Windows::Storage::FileAccessMode::ReadWrite, + winrt::Windows::Storage::StorageOpenOptions::None, + winrt::Windows::Storage::Streams::FileOpenDisposition::CreateNew) + .get(); + } + catch (const winrt::hresult_error& e) + { + if (e.code() != HRESULT_FROM_WIN32(ERROR_FILE_EXISTS)) + { + throw; + } + } } - const auto downloadFolder = winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(downloadFolderPath.wstring()).get(); - - const auto file = - downloadFolder.CreateFileAsync(Filename, winrt::Windows::Storage::CreationCollisionOption::GenerateUniqueName).get(); - auto deleteFileOnFailure = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&] { file.DeleteAsync().get(); }); - - const auto outputStream = file.OpenAsync(winrt::Windows::Storage::FileAccessMode::ReadWrite).get().GetOutputStreamAt(0); + auto deleteFileOnFailure = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&] { + outputStream.Close(); + std::error_code ec; + std::filesystem::remove(filePath, ec); + }); // By default downloaded files are cached in %appdata%/local/packages/{package-family}/AC/InetCache . // Disable caching since there's no reason to keep local copies of .msixbundle files. @@ -421,7 +440,7 @@ std::wstring wsl::windows::common::wslutil::DownloadFileImpl( download.get(); deleteFileOnFailure.release(); - return file.Path().c_str(); + return filePath; } [[nodiscard]] HANDLE wsl::windows::common::wslutil::DuplicateHandle(_In_ HANDLE Handle, _In_ std::optional DesiredAccess, _In_ BOOL InheritHandle) From ef35a15cdd804055397b05b3a135d4c445c29ffb Mon Sep 17 00:00:00 2001 From: Feng Wang Date: Fri, 12 Jun 2026 14:21:38 +0800 Subject: [PATCH 7/7] resolve comments --- src/windows/common/wslutil.cpp | 6 +-- test/windows/Common.cpp | 15 +++--- test/windows/Common.h | 2 +- test/windows/UnitTests.cpp | 92 ++++++++++++++++++++++++---------- 4 files changed, 76 insertions(+), 39 deletions(-) diff --git a/src/windows/common/wslutil.cpp b/src/windows/common/wslutil.cpp index 712e8e4d17..3201937444 100644 --- a/src/windows/common/wslutil.cpp +++ b/src/windows/common/wslutil.cpp @@ -368,7 +368,7 @@ std::wstring wsl::windows::common::wslutil::DownloadFileImpl( Filename = Url.substr(lastSlash + 1); } - // GetFodlerFromPathAsync won't work if the folder is hidden or system. + // GetFolderFromPathAsync won't work if the folder is hidden or system. auto downloadFolderPath = std::filesystem::temp_directory_path(); auto filenameStem = std::filesystem::path(Filename).stem().wstring(); auto filenameExtension = std::filesystem::path(Filename).extension().wstring(); @@ -393,9 +393,9 @@ std::wstring wsl::windows::common::wslutil::DownloadFileImpl( winrt::Windows::Storage::Streams::FileOpenDisposition::CreateNew) .get(); } - catch (const winrt::hresult_error& e) + catch (...) { - if (e.code() != HRESULT_FROM_WIN32(ERROR_FILE_EXISTS)) + if (wil::ResultFromCaughtException() != HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) { throw; } diff --git a/test/windows/Common.cpp b/test/windows/Common.cpp index fedb76f930..69a40cc352 100644 --- a/test/windows/Common.cpp +++ b/test/windows/Common.cpp @@ -2474,17 +2474,14 @@ void Trim(std::wstring& string) std::erase_if(string, [](auto c) { return !isalnum(c); }); } -ScopedEnvVariable::ScopedEnvVariable(const std::wstring& Name, const std::wstring& Value, bool restore) : m_name(Name) +ScopedEnvVariable::ScopedEnvVariable(const std::wstring& Name, const std::wstring& Value) : m_name(Name) { - if (restore) + std::wstring value; + const auto result = wil::GetEnvironmentVariableW(Name.c_str(), value); + if (result != HRESULT_FROM_WIN32(ERROR_ENVVAR_NOT_FOUND)) { - std::wstring value; - const auto result = wil::GetEnvironmentVariableW(Name.c_str(), value); - if (result != HRESULT_FROM_WIN32(ERROR_ENVVAR_NOT_FOUND)) - { - VERIFY_SUCCEEDED(result); - m_originalValue = std::move(value); - } + VERIFY_SUCCEEDED(result); + m_originalValue = std::move(value); } VERIFY_IS_TRUE(SetEnvironmentVariable(Name.c_str(), Value.c_str())); diff --git a/test/windows/Common.h b/test/windows/Common.h index 0746991660..f018ccf778 100644 --- a/test/windows/Common.h +++ b/test/windows/Common.h @@ -309,7 +309,7 @@ class RegistryKeyChange class ScopedEnvVariable { public: - ScopedEnvVariable(const std::wstring& Name, const std::wstring& Value, bool restore = false); + ScopedEnvVariable(const std::wstring& Name, const std::wstring& Value); ~ScopedEnvVariable(); NON_COPYABLE(ScopedEnvVariable); diff --git a/test/windows/UnitTests.cpp b/test/windows/UnitTests.cpp index e552abcb06..08fbf51cca 100644 --- a/test/windows/UnitTests.cpp +++ b/test/windows/UnitTests.cpp @@ -5216,7 +5216,7 @@ Error code: Wsl/Service/RegisterDistro/E_INVALIDARG\r\n"; wsl::shared::string::MultiByteToWide("01:23:45:67:89:AB")); } - static void ModernDistroInstallImpl() + TEST_METHOD(ModernDistroInstall) { auto tarPath = "file://" + wsl::shared::string::WideToMultiByte(EscapePath(g_testDistroPath)); @@ -5852,31 +5852,6 @@ Error code: Wsl/InstallDistro/WSL_E_INVALID_JSON\r\n", } } - TEST_METHOD(ModernDistroInstall) - { - ModernDistroInstallImpl(); - } - - TEST_METHOD(ModernDistroInstallWithHiddenTempFolder) - { - // Avoid contaminating the real temp folder. - const auto testTempFolder = std::filesystem::temp_directory_path() / L"wsl-install-test"; - std::filesystem::create_directories(testTempFolder); - auto cleanupTempFolder = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&] { - std::error_code error; - std::filesystem::remove_all(testTempFolder, error); - }); - - const auto originalAttributes = GetFileAttributesW(testTempFolder.c_str()); - VERIFY_IS_TRUE(originalAttributes != INVALID_FILE_ATTRIBUTES); - VERIFY_IS_TRUE(SetFileAttributesW(testTempFolder.c_str(), originalAttributes | FILE_ATTRIBUTE_HIDDEN)); - - ScopedEnvVariable temp(L"TEMP", testTempFolder.wstring(), true); - ScopedEnvVariable tmp(L"TMP", testTempFolder.wstring(), true); - - ModernDistroInstallImpl(); - } - TEST_METHOD(ModernInstallEndToEnd) { constexpr auto tarName = L"end2end.tar"; @@ -7412,5 +7387,70 @@ Error code: Wsl/InstallDistro/WSL_E_INVALID_JSON\r\n", } } + TEST_METHOD(DownloadToHiddenSystemTempFolder) + { + // Avoid contaminating the real temp folder. + const auto testTempFolder = std::filesystem::temp_directory_path() / L"wsl-download-test"; + std::filesystem::create_directories(testTempFolder); + auto cleanupTempFolder = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&] { + std::error_code error; + std::filesystem::remove_all(testTempFolder, error); + }); + + const auto originalAttributes = GetFileAttributesW(testTempFolder.c_str()); + VERIFY_IS_TRUE(originalAttributes != INVALID_FILE_ATTRIBUTES); + VERIFY_IS_TRUE(SetFileAttributesW(testTempFolder.c_str(), originalAttributes | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)); + + ScopedEnvVariable temp(L"TEMP", testTempFolder.wstring()); + ScopedEnvVariable tmp(L"TMP", testTempFolder.wstring()); + + VERIFY_IS_TRUE(std::filesystem::equivalent(std::filesystem::temp_directory_path(), testTempFolder)); + + constexpr USHORT port = 6666; + const auto endpoint = std::format(L"http://127.0.0.1:{}/", port); + constexpr auto fileName = L"downloaded-file.bin"; + constexpr auto fileContent = L"wsl download test content"; + UniqueWebServer server(endpoint.c_str(), fileContent); + + const auto url = endpoint + fileName; + const auto noProgress = [](uint64_t, uint64_t) {}; + + wsl::shared::retry::RetryWithTimeout( + [&]() { + wil::unique_socket probe{socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)}; + THROW_LAST_ERROR_IF(!probe); + + sockaddr_in address{}; + address.sin_family = AF_INET; + address.sin_port = htons(port); + address.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + THROW_LAST_ERROR_IF(connect(probe.get(), reinterpret_cast(&address), sizeof(address)) == SOCKET_ERROR); + }, + std::chrono::milliseconds(500), + std::chrono::seconds(5)); + + const auto firstPath = wsl::windows::common::wslutil::DownloadFileImpl(url, L"", noProgress); + + auto readFile = [](const std::filesystem::path& Path) { + std::ifstream file(Path, std::ios::binary); + VERIFY_IS_TRUE(file.good()); + return std::string{std::istreambuf_iterator(file), {}}; + }; + + VERIFY_ARE_EQUAL(std::filesystem::path(firstPath).parent_path(), testTempFolder); + VERIFY_ARE_EQUAL(std::filesystem::path(firstPath).filename().wstring(), std::wstring(fileName)); + VERIFY_IS_TRUE(std::filesystem::exists(firstPath)); + VERIFY_ARE_EQUAL(readFile(firstPath), wsl::shared::string::WideToMultiByte(fileContent)); + + const auto secondPath = wsl::windows::common::wslutil::DownloadFileImpl(url, L"", noProgress); + + VERIFY_ARE_EQUAL(std::filesystem::path(secondPath).parent_path(), testTempFolder); + VERIFY_ARE_EQUAL(std::filesystem::path(secondPath).filename().wstring(), std::wstring(L"downloaded-file (2).bin")); + VERIFY_IS_TRUE(std::filesystem::exists(firstPath)); + VERIFY_IS_TRUE(std::filesystem::exists(secondPath)); + VERIFY_ARE_EQUAL(readFile(secondPath), wsl::shared::string::WideToMultiByte(fileContent)); + } + }; // namespace UnitTests } // namespace UnitTests