Refactor tests: use TAEF metadata for WSL version filtering (#40129)

Replace runtime WSL2_TEST_ONLY()/WSL1_TEST_ONLY() skip macros with
TAEF metadata-based test selection. Tests that don't apply to the
current WSL version are now excluded by /select: queries at selection
time rather than skipped at runtime, eliminating hundreds of 'skipped'
results from test output.

Changes:
- Add WSL2_TEST_METHOD, WSL1_TEST_METHOD, WSLC_TEST_METHOD macros
  in Common.h that tag tests with WSLVersion metadata property
- Convert ~430 test methods across 26 files to use new macros
- Update run-tests.ps1 to auto-add /select: version filter
- Update CloudTest XML configs with version selection queries
- Remove WSL2_TEST_ONLY() from composite macros in NetworkTests.cpp
- Update test README with new macro documentation

Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Ben Hillis
2026-04-08 17:45:18 -07:00
committed by GitHub
parent 01706c9cdc
commit 9c4dba919f
30 changed files with 610 additions and 1372 deletions

View File

@@ -22,6 +22,6 @@
</Setup>
<TestJob Name="CloudTest.Taef" TimeoutMins="120">
<Execution Type="TAEF" Path="[WorkingDirectory]\wsltests.dll" Args="/p:bugReportDirectory=[LoggingDirectory]\BugReportOutput /errorOnCrash /testmode:etwlogger /EtwLogger:WPRProfileFile=[WorkingDirectory]\wsl.wprp /EtwLogger:WPRProfile=WSL /EtwLogger:SavePoint=ExecutionComplete /EtwLogger:RecordingScope=Execution /p:SetupScript=.\test-setup.ps1 /p:Package=[WorkingDirectory]\Microsoft.WSL_${PACKAGE_VERSION}_x64_ARM64.msixbundle /p:Version=2 /p:AllowUnsigned=${ALLOW_UNSIGNED_PACKAGE} /p:UnitTestsPath=[WorkingDirectory]\unit_tests /p:DistroPath=[WorkingDirectory]\test_distro.tar.xz /p:TestDataPath=[WorkingDirectory]\test_data /p:DistroName=test_distro /logOutput:High /p:RedirectStdout=[LoggingDirectory]\stdout.txt /p:RedirectStderr=[LoggingDirectory]\stderr.txt /p:KernelLogs=[LoggingDirectory]\dmesg.txt /p:DumpFolder=[LoggingDirectory] /p:WerReport /p:LogDmesg /p:PipelineBuildId=${PIPELINE_BUILD_ID} /p:DumpTool=DumpTool.exe /select:&quot;@TestCategory='WSLC'&quot;" />
<Execution Type="TAEF" Path="[WorkingDirectory]\wsltests.dll" Args="/p:bugReportDirectory=[LoggingDirectory]\BugReportOutput /errorOnCrash /testmode:etwlogger /EtwLogger:WPRProfileFile=[WorkingDirectory]\wsl.wprp /EtwLogger:WPRProfile=WSL /EtwLogger:SavePoint=ExecutionComplete /EtwLogger:RecordingScope=Execution /p:SetupScript=.\test-setup.ps1 /p:Package=[WorkingDirectory]\Microsoft.WSL_${PACKAGE_VERSION}_x64_ARM64.msixbundle /p:Version=2 /p:AllowUnsigned=${ALLOW_UNSIGNED_PACKAGE} /p:UnitTestsPath=[WorkingDirectory]\unit_tests /p:DistroPath=[WorkingDirectory]\test_distro.tar.xz /p:TestDataPath=[WorkingDirectory]\test_data /p:DistroName=test_distro /logOutput:High /p:RedirectStdout=[LoggingDirectory]\stdout.txt /p:RedirectStderr=[LoggingDirectory]\stderr.txt /p:KernelLogs=[LoggingDirectory]\dmesg.txt /p:DumpFolder=[LoggingDirectory] /p:WerReport /p:LogDmesg /p:PipelineBuildId=${PIPELINE_BUILD_ID} /p:DumpTool=DumpTool.exe /select:&quot;@TestCategory='WSLC' and (@WSLVersion='2' or not(@WSLVersion='*'))&quot;" />
</TestJob>
</TestJobGroup>

View File

@@ -22,6 +22,6 @@
</Setup>
<TestJob Name="CloudTest.Taef" TimeoutMins="240">
<Execution Type="TAEF" Path="[WorkingDirectory]\wsltests.dll" Args="/p:bugReportDirectory=[LoggingDirectory]\BugReportOutput /errorOnCrash /testmode:etwlogger /EtwLogger:WPRProfileFile=[WorkingDirectory]\wsl.wprp /EtwLogger:WPRProfile=WSL /EtwLogger:SavePoint=ExecutionComplete /EtwLogger:RecordingScope=Execution /p:SetupScript=.\test-setup.ps1 /p:Package=[WorkingDirectory]\Microsoft.WSL_${PACKAGE_VERSION}_x64_ARM64.msixbundle /p:Version=${version} /p:AllowUnsigned=${ALLOW_UNSIGNED_PACKAGE} /p:UnitTestsPath=[WorkingDirectory]\unit_tests /p:DistroPath=[WorkingDirectory]\test_distro.tar.xz /p:TestDataPath=[WorkingDirectory]\test_data /p:DistroName=test_distro /logOutput:High /p:RedirectStdout=[LoggingDirectory]\stdout.txt /p:RedirectStderr=[LoggingDirectory]\stderr.txt /p:KernelLogs=[LoggingDirectory]\dmesg.txt /p:DumpFolder=[LoggingDirectory] /p:WerReport /p:LogDmesg /p:PipelineBuildId=${PIPELINE_BUILD_ID} /p:DumpTool=DumpTool.exe /select:&quot;not(@TestCategory='WSLC')&quot;" />
<Execution Type="TAEF" Path="[WorkingDirectory]\wsltests.dll" Args="/p:bugReportDirectory=[LoggingDirectory]\BugReportOutput /errorOnCrash /testmode:etwlogger /EtwLogger:WPRProfileFile=[WorkingDirectory]\wsl.wprp /EtwLogger:WPRProfile=WSL /EtwLogger:SavePoint=ExecutionComplete /EtwLogger:RecordingScope=Execution /p:SetupScript=.\test-setup.ps1 /p:Package=[WorkingDirectory]\Microsoft.WSL_${PACKAGE_VERSION}_x64_ARM64.msixbundle /p:Version=${version} /p:AllowUnsigned=${ALLOW_UNSIGNED_PACKAGE} /p:UnitTestsPath=[WorkingDirectory]\unit_tests /p:DistroPath=[WorkingDirectory]\test_distro.tar.xz /p:TestDataPath=[WorkingDirectory]\test_data /p:DistroName=test_distro /logOutput:High /p:RedirectStdout=[LoggingDirectory]\stdout.txt /p:RedirectStderr=[LoggingDirectory]\stderr.txt /p:KernelLogs=[LoggingDirectory]\dmesg.txt /p:DumpFolder=[LoggingDirectory] /p:WerReport /p:LogDmesg /p:PipelineBuildId=${PIPELINE_BUILD_ID} /p:DumpTool=DumpTool.exe /select:&quot;not(@TestCategory='WSLC') and (@WSLVersion='${version}' or not(@WSLVersion='*'))&quot;" />
</TestJob>
</TestJobGroup>

View File

@@ -81,6 +81,18 @@ Below is a brief overview:
### Writing the Test
For tests that only apply to a specific WSL version, use the version-specific test method macros instead of `TEST_METHOD`:
- `WSL2_TEST_METHOD(Name)` — test only runs on WSL2
- `WSL1_TEST_METHOD(Name)` — test only runs on WSL1
- `WSLC_TEST_METHOD(Name)` — test only runs on WSL2 (for use in WSLC test classes)
- `TEST_METHOD(Name)` — test runs on both WSL1 and WSL2
These macros use TAEF metadata properties to tag tests with their required WSL version.
When tests are run via `run-tests.ps1` or CloudTest, a `/select:` query automatically
filters out tests that don't match the target version—so they don't appear in results at all
(no "skipped" noise).
For example, consider the file below, named `ExampleTest.cpp`:
```cpp
@@ -96,13 +108,19 @@ For example, consider the file below, named `ExampleTest.cpp`:
{
TEST_CLASS(ExampleTest) // define this as a test class
// add tests via test methods of the test class
TEST_METHOD(HelloWorldTest) // ExampleTest::ExampleTest::HelloWorldTest
// runs on both WSL1 and WSL2
TEST_METHOD(HelloWorldTest)
{
std::wstring outputExpected = L"Linux on Windows Rocks!\n";
auto [output, __] = LxsstuLaunchWslAndCaptureOutput(L"echo Linux on Windows Rocks!"); // from /test/Common.h
VERIFY_ARE_EQUAL(output, outputExpected); // TAEF test method that passes if both are equal, and fails otherwise.
}
// only runs on WSL2
WSL2_TEST_METHOD(Wsl2OnlyTest)
{
// ...
}
};
} //namespace ExampleTest
```

View File

@@ -38,19 +38,29 @@ using namespace std::chrono_literals;
#define LXSST_REMOVE_DISTRO_CONF_COMMAND_LINE L"-u root -e rm /etc/wsl.conf"
#define WSL1_TEST_ONLY() \
if (LxsstuVmMode()) \
{ \
LogSkipped("This test is only applicable to WSL1"); \
return; \
}
//
// Test method declaration macros that tag tests with TAEF metadata for version-based selection.
// Use these instead of TEST_METHOD() for tests that only apply to a specific WSL version.
// When run via run-tests.ps1 or CloudTest, inapplicable tests are excluded from the run
// entirely (no "skipped" noise) via TAEF /select: queries.
//
#define WSL1_TEST_METHOD(_name) \
TAEF_BEGIN_TEST_METHOD_PROPERTIES_IN_CLASS_SCOPE(_name) \
TEST_METHOD_PROPERTY(L"WSLVersion", L"1") \
TAEF_END_TEST_METHOD_PROPERTIES_IN_CLASS_SCOPE() \
TEST_METHOD(_name)
#define WSL2_TEST_ONLY() \
if (!LxsstuVmMode()) \
{ \
LogSkipped("This test is only applicable to WSL2"); \
return; \
}
#define WSL2_TEST_METHOD(_name) \
TAEF_BEGIN_TEST_METHOD_PROPERTIES_IN_CLASS_SCOPE(_name) \
TEST_METHOD_PROPERTY(L"WSLVersion", L"2") \
TAEF_END_TEST_METHOD_PROPERTIES_IN_CLASS_SCOPE() \
TEST_METHOD(_name)
#define WSLC_TEST_METHOD(_name) \
TAEF_BEGIN_TEST_METHOD_PROPERTIES_IN_CLASS_SCOPE(_name) \
TEST_METHOD_PROPERTY(L"WSLVersion", L"2") \
TAEF_END_TEST_METHOD_PROPERTIES_IN_CLASS_SCOPE() \
TEST_METHOD(_name)
// macro for skipping tests that are currently failing due to not yet being fully implemented
#define SKIP_TEST_NOT_IMPL() \

View File

@@ -258,7 +258,6 @@ public:
void DrvfsMountElevated(DrvFsMode Mode)
{
WSL2_TEST_ONLY();
WINDOWS_11_TEST_ONLY(); // TODO: Enable on Windows 10 when virtio support is added
SKIP_TEST_ARM64();
@@ -270,7 +269,6 @@ public:
void DrvfsMountElevatedDifferentConsole(DrvFsMode Mode)
{
WSL2_TEST_ONLY();
WINDOWS_11_TEST_ONLY(); // TODO: Enable on Windows 10 when virtio support is added
SKIP_TEST_ARM64();
@@ -282,7 +280,6 @@ public:
void DrvfsMountNonElevated(DrvFsMode Mode)
{
WSL2_TEST_ONLY();
WINDOWS_11_TEST_ONLY(); // TODO: Enable on Windows 10 when virtio support is added
SKIP_TEST_ARM64();
@@ -296,7 +293,6 @@ public:
void DrvfsMountNonElevatedDifferentConsole(DrvFsMode Mode)
{
WSL2_TEST_ONLY();
WINDOWS_11_TEST_ONLY(); // TODO: Enable on Windows 10 when virtio support is added
SKIP_TEST_ARM64();
@@ -310,7 +306,6 @@ public:
void DrvfsMountElevatedSystemDistroEnabled(DrvFsMode Mode)
{
WSL2_TEST_ONLY();
WINDOWS_11_TEST_ONLY(); // TODO: Enable on Windows 10 when virtio support is added
SKIP_TEST_ARM64();
@@ -322,7 +317,6 @@ public:
void DrvfsMountNonElevatedSystemDistroEnabled(DrvFsMode Mode)
{
WSL2_TEST_ONLY();
WINDOWS_11_TEST_ONLY(); // TODO: Enable on Windows 10 when virtio support is added
SKIP_TEST_ARM64();
@@ -383,8 +377,6 @@ public:
void DrvFsMountUnicodePath(DrvFsMode Mode)
{
WSL2_TEST_ONLY();
// Create a Windows directory with unicode characters
constexpr auto unicodeDir = L"C:\\drvfs-测试-テスト";
auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() { std::filesystem::remove_all(unicodeDir); });
@@ -1149,63 +1141,53 @@ class WSL1 : public DrvFsTests
return true;
}
TEST_METHOD(DrvFsDisableQueryByName)
WSL1_TEST_METHOD(DrvFsDisableQueryByName)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(DrvFsCommon(LX_DRVFS_DISABLE_QUERY_BY_NAME));
}
TEST_METHOD(DrvFsDisableQueryByNameAndStatInfo)
WSL1_TEST_METHOD(DrvFsDisableQueryByNameAndStatInfo)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(DrvFsCommon(LX_DRVFS_DISABLE_QUERY_BY_NAME_AND_STAT_INFO));
}
TEST_METHOD(VfsAccessDrvFs)
WSL1_TEST_METHOD(VfsAccessDrvFs)
{
WSL1_TEST_ONLY();
DrvFsTests::VfsAccessDrvFs();
}
TEST_METHOD(FsCommonDrvFs)
WSL1_TEST_METHOD(FsCommonDrvFs)
{
WSL1_TEST_ONLY();
DrvFsTests::FsCommonDrvFs();
}
TEST_METHOD(DrvFs)
WSL1_TEST_METHOD(DrvFs)
{
WSL1_TEST_ONLY();
DrvFsTests::DrvFs(DrvFsMode::WSL1);
}
TEST_METHOD(DrvFsFat)
WSL1_TEST_METHOD(DrvFsFat)
{
WSL1_TEST_ONLY();
DrvFsTests::DrvFsFat(DrvFsMode::WSL1);
}
TEST_METHOD(DrvFsSmb)
WSL1_TEST_METHOD(DrvFsSmb)
{
WSL1_TEST_ONLY();
DrvFsTests::DrvFsSmb(DrvFsMode::WSL1);
}
TEST_METHOD(DrvFsMetadata)
WSL1_TEST_METHOD(DrvFsMetadata)
{
WSL1_TEST_ONLY();
DrvFsTests::DrvFsMetadata(DrvFsMode::WSL1);
}
TEST_METHOD(XattrDrvFs)
WSL1_TEST_METHOD(XattrDrvFs)
{
WSL1_TEST_ONLY();
DrvFsTests::XattrDrvFs(DrvFsMode::WSL1);
}
TEST_METHOD(WslPath)
WSL1_TEST_METHOD(WslPath)
{
WSL1_TEST_ONLY();
DrvFsTests::WslPath(DrvFsMode::WSL1);
}
};
@@ -1242,99 +1224,83 @@ class WSL1 : public DrvFsTests
return true; \
} \
\
TEST_METHOD(VfsAccessDrvFs) \
WSL2_TEST_METHOD(VfsAccessDrvFs) \
{ \
WSL2_TEST_ONLY(); \
DrvFsTests::VfsAccessDrvFs(); \
} \
\
TEST_METHOD(FsCommonDrvFs) \
WSL2_TEST_METHOD(FsCommonDrvFs) \
{ \
WSL2_TEST_ONLY(); \
DrvFsTests::FsCommonDrvFs(); \
} \
\
TEST_METHOD(DrvFs) \
WSL2_TEST_METHOD(DrvFs) \
{ \
WSL2_TEST_ONLY(); \
DrvFsTests::DrvFs(DrvFsMode::##_mode##); \
} \
\
TEST_METHOD(DrvFsFat) \
WSL2_TEST_METHOD(DrvFsFat) \
{ \
WSL2_TEST_ONLY(); \
DrvFsTests::DrvFsFat(DrvFsMode::##_mode##); \
} \
\
TEST_METHOD(DrvFsSmb) \
WSL2_TEST_METHOD(DrvFsSmb) \
{ \
WSL2_TEST_ONLY(); \
DrvFsTests::DrvFsSmb(DrvFsMode::##_mode##); \
} \
\
TEST_METHOD(DrvFsMetadata) \
WSL2_TEST_METHOD(DrvFsMetadata) \
{ \
WSL2_TEST_ONLY(); \
DrvFsTests::DrvFsMetadata(DrvFsMode::##_mode##); \
} \
\
TEST_METHOD(DrvfsMountElevated) \
WSL2_TEST_METHOD(DrvfsMountElevated) \
{ \
WSL2_TEST_ONLY(); \
DrvFsTests::DrvfsMountElevated(DrvFsMode::##_mode##); \
} \
\
TEST_METHOD(DrvfsMountElevatedDifferentConsole) \
WSL2_TEST_METHOD(DrvfsMountElevatedDifferentConsole) \
{ \
WSL2_TEST_ONLY(); \
DrvFsTests::DrvfsMountElevatedDifferentConsole(DrvFsMode::##_mode##); \
} \
\
TEST_METHOD(DrvfsMountNonElevated) \
WSL2_TEST_METHOD(DrvfsMountNonElevated) \
{ \
WSL2_TEST_ONLY(); \
DrvFsTests::DrvfsMountNonElevated(DrvFsMode::##_mode##); \
} \
\
TEST_METHOD(DrvfsMountNonElevatedDifferentConsole) \
WSL2_TEST_METHOD(DrvfsMountNonElevatedDifferentConsole) \
{ \
WSL2_TEST_ONLY(); \
DrvFsTests::DrvfsMountNonElevatedDifferentConsole(DrvFsMode::##_mode##); \
} \
\
TEST_METHOD(DrvfsMountElevatedSystemDistroEnabled) \
WSL2_TEST_METHOD(DrvfsMountElevatedSystemDistroEnabled) \
{ \
WSL2_TEST_ONLY(); \
DrvFsTests::DrvfsMountElevatedSystemDistroEnabled(DrvFsMode::##_mode##); \
} \
\
TEST_METHOD(DrvfsMountNonElevatedSystemDistroEnabled) \
WSL2_TEST_METHOD(DrvfsMountNonElevatedSystemDistroEnabled) \
{ \
WSL2_TEST_ONLY(); \
DrvFsTests::DrvfsMountNonElevatedSystemDistroEnabled(DrvFsMode::##_mode##); \
} \
\
TEST_METHOD(XattrDrvFs) \
WSL2_TEST_METHOD(XattrDrvFs) \
{ \
WSL2_TEST_ONLY(); \
DrvFsTests::XattrDrvFs(DrvFsMode::##_mode##); \
} \
\
TEST_METHOD(DrvFsReFs) \
WSL2_TEST_METHOD(DrvFsReFs) \
{ \
WSL2_TEST_ONLY(); \
DrvFsTests::DrvFsReFs(DrvFsMode::##_mode##); \
} \
\
TEST_METHOD(WslPath) \
WSL2_TEST_METHOD(WslPath) \
{ \
WSL2_TEST_ONLY(); \
DrvFsTests::WslPath(DrvFsMode::##_mode##); \
} \
\
TEST_METHOD(DrvFsMountUnicodePath) \
WSL2_TEST_METHOD(DrvFsMountUnicodePath) \
{ \
WSL2_TEST_ONLY(); \
DrvFsTests::DrvFsMountUnicodePath(DrvFsMode::##_mode##); \
} \
}

View File

@@ -203,13 +203,13 @@ class MountTests
}
// Attach a vhd, but don't mount it
TEST_METHOD(TestBareMountVhd)
WSL2_TEST_METHOD(TestBareMountVhd)
{
TestBareMountImpl(true);
}
// Mount one partition using --vhd and validate that options are correctly applied
TEST_METHOD(TestMountOnePartitionVhd)
WSL2_TEST_METHOD(TestMountOnePartitionVhd)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
@@ -217,7 +217,7 @@ class MountTests
}
// Mount two partitions using --vhd on the same disk
TEST_METHOD(TestMountTwoPartitionsVhd)
WSL2_TEST_METHOD(TestMountTwoPartitionsVhd)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
@@ -225,7 +225,7 @@ class MountTests
}
// Run a bare mount using --vhd and then mount a partition
TEST_METHOD(TestAttachThenMountVhd)
WSL2_TEST_METHOD(TestAttachThenMountVhd)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
@@ -233,7 +233,7 @@ class MountTests
}
// Mount the disk directly
TEST_METHOD(TestMountWholeDiskVhd)
WSL2_TEST_METHOD(TestMountWholeDiskVhd)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
@@ -241,49 +241,49 @@ class MountTests
}
// Test that mount state is deleted on shutdown (--vhd)
TEST_METHOD(TestMountStateIsDeletedOnShutdownVhd)
WSL2_TEST_METHOD(TestMountStateIsDeletedOnShutdownVhd)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
TestMountStateIsDeletedOnShutdownImpl(true);
}
TEST_METHOD(TestFilesystemDetectionWholeDisk)
WSL2_TEST_METHOD(TestFilesystemDetectionWholeDisk)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
TestFilesystemDetectionWholeDiskImpl(false);
}
TEST_METHOD(TestFilesystemDetectionWholeDiskVhd)
WSL2_TEST_METHOD(TestFilesystemDetectionWholeDiskVhd)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
TestFilesystemDetectionWholeDiskImpl(true);
}
TEST_METHOD(TestMountTwoPartitionsWithDetection)
WSL2_TEST_METHOD(TestMountTwoPartitionsWithDetection)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
TestMountTwoPartitionsWithDetectionImpl(false);
}
TEST_METHOD(TestMountTwoPartitionsWithDetectionVhd)
WSL2_TEST_METHOD(TestMountTwoPartitionsWithDetectionVhd)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
TestMountTwoPartitionsWithDetectionImpl(true);
}
TEST_METHOD(TestFilesystemDetectionFail)
WSL2_TEST_METHOD(TestFilesystemDetectionFail)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
TestFilesystemDetectionFailImpl(false);
}
TEST_METHOD(TestFilesystemDetectionFailVhd)
WSL2_TEST_METHOD(TestFilesystemDetectionFailVhd)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
@@ -291,11 +291,9 @@ class MountTests
}
// Test specifying a mount name for a vhd
TEST_METHOD(SpecifyMountName)
WSL2_TEST_METHOD(SpecifyMountName)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL2_TEST_ONLY();
const auto mountCommand = L"--mount " + VhdDevice + L" --vhd --name " + TEST_MOUNT_NAME;
WslKeepAlive keepAlive;
@@ -344,11 +342,9 @@ class MountTests
}
// Test ensuring that name collision detection works in --mount --name
TEST_METHOD(SpecifyMountNameCollision)
WSL2_TEST_METHOD(SpecifyMountNameCollision)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL2_TEST_ONLY();
const auto mountCommand = L"--mount " + VhdDevice + L" --vhd --name " + TEST_MOUNT_NAME;
WslKeepAlive keepAlive;
@@ -372,11 +368,9 @@ class MountTests
}
// Test that multiple partitions can be mounted with --name
TEST_METHOD(SpecifyMountNameTwoPartitions)
WSL2_TEST_METHOD(SpecifyMountNameTwoPartitions)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL2_TEST_ONLY();
const auto mountCommandOne = L"--mount " + VhdDevice + L" --vhd --name " + TEST_MOUNT_NAME + L"p1";
const auto mountCommandTwo = L"--mount " + VhdDevice + L" --vhd --name " + TEST_MOUNT_NAME + L"p2";
@@ -403,11 +397,9 @@ class MountTests
}
// Test relative mount/unmounting of a --vhd
TEST_METHOD(RelativePathUnmount)
WSL2_TEST_METHOD(RelativePathUnmount)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL2_TEST_ONLY();
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"--mount " TEST_MOUNT_VHD L" --vhd --bare"), (DWORD)0);
const auto disk = GetBlockDeviceInWsl();
@@ -417,11 +409,9 @@ class MountTests
}
// Test relative mount/unmounting of a --vhd that does not exist
TEST_METHOD(RelativePathUnmountNoFileExists)
WSL2_TEST_METHOD(RelativePathUnmountNoFileExists)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL2_TEST_ONLY();
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"--mount " TEST_MOUNT_VHD L" --vhd --bare"), (DWORD)0);
const auto disk = GetBlockDeviceInWsl();
@@ -431,11 +421,9 @@ class MountTests
VERIFY_ARE_NOT_EQUAL(LxsstuLaunchWsl(L"--unmount " TEST_UNMOUNT_VHD_DNE), (DWORD)0);
}
TEST_METHOD(AbsolutePathVhdUnmount)
WSL2_TEST_METHOD(AbsolutePathVhdUnmount)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL2_TEST_ONLY();
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"--mount " TEST_MOUNT_VHD L" --vhd --bare"), (DWORD)0);
const auto disk = GetBlockDeviceInWsl();
@@ -451,7 +439,7 @@ class MountTests
}
// Attach a disk, but don't mount it
TEST_METHOD(TestBareMount)
WSL2_TEST_METHOD(TestBareMount)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
@@ -460,11 +448,9 @@ class MountTests
// Validate that attached disks that were offline when attached
// are still offline when detached
TEST_METHOD(TestOfflineDiskStaysOffline)
WSL2_TEST_METHOD(TestOfflineDiskStaysOffline)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL2_TEST_ONLY();
WslKeepAlive keepAlive;
auto diskHandle = wsl::windows::common::disk::OpenDevice(DiskDevice.c_str(), GENERIC_ALL, c_diskOpenTimeoutMs);
@@ -493,7 +479,7 @@ class MountTests
}
// Mount one partition and validate that options are correctly applied
TEST_METHOD(TestMountOnePartition)
WSL2_TEST_METHOD(TestMountOnePartition)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
@@ -501,7 +487,7 @@ class MountTests
}
// Mount two partitions on the same disk
TEST_METHOD(TestMountTwoPartitions)
WSL2_TEST_METHOD(TestMountTwoPartitions)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
@@ -509,11 +495,9 @@ class MountTests
}
// Mount a fat partition
TEST_METHOD(TestMountFatPartition)
WSL2_TEST_METHOD(TestMountFatPartition)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL2_TEST_ONLY();
WslKeepAlive keepAlive;
// Create a MBR disk with 1 ntfs partition
@@ -539,14 +523,14 @@ class MountTests
}
// Mount the disk directly
TEST_METHOD(TestMountWholeDisk)
WSL2_TEST_METHOD(TestMountWholeDisk)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
TestMountWholeDiskImpl(false);
}
TEST_METHOD(TestMountStateIsDeletedOnShutdown)
WSL2_TEST_METHOD(TestMountStateIsDeletedOnShutdown)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
@@ -554,11 +538,9 @@ class MountTests
}
// Validate that a failure to mount a disk isn't fatal
TEST_METHOD(TestMountFailuresArentFatal)
WSL2_TEST_METHOD(TestMountFailuresArentFatal)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL2_TEST_ONLY();
WslKeepAlive keepAlive;
// Create a MBR disk with 1 ext4 partition
@@ -615,20 +597,16 @@ class MountTests
}
// wsl --unmount should succeed even when no disk is mounted
TEST_METHOD(UnmountWithoutAnyDisk)
WSL2_TEST_METHOD(UnmountWithoutAnyDisk)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL2_TEST_ONLY();
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"--unmount"), (DWORD)0);
}
// Mount two partitions on the same disk and validate that the mount is restored
TEST_METHOD(TestMountTwoPartitionsAfterTimeout)
WSL2_TEST_METHOD(TestMountTwoPartitionsAfterTimeout)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL2_TEST_ONLY();
WslKeepAlive keepAlive;
// Create a MBR disk with 1 ext4 partition and one fat partitions
@@ -656,11 +634,9 @@ class MountTests
}
// Validate that non-admin can remount saved disks
TEST_METHOD(TestMount1PartitionAndRemountAsNonAdmin)
WSL2_TEST_METHOD(TestMount1PartitionAndRemountAsNonAdmin)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL2_TEST_ONLY();
WslKeepAlive keepAlive;
FormatDisk({L"ext4"}, false);
@@ -695,7 +671,7 @@ class MountTests
}
// Run a bare mount and then mount a partition
TEST_METHOD(TestAttachThenMount)
WSL2_TEST_METHOD(TestAttachThenMount)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
@@ -703,11 +679,9 @@ class MountTests
}
// Validate that unmounting works when the UVM is not running
TEST_METHOD(TestMountOnePartitionAfterTimeout)
WSL2_TEST_METHOD(TestMountOnePartitionAfterTimeout)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL2_TEST_ONLY();
WslKeepAlive keepAlive;
// Create a MBR disk with 1 ext4 partition
@@ -735,11 +709,9 @@ class MountTests
}
// Validate that the proper mount error is returned if the filesystem type is wrong
TEST_METHOD(TestMountPartitionWithWrongFs)
WSL2_TEST_METHOD(TestMountPartitionWithWrongFs)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL2_TEST_ONLY();
WslKeepAlive keepAlive;
// Create a MBR disk with 1 ext4 partition
@@ -759,11 +731,9 @@ class MountTests
}
// Validate that the proper mount error is returned if the partition can't be found
TEST_METHOD(TestMountPartitionWithBadPartitionIndex)
WSL2_TEST_METHOD(TestMountPartitionWithBadPartitionIndex)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL2_TEST_ONLY();
WslKeepAlive keepAlive;
// Create a MBR disk with 1 fat partition
@@ -783,11 +753,9 @@ class MountTests
}
// Validate that disk aren't detached if in use by other processes
TEST_METHOD(TestDeviceCantBeMountedIfInUse)
WSL2_TEST_METHOD(TestDeviceCantBeMountedIfInUse)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL2_TEST_ONLY();
{
// Format-Volume fails without automount enabled
SetAutoMountPolicy AutoMountPolicy{true};
@@ -836,11 +804,9 @@ class MountTests
VERIFY_ARE_EQUAL(output, wsl::shared::string::MultiByteToWide(fileContent));
}
TEST_METHOD(TestMountWithFlagOption)
WSL2_TEST_METHOD(TestMountWithFlagOption)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL2_TEST_ONLY();
WslKeepAlive keepAlive;
// Create a MBR disk with 1 ext4 partition
@@ -879,21 +845,17 @@ class MountTests
WaitForDiskReady();
}
TEST_METHOD(TestAttachFailsWithoutWsl2Distro)
WSL1_TEST_METHOD(TestAttachFailsWithoutWsl2Distro)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL1_TEST_ONLY();
// Attempt to mount a disk with only a WSL1 distro
wsl::windows::common::SvcComm service;
VERIFY_ARE_EQUAL(service.AttachDisk(L"Dummy", LXSS_ATTACH_MOUNT_FLAGS_PASS_THROUGH), WSL_E_WSL2_NEEDED);
}
TEST_METHOD(VhdWithSpaces)
WSL2_TEST_METHOD(VhdWithSpaces)
{
SKIP_UNSUPPORTED_ARM64_MOUNT_TEST();
WSL2_TEST_ONLY();
LxsstuLaunchPowershellAndCaptureOutput(L"New-Vhd -Path 'vhd with spaces.vhdx' -SizeBytes 20MB");
auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, []() {
@@ -1188,8 +1150,6 @@ class MountTests
void TestBareMountImpl(bool isVhd)
{
WSL2_TEST_ONLY();
WslKeepAlive keepAlive;
const auto deviceName = (isVhd) ? VhdDevice : DiskDevice;
@@ -1223,8 +1183,6 @@ class MountTests
void TestMountOnePartitionImpl(bool isVhd)
{
WSL2_TEST_ONLY();
const auto deviceName = (isVhd) ? VhdDevice : DiskDevice;
const auto mountCommand = (isVhd) ? (L"--mount " + deviceName + L" --vhd") : (L"--mount " + deviceName);
@@ -1279,8 +1237,6 @@ class MountTests
void TestMountTwoPartitionsImpl(bool isVhd)
{
WSL2_TEST_ONLY();
const auto deviceName = (isVhd) ? VhdDevice : DiskDevice;
const auto mountCommand = (isVhd) ? (L"--mount " + deviceName + L" --vhd") : (L"--mount " + deviceName);
@@ -1315,8 +1271,6 @@ class MountTests
void TestAttachThenMountImpl(bool isVhd)
{
WSL2_TEST_ONLY();
const auto deviceName = (isVhd) ? VhdDevice : DiskDevice;
const auto mountCommand = (isVhd) ? (L"--mount " + deviceName + L" --vhd") : (L"--mount " + deviceName);
@@ -1346,8 +1300,6 @@ class MountTests
void TestMountWholeDiskImpl(bool isVhd)
{
WSL2_TEST_ONLY();
const auto deviceName = (isVhd) ? VhdDevice : DiskDevice;
const auto mountCommand = (isVhd) ? (L"--mount " + deviceName + L" --vhd") : (L"--mount " + deviceName);
@@ -1381,8 +1333,6 @@ class MountTests
void TestMountStateIsDeletedOnShutdownImpl(bool isVhd)
{
WSL2_TEST_ONLY();
const auto deviceName = (isVhd) ? VhdDevice : DiskDevice;
const auto mountCommand = (isVhd) ? (L"--mount " + deviceName + L" --vhd") : (L"--mount " + deviceName);
@@ -1414,8 +1364,6 @@ class MountTests
void TestFilesystemDetectionWholeDiskImpl(bool isVhd)
{
WSL2_TEST_ONLY();
const auto deviceName = (isVhd) ? VhdDevice : DiskDevice;
const auto mountCommand = (isVhd) ? (L"--mount " + deviceName + L" --vhd") : (L"--mount " + deviceName);
@@ -1449,8 +1397,6 @@ class MountTests
void TestMountTwoPartitionsWithDetectionImpl(bool isVhd)
{
WSL2_TEST_ONLY();
const auto deviceName = (isVhd) ? VhdDevice : DiskDevice;
const auto mountCommand = (isVhd) ? (L"--mount " + deviceName + L" --vhd") : (L"--mount " + deviceName);
@@ -1485,8 +1431,6 @@ class MountTests
void TestFilesystemDetectionFailImpl(bool isVhd)
{
WSL2_TEST_ONLY();
const auto deviceName = (isVhd) ? VhdDevice : DiskDevice;
const auto mountCommand = (isVhd) ? (L"--mount " + deviceName + L" --vhd") : (L"--mount " + deviceName);

File diff suppressed because it is too large Load Diff

View File

@@ -150,10 +150,8 @@ class PluginTests
}
}
TEST_METHOD(Success)
WSL2_TEST_METHOD(Success)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=1
VM created (settings->CustomConfigurationFlags=0)
@@ -168,10 +166,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(CustomKernelOverriddenByPolicy)
WSL2_TEST_METHOD(CustomKernelOverriddenByPolicy)
{
WSL2_TEST_ONLY();
RegistryKeyChange policy(
HKEY_LOCAL_MACHINE, wsl::windows::policies::c_registryKey, wsl::windows::policies::c_allowCustomKernelUserSetting, static_cast<DWORD>(0));
@@ -191,10 +187,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(DuplicatedPlugin)
WSL2_TEST_METHOD(DuplicatedPlugin)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=1
VM created (settings->CustomConfigurationFlags=0)
@@ -217,10 +211,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(CustomKernel)
WSL2_TEST_METHOD(CustomKernel)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=1
VM created (settings->CustomConfigurationFlags=1)
@@ -250,10 +242,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(CustomKernelCommandLine)
WSL2_TEST_METHOD(CustomKernelCommandLine)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=1
VM created (settings->CustomConfigurationFlags=2)
@@ -270,10 +260,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(DistroIdStaysTheSame)
WSL2_TEST_METHOD(DistroIdStaysTheSame)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=10
VM created (settings->CustomConfigurationFlags=0)
@@ -294,10 +282,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(InitPidIsDifferent)
WSL2_TEST_METHOD(InitPidIsDifferent)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=14
VM created (settings->CustomConfigurationFlags=0)
@@ -316,10 +302,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(PluginUpdateRequired)
WSL2_TEST_METHOD(PluginUpdateRequired)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=9
OnLoad: WSL_E_PLUGINREQUIRESUPDATE)";
@@ -333,10 +317,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(APIErrors)
WSL2_TEST_METHOD(APIErrors)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=7
VM created (settings->CustomConfigurationFlags=0)
@@ -350,10 +332,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(SuccessWSL1)
WSL1_TEST_METHOD(SuccessWSL1)
{
WSL1_TEST_ONLY();
constexpr auto ExpectedOutput = LR"(Plugin loaded. TestMode=1)";
ConfigurePlugin(PluginTestType::Success);
@@ -361,9 +341,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(LoadFailureFatalWSL2)
WSL2_TEST_METHOD(LoadFailureFatalWSL2)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=2
OnLoad: E_UNEXPECTED)";
@@ -376,10 +355,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(LoadFailureNonFatalWSL1)
WSL1_TEST_METHOD(LoadFailureNonFatalWSL1)
{
WSL1_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=2
OnLoad: E_UNEXPECTED)";
@@ -389,10 +366,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(VmStartFailure)
WSL2_TEST_METHOD(VmStartFailure)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=3
VM created (settings->CustomConfigurationFlags=0)
@@ -407,10 +382,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(VmStartFailureWithPluginErrorTwice)
WSL2_TEST_METHOD(VmStartFailureWithPluginErrorTwice)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=13
VM created (settings->CustomConfigurationFlags=0)
@@ -435,10 +408,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(VmStopFailure)
WSL2_TEST_METHOD(VmStopFailure)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=5
VM created (settings->CustomConfigurationFlags=0)
@@ -452,10 +423,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(DistributionStartFailure)
WSL2_TEST_METHOD(DistributionStartFailure)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=4
VM created (settings->CustomConfigurationFlags=0)
@@ -472,10 +441,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(DistributionStopFailure)
WSL2_TEST_METHOD(DistributionStopFailure)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=6
VM created (settings->CustomConfigurationFlags=0)
@@ -489,10 +456,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(ErrorMessageStartVm)
WSL2_TEST_METHOD(ErrorMessageStartVm)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=11
VM created (settings->CustomConfigurationFlags=0)
@@ -508,10 +473,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(ErrorMessageStartDistro)
WSL2_TEST_METHOD(ErrorMessageStartDistro)
{
WSL2_TEST_ONLY();
constexpr auto ExpectedOutput =
LR"(Plugin loaded. TestMode=12
VM created (settings->CustomConfigurationFlags=0)
@@ -529,10 +492,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(RegisterSuccess)
WSL2_TEST_METHOD(RegisterSuccess)
{
WSL2_TEST_ONLY();
ConfigurePlugin(PluginTestType::Success);
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"--import plugin-test-distro . \"" + g_testDistroPath + L"\" --version 2"), 0L);
@@ -550,10 +511,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(ImportInplaceSuccess)
WSL2_TEST_METHOD(ImportInplaceSuccess)
{
WSL2_TEST_ONLY();
ConfigurePlugin(PluginTestType::Success);
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"--import plugin-test-distro . \"" + g_testDistroPath + L"\" --version 2"), 0L);
@@ -581,10 +540,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(RegisterUnregisterFail)
WSL2_TEST_METHOD(RegisterUnregisterFail)
{
WSL2_TEST_ONLY();
ConfigurePlugin(PluginTestType::FailToRegisterUnregisterDistro);
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"--import plugin-test-distro . \"" + g_testDistroPath + L"\" --version 2"), 0L);
@@ -602,10 +559,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(ExecuteDistroCommand)
WSL2_TEST_METHOD(ExecuteDistroCommand)
{
WSL2_TEST_ONLY();
ConfigurePlugin(PluginTestType::RunDistroCommand);
constexpr auto ExpectedOutput =
@@ -622,10 +577,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
TEST_METHOD(PluginToken)
WSL2_TEST_METHOD(PluginToken)
{
WSL2_TEST_ONLY();
ConfigurePlugin(PluginTestType::GetUsername);
constexpr auto ExpectedOutput =
@@ -640,10 +593,8 @@ class PluginTests
ValidateLogFile(ExpectedOutput);
}
// This test must run last so it doesn't break test cases that depends on plugin signature.
TEST_METHOD(InvalidPluginSignature)
WSL2_TEST_METHOD(InvalidPluginSignature)
{
WSL2_TEST_ONLY();
if constexpr (!wsl::shared::OfficialBuild)
{
LogSkipped("This test only applies to signed builds");

View File

@@ -73,11 +73,9 @@ class PolicyTest
}
};
TEST_METHOD(MountPolicyAllowed)
WSL2_TEST_METHOD(MountPolicyAllowed)
{
SKIP_TEST_ARM64();
WSL2_TEST_ONLY();
auto revert = SetPolicy(c_allowDiskMount, 1);
ValidateOutput(
L"--mount DoesNotExist",
@@ -85,11 +83,9 @@ class PolicyTest
L"Error code: Wsl/Service/AttachDisk/MountDisk/HCS/ERROR_FILE_NOT_FOUND\r\n");
}
TEST_METHOD(MountPolicyDisabled)
WSL2_TEST_METHOD(MountPolicyDisabled)
{
SKIP_TEST_ARM64();
WSL2_TEST_ONLY();
auto revert = SetPolicy(c_allowDiskMount, 0);
ValidateOutput(
L"--mount DoesNotExist",
@@ -128,10 +124,8 @@ class PolicyTest
}
}
TEST_METHOD(KernelCommandLine)
WSL2_TEST_METHOD(KernelCommandLine)
{
WSL2_TEST_ONLY();
auto validate = [](DWORD policyValue) {
auto [commandLine, _] = LxsstuLaunchWslAndCaptureOutput(L"cat /proc/cmdline");
@@ -152,10 +146,9 @@ class PolicyTest
validate);
}
TEST_METHOD(NestedVirtualization)
WSL2_TEST_METHOD(NestedVirtualization)
{
SKIP_TEST_ARM64();
WSL2_TEST_ONLY();
WINDOWS_11_TEST_ONLY();
ValidatePolicy(
@@ -164,10 +157,8 @@ class PolicyTest
L"wsl: The .wslconfig setting 'wsl2.nestedVirtualization' is disabled by the computer policy.\r\n");
}
TEST_METHOD(KernelDebugging)
WSL2_TEST_METHOD(KernelDebugging)
{
WSL2_TEST_ONLY();
WINDOWS_11_TEST_ONLY();
ValidatePolicy(
@@ -176,10 +167,8 @@ class PolicyTest
L"wsl: The .wslconfig setting 'wsl2.kernelDebugPort' is disabled by the computer policy.\r\n");
}
TEST_METHOD(CustomKernel)
WSL2_TEST_METHOD(CustomKernel)
{
WSL2_TEST_ONLY();
const std::wstring wslConfigPath = wsl::windows::common::helpers::GetWslConfigPath();
const std::wstring nonExistentFile = L"DoesNotExist";
WslConfigChange config(LxssGenerateTestConfig({.kernel = nonExistentFile.c_str(), .kernelModules = nonExistentFile.c_str()}));
@@ -215,10 +204,8 @@ class PolicyTest
}
}
TEST_METHOD(CustomSystemDistro)
WSL2_TEST_METHOD(CustomSystemDistro)
{
WSL2_TEST_ONLY();
WslConfigChange config(LxssGenerateTestConfig() + L"systemDistro=DoesNotExist");
const std::wstring wslConfigPath = wsl::windows::common::helpers::GetWslConfigPath();
@@ -241,10 +228,8 @@ class PolicyTest
}
}
TEST_METHOD(CustomNetworkingMode)
WSL2_TEST_METHOD(CustomNetworkingMode)
{
WSL2_TEST_ONLY();
WslConfigChange config(LxssGenerateTestConfig({.networkingMode = wsl::core::NetworkingMode::VirtioProxy}));
{
@@ -274,10 +259,8 @@ class PolicyTest
}
}
TEST_METHOD(DebugShell)
WSL2_TEST_METHOD(DebugShell)
{
WSL2_TEST_ONLY();
auto revert = SetPolicy(c_allowDebugShellUserSetting, 0);
WslShutdown();
@@ -388,10 +371,8 @@ class PolicyTest
testPolicy(wsl::windows::policies::c_allowWSL, HRESULT_FROM_WIN32(ERROR_ACCESS_DISABLED_BY_POLICY), false);
}
TEST_METHOD(DefaultNetworkingMode)
WSL2_TEST_METHOD(DefaultNetworkingMode)
{
WSL2_TEST_ONLY();
WslConfigChange config(LxssGenerateTestConfig());
{

View File

@@ -73,10 +73,8 @@ class SimpleTests
VERIFY_IS_TRUE(WI_IsFlagSet(attributes, FILE_ATTRIBUTE_SPARSE_FILE) == sparse);
}
TEST_METHOD(CheckSparse)
WSL2_TEST_METHOD(CheckSparse)
{
WSL2_TEST_ONLY();
WslConfigChange config(LxssGenerateTestConfig({.sparse = true}));
std::filesystem::path tar = std::tmpnam(nullptr);

View File

@@ -170,10 +170,8 @@ class UnitTests
}
}
TEST_METHOD(SystemdSafeMode)
WSL2_TEST_METHOD(SystemdSafeMode)
{
WSL2_TEST_ONLY();
SKIP_TEST_UNSTABLE(); // TODO: Re-enable when this issue is solved in main.
auto revert = EnableSystemd();
@@ -190,19 +188,15 @@ class UnitTests
VERIFY_IS_TRUE(IsSystemdRunning(L"--system"));
}
TEST_METHOD(SystemdDisabled)
WSL2_TEST_METHOD(SystemdDisabled)
{
WSL2_TEST_ONLY();
// tests that systemd does not run without the wsl.conf option enabled
// run and check the output of systemctl --system
VERIFY_IS_FALSE(IsSystemdRunning(L"--system", 1));
}
TEST_METHOD(SystemdSystem)
WSL2_TEST_METHOD(SystemdSystem)
{
WSL2_TEST_ONLY();
auto cleanup = wil::scope_exit([] {
// clean up wsl.conf file
const std::wstring disableSystemdCmd(LXSST_REMOVE_DISTRO_CONF_COMMAND_LINE);
@@ -226,10 +220,8 @@ class UnitTests
VERIFY_ARE_EQUAL(outNm, L" Loaded: masked (Reason: Unit NetworkManager-wait-online.service is masked.)\n");
}
TEST_METHOD(SystemdUser)
WSL2_TEST_METHOD(SystemdUser)
{
WSL2_TEST_ONLY();
// enable systemd before creating the user.
// if not called first, the runtime directories needed for --user will not have been created
auto cleanup = EnableSystemd();
@@ -335,10 +327,8 @@ class UnitTests
return false;
}
TEST_METHOD(SystemdNoClearTmpUnit)
WSL2_TEST_METHOD(SystemdNoClearTmpUnit)
{
WSL2_TEST_ONLY();
// ensures that we don't leave state on exit
auto cleanup = EnableSystemd("initTimeout=0");
@@ -350,10 +340,8 @@ class UnitTests
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"test -d /tmp/.X11-unix"), 0L);
}
TEST_METHOD(SystemdBinfmtIsRestored)
WSL2_TEST_METHOD(SystemdBinfmtIsRestored)
{
WSL2_TEST_ONLY();
// Override WSL's binfmt interpreter
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"mkdir -p /usr/lib/binfmt.d && echo ':WSLInterop:M::MZ::/bin/echo:PF' > /usr/lib/binfmt.d/dummy.conf"), 0L);
@@ -405,10 +393,8 @@ class UnitTests
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests dup", L"Dup"));
}
TEST_METHOD(Epoll)
WSL1_TEST_METHOD(Epoll)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests epoll", L"Epoll"));
}
@@ -424,17 +410,13 @@ class UnitTests
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests flock", L"Flock"));
}
TEST_METHOD(Fork)
WSL1_TEST_METHOD(Fork)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests fork", L"Fork"));
}
TEST_METHOD(FsCommonLxFs)
WSL1_TEST_METHOD(FsCommonLxFs)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests fscommon", L"fscommon_lxfs"));
}
@@ -443,10 +425,8 @@ class UnitTests
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests get_set_id", L"get_set_id"));
}
TEST_METHOD(Inotify)
WSL1_TEST_METHOD(Inotify)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests inotify", L"INOTIFY"));
}
@@ -474,45 +454,33 @@ class UnitTests
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests mprotect", L"mprotect"));
}
TEST_METHOD(Pipe)
WSL1_TEST_METHOD(Pipe)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests pipe", L"Pipe"));
}
TEST_METHOD(Sched)
WSL1_TEST_METHOD(Sched)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests sched", L"sched"));
}
TEST_METHOD(SocketNonblocking)
WSL1_TEST_METHOD(SocketNonblocking)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests socket_nonblock", L"socket_nonblocking"));
}
TEST_METHOD(Splice)
WSL1_TEST_METHOD(Splice)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests splice", L"Splice"));
}
TEST_METHOD(Sysfs)
WSL1_TEST_METHOD(Sysfs)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests sysfs", L"SysFs"));
}
TEST_METHOD(Tty)
WSL1_TEST_METHOD(Tty)
{
WSL1_TEST_ONLY();
auto OriginalHandles = UseOriginalStdHandles();
auto Restore = wil::scope_exit([&OriginalHandles]() { RestoreTestStdHandles(OriginalHandles); });
@@ -520,10 +488,8 @@ class UnitTests
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests tty", L"tty"));
}
TEST_METHOD(Utimensat)
WSL1_TEST_METHOD(Utimensat)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests utimensat", L"Utimensat"));
}
@@ -547,10 +513,8 @@ class UnitTests
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests vfsaccess", L"vfsaccess"));
}
TEST_METHOD(DevPt)
WSL1_TEST_METHOD(DevPt)
{
WSL1_TEST_ONLY();
auto OriginalHandles = UseOriginalStdHandles();
auto Restore = wil::scope_exit([&OriginalHandles]() { RestoreTestStdHandles(OriginalHandles); });
@@ -560,17 +524,13 @@ class UnitTests
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests dev_pt_2", L"dev_pt_2"));
}
TEST_METHOD(Timer)
WSL1_TEST_METHOD(Timer)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests timer", L"timer"));
}
TEST_METHOD(SysInfo)
WSL1_TEST_METHOD(SysInfo)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests sysinfo", L"Sysinfo"));
}
@@ -579,10 +539,8 @@ class UnitTests
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests timerfd", L"timerfd"));
}
TEST_METHOD(Ioprio)
WSL1_TEST_METHOD(Ioprio)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests ioprio", L"Ioprio"));
}
@@ -700,10 +658,8 @@ class UnitTests
LxsstuLaunchWsl(L"stat -c %U /data/test/default_user_test | grep -iF kerneltest", nullptr, nullptr, nullptr, nullptr), 0u);
}
TEST_METHOD(Execve)
WSL1_TEST_METHOD(Execve)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests execve", L"Execve"));
}
@@ -712,10 +668,8 @@ class UnitTests
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests xattr", L"xattr"));
}
TEST_METHOD(Namespace)
WSL1_TEST_METHOD(Namespace)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests namespace", L"Namespace"));
}
@@ -749,17 +703,13 @@ class UnitTests
}
}
TEST_METHOD(Netlink)
WSL1_TEST_METHOD(Netlink)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests netlink", L"Netlink"));
}
TEST_METHOD(Random)
WSL1_TEST_METHOD(Random)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests random", L"random"));
}
@@ -768,31 +718,23 @@ class UnitTests
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests keymgmt", L"Keymgmt"));
}
TEST_METHOD(Shm)
WSL1_TEST_METHOD(Shm)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests shm", L"shm"));
}
TEST_METHOD(Sem)
WSL1_TEST_METHOD(Sem)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests sem", L"sem"));
}
TEST_METHOD(Ttys)
WSL1_TEST_METHOD(Ttys)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests ttys", L"Ttys"));
}
TEST_METHOD(OverlayFs)
WSL1_TEST_METHOD(OverlayFs)
{
WSL1_TEST_ONLY();
VERIFY_NO_THROW(LxsstuRunTest(L"/data/test/wsl_unit_tests overlayfs", L"OverlayFs"));
}
@@ -1748,10 +1690,8 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
VerifyOutput(L"--install foo", AddCrlf(WslInstallHelpMessage), -1);
}
TEST_METHOD(TestExistingSwapVhd)
WSL2_TEST_METHOD(TestExistingSwapVhd)
{
WSL2_TEST_ONLY();
// Create a 100MB swap vhdx.
auto swapVhd = wil::GetCurrentDirectoryW<std::wstring>() + L"\\TestSwap.vhdx";
@@ -1805,17 +1745,13 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
VERIFY_ARE_EQUAL(L"SigBlk:\t0000000000000000\n", output);
}
TEST_METHOD(InitReadonly)
WSL2_TEST_METHOD(InitReadonly)
{
WSL2_TEST_ONLY();
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L" grep '^rootfs /init rootfs ro,' /proc/self/mounts", nullptr, nullptr, nullptr, nullptr), 0u);
}
TEST_METHOD(GpuMounts)
WSL2_TEST_METHOD(GpuMounts)
{
WSL2_TEST_ONLY();
auto ValidateGpuMounts = [](HANDLE Token) {
VERIFY_ARE_EQUAL(
LxsstuLaunchWsl(
@@ -1928,10 +1864,8 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
validate(longHostName, wsl::shared::string::MultiByteToWide(longHostName.substr(0, 64)));
}
TEST_METHOD(WslConfWarnings)
WSL2_TEST_METHOD(WslConfWarnings)
{
WSL2_TEST_ONLY();
DistroFileChange configChange(L"/etc/wsl.conf", false);
auto validateWarnings = [&configChange](const std::wstring& config, const std::wstring& expectedWarnings) {
@@ -1981,10 +1915,8 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
}
}
TEST_METHOD(Warnings)
WSL2_TEST_METHOD(Warnings)
{
WSL2_TEST_ONLY();
WslConfigChange configChange(LxssGenerateTestConfig());
auto validateWarnings = [&configChange](
@@ -2172,10 +2104,8 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
VERIFY_ARE_EQUAL(L"", warnings);
}
TEST_METHOD(Processors)
WSL2_TEST_METHOD(Processors)
{
WSL2_TEST_ONLY();
WslConfigChange configChange(LxssGenerateTestConfig() + L"\nprocessors=1");
auto [output, warnings] = LxsstuLaunchWslAndCaptureOutput(L"nproc --all");
@@ -2183,10 +2113,8 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
VERIFY_ARE_EQUAL(L"", warnings);
}
TEST_METHOD(GuiApplications)
WSL2_TEST_METHOD(GuiApplications)
{
WSL2_TEST_ONLY();
auto validateEnvironment = [&](bool systemdEnabled) {
WslConfigChange configChange(LxssGenerateTestConfig({.guiApplications = true}));
@@ -2252,10 +2180,8 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
validateEnvironment(true);
}
TEST_METHOD(GuiApplicationsSystemd)
WSL2_TEST_METHOD(GuiApplicationsSystemd)
{
WSL2_TEST_ONLY();
DistroFileChange wslConf(L"/etc/wsl.conf", false);
wslConf.SetContent(L"[boot]\nsystemd=true\n");
WslConfigChange config{LxssGenerateTestConfig({.guiApplications = true})};
@@ -2360,10 +2286,8 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
VERIFY_ARE_NOT_EQUAL(signedFiles, 0);
}
TEST_METHOD(CorruptedVhd)
WSL2_TEST_METHOD(CorruptedVhd)
{
WSL2_TEST_ONLY();
// Create a 100MB vhd without a filesystem.
auto distroPath = std::filesystem::weakly_canonical(wil::GetCurrentDirectoryW<std::wstring>());
auto vhdPath = distroPath / L"CorruptedTest.vhdx";
@@ -2608,10 +2532,8 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
cleanup.release();
}
TEST_METHOD(ManualDistroShutdown)
WSL2_TEST_METHOD(ManualDistroShutdown)
{
WSL2_TEST_ONLY();
// Terminate a distribution from within WSL. This command should be terminated by the VM terminating
LxsstuLaunchWsl(L"echo foo > /dev/shm/bar ; reboot -f ; sleep 1d");
@@ -2631,10 +2553,8 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
VERIFY_ARE_EQUAL(out, L"ok");
}
TEST_METHOD(KernelModules)
WSL2_TEST_METHOD(KernelModules)
{
WSL2_TEST_ONLY();
// Get the kernel version and strip off everything after the first dash.
std::wstring kernelVersion{TEXT(KERNEL_VERSION)};
auto position = kernelVersion.find_first_of(L"-");
@@ -2727,10 +2647,8 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
ValidateOutput(L"dmesg | grep -iF \"failed to load module 'not-found'\" | wc -l", L"1\n", L"", 0);
}
TEST_METHOD(CrashCollection)
WSL2_TEST_METHOD(CrashCollection)
{
WSL2_TEST_ONLY();
const auto folder = std::filesystem::absolute(L"test-crash-dumps");
auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() {
@@ -2878,10 +2796,8 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
}
}
TEST_METHOD(Resize)
WSL2_TEST_METHOD(Resize)
{
WSL2_TEST_ONLY();
constexpr auto name = L"resize-test-distro";
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(std::format(L"--import {} . \"{}\" --version 2", name, g_testDistroPath)), 0L);
@@ -2917,10 +2833,8 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
}
}
TEST_METHOD(FileOffsets)
WSL2_TEST_METHOD(FileOffsets)
{
WSL2_TEST_ONLY();
auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, []() { DeleteFile(L"output.txt"); });
std::ofstream file("output.txt");
@@ -2950,9 +2864,8 @@ Error code: Wsl/InstallDistro/WSL_E_DISTRO_NOT_FOUND
VERIFY_IS_TRUE(isDriveMountingEnabled());
}
TEST_METHOD(WriteWslConfig)
WSL2_TEST_METHOD(WriteWslConfig)
{
WSL2_TEST_ONLY();
WSL_SETTINGS_TEST();
auto installPath = wsl::windows::common::wslutil::GetMsiPackagePath();
@@ -6241,10 +6154,8 @@ Error code: Wsl/InstallDistro/WSL_E_INVALID_JSON\r\n",
}
}
TEST_METHOD(CustomModulesVhd)
WSL2_TEST_METHOD(CustomModulesVhd)
{
WSL2_TEST_ONLY();
#ifdef WSL_DEV_INSTALL_PATH
auto modulesPath = std::format(L"{}\\modules.vhd", WSL_DEV_INSTALL_PATH);
@@ -6417,19 +6328,15 @@ Error code: Wsl/InstallDistro/WSL_E_INVALID_JSON\r\n",
VERIFY_ARE_EQUAL(err, L"");
}
TEST_METHOD(WslDebug)
WSL2_TEST_METHOD(WslDebug)
{
WSL2_TEST_ONLY();
// Verify that hvsocket debug events are logged to dmesg.
WslConfigChange config(LxssGenerateTestConfig({.kernelCommandLine = L"WSL_DEBUG=hvsocket"}));
VERIFY_ARE_EQUAL(LxsstuLaunchWsl(L"dmesg | grep -iF 'vmbus_send_tl_connect_request'"), 0L);
}
TEST_METHOD(CGroupv1)
WSL2_TEST_METHOD(CGroupv1)
{
WSL2_TEST_ONLY();
auto expectedMount = [](const char* path, const wchar_t* expected) {
auto [out, _] = LxsstuLaunchWslAndCaptureOutput(std::format(L"findmnt -ln '{}' || true", path));
@@ -6464,19 +6371,15 @@ Error code: Wsl/InstallDistro/WSL_E_INVALID_JSON\r\n",
std::wstring::npos);
}
TEST_METHOD(InitPermissions)
WSL2_TEST_METHOD(InitPermissions)
{
WSL2_TEST_ONLY();
auto [out, _] = LxsstuLaunchWslAndCaptureOutput(L"stat -c %a /init");
VERIFY_ARE_EQUAL(out, L"755\n");
}
TEST_METHOD(ExportImportVhd)
WSL2_TEST_METHOD(ExportImportVhd)
{
WSL2_TEST_ONLY();
WslShutdown();
constexpr auto vhdPath = L"exported-test-distro.vhd";
@@ -6608,10 +6511,8 @@ Error code: Wsl/InstallDistro/WSL_E_INVALID_JSON\r\n",
VERIFY_IS_TRUE(threw);
}
TEST_METHOD(InteractiveMount)
WSL2_TEST_METHOD(InteractiveMount)
{
WSL2_TEST_ONLY();
// Add a fake interactive mount helper.
DistroFileChange mountHelper(L"/sbin/mount.hang", false);
mountHelper.SetContent(

View File

@@ -167,10 +167,8 @@ class WSLCTests
return RunningWSLCContainer(std::move(rawContainer), {});
}
TEST_METHOD(GetVersion)
WSLC_TEST_METHOD(GetVersion)
{
WSL2_TEST_ONLY();
wil::com_ptr<IWSLCSessionManager> sessionManager;
VERIFY_SUCCEEDED(CoCreateInstance(__uuidof(WSLCSessionManager), nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&sessionManager)));
@@ -269,10 +267,8 @@ class WSLCTests
}
}
TEST_METHOD(ListSessionsReturnsSessionWithDisplayName)
WSLC_TEST_METHOD(ListSessionsReturnsSessionWithDisplayName)
{
WSL2_TEST_ONLY();
auto sessionManager = OpenSessionManager();
// Act: list sessions
@@ -310,10 +306,8 @@ class WSLCTests
}
}
TEST_METHOD(OpenSessionByNameFindsExistingSession)
WSLC_TEST_METHOD(OpenSessionByNameFindsExistingSession)
{
WSL2_TEST_ONLY();
auto sessionManager = OpenSessionManager();
// Act: open by the same display name
@@ -327,10 +321,8 @@ class WSLCTests
VERIFY_ARE_EQUAL(hr, HRESULT_FROM_WIN32(ERROR_NOT_FOUND));
}
TEST_METHOD(CreateSessionValidation)
WSLC_TEST_METHOD(CreateSessionValidation)
{
WSL2_TEST_ONLY();
auto sessionManager = OpenSessionManager();
// Reject NULL DisplayName.
@@ -411,10 +403,8 @@ class WSLCTests
return std::move(deletedImages);
}
TEST_METHOD(PullImage)
WSLC_TEST_METHOD(PullImage)
{
WSL2_TEST_ONLY();
{
HRESULT pullResult = m_defaultSession->PullImage("hello-world:linux", nullptr, nullptr);
@@ -469,10 +459,8 @@ class WSLCTests
}
}
TEST_METHOD(PullImageAdvanced)
WSLC_TEST_METHOD(PullImageAdvanced)
{
WSL2_TEST_ONLY();
// TODO: Enable once custom registries are supported, to avoid hitting public registry rate limits.
SKIP_TEST_UNSTABLE();
@@ -541,10 +529,8 @@ class WSLCTests
}
}
TEST_METHOD(ListImages)
WSLC_TEST_METHOD(ListImages)
{
WSL2_TEST_ONLY();
// Setup: Ensure debian:latest is available
ExpectImagePresent(*m_defaultSession, "debian:latest");
@@ -858,10 +844,8 @@ class WSLCTests
ExpectImagePresent(*m_defaultSession, "debian:latest", true);
}
TEST_METHOD(LoadImage)
WSLC_TEST_METHOD(LoadImage)
{
WSL2_TEST_ONLY();
std::filesystem::path imageTar = GetTestImagePath("hello-world:latest");
wil::unique_handle imageTarFileHandle{
CreateFileW(imageTar.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr)};
@@ -893,10 +877,8 @@ class WSLCTests
}
}
TEST_METHOD(ImportImage)
WSLC_TEST_METHOD(ImportImage)
{
WSL2_TEST_ONLY();
auto cleanup =
wil::scope_exit([&]() { LOG_IF_FAILED(DeleteImageNoThrow("my-hello-world:test", WSLCDeleteImageFlagsNone).first); });
@@ -944,10 +926,8 @@ class WSLCTests
}
}
TEST_METHOD(DeleteImage)
WSLC_TEST_METHOD(DeleteImage)
{
WSL2_TEST_ONLY();
// Prepare alpine image to delete.
LoadTestImage("alpine:latest");
@@ -1038,10 +1018,8 @@ class WSLCTests
return BuildImageFromContext(contextDir, &options);
}
TEST_METHOD(BuildImage)
WSLC_TEST_METHOD(BuildImage)
{
WSL2_TEST_ONLY();
auto contextDir = std::filesystem::current_path() / "build-context";
std::filesystem::create_directories(contextDir);
auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() {
@@ -1069,10 +1047,8 @@ class WSLCTests
}
// This test validates both that we can build an image with an empty CMD, and that we can run such an image.
TEST_METHOD(BuildImageEntrypoint)
WSLC_TEST_METHOD(BuildImageEntrypoint)
{
WSL2_TEST_ONLY();
auto contextDir = std::filesystem::current_path() / "build-context-entrypoint";
std::filesystem::create_directories(contextDir);
auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() {
@@ -1127,10 +1103,8 @@ class WSLCTests
}
}
TEST_METHOD(BuildImageWithContext)
WSLC_TEST_METHOD(BuildImageWithContext)
{
WSL2_TEST_ONLY();
auto contextDir = std::filesystem::current_path() / "build-context-file";
std::filesystem::create_directories(contextDir);
auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() {
@@ -1163,10 +1137,8 @@ class WSLCTests
VERIFY_IS_TRUE(result.Output[1].find("Hello from a WSL container context file!") != std::string::npos);
}
TEST_METHOD(BuildImageManyFiles)
WSLC_TEST_METHOD(BuildImageManyFiles)
{
WSL2_TEST_ONLY();
static constexpr int fileCount = 1024;
auto contextDir = std::filesystem::current_path() / "build-context-many";
@@ -1216,10 +1188,8 @@ class WSLCTests
VERIFY_IS_TRUE(result.Output[1].find(sentinel) != std::string::npos);
}
TEST_METHOD(BuildImageLargeFile)
WSLC_TEST_METHOD(BuildImageLargeFile)
{
WSL2_TEST_ONLY();
RunCommand(m_defaultSession.get(), {"/usr/bin/docker", "rmi", "-f", "wslc-test-build-large:latest"});
ExpectCommandResult(m_defaultSession.get(), {"/usr/bin/docker", "builder", "prune", "-f"}, 0);
@@ -1272,10 +1242,8 @@ class WSLCTests
VERIFY_IS_TRUE(result.Output[1].find("size_ok") != std::string::npos);
}
TEST_METHOD(BuildImageMultiStage)
WSLC_TEST_METHOD(BuildImageMultiStage)
{
WSL2_TEST_ONLY();
auto contextDir = std::filesystem::current_path() / "build-context-multistage";
std::filesystem::create_directories(contextDir);
auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() {
@@ -1313,10 +1281,8 @@ class WSLCTests
VERIFY_IS_TRUE(result.Output[1].find("WSL containers support multi-stage builds") != std::string::npos);
}
TEST_METHOD(BuildImageDockerIgnore)
WSLC_TEST_METHOD(BuildImageDockerIgnore)
{
WSL2_TEST_ONLY();
auto contextDir = std::filesystem::current_path() / "build-context-dockerignore";
std::filesystem::create_directories(contextDir / "temp");
auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() {
@@ -1361,10 +1327,8 @@ class WSLCTests
VERIFY_IS_TRUE(result.Output[1].find("dockerignore_ok") != std::string::npos);
}
TEST_METHOD(BuildImageFailure)
WSLC_TEST_METHOD(BuildImageFailure)
{
WSL2_TEST_ONLY();
auto contextDir = std::filesystem::current_path() / "build-context-failure";
std::filesystem::create_directories(contextDir);
auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() {
@@ -1385,10 +1349,8 @@ class WSLCTests
ExpectImagePresent(*m_defaultSession, "wslc-test-build-failure:latest", false);
}
TEST_METHOD(BuildImageFailureShowsBuildOutput)
WSLC_TEST_METHOD(BuildImageFailureShowsBuildOutput)
{
WSL2_TEST_ONLY();
auto contextDir = std::filesystem::current_path() / "build-context-failure-output";
std::filesystem::create_directories(contextDir);
auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() {
@@ -1440,10 +1402,8 @@ class WSLCTests
VERIFY_IS_TRUE(progressOutput.find("build-log-marker") != std::string::npos);
}
TEST_METHOD(BuildImageStdinDockerfile)
WSLC_TEST_METHOD(BuildImageStdinDockerfile)
{
WSL2_TEST_ONLY();
auto contextDir = std::filesystem::current_path() / "build-context-stdin";
std::filesystem::create_directories(contextDir);
auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() {
@@ -1482,10 +1442,8 @@ class WSLCTests
VERIFY_IS_TRUE(result.Output[1].find("stdin-dockerfile-ok") != std::string::npos);
}
TEST_METHOD(BuildImageBuildArgs)
WSLC_TEST_METHOD(BuildImageBuildArgs)
{
WSL2_TEST_ONLY();
auto contextDir = std::filesystem::current_path() / "build-context-buildargs";
std::filesystem::create_directories(contextDir);
auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() {
@@ -1515,10 +1473,8 @@ class WSLCTests
ValidateProcessOutput(initProcess, {{1, "build-arg-value=hello-from-build-arg\n"}});
}
TEST_METHOD(BuildImageMultipleTags)
WSLC_TEST_METHOD(BuildImageMultipleTags)
{
WSL2_TEST_ONLY();
auto contextDir = std::filesystem::current_path() / "build-context-multitag";
std::filesystem::create_directories(contextDir);
LPCSTR tags[] = {"wslc-test-multitag:v1", "wslc-test-multitag:v2"};
@@ -1543,19 +1499,15 @@ class WSLCTests
ExpectImagePresent(*m_defaultSession, "wslc-test-multitag:v2");
}
TEST_METHOD(BuildImageNullHandle)
WSLC_TEST_METHOD(BuildImageNullHandle)
{
WSL2_TEST_ONLY();
WSLCBuildImageOptions options{.ContextPath = L"C:\\", .DockerfileHandle = {}, .Tags = {nullptr, 0}};
VERIFY_ARE_EQUAL(m_defaultSession->BuildImage(&options, nullptr, nullptr), HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE));
}
TEST_METHOD(BuildImageCancel)
WSLC_TEST_METHOD(BuildImageCancel)
{
WSL2_TEST_ONLY();
class TestProgressCallback
: public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IProgressCallback>
{
@@ -1618,7 +1570,11 @@ class WSLCTests
{
// TODO: Add more test coverage once anonymous volumes are fully supported and switch to using -v instead of building an image.
WSL2_TEST_ONLY();
if (!LxsstuVmMode())
{
LogSkipped("This test is only applicable to WSL2");
return;
}
auto contextDir = std::filesystem::current_path() / "build-context";
std::filesystem::create_directories(contextDir);
@@ -1668,10 +1624,8 @@ class WSLCTests
VERIFY_ARE_EQUAL(containers[0].Id, containerId);
}
TEST_METHOD(TagImage)
WSLC_TEST_METHOD(TagImage)
{
WSL2_TEST_ONLY();
auto runTagImage = [&](LPCSTR Image, LPCSTR Repo, LPCSTR Tag) {
WSLCTagImageOptions options{};
options.Image = Image;
@@ -1810,10 +1764,8 @@ class WSLCTests
}
}
TEST_METHOD(InspectImage)
WSLC_TEST_METHOD(InspectImage)
{
WSL2_TEST_ONLY();
// Test inspect debian:latest
{
wil::unique_cotaskmem_ansistring output;
@@ -1978,9 +1930,8 @@ class WSLCTests
bool m_allowEarlyCompletion{};
};
TEST_METHOD(SaveImage)
WSLC_TEST_METHOD(SaveImage)
{
WSL2_TEST_ONLY();
{
std::filesystem::path imageTar = GetTestImagePath("hello-world:latest");
wil::unique_handle imageTarFileHandle{
@@ -2068,10 +2019,8 @@ class WSLCTests
}
}
TEST_METHOD(SynchronousIoCancellation)
WSLC_TEST_METHOD(SynchronousIoCancellation)
{
WSL2_TEST_ONLY();
// Create a blocked operation that will cause the service to get stuck on a ReadFile() call.
// Because the pipe handle that we're passing in doesn't support overlapped IO, the service will get stuck in a
// synchronous ReadFile() call. Validate that terminating the session correctly cancels the IO.
@@ -2112,10 +2061,8 @@ class WSLCTests
}
}
TEST_METHOD(ExportContainer)
WSLC_TEST_METHOD(ExportContainer)
{
WSL2_TEST_ONLY();
// Load an image and launch a container to verify image is valid.
// Then export the container to a tar file.
// Load the exported tar file to verify it's a valid image and can be launched.
@@ -2199,9 +2146,8 @@ class WSLCTests
}
}
TEST_METHOD(CustomDmesgOutput)
WSLC_TEST_METHOD(CustomDmesgOutput)
{
WSL2_TEST_ONLY();
SKIP_TEST_ARM64();
auto createVmWithDmesg = [this](bool earlyBootLogging) {
@@ -2282,10 +2228,8 @@ class WSLCTests
}
}
TEST_METHOD(TerminationCallback)
WSLC_TEST_METHOD(TerminationCallback)
{
WSL2_TEST_ONLY();
class DECLSPEC_UUID("7BC4E198-6531-4FA6-ADE2-5EF3D2A04DFF") CallbackInstance
: public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, ITerminationCallback, IFastRundown>
{
@@ -2326,10 +2270,8 @@ class WSLCTests
VERIFY_ARE_NOT_EQUAL(details, L"");
}
TEST_METHOD(InteractiveShell)
WSLC_TEST_METHOD(InteractiveShell)
{
WSL2_TEST_ONLY();
WSLCProcessLauncher launcher("/bin/sh", {"/bin/sh"}, {"TERM=xterm-256color"}, WSLCProcessFlagsTty | WSLCProcessFlagsStdin);
auto process = launcher.Launch(*m_defaultSession);
@@ -2369,8 +2311,6 @@ class WSLCTests
void ValidateNetworking(WSLCNetworkingMode mode, bool enableDnsTunneling = false)
{
WSL2_TEST_ONLY();
// Reuse the default session if settings match (same networking mode and DNS tunneling setting).
auto createNewSession = mode != m_defaultSessionSettings.NetworkingMode ||
enableDnsTunneling != WI_IsFlagSet(m_defaultSessionSettings.FeatureFlags, WslcFeatureFlagsDnsTunneling);
@@ -2469,8 +2409,6 @@ class WSLCTests
void ValidatePortMapping(WSLCNetworkingMode networkingMode)
{
WSL2_TEST_ONLY();
auto settings = GetDefaultSessionSettings(L"port-mapping-test");
settings.NetworkingMode = networkingMode;
@@ -2605,10 +2543,8 @@ class WSLCTests
ValidatePortMapping(WSLCNetworkingModeVirtioProxy);
}
TEST_METHOD(StuckVmTermination)
WSLC_TEST_METHOD(StuckVmTermination)
{
WSL2_TEST_ONLY();
// Create a 'stuck' process
auto process = WSLCProcessLauncher{"/bin/cat", {"/bin/cat"}, {}, WSLCProcessFlagsStdin}.Launch(*m_defaultSession);
@@ -2726,23 +2662,19 @@ class WSLCTests
}
}
TEST_METHOD(WindowsMounts)
WSLC_TEST_METHOD(WindowsMounts)
{
WSL2_TEST_ONLY();
ValidateWindowsMounts(false);
}
TEST_METHOD(WindowsMountsVirtioFs)
WSLC_TEST_METHOD(WindowsMountsVirtioFs)
{
WSL2_TEST_ONLY();
ValidateWindowsMounts(true);
}
// This test case validates that no file descriptors are leaked to user processes.
TEST_METHOD(Fd)
WSLC_TEST_METHOD(Fd)
{
WSL2_TEST_ONLY();
auto result = ExpectCommandResult(
m_defaultSession.get(), {"/bin/sh", "-c", "echo /proc/self/fd/* && (readlink -v /proc/self/fd/* || true)"}, 0);
@@ -2754,10 +2686,8 @@ class WSLCTests
}
}
TEST_METHOD(GPU)
WSLC_TEST_METHOD(GPU)
{
WSL2_TEST_ONLY();
// Validate that trying to mount the shares without GPU support enabled fails.
{
auto settings = GetDefaultSessionSettings(L"gpu-test-disabled");
@@ -2798,10 +2728,8 @@ class WSLCTests
}
}
TEST_METHOD(Modules)
WSLC_TEST_METHOD(Modules)
{
WSL2_TEST_ONLY();
// Sanity check.
ExpectCommandResult(m_defaultSession.get(), {"/bin/sh", "-c", "lsmod | grep ^xsk_diag"}, 1);
@@ -2812,10 +2740,8 @@ class WSLCTests
ExpectCommandResult(m_defaultSession.get(), {"/bin/sh", "-c", "lsmod | grep ^xsk_diag"}, 0);
}
TEST_METHOD(CreateRootNamespaceProcess)
WSLC_TEST_METHOD(CreateRootNamespaceProcess)
{
WSL2_TEST_ONLY();
// Simple case
{
auto result = ExpectCommandResult(m_defaultSession.get(), {"/bin/sh", "-c", "echo OK"}, 0);
@@ -2935,10 +2861,8 @@ class WSLCTests
}
}
TEST_METHOD(CrashDumpCollection)
WSLC_TEST_METHOD(CrashDumpCollection)
{
WSL2_TEST_ONLY();
int processId = 0;
// Cache the existing crash dumps so we can check that a new one is created.
@@ -3003,10 +2927,8 @@ class WSLCTests
VERIFY_IS_TRUE(std::filesystem::file_size(dumpFile) > 0);
}
TEST_METHOD(VhdFormatting)
WSLC_TEST_METHOD(VhdFormatting)
{
WSL2_TEST_ONLY();
constexpr auto formatedVhd = L"test-format-vhd.vhdx";
// TODO: Replace this by a proper SDK method once it exists
@@ -3024,10 +2946,8 @@ class WSLCTests
VERIFY_ARE_EQUAL(m_defaultSession->FormatVirtualDisk(L"C:\\DoesNotExist.vhdx"), HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
}
TEST_METHOD(NamedVolumesTest)
WSLC_TEST_METHOD(NamedVolumesTest)
{
WSL2_TEST_ONLY();
const std::string volumeName = "wslc-test-named-volume";
const std::filesystem::path volumeVhdPath = m_storagePath / "volumes" / (volumeName + ".vhdx");
@@ -3106,10 +3026,8 @@ class WSLCTests
cleanup.release();
}
TEST_METHOD(NamedVolumesSessionRecovery)
WSLC_TEST_METHOD(NamedVolumesSessionRecovery)
{
WSL2_TEST_ONLY();
const std::string volumeName = "wslc-test-named-volume";
const std::string containerName = "wslc-test-container";
const std::filesystem::path volumeVhdPath = m_storagePath / "volumes" / (volumeName + ".vhdx");
@@ -3185,10 +3103,8 @@ class WSLCTests
VERIFY_ARE_EQUAL(m_defaultSession->DeleteVolume(volumeName.c_str()), WSLC_E_VOLUME_NOT_FOUND);
}
TEST_METHOD(NamedVolumeOptionsParseTest)
WSLC_TEST_METHOD(NamedVolumeOptionsParseTest)
{
WSL2_TEST_ONLY();
const std::string volumeName = "wslc-volume-name";
auto validateInvalidOptionsFailure =
@@ -3232,10 +3148,8 @@ class WSLCTests
validateInvalidOptionsFailure("", WSL_E_INVALID_JSON);
}
TEST_METHOD(ListAndInspectNamedVolumesTest)
WSLC_TEST_METHOD(ListAndInspectNamedVolumesTest)
{
WSL2_TEST_ONLY();
const std::string volumeName1 = "wsla-test-vol1";
const std::string volumeName2 = "wsla-test-vol2";
@@ -3301,10 +3215,8 @@ class WSLCTests
VERIFY_ARE_EQUAL(std::string(volumes[0].Name), volumeName2);
}
TEST_METHOD(CreateContainer)
WSLC_TEST_METHOD(CreateContainer)
{
WSL2_TEST_ONLY();
// Test a simple container start.
{
WSLCContainerLauncher launcher("debian:latest", "test-simple", {"echo", "OK"});
@@ -3662,10 +3574,8 @@ class WSLCTests
}
}
TEST_METHOD(ContainerStartAfterStop)
WSLC_TEST_METHOD(ContainerStartAfterStop)
{
WSL2_TEST_ONLY();
{
WSLCContainerLauncher launcher("debian:latest", "test-stop-start", {"echo", "OK"});
auto container = launcher.Launch(*m_defaultSession);
@@ -3742,10 +3652,8 @@ class WSLCTests
}
}
TEST_METHOD(OpenContainer)
WSLC_TEST_METHOD(OpenContainer)
{
WSL2_TEST_ONLY();
auto expectOpen = [&](const char* Id, HRESULT expectedResult = S_OK) {
wil::com_ptr<IWSLCContainer> container;
auto result = m_defaultSession->OpenContainer(Id, &container);
@@ -3833,10 +3741,8 @@ class WSLCTests
}
}
TEST_METHOD(ContainerState)
WSLC_TEST_METHOD(ContainerState)
{
WSL2_TEST_ONLY();
auto expectContainerList = [&](const std::vector<std::tuple<std::string, std::string, WSLCContainerState>>& expectedContainers) {
wil::unique_cotaskmem_array_ptr<WSLCContainerEntry> containers;
wil::unique_cotaskmem_array_ptr<WSLCContainerPortMapping> ports;
@@ -4112,9 +4018,8 @@ class WSLCTests
}
}
TEST_METHOD(DeleteContainer)
WSLC_TEST_METHOD(DeleteContainer)
{
WSL2_TEST_ONLY();
WSLCContainerLauncher launcher("debian:latest", "test-container-delete", {"sleep", "99999"});
{
@@ -4143,10 +4048,8 @@ class WSLCTests
}
}
TEST_METHOD(ContainerNetwork)
WSLC_TEST_METHOD(ContainerNetwork)
{
WSL2_TEST_ONLY();
auto expectContainerList = [&](const std::vector<std::tuple<std::string, std::string, WSLCContainerState>>& expectedContainers) {
wil::unique_cotaskmem_array_ptr<WSLCContainerEntry> containers;
wil::unique_cotaskmem_array_ptr<WSLCContainerPortMapping> ports;
@@ -4250,10 +4153,8 @@ class WSLCTests
}
}
TEST_METHOD(ContainerInspect)
WSLC_TEST_METHOD(ContainerInspect)
{
WSL2_TEST_ONLY();
// Helper to verify port mappings.
auto expectPorts = [&](const auto& actualPorts, const std::map<std::string, std::set<std::string>>& expectedPorts) {
VERIFY_ARE_EQUAL(actualPorts.size(), expectedPorts.size());
@@ -4393,10 +4294,8 @@ class WSLCTests
}
}
TEST_METHOD(Exec)
WSLC_TEST_METHOD(Exec)
{
WSL2_TEST_ONLY();
// Create a container.
WSLCContainerLauncher launcher(
"debian:latest", "test-container-exec", {"sleep", "99999"}, {}, WSLCContainerNetworkType::WSLCContainerNetworkTypeNone);
@@ -4539,10 +4438,8 @@ class WSLCTests
}
}
TEST_METHOD(ExecContainerDelete)
WSLC_TEST_METHOD(ExecContainerDelete)
{
WSL2_TEST_ONLY();
WSLCContainerLauncher launcher("debian:latest", "test-exec-dtor", {"sleep", "99999"}, {}, WSLCContainerNetworkType::WSLCContainerNetworkTypeNone);
auto container = launcher.Launch(*m_defaultSession);
@@ -4823,20 +4720,16 @@ class WSLCTests
return std::make_pair(std::move(restore), std::move(session));
}
TEST_METHOD(PortMappingsNat)
WSLC_TEST_METHOD(PortMappingsNat)
{
WSL2_TEST_ONLY();
auto [restore, session] = SetupPortMappingsTest(WSLCNetworkingModeNAT);
RunPortMappingsTest(*session, WSLCContainerNetworkTypeBridged);
RunPortMappingsTest(*session, WSLCContainerNetworkTypeHost);
}
TEST_METHOD(PortMappingsVirtioProxy)
WSLC_TEST_METHOD(PortMappingsVirtioProxy)
{
WSL2_TEST_ONLY();
auto [restore, session] = SetupPortMappingsTest(WSLCNetworkingModeVirtioProxy);
RunPortMappingsTest(*session, WSLCContainerNetworkTypeBridged);
@@ -4856,8 +4749,6 @@ class WSLCTests
void ValidateContainerVolumes(bool enableVirtioFs)
{
WSL2_TEST_ONLY();
auto restore = ResetTestSession();
auto hostFolder = std::filesystem::current_path() / "test-volume";
auto hostFolderReadOnly = std::filesystem::current_path() / "test-volume-ro";
@@ -4931,8 +4822,6 @@ class WSLCTests
void ValidateContainerVolumeUnmountAllFoldersOnError(bool enableVirtioFs)
{
WSL2_TEST_ONLY();
auto hostFolder = std::filesystem::current_path() / "test-volume";
auto storage = std::filesystem::current_path() / "storage";
@@ -5176,10 +5065,8 @@ class WSLCTests
runTest({"3\r\nfoo\r\n3\r\nbar\r\n0", "\r\n\r\n"}, {"foo", "bar"});
}
TEST_METHOD(WriteHandleContent)
WSLC_TEST_METHOD(WriteHandleContent)
{
WSL2_TEST_ONLY();
// Validate that writing to a pipe works as expected.
{
const std::string expectedData = "Pipe-test";
@@ -5319,10 +5206,8 @@ class WSLCTests
}
}
TEST_METHOD(ContainerRecoveryFromStorage)
WSLC_TEST_METHOD(ContainerRecoveryFromStorage)
{
WSL2_TEST_ONLY();
auto restore = ResetTestSession(); // Required to access the storage folder.
std::string containerName = "test-container";
@@ -5393,10 +5278,8 @@ class WSLCTests
}
}
TEST_METHOD(ContainerVolumeAndPortRecoveryFromStorage)
WSLC_TEST_METHOD(ContainerVolumeAndPortRecoveryFromStorage)
{
WSL2_TEST_ONLY();
auto restore = ResetTestSession();
std::string containerName = "test-recovery-volumes-ports";
@@ -5485,10 +5368,8 @@ class WSLCTests
}
}
TEST_METHOD(SessionManagement)
WSLC_TEST_METHOD(SessionManagement)
{
WSL2_TEST_ONLY();
auto manager = OpenSessionManager();
auto expectSessions = [&](const std::vector<std::wstring>& expectedSessions) {
@@ -5606,10 +5487,8 @@ class WSLCTests
VERIFY_ARE_EQUAL(EscapeString(expectedOutput), EscapeString(ReadToString(handle)));
}
TEST_METHOD(ContainerLogs)
WSLC_TEST_METHOD(ContainerLogs)
{
WSL2_TEST_ONLY();
auto expectLogs = [](auto& container,
const std::string& expectedStdout,
const std::optional<std::string>& expectedStderr,
@@ -5749,10 +5628,8 @@ class WSLCTests
}
}
TEST_METHOD(ContainerLabels)
WSLC_TEST_METHOD(ContainerLabels)
{
WSL2_TEST_ONLY();
// Docker labels do not have a size limit, so test with a very large label value to validate that the API can handle it.
std::map<std::string, std::string> labels = {{"key1", "value1"}, {"key2", std::string(10000, 'a')}};
@@ -5838,10 +5715,8 @@ class WSLCTests
}
}
TEST_METHOD(ContainerAttach)
WSLC_TEST_METHOD(ContainerAttach)
{
WSL2_TEST_ONLY();
// Validate attach behavior in a non-tty process.
{
WSLCContainerLauncher launcher("debian:latest", "attach-test-1", {"/bin/cat"}, {}, {}, WSLCProcessFlagsStdin);
@@ -6006,10 +5881,8 @@ class WSLCTests
}
}
TEST_METHOD(InvalidNames)
WSLC_TEST_METHOD(InvalidNames)
{
WSL2_TEST_ONLY();
auto expectInvalidArg = [&](const std::string& name) {
wil::com_ptr<IWSLCContainer> container;
VERIFY_ARE_EQUAL(m_defaultSession->OpenContainer(name.c_str(), &container), E_INVALIDARG);
@@ -6047,9 +5920,8 @@ class WSLCTests
expectInvalidPull("bad+image");
}
TEST_METHOD(PageReporting)
WSLC_TEST_METHOD(PageReporting)
{
WSL2_TEST_ONLY();
SKIP_TEST_ARM64();
// Determine expected page reporting order based on Windows version.
@@ -6064,10 +5936,8 @@ class WSLCTests
VERIFY_ARE_EQUAL(result.Output[1], std::format("{}\n", expectedOrder));
}
TEST_METHOD(ContainerAutoRemove)
WSLC_TEST_METHOD(ContainerAutoRemove)
{
WSL2_TEST_ONLY();
// Test that a container with the Rm flag is automatically deleted on Stop().
{
WSLCContainerLauncher launcher("debian:latest", "test-auto-remove", {"/bin/cat"}, {}, {}, WSLCProcessFlagsStdin);
@@ -6170,10 +6040,8 @@ class WSLCTests
}
}
TEST_METHOD(ContainerAutoRemoveReadStdout)
WSLC_TEST_METHOD(ContainerAutoRemoveReadStdout)
{
WSL2_TEST_ONLY();
WSLCContainerLauncher launcher("debian:latest", "test-auto-remove-stdout", {"echo", "Hello World"});
launcher.SetContainerFlags(WSLCContainerFlagsRm);
@@ -6205,10 +6073,8 @@ class WSLCTests
VERIFY_ARE_EQUAL(containers.size(), 0);
}
TEST_METHOD(ContainerNameGeneration)
WSLC_TEST_METHOD(ContainerNameGeneration)
{
WSL2_TEST_ONLY();
{
// Create a container with a specific name
auto container = WSLCContainerLauncher("debian:latest", "test-container-name").Create(*m_defaultSession.get());
@@ -6226,10 +6092,8 @@ class WSLCTests
}
}
TEST_METHOD(DeferredPortAndVolumeMappingOnStart)
WSLC_TEST_METHOD(DeferredPortAndVolumeMappingOnStart)
{
WSL2_TEST_ONLY();
// Verify port mapping.
// Two containers created with the same host port, only the first Start() succeeds.
{
@@ -6291,10 +6155,8 @@ class WSLCTests
}
// This test case validates that multiple operations can happen in parallel in the same session.
TEST_METHOD(ParallelSessionOperations)
WSLC_TEST_METHOD(ParallelSessionOperations)
{
WSL2_TEST_ONLY();
// Start a blocking export
BlockingOperation operation([&](HANDLE handle) {
return m_defaultSession->SaveImage(ToCOMInputHandle(handle), "debian:latest", nullptr, nullptr);
@@ -6334,10 +6196,8 @@ class WSLCTests
}
}
TEST_METHOD(ParallelContainerOperations)
WSLC_TEST_METHOD(ParallelContainerOperations)
{
WSL2_TEST_ONLY();
WSLCContainerLauncher launcher("debian:latest", "test-parallel-container-operations", {"echo", "OK"});
auto container = launcher.Launch(*m_defaultSession);
@@ -6388,10 +6248,8 @@ class WSLCTests
}
}
TEST_METHOD(SessionTerminationDuringSave)
WSLC_TEST_METHOD(SessionTerminationDuringSave)
{
WSL2_TEST_ONLY();
// Validate that SaveImage is aborted when the session terminates.
// Use overlapped write pipe so the server-side WriteFile doesn't block synchronously.
BlockingOperation operation(
@@ -6403,10 +6261,8 @@ class WSLCTests
auto restore = ResetTestSession();
}
TEST_METHOD(SessionTerminationDuringExport)
WSLC_TEST_METHOD(SessionTerminationDuringExport)
{
WSL2_TEST_ONLY();
// Validate that container Export is aborted when the session terminates.
WSLCContainerLauncher launcher("debian:latest", "test-export-session-terminate", {"echo", "OK"});
auto container = launcher.Launch(*m_defaultSession);
@@ -6430,10 +6286,8 @@ class WSLCTests
auto restore = ResetTestSession();
}
TEST_METHOD(InteractiveDetach)
WSLC_TEST_METHOD(InteractiveDetach)
{
WSL2_TEST_ONLY();
auto validateDetaches = [](HANDLE TtyIn, HANDLE TtyOut, const std::vector<char>& Input) {
VERIFY_WIN32_BOOL_SUCCEEDED(WriteFile(TtyIn, Input.data(), static_cast<DWORD>(Input.size()), nullptr, nullptr));
@@ -6529,10 +6383,8 @@ class WSLCTests
}
}
TEST_METHOD(ContainerPrune)
WSLC_TEST_METHOD(ContainerPrune)
{
WSL2_TEST_ONLY();
auto expectPrune = [this](
const std::vector<std::string>& expectedIds = {},
const std::map<std::string, std::pair<const char*, bool>>& labels = {},
@@ -6725,10 +6577,8 @@ class WSLCTests
"2001:0db8:85a3:0000:0000:8a2e:0370:7334:80/path", "2001:0db8:85a3:0000:0000:8a2e:0370:7334:80", "path");
}
TEST_METHOD(ElevatedTokenCanOpenNonElevatedHandles)
WSLC_TEST_METHOD(ElevatedTokenCanOpenNonElevatedHandles)
{
WSL2_TEST_ONLY();
wil::com_ptr<IWSLCSession> nonElevatedSession;
{

View File

@@ -236,10 +236,8 @@ class WslcSdkTests
// Session tests
// -----------------------------------------------------------------------
TEST_METHOD(CreateSession)
WSLC_TEST_METHOD(CreateSession)
{
WSL2_TEST_ONLY();
std::filesystem::path extraStorage = m_storagePath / "wslc-extra-session-storage";
WslcSessionSettings sessionSettings;
@@ -265,10 +263,8 @@ class WslcSdkTests
VERIFY_ARE_EQUAL(WslcCreateSession(nullptr, &session2, nullptr), E_POINTER);
}
TEST_METHOD(TerminationCallbackViaTerminate)
WSLC_TEST_METHOD(TerminationCallbackViaTerminate)
{
WSL2_TEST_ONLY();
std::promise<WslcSessionTerminationReason> promise;
auto callback = [](WslcSessionTerminationReason reason, PVOID context) {
@@ -294,10 +290,8 @@ class WslcSdkTests
VERIFY_ARE_EQUAL(future.get(), WSLC_SESSION_TERMINATION_REASON_SHUTDOWN);
}
TEST_METHOD(TerminationCallbackViaRelease)
WSLC_TEST_METHOD(TerminationCallbackViaRelease)
{
WSL2_TEST_ONLY();
std::promise<WslcSessionTerminationReason> promise;
auto callback = [](WslcSessionTerminationReason reason, PVOID context) {
@@ -329,10 +323,8 @@ class WslcSdkTests
// Image tests
// -----------------------------------------------------------------------
TEST_METHOD(PullImage)
WSLC_TEST_METHOD(PullImage)
{
WSL2_TEST_ONLY();
// Positive: pull a well-known image.
{
WslcPullImageOptions opts{};
@@ -385,10 +377,8 @@ class WslcSdkTests
}
}
TEST_METHOD(ImageList)
WSLC_TEST_METHOD(ImageList)
{
WSL2_TEST_ONLY();
// Positive: session has images pre-loaded — list must return at least one entry.
{
WslcImageInfo* images = nullptr;
@@ -424,10 +414,8 @@ class WslcSdkTests
}
}
TEST_METHOD(LoadImage)
WSLC_TEST_METHOD(LoadImage)
{
WSL2_TEST_ONLY();
// Positive: load a saved image tar and verify the image can be run.
{
// Remove the image first (ignore failure if it wasn't present).
@@ -478,10 +466,8 @@ class WslcSdkTests
VERIFY_ARE_EQUAL(WslcLoadSessionImageFromFile(m_defaultSession, nullptr, &opts, nullptr), E_POINTER);
}
TEST_METHOD(ImportImage)
WSLC_TEST_METHOD(ImportImage)
{
WSL2_TEST_ONLY();
const auto exportedImageTar = std::filesystem::path{g_testDataPath} / L"HelloWorldExported.tar";
constexpr auto c_handleImportedImageName = "my-hello-world-handle:test";
constexpr auto c_pathImportedImageName = "my-hello-world-path:test";
@@ -533,9 +519,8 @@ class WslcSdkTests
VERIFY_ARE_EQUAL(WslcImportSessionImage(m_defaultSession, "zero-length:test", GetCurrentThreadEffectiveToken(), 0, &opts, nullptr), E_INVALIDARG);
}
TEST_METHOD(LoadImageNonTar)
WSLC_TEST_METHOD(LoadImageNonTar)
{
WSL2_TEST_ONLY();
// The load should fail but it just silently ignores the load currently.
SKIP_TEST_NOT_IMPL();
@@ -556,10 +541,8 @@ class WslcSdkTests
}
}
TEST_METHOD(ImportImageNonTar)
WSLC_TEST_METHOD(ImportImageNonTar)
{
WSL2_TEST_ONLY();
// Negative: attempt to load a non-tar file.
{
std::filesystem::path pathToSelf = wil::QueryFullProcessImageNameW<std::wstring>(GetCurrentProcess());
@@ -580,10 +563,8 @@ class WslcSdkTests
}
}
TEST_METHOD(ImageDelete)
WSLC_TEST_METHOD(ImageDelete)
{
WSL2_TEST_ONLY();
auto checkForImage = [this](std::string_view image) -> bool {
WslcImageInfo* images = nullptr;
uint32_t count = 0;
@@ -621,10 +602,8 @@ class WslcSdkTests
// Container lifecycle tests
// -----------------------------------------------------------------------
TEST_METHOD(CreateContainer)
WSLC_TEST_METHOD(CreateContainer)
{
WSL2_TEST_ONLY();
// Simple echo — verify stdout is captured correctly.
{
auto output = RunContainerAndCapture(m_defaultSession, "debian:latest", {"/bin/echo", "OK"});
@@ -670,10 +649,8 @@ class WslcSdkTests
}
}
TEST_METHOD(ContainerGetID)
WSLC_TEST_METHOD(ContainerGetID)
{
WSL2_TEST_ONLY();
UniqueContainer container;
WslcContainerSettings containerSettings;
VERIFY_SUCCEEDED(WslcInitContainerSettings("debian:latest", &containerSettings));
@@ -690,10 +667,8 @@ class WslcSdkTests
VERIFY_SUCCEEDED(WslcDeleteContainer(container.get(), WSLC_DELETE_CONTAINER_FLAG_NONE, nullptr));
}
TEST_METHOD(ContainerGetState)
WSLC_TEST_METHOD(ContainerGetState)
{
WSL2_TEST_ONLY();
WslcProcessSettings procSettings;
VERIFY_SUCCEEDED(WslcInitProcessSettings(&procSettings));
const char* argv[] = {"/bin/sleep", "99"};
@@ -737,10 +712,8 @@ class WslcSdkTests
VERIFY_SUCCEEDED(WslcDeleteContainer(container.get(), WSLC_DELETE_CONTAINER_FLAG_NONE, nullptr));
}
TEST_METHOD(ContainerStopAndDelete)
WSLC_TEST_METHOD(ContainerStopAndDelete)
{
WSL2_TEST_ONLY();
// Build a long-running container.
WslcProcessSettings procSettings;
VERIFY_SUCCEEDED(WslcInitProcessSettings(&procSettings));
@@ -769,10 +742,8 @@ class WslcSdkTests
VERIFY_SUCCEEDED(WslcDeleteContainer(container.get(), WSLC_DELETE_CONTAINER_FLAG_NONE, nullptr));
}
TEST_METHOD(ProcessIOHandles)
WSLC_TEST_METHOD(ProcessIOHandles)
{
WSL2_TEST_ONLY();
// Verify that stdout and stderr can each be read, and are independent streams.
WslcProcessSettings procSettings;
VERIFY_SUCCEEDED(WslcInitProcessSettings(&procSettings));
@@ -811,10 +782,8 @@ class WslcSdkTests
VERIFY_ARE_EQUAL(WaitForSingleObject(exitEvent, 60 * 1000), WAIT_OBJECT_0);
}
TEST_METHOD(ContainerNetworkingMode)
WSLC_TEST_METHOD(ContainerNetworkingMode)
{
WSL2_TEST_ONLY();
// BRIDGED: container should have an eth0 interface in sysfs.
{
auto output = RunContainerAndCapture(
@@ -849,10 +818,8 @@ class WslcSdkTests
}
}
TEST_METHOD(ContainerPortMapping)
WSLC_TEST_METHOD(ContainerPortMapping)
{
WSL2_TEST_ONLY();
// Negative: null mappings with nonzero count must fail.
{
WslcContainerSettings containerSettings;
@@ -929,10 +896,8 @@ class WslcSdkTests
}
}
TEST_METHOD(ContainerVolumeUnit)
WSLC_TEST_METHOD(ContainerVolumeUnit)
{
WSL2_TEST_ONLY();
// Negative: null volumes with nonzero count must fail.
{
WslcContainerSettings containerSettings;
@@ -997,10 +962,8 @@ class WslcSdkTests
}
}
TEST_METHOD(ContainerVolumeFunctional)
WSLC_TEST_METHOD(ContainerVolumeFunctional)
{
WSL2_TEST_ONLY();
// Functional: mount a read-write and a read-only directory into the container.
{
auto hostRwDir = std::filesystem::current_path() / "wslc-test-vol-rw";
@@ -1070,10 +1033,8 @@ class WslcSdkTests
}
}
TEST_METHOD(ContainerInspect)
WSLC_TEST_METHOD(ContainerInspect)
{
WSL2_TEST_ONLY();
UniqueContainer container;
WslcContainerSettings containerSettings;
VERIFY_SUCCEEDED(WslcInitContainerSettings("debian:latest", &containerSettings));
@@ -1092,10 +1053,8 @@ class WslcSdkTests
VERIFY_ARE_EQUAL(containerId, inspectObject.Id);
}
TEST_METHOD(ContainerExec)
WSLC_TEST_METHOD(ContainerExec)
{
WSL2_TEST_ONLY();
// Start a long-running container so we can exec into it.
WslcProcessSettings initProcSettings;
VERIFY_SUCCEEDED(WslcInitProcessSettings(&initProcSettings));
@@ -1143,10 +1102,8 @@ class WslcSdkTests
}
}
TEST_METHOD(ContainerHostName)
WSLC_TEST_METHOD(ContainerHostName)
{
WSL2_TEST_ONLY();
// Unit: setting a hostname succeeds.
{
WslcContainerSettings containerSettings;
@@ -1171,10 +1128,8 @@ class WslcSdkTests
}
}
TEST_METHOD(ContainerDomainName)
WSLC_TEST_METHOD(ContainerDomainName)
{
WSL2_TEST_ONLY();
// Unit: setting a domain name succeeds.
{
WslcContainerSettings containerSettings;
@@ -1199,10 +1154,8 @@ class WslcSdkTests
}
}
TEST_METHOD(ProcessEnvVariables)
WSLC_TEST_METHOD(ProcessEnvVariables)
{
WSL2_TEST_ONLY();
// Negative: null pointer with nonzero count must fail.
{
WslcProcessSettings procSettings;
@@ -1243,10 +1196,8 @@ class WslcSdkTests
}
}
TEST_METHOD(ProcessSignal)
WSLC_TEST_METHOD(ProcessSignal)
{
WSL2_TEST_ONLY();
WslcProcessSettings procSettings;
VERIFY_SUCCEEDED(WslcInitProcessSettings(&procSettings));
const char* argv[] = {"/bin/sleep", "99"};
@@ -1276,10 +1227,8 @@ class WslcSdkTests
VERIFY_ARE_EQUAL(WslcSignalProcess(nullptr, WSLC_SIGNAL_SIGKILL), E_POINTER);
}
TEST_METHOD(ProcessGetPid)
WSLC_TEST_METHOD(ProcessGetPid)
{
WSL2_TEST_ONLY();
WslcProcessSettings procSettings;
VERIFY_SUCCEEDED(WslcInitProcessSettings(&procSettings));
const char* argv[] = {"/bin/sleep", "99"};
@@ -1309,10 +1258,8 @@ class WslcSdkTests
VERIFY_ARE_EQUAL(WslcGetProcessPid(nullProcess, &pid), E_POINTER);
}
TEST_METHOD(ProcessGetExitCode)
WSLC_TEST_METHOD(ProcessGetExitCode)
{
WSL2_TEST_ONLY();
auto RunAndGetProcess = [&](int exitCodeArg) -> UniqueProcess {
std::string script = "exit " + std::to_string(exitCodeArg);
const char* argv[] = {"/bin/sh", "-c", script.c_str()};
@@ -1365,10 +1312,8 @@ class WslcSdkTests
}
}
TEST_METHOD(ProcessGetState)
WSLC_TEST_METHOD(ProcessGetState)
{
WSL2_TEST_ONLY();
WslcProcessSettings procSettings;
VERIFY_SUCCEEDED(WslcInitProcessSettings(&procSettings));
const char* argv[] = {"/bin/sleep", "99"};
@@ -1424,10 +1369,8 @@ class WslcSdkTests
}
}
TEST_METHOD(ProcessCurrentDirectory)
WSLC_TEST_METHOD(ProcessCurrentDirectory)
{
WSL2_TEST_ONLY();
// Unit: setting a current directory returns S_OK.
{
WslcProcessSettings procSettings;
@@ -1462,10 +1405,8 @@ class WslcSdkTests
}
}
TEST_METHOD(GetVersion)
WSLC_TEST_METHOD(GetVersion)
{
WSL2_TEST_ONLY();
// Positive: returns S_OK and fills in a non-zero version.
{
WslcVersion version{};
@@ -1477,10 +1418,8 @@ class WslcSdkTests
VERIFY_ARE_EQUAL(WslcGetVersion(nullptr), E_POINTER);
}
TEST_METHOD(CanRun)
WSLC_TEST_METHOD(CanRun)
{
WSL2_TEST_ONLY();
BOOL canRun = FALSE;
WslcComponentFlags missing{};
VERIFY_SUCCEEDED(WslcCanRun(&canRun, &missing));
@@ -1495,10 +1434,8 @@ class WslcSdkTests
// WslcSetProcessSettingsCallbacks tests
// -----------------------------------------------------------------------
TEST_METHOD(ProcessIoCallbackUnit)
WSLC_TEST_METHOD(ProcessIoCallbackUnit)
{
WSL2_TEST_ONLY();
auto noopIoCb = [](WslcProcessIOHandle, const BYTE*, uint32_t, PVOID) {};
auto noopExitCb = [](INT32, PVOID) {};
@@ -1584,10 +1521,8 @@ class WslcSdkTests
}
}
TEST_METHOD(ProcessIoCallbackInitProcess)
WSLC_TEST_METHOD(ProcessIoCallbackInitProcess)
{
WSL2_TEST_ONLY();
struct IOContext
{
std::string stdoutData;
@@ -1636,10 +1571,8 @@ class WslcSdkTests
VERIFY_ARE_EQUAL(ioContext.stderrData, "STDERR\n");
}
TEST_METHOD(ProcessIoCallbackExecProcess)
WSLC_TEST_METHOD(ProcessIoCallbackExecProcess)
{
WSL2_TEST_ONLY();
// Start a long-running container so we can exec into it.
WslcProcessSettings initProcSettings;
VERIFY_SUCCEEDED(WslcInitProcessSettings(&initProcSettings));
@@ -1691,10 +1624,8 @@ class WslcSdkTests
VERIFY_ARE_EQUAL(ioContext.stderrData, "EXEC_ERR\n");
}
TEST_METHOD(ProcessIoCallbackHandleExclusion)
WSLC_TEST_METHOD(ProcessIoCallbackHandleExclusion)
{
WSL2_TEST_ONLY();
// Register a stdout callback only. IOCallback always acquires ALL pipe handles
// (draining uncallbacked streams to prevent deadlock), so both stdout and stderr
// handles are consumed and neither can be obtained via WslcGetProcessIOHandle.
@@ -1733,10 +1664,8 @@ class WslcSdkTests
}
}
TEST_METHOD(ProcessIoCallbackExitCallback)
WSLC_TEST_METHOD(ProcessIoCallbackExitCallback)
{
WSL2_TEST_ONLY();
// Verify the onExit callback fires with the correct exit code after IO has been flushed.
// We test both exit 0 and a non-zero exit code.
auto RunAndCaptureExit = [&](int exitCodeArg) -> std::pair<INT32, std::string> {
@@ -1801,10 +1730,8 @@ class WslcSdkTests
}
}
TEST_METHOD(ProcessIoCallbackCancelOnRelease)
WSLC_TEST_METHOD(ProcessIoCallbackCancelOnRelease)
{
WSL2_TEST_ONLY();
// Verify that releasing the process handle while an exec'd process is still running
// and writing IO cancels the IOCallback pump:
// - No IO callbacks arrive after the handle is released.
@@ -1873,10 +1800,8 @@ class WslcSdkTests
VERIFY_IS_FALSE(ctx.exitFired.load());
}
TEST_METHOD(ProcessIoCallbackLargeOutput)
WSLC_TEST_METHOD(ProcessIoCallbackLargeOutput)
{
WSL2_TEST_ONLY();
// Generate ~1 MiB of stdout via: dd if=/dev/zero bs=1024 count=1024 | base64
// 1,048,576 zero bytes → base64 output is 1,398,104 bytes (ceil(1048576/3)*4).
static constexpr size_t c_expectedBytes = 1'398'104;
@@ -1923,10 +1848,8 @@ class WslcSdkTests
// Storage tests
// -----------------------------------------------------------------------
TEST_METHOD(SessionCreateVhd)
WSLC_TEST_METHOD(SessionCreateVhd)
{
WSL2_TEST_ONLY();
constexpr auto c_volumeName = "wslc-test-data-vol";
constexpr auto c_vhdSizeBytes = _1GB;
@@ -2060,10 +1983,8 @@ class WslcSdkTests
// should be updated to exercise the real behaviour.
// -----------------------------------------------------------------------
TEST_METHOD(InstallWithDependenciesNotImplemented)
WSLC_TEST_METHOD(InstallWithDependenciesNotImplemented)
{
WSL2_TEST_ONLY();
VERIFY_ARE_EQUAL(WslcInstallWithDependencies(nullptr, nullptr), E_NOTIMPL);
}
};

View File

@@ -80,23 +80,20 @@ class WSLCE2EContainerCreateTests
return true;
}
TEST_METHOD(WSLCE2E_Container_Create_HelpCommand)
WSLC_TEST_METHOD(WSLCE2E_Container_Create_HelpCommand)
{
WSL2_TEST_ONLY();
auto result = RunWslc(L"container create --help");
result.Verify({.Stdout = GetHelpMessage(), .Stderr = L"", .ExitCode = S_OK});
}
TEST_METHOD(WSLCE2E_Container_Create_MissingImage)
WSLC_TEST_METHOD(WSLCE2E_Container_Create_MissingImage)
{
WSL2_TEST_ONLY();
auto result = RunWslc(L"container create --name " + WslcContainerName);
result.Verify({.Stdout = GetHelpMessage(), .Stderr = L"Required argument not provided: 'image'\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Container_Create_InvalidImage)
WSLC_TEST_METHOD(WSLCE2E_Container_Create_InvalidImage)
{
WSL2_TEST_ONLY();
auto result = RunWslc(L"container create --name " + WslcContainerName + L" " + InvalidImage.NameAndTag());
std::wstringstream expectedError;
expectedError << L"Image '" << InvalidImage.NameAndTag() << L"' not found, pulling\r\n"
@@ -106,9 +103,8 @@ class WSLCE2EContainerCreateTests
result.Verify({.Stderr = expectedError.str(), .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Container_Create_Valid)
WSLC_TEST_METHOD(WSLCE2E_Container_Create_Valid)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
// Create the container with a valid image
@@ -120,9 +116,8 @@ class WSLCE2EContainerCreateTests
VerifyContainerIsListed(containerId, L"created");
}
TEST_METHOD(WSLCE2E_Container_Create_DuplicateContainerName)
WSLC_TEST_METHOD(WSLCE2E_Container_Create_DuplicateContainerName)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
// Create the container with a valid image
@@ -137,10 +132,8 @@ class WSLCE2EContainerCreateTests
.ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Container_Create_Volume_WriteFromHostReadFromContainer)
WSLC_TEST_METHOD(WSLCE2E_Container_Create_Volume_WriteFromHostReadFromContainer)
{
WSL2_TEST_ONLY();
// Write to a temp file that we will mount as a volume to the container
const std::wstring tempFile = VolumeTestFile1.wstring();
std::wofstream out(tempFile);
@@ -159,10 +152,8 @@ class WSLCE2EContainerCreateTests
result.Verify({.Stdout = L"WSLC Volume Test", .Stderr = L"", .ExitCode = S_OK});
}
TEST_METHOD(WSLCE2E_Container_Create_Volume_WriteFromContainerReadFromHost_ReadWritePermissionByDefault)
WSLC_TEST_METHOD(WSLCE2E_Container_Create_Volume_WriteFromContainerReadFromHost_ReadWritePermissionByDefault)
{
WSL2_TEST_ONLY();
auto hostDirectory = VolumeTestFile1.parent_path();
auto fileName = VolumeTestFile1.filename().wstring();
auto result = RunWslc(std::format(
@@ -178,10 +169,8 @@ class WSLCE2EContainerCreateTests
VERIFY_ARE_EQUAL(L"WSLC Volume Test", content);
}
TEST_METHOD(WSLCE2E_Container_Create_Volume_WriteFromContainerReadFromHost_ReadWritePermission)
WSLC_TEST_METHOD(WSLCE2E_Container_Create_Volume_WriteFromContainerReadFromHost_ReadWritePermission)
{
WSL2_TEST_ONLY();
auto hostDirectory = VolumeTestFile1.parent_path();
auto fileName = VolumeTestFile1.filename().wstring();
auto result = RunWslc(std::format(
@@ -199,10 +188,8 @@ class WSLCE2EContainerCreateTests
VERIFY_ARE_EQUAL(L"WSLC Volume Test", buffer.str());
}
TEST_METHOD(WSLCE2E_Container_Create_Volume_WriteFromContainerReadFromHost_ReadOnlyPermission_Fail)
WSLC_TEST_METHOD(WSLCE2E_Container_Create_Volume_WriteFromContainerReadFromHost_ReadOnlyPermission_Fail)
{
WSL2_TEST_ONLY();
auto hostDirectory = VolumeTestFile1.parent_path();
auto fileName = VolumeTestFile1.filename().wstring();
auto result = RunWslc(std::format(
@@ -215,10 +202,8 @@ class WSLCE2EContainerCreateTests
result.Verify({.Stdout = L"", .Stderr = errorMessage, .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Container_Create_Volume_Multiple_WriteFromContainerReadFromHost_ReadWritePermission)
WSLC_TEST_METHOD(WSLCE2E_Container_Create_Volume_Multiple_WriteFromContainerReadFromHost_ReadWritePermission)
{
WSL2_TEST_ONLY();
// Mount multiple volumes to the container
auto hostDirectory1 = VolumeTestFile1.parent_path();
auto fileName1 = VolumeTestFile1.filename().wstring();
@@ -249,10 +234,8 @@ class WSLCE2EContainerCreateTests
VERIFY_ARE_EQUAL(L"Test2", buffer2.str());
}
TEST_METHOD(WSLCE2E_Container_Create_Volume_Invalid)
WSLC_TEST_METHOD(WSLCE2E_Container_Create_Volume_Invalid)
{
WSL2_TEST_ONLY();
{
auto result =
RunWslc(std::format(L"container run --name {} --volume :/containerPath {}", WslcContainerName, AlpineImage.NameAndTag()));
@@ -329,13 +312,11 @@ class WSLCE2EContainerCreateTests
}
}
TEST_METHOD(WSLCE2E_Container_Create_Volume_NotSupported)
WSLC_TEST_METHOD(WSLCE2E_Container_Create_Volume_NotSupported)
{
// Commands tested in this method are not currently supported in WSLC,
// so we just verify that they fail with the expected error message.
// https://github.com/microsoft/WSL/issues/14432
WSL2_TEST_ONLY();
{
auto result = RunWslc(
std::format(L"container run --name {} --volume \"C:\\hostPath\" {}", WslcContainerName, AlpineImage.NameAndTag()));
@@ -371,9 +352,8 @@ class WSLCE2EContainerCreateTests
}
}
TEST_METHOD(WSLCE2E_Container_Create_Remove)
WSLC_TEST_METHOD(WSLCE2E_Container_Create_Remove)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
auto result = RunWslc(std::format(L"container create --rm --name {} {} echo hello", WslcContainerName, DebianImage.NameAndTag()));
@@ -387,9 +367,8 @@ class WSLCE2EContainerCreateTests
VerifyContainerIsNotListed(WslcContainerName, std::chrono::seconds(2), std::chrono::minutes(1));
}
TEST_METHOD(WSLCE2E_Container_Run_Remove)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_Remove)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
// Run the container with a valid image
@@ -400,9 +379,8 @@ class WSLCE2EContainerCreateTests
VerifyContainerIsNotListed(WslcContainerName);
}
TEST_METHOD(WSLCE2E_Container_Run_EnvOption)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_EnvOption)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
auto result = RunWslc(std::format(
@@ -413,9 +391,8 @@ class WSLCE2EContainerCreateTests
VERIFY_IS_TRUE(ContainsOutputLine(outputLines, std::format(L"{}=A", HostEnvVariableName)));
}
TEST_METHOD(WSLCE2E_Container_Run_EnvOption_MultipleValues)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_EnvOption_MultipleValues)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
auto result = RunWslc(std::format(
@@ -431,9 +408,8 @@ class WSLCE2EContainerCreateTests
VERIFY_IS_TRUE(ContainsOutputLine(outputLines, std::format(L"{}=B", HostEnvVariableName2)));
}
TEST_METHOD(WSLCE2E_Container_Run_EnvOption_KeyOnly_UsesHostValue)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_EnvOption_KeyOnly_UsesHostValue)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
auto result = RunWslc(std::format(
@@ -444,9 +420,8 @@ class WSLCE2EContainerCreateTests
VERIFY_IS_TRUE(ContainsOutputLine(outputLines, std::format(L"{}={}", HostEnvVariableName, HostEnvVariableValue)));
}
TEST_METHOD(WSLCE2E_Container_Run_EnvOption_KeyOnly_MultipleValues_UsesHostValues)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_EnvOption_KeyOnly_MultipleValues_UsesHostValues)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
auto result = RunWslc(std::format(
@@ -462,9 +437,8 @@ class WSLCE2EContainerCreateTests
VERIFY_IS_TRUE(ContainsOutputLine(outputLines, std::format(L"{}={}", HostEnvVariableName2, HostEnvVariableValue2)));
}
TEST_METHOD(WSLCE2E_Container_Run_EnvOption_EmptyValue)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_EnvOption_EmptyValue)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
auto result = RunWslc(std::format(
@@ -475,9 +449,8 @@ class WSLCE2EContainerCreateTests
VERIFY_IS_TRUE(ContainsOutputLine(outputLines, std::format(L"{}=", HostEnvVariableName)));
}
TEST_METHOD(WSLCE2E_Container_Run_EnvFile)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_EnvFile)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
WriteEnvFile(EnvTestFile1, {"WSLC_TEST_ENV_FILE_A=env-file-a", "WSLC_TEST_ENV_FILE_B=env-file-b"});
@@ -494,9 +467,8 @@ class WSLCE2EContainerCreateTests
VERIFY_IS_TRUE(ContainsOutputLine(outputLines, L"WSLC_TEST_ENV_FILE_B=env-file-b"));
}
TEST_METHOD(WSLCE2E_Container_Run_EnvOption_MixedWithEnvFile)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_EnvOption_MixedWithEnvFile)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
WriteEnvFile(EnvTestFile1, {"WSLC_TEST_ENV_MIX_FILE_A=from-file-a", "WSLC_TEST_ENV_MIX_FILE_B=from-file-b"});
@@ -514,9 +486,8 @@ class WSLCE2EContainerCreateTests
VERIFY_IS_TRUE(ContainsOutputLine(outputLines, L"WSLC_TEST_ENV_MIX_CLI=from-cli"));
}
TEST_METHOD(WSLCE2E_Container_Run_EnvFile_MultipleFiles)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_EnvFile_MultipleFiles)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
WriteEnvFile(EnvTestFile1, {"WSLC_TEST_ENV_FILE_MULTI_A=file1-a", "WSLC_TEST_ENV_FILE_MULTI_B=file1-b"});
@@ -538,9 +509,8 @@ class WSLCE2EContainerCreateTests
VERIFY_IS_TRUE(ContainsOutputLine(outputLines, L"WSLC_TEST_ENV_FILE_MULTI_D=file2-d"));
}
TEST_METHOD(WSLCE2E_Container_Run_EnvFile_MissingFile)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_EnvFile_MissingFile)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
auto result = RunWslc(std::format(
@@ -549,9 +519,8 @@ class WSLCE2EContainerCreateTests
{.Stderr = L"Environment file 'ENV_FILE_NOT_FOUND' cannot be opened for reading\r\nError code: E_INVALIDARG\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Container_Run_EnvFile_InvalidContent)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_EnvFile_InvalidContent)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
WriteEnvFile(EnvTestFile1, {"WSLC_TEST_ENV_VALID=ok", "BAD KEY=value"});
@@ -564,9 +533,8 @@ class WSLCE2EContainerCreateTests
result.Verify({.Stderr = L"Environment variable key 'BAD KEY' cannot contain whitespace\r\nError code: E_INVALIDARG\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Container_Run_EnvFile_DuplicateKeys_Precedence)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_EnvFile_DuplicateKeys_Precedence)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
WriteEnvFile(EnvTestFile1, {"WSLC_TEST_ENV_DUP=from-file-1"});
@@ -598,9 +566,8 @@ class WSLCE2EContainerCreateTests
VERIFY_IS_TRUE(ContainsOutputLine(outputLines, L"WSLC_TEST_ENV_DUP=from-cli"));
}
TEST_METHOD(WSLCE2E_Container_Run_EnvFile_ValueContainsEquals)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_EnvFile_ValueContainsEquals)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
WriteEnvFile(EnvTestFile1, {"WSLC_TEST_ENV_EQUALS=value=with=equals"});
@@ -616,10 +583,8 @@ class WSLCE2EContainerCreateTests
VERIFY_IS_TRUE(ContainsOutputLine(outputLines, L"WSLC_TEST_ENV_EQUALS=value=with=equals"));
}
TEST_METHOD(WSLCE2E_Container_Exec_EnvOption)
WSLC_TEST_METHOD(WSLCE2E_Container_Exec_EnvOption)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = S_OK});
@@ -630,10 +595,8 @@ class WSLCE2EContainerCreateTests
VERIFY_IS_TRUE(ContainsOutputLine(outputLines, std::format(L"{}=A", HostEnvVariableName)));
}
TEST_METHOD(WSLCE2E_Container_Exec_EnvOption_KeyOnly_UsesHostValue)
WSLC_TEST_METHOD(WSLCE2E_Container_Exec_EnvOption_KeyOnly_UsesHostValue)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = S_OK});
@@ -644,10 +607,8 @@ class WSLCE2EContainerCreateTests
VERIFY_IS_TRUE(ContainsOutputLine(outputLines, std::format(L"{}={}", HostEnvVariableName, HostEnvVariableValue)));
}
TEST_METHOD(WSLCE2E_Container_Exec_EnvFile)
WSLC_TEST_METHOD(WSLCE2E_Container_Exec_EnvFile)
{
WSL2_TEST_ONLY();
WriteEnvFile(EnvTestFile1, {"WSLC_TEST_EXEC_ENV_FILE_A=exec-env-file-a", "WSLC_TEST_EXEC_ENV_FILE_B=exec-env-file-b"});
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
@@ -661,10 +622,8 @@ class WSLCE2EContainerCreateTests
VERIFY_IS_TRUE(ContainsOutputLine(outputLines, L"WSLC_TEST_EXEC_ENV_FILE_B=exec-env-file-b"));
}
TEST_METHOD(WSLCE2E_Container_Exec_EnvOption_MixedWithEnvFile)
WSLC_TEST_METHOD(WSLCE2E_Container_Exec_EnvOption_MixedWithEnvFile)
{
WSL2_TEST_ONLY();
WriteEnvFile(EnvTestFile1, {"WSLC_TEST_EXEC_ENV_MIX_FILE_A=from-file-a", "WSLC_TEST_EXEC_ENV_MIX_FILE_B=from-file-b"});
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
@@ -680,10 +639,8 @@ class WSLCE2EContainerCreateTests
VERIFY_IS_TRUE(ContainsOutputLine(outputLines, L"WSLC_TEST_EXEC_ENV_MIX_CLI=from-cli"));
}
TEST_METHOD(WSLCE2E_Container_Exec_EnvFile_MissingFile)
WSLC_TEST_METHOD(WSLCE2E_Container_Exec_EnvFile_MissingFile)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = S_OK});
@@ -692,9 +649,8 @@ class WSLCE2EContainerCreateTests
{.Stderr = L"Environment file 'ENV_FILE_NOT_FOUND' cannot be opened for reading\r\nError code: E_INVALIDARG\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Container_RunInteractive_TTY)
WSLC_TEST_METHOD(WSLCE2E_Container_RunInteractive_TTY)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
const auto& prompt = ">";
@@ -719,9 +675,8 @@ class WSLCE2EContainerCreateTests
VERIFY_ARE_EQUAL(0, exitCode);
}
TEST_METHOD(WSLCE2E_Container_RunInteractive_NoTTY)
WSLC_TEST_METHOD(WSLCE2E_Container_RunInteractive_NoTTY)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
auto session = RunWslcInteractive(std::format(L"container run -i --name {} {} cat", WslcContainerName, DebianImage.NameAndTag()));
@@ -741,9 +696,8 @@ class WSLCE2EContainerCreateTests
session.VerifyNoErrors();
}
TEST_METHOD(WSLCE2E_Container_RunAttach_TTY)
WSLC_TEST_METHOD(WSLCE2E_Container_RunAttach_TTY)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
const auto& prompt = ">";
@@ -777,9 +731,8 @@ class WSLCE2EContainerCreateTests
VERIFY_ARE_EQUAL(0, exitCode);
}
TEST_METHOD(WSLCE2E_Container_RunAttach_NoTTY)
WSLC_TEST_METHOD(WSLCE2E_Container_RunAttach_NoTTY)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
auto result = RunWslc(std::format(L"container run -id --name {} {} cat", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = S_OK});
@@ -802,9 +755,8 @@ class WSLCE2EContainerCreateTests
session.VerifyNoErrors();
}
TEST_METHOD(WSLCE2E_Container_ExecInteractive_TTY)
WSLC_TEST_METHOD(WSLCE2E_Container_ExecInteractive_TTY)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
const auto& prompt = ">";
@@ -835,9 +787,8 @@ class WSLCE2EContainerCreateTests
VERIFY_ARE_EQUAL(0, exitCode);
}
TEST_METHOD(WSLCE2E_Container_ExecInteractive_NoTTY)
WSLC_TEST_METHOD(WSLCE2E_Container_ExecInteractive_NoTTY)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
auto result = RunWslc(std::format(L"container run -id --name {} {}", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = S_OK});
@@ -860,9 +811,8 @@ class WSLCE2EContainerCreateTests
session.VerifyNoErrors();
}
TEST_METHOD(WSLCE2E_Container_CreateStartAttach_TTY)
WSLC_TEST_METHOD(WSLCE2E_Container_CreateStartAttach_TTY)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
const auto& prompt = ">";
@@ -893,9 +843,8 @@ class WSLCE2EContainerCreateTests
VERIFY_ARE_EQUAL(0, exitCode);
}
TEST_METHOD(WSLCE2E_Container_CreateStartAttach_NoTTY)
WSLC_TEST_METHOD(WSLCE2E_Container_CreateStartAttach_NoTTY)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
auto result = RunWslc(std::format(L"container create -i --name {} {} cat", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = S_OK});
@@ -919,9 +868,8 @@ class WSLCE2EContainerCreateTests
session.VerifyNoErrors();
}
TEST_METHOD(WSLCE2E_Container_CreateStartAttach_ShortRunningInitProcess)
WSLC_TEST_METHOD(WSLCE2E_Container_CreateStartAttach_ShortRunningInitProcess)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
constexpr auto ExpectedExitCode = 37;
@@ -935,10 +883,8 @@ class WSLCE2EContainerCreateTests
result.Verify({.Stdout = L"lifecycle works\n", .Stderr = L"", .ExitCode = ExpectedExitCode});
}
TEST_METHOD(WSLCE2E_Container_Run_Port_TCP)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_Port_TCP)
{
WSL2_TEST_ONLY();
// Start a container with a simple server listening on a port
auto result = RunWslc(std::format(
L"container run -d --name {} -p {}:{} {} {}",
@@ -963,10 +909,8 @@ class WSLCE2EContainerCreateTests
VERIFY_ARE_EQUAL("127.0.0.1", portBindings[0].HostIp);
}
TEST_METHOD(WSLCE2E_Container_Run_PortMultipleMappings)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_PortMultipleMappings)
{
WSL2_TEST_ONLY();
// Start a container with a simple server listening on a port
// Map two host ports to the same container port
auto result = RunWslc(std::format(
@@ -985,13 +929,11 @@ class WSLCE2EContainerCreateTests
ExpectHttpResponse(std::format(L"http://127.0.0.1:{}", HostTestPort2).c_str(), HTTP_STATUS_OK, true);
}
TEST_METHOD(WSLCE2E_Container_Run_PortAlreadyInUse)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_PortAlreadyInUse)
{
// Bug: https://github.com/microsoft/WSL/issues/14448
SKIP_TEST_NOT_IMPL();
WSL2_TEST_ONLY();
// Start a container with a simple server listening on a port
auto result1 = RunWslc(std::format(
L"container run -d --name {} -p {}:{} {} {}",
@@ -1008,36 +950,28 @@ class WSLCE2EContainerCreateTests
}
// https://github.com/microsoft/WSL/issues/14433
TEST_METHOD(WSLCE2E_Container_Run_PortEphemeral_NotSupported)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_PortEphemeral_NotSupported)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run -p 80 {}", DebianImage.NameAndTag()));
result.Verify({.Stderr = L"Port mappings with ephemeral host ports, specific host IPs, or UDP protocol are not currently supported\r\nError code: ERROR_NOT_SUPPORTED\r\n", .ExitCode = 1});
}
// https://github.com/microsoft/WSL/issues/14433
TEST_METHOD(WSLCE2E_Container_Run_PortUdp_NotSupported)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_PortUdp_NotSupported)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run -p 80:80/udp {}", DebianImage.NameAndTag()));
result.Verify({.Stderr = L"Port mappings with ephemeral host ports, specific host IPs, or UDP protocol are not currently supported\r\nError code: ERROR_NOT_SUPPORTED\r\n", .ExitCode = 1});
}
// https://github.com/microsoft/WSL/issues/14433
TEST_METHOD(WSLCE2E_Container_Run_PortHostIP_NotSupported)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_PortHostIP_NotSupported)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run -p 127.0.0.1:80:80 {}", DebianImage.NameAndTag()));
result.Verify({.Stderr = L"Port mappings with ephemeral host ports, specific host IPs, or UDP protocol are not currently supported\r\nError code: ERROR_NOT_SUPPORTED\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Container_Create_UserOption_UidRoot)
WSLC_TEST_METHOD(WSLCE2E_Container_Create_UserOption_UidRoot)
{
WSL2_TEST_ONLY();
auto result = RunWslc(
std::format(L"container create --name {} -u 0 {} sh -c \"id -u; id -g\"", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = S_OK});
@@ -1046,10 +980,8 @@ class WSLCE2EContainerCreateTests
result.Verify({.Stdout = L"0\n0\n", .Stderr = L"", .ExitCode = S_OK});
}
TEST_METHOD(WSLCE2E_Container_Create_UserOption_NameGroupRoot)
WSLC_TEST_METHOD(WSLCE2E_Container_Create_UserOption_NameGroupRoot)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(
L"container create --name {} -u root:root {} sh -c \"id -un; id -u; id -g\"", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = S_OK});
@@ -1058,10 +990,8 @@ class WSLCE2EContainerCreateTests
result.Verify({.Stdout = L"root\n0\n0\n", .Stderr = L"", .ExitCode = S_OK});
}
TEST_METHOD(WSLCE2E_Container_Create_UserOption_UnknownUser_Fails)
WSLC_TEST_METHOD(WSLCE2E_Container_Create_UserOption_UnknownUser_Fails)
{
WSL2_TEST_ONLY();
auto result = RunWslc(
std::format(L"container create --name {} -u user_does_not_exist {} id -u", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = 0});
@@ -1071,10 +1001,8 @@ class WSLCE2EContainerCreateTests
{.Stderr = L"unable to find user user_does_not_exist: no matching entries in passwd file\r\nError code: E_FAIL\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Container_Exec_UserOption_UidRoot)
WSLC_TEST_METHOD(WSLCE2E_Container_Exec_UserOption_UidRoot)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = S_OK});
@@ -1082,10 +1010,8 @@ class WSLCE2EContainerCreateTests
result.Verify({.Stdout = L"0\n0\n", .Stderr = L"", .ExitCode = S_OK});
}
TEST_METHOD(WSLCE2E_Container_Exec_UserOption_NameGroupRoot)
WSLC_TEST_METHOD(WSLCE2E_Container_Exec_UserOption_NameGroupRoot)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = S_OK});
@@ -1093,10 +1019,8 @@ class WSLCE2EContainerCreateTests
result.Verify({.Stdout = L"root\n0\n0\n", .Stderr = L"", .ExitCode = S_OK});
}
TEST_METHOD(WSLCE2E_Container_Exec_UserOption_InvalidGroup_Fails)
WSLC_TEST_METHOD(WSLCE2E_Container_Exec_UserOption_InvalidGroup_Fails)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = S_OK});

