23
#include "ContainerNameGenerator.h"
24
#include "wslc/e2e/WSLCE2EHelpers.h"
25
#include "HttpHeaderEndDetector.h"
26
+#include "WSLCSessionDefaults.h"
27
#include <nlohmann/json.hpp>
28
29
using namespace std::literals::chrono_literals;
150
return sessionManager;
151
}
152
153
+ // Returns true for the names the wslc CLI reserves for its default sessions.
154
+ static bool IsCliSessionName(std::wstring_view Name)
155
+ {
156
+ constexpr std::wstring_view prefix{wsl::windows::wslc::DefaultSessionName};
157
+
158
+ return Name.size() >= prefix.size() && wsl::shared::string::IsEqual(Name.substr(0, prefix.size()), prefix, true) &&
159
+ (Name.size() == prefix.size() || Name[prefix.size()] == L'-');
160
+ }
161
+
162
+ // ListSessions() reports every session on the machine, including the persistent sessions the
163
+ // wslc CLI creates for itself. Those are outside this class's control, so they are filtered
164
+ // out to keep assertions independent of what else has run on the machine.
165
+ static std::set<std::wstring> ListTestSessionNames(IWSLCSessionManager* SessionManager)
166
+ {
167
+ wil::unique_cotaskmem_array_ptr<WSLCSessionListEntry> sessions;
168
+ VERIFY_SUCCEEDED(SessionManager->ListSessions(&sessions, sessions.size_address<ULONG>()));
169
+
170
+ std::set<std::wstring> names;
171
+ for (const auto& e : sessions)
172
+ {
173
+ if (IsCliSessionName(e.DisplayName))
174
+ {
175
+ continue;
176
+ }
177
+
178
+ auto [it, inserted] = names.emplace(e.DisplayName);
179
+ VERIFY_IS_TRUE(inserted);
180
+ }
181
+
182
+ return names;
183
+ }
184
+
185
wil::com_ptr<IWSLCSession> CreateSession(const WSLCSessionSettings& sessionSettings, WSLCSessionFlags Flags = WSLCSessionFlagsNone)
186
{
187
const auto sessionManager = OpenSessionManager();
397
398
// Act: list sessions
399
{
367
- wil::unique_cotaskmem_array_ptr<WSLCSessionListEntry> sessions;
368
- VERIFY_SUCCEEDED(sessionManager->ListSessions(&sessions, sessions.size_address<ULONG>()));
400
+ const auto names = ListTestSessionNames(sessionManager.get());
401
402
// Assert
371
- VERIFY_ARE_EQUAL(sessions.size(), 1u);
372
- const auto& info = sessions[0];
403
+ VERIFY_ARE_EQUAL(names.size(), 1u);
404
405
// SessionId is implementation detail (starts at 1), so we only assert DisplayName here.
375
- VERIFY_ARE_EQUAL(std::wstring(info.DisplayName), c_testSessionName);
406
+ VERIFY_IS_TRUE(names.contains(c_testSessionName));
407
}
408
409
// List multiple sessions.
410
{
411
auto session2 = CreateSession(GetDefaultSessionSettings(L"wslc-test-list-2"));
412
382
- wil::unique_cotaskmem_array_ptr<WSLCSessionListEntry> sessions;
383
- VERIFY_SUCCEEDED(sessionManager->ListSessions(&sessions, sessions.size_address<ULONG>()));
413
+ const auto names = ListTestSessionNames(sessionManager.get());
414
385
- VERIFY_ARE_EQUAL(sessions.size(), 2);
386
-
387
- std::vector<std::wstring> displayNames;
388
- for (const auto& e : sessions)
389
- {
390
- displayNames.push_back(e.DisplayName);
391
- }
392
-
393
- std::ranges::sort(displayNames);
394
-
395
- VERIFY_ARE_EQUAL(displayNames[0], c_testSessionName);
396
- VERIFY_ARE_EQUAL(displayNames[1], L"wslc-test-list-2");
415
+ VERIFY_ARE_EQUAL(names.size(), 2u);
416
+ VERIFY_IS_TRUE(names.contains(c_testSessionName));
417
+ VERIFY_IS_TRUE(names.contains(L"wslc-test-list-2"));
418
}
419
}
420
10364
auto manager = OpenSessionManager();
10365
10366
auto expectSessions = [&](const std::vector<std::wstring>& expectedSessions) {
10346
- wil::unique_cotaskmem_array_ptr<WSLCSessionListEntry> sessions;
10347
- VERIFY_SUCCEEDED(manager->ListSessions(&sessions, sessions.size_address<ULONG>()));
10348
-
10349
- std::set<std::wstring> displayNames;
10350
- for (const auto& e : sessions)
10351
- {
10352
- auto [_, inserted] = displayNames.insert(e.DisplayName);
10353
-
10354
- VERIFY_IS_TRUE(inserted);
10355
- }
10367
+ auto displayNames = ListTestSessionNames(manager.get());
10368
10369
for (const auto& e : expectedSessions)
10370
{
10385
}
10386
};
10387
10376
- auto create = [this](LPCWSTR Name, WSLCSessionFlags Flags) {
10388
+ // Persistent sessions outlive the COM reference that created them, so a test that fails
10389
+ // partway through would leave them behind for the next run to trip over. Terminate the ones
10390
+ // this test created, however it exits.
10391
+ std::set<std::wstring> persistentSessions;
10392
+ auto terminatePersistentSessions = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() {
10393
+ for (const auto& name : persistentSessions)
10394
+ {
10395
+ wil::com_ptr<IWSLCSession> session;
10396
+ if (SUCCEEDED(manager->OpenSessionByName(name.c_str(), &session)))
10397
+ {
10398
+ LOG_IF_FAILED(session->Terminate());
10399
+ }
10400
+ }
10401
+ });
10402
+
10403
+ auto create = [&](LPCWSTR Name, WSLCSessionFlags Flags) {
10404
+ if (WI_IsFlagSet(Flags, WSLCSessionFlagsPersistent))
10405
+ {
10406
+ persistentSessions.emplace(Name);
10407
+ }
10408
+
10409
return CreateSession(GetDefaultSessionSettings(Name), Flags);
10410
};
10411