Skip to content
Open
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 126 additions & 0 deletions test/windows/WSLCTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,68 @@ class WSLCTests

ValidateCOMErrorMessage(L"archive/tar: invalid tar header");
}

// Validate that LoadImage is aborted when the input data source pipe is broken and the session terminates.
// This simulates the scenario where the calling process exits during a LoadImage operation.
{
wil::unique_handle pipeRead;
wil::unique_handle pipeWrite;
VERIFY_WIN32_BOOL_SUCCEEDED(CreatePipe(&pipeRead, &pipeWrite, nullptr, 2));
Comment thread
yao-msft marked this conversation as resolved.
Comment thread
yao-msft marked this conversation as resolved.
Outdated
Comment thread
yao-msft marked this conversation as resolved.

std::promise<HRESULT> processExitResult;
wil::unique_event testCompleted{wil::EventOptions::ManualReset};
std::thread operationThread([&]() {
processExitResult.set_value(m_defaultSession->LoadImage(ToCOMInputHandle(pipeRead.get()), nullptr, 1024 * 1024));
Comment thread
yao-msft marked this conversation as resolved.
Outdated
WI_ASSERT(testCompleted.is_signaled());
});

auto threadCleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() { operationThread.join(); });

// Write some data to validate that the service has started reading from the pipe (pipe buffer is 2 bytes).
DWORD bytesWritten{};
VERIFY_WIN32_BOOL_SUCCEEDED(WriteFile(pipeWrite.get(), "data", 4, &bytesWritten, nullptr));
Comment thread
yao-msft marked this conversation as resolved.
Outdated

Comment thread
yao-msft marked this conversation as resolved.
testCompleted.SetEvent();
Comment thread
yao-msft marked this conversation as resolved.
Outdated

Comment thread
yao-msft marked this conversation as resolved.
Outdated
// Close the write end of the pipe to simulate the input process exiting,
// then terminate the session to cancel the synchronous IO in the service.
pipeWrite.reset();
Comment thread
yao-msft marked this conversation as resolved.
VERIFY_SUCCEEDED(m_defaultSession->Terminate());

auto restore = ResetTestSession();
Comment thread
yao-msft marked this conversation as resolved.
Outdated
Comment thread
yao-msft marked this conversation as resolved.
Outdated

auto hr = processExitResult.get_future().get();
VERIFY_IS_TRUE(hr == E_ABORT || hr == HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED));
Comment thread
yao-msft marked this conversation as resolved.
Outdated
}

// Validate that LoadImage is aborted when the session terminates.
{
wil::unique_handle pipeRead;
wil::unique_handle pipeWrite;
VERIFY_WIN32_BOOL_SUCCEEDED(CreatePipe(&pipeRead, &pipeWrite, nullptr, 2));

std::promise<HRESULT> terminateResult;
wil::unique_event testCompleted{wil::EventOptions::ManualReset};
std::thread operationThread([&]() {
terminateResult.set_value(m_defaultSession->LoadImage(ToCOMInputHandle(pipeRead.get()), nullptr, 1024 * 1024));
WI_ASSERT(testCompleted.is_signaled());
});

auto threadCleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() { operationThread.join(); });

// Write some data to validate that the service has started reading from the pipe (pipe buffer is 2 bytes).
DWORD bytesWritten{};
VERIFY_WIN32_BOOL_SUCCEEDED(WriteFile(pipeWrite.get(), "data", 4, &bytesWritten, nullptr));

testCompleted.SetEvent();

Comment thread
yao-msft marked this conversation as resolved.
VERIFY_SUCCEEDED(m_defaultSession->Terminate());

auto restore = ResetTestSession();

auto hr = terminateResult.get_future().get();
Comment thread
yao-msft marked this conversation as resolved.
VERIFY_IS_TRUE(hr == E_ABORT || hr == HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED));
Comment thread
yao-msft marked this conversation as resolved.
}
}

WSLC_TEST_METHOD(ImportImage)
Expand Down Expand Up @@ -1049,6 +1111,70 @@ class WSLCTests

ValidateCOMErrorMessage(L"archive/tar: invalid tar header");
}

// Validate that ImportImage is aborted when the input data source pipe is broken and the session terminates.
// This simulates the scenario where the calling process exits during an ImportImage operation.
{
wil::unique_handle pipeRead;
wil::unique_handle pipeWrite;
VERIFY_WIN32_BOOL_SUCCEEDED(CreatePipe(&pipeRead, &pipeWrite, nullptr, 2));

std::promise<HRESULT> processExitResult;
wil::unique_event testCompleted{wil::EventOptions::ManualReset};
std::thread operationThread([&]() {
processExitResult.set_value(
m_defaultSession->ImportImage(ToCOMInputHandle(pipeRead.get()), "process-exit:test", nullptr, 1024 * 1024));
Comment thread
yao-msft marked this conversation as resolved.
Outdated
WI_ASSERT(testCompleted.is_signaled());
});

auto threadCleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() { operationThread.join(); });

// Write some data to validate that the service has started reading from the pipe (pipe buffer is 2 bytes).
DWORD bytesWritten{};
VERIFY_WIN32_BOOL_SUCCEEDED(WriteFile(pipeWrite.get(), "data", 4, &bytesWritten, nullptr));

testCompleted.SetEvent();

// Close the write end of the pipe to simulate the input process exiting,
// then terminate the session to cancel the synchronous IO in the service.
pipeWrite.reset();
VERIFY_SUCCEEDED(m_defaultSession->Terminate());

auto restore = ResetTestSession();
Comment thread
yao-msft marked this conversation as resolved.
Outdated

auto hr = processExitResult.get_future().get();
VERIFY_IS_TRUE(hr == E_ABORT || hr == HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED));
}

// Validate that ImportImage is aborted when the session terminates.
{
wil::unique_handle pipeRead;
wil::unique_handle pipeWrite;
VERIFY_WIN32_BOOL_SUCCEEDED(CreatePipe(&pipeRead, &pipeWrite, nullptr, 2));

std::promise<HRESULT> terminateResult;
wil::unique_event testCompleted{wil::EventOptions::ManualReset};
std::thread operationThread([&]() {
terminateResult.set_value(
m_defaultSession->ImportImage(ToCOMInputHandle(pipeRead.get()), "session-terminate:test", nullptr, 1024 * 1024));
WI_ASSERT(testCompleted.is_signaled());
});

auto threadCleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() { operationThread.join(); });

// Write some data to validate that the service has started reading from the pipe (pipe buffer is 2 bytes).
DWORD bytesWritten{};
VERIFY_WIN32_BOOL_SUCCEEDED(WriteFile(pipeWrite.get(), "data", 4, &bytesWritten, nullptr));

testCompleted.SetEvent();

VERIFY_SUCCEEDED(m_defaultSession->Terminate());

auto restore = ResetTestSession();

auto hr = terminateResult.get_future().get();
VERIFY_IS_TRUE(hr == E_ABORT || hr == HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED));
}
}

WSLC_TEST_METHOD(DeleteImage)
Expand Down
Loading