Use RetryWithTimeout for ManageRejectedWhileLocked lock wait (#41188)
Address PR #41170 feedback from @oneblue: the wait for the distribution to enter the Exporting state was capped at ~10 seconds (100 x 100ms), which can flake on slow machines before the export acquires the lock. Replace the hand-rolled poll loop with wsl::shared::retry::RetryWithTimeout and raise the total timeout to two minutes, matching the retryshared.h convention already used elsewhere in the tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com> Copilot-Session: 6c2f7701-180c-45fc-a1d6-c9ca46be324b
Ben Hillis committed
Jul 27, 2026 at 16:32 UTC
ad8b78ff37be2ee6a3d5451a5db39e5e9977af87
1 file changed
+22
-12
test/windows/UnitTests.cpp
+22
-12
@@ -18,6 +18,7 @@ Abstract:
18
#include "install.h"
19
#include <AclAPI.h>
20
#include <fstream>
21
+#include <sstream>
22
#include <filesystem>
23
#include "wslservice.h"
24
#include "registry.hpp"
@@ -29,6 +30,7 @@ Abstract:
30
#include "Distribution.h"
31
#include "WslCoreConfigInterface.h"
32
#include "CommandLine.h"
33
+#include "retryshared.h"
34
35
#define LXSST_TEST_USERNAME L"kerneltest"
36
@@ -3296,19 +3298,27 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
3298
}
3299
});
3300
3299
- // Wait until the service reports the distribution as Exporting (i.e. the lock is held).
3300
- bool locked = false;
3301
- for (int i = 0; i < 100 && !locked; ++i)
3302
- {
3303
- auto [out, _] = LxsstuLaunchWslAndCaptureOutput(L"--list --verbose");
3304
- locked = (out.find(name) != std::wstring::npos) && (out.find(L"Exporting") != std::wstring::npos);
3305
- if (!locked)
3306
- {
3307
- std::this_thread::sleep_for(std::chrono::milliseconds(100));
3308
- }
3309
- }
3301
+ // Wait until the service reports the distribution as Exporting (i.e. the lock is held), retrying for up
3302
+ // to two minutes so a slow machine doesn't flake before the export acquires the lock.
3303
+ wsl::shared::retry::RetryWithTimeout<void>(
3304
+ [&]() {
3305
+ auto [out, _] = LxsstuLaunchWslAndCaptureOutput(L"--list --verbose");
3306
+ bool locked = false;
3307
+ std::wistringstream stream(out);
3308
+ for (std::wstring line; std::getline(stream, line);)
3309
+ {
3310
+ if (line.find(name) != std::wstring::npos && line.find(L"Exporting") != std::wstring::npos)
3311
+ {
3312
+ locked = true;
3313
+ break;
3314
+ }
3315
+ }
3316
3311
- VERIFY_IS_TRUE(locked);
3317
+ THROW_HR_IF(E_ABORT, !locked);
3318
+ },
3319
+ std::chrono::milliseconds(100),
3320
+ std::chrono::minutes(2),
3321
+ [] { return wil::ResultFromCaughtException() == E_ABORT; });
3322
3323
// Each VHD-mutating manage operation must be rejected with E_ILLEGAL_STATE_CHANGE while the lock is held.
3324
auto verifyRejected = [&](const std::wstring& command) {