зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1749504 - Introduce a new method QuotaManager::OpenStorageDirectory; r=dom-storage-reviewers,jstutte
Quota manager origin operations and IndexedDB database maintenance currently call QuotaManager::CreateDirectoryLockInternal and DirectoryLock::Acquire to acquire a universal directory lock. Once that's all successfully done, they bounce to the QuotaManager IO thread where they synchronously call QuotaManager::EnsureStorageIsInitializedInternal. The new QuotaManager::OpenStorageDirectory method wraps all this complexity, so consumers can just obtain a universal directory lock when all required storage initialization is done. Changes done in this patch: - added QuotaManager::OpenStorageDirectory - added tests for the new method Differential Revision: https://phabricator.services.mozilla.com/D186134
This commit is contained in:
Родитель
fb80484f6c
Коммит
9fd6f9cf81
|
@ -4993,6 +4993,79 @@ nsresult QuotaManager::EnsureStorageIsInitializedInternal() {
|
|||
"dom::quota::FirstInitializationAttempt::Storage"_ns, innerFunc);
|
||||
}
|
||||
|
||||
RefPtr<UniversalDirectoryLockPromise> QuotaManager::OpenStorageDirectory(
|
||||
const Nullable<PersistenceType>& aPersistenceType,
|
||||
const OriginScope& aOriginScope, const Nullable<Client::Type>& aClientType,
|
||||
bool aExclusive,
|
||||
Maybe<RefPtr<UniversalDirectoryLock>&> aPendingDirectoryLockOut) {
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
RefPtr<UniversalDirectoryLock> storageDirectoryLock;
|
||||
|
||||
RefPtr<BoolPromise> storageDirectoryLockPromise;
|
||||
|
||||
if (mStorageInitialized && !mShutdownStorageOpCount) {
|
||||
storageDirectoryLockPromise = BoolPromise::CreateAndResolve(true, __func__);
|
||||
} else {
|
||||
storageDirectoryLock = CreateDirectoryLockInternal(
|
||||
Nullable<PersistenceType>(), OriginScope::FromNull(),
|
||||
Nullable<Client::Type>(),
|
||||
/* aExclusive */ false);
|
||||
|
||||
storageDirectoryLockPromise = storageDirectoryLock->Acquire();
|
||||
}
|
||||
|
||||
RefPtr<UniversalDirectoryLock> universalDirectoryLock =
|
||||
CreateDirectoryLockInternal(aPersistenceType, aOriginScope, aClientType,
|
||||
aExclusive);
|
||||
|
||||
RefPtr<BoolPromise> universalDirectoryLockPromise =
|
||||
universalDirectoryLock->Acquire();
|
||||
|
||||
if (aPendingDirectoryLockOut.isSome()) {
|
||||
aPendingDirectoryLockOut.ref() = universalDirectoryLock;
|
||||
}
|
||||
|
||||
return storageDirectoryLockPromise
|
||||
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||
[self = RefPtr(this),
|
||||
storageDirectoryLock = std::move(storageDirectoryLock)](
|
||||
const BoolPromise::ResolveOrRejectValue& aValue) mutable {
|
||||
if (aValue.IsReject()) {
|
||||
return BoolPromise::CreateAndReject(aValue.RejectValue(),
|
||||
__func__);
|
||||
}
|
||||
|
||||
if (!storageDirectoryLock) {
|
||||
return BoolPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
return self->InitializeStorage(std::move(storageDirectoryLock));
|
||||
})
|
||||
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||
[universalDirectoryLockPromise =
|
||||
std::move(universalDirectoryLockPromise)](
|
||||
const BoolPromise::ResolveOrRejectValue& aValue) mutable {
|
||||
if (aValue.IsReject()) {
|
||||
return BoolPromise::CreateAndReject(aValue.RejectValue(),
|
||||
__func__);
|
||||
}
|
||||
|
||||
return std::move(universalDirectoryLockPromise);
|
||||
})
|
||||
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||
[universalDirectoryLock = std::move(universalDirectoryLock)](
|
||||
const BoolPromise::ResolveOrRejectValue& aValue) mutable {
|
||||
if (aValue.IsReject()) {
|
||||
return UniversalDirectoryLockPromise::CreateAndReject(
|
||||
aValue.RejectValue(), __func__);
|
||||
}
|
||||
|
||||
return UniversalDirectoryLockPromise::CreateAndResolve(
|
||||
std::move(universalDirectoryLock), __func__);
|
||||
});
|
||||
}
|
||||
|
||||
RefPtr<ClientDirectoryLockPromise> QuotaManager::OpenClientDirectory(
|
||||
const ClientMetadata& aClientMetadata,
|
||||
Maybe<RefPtr<ClientDirectoryLock>&> aPendingDirectoryLockOut) {
|
||||
|
|
|
@ -50,9 +50,12 @@ using BoolResponseResolver = std::function<void(const BoolResponse&)>;
|
|||
namespace dom::quota {
|
||||
|
||||
class ClientDirectoryLock;
|
||||
class UniversalDirectoryLock;
|
||||
|
||||
using ClientDirectoryLockPromise =
|
||||
MozPromise<RefPtr<ClientDirectoryLock>, nsresult, true>;
|
||||
using UniversalDirectoryLockPromise =
|
||||
MozPromise<RefPtr<UniversalDirectoryLock>, nsresult, true>;
|
||||
|
||||
} // namespace dom::quota
|
||||
|
||||
|
|
|
@ -258,6 +258,13 @@ class QuotaManager final : public BackgroundThreadObject {
|
|||
|
||||
Result<OriginMetadata, nsresult> GetOriginMetadata(nsIFile* aDirectory);
|
||||
|
||||
RefPtr<UniversalDirectoryLockPromise> OpenStorageDirectory(
|
||||
const Nullable<PersistenceType>& aPersistenceType,
|
||||
const OriginScope& aOriginScope,
|
||||
const Nullable<Client::Type>& aClientType, bool aExclusive,
|
||||
Maybe<RefPtr<UniversalDirectoryLock>&> aPendingDirectoryLockOut =
|
||||
Nothing());
|
||||
|
||||
// This is the main entry point into the QuotaManager API.
|
||||
// Any storage API implementation (quota client) that participates in
|
||||
// centralized quota and storage handling should call this method to get
|
||||
|
|
|
@ -21,6 +21,414 @@ class TestQuotaManager : public QuotaManagerDependencyFixture {
|
|||
static void TearDownTestCase() { ASSERT_NO_FATAL_FAILURE(ShutdownFixture()); }
|
||||
};
|
||||
|
||||
// Test OpenStorageDirectory when an opening of the storage directory is
|
||||
// already ongoing and storage shutdown is scheduled after that.
|
||||
TEST_F(TestQuotaManager, OpenStorageDirectory_OngoingWithScheduledShutdown) {
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
PerformOnBackgroundThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
RefPtr<UniversalDirectoryLock> directoryLock;
|
||||
|
||||
nsTArray<RefPtr<BoolPromise>> promises;
|
||||
|
||||
promises.AppendElement(
|
||||
quotaManager
|
||||
->OpenStorageDirectory(
|
||||
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||
/* aExclusive */ false)
|
||||
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||
[&directoryLock](
|
||||
UniversalDirectoryLockPromise::ResolveOrRejectValue&&
|
||||
aValue) {
|
||||
if (aValue.IsReject()) {
|
||||
return BoolPromise::CreateAndReject(aValue.RejectValue(),
|
||||
__func__);
|
||||
}
|
||||
|
||||
[&aValue]() { ASSERT_TRUE(aValue.ResolveValue()); }();
|
||||
|
||||
directoryLock = std::move(aValue.ResolveValue());
|
||||
|
||||
return BoolPromise::CreateAndResolve(true, __func__);
|
||||
})
|
||||
->Then(quotaManager->IOThread(), __func__,
|
||||
[](const BoolPromise::ResolveOrRejectValue& aValue) {
|
||||
if (aValue.IsReject()) {
|
||||
return BoolPromise::CreateAndReject(aValue.RejectValue(),
|
||||
__func__);
|
||||
}
|
||||
|
||||
[]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
ASSERT_TRUE(
|
||||
quotaManager->IsStorageInitializedInternal());
|
||||
}();
|
||||
|
||||
return BoolPromise::CreateAndResolve(true, __func__);
|
||||
})
|
||||
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||
[&directoryLock](
|
||||
const BoolPromise::ResolveOrRejectValue& aValue) {
|
||||
directoryLock = nullptr;
|
||||
|
||||
if (aValue.IsReject()) {
|
||||
return BoolPromise::CreateAndReject(aValue.RejectValue(),
|
||||
__func__);
|
||||
}
|
||||
|
||||
return BoolPromise::CreateAndResolve(true, __func__);
|
||||
}));
|
||||
promises.AppendElement(quotaManager->ShutdownStorage());
|
||||
promises.AppendElement(
|
||||
quotaManager
|
||||
->OpenStorageDirectory(
|
||||
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||
/* aExclusive */ false)
|
||||
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||
[](const UniversalDirectoryLockPromise::ResolveOrRejectValue&
|
||||
aValue) {
|
||||
if (aValue.IsReject()) {
|
||||
return BoolPromise::CreateAndReject(aValue.RejectValue(),
|
||||
__func__);
|
||||
}
|
||||
|
||||
return BoolPromise::CreateAndResolve(true, __func__);
|
||||
}));
|
||||
|
||||
bool done = false;
|
||||
|
||||
BoolPromise::All(GetCurrentSerialEventTarget(), promises)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&done](const CopyableTArray<bool>& aResolveValues) {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
ASSERT_TRUE(quotaManager->IsStorageInitialized());
|
||||
|
||||
done = true;
|
||||
},
|
||||
[&done](nsresult aRejectValue) {
|
||||
ASSERT_TRUE(false);
|
||||
|
||||
done = true;
|
||||
});
|
||||
|
||||
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||
});
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsInitialized());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
}
|
||||
|
||||
// Test OpenStorageDirectory when an opening of the storage directory is
|
||||
// already ongoing and an exclusive directory lock is requested after that.
|
||||
TEST_F(TestQuotaManager,
|
||||
OpenStorageDirectory_OngoingWithExclusiveDirectoryLock) {
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
PerformOnBackgroundThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
RefPtr<UniversalDirectoryLock> directoryLock =
|
||||
quotaManager->CreateDirectoryLockInternal(Nullable<PersistenceType>(),
|
||||
OriginScope::FromNull(),
|
||||
Nullable<Client::Type>(),
|
||||
/* aExclusive */ true);
|
||||
|
||||
nsTArray<RefPtr<BoolPromise>> promises;
|
||||
|
||||
promises.AppendElement(
|
||||
quotaManager
|
||||
->OpenStorageDirectory(
|
||||
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||
/* aExclusive */ false)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&directoryLock](
|
||||
const UniversalDirectoryLockPromise::ResolveOrRejectValue&
|
||||
aValue) {
|
||||
directoryLock = nullptr;
|
||||
|
||||
if (aValue.IsReject()) {
|
||||
return BoolPromise::CreateAndReject(aValue.RejectValue(),
|
||||
__func__);
|
||||
}
|
||||
|
||||
return BoolPromise::CreateAndResolve(true, __func__);
|
||||
}));
|
||||
promises.AppendElement(directoryLock->Acquire());
|
||||
promises.AppendElement(
|
||||
quotaManager
|
||||
->OpenStorageDirectory(
|
||||
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||
/* aExclusive */ false)
|
||||
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||
[](const UniversalDirectoryLockPromise::ResolveOrRejectValue&
|
||||
aValue) {
|
||||
if (aValue.IsReject()) {
|
||||
return BoolPromise::CreateAndReject(aValue.RejectValue(),
|
||||
__func__);
|
||||
}
|
||||
|
||||
return BoolPromise::CreateAndResolve(true, __func__);
|
||||
}));
|
||||
|
||||
bool done = false;
|
||||
|
||||
BoolPromise::All(GetCurrentSerialEventTarget(), promises)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&done](const CopyableTArray<bool>& aResolveValues) {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
ASSERT_TRUE(quotaManager->IsStorageInitialized());
|
||||
|
||||
done = true;
|
||||
},
|
||||
[&done](nsresult aRejectValue) {
|
||||
ASSERT_TRUE(false);
|
||||
|
||||
done = true;
|
||||
});
|
||||
|
||||
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||
});
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsInitialized());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
}
|
||||
|
||||
// Test OpenStorageDirectory when an opening of the storage directory already
|
||||
// finished.
|
||||
TEST_F(TestQuotaManager, OpenStorageDirectory_Finished) {
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
PerformOnBackgroundThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
bool done = false;
|
||||
|
||||
quotaManager
|
||||
->OpenStorageDirectory(
|
||||
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||
/* aExclusive */ false)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&done](const UniversalDirectoryLockPromise::ResolveOrRejectValue&
|
||||
aValue) {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
ASSERT_TRUE(quotaManager->IsStorageInitialized());
|
||||
|
||||
done = true;
|
||||
});
|
||||
|
||||
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||
|
||||
done = false;
|
||||
|
||||
quotaManager
|
||||
->OpenStorageDirectory(
|
||||
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||
/* aExclusive */ false)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&done](const UniversalDirectoryLockPromise::ResolveOrRejectValue&
|
||||
aValue) {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
ASSERT_TRUE(quotaManager->IsStorageInitialized());
|
||||
|
||||
done = true;
|
||||
});
|
||||
|
||||
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||
});
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsInitialized());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
}
|
||||
|
||||
// Test OpenStorageDirectory when an opening of the storage directory already
|
||||
// finished but storage shutdown has just been scheduled.
|
||||
TEST_F(TestQuotaManager, OpenStorageDirectory_FinishedWithScheduledShutdown) {
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
PerformOnBackgroundThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
bool done = false;
|
||||
|
||||
quotaManager
|
||||
->OpenStorageDirectory(
|
||||
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||
/* aExclusive */ false)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&done](const UniversalDirectoryLockPromise::ResolveOrRejectValue&
|
||||
aValue) {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
ASSERT_TRUE(quotaManager->IsStorageInitialized());
|
||||
|
||||
done = true;
|
||||
});
|
||||
|
||||
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||
|
||||
nsTArray<RefPtr<BoolPromise>> promises;
|
||||
|
||||
promises.AppendElement(quotaManager->ShutdownStorage());
|
||||
promises.AppendElement(
|
||||
quotaManager
|
||||
->OpenStorageDirectory(
|
||||
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||
/* aExclusive */ false)
|
||||
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||
[](const UniversalDirectoryLockPromise::ResolveOrRejectValue&
|
||||
aValue) {
|
||||
if (aValue.IsReject()) {
|
||||
return BoolPromise::CreateAndReject(aValue.RejectValue(),
|
||||
__func__);
|
||||
}
|
||||
|
||||
return BoolPromise::CreateAndResolve(true, __func__);
|
||||
}));
|
||||
|
||||
done = false;
|
||||
|
||||
BoolPromise::All(GetCurrentSerialEventTarget(), promises)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&done](const CopyableTArray<bool>& aResolveValues) {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
ASSERT_TRUE(quotaManager->IsStorageInitialized());
|
||||
|
||||
done = true;
|
||||
},
|
||||
[&done](nsresult aRejectValue) {
|
||||
ASSERT_TRUE(false);
|
||||
|
||||
done = true;
|
||||
});
|
||||
|
||||
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||
});
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsInitialized());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
}
|
||||
|
||||
// Test OpenStorageDirectory when an opening of the storage directory already
|
||||
// finished and an exclusive client directory lock for a non-overlapping
|
||||
// origin is acquired in between.
|
||||
TEST_F(TestQuotaManager,
|
||||
OpenStorageDirectory_FinishedWithExclusiveClientDirectoryLock) {
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
PerformOnBackgroundThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
bool done = false;
|
||||
|
||||
quotaManager
|
||||
->OpenStorageDirectory(
|
||||
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||
/* aExclusive */ false)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&done](const UniversalDirectoryLockPromise::ResolveOrRejectValue&
|
||||
aValue) {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
ASSERT_TRUE(quotaManager->IsStorageInitialized());
|
||||
|
||||
done = true;
|
||||
});
|
||||
|
||||
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||
|
||||
RefPtr<ClientDirectoryLock> directoryLock =
|
||||
quotaManager->CreateDirectoryLock(GetTestClientMetadata(),
|
||||
/* aExclusive */ true);
|
||||
|
||||
done = false;
|
||||
|
||||
directoryLock->Acquire()->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&done](const BoolPromise::ResolveOrRejectValue& aValue) {
|
||||
done = true;
|
||||
});
|
||||
|
||||
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||
|
||||
done = false;
|
||||
|
||||
quotaManager
|
||||
->OpenStorageDirectory(
|
||||
Nullable<PersistenceType>(PERSISTENCE_TYPE_PERSISTENT),
|
||||
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||
/* aExclusive */ false)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&done](const UniversalDirectoryLockPromise::ResolveOrRejectValue&
|
||||
aValue) {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
ASSERT_TRUE(quotaManager->IsStorageInitialized());
|
||||
|
||||
done = true;
|
||||
});
|
||||
|
||||
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||
});
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsInitialized());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
}
|
||||
|
||||
// Test OpenClientDirctory when an opening of a client directory is already
|
||||
// ongoing and storage shutdown is scheduled after that.
|
||||
TEST_F(TestQuotaManager, OpenClientDirectory_OngoingWithScheduledShutdown) {
|
||||
|
@ -47,6 +455,8 @@ TEST_F(TestQuotaManager, OpenClientDirectory_OngoingWithScheduledShutdown) {
|
|||
__func__);
|
||||
}
|
||||
|
||||
[&aValue]() { ASSERT_TRUE(aValue.ResolveValue()); }();
|
||||
|
||||
directoryLock = std::move(aValue.ResolveValue());
|
||||
|
||||
return BoolPromise::CreateAndResolve(true, __func__);
|
||||
|
|
Загрузка…
Ссылка в новой задаче