master
cpp 143 lines 5.36 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 WSLCE2EImageInspectTests.cpp
8
9 Abstract:
10
11 This file contains end-to-end tests for WSLC.
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 <wslc_schema.h>
20
21 namespace WSLCE2ETests {
22 using namespace wsl::shared;
23
24 class WSLCE2EImageInspectTests
25 {
26 WSLC_TEST_CLASS(WSLCE2EImageInspectTests)
27
28 TEST_CLASS_SETUP(ClassSetup)
29 {
30 TestImageRegistry::Instance().EnsureLoaded(DebianImage);
31 return true;
32 }
33
34 TEST_CLASS_CLEANUP(ClassCleanup)
35 {
36 TestImageRegistry::Instance().Delete(BuiltExposeImage);
37 return true;
38 }
39
40 WSLC_TEST_METHOD(WSLCE2E_Image_Inspect_HelpCommand)
41 {
42 auto result = RunWslc(L"image inspect --help");
43 result.Verify({.Stderr = L"", .ExitCode = 0});
44 VERIFY_IS_FALSE(result.Stdout.value().empty());
45 }
46
47 WSLC_TEST_METHOD(WSLCE2E_Image_Inspect_MissingImageName)
48 {
49 auto result = RunWslc(L"image inspect");
50 result.Verify({.Stdout = L"", .ExitCode = 1});
51 VERIFY_IS_TRUE(result.StderrContainsSubstring(L"Required argument not provided: 'image'"));
52 }
53
54 WSLC_TEST_METHOD(WSLCE2E_Image_Inspect_ImageNotFound)
55 {
56 auto result = RunWslc(std::format(L"image inspect {}", InvalidImage.NameAndTag()));
57 result.Verify({.Stdout = L"[]\r\n", .Stderr = std::format(L"Image '{}' not found.\r\n", InvalidImage.NameAndTag()), .ExitCode = 1});
58 }
59
60 WSLC_TEST_METHOD(WSLCE2E_Image_Inspect_FormatJson_IsSingleLine)
61 {
62 auto result = RunWslc(std::format(L"image inspect --format json {}", DebianImage.NameAndTag()));
63 result.Verify({.Stderr = L"", .ExitCode = 0});
64
65 const auto document = VerifyCompactJsonOutput(result);
66 VERIFY_IS_TRUE(document.is_array());
67 VERIFY_ARE_EQUAL(1u, document.size());
68 VERIFY_ARE_EQUAL(wsl::shared::string::WideToMultiByte(DebianImage.NameAndTag()), document[0]["RepoTags"][0].get<std::string>());
69 }
70
71 WSLC_TEST_METHOD(WSLCE2E_Image_Inspect_Success)
72 {
73 auto result = RunWslc(std::format(L"image inspect {}", DebianImage.NameAndTag()));
74 result.Verify({.Stderr = L"", .ExitCode = 0});
75 auto inspectData =
76 wsl::shared::FromJson<std::vector<wsl::windows::common::wslc_schema::InspectImage>>(result.Stdout.value().c_str());
77 VERIFY_ARE_EQUAL(1u, inspectData.size());
78 VERIFY_IS_TRUE(inspectData[0].RepoTags.has_value());
79 VERIFY_ARE_EQUAL(1u, inspectData[0].RepoTags.value().size());
80 VERIFY_ARE_EQUAL(DebianImage.NameAndTag(), wsl::shared::string::MultiByteToWide(inspectData[0].RepoTags.value()[0]));
81
82 // Verify RootFS is populated.
83 VERIFY_IS_TRUE(inspectData[0].RootFS.has_value());
84 VERIFY_ARE_EQUAL(std::string{"layers"}, inspectData[0].RootFS.value().Type);
85 VERIFY_IS_TRUE(inspectData[0].RootFS.value().Layers.has_value());
86 VERIFY_IS_GREATER_THAN(inspectData[0].RootFS.value().Layers.value().size(), 0u);
87
88 // Debian has no ExposedPorts or Volumes.
89 VERIFY_IS_TRUE(inspectData[0].Config.has_value());
90 VERIFY_IS_FALSE(inspectData[0].Config.value().ExposedPorts.has_value());
91 VERIFY_IS_FALSE(inspectData[0].Config.value().Volumes.has_value());
92 }
93
94 WSLC_TEST_METHOD(WSLCE2E_Image_Inspect_ConfigExtras_Success)
95 {
96 auto testRoot = std::filesystem::current_path() / L"wslc-e2e-inspect-config-extras";
97 auto cleanupDir = SetupTestDirectory(testRoot);
98
99 auto contextDir = testRoot / L"context";
100 std::error_code ec;
101 std::filesystem::create_directories(contextDir, ec);
102 THROW_HR_IF(E_FAIL, ec.value() != 0 || !std::filesystem::exists(contextDir));
103
104 auto dockerfilePath = testRoot / L"Dockerfile";
105 WriteTestFileContent(
106 dockerfilePath,
107 std::format(
108 "FROM {}\n"
109 "EXPOSE 8080/tcp\n"
110 "EXPOSE 9090/udp\n"
111 "VOLUME /data\n"
112 "VOLUME /var/log/app\n"
113 "STOPSIGNAL SIGTERM\n",
114 wsl::shared::string::WideToMultiByte(DebianImage.NameAndTag())));
115
116 auto buildResult = RunWslc(std::format(
117 L"build \"{}\" -f \"{}\" -t {}", contextDir.wstring(), dockerfilePath.wstring(), BuiltExposeImage.NameAndTag()));
118 buildResult.Verify({.Stdout = L"", .ExitCode = 0});
119
120 auto inspectData = InspectImage(BuiltExposeImage.NameAndTag());
121 VERIFY_IS_TRUE(inspectData.Config.has_value());
122 const auto& config = inspectData.Config.value();
123
124 VERIFY_IS_TRUE(config.ExposedPorts.has_value());
125 const auto& ports = config.ExposedPorts.value();
126 VERIFY_IS_TRUE(ports.contains("8080/tcp"));
127 VERIFY_IS_TRUE(ports.contains("9090/udp"));
128
129 VERIFY_IS_TRUE(config.Volumes.has_value());
130 const auto& volumes = config.Volumes.value();
131 VERIFY_IS_TRUE(volumes.contains("/data"));
132 VERIFY_IS_TRUE(volumes.contains("/var/log/app"));
133
134 VERIFY_ARE_EQUAL(std::string{"SIGTERM"}, config.StopSignal);
135 }
136
137 private:
138 const std::wstring WslcContainerName = L"wslc-test-container";
139 const TestImage& DebianImage = DebianTestImage();
140 const TestImage& InvalidImage = InvalidTestImage();
141 const TestImage BuiltExposeImage{L"wslc-e2e-inspect-config-extras", L"latest", L""};
142 };
143 } // namespace WSLCE2ETests