View File

@@ -41,18 +41,14 @@ class WSLCE2EContainerExecTests
return true;
}
TEST_METHOD(WSLCE2E_Container_Exec_HelpCommand)
WSLC_TEST_METHOD(WSLCE2E_Container_Exec_HelpCommand)
{
WSL2_TEST_ONLY();
auto result = RunWslc(L"container exec --help");
result.Verify({.Stdout = GetHelpMessage(), .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Container_Exec_WorkDir)
WSLC_TEST_METHOD(WSLCE2E_Container_Exec_WorkDir)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = 0});
@@ -60,10 +56,8 @@ class WSLCE2EContainerExecTests
result.Verify({.Stdout = L"/tmp\n", .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Container_Exec_WorkDir_ShortAlias)
WSLC_TEST_METHOD(WSLCE2E_Container_Exec_WorkDir_ShortAlias)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = 0});

View File

@@ -44,18 +44,14 @@ class WSLCE2EContainerKillTests
return true;
}
TEST_METHOD(WSLCE2E_Container_Kill_HelpCommand)
WSLC_TEST_METHOD(WSLCE2E_Container_Kill_HelpCommand)
{
WSL2_TEST_ONLY();
auto result = RunWslc(L"container kill --help");
result.Verify({.Stdout = GetHelpMessage(), .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Container_Kill_KillsRunningContainer)
WSLC_TEST_METHOD(WSLCE2E_Container_Kill_KillsRunningContainer)
{
WSL2_TEST_ONLY();
// Run a container in the background
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = 0});
@@ -73,10 +69,8 @@ class WSLCE2EContainerKillTests
VerifyContainerIsListed(containerId, L"exited");
}
TEST_METHOD(WSLCE2E_Container_Kill_ByName)
WSLC_TEST_METHOD(WSLCE2E_Container_Kill_ByName)
{
WSL2_TEST_ONLY();
// Run a container in the background
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = 0});
@@ -94,20 +88,16 @@ class WSLCE2EContainerKillTests
VerifyContainerIsListed(containerId, L"exited");
}
TEST_METHOD(WSLCE2E_Container_Kill_NotFound)
WSLC_TEST_METHOD(WSLCE2E_Container_Kill_NotFound)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
auto result = RunWslc(std::format(L"container kill {}", WslcContainerName));
result.Verify({.Stderr = L"Element not found. \r\nError code: ERROR_NOT_FOUND\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Container_Kill_InvalidSignal)
WSLC_TEST_METHOD(WSLCE2E_Container_Kill_InvalidSignal)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run --name {} {}", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = 0});
@@ -122,10 +112,8 @@ class WSLCE2EContainerKillTests
}
}
TEST_METHOD(WSLCE2E_Container_Kill_TargetedContainerOnly)
WSLC_TEST_METHOD(WSLCE2E_Container_Kill_TargetedContainerOnly)
{
WSL2_TEST_ONLY();
// Run first container in background
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = 0});

