/ src / common / UnitTests-CommonUtils / ProcessWaiter.Tests.cpp
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  }