#include "pch.h" #include "TestHelpers.h" #include using namespace Microsoft::VisualStudio::CppUnitTestFramework; using namespace ProcessWaiter; namespace UnitTestsCommonUtils { TEST_CLASS(ProcessWaiterTests) { public: TEST_METHOD(OnProcessTerminate_InvalidPid_DoesNotCrash) { std::atomic called{ false }; // Use a very unlikely PID (negative value as string will fail conversion) OnProcessTerminate(L"invalid", [&called](DWORD) { called = true; }); // Wait briefly std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Should not crash, callback may or may not be called depending on implementation Assert::IsTrue(true); } TEST_METHOD(OnProcessTerminate_NonExistentPid_DoesNotCrash) { std::atomic called{ false }; // Use a PID that likely doesn't exist OnProcessTerminate(L"999999999", [&called](DWORD) { called = true; }); // Wait briefly std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Should not crash Assert::IsTrue(true); } TEST_METHOD(OnProcessTerminate_ZeroPid_DoesNotCrash) { std::atomic called{ false }; OnProcessTerminate(L"0", [&called](DWORD) { called = true; }); std::this_thread::sleep_for(std::chrono::milliseconds(100)); Assert::IsTrue(true); } TEST_METHOD(OnProcessTerminate_CurrentProcessPid_DoesNotTerminate) { std::atomic called{ false }; // Use current process PID - it shouldn't terminate during test std::wstring pid = std::to_wstring(GetCurrentProcessId()); OnProcessTerminate(pid, [&called](DWORD) { called = true; }); // Wait briefly - current process should not terminate std::this_thread::sleep_for(std::chrono::milliseconds(200)); // Callback should not have been called since process is still running Assert::IsFalse(called); } TEST_METHOD(OnProcessTerminate_EmptyCallback_DoesNotCrash) { // Test with an empty function OnProcessTerminate(L"999999999", std::function()); std::this_thread::sleep_for(std::chrono::milliseconds(100)); Assert::IsTrue(true); } TEST_METHOD(OnProcessTerminate_MultipleCallsForSamePid_DoesNotCrash) { std::atomic counter{ 0 }; std::wstring pid = std::to_wstring(GetCurrentProcessId()); // Multiple waits on same (running) process for (int i = 0; i < 5; ++i) { OnProcessTerminate(pid, [&counter](DWORD) { counter++; }); } std::this_thread::sleep_for(std::chrono::milliseconds(200)); // None should have been called since process is running Assert::AreEqual(0, counter.load()); } TEST_METHOD(OnProcessTerminate_NegativeNumberString_DoesNotCrash) { std::atomic called{ false }; OnProcessTerminate(L"-1", [&called](DWORD) { called = true; }); std::this_thread::sleep_for(std::chrono::milliseconds(100)); Assert::IsTrue(true); } TEST_METHOD(OnProcessTerminate_LargeNumber_DoesNotCrash) { std::atomic called{ false }; OnProcessTerminate(L"18446744073709551615", [&called](DWORD) { called = true; }); std::this_thread::sleep_for(std::chrono::milliseconds(100)); Assert::IsTrue(true); } }; }