@samitouri / QOSAMI-WSL / commits / 081d9625

wslc: emit list command --format json output as one object per line (#41280)

AmirMS committed Aug 10, 2026 at 09:37 UTC 081d96257b49d605cb1cd473633476cc94a742cd
13 files changed +100 -51
src/shared/inc/JsonUtils.h
+1 -4
@@ -53,10 +53,7 @@ inline void from_json(const nlohmann::json&, EmptyObject&)
53 template <typename T>
54 std::string ToJson(const T& Value, int indent = -1)
55 {
56 - nlohmann::json json;
57 - to_json(json, Value);
58 -
59 - return json.dump(indent);
56 + return nlohmann::json(Value).dump(indent);
57 }
58
59 template <typename T>
src/windows/wslc/tasks/ContainerTasks.cpp
+10 -3
@@ -560,8 +560,11 @@ void ListContainers(CLIExecutionContext& context)
560 {
561 case FormatType::Json:
562 {
563 - auto json = ToJson(containers, c_jsonCompactIndent);
564 - context.Terminal.Output(L"{}\n", MultiByteToWide(json));
563 + for (const auto& container : containers)
564 + {
565 + context.Terminal.Output(L"{}\n", ToJsonW(container, c_jsonCompactIndent));
566 + }
567 +
568 break;
569 }
570 case FormatType::Table:
@@ -937,7 +940,11 @@ void ShowContainerStats(CLIExecutionContext& context)
940 {
941 case FormatType::Json:
942 {
940 - context.Terminal.Output(L"{}\n", MultiByteToWide(statsJson.dump(c_jsonCompactIndent)));
943 + for (const auto& entry : statsJson)
944 + {
945 + context.Terminal.Output(L"{}\n", ToJsonW(entry, c_jsonCompactIndent));
946 + }
947 +
948 break;
949 }
950 case FormatType::Table:
src/windows/wslc/tasks/ImageTasks.cpp
+5 -2
@@ -171,8 +171,11 @@ void ListImages(CLIExecutionContext& context)
171 {
172 case FormatType::Json:
173 {
174 - auto json = ToJson(images, c_jsonCompactIndent);
175 - context.Terminal.Output(L"{}\n", MultiByteToWide(json));
174 + for (const auto& image : images)
175 + {
176 + context.Terminal.Output(L"{}\n", ToJsonW(image, c_jsonCompactIndent));
177 + }
178 +
179 break;
180 }
181 case FormatType::Table:
src/windows/wslc/tasks/NetworkTasks.cpp
+5 -2
@@ -186,8 +186,11 @@ void ListNetworks(CLIExecutionContext& context)
186 {
187 case FormatType::Json:
188 {
189 - auto json = ToJson(networks, c_jsonCompactIndent);
190 - context.Terminal.Output(L"{}\n", MultiByteToWide(json));
189 + for (const auto& network : networks)
190 + {
191 + context.Terminal.Output(L"{}\n", ToJsonW(network, c_jsonCompactIndent));
192 + }
193 +
194 break;
195 }
196 case FormatType::Table:
src/windows/wslc/tasks/VolumeTasks.cpp
+5 -2
@@ -171,8 +171,11 @@ void ListVolumes(CLIExecutionContext& context)
171 {
172 case FormatType::Json:
173 {
174 - auto json = ToJson(volumes, c_jsonCompactIndent);
175 - context.Terminal.Output(L"{}\n", MultiByteToWide(json));
174 + for (const auto& volume : volumes)
175 + {
176 + context.Terminal.Output(L"{}\n", ToJsonW(volume, c_jsonCompactIndent));
177 + }
178 +
179 break;
180 }
181 case FormatType::Table:
test/windows/wslc/e2e/WSLCE2EContainerListTests.cpp
+11 -12
@@ -176,11 +176,10 @@ class WSLCE2EContainerListTests
176 // List containers with json format
177 result = RunWslc(L"container list --all --format json");
178 result.Verify({.Stderr = L"", .ExitCode = 0});
179 - // The payload is emitted on a single compact line.
180 - VERIFY_ARE_EQUAL(1u, result.GetStdoutLines().size());
179 // Parse json and verify we got the expected container information back
182 - auto containers = wsl::shared::FromJson<std::vector<ContainerInformation>>(result.Stdout.value().c_str());
180 + auto containers = ParseNdjsonOutputAs<ContainerInformation>(result);
181 VERIFY_IS_GREATER_THAN_OR_EQUAL(containers.size(), 1U);
182 + VERIFY_ARE_EQUAL(containers.size(), result.GetStdoutLines().size());
183
184 auto findContainer = [](const std::vector<ContainerInformation>& list, const std::wstring& id) {
185 return std::ranges::any_of(list, [&](const auto& c) { return wsl::shared::string::MultiByteToWide(c.Id) == id; });
@@ -198,7 +197,7 @@ class WSLCE2EContainerListTests
197 result = RunWslc(L"container list --all --format json");
198 result.Verify({.Stderr = L"", .ExitCode = 0});
199 // Parse json and verify we got both containers back
201 - containers = wsl::shared::FromJson<std::vector<ContainerInformation>>(result.Stdout.value().c_str());
200 + containers = ParseNdjsonOutputAs<ContainerInformation>(result);
201 VERIFY_IS_GREATER_THAN_OR_EQUAL(containers.size(), 2U);
202
203 VERIFY_IS_TRUE(findContainer(containers, containerId));
@@ -247,7 +246,7 @@ class WSLCE2EContainerListTests
246 result = RunWslc(std::format(L"container list --all --format json --filter name={}", WslcContainerName2));
247 result.Verify({.Stderr = L"", .ExitCode = 0});
248
250 - const auto containers = wsl::shared::FromJson<std::vector<ContainerInformation>>(result.Stdout.value().c_str());
249 + const auto containers = ParseNdjsonOutputAs<ContainerInformation>(result);
250 VERIFY_ARE_EQUAL(1U, containers.size());
251 VERIFY_ARE_EQUAL(WideToMultiByte(WslcContainerName2), std::string(containers[0].Name));
252 }
@@ -268,7 +267,7 @@ class WSLCE2EContainerListTests
267 auto listNames = [&](const std::wstring& filterArgs) {
268 auto r = RunWslc(std::format(L"container list --all --format json {}", filterArgs));
269 r.Verify({.Stderr = L"", .ExitCode = 0});
271 - const auto containers = wsl::shared::FromJson<std::vector<ContainerInformation>>(r.Stdout.value().c_str());
270 + const auto containers = ParseNdjsonOutputAs<ContainerInformation>(r);
271 std::set<std::string> names;
272 for (const auto& c : containers)
273 {
@@ -315,7 +314,7 @@ class WSLCE2EContainerListTests
314 auto listNames = [&](const std::wstring& filterArgs) {
315 auto r = RunWslc(std::format(L"container list --all --format json {}", filterArgs));
316 r.Verify({.Stderr = L"", .ExitCode = 0});
318 - const auto containers = wsl::shared::FromJson<std::vector<ContainerInformation>>(r.Stdout.value().c_str());
317 + const auto containers = ParseNdjsonOutputAs<ContainerInformation>(r);
318 std::set<std::string> names;
319 for (const auto& c : containers)
320 {
@@ -362,7 +361,7 @@ class WSLCE2EContainerListTests
361 result = RunWslc(std::format(L"container list --all --format json --filter id={}", containerId));
362 result.Verify({.Stderr = L"", .ExitCode = 0});
363
365 - const auto containers = wsl::shared::FromJson<std::vector<ContainerInformation>>(result.Stdout.value().c_str());
364 + const auto containers = ParseNdjsonOutputAs<ContainerInformation>(result);
365 VERIFY_ARE_EQUAL(1U, containers.size());
366 VERIFY_ARE_EQUAL(WideToMultiByte(containerId), std::string(containers[0].Id));
367 }
@@ -383,7 +382,7 @@ class WSLCE2EContainerListTests
382 auto listNames = [&](const std::wstring& filterArgs) {
383 auto r = RunWslc(std::format(L"container list --all --format json {}", filterArgs));
384 r.Verify({.Stderr = L"", .ExitCode = 0});
386 - const auto containers = wsl::shared::FromJson<std::vector<ContainerInformation>>(r.Stdout.value().c_str());
385 + const auto containers = ParseNdjsonOutputAs<ContainerInformation>(r);
386 std::set<std::string> names;
387 for (const auto& c : containers)
388 {
@@ -422,7 +421,7 @@ class WSLCE2EContainerListTests
421 auto listNames = [&](const std::wstring& filterArgs) {
422 auto r = RunWslc(std::format(L"container list --all --format json {}", filterArgs));
423 r.Verify({.Stderr = L"", .ExitCode = 0});
425 - const auto containers = wsl::shared::FromJson<std::vector<ContainerInformation>>(r.Stdout.value().c_str());
424 + const auto containers = ParseNdjsonOutputAs<ContainerInformation>(r);
425 std::set<std::string> names;
426 for (const auto& c : containers)
427 {
@@ -464,7 +463,7 @@ class WSLCE2EContainerListTests
463 result = RunWslc(L"container list --latest --format json");
464 result.Verify({.Stderr = L"", .ExitCode = 0});
465
467 - const auto containers = wsl::shared::FromJson<std::vector<ContainerInformation>>(result.Stdout.value().c_str());
466 + const auto containers = ParseNdjsonOutputAs<ContainerInformation>(result);
467 VERIFY_ARE_EQUAL(1U, containers.size());
468 VERIFY_ARE_EQUAL(WideToMultiByte(WslcContainerName2), std::string(containers[0].Name));
469 }
@@ -474,7 +473,7 @@ class WSLCE2EContainerListTests
473 result = RunWslc(L"container list --last 2 --format json");
474 result.Verify({.Stderr = L"", .ExitCode = 0});
475
477 - const auto containers = wsl::shared::FromJson<std::vector<ContainerInformation>>(result.Stdout.value().c_str());
476 + const auto containers = ParseNdjsonOutputAs<ContainerInformation>(result);
477 VERIFY_IS_TRUE(containers.size() <= 2u);
478 }
479
test/windows/wslc/e2e/WSLCE2EContainerStatsTests.cpp
+3 -4
@@ -208,11 +208,10 @@ class WSLCE2EContainerStatsTests
208 result.Verify({.Stderr = L"", .ExitCode = 0});
209
210 // Parse and validate the JSON output
211 - const auto json = nlohmann::json::parse(WideToMultiByte(result.Stdout.value()));
212 - VERIFY_IS_TRUE(json.is_array());
213 - VERIFY_IS_GREATER_THAN_OR_EQUAL(json.size(), 1U);
211 + const auto entries = ParseNdjsonOutput(result);
212 + VERIFY_IS_GREATER_THAN_OR_EQUAL(entries.size(), 1U);
213
215 - const auto& entry = json[0];
214 + const auto& entry = entries[0];
215 VERIFY_IS_TRUE(entry.contains("ID"));
216 VERIFY_IS_TRUE(entry.contains("Name"));
217 VERIFY_IS_TRUE(entry.contains("CPUPerc"));
test/windows/wslc/e2e/WSLCE2EHelpers.cpp
+12 -12
@@ -204,7 +204,7 @@ void VerifyImageIsListed(const TestImage& image)
204 {
205 auto result = RunWslc(L"image list --format json");
206 result.Verify({.Stderr = L"", .ExitCode = 0});
207 - auto images = wsl::shared::FromJson<std::vector<wsl::windows::wslc::models::ImageInformation>>(result.Stdout.value().c_str());
207 + auto images = ParseNdjsonOutputAs<wsl::windows::wslc::models::ImageInformation>(result);
208 for (const auto& img : images)
209 {
210 if (img.Repository == wsl::shared::string::WideToMultiByte(image.Name) &&
@@ -221,7 +221,7 @@ void VerifyVolumeIsListed(const std::wstring& volumeName)
221 {
222 auto result = RunWslc(L"volume list --format json");
223 result.Verify({.Stderr = L"", .ExitCode = 0});
224 - auto volumes = wsl::shared::FromJson<std::vector<WSLCVolumeInformation>>(result.Stdout.value().c_str());
224 + auto volumes = ParseNdjsonOutputAs<WSLCVolumeInformation>(result);
225 for (const auto& vol : volumes)
226 {
227 if (vol.Name == wsl::shared::string::WideToMultiByte(volumeName))
@@ -237,7 +237,7 @@ void VerifyVolumeIsNotListed(const std::wstring& volumeName)
237 {
238 auto result = RunWslc(L"volume list --format json");
239 result.Verify({.Stderr = L"", .ExitCode = 0});
240 - auto volumes = wsl::shared::FromJson<std::vector<WSLCVolumeInformation>>(result.Stdout.value().c_str());
240 + auto volumes = ParseNdjsonOutputAs<WSLCVolumeInformation>(result);
241 for (const auto& vol : volumes)
242 {
243 if (vol.Name == wsl::shared::string::WideToMultiByte(volumeName))
@@ -251,7 +251,7 @@ void VerifyNetworkIsListed(const std::wstring& networkName)
251 {
252 auto result = RunWslc(L"network list --format json");
253 result.Verify({.Stderr = L"", .ExitCode = 0});
254 - auto networks = wsl::shared::FromJson<std::vector<WSLCNetworkInformation>>(result.Stdout.value().c_str());
254 + auto networks = ParseNdjsonOutputAs<WSLCNetworkInformation>(result);
255 for (const auto& net : networks)
256 {
257 if (net.Name == wsl::shared::string::WideToMultiByte(networkName))
@@ -267,7 +267,7 @@ void VerifyNetworkIsNotListed(const std::wstring& networkName)
267 {
268 auto result = RunWslc(L"network list --format json");
269 result.Verify({.Stderr = L"", .ExitCode = 0});
270 - auto networks = wsl::shared::FromJson<std::vector<WSLCNetworkInformation>>(result.Stdout.value().c_str());
270 + auto networks = ParseNdjsonOutputAs<WSLCNetworkInformation>(result);
271 for (const auto& net : networks)
272 {
273 if (net.Name == wsl::shared::string::WideToMultiByte(networkName))
@@ -359,7 +359,7 @@ std::vector<wsl::windows::wslc::models::ContainerInformation> ListAllContainers(
359 {
360 auto result = RunWslc(L"container list --all --format json");
361 result.Verify({.Stderr = L"", .ExitCode = 0});
362 - return wsl::shared::FromJson<std::vector<wsl::windows::wslc::models::ContainerInformation>>(result.Stdout.value().c_str());
362 + return ParseNdjsonOutputAs<wsl::windows::wslc::models::ContainerInformation>(result);
363 }
364
365 void EnsureImageContainersAreDeleted(const TestImage& image)
@@ -381,7 +381,7 @@ void EnsureImageIsDeleted(const TestImage& image)
381 auto result = RunWslc(L"image list --format json");
382 result.Verify({.Stderr = L"", .ExitCode = 0});
383
384 - auto images = wsl::shared::FromJson<std::vector<wsl::windows::wslc::models::ImageInformation>>(result.Stdout.value().c_str());
384 + auto images = ParseNdjsonOutputAs<wsl::windows::wslc::models::ImageInformation>(result);
385 for (const auto& img : images)
386 {
387 if (img.Repository == wsl::shared::string::WideToMultiByte(image.Name) &&
@@ -400,7 +400,7 @@ void DeleteImagesWithRepositoryPrefix(const std::wstring& repositoryPrefix)
400 auto result = RunWslc(L"image list --format json");
401 result.Verify({.Stderr = L"", .ExitCode = 0});
402
403 - const auto images = wsl::shared::FromJson<std::vector<wsl::windows::wslc::models::ImageInformation>>(result.Stdout.value().c_str());
403 + const auto images = ParseNdjsonOutputAs<wsl::windows::wslc::models::ImageInformation>(result);
404 const auto prefix = wsl::shared::string::WideToMultiByte(repositoryPrefix);
405 for (const auto& image : images)
406 {
@@ -420,7 +420,7 @@ void EnsureNoUntaggedImages()
420 auto result = RunWslc(L"image list --format json --filter dangling=true");
421 result.Verify({.Stderr = L"", .ExitCode = 0});
422
423 - const auto images = wsl::shared::FromJson<std::vector<wsl::windows::wslc::models::ImageInformation>>(result.Stdout.value().c_str());
423 + const auto images = ParseNdjsonOutputAs<wsl::windows::wslc::models::ImageInformation>(result);
424
425 for (const auto& image : images)
426 {
@@ -448,7 +448,7 @@ void EnsureImageIsLoaded(const TestImage& image, const std::wstring& sessionName
448 auto result = RunWslc(listCommand);
449 result.Verify({.Stderr = L"", .ExitCode = 0});
450
451 - auto images = wsl::shared::FromJson<std::vector<wsl::windows::wslc::models::ImageInformation>>(result.Stdout.value().c_str());
451 + auto images = ParseNdjsonOutputAs<wsl::windows::wslc::models::ImageInformation>(result);
452 for (const auto& img : images)
453 {
454 if (img.Repository == wsl::shared::string::WideToMultiByte(image.Name) &&
@@ -504,7 +504,7 @@ void EnsureVolumeDoesNotExist(const std::wstring& volumeName)
504 {
505 auto result = RunWslc(L"volume list --format json");
506 result.Verify({.Stderr = L"", .ExitCode = 0});
507 - auto volumes = wsl::shared::FromJson<std::vector<WSLCVolumeInformation>>(result.Stdout.value().c_str());
507 + auto volumes = ParseNdjsonOutputAs<WSLCVolumeInformation>(result);
508 for (const auto& vol : volumes)
509 {
510 if (vol.Name == wsl::shared::string::WideToMultiByte(volumeName))
@@ -520,7 +520,7 @@ void EnsureNetworkDoesNotExist(const std::wstring& networkName)
520 {
521 auto result = RunWslc(L"network list --format json");
522 result.Verify({.Stderr = L"", .ExitCode = 0});
523 - auto networks = wsl::shared::FromJson<std::vector<WSLCNetworkInformation>>(result.Stdout.value().c_str());
523 + auto networks = ParseNdjsonOutputAs<WSLCNetworkInformation>(result);
524 for (const auto& net : networks)
525 {
526 if (net.Name == wsl::shared::string::WideToMultiByte(networkName))
test/windows/wslc/e2e/WSLCE2EHelpers.h
+38
@@ -236,6 +236,44 @@ inline nlohmann::json VerifyCompactJsonOutput(const WSLCExecutionResult& result)
236 return nlohmann::json::parse(wsl::shared::string::WideToMultiByte(lines[0]));
237 }
238
239 +// Parses list output emitted as one compact JSON object per line.
240 +inline std::vector<nlohmann::json> ParseNdjsonOutput(const WSLCExecutionResult& result)
241 +{
242 + VERIFY_IS_TRUE(result.Stdout.has_value());
243 +
244 + std::vector<nlohmann::json> entries;
245 + for (const auto& line : result.GetStdoutLines())
246 + {
247 + if (line.empty())
248 + {
249 + continue;
250 + }
251 +
252 + auto entry = nlohmann::json::parse(wsl::shared::string::WideToMultiByte(line));
253 + if (!entry.is_object())
254 + {
255 + VERIFY_FAIL(std::format(L"Line is not a JSON object: '{}'", line).c_str());
256 + }
257 +
258 + entries.push_back(std::move(entry));
259 + }
260 +
261 + return entries;
262 +}
263 +
264 +// Typed form of ParseNdjsonOutput() that deserializes each line into T.
265 +template <typename T>
266 +std::vector<T> ParseNdjsonOutputAs(const WSLCExecutionResult& result)
267 +{
268 + std::vector<T> entries;
269 + for (const auto& entry : ParseNdjsonOutput(result))
270 + {
271 + entries.push_back(entry.get<T>());
272 + }
273 +
274 + return entries;
275 +}
276 +
277 // Verifies that a string is a valid hex ID output.
278 // truncated=true expects 12 hex chars, truncated=false expects 64 hex chars.
279 inline void VerifyIdOutput(const std::wstring& id, bool truncated)
test/windows/wslc/e2e/WSLCE2EImageImportTests.cpp
+1 -1
@@ -103,7 +103,7 @@ class WSLCE2EImageImportTests
103 auto countUntaggedImages = [&]() {
104 auto result = RunWslc(L"image list --format json");
105 result.Verify({.Stderr = L"", .ExitCode = 0});
106 - auto images = FromJson<std::vector<wsl::windows::wslc::models::ImageInformation>>(result.Stdout.value().c_str());
106 + auto images = ParseNdjsonOutputAs<wsl::windows::wslc::models::ImageInformation>(result);
107 size_t count = 0;
108 for (const auto& img : images)
109 {
test/windows/wslc/e2e/WSLCE2EImageListTests.cpp
+7 -7
@@ -67,7 +67,7 @@ class WSLCE2EImageListTests
67 // Get the expected image ID from JSON output.
68 auto jsonResult = RunWslc(L"image list --format json");
69 jsonResult.Verify({.Stderr = L"", .ExitCode = 0});
70 - const auto images = wsl::shared::FromJson<std::vector<ImageInformation>>(jsonResult.Stdout.value().c_str());
70 + const auto images = ParseNdjsonOutputAs<ImageInformation>(jsonResult);
71
72 std::string debianId;
73 for (const auto& image : images)
@@ -128,7 +128,7 @@ class WSLCE2EImageListTests
128 const auto result = RunWslc(L"image list --format json");
129 result.Verify({.Stderr = L"", .ExitCode = 0});
130
131 - const auto images = wsl::shared::FromJson<std::vector<ImageInformation>>(result.Stdout.value().c_str());
131 + const auto images = ParseNdjsonOutputAs<ImageInformation>(result);
132
133 VERIFY_IS_GREATER_THAN_OR_EQUAL(images.size(), 2u);
134
@@ -188,7 +188,7 @@ class WSLCE2EImageListTests
188 auto listNames = [&](const std::wstring& filterArgs) {
189 auto r = RunWslc(std::format(L"image list --format json {}", filterArgs));
190 r.Verify({.Stderr = L"", .ExitCode = 0});
191 - const auto images = wsl::shared::FromJson<std::vector<ImageInformation>>(r.Stdout.value().c_str());
191 + const auto images = ParseNdjsonOutputAs<ImageInformation>(r);
192 std::set<std::wstring> names;
193 for (const auto& image : images)
194 {
@@ -234,7 +234,7 @@ class WSLCE2EImageListTests
234 auto result = RunWslc(L"image list --format json --filter dangling=false");
235 result.Verify({.Stderr = L"", .ExitCode = 0});
236
237 - auto images = wsl::shared::FromJson<std::vector<ImageInformation>>(result.Stdout.value().c_str());
237 + auto images = ParseNdjsonOutputAs<ImageInformation>(result);
238 bool foundDebian = false;
239 for (const auto& image : images)
240 {
@@ -250,7 +250,7 @@ class WSLCE2EImageListTests
250 result = RunWslc(L"image list --format json --filter dangling=true");
251 result.Verify({.Stderr = L"", .ExitCode = 0});
252
253 - images = wsl::shared::FromJson<std::vector<ImageInformation>>(result.Stdout.value().c_str());
253 + images = ParseNdjsonOutputAs<ImageInformation>(result);
254 for (const auto& image : images)
255 {
256 VERIFY_IS_FALSE(
@@ -267,7 +267,7 @@ class WSLCE2EImageListTests
267 RunWslc(std::format(L"image list --format json --filter reference={} --filter dangling=false", DebianImage.Name));
268 result.Verify({.Stderr = L"", .ExitCode = 0});
269
270 - const auto images = wsl::shared::FromJson<std::vector<ImageInformation>>(result.Stdout.value().c_str());
270 + const auto images = ParseNdjsonOutputAs<ImageInformation>(result);
271 bool foundDebian = false;
272 for (const auto& image : images)
273 {
@@ -286,7 +286,7 @@ class WSLCE2EImageListTests
286 // Pull the full image id from JSON output (always untruncated).
287 auto jsonResult = RunWslc(L"image list --format json");
288 jsonResult.Verify({.Stderr = L"", .ExitCode = 0});
289 - const auto images = wsl::shared::FromJson<std::vector<ImageInformation>>(jsonResult.Stdout.value().c_str());
289 + const auto images = ParseNdjsonOutputAs<ImageInformation>(jsonResult);
290
291 std::string fullDebianId;
292 for (const auto& image : images)
test/windows/wslc/e2e/WSLCE2ENetworkListTests.cpp
+1 -1
@@ -78,7 +78,7 @@ class WSLCE2ENetworkListTests
78 result = RunWslc(L"network list --format json");
79 result.Verify({.Stderr = L"", .ExitCode = 0});
80
81 - auto networks = FromJson<std::vector<WSLCNetworkInformation>>(result.Stdout.value().c_str());
81 + auto networks = ParseNdjsonOutputAs<WSLCNetworkInformation>(result);
82 VERIFY_ARE_EQUAL(2U, networks.size());
83
84 std::vector<std::string> names;
test/windows/wslc/e2e/WSLCE2EVolumeListTests.cpp
+1 -1
@@ -80,7 +80,7 @@ class WSLCE2EVolumeListTests
80 result = RunWslc(L"volume list --format json");
81 result.Verify({.Stderr = L"", .ExitCode = 0});
82
83 - auto volumes = FromJson<std::vector<WSLCVolumeInformation>>(result.Stdout.value().c_str());
83 + auto volumes = ParseNdjsonOutputAs<WSLCVolumeInformation>(result);
84 VERIFY_ARE_EQUAL(2U, volumes.size());
85
86 std::vector<std::string> names;