зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1749504 - Add QuotaManager::InitializeStorage method; r=dom-storage-reviewers,jstutte
There's currently EnsureStorageIsInitializedInternal which can only be called on the QuotaManager IO thread. That method shouldn't be exposed to quota clients and origin operations. There should be a public method callable from the PBackground thread returning a MozPromise instead. Such method will guarantee that proper directory locking is acquired before storage initialization is started. Changes done in this patch: - added QuotaManager::InitializeStorage method - added QuotaManager::IsStorageInitialized method - QuotaManagerService::Init reworked to use an asynchronous message instead of creating a sub actor - added QuotaManagerDependencyFixture::IsStorageInitialized - added QuotaManagerDependencyFixture::AssertStorageIsInitialized - added QuotaManagerDependencyFixture::AssertStorageIsNotInitialized - eliminated QuotaManager::IsStorageInitializedInternal calls in tests - eliminated QuotaManager::EnsureStorageIsInitializedInternal calls in tests - added a bunch of tests for the new QuotaManager::InitializeStorage method Differential Revision: https://phabricator.services.mozilla.com/D185570
This commit is contained in:
Родитель
ac70b31bd2
Коммит
1ae113cb02
|
@ -361,7 +361,6 @@ mozilla::ipc::IPCResult QuotaRequestChild::Recv__delete__(
|
|||
aResponse.get_TemporaryStorageInitializedResponse().initialized());
|
||||
break;
|
||||
|
||||
case RequestResponse::TInitResponse:
|
||||
case RequestResponse::TInitTemporaryStorageResponse:
|
||||
case RequestResponse::TClearOriginResponse:
|
||||
case RequestResponse::TResetOriginResponse:
|
||||
|
|
|
@ -1656,6 +1656,8 @@ QuotaManager::QuotaManager(const nsAString& aBasePath,
|
|||
mStorageName(aStorageName),
|
||||
mTemporaryStorageUsage(0),
|
||||
mNextDirectoryLockId(0),
|
||||
mShutdownStorageOpCount(0),
|
||||
mStorageInitialized(false),
|
||||
mTemporaryStorageInitialized(false),
|
||||
mCacheUsable(false) {
|
||||
AssertIsOnOwningThread();
|
||||
|
@ -4847,6 +4849,36 @@ Result<Ok, nsresult> QuotaManager::CreateEmptyLocalStorageArchive(
|
|||
return Ok{};
|
||||
}
|
||||
|
||||
RefPtr<BoolPromise> QuotaManager::InitializeStorage() {
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
// If storage is initialized but there's a clear storage or shutdown storage
|
||||
// operation already scheduled, we can't immediately resolve the promise and
|
||||
// return from the function because the clear or shutdown storage operation
|
||||
// uninitializes storage.
|
||||
if (mStorageInitialized && !mShutdownStorageOpCount) {
|
||||
return BoolPromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
auto initializeStorageOp = CreateInitOp();
|
||||
|
||||
RegisterNormalOriginOp(*initializeStorageOp);
|
||||
|
||||
initializeStorageOp->RunImmediately();
|
||||
|
||||
return initializeStorageOp->OnResults()->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[self = RefPtr(this)](const BoolPromise::ResolveOrRejectValue& aValue) {
|
||||
if (aValue.IsReject()) {
|
||||
return BoolPromise::CreateAndReject(aValue.RejectValue(), __func__);
|
||||
}
|
||||
|
||||
self->mStorageInitialized = true;
|
||||
|
||||
return BoolPromise::CreateAndResolve(true, __func__);
|
||||
});
|
||||
}
|
||||
|
||||
nsresult QuotaManager::EnsureStorageIsInitializedInternal() {
|
||||
DiagnosticAssertIsOnIOThread();
|
||||
|
||||
|
@ -5122,7 +5154,23 @@ RefPtr<BoolPromise> QuotaManager::ClearStorage() {
|
|||
|
||||
clearStorageOp->RunImmediately();
|
||||
|
||||
return clearStorageOp->OnResults();
|
||||
// Storage clearing also shuts it down, so we need to increses the counter
|
||||
// here as well.
|
||||
mShutdownStorageOpCount++;
|
||||
|
||||
return clearStorageOp->OnResults()->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[self = RefPtr(this)](const BoolPromise::ResolveOrRejectValue& aValue) {
|
||||
self->mShutdownStorageOpCount--;
|
||||
|
||||
if (aValue.IsReject()) {
|
||||
return BoolPromise::CreateAndReject(aValue.RejectValue(), __func__);
|
||||
}
|
||||
|
||||
self->mStorageInitialized = false;
|
||||
|
||||
return BoolPromise::CreateAndResolve(true, __func__);
|
||||
});
|
||||
}
|
||||
|
||||
RefPtr<BoolPromise> QuotaManager::ShutdownStorage() {
|
||||
|
@ -5134,7 +5182,21 @@ RefPtr<BoolPromise> QuotaManager::ShutdownStorage() {
|
|||
|
||||
shutdownStorageOp->RunImmediately();
|
||||
|
||||
return shutdownStorageOp->OnResults();
|
||||
mShutdownStorageOpCount++;
|
||||
|
||||
return shutdownStorageOp->OnResults()->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[self = RefPtr(this)](const BoolPromise::ResolveOrRejectValue& aValue) {
|
||||
self->mShutdownStorageOpCount--;
|
||||
|
||||
if (aValue.IsReject()) {
|
||||
return BoolPromise::CreateAndReject(aValue.RejectValue(), __func__);
|
||||
}
|
||||
|
||||
self->mStorageInitialized = false;
|
||||
|
||||
return BoolPromise::CreateAndResolve(true, __func__);
|
||||
});
|
||||
}
|
||||
|
||||
void QuotaManager::ShutdownStorageInternal() {
|
||||
|
|
|
@ -289,7 +289,7 @@ class TemporaryStorageInitializedOp final : public InitializedRequestBase {
|
|||
void GetResponse(RequestResponse& aResponse) override;
|
||||
};
|
||||
|
||||
class InitOp final : public QuotaRequestBase {
|
||||
class InitOp final : public ResolvableNormalOriginOp<bool> {
|
||||
public:
|
||||
InitOp();
|
||||
|
||||
|
@ -298,7 +298,7 @@ class InitOp final : public QuotaRequestBase {
|
|||
|
||||
nsresult DoDirectoryWork(QuotaManager& aQuotaManager) override;
|
||||
|
||||
void GetResponse(RequestResponse& aResponse) override;
|
||||
bool GetResolveValue() override;
|
||||
};
|
||||
|
||||
class InitTemporaryStorageOp final : public QuotaRequestBase {
|
||||
|
@ -571,7 +571,9 @@ RefPtr<QuotaRequestBase> CreateTemporaryStorageInitializedOp() {
|
|||
return MakeRefPtr<TemporaryStorageInitializedOp>();
|
||||
}
|
||||
|
||||
RefPtr<QuotaRequestBase> CreateInitOp() { return MakeRefPtr<InitOp>(); }
|
||||
RefPtr<ResolvableNormalOriginOp<bool>> CreateInitOp() {
|
||||
return MakeRefPtr<InitOp>();
|
||||
}
|
||||
|
||||
RefPtr<QuotaRequestBase> CreateInitTemporaryStorageOp() {
|
||||
return MakeRefPtr<InitTemporaryStorageOp>();
|
||||
|
@ -1102,7 +1104,10 @@ void TemporaryStorageInitializedOp::GetResponse(RequestResponse& aResponse) {
|
|||
}
|
||||
|
||||
InitOp::InitOp()
|
||||
: QuotaRequestBase("dom::quota::InitOp", /* aExclusive */ false) {
|
||||
: ResolvableNormalOriginOp(
|
||||
"dom::quota::InitOp", Nullable<PersistenceType>(),
|
||||
OriginScope::FromNull(), Nullable<Client::Type>(),
|
||||
/* aExclusive */ false) {
|
||||
AssertIsOnOwningThread();
|
||||
}
|
||||
|
||||
|
@ -1116,11 +1121,7 @@ nsresult InitOp::DoDirectoryWork(QuotaManager& aQuotaManager) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void InitOp::GetResponse(RequestResponse& aResponse) {
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
aResponse = InitResponse();
|
||||
}
|
||||
bool InitOp::GetResolveValue() { return true; }
|
||||
|
||||
InitTemporaryStorageOp::InitTemporaryStorageOp()
|
||||
: QuotaRequestBase("dom::quota::InitTemporaryStorageOp",
|
||||
|
|
|
@ -53,7 +53,7 @@ RefPtr<QuotaRequestBase> CreateStorageInitializedOp();
|
|||
|
||||
RefPtr<QuotaRequestBase> CreateTemporaryStorageInitializedOp();
|
||||
|
||||
RefPtr<QuotaRequestBase> CreateInitOp();
|
||||
RefPtr<ResolvableNormalOriginOp<bool>> CreateInitOp();
|
||||
|
||||
RefPtr<QuotaRequestBase> CreateInitTemporaryStorageOp();
|
||||
|
||||
|
|
|
@ -49,10 +49,6 @@ struct TemporaryStorageInitializedParams
|
|||
{
|
||||
};
|
||||
|
||||
struct InitParams
|
||||
{
|
||||
};
|
||||
|
||||
struct InitTemporaryStorageParams
|
||||
{
|
||||
};
|
||||
|
@ -140,7 +136,6 @@ union RequestParams
|
|||
StorageNameParams;
|
||||
StorageInitializedParams;
|
||||
TemporaryStorageInitializedParams;
|
||||
InitParams;
|
||||
InitTemporaryStorageParams;
|
||||
InitializePersistentOriginParams;
|
||||
InitializeTemporaryOriginParams;
|
||||
|
@ -169,6 +164,9 @@ parent:
|
|||
|
||||
async PQuotaRequest(RequestParams params);
|
||||
|
||||
async InitializeStorage()
|
||||
returns(BoolResponse response);
|
||||
|
||||
async ClearStoragesForPrivateBrowsing()
|
||||
returns(BoolResponse response);
|
||||
|
||||
|
|
|
@ -28,10 +28,6 @@ struct TemporaryStorageInitializedResponse
|
|||
bool initialized;
|
||||
};
|
||||
|
||||
struct InitResponse
|
||||
{
|
||||
};
|
||||
|
||||
struct InitTemporaryStorageResponse
|
||||
{
|
||||
};
|
||||
|
@ -89,7 +85,6 @@ union RequestResponse
|
|||
StorageNameResponse;
|
||||
StorageInitializedResponse;
|
||||
TemporaryStorageInitializedResponse;
|
||||
InitResponse;
|
||||
InitTemporaryStorageResponse;
|
||||
InitializePersistentOriginResponse;
|
||||
InitializeTemporaryOriginResponse;
|
||||
|
|
|
@ -300,6 +300,14 @@ class QuotaManager final : public BackgroundThreadObject {
|
|||
template <typename P>
|
||||
void CollectPendingOriginsForListing(P aPredicate);
|
||||
|
||||
RefPtr<BoolPromise> InitializeStorage();
|
||||
|
||||
bool IsStorageInitialized() const {
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
return mStorageInitialized;
|
||||
}
|
||||
|
||||
bool IsStorageInitializedInternal() const {
|
||||
AssertIsOnIOThread();
|
||||
return static_cast<bool>(mStorageConnection);
|
||||
|
@ -709,6 +717,8 @@ class QuotaManager final : public BackgroundThreadObject {
|
|||
uint64_t mTemporaryStorageLimit;
|
||||
uint64_t mTemporaryStorageUsage;
|
||||
int64_t mNextDirectoryLockId;
|
||||
uint64_t mShutdownStorageOpCount;
|
||||
bool mStorageInitialized;
|
||||
bool mTemporaryStorageInitialized;
|
||||
bool mCacheUsable;
|
||||
};
|
||||
|
|
|
@ -528,16 +528,13 @@ QuotaManagerService::Init(nsIQuotaRequest** _retval) {
|
|||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()));
|
||||
|
||||
RefPtr<Request> request = new Request();
|
||||
|
||||
InitParams params;
|
||||
|
||||
RequestInfo info(request, params);
|
||||
|
||||
nsresult rv = InitiateRequest(info);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
mBackgroundActor->SendInitializeStorage()->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
BoolResponsePromiseResolveOrRejectCallback(request));
|
||||
|
||||
request.forget(_retval);
|
||||
return NS_OK;
|
||||
|
|
|
@ -134,7 +134,6 @@ bool Quota::VerifyRequestParams(const RequestParams& aParams) const {
|
|||
case RequestParams::TStorageNameParams:
|
||||
case RequestParams::TStorageInitializedParams:
|
||||
case RequestParams::TTemporaryStorageInitializedParams:
|
||||
case RequestParams::TInitParams:
|
||||
case RequestParams::TInitTemporaryStorageParams:
|
||||
break;
|
||||
|
||||
|
@ -408,9 +407,6 @@ PQuotaRequestParent* Quota::AllocPQuotaRequestParent(
|
|||
case RequestParams::TTemporaryStorageInitializedParams:
|
||||
return CreateTemporaryStorageInitializedOp();
|
||||
|
||||
case RequestParams::TInitParams:
|
||||
return CreateInitOp();
|
||||
|
||||
case RequestParams::TInitTemporaryStorageParams:
|
||||
return CreateInitTemporaryStorageOp();
|
||||
|
||||
|
@ -481,6 +477,24 @@ bool Quota::DeallocPQuotaRequestParent(PQuotaRequestParent* aActor) {
|
|||
return true;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult Quota::RecvInitializeStorage(
|
||||
InitializeStorageResolver&& aResolver) {
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
QM_TRY(MOZ_TO_RESULT(!QuotaManager::IsShuttingDown()),
|
||||
ResolveBoolResponseAndReturn(aResolver));
|
||||
|
||||
QM_TRY_UNWRAP(const NotNull<RefPtr<QuotaManager>> quotaManager,
|
||||
QuotaManager::GetOrCreate(),
|
||||
ResolveBoolResponseAndReturn(aResolver));
|
||||
|
||||
quotaManager->InitializeStorage()->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
BoolPromiseResolveOrRejectCallback(this, std::move(aResolver)));
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult Quota::RecvClearStoragesForPrivateBrowsing(
|
||||
ClearStoragesForPrivateBrowsingResolver&& aResolver) {
|
||||
AssertIsOnBackgroundThread();
|
||||
|
|
|
@ -50,6 +50,9 @@ class Quota final : public PQuotaParent {
|
|||
|
||||
virtual bool DeallocPQuotaRequestParent(PQuotaRequestParent* aActor) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvInitializeStorage(
|
||||
InitializeStorageResolver&& aResolver) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvClearStoragesForPrivateBrowsing(
|
||||
ClearStoragesForPrivateBrowsingResolver&& aResolver) override;
|
||||
|
||||
|
|
|
@ -92,6 +92,24 @@ void QuotaManagerDependencyFixture::ShutdownFixture() {
|
|||
sBackgroundTarget = nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
void QuotaManagerDependencyFixture::InitializeStorage() {
|
||||
PerformOnBackgroundThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
bool done = false;
|
||||
|
||||
quotaManager->InitializeStorage()->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&done](const BoolPromise::ResolveOrRejectValue& aValue) {
|
||||
done = true;
|
||||
});
|
||||
|
||||
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||
});
|
||||
}
|
||||
|
||||
// static
|
||||
void QuotaManagerDependencyFixture::StorageInitialized(bool* aResult) {
|
||||
AutoJSAPI jsapi;
|
||||
|
@ -124,6 +142,32 @@ void QuotaManagerDependencyFixture::StorageInitialized(bool* aResult) {
|
|||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void QuotaManagerDependencyFixture::IsStorageInitialized(bool* aResult) {
|
||||
ASSERT_TRUE(aResult);
|
||||
|
||||
PerformOnBackgroundThread([aResult]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
*aResult = quotaManager->IsStorageInitialized();
|
||||
});
|
||||
}
|
||||
|
||||
// static
|
||||
void QuotaManagerDependencyFixture::AssertStorageIsInitialized() {
|
||||
bool result;
|
||||
ASSERT_NO_FATAL_FAILURE(IsStorageInitialized(&result));
|
||||
ASSERT_TRUE(result);
|
||||
}
|
||||
|
||||
// static
|
||||
void QuotaManagerDependencyFixture::AssertStorageIsNotInitialized() {
|
||||
bool result;
|
||||
ASSERT_NO_FATAL_FAILURE(IsStorageInitialized(&result));
|
||||
ASSERT_FALSE(result);
|
||||
}
|
||||
|
||||
// static
|
||||
void QuotaManagerDependencyFixture::ShutdownStorage() {
|
||||
PerformOnBackgroundThread([]() {
|
||||
|
@ -173,6 +217,21 @@ void QuotaManagerDependencyFixture::ClearStoragesForOrigin(
|
|||
[&resolver]() { return resolver->Done(); });
|
||||
}
|
||||
|
||||
// static
|
||||
OriginMetadata QuotaManagerDependencyFixture::GetTestOriginMetadata() {
|
||||
return {""_ns,
|
||||
"example.com"_ns,
|
||||
"http://example.com"_ns,
|
||||
"http://example.com"_ns,
|
||||
/* aIsPrivate */ false,
|
||||
PERSISTENCE_TYPE_DEFAULT};
|
||||
}
|
||||
|
||||
// static
|
||||
ClientMetadata QuotaManagerDependencyFixture::GetTestClientMetadata() {
|
||||
return {GetTestOriginMetadata(), Client::SDB};
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISerialEventTarget> QuotaManagerDependencyFixture::sBackgroundTarget;
|
||||
|
||||
} // namespace mozilla::dom::quota::test
|
||||
|
|
|
@ -22,7 +22,11 @@ class QuotaManagerDependencyFixture : public testing::Test {
|
|||
|
||||
static void ShutdownFixture();
|
||||
|
||||
static void InitializeStorage();
|
||||
static void StorageInitialized(bool* aResult = nullptr);
|
||||
static void IsStorageInitialized(bool* aResult);
|
||||
static void AssertStorageIsInitialized();
|
||||
static void AssertStorageIsNotInitialized();
|
||||
static void ShutdownStorage();
|
||||
|
||||
static void ClearStoragesForOrigin(const OriginMetadata& aOriginMetadata);
|
||||
|
@ -79,6 +83,9 @@ class QuotaManagerDependencyFixture : public testing::Test {
|
|||
return sBackgroundTarget;
|
||||
}
|
||||
|
||||
static OriginMetadata GetTestOriginMetadata();
|
||||
static ClientMetadata GetTestClientMetadata();
|
||||
|
||||
private:
|
||||
static nsCOMPtr<nsISerialEventTarget> sBackgroundTarget;
|
||||
};
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "gtest/gtest.h"
|
||||
#include "mozilla/SpinEventLoopUntil.h"
|
||||
#include "mozilla/dom/quota/DirectoryLock.h"
|
||||
#include "mozilla/dom/quota/OriginScope.h"
|
||||
#include "mozilla/dom/quota/QuotaManager.h"
|
||||
#include "mozilla/gtest/MozAssertions.h"
|
||||
#include "QuotaManagerDependencyFixture.h"
|
||||
|
@ -19,29 +21,611 @@ class TestQuotaManager : public QuotaManagerDependencyFixture {
|
|||
static void TearDownTestCase() { ASSERT_NO_FATAL_FAILURE(ShutdownFixture()); }
|
||||
};
|
||||
|
||||
// Test simple InitializeStorage.
|
||||
TEST_F(TestQuotaManager, InitializeStorage_Simple) {
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
PerformOnBackgroundThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
bool done = false;
|
||||
|
||||
quotaManager->InitializeStorage()->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&done](const BoolPromise::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 InitializeStorage when a storage initialization is already ongoing.
|
||||
TEST_F(TestQuotaManager, InitializeStorage_Ongoing) {
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
PerformOnBackgroundThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
nsTArray<RefPtr<BoolPromise>> promises;
|
||||
|
||||
promises.AppendElement(quotaManager->InitializeStorage());
|
||||
promises.AppendElement(quotaManager->InitializeStorage());
|
||||
|
||||
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 InitializeStorage when a storage initialization is already ongoing and
|
||||
// storage shutdown is scheduled after that.
|
||||
TEST_F(TestQuotaManager, InitializeStorage_OngoingWithScheduledShutdown) {
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
PerformOnBackgroundThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
nsTArray<RefPtr<BoolPromise>> promises;
|
||||
|
||||
promises.AppendElement(quotaManager->InitializeStorage());
|
||||
promises.AppendElement(quotaManager->ShutdownStorage());
|
||||
promises.AppendElement(quotaManager->InitializeStorage());
|
||||
|
||||
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 InitializeStorage when a storage initialization is already ongoing and
|
||||
// an exclusive directory lock is requested after that.
|
||||
TEST_F(TestQuotaManager, InitializeStorage_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->InitializeStorage()->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&directoryLock](const BoolPromise::ResolveOrRejectValue& aValue) {
|
||||
// The exclusive directory lock must be released when the first
|
||||
// storage initialization is finished, otherwise it would endlessly
|
||||
// block the second storage initialization.
|
||||
directoryLock = nullptr;
|
||||
|
||||
if (aValue.IsReject()) {
|
||||
return BoolPromise::CreateAndReject(aValue.RejectValue(), __func__);
|
||||
}
|
||||
|
||||
return BoolPromise::CreateAndResolve(true, __func__);
|
||||
}));
|
||||
promises.AppendElement(directoryLock->Acquire());
|
||||
promises.AppendElement(quotaManager->InitializeStorage());
|
||||
|
||||
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 InitializeStorage when a storage initialization is already ongoing and
|
||||
// shared client directory locks are requested after that.
|
||||
// The shared client directory locks don't have to be released in this case.
|
||||
TEST_F(TestQuotaManager, InitializeStorage_OngoingWithClientDirectoryLocks) {
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
PerformOnBackgroundThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
RefPtr<ClientDirectoryLock> directoryLock =
|
||||
quotaManager->CreateDirectoryLock(GetTestClientMetadata(),
|
||||
/* aExclusive */ false);
|
||||
|
||||
RefPtr<ClientDirectoryLock> directoryLock2 =
|
||||
quotaManager->CreateDirectoryLock(GetTestClientMetadata(),
|
||||
/* aExclusive */ false);
|
||||
|
||||
nsTArray<RefPtr<BoolPromise>> promises;
|
||||
|
||||
promises.AppendElement(quotaManager->InitializeStorage());
|
||||
promises.AppendElement(directoryLock->Acquire());
|
||||
promises.AppendElement(quotaManager->InitializeStorage());
|
||||
promises.AppendElement(directoryLock2->Acquire());
|
||||
|
||||
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 InitializeStorage when a storage initialization is already ongoing and
|
||||
// shared client directory locks are requested after that with storage shutdown
|
||||
// scheduled in between.
|
||||
TEST_F(TestQuotaManager,
|
||||
InitializeStorage_OngoingWithClientDirectoryLocksAndScheduledShutdown) {
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
PerformOnBackgroundThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
RefPtr<ClientDirectoryLock> directoryLock =
|
||||
quotaManager->CreateDirectoryLock(GetTestClientMetadata(),
|
||||
/* aExclusive */ false);
|
||||
|
||||
directoryLock->OnInvalidate(
|
||||
[&directoryLock]() { directoryLock = nullptr; });
|
||||
|
||||
RefPtr<ClientDirectoryLock> directoryLock2 =
|
||||
quotaManager->CreateDirectoryLock(GetTestClientMetadata(),
|
||||
/* aExclusive */ false);
|
||||
|
||||
nsTArray<RefPtr<BoolPromise>> promises;
|
||||
|
||||
promises.AppendElement(quotaManager->InitializeStorage());
|
||||
promises.AppendElement(directoryLock->Acquire());
|
||||
promises.AppendElement(quotaManager->ShutdownStorage());
|
||||
promises.AppendElement(quotaManager->InitializeStorage());
|
||||
promises.AppendElement(directoryLock2->Acquire());
|
||||
|
||||
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 InitializeStorage when a storage initialization already finished.
|
||||
TEST_F(TestQuotaManager, InitializeStorage_Finished) {
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
PerformOnBackgroundThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
bool done = false;
|
||||
|
||||
quotaManager->InitializeStorage()->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&done](const BoolPromise::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->InitializeStorage()->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&done](const BoolPromise::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 InitializeStorage when a storage initialization already finished but
|
||||
// storage shutdown has just been scheduled.
|
||||
TEST_F(TestQuotaManager, InitializeStorage_FinishedWithScheduledShutdown) {
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
PerformOnBackgroundThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
bool done = false;
|
||||
|
||||
quotaManager->InitializeStorage()->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&done](const BoolPromise::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->InitializeStorage());
|
||||
|
||||
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 InitializeStorage when a storage initialization already finished and
|
||||
// shared client directory locks are requested immediately after requesting
|
||||
// storage initialization.
|
||||
TEST_F(TestQuotaManager, InitializeStorage_FinishedWithClientDirectoryLocks) {
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
PerformOnBackgroundThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
RefPtr<ClientDirectoryLock> directoryLock =
|
||||
quotaManager->CreateDirectoryLock(GetTestClientMetadata(),
|
||||
/* aExclusive */ false);
|
||||
|
||||
nsTArray<RefPtr<BoolPromise>> promises;
|
||||
|
||||
promises.AppendElement(quotaManager->InitializeStorage());
|
||||
promises.AppendElement(directoryLock->Acquire());
|
||||
|
||||
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; });
|
||||
|
||||
RefPtr<ClientDirectoryLock> directoryLock2 =
|
||||
quotaManager->CreateDirectoryLock(GetTestClientMetadata(),
|
||||
/* aExclusive */ false);
|
||||
|
||||
promises.Clear();
|
||||
|
||||
promises.AppendElement(quotaManager->InitializeStorage());
|
||||
promises.AppendElement(directoryLock2->Acquire());
|
||||
|
||||
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 InitializeStorage when a storage initialization already finished and
|
||||
// shared client directory locks are requested immediatelly after requesting
|
||||
// storage initialization with storage shutdown performed in between.
|
||||
// The shared client directory lock is released when it gets invalidated by
|
||||
// storage shutdown which then unblocks the shutdown.
|
||||
TEST_F(TestQuotaManager,
|
||||
InitializeStorage_FinishedWithClientDirectoryLocksAndScheduledShutdown) {
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
PerformOnBackgroundThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
RefPtr<ClientDirectoryLock> directoryLock =
|
||||
quotaManager->CreateDirectoryLock(GetTestClientMetadata(),
|
||||
/* aExclusive */ false);
|
||||
|
||||
directoryLock->OnInvalidate(
|
||||
[&directoryLock]() { directoryLock = nullptr; });
|
||||
|
||||
nsTArray<RefPtr<BoolPromise>> promises;
|
||||
|
||||
promises.AppendElement(quotaManager->InitializeStorage());
|
||||
promises.AppendElement(directoryLock->Acquire());
|
||||
|
||||
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; });
|
||||
|
||||
done = false;
|
||||
|
||||
quotaManager->ShutdownStorage()->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&done](const BoolPromise::ResolveOrRejectValue& aValue) {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
ASSERT_FALSE(quotaManager->IsStorageInitialized());
|
||||
|
||||
done = true;
|
||||
});
|
||||
|
||||
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||
|
||||
RefPtr<ClientDirectoryLock> directoryLock2 =
|
||||
quotaManager->CreateDirectoryLock(GetTestClientMetadata(),
|
||||
/* aExclusive */ false);
|
||||
|
||||
promises.Clear();
|
||||
|
||||
promises.AppendElement(quotaManager->InitializeStorage());
|
||||
promises.AppendElement(directoryLock2->Acquire());
|
||||
|
||||
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 simple ShutdownStorage.
|
||||
TEST_F(TestQuotaManager, ShutdownStorage_Simple) {
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
|
||||
PerformOnIOThread([]() {
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(InitializeStorage());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsInitialized());
|
||||
|
||||
PerformOnBackgroundThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
ASSERT_FALSE(quotaManager->IsStorageInitializedInternal());
|
||||
bool done = false;
|
||||
|
||||
ASSERT_NS_SUCCEEDED(quotaManager->EnsureStorageIsInitializedInternal());
|
||||
quotaManager->ShutdownStorage()->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&done](const BoolPromise::ResolveOrRejectValue& aValue) {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
ASSERT_TRUE(quotaManager->IsStorageInitializedInternal());
|
||||
ASSERT_FALSE(quotaManager->IsStorageInitialized());
|
||||
|
||||
done = true;
|
||||
});
|
||||
|
||||
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||
});
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
|
||||
PerformOnIOThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
ASSERT_FALSE(quotaManager->IsStorageInitializedInternal());
|
||||
});
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
}
|
||||
|
@ -50,16 +634,11 @@ TEST_F(TestQuotaManager, ShutdownStorage_Simple) {
|
|||
TEST_F(TestQuotaManager, ShutdownStorage_Ongoing) {
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
|
||||
PerformOnIOThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
ASSERT_FALSE(quotaManager->IsStorageInitializedInternal());
|
||||
ASSERT_NO_FATAL_FAILURE(InitializeStorage());
|
||||
|
||||
ASSERT_NS_SUCCEEDED(quotaManager->EnsureStorageIsInitializedInternal());
|
||||
|
||||
ASSERT_TRUE(quotaManager->IsStorageInitializedInternal());
|
||||
});
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsInitialized());
|
||||
|
||||
PerformOnBackgroundThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
|
@ -76,6 +655,11 @@ TEST_F(TestQuotaManager, ShutdownStorage_Ongoing) {
|
|||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&done](const CopyableTArray<bool>& aResolveValues) {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
ASSERT_FALSE(quotaManager->IsStorageInitialized());
|
||||
|
||||
done = true;
|
||||
},
|
||||
[&done](nsresult aRejectValue) {
|
||||
|
@ -87,12 +671,7 @@ TEST_F(TestQuotaManager, ShutdownStorage_Ongoing) {
|
|||
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||
});
|
||||
|
||||
PerformOnIOThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
ASSERT_FALSE(quotaManager->IsStorageInitializedInternal());
|
||||
});
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
}
|
||||
|
@ -102,16 +681,11 @@ TEST_F(TestQuotaManager, ShutdownStorage_Ongoing) {
|
|||
TEST_F(TestQuotaManager, ShutdownStorage_OngoingWithScheduledInitialization) {
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
|
||||
PerformOnIOThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
ASSERT_FALSE(quotaManager->IsStorageInitializedInternal());
|
||||
ASSERT_NO_FATAL_FAILURE(InitializeStorage());
|
||||
|
||||
ASSERT_NS_SUCCEEDED(quotaManager->EnsureStorageIsInitializedInternal());
|
||||
|
||||
ASSERT_TRUE(quotaManager->IsStorageInitializedInternal());
|
||||
});
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsInitialized());
|
||||
|
||||
PerformOnBackgroundThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
|
@ -120,11 +694,7 @@ TEST_F(TestQuotaManager, ShutdownStorage_OngoingWithScheduledInitialization) {
|
|||
nsTArray<RefPtr<BoolPromise>> promises;
|
||||
|
||||
promises.AppendElement(quotaManager->ShutdownStorage());
|
||||
// XXX We have to use ClearPrivateRepository for now because there's no
|
||||
// dedicated method for initializing storage on the PBackground thread yet.
|
||||
// ClearPrivateRepository triggers storage initialization before it clear
|
||||
// the private repository.
|
||||
promises.AppendElement(quotaManager->ClearPrivateRepository());
|
||||
promises.AppendElement(quotaManager->InitializeStorage());
|
||||
promises.AppendElement(quotaManager->ShutdownStorage());
|
||||
|
||||
bool done = false;
|
||||
|
@ -133,6 +703,11 @@ TEST_F(TestQuotaManager, ShutdownStorage_OngoingWithScheduledInitialization) {
|
|||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[&done](const CopyableTArray<bool>& aResolveValues) {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
ASSERT_FALSE(quotaManager->IsStorageInitialized());
|
||||
|
||||
done = true;
|
||||
},
|
||||
[&done](nsresult aRejectValue) {
|
||||
|
@ -144,12 +719,7 @@ TEST_F(TestQuotaManager, ShutdownStorage_OngoingWithScheduledInitialization) {
|
|||
SpinEventLoopUntil("Promise is fulfilled"_ns, [&done]() { return done; });
|
||||
});
|
||||
|
||||
PerformOnIOThread([]() {
|
||||
QuotaManager* quotaManager = QuotaManager::Get();
|
||||
ASSERT_TRUE(quotaManager);
|
||||
|
||||
ASSERT_FALSE(quotaManager->IsStorageInitializedInternal());
|
||||
});
|
||||
ASSERT_NO_FATAL_FAILURE(AssertStorageIsNotInitialized());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче