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 }