View File

@@ -48,16 +48,14 @@ class WSLCE2EContainerListTests
return true;
}
TEST_METHOD(WSLCE2E_Container_List_HelpCommand)
WSLC_TEST_METHOD(WSLCE2E_Container_List_HelpCommand)
{
WSL2_TEST_ONLY();
auto result = RunWslc(L"container list --help");
result.Verify({.Stdout = GetHelpMessage(), .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Container_List_AllOption)
WSLC_TEST_METHOD(WSLCE2E_Container_List_AllOption)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
// Create a container
@@ -85,9 +83,8 @@ class WSLCE2EContainerListTests
VERIFY_ARE_NOT_EQUAL(std::wstring::npos, foundContainerLine->find(L"created"));
}
TEST_METHOD(WSLCE2E_Container_List_NoOptions_RunningContainers)
WSLC_TEST_METHOD(WSLCE2E_Container_List_NoOptions_RunningContainers)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
// Run a container in the background
@@ -115,9 +112,8 @@ class WSLCE2EContainerListTests
VERIFY_ARE_NOT_EQUAL(std::wstring::npos, foundContainerLine->find(L"running"));
}
TEST_METHOD(WSLCE2E_Container_List_NoOptions_ExcludesCreatedContainers)
WSLC_TEST_METHOD(WSLCE2E_Container_List_NoOptions_ExcludesCreatedContainers)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
// Create (but do not start) a container.
@@ -142,9 +138,8 @@ class WSLCE2EContainerListTests
VERIFY_IS_FALSE(isListed);
}
TEST_METHOD(WSLCE2E_Container_List_QuietOption_OutputsIdsOnly)
WSLC_TEST_METHOD(WSLCE2E_Container_List_QuietOption_OutputsIdsOnly)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
auto result = RunWslc(std::format(L"container create --name {} {}", WslcContainerName, DebianImage.NameAndTag()));
@@ -159,17 +154,14 @@ class WSLCE2EContainerListTests
VERIFY_ARE_EQUAL(containerId, outputLine);
}
TEST_METHOD(WSLCE2E_Container_List_InvalidFormatOption)
WSLC_TEST_METHOD(WSLCE2E_Container_List_InvalidFormatOption)
{
WSL2_TEST_ONLY();
const auto result = RunWslc(L"container list --format invalid");
result.Verify({.Stderr = L"Invalid format value: invalid is not a recognized format type. Supported format types are: json, table.\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Container_List_JsonFormat)
WSLC_TEST_METHOD(WSLCE2E_Container_List_JsonFormat)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
// Create a container

View File

@@ -44,26 +44,22 @@ class WSLCE2EContainerRemoveTests
return true;
}
TEST_METHOD(WSLCE2E_Container_Remove_HelpCommand)
WSLC_TEST_METHOD(WSLCE2E_Container_Remove_HelpCommand)
{
WSL2_TEST_ONLY();
auto result = RunWslc(L"container remove --help");
result.Verify({.Stdout = GetHelpMessage(), .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Container_Remove_NotFound)
WSLC_TEST_METHOD(WSLCE2E_Container_Remove_NotFound)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
auto result = RunWslc(std::format(L"container remove {}", WslcContainerName));
result.Verify({.Stdout = L"", .Stderr = L"Element not found. \r\nError code: ERROR_NOT_FOUND\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Container_Remove_Valid)
WSLC_TEST_METHOD(WSLCE2E_Container_Remove_Valid)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
// Create the container with a valid image
@@ -82,9 +78,8 @@ class WSLCE2EContainerRemoveTests
VerifyContainerIsNotListed(WslcContainerName);
}
TEST_METHOD(WSLCE2E_Container_Remove_ById_Valid)
WSLC_TEST_METHOD(WSLCE2E_Container_Remove_ById_Valid)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
auto result = RunWslc(std::format(L"container create --name {} {}", WslcContainerName, DebianImage.NameAndTag()));
@@ -101,9 +96,8 @@ class WSLCE2EContainerRemoveTests
VerifyContainerIsNotListed(WslcContainerName);
}
TEST_METHOD(WSLCE2E_Container_Remove_Force_RunningContainer)
WSLC_TEST_METHOD(WSLCE2E_Container_Remove_Force_RunningContainer)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
// Run a container so it is in running state
@@ -132,9 +126,8 @@ class WSLCE2EContainerRemoveTests
VerifyContainerIsNotListed(WslcContainerName);
}
TEST_METHOD(WSLCE2E_Container_Remove_Multiple_Valid)
WSLC_TEST_METHOD(WSLCE2E_Container_Remove_Multiple_Valid)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
VerifyContainerIsNotListed(WslcContainerName2);

View File

@@ -41,18 +41,14 @@ class WSLCE2EContainerRunTests
return true;
}
TEST_METHOD(WSLCE2E_Container_Run_HelpCommand)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_HelpCommand)
{
WSL2_TEST_ONLY();
auto result = RunWslc(L"container run --help");
result.Verify({.Stdout = GetHelpMessage(), .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Container_Run_Container_With_Command)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_Container_With_Command)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
auto command = L"echo echo_from_container";
@@ -62,36 +58,28 @@ class WSLCE2EContainerRunTests
VerifyContainerIsListed(WslcContainerName, L"exited");
}
TEST_METHOD(WSLCE2E_Container_Run_Entrypoint)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_Entrypoint)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run --rm --entrypoint /bin/whoami {}", DebianImage.NameAndTag()));
result.Verify({.Stdout = L"root\n", .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Container_Run_Entrypoint_And_Arguments)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_Entrypoint_And_Arguments)
{
WSL2_TEST_ONLY();
auto result = RunWslc(
std::format(L"container run --rm --entrypoint /bin/echo {} hello from entrypoint with args", DebianImage.NameAndTag()));
result.Verify({.Stdout = L"hello from entrypoint with args\n", .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Container_Run_Entrypoint_Invalid_Path)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_Entrypoint_Invalid_Path)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run --rm --entrypoint /bin/does-not-exist {}", DebianImage.NameAndTag()));
result.Verify(
{.Stdout = L"", .Stderr = L"failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: exec: \"/bin/does-not-exist\": stat /bin/does-not-exist: no such file or directory: unknown\r\nError code: E_INVALIDARG\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Container_Run_Entrypoint_Detach_Lifecycle)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_Entrypoint_Detach_Lifecycle)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(
L"container run --name {} -d --entrypoint /bin/sleep {} infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = 0});
@@ -99,60 +87,46 @@ class WSLCE2EContainerRunTests
VerifyContainerIsListed(WslcContainerName, L"running");
}
TEST_METHOD(WSLCE2E_Container_Run_UserOption_NameRoot)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_UserOption_NameRoot)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run --rm -u root {} sh -c \"id -un; id -u; id -g\"", DebianImage.NameAndTag()));
result.Verify({.Stdout = L"root\n0\n0\n", .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Container_Run_UserOption_UidRoot)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_UserOption_UidRoot)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run --rm -u 0 {} id -u", DebianImage.NameAndTag()));
result.Verify({.Stdout = L"0\n", .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Container_Run_UserOption_UidGidRoot)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_UserOption_UidGidRoot)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run --rm -u 0:0 {} sh -c \"id -u; id -g\"", DebianImage.NameAndTag()));
result.Verify({.Stdout = L"0\n0\n", .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Container_Run_UserOption_UnknownUser_Fails)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_UserOption_UnknownUser_Fails)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run --rm -u user_does_not_exist {} id -u", DebianImage.NameAndTag()));
result.Verify(
{.Stderr = L"unable to find user user_does_not_exist: no matching entries in passwd file\r\nError code: E_FAIL\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Container_Run_UserOption_UnknownGroup_Fails)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_UserOption_UnknownGroup_Fails)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run --rm -u root:badgid {} id -u", DebianImage.NameAndTag()));
result.Verify({.Stderr = L"unable to find group badgid: no matching entries in group file\r\nError code: E_FAIL\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Container_Run_UserOption_NameGroupRoot)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_UserOption_NameGroupRoot)
{
WSL2_TEST_ONLY();
auto result =
RunWslc(std::format(L"container run --rm -u root:root {} sh -c \"id -un; id -u; id -g\"", DebianImage.NameAndTag()));
result.Verify({.Stdout = L"root\n0\n0\n", .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Container_Run_UserOption_NonRootUser_Succeeds)
WSLC_TEST_METHOD(WSLCE2E_Container_Run_UserOption_NonRootUser_Succeeds)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run --rm -u nobody {} sh -c \"id -un; id -u; id -g\"", DebianImage.NameAndTag()));
result.Verify({.Stdout = L"nobody\n65534\n65534\n", .Stderr = L"", .ExitCode = 0});
}

View File

@@ -44,18 +44,14 @@ class WSLCE2EContainerStopTests
return true;
}
TEST_METHOD(WSLCE2E_Container_Stop_HelpCommand)
WSLC_TEST_METHOD(WSLCE2E_Container_Stop_HelpCommand)
{
WSL2_TEST_ONLY();
auto result = RunWslc(L"container stop --help");
result.Verify({.Stdout = GetHelpMessage(), .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Container_Stop_InvalidSignal)
WSLC_TEST_METHOD(WSLCE2E_Container_Stop_InvalidSignal)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"container run --name {} {}", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = 0});
@@ -70,10 +66,8 @@ class WSLCE2EContainerStopTests
}
}
TEST_METHOD(WSLCE2E_Container_Stop_KillsRunningContainer)
WSLC_TEST_METHOD(WSLCE2E_Container_Stop_KillsRunningContainer)
{
WSL2_TEST_ONLY();
// Run a container in the background
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = 0});
@@ -91,10 +85,8 @@ class WSLCE2EContainerStopTests
VerifyContainerIsListed(containerId, L"exited");
}
TEST_METHOD(WSLCE2E_Container_Stop_ByName)
WSLC_TEST_METHOD(WSLCE2E_Container_Stop_ByName)
{
WSL2_TEST_ONLY();
// Run a container in the background
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = 0});
@@ -112,20 +104,16 @@ class WSLCE2EContainerStopTests
VerifyContainerIsListed(containerId, L"exited");
}
TEST_METHOD(WSLCE2E_Container_Stop_NotFound)
WSLC_TEST_METHOD(WSLCE2E_Container_Stop_NotFound)
{
WSL2_TEST_ONLY();
VerifyContainerIsNotListed(WslcContainerName);
auto result = RunWslc(std::format(L"container stop {} -t 0", WslcContainerName));
result.Verify({.Stderr = L"Element not found. \r\nError code: ERROR_NOT_FOUND\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Container_Stop_TargetedContainerOnly)
WSLC_TEST_METHOD(WSLCE2E_Container_Stop_TargetedContainerOnly)
{
WSL2_TEST_ONLY();
// Run first container in background
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = 0});
@@ -151,10 +139,8 @@ class WSLCE2EContainerStopTests
VerifyContainerIsListed(secondContainerId, L"running");
}
TEST_METHOD(WSLCE2E_Container_Stop_SignalByName)
WSLC_TEST_METHOD(WSLCE2E_Container_Stop_SignalByName)
{
WSL2_TEST_ONLY();
// Run a container in the background
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = 0});
@@ -172,10 +158,8 @@ class WSLCE2EContainerStopTests
VerifyContainerIsListed(containerId, L"exited");
}
TEST_METHOD(WSLCE2E_Container_Stop_InvalidSignalName)
WSLC_TEST_METHOD(WSLCE2E_Container_Stop_InvalidSignalName)
{
WSL2_TEST_ONLY();
// Run a container in the background
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = 0});
@@ -193,10 +177,8 @@ class WSLCE2EContainerStopTests
VerifyContainerIsListed(containerId, L"running");
}
TEST_METHOD(WSLCE2E_Container_Stop_InvalidTimeout)
WSLC_TEST_METHOD(WSLCE2E_Container_Stop_InvalidTimeout)
{
WSL2_TEST_ONLY();
// Run a container in the background
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = 0});
@@ -234,10 +216,8 @@ class WSLCE2EContainerStopTests
}
}
TEST_METHOD(WSLCE2E_Container_Stop_ValidTimeoutNegativeOne)
WSLC_TEST_METHOD(WSLCE2E_Container_Stop_ValidTimeoutNegativeOne)
{
WSL2_TEST_ONLY();
// Run a container in the background
auto result = RunWslc(std::format(L"container run -d --name {} {} sleep infinity", WslcContainerName, DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = 0});

View File

@@ -34,15 +34,13 @@ class WSLCE2EContainerTests
return true;
}
TEST_METHOD(WSLCE2E_Container_HelpCommand)
WSLC_TEST_METHOD(WSLCE2E_Container_HelpCommand)
{
WSL2_TEST_ONLY();
RunWslc(L"container --help").Verify({.Stdout = GetHelpMessage(), .Stderr = L"", .ExitCode = S_OK});
}
TEST_METHOD(WSLCE2E_Container_InvalidCommand_DisplaysErrorMessage)
WSLC_TEST_METHOD(WSLCE2E_Container_InvalidCommand_DisplaysErrorMessage)
{
WSL2_TEST_ONLY();
RunWslc(L"container INVALID_CMD").Verify({.Stdout = GetHelpMessage(), .Stderr = L"Unrecognized command: 'INVALID_CMD'\r\n", .ExitCode = 1});
}

