ProcessWaiter.Tests.cpp
1 #include "pch.h" 2 #include "TestHelpers.h" 3 #include <ProcessWaiter.h> 4 5 using namespace Microsoft::VisualStudio::CppUnitTestFramework; 6 using namespace ProcessWaiter; 7 8 namespace UnitTestsCommonUtils 9 { 10 TEST_CLASS(ProcessWaiterTests) 11 { 12 public: 13 TEST_METHOD(OnProcessTerminate_InvalidPid_DoesNotCrash) 14 { 15 std::atomic<bool> called{ false }; 16 17 // Use a very unlikely PID (negative value as string will fail conversion) 18 OnProcessTerminate(L"invalid", [&called](DWORD) { 19 called = true; 20 }); 21 22 // Wait briefly 23 std::this_thread::sleep_for(std::chrono::milliseconds(100)); 24 25 // Should not crash, callback may or may not be called depending on implementation 26 Assert::IsTrue(true); 27 } 28 29 TEST_METHOD(OnProcessTerminate_NonExistentPid_DoesNotCrash) 30 { 31 std::atomic<bool> called{ false }; 32 33 // Use a PID that likely doesn't exist 34 OnProcessTerminate(L"999999999", [&called](DWORD) { 35 called = true; 36 }); 37 38 // Wait briefly 39 std::this_thread::sleep_for(std::chrono::milliseconds(100)); 40 41 // Should not crash 42 Assert::IsTrue(true); 43 } 44 45 TEST_METHOD(OnProcessTerminate_ZeroPid_DoesNotCrash) 46 { 47 std::atomic<bool> called{ false }; 48 49 OnProcessTerminate(L"0", [&called](DWORD) { 50 called = true; 51 }); 52 53 std::this_thread::sleep_for(std::chrono::milliseconds(100)); 54 Assert::IsTrue(true); 55 } 56 57 TEST_METHOD(OnProcessTerminate_CurrentProcessPid_DoesNotTerminate) 58 { 59 std::atomic<bool> called{ false }; 60 61 // Use current process PID - it shouldn't terminate during test 62 std::wstring pid = std::to_wstring(GetCurrentProcessId()); 63 64 OnProcessTerminate(pid, [&called](DWORD) { 65 called = true; 66 }); 67 68 // Wait briefly - current process should not terminate 69 std::this_thread::sleep_for(std::chrono::milliseconds(200)); 70 71 // Callback should not have been called since process is still running 72 Assert::IsFalse(called); 73 } 74 75 TEST_METHOD(OnProcessTerminate_EmptyCallback_DoesNotCrash) 76 { 77 // Test with an empty function 78 OnProcessTerminate(L"999999999", std::function<void(DWORD)>()); 79 80 std::this_thread::sleep_for(std::chrono::milliseconds(100)); 81 Assert::IsTrue(true); 82 } 83 84 TEST_METHOD(OnProcessTerminate_MultipleCallsForSamePid_DoesNotCrash) 85 { 86 std::atomic<int> counter{ 0 }; 87 std::wstring pid = std::to_wstring(GetCurrentProcessId()); 88 89 // Multiple waits on same (running) process 90 for (int i = 0; i < 5; ++i) 91 { 92 OnProcessTerminate(pid, [&counter](DWORD) { 93 counter++; 94 }); 95 } 96 97 std::this_thread::sleep_for(std::chrono::milliseconds(200)); 98 99 // None should have been called since process is running 100 Assert::AreEqual(0, counter.load()); 101 } 102 103 TEST_METHOD(OnProcessTerminate_NegativeNumberString_DoesNotCrash) 104 { 105 std::atomic<bool> called{ false }; 106 107 OnProcessTerminate(L"-1", [&called](DWORD) { 108 called = true; 109 }); 110 111 std::this_thread::sleep_for(std::chrono::milliseconds(100)); 112 Assert::IsTrue(true); 113 } 114 115 TEST_METHOD(OnProcessTerminate_LargeNumber_DoesNotCrash) 116 { 117 std::atomic<bool> called{ false }; 118 119 OnProcessTerminate(L"18446744073709551615", [&called](DWORD) { 120 called = true; 121 }); 122 123 std::this_thread::sleep_for(std::chrono::milliseconds(100)); 124 Assert::IsTrue(true); 125 } 126 }; 127 }