master
cpp 168 lines 5.94 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 WSLCE2EImageImportTests.cpp
8
9 Abstract:
10
11 This file contains end-to-end tests for WSLC image import.
12 --*/
13
14 #include "precomp.h"
15 #include "windows/Common.h"
16 #include "WSLCExecutor.h"
17 #include "WSLCE2EHelpers.h"
18 #include "TestImageRegistry.h"
19 #include "ImageModel.h"
20
21 namespace WSLCE2ETests {
22 using namespace wsl::shared;
23
24 class WSLCE2EImageImportTests
25 {
26 WSLC_TEST_CLASS(WSLCE2EImageImportTests)
27
28 TEST_CLASS_CLEANUP(ClassCleanup)
29 {
30 TestImageRegistry::Instance().Delete(ImportedImage);
31 EnsureNoUntaggedImages();
32 return true;
33 }
34
35 TEST_METHOD_SETUP(MethodSetup)
36 {
37 TestImageRegistry::Instance().EnsureLoaded(DebianImage);
38 TestImageRegistry::Instance().Delete(ImportedImage);
39 EnsureNoUntaggedImages();
40 SavedArchivePath = wsl::windows::common::filesystem::GetTempFilename();
41 return true;
42 }
43
44 TEST_METHOD_CLEANUP(MethodCleanup)
45 {
46 DeleteFileW(SavedArchivePath.c_str());
47 return true;
48 }
49
50 WSLC_TEST_METHOD(WSLCE2E_Image_Import_HelpCommand)
51 {
52 auto result = RunWslc(L"image import --help");
53 result.Verify({.Stderr = L"", .ExitCode = 0});
54 VERIFY_IS_FALSE(result.Stdout.value().empty());
55 }
56
57 WSLC_TEST_METHOD(WSLCE2E_Image_Import_MissingFile)
58 {
59 const auto result = RunWslc(L"image import");
60 result.Verify({.Stdout = L"", .ExitCode = 1});
61 VERIFY_IS_TRUE(result.StderrContainsSubstring(L"Required argument not provided: 'file'"));
62 }
63
64 WSLC_TEST_METHOD(WSLCE2E_Image_Import_Success)
65 {
66 // Save image as a tarball
67 auto saveResult = RunWslc(std::format(L"image save --output \"{}\" {}", SavedArchivePath.wstring(), DebianImage.NameAndTag()));
68 saveResult.Verify({.Stdout = L"", .Stderr = L"", .ExitCode = 0});
69
70 // Import the tarball as a new image with a tag
71 auto importResult = RunWslc(std::format(L"image import \"{}\" {}", SavedArchivePath.wstring(), ImportedImage.NameAndTag()));
72 importResult.Verify({.Stderr = L"", .ExitCode = 0});
73
74 VerifyIdOutput(importResult.GetStdoutOneLine(), true);
75
76 // Verify the imported image is listed
77 VerifyImageIsListed(ImportedImage);
78 }
79
80 WSLC_TEST_METHOD(WSLCE2E_Image_Import_Success_NoTrunc)
81 {
82 // Save image as a tarball
83 auto saveResult = RunWslc(std::format(L"image save --output \"{}\" {}", SavedArchivePath.wstring(), DebianImage.NameAndTag()));
84 saveResult.Verify({.Stdout = L"", .Stderr = L"", .ExitCode = 0});
85
86 // Import with --no-trunc
87 auto importResult =
88 RunWslc(std::format(L"image import --no-trunc \"{}\" {}", SavedArchivePath.wstring(), ImportedImage.NameAndTag()));
89 importResult.Verify({.Stderr = L"", .ExitCode = 0});
90
91 VerifyIdOutput(importResult.GetStdoutOneLine(), false);
92
93 // Verify the imported image is listed
94 VerifyImageIsListed(ImportedImage);
95 }
96
97 WSLC_TEST_METHOD(WSLCE2E_Image_Import_WithoutTag)
98 {
99 // Save image as a tarball
100 auto saveResult = RunWslc(std::format(L"image save --output \"{}\" {}", SavedArchivePath.wstring(), DebianImage.NameAndTag()));
101 saveResult.Verify({.Stdout = L"", .Stderr = L"", .ExitCode = 0});
102
103 auto countUntaggedImages = [&]() {
104 auto result = RunWslc(L"image list --format json");
105 result.Verify({.Stderr = L"", .ExitCode = 0});
106 auto images = ParseNdjsonOutputAs<wsl::windows::wslc::models::ImageOutputInformation>(result);
107 size_t count = 0;
108 for (const auto& img : images)
109 {
110 if (img.Repository == wsl::windows::wslc::models::c_none)
111 {
112 count++;
113 }
114 }
115 return count;
116 };
117
118 auto untaggedBefore = countUntaggedImages();
119
120 // Import without specifying an image name — creates an untagged image
121 auto importResult = RunWslc(std::format(L"image import \"{}\"", SavedArchivePath.wstring()));
122
123 // Extract the returned ID, validate its format, and use it for cleanup
124 auto imageId = importResult.GetStdoutOneLine();
125
126 // As soon as we have the image ID, set up cleanup.
127 auto cleanup = wil::scope_exit([&] {
128 auto deleteResult = RunWslc(std::format(L"image rm {}", imageId));
129 deleteResult.Verify({.ExitCode = 0});
130 });
131
132 // Import and image id verification is intentionally after the scope exit is created
133 // for best-effort cleanup if verification fails.
134 importResult.Verify({.Stderr = L"", .ExitCode = 0});
135 VerifyIdOutput(imageId, true);
136
137 // Verify that there is now one more untagged image
138 VERIFY_ARE_EQUAL(countUntaggedImages(), untaggedBefore + 1);
139 }
140
141 WSLC_TEST_METHOD(WSLCE2E_Image_Import_FromStdin_Success)
142 {
143 // Save image as a tarball
144 auto saveResult = RunWslc(std::format(L"image save --output \"{}\" {}", SavedArchivePath.wstring(), DebianImage.NameAndTag()));
145 saveResult.Verify({.Stdout = L"", .Stderr = L"", .ExitCode = 0});
146
147 // '-' reads the archive from stdin; a file handle is required because import needs the size.
148 auto importResult = RunWslcWithStdinFile(std::format(L"image import - {}", ImportedImage.NameAndTag()), SavedArchivePath);
149 importResult.Verify({.Stderr = L"", .ExitCode = 0});
150
151 VerifyIdOutput(importResult.GetStdoutOneLine(), true);
152 VerifyImageIsListed(ImportedImage);
153 }
154
155 WSLC_TEST_METHOD(WSLCE2E_Image_Import_InvalidPath)
156 {
157 const auto result =
158 RunWslc(std::format(L"image import \"{}\" {}", L"C:\\nonexistent\\path\\image.tar", ImportedImage.NameAndTag()));
159 result.Verify({.ExitCode = 1});
160 }
161
162 private:
163 const TestImage DebianImage = DebianTestImage();
164 const TestImage ImportedImage{L"wslc-test-imported", L"latest", L""};
165
166 std::filesystem::path SavedArchivePath{};
167 };
168 } // namespace WSLCE2ETests