View File

@@ -39,34 +39,28 @@ class WSLCE2EGlobalTests
return true;
}
TEST_METHOD(WSLCE2E_HelpCommand)
WSLC_TEST_METHOD(WSLCE2E_HelpCommand)
{
WSL2_TEST_ONLY();
RunWslcAndVerify(L"--help", {.Stdout = GetHelpMessage(), .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_InvalidCommand_DisplaysErrorMessage)
WSLC_TEST_METHOD(WSLCE2E_InvalidCommand_DisplaysErrorMessage)
{
WSL2_TEST_ONLY();
RunWslcAndVerify(L"INVALID_CMD", {.Stdout = GetHelpMessage(), .Stderr = L"Unrecognized command: 'INVALID_CMD'\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_VersionCommand)
WSLC_TEST_METHOD(WSLCE2E_VersionCommand)
{
WSL2_TEST_ONLY();
RunWslcAndVerify(L"version", {.Stdout = GetVersionMessage(), .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_VersionFlag)
WSLC_TEST_METHOD(WSLCE2E_VersionFlag)
{
WSL2_TEST_ONLY();
RunWslcAndVerify(L"--version", {.Stdout = GetVersionMessage(), .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Session_DefaultElevated)
WSLC_TEST_METHOD(WSLCE2E_Session_DefaultElevated)
{
WSL2_TEST_ONLY();
// Run container list to create the default elevated session
auto result = RunWslc(L"container list", ElevationType::Elevated);
result.Verify({.Stderr = L"", .ExitCode = S_OK});
@@ -79,10 +73,8 @@ class WSLCE2EGlobalTests
VERIFY_IS_TRUE(result.Stdout->find(L"wslc-cli-admin") != std::wstring::npos);
}
TEST_METHOD(WSLCE2E_Session_DefaultNonElevated)
WSLC_TEST_METHOD(WSLCE2E_Session_DefaultNonElevated)
{
WSL2_TEST_ONLY();
// Run container list non-elevated to create the default non-elevated session
auto result = RunWslc(L"container list", ElevationType::NonElevated);
result.Verify({.Stderr = L"", .ExitCode = S_OK});
@@ -97,10 +89,8 @@ class WSLCE2EGlobalTests
VERIFY_IS_TRUE(result.Stdout->find(L"wslc-cli\r\n") != std::wstring::npos);
}
TEST_METHOD(WSLCE2E_Session_NonElevatedCannotAccessAdminSession)
WSLC_TEST_METHOD(WSLCE2E_Session_NonElevatedCannotAccessAdminSession)
{
WSL2_TEST_ONLY();
// First ensure admin session is created by running container list.
auto result = RunWslc(L"container list", ElevationType::Elevated);
result.Verify({.Stderr = L"", .ExitCode = S_OK});
@@ -112,10 +102,8 @@ class WSLCE2EGlobalTests
result.Verify({.Stderr = L"The requested operation requires elevation. \r\nError code: ERROR_ELEVATION_REQUIRED\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Session_ElevatedCanAccessNonElevatedSession)
WSLC_TEST_METHOD(WSLCE2E_Session_ElevatedCanAccessNonElevatedSession)
{
WSL2_TEST_ONLY();
// First ensure non-elevated session is created by running container list.
auto result = RunWslc(L"container list", ElevationType::NonElevated);
result.Verify({.Stderr = L"", .ExitCode = S_OK});
@@ -127,10 +115,8 @@ class WSLCE2EGlobalTests
result.Verify({.Stderr = L"", .ExitCode = S_OK});
}
TEST_METHOD(WSLCE2E_Session_CreateMixedElevation_Fails)
WSLC_TEST_METHOD(WSLCE2E_Session_CreateMixedElevation_Fails)
{
WSL2_TEST_ONLY();
EnsureSessionIsTerminated(L"wslc-cli");
EnsureSessionIsTerminated(L"wslc-cli-admin");
@@ -143,10 +129,8 @@ class WSLCE2EGlobalTests
result.Verify({.Stderr = L"Element not found. \r\nError code: ERROR_NOT_FOUND\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Session_Terminate_Implicit)
WSLC_TEST_METHOD(WSLCE2E_Session_Terminate_Implicit)
{
WSL2_TEST_ONLY();
// Run container list to create the default session if it does not already exist
auto result = RunWslc(L"container list");
result.Verify({.Stderr = L"", .ExitCode = S_OK});
@@ -190,10 +174,8 @@ class WSLCE2EGlobalTests
VERIFY_IS_FALSE(result.Stdout->find(L"wslc-cli\r\n") != std::wstring::npos);
}
TEST_METHOD(WSLCE2E_Session_Terminate_Explicit)
WSLC_TEST_METHOD(WSLCE2E_Session_Terminate_Explicit)
{
WSL2_TEST_ONLY();
// Run container list to create the default session if it does not already exist
auto result = RunWslc(L"container list");
result.Verify({.Stderr = L"", .ExitCode = S_OK});
@@ -237,10 +219,8 @@ class WSLCE2EGlobalTests
VERIFY_IS_FALSE(result.Stdout->find(L"wslc-cli\r\n") != std::wstring::npos);
}
TEST_METHOD(WSLCE2E_Session_Terminate_MixedElevation)
WSLC_TEST_METHOD(WSLCE2E_Session_Terminate_MixedElevation)
{
WSL2_TEST_ONLY();
// Run container list to create the default sessions if they do not already exist.
auto result = RunWslc(L"container list", ElevationType::Elevated);
result.Verify({.Stderr = L"", .ExitCode = S_OK});
@@ -269,10 +249,8 @@ class WSLCE2EGlobalTests
VERIFY_IS_FALSE(result.Stdout->find(L"wslc-cli\r\n") != std::wstring::npos);
}
TEST_METHOD(WSLCE2E_Session_Targeting)
WSLC_TEST_METHOD(WSLCE2E_Session_Targeting)
{
WSL2_TEST_ONLY();
// Generate a unique session name to avoid conflicts with previous runs or concurrent tests.
// Use only a short portion of the GUID to avoid MAX_PATH issues.
GUID sessionGuid;
@@ -315,10 +293,8 @@ class WSLCE2EGlobalTests
VerifyContainerIsNotListed(L"test-cont");
}
TEST_METHOD(WSLCE2E_Session_Shell)
WSLC_TEST_METHOD(WSLCE2E_Session_Shell)
{
WSL2_TEST_ONLY();
// Ensure sessions are created by running container list elevated and non-elevated.
auto result = RunWslc(L"container list", ElevationType::NonElevated);
result.Verify({.Stderr = L"", .ExitCode = S_OK});

View File

@@ -49,10 +49,8 @@ class WSLCE2EImageBuildTests
return true;
}
TEST_METHOD(WSLCE2E_Image_Build_EmptyContextDirectory_Success)
WSLC_TEST_METHOD(WSLCE2E_Image_Build_EmptyContextDirectory_Success)
{
WSL2_TEST_ONLY();
auto testRoot = std::filesystem::current_path() / L"wslc-e2e-build-empty-context";
auto cleanup = SetupTestDirectory(testRoot);
@@ -74,10 +72,8 @@ class WSLCE2EImageBuildTests
VERIFY_ARE_EQUAL(BuiltImage.NameAndTag(), wsl::shared::string::MultiByteToWide(inspectData.RepoTags.value()[0]));
}
TEST_METHOD(WSLCE2E_Image_Build_BuildArgsFileAndMultipleTags_Success)
WSLC_TEST_METHOD(WSLCE2E_Image_Build_BuildArgsFileAndMultipleTags_Success)
{
WSL2_TEST_ONLY();
auto testRoot = std::filesystem::current_path() / L"wslc-e2e-build-args-tags";
auto cleanup = SetupTestDirectory(testRoot);
@@ -125,22 +121,18 @@ class WSLCE2EImageBuildTests
VERIFY_ARE_EQUAL(std::string("wslc_e2e_test"), it->second);
}
TEST_METHOD(WSLCE2E_Image_Build_DockerfileInContextDir_Success)
WSLC_TEST_METHOD(WSLCE2E_Image_Build_DockerfileInContextDir_Success)
{
WSL2_TEST_ONLY();
BuildFromContextFile(L"Dockerfile", BuiltImageDockerfile);
}
TEST_METHOD(WSLCE2E_Image_Build_ContainerfileInContextDir_Success)
WSLC_TEST_METHOD(WSLCE2E_Image_Build_ContainerfileInContextDir_Success)
{
WSL2_TEST_ONLY();
BuildFromContextFile(L"Containerfile", BuiltImageContainerfile);
}
TEST_METHOD(WSLCE2E_Image_Build_BothDockerfileAndContainerfile_Fails)
WSLC_TEST_METHOD(WSLCE2E_Image_Build_BothDockerfileAndContainerfile_Fails)
{
WSL2_TEST_ONLY();
auto testRoot = std::filesystem::current_path() / L"wslc-e2e-build-both-files";
auto cleanup = SetupTestDirectory(testRoot);
@@ -154,10 +146,8 @@ class WSLCE2EImageBuildTests
.ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Image_Build_NeitherDockerfileNorContainerfile_Fails)
WSLC_TEST_METHOD(WSLCE2E_Image_Build_NeitherDockerfileNorContainerfile_Fails)
{
WSL2_TEST_ONLY();
auto testRoot = std::filesystem::current_path() / L"wslc-e2e-build-no-files";
auto cleanup = SetupTestDirectory(testRoot);
@@ -168,10 +158,8 @@ class WSLCE2EImageBuildTests
.ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Image_Build_ContainerfileAccessDenied_Fails)
WSLC_TEST_METHOD(WSLCE2E_Image_Build_ContainerfileAccessDenied_Fails)
{
WSL2_TEST_ONLY();
auto testRoot = std::filesystem::current_path() / L"wslc-e2e-build-access-denied";
auto cleanup = SetupTestDirectory(testRoot);

View File

@@ -37,35 +37,27 @@ class WSLCE2EImageDeleteTests
return true;
}
TEST_METHOD(WSLCE2E_Image_Delete_HelpCommand)
WSLC_TEST_METHOD(WSLCE2E_Image_Delete_HelpCommand)
{
WSL2_TEST_ONLY();
auto result = RunWslc(L"image delete --help");
result.Verify({.Stdout = GetHelpMessage(), .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Image_Delete_ImageNotFound)
WSLC_TEST_METHOD(WSLCE2E_Image_Delete_ImageNotFound)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"image delete {}", InvalidImage.Name));
auto errorMessage = std::format(L"No such image: {}\r\nError code: WSLC_E_IMAGE_NOT_FOUND\r\n", InvalidImage.NameAndTag());
result.Verify({.Stdout = L"", .Stderr = errorMessage, .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Image_Delete_MissingImageName)
WSLC_TEST_METHOD(WSLCE2E_Image_Delete_MissingImageName)
{
WSL2_TEST_ONLY();
auto result = RunWslc(L"image delete");
result.Verify({.Stdout = GetHelpMessage(), .Stderr = L"Required argument not provided: 'image'\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Image_Delete_UnusedImage_Success)
WSLC_TEST_METHOD(WSLCE2E_Image_Delete_UnusedImage_Success)
{
WSL2_TEST_ONLY();
EnsureImageIsLoaded(DebianImage);
VerifyImageIsNotUsed(DebianImage);
@@ -73,10 +65,8 @@ class WSLCE2EImageDeleteTests
result.Verify({.Stdout = L"", .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Image_Delete_UsedImage_Failure)
WSLC_TEST_METHOD(WSLCE2E_Image_Delete_UsedImage_Failure)
{
WSL2_TEST_ONLY();
EnsureImageIsLoaded(DebianImage);
VerifyImageIsNotUsed(DebianImage);
@@ -100,10 +90,8 @@ class WSLCE2EImageDeleteTests
result.Verify({.Stdout = L"", .Stderr = errorMessage, .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Image_DeleteForce_UsedImage_Success)
WSLC_TEST_METHOD(WSLCE2E_Image_DeleteForce_UsedImage_Success)
{
WSL2_TEST_ONLY();
EnsureImageIsLoaded(DebianImage);
VerifyImageIsNotUsed(DebianImage);
@@ -116,10 +104,8 @@ class WSLCE2EImageDeleteTests
result.Verify({.Stdout = L"", .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Image_DeleteNoPrune)
WSLC_TEST_METHOD(WSLCE2E_Image_DeleteNoPrune)
{
WSL2_TEST_ONLY();
// TODO: Implement once 'image tag' is implemented
SKIP_TEST_NOT_IMPL();
}

View File

@@ -36,35 +36,27 @@ class WSLCE2EImageInspectTests
return true;
}
TEST_METHOD(WSLCE2E_Image_Inspect_HelpCommand)
WSLC_TEST_METHOD(WSLCE2E_Image_Inspect_HelpCommand)
{
WSL2_TEST_ONLY();
auto result = RunWslc(L"image inspect --help");
result.Verify({.Stdout = GetHelpMessage(), .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Image_Inspect_MissingImageName)
WSLC_TEST_METHOD(WSLCE2E_Image_Inspect_MissingImageName)
{
WSL2_TEST_ONLY();
auto result = RunWslc(L"image inspect");
result.Verify({.Stdout = GetHelpMessage(), .Stderr = L"Required argument not provided: 'image'\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Image_Inspect_ImageNotFound)
WSLC_TEST_METHOD(WSLCE2E_Image_Inspect_ImageNotFound)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"image inspect {}", InvalidImage.NameAndTag()));
auto errorMessage = std::format(L"No such image: {}\r\nError code: WSLC_E_IMAGE_NOT_FOUND\r\n", InvalidImage.NameAndTag());
result.Verify({.Stdout = L"", .Stderr = errorMessage, .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Image_Inspect_Success)
WSLC_TEST_METHOD(WSLCE2E_Image_Inspect_Success)
{
WSL2_TEST_ONLY();
auto result = RunWslc(std::format(L"image inspect {}", DebianImage.NameAndTag()));
result.Verify({.Stderr = L"", .ExitCode = 0});
auto inspectData =

View File

@@ -40,17 +40,14 @@ class WSLCE2EImageListTests
return true;
}
TEST_METHOD(WSLCE2E_Image_List_HelpCommand)
WSLC_TEST_METHOD(WSLCE2E_Image_List_HelpCommand)
{
WSL2_TEST_ONLY();
const auto result = RunWslc(L"image list --help");
result.Verify({.Stdout = GetHelpMessage(), .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Image_List_DisplayLoadedImage)
WSLC_TEST_METHOD(WSLCE2E_Image_List_DisplayLoadedImage)
{
WSL2_TEST_ONLY();
const auto result = RunWslc(L"image list");
result.Verify({.Stderr = L"", .ExitCode = 0});
for (const auto& line : result.GetStdoutLines())
@@ -64,10 +61,8 @@ class WSLCE2EImageListTests
VERIFY_FAIL(L"Failed to find the loaded image in the output");
}
TEST_METHOD(WSLCE2E_Image_List_QuietOption_OutputsNamesOnly)
WSLC_TEST_METHOD(WSLCE2E_Image_List_QuietOption_OutputsNamesOnly)
{
WSL2_TEST_ONLY();
const auto result = RunWslc(L"image list --quiet");
result.Verify({.Stderr = L"", .ExitCode = 0});
@@ -84,18 +79,14 @@ class WSLCE2EImageListTests
VERIFY_IS_TRUE(imageFound);
}
TEST_METHOD(WSLCE2E_Image_List_InvalidFormatOption)
WSLC_TEST_METHOD(WSLCE2E_Image_List_InvalidFormatOption)
{
WSL2_TEST_ONLY();
const auto result = RunWslc(L"image list --format invalid");
result.Verify({.Stderr = L"Invalid format value: invalid is not a recognized format type. Supported format types are: json, table.\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Image_List_JsonFormat)
WSLC_TEST_METHOD(WSLCE2E_Image_List_JsonFormat)
{
WSL2_TEST_ONLY();
const auto result = RunWslc(L"image list --format json");
result.Verify({.Stderr = L"", .ExitCode = 0});
@@ -117,10 +108,8 @@ class WSLCE2EImageListTests
VERIFY_ARE_NOT_EQUAL(imageNames.end(), std::find(imageNames.begin(), imageNames.end(), AlpineImage.NameAndTag()));
}
TEST_METHOD(WSLCE2E_Image_List_TableFormat_HasExpectedColumns)
WSLC_TEST_METHOD(WSLCE2E_Image_List_TableFormat_HasExpectedColumns)
{
WSL2_TEST_ONLY();
const auto result = RunWslc(L"image list");
result.Verify({.Stderr = L"", .ExitCode = 0});

View File

@@ -42,42 +42,32 @@ class WSLCE2EImageSaveTests
return true;
}
TEST_METHOD(WSLCE2E_Image_Save_HelpCommand)
WSLC_TEST_METHOD(WSLCE2E_Image_Save_HelpCommand)
{
WSL2_TEST_ONLY();
auto result = RunWslc(L"image save --help");
result.Verify({.Stdout = GetHelpMessage(), .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Image_Save_MissingImageName)
WSLC_TEST_METHOD(WSLCE2E_Image_Save_MissingImageName)
{
WSL2_TEST_ONLY();
const auto result = RunWslc(std::format(L"image save --output \"{}\"", SavedArchivePath.wstring()));
result.Verify({.Stdout = GetHelpMessage(), .Stderr = L"Required argument not provided: 'image'\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Image_Save_MissingOutputPath)
WSLC_TEST_METHOD(WSLCE2E_Image_Save_MissingOutputPath)
{
WSL2_TEST_ONLY();
const auto result = RunWslc(std::format(L"image save {}", DebianImage.NameAndTag()));
result.Verify({.Stderr = L"Required argument not provided: 'output'\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Image_Save_ImageNotFound)
WSLC_TEST_METHOD(WSLCE2E_Image_Save_ImageNotFound)
{
WSL2_TEST_ONLY();
const auto result = RunWslc(std::format(L"image save --output \"{}\" {}", SavedArchivePath.wstring(), InvalidImage.NameAndTag()));
result.Verify({.Stdout = L"", .Stderr = L"reference does not exist\r\nError code: E_FAIL\r\n", .ExitCode = 1});
}
TEST_METHOD(WSLCE2E_Image_Save_Success)
WSLC_TEST_METHOD(WSLCE2E_Image_Save_Success)
{
WSL2_TEST_ONLY();
const auto result = RunWslc(std::format(L"image save --output \"{}\" {}", SavedArchivePath.wstring(), DebianImage.NameAndTag()));
result.Verify({.Stdout = L"", .Stderr = L"", .ExitCode = 0});
@@ -87,10 +77,8 @@ class WSLCE2EImageSaveTests
VERIFY_ARE_EQUAL(sourceFileSize, archiveFileSize);
}
TEST_METHOD(WSLCE2E_Image_Save_Load)
WSLC_TEST_METHOD(WSLCE2E_Image_Save_Load)
{
WSL2_TEST_ONLY();
// Save source image
auto saveResult = RunWslc(std::format(L"image save --output \"{}\" {}", SavedArchivePath.wstring(), DebianImage.NameAndTag()));
saveResult.Verify({.Stdout = L"", .Stderr = L"", .ExitCode = 0});

View File

@@ -24,23 +24,20 @@ class WSLCE2EImageTests
{
WSLC_TEST_CLASS(WSLCE2EImageTests)
TEST_METHOD(WSLCE2E_Image_HelpCommand)
WSLC_TEST_METHOD(WSLCE2E_Image_HelpCommand)
{
WSL2_TEST_ONLY();
auto result = RunWslc(L"image --help");
result.Verify({.Stdout = GetHelpMessage(), .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Image_NoSubcommand_ShowsHelp)
WSLC_TEST_METHOD(WSLCE2E_Image_NoSubcommand_ShowsHelp)
{
WSL2_TEST_ONLY();
auto result = RunWslc(L"image");
result.Verify({.Stdout = GetHelpMessage(), .Stderr = L"", .ExitCode = 0});
}
TEST_METHOD(WSLCE2E_Image_InvalidCommand_DisplaysErrorMessage)
WSLC_TEST_METHOD(WSLCE2E_Image_InvalidCommand_DisplaysErrorMessage)
{
WSL2_TEST_ONLY();
auto result = RunWslc(L"image INVALID_CMD");
result.Verify({.Stdout = GetHelpMessage(), .Stderr = L"Unrecognized command: 'INVALID_CMD'\r\n", .ExitCode = 1});
}

View File

@@ -38,10 +38,8 @@ class WSLCE2ESessionEnterTests
return true;
}
TEST_METHOD(WSLCE2E_SessionEnter_WithName)
WSLC_TEST_METHOD(WSLCE2E_SessionEnter_WithName)
{
WSL2_TEST_ONLY();
constexpr auto sessionName = L"test-wslc-session-enter";
// Run an interactive session enter with an explicit name.
@@ -73,10 +71,8 @@ class WSLCE2ESessionEnterTests
VERIFY_IS_FALSE(listResult.Stdout->find(sessionName) != std::wstring::npos);
}
TEST_METHOD(WSLCE2E_SessionEnter_WithoutName_GeneratesGuid)
WSLC_TEST_METHOD(WSLCE2E_SessionEnter_WithoutName_GeneratesGuid)
{
WSL2_TEST_ONLY();
auto session = RunWslcInteractive(std::format(L"session enter \"{}\"", SessionOptions::GetStoragePath()));
VERIFY_IS_TRUE(session.IsRunning(), L"Session should be running");
@@ -86,10 +82,8 @@ class WSLCE2ESessionEnterTests
VERIFY_ARE_EQUAL(session.Exit(), 0);
}
TEST_METHOD(WSLCE2E_SessionEnter_StoragePathNotFound)
WSLC_TEST_METHOD(WSLCE2E_SessionEnter_StoragePathNotFound)
{
WSL2_TEST_ONLY();
auto result = RunWslc(L"session enter does-not-exist");
result.Verify({
.Stderr = L"The system cannot find the path specified. \r\nError code: ERROR_PATH_NOT_FOUND\r\n",

View File

@@ -48,7 +48,25 @@ if ($Fast)
$SetupScript = $null
}
te.exe $TestDllPath /p:SetupScript=$SetupScript /p:Version=$Version /p:DistroPath=$DistroPath /p:TestDataPath=$TestDataPath /p:Package=$Package /p:UnitTestsPath=$UnitTestsPath /p:PullRequest=$PullRequest /p:AllowUnsigned=1 @TeArgs
$HasUserSelection = $false
foreach ($arg in $TeArgs)
{
if ($arg -like '/name:*' -or $arg -like '/select:*' -or $arg -like '-name:*' -or $arg -like '-select:*')
{
$HasUserSelection = $true
break
}
}
if ($HasUserSelection)
{
te.exe $TestDllPath /p:SetupScript=$SetupScript /p:Version=$Version /p:DistroPath=$DistroPath /p:TestDataPath=$TestDataPath /p:Package=$Package /p:UnitTestsPath=$UnitTestsPath /p:PullRequest=$PullRequest /p:AllowUnsigned=1 @TeArgs
}
else
{
$env:TAEF_SELECT = "@WSLVersion='$Version' or not(@WSLVersion='*')"
te.exe $TestDllPath /p:SetupScript=$SetupScript /p:Version=$Version /p:DistroPath=$DistroPath /p:TestDataPath=$TestDataPath /p:Package=$Package /p:UnitTestsPath=$UnitTestsPath /p:PullRequest=$PullRequest /p:AllowUnsigned=1 @TeArgs --% /select:"%TAEF_SELECT%"
}
if (!$?)
{