TestDirectoryLock.cpp (5729B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "DirectoryLockImpl.h" 8 #include "QuotaManagerDependencyFixture.h" 9 #include "gtest/gtest.h" 10 #include "mozilla/SpinEventLoopUntil.h" 11 #include "mozilla/dom/quota/OriginScope.h" 12 #include "mozilla/dom/quota/UniversalDirectoryLock.h" 13 14 namespace mozilla::dom::quota::test { 15 16 class DOM_Quota_DirectoryLock : public QuotaManagerDependencyFixture { 17 public: 18 static void SetUpTestCase() { ASSERT_NO_FATAL_FAILURE(InitializeFixture()); } 19 20 static void TearDownTestCase() { ASSERT_NO_FATAL_FAILURE(ShutdownFixture()); } 21 }; 22 23 using BoolTripleTestParams = std::tuple<bool, bool, bool>; 24 25 class DOM_Quota_DirectoryLockWithBoolTriple 26 : public DOM_Quota_DirectoryLock, 27 public testing::WithParamInterface<BoolTripleTestParams> {}; 28 29 TEST_F(DOM_Quota_DirectoryLock, MutableManagerRef) { 30 PerformOnBackgroundThread([]() { 31 QuotaManager* quotaManager = QuotaManager::Get(); 32 ASSERT_TRUE(quotaManager); 33 34 RefPtr<ClientDirectoryLock> directoryLock = 35 quotaManager->CreateDirectoryLock(GetTestClientMetadata(), 36 /* aExclusive */ false); 37 38 EXPECT_EQ(&directoryLock->MutableManagerRef(), quotaManager); 39 }); 40 } 41 42 // Test that Drop unregisters directory lock asynchronously. 43 TEST_F(DOM_Quota_DirectoryLock, Drop_Timing) { 44 PerformOnBackgroundThread([]() { 45 QuotaManager* quotaManager = QuotaManager::Get(); 46 ASSERT_TRUE(quotaManager); 47 48 RefPtr<UniversalDirectoryLock> exclusiveDirectoryLock = 49 quotaManager->CreateDirectoryLockInternal( 50 PersistenceScope::CreateFromNull(), OriginScope::FromNull(), 51 ClientStorageScope::CreateFromNull(), 52 /* aExclusive */ true, DirectoryLockCategory::None); 53 54 bool done = false; 55 56 exclusiveDirectoryLock->Acquire()->Then( 57 GetCurrentSerialEventTarget(), __func__, 58 [&done](const BoolPromise::ResolveOrRejectValue& aValue) { 59 done = true; 60 }); 61 62 SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; }); 63 64 auto exclusiveDirectoryLockDropPromise = exclusiveDirectoryLock->Drop(); 65 exclusiveDirectoryLock = nullptr; 66 67 RefPtr<UniversalDirectoryLock> sharedDirectoryLock = 68 quotaManager->CreateDirectoryLockInternal( 69 PersistenceScope::CreateFromNull(), OriginScope::FromNull(), 70 ClientStorageScope::CreateFromNull(), 71 /* aExclusive */ false, DirectoryLockCategory::None); 72 73 ASSERT_TRUE(sharedDirectoryLock->MustWait()); 74 75 done = false; 76 77 exclusiveDirectoryLockDropPromise->Then( 78 GetCurrentSerialEventTarget(), __func__, 79 [&done](const BoolPromise::ResolveOrRejectValue& aValue) { 80 done = true; 81 }); 82 83 SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; }); 84 85 ASSERT_FALSE(sharedDirectoryLock->MustWait()); 86 87 sharedDirectoryLock = nullptr; 88 }); 89 } 90 91 TEST_P(DOM_Quota_DirectoryLockWithBoolTriple, BlockingBehavior) { 92 const BoolTripleTestParams& param = GetParam(); 93 94 const bool firstExclusive = std::get<0>(param); 95 const bool secondExclusive = std::get<1>(param); 96 const bool secondMustWait = std::get<2>(param); 97 98 PerformOnBackgroundThread([firstExclusive, secondExclusive, 99 secondMustWait]() { 100 QuotaManager* quotaManager = QuotaManager::Get(); 101 ASSERT_TRUE(quotaManager); 102 103 RefPtr<ClientDirectoryLock> directoryLock1 = 104 quotaManager->CreateDirectoryLock(GetTestClientMetadata(), 105 /* aExclusive */ firstExclusive); 106 Await(directoryLock1->Acquire()); 107 108 RefPtr<ClientDirectoryLock> directoryLock2 = 109 quotaManager->CreateDirectoryLock(GetTestClientMetadata(), 110 /* aExclusive */ secondExclusive); 111 112 EXPECT_EQ(directoryLock2->MustWait(), secondMustWait); 113 EXPECT_EQ(directoryLock2->LocksMustWaitFor().IsEmpty(), !secondMustWait); 114 115 DropDirectoryLock(directoryLock1); 116 }); 117 } 118 119 INSTANTIATE_TEST_SUITE_P( 120 , DOM_Quota_DirectoryLockWithBoolTriple, 121 testing::Values(std::make_tuple(/* firstExclusive */ false, 122 /* secondExclusive */ false, 123 /* secondMustWait */ false), 124 std::make_tuple(/* firstExclusive */ false, 125 /* secondExclusive */ true, 126 /* secondMustWait */ true), 127 std::make_tuple(/* firstExclusive */ true, 128 /* secondExclusive */ false, 129 /* secondMustWait */ true), 130 std::make_tuple(/* firstExclusive */ true, 131 /* secondExclusive */ true, 132 /* secondMustWait */ true)), 133 [](const testing::TestParamInfo<BoolTripleTestParams>& aParam) 134 -> std::string { 135 const BoolTripleTestParams& param = aParam.param; 136 137 const bool firstExclusive = std::get<0>(param); 138 const bool secondExclusive = std::get<1>(param); 139 const bool secondMustWait = std::get<2>(param); 140 141 std::stringstream ss; 142 143 ss << (firstExclusive ? "FirstExclusive" : "FirstShared") << "_" 144 << (secondExclusive ? "SecondExclusive" : "SecondShared") << "_" 145 << (secondMustWait ? "SecondMustWait" : "SecondMustNotWait"); 146 147 return ss.str(); 148 }); 149 150 } // namespace mozilla::dom::quota::test