/ src / common / UnitTests-CommonUtils / AppMutex.Tests.cpp
AppMutex.Tests.cpp
  1  #include "pch.h"
  2  #include "TestHelpers.h"
  3  #include <appMutex.h>
  4  
  5  using namespace Microsoft::VisualStudio::CppUnitTestFramework;
  6  
  7  namespace UnitTestsCommonUtils
  8  {
  9      TEST_CLASS(AppMutexTests)
 10      {
 11      public:
 12          TEST_METHOD(CreateAppMutex_ValidName_ReturnsHandle)
 13          {
 14              std::wstring mutexName = L"TestMutex_" + std::to_wstring(GetCurrentProcessId()) + L"_1";
 15              auto handle = createAppMutex(mutexName);
 16              Assert::IsNotNull(handle.get());
 17          }
 18  
 19          TEST_METHOD(CreateAppMutex_SameName_ReturnsExistingHandle)
 20          {
 21              std::wstring mutexName = L"TestMutex_" + std::to_wstring(GetCurrentProcessId()) + L"_2";
 22  
 23              auto handle1 = createAppMutex(mutexName);
 24              Assert::IsNotNull(handle1.get());
 25  
 26              auto handle2 = createAppMutex(mutexName);
 27              Assert::IsNull(handle2.get());
 28          }
 29  
 30          TEST_METHOD(CreateAppMutex_DifferentNames_ReturnsDifferentHandles)
 31          {
 32              std::wstring mutexName1 = L"TestMutex_" + std::to_wstring(GetCurrentProcessId()) + L"_A";
 33              std::wstring mutexName2 = L"TestMutex_" + std::to_wstring(GetCurrentProcessId()) + L"_B";
 34  
 35              auto handle1 = createAppMutex(mutexName1);
 36              auto handle2 = createAppMutex(mutexName2);
 37  
 38              Assert::IsNotNull(handle1.get());
 39              Assert::IsNotNull(handle2.get());
 40              Assert::AreNotEqual(handle1.get(), handle2.get());
 41          }
 42  
 43          TEST_METHOD(CreateAppMutex_EmptyName_ReturnsHandle)
 44          {
 45              // Empty name creates unnamed mutex
 46              auto handle = createAppMutex(L"");
 47              // CreateMutexW with empty string should still work
 48              Assert::IsTrue(true);
 49              // Test passes regardless - just checking it doesn't crash
 50              Assert::IsTrue(true);
 51          }
 52  
 53          TEST_METHOD(CreateAppMutex_LongName_ReturnsHandle)
 54          {
 55              // Create a long mutex name
 56              std::wstring mutexName = L"TestMutex_" + std::to_wstring(GetCurrentProcessId()) + L"_";
 57              for (int i = 0; i < 50; ++i)
 58              {
 59                  mutexName += L"LongNameSegment";
 60              }
 61  
 62              auto handle = createAppMutex(mutexName);
 63              // Long names might fail, but shouldn't crash
 64              Assert::IsTrue(true);
 65          }
 66  
 67          TEST_METHOD(CreateAppMutex_SpecialCharacters_ReturnsHandle)
 68          {
 69              std::wstring mutexName = L"TestMutex_" + std::to_wstring(GetCurrentProcessId()) + L"_Special!@#$%";
 70  
 71              auto handle = createAppMutex(mutexName);
 72              // Some special characters might not be valid in mutex names
 73              Assert::IsTrue(true);
 74          }
 75  
 76          TEST_METHOD(CreateAppMutex_GlobalPrefix_ReturnsHandle)
 77          {
 78              // Global prefix for cross-session mutex
 79              std::wstring mutexName = L"Global\\TestMutex_" + std::to_wstring(GetCurrentProcessId());
 80  
 81              auto handle = createAppMutex(mutexName);
 82              // Might require elevation, but shouldn't crash
 83              Assert::IsTrue(true);
 84          }
 85  
 86          TEST_METHOD(CreateAppMutex_LocalPrefix_ReturnsHandle)
 87          {
 88              std::wstring mutexName = L"Local\\TestMutex_" + std::to_wstring(GetCurrentProcessId());
 89  
 90              auto handle = createAppMutex(mutexName);
 91              Assert::IsNotNull(handle.get());
 92          }
 93  
 94          TEST_METHOD(CreateAppMutex_MultipleCalls_AllSucceed)
 95          {
 96              std::vector<wil::unique_mutex_nothrow> handles;
 97              for (int i = 0; i < 10; ++i)
 98              {
 99                  std::wstring mutexName = L"TestMutex_" + std::to_wstring(GetCurrentProcessId()) +
100                                           L"_Multi_" + std::to_wstring(i);
101                  auto handle = createAppMutex(mutexName);
102                  Assert::IsNotNull(handle.get());
103                  handles.push_back(std::move(handle));
104              }
105          }
106  
107          TEST_METHOD(CreateAppMutex_ReleaseAndRecreate_Works)
108          {
109              std::wstring mutexName = L"TestMutex_" + std::to_wstring(GetCurrentProcessId()) + L"_Recreate";
110  
111              auto handle1 = createAppMutex(mutexName);
112              Assert::IsNotNull(handle1.get());
113              handle1.reset();
114  
115              // After closing, should be able to create again
116              auto handle2 = createAppMutex(mutexName);
117              Assert::IsNotNull(handle2.get());
118          }
119      };
120  }