зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1616003 - QM: Make it possible to verify initialization status from unit tests; r=ttung,dom-workers-and-storage-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D63052 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
36fd1ef404
Коммит
34927b46f0
|
@ -304,6 +304,14 @@ mozilla::ipc::IPCResult QuotaRequestChild::Recv__delete__(
|
|||
HandleResponse(aResponse.get_nsresult());
|
||||
break;
|
||||
|
||||
case RequestResponse::TStorageInitializedResponse:
|
||||
HandleResponse(aResponse.get_StorageInitializedResponse().initialized());
|
||||
break;
|
||||
|
||||
case RequestResponse::TTemporaryStorageInitializedResponse:
|
||||
HandleResponse(aResponse.get_TemporaryStorageInitializedResponse().initialized());
|
||||
break;
|
||||
|
||||
case RequestResponse::TInitResponse:
|
||||
case RequestResponse::TInitTemporaryStorageResponse:
|
||||
case RequestResponse::TClearOriginResponse:
|
||||
|
|
|
@ -1487,6 +1487,35 @@ class QuotaRequestBase : public NormalOriginOperationBase,
|
|||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
};
|
||||
|
||||
class InitializedRequestBase : public QuotaRequestBase {
|
||||
protected:
|
||||
bool mInitialized;
|
||||
|
||||
public:
|
||||
bool Init(Quota* aQuota) override;
|
||||
|
||||
protected:
|
||||
InitializedRequestBase();
|
||||
};
|
||||
|
||||
class StorageInitializedOp final : public InitializedRequestBase {
|
||||
private:
|
||||
~StorageInitializedOp() = default;
|
||||
|
||||
nsresult DoDirectoryWork(QuotaManager* aQuotaManager) override;
|
||||
|
||||
void GetResponse(RequestResponse& aResponse) override;
|
||||
};
|
||||
|
||||
class TemporaryStorageInitializedOp final : public InitializedRequestBase {
|
||||
private:
|
||||
~TemporaryStorageInitializedOp() = default;
|
||||
|
||||
nsresult DoDirectoryWork(QuotaManager* aQuotaManager) override;
|
||||
|
||||
void GetResponse(RequestResponse& aResponse) override;
|
||||
};
|
||||
|
||||
class InitOp final : public QuotaRequestBase {
|
||||
public:
|
||||
InitOp() : QuotaRequestBase(/* aExclusive */ false) {
|
||||
|
@ -6234,7 +6263,7 @@ nsresult QuotaManager::UpgradeLocalStorageArchiveFrom4To5(
|
|||
|
||||
void QuotaManager::AssertStorageIsInitialized() const {
|
||||
AssertIsOnIOThread();
|
||||
MOZ_ASSERT(mStorageConnection);
|
||||
MOZ_ASSERT(IsStorageInitialized());
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
||||
|
@ -8503,6 +8532,8 @@ bool Quota::VerifyRequestParams(const RequestParams& aParams) const {
|
|||
MOZ_ASSERT(aParams.type() != RequestParams::T__None);
|
||||
|
||||
switch (aParams.type()) {
|
||||
case RequestParams::TStorageInitializedParams:
|
||||
case RequestParams::TTemporaryStorageInitializedParams:
|
||||
case RequestParams::TInitParams:
|
||||
case RequestParams::TInitTemporaryStorageParams:
|
||||
break;
|
||||
|
@ -8695,6 +8726,14 @@ PQuotaRequestParent* Quota::AllocPQuotaRequestParent(
|
|||
RefPtr<QuotaRequestBase> actor;
|
||||
|
||||
switch (aParams.type()) {
|
||||
case RequestParams::TStorageInitializedParams:
|
||||
actor = new StorageInitializedOp();
|
||||
break;
|
||||
|
||||
case RequestParams::TTemporaryStorageInitializedParams:
|
||||
actor = new TemporaryStorageInitializedOp();
|
||||
break;
|
||||
|
||||
case RequestParams::TInitParams:
|
||||
actor = new InitOp();
|
||||
break;
|
||||
|
@ -9320,6 +9359,65 @@ void QuotaRequestBase::ActorDestroy(ActorDestroyReason aWhy) {
|
|||
NoteActorDestroyed();
|
||||
}
|
||||
|
||||
InitializedRequestBase::InitializedRequestBase()
|
||||
: QuotaRequestBase(/* aExclusive */ false), mInitialized(false) {
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
// Overwrite NormalOriginOperationBase default values.
|
||||
mNeedsDirectoryLocking = false;
|
||||
|
||||
// Overwrite OriginOperationBase default values.
|
||||
mNeedsQuotaManagerInit = true;
|
||||
mNeedsStorageInit = false;
|
||||
}
|
||||
|
||||
bool InitializedRequestBase::Init(Quota* aQuota) {
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aQuota);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult StorageInitializedOp::DoDirectoryWork(QuotaManager* aQuotaManager) {
|
||||
AssertIsOnIOThread();
|
||||
|
||||
AUTO_PROFILER_LABEL("StorageInitializedOp::DoDirectoryWork", OTHER);
|
||||
|
||||
mInitialized = aQuotaManager->IsStorageInitialized();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void StorageInitializedOp::GetResponse(RequestResponse& aResponse) {
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
StorageInitializedResponse storageInitializedResponse;
|
||||
|
||||
storageInitializedResponse.initialized() = mInitialized;
|
||||
|
||||
aResponse = storageInitializedResponse;
|
||||
}
|
||||
|
||||
nsresult TemporaryStorageInitializedOp::DoDirectoryWork(QuotaManager* aQuotaManager) {
|
||||
AssertIsOnIOThread();
|
||||
|
||||
AUTO_PROFILER_LABEL("TemporaryStorageInitializedOp::DoDirectoryWork", OTHER);
|
||||
|
||||
mInitialized = aQuotaManager->IsTemporaryStorageInitialized();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void TemporaryStorageInitializedOp::GetResponse(RequestResponse& aResponse) {
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
TemporaryStorageInitializedResponse temporaryStorageInitializedResponse;
|
||||
|
||||
temporaryStorageInitializedResponse.initialized() = mInitialized;
|
||||
|
||||
aResponse = temporaryStorageInitializedResponse;
|
||||
}
|
||||
|
||||
nsresult InitOp::DoDirectoryWork(QuotaManager* aQuotaManager) {
|
||||
AssertIsOnIOThread();
|
||||
|
||||
|
|
|
@ -26,6 +26,14 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
namespace quota {
|
||||
|
||||
struct StorageInitializedParams
|
||||
{
|
||||
};
|
||||
|
||||
struct TemporaryStorageInitializedParams
|
||||
{
|
||||
};
|
||||
|
||||
struct InitParams
|
||||
{
|
||||
};
|
||||
|
@ -113,6 +121,8 @@ struct ListOriginsParams
|
|||
|
||||
union RequestParams
|
||||
{
|
||||
StorageInitializedParams;
|
||||
TemporaryStorageInitializedParams;
|
||||
InitParams;
|
||||
InitTemporaryStorageParams;
|
||||
InitStorageAndOriginParams;
|
||||
|
|
|
@ -8,6 +8,16 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
namespace quota {
|
||||
|
||||
struct StorageInitializedResponse
|
||||
{
|
||||
bool initialized;
|
||||
};
|
||||
|
||||
struct TemporaryStorageInitializedResponse
|
||||
{
|
||||
bool initialized;
|
||||
};
|
||||
|
||||
struct InitResponse
|
||||
{
|
||||
};
|
||||
|
@ -64,6 +74,8 @@ struct ListOriginsResponse
|
|||
union RequestResponse
|
||||
{
|
||||
nsresult;
|
||||
StorageInitializedResponse;
|
||||
TemporaryStorageInitializedResponse;
|
||||
InitResponse;
|
||||
InitTemporaryStorageResponse;
|
||||
InitStorageAndOriginResponse;
|
||||
|
|
|
@ -327,6 +327,11 @@ class QuotaManager final : public BackgroundThreadObject {
|
|||
template <typename P>
|
||||
void CollectPendingOriginsForListing(P aPredicate);
|
||||
|
||||
bool IsStorageInitialized() const {
|
||||
AssertIsOnIOThread();
|
||||
return static_cast<bool>(mStorageConnection);
|
||||
}
|
||||
|
||||
void AssertStorageIsInitialized() const
|
||||
#ifdef DEBUG
|
||||
;
|
||||
|
|
|
@ -385,6 +385,54 @@ NS_IMPL_RELEASE_WITH_DESTROY(QuotaManagerService, Destroy())
|
|||
NS_IMPL_QUERY_INTERFACE(QuotaManagerService, nsIQuotaManagerService,
|
||||
nsIObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
QuotaManagerService::StorageInitialized(nsIQuotaRequest** _retval) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
|
||||
|
||||
if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
RefPtr<Request> request = new Request();
|
||||
|
||||
StorageInitializedParams params;
|
||||
|
||||
nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
|
||||
|
||||
nsresult rv = InitiateRequest(info);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
request.forget(_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
QuotaManagerService::TemporaryStorageInitialized(nsIQuotaRequest** _retval) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
|
||||
|
||||
if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
RefPtr<Request> request = new Request();
|
||||
|
||||
TemporaryStorageInitializedParams params;
|
||||
|
||||
nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
|
||||
|
||||
nsresult rv = InitiateRequest(info);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
request.forget(_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
QuotaManagerService::Init(nsIQuotaRequest** _retval) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
|
|
@ -15,6 +15,18 @@ interface nsIQuotaUsageRequest;
|
|||
[scriptable, builtinclass, uuid(1b3d0a38-8151-4cf9-89fa-4f92c2ef0e7e)]
|
||||
interface nsIQuotaManagerService : nsISupports
|
||||
{
|
||||
/**
|
||||
* Check if storage is initialized.
|
||||
*/
|
||||
[must_use] nsIQuotaRequest
|
||||
storageInitialized();
|
||||
|
||||
/**
|
||||
* Check if temporary storage is initialized.
|
||||
*/
|
||||
[must_use] nsIQuotaRequest
|
||||
temporaryStorageInitialized();
|
||||
|
||||
/**
|
||||
* Initializes storage directory. This can be used in tests to verify
|
||||
* upgrade methods.
|
||||
|
|
|
@ -116,6 +116,20 @@ function resetGlobalLimit() {
|
|||
SpecialPowers.clearUserPref("dom.quotaManager.temporaryStorage.fixedLimit");
|
||||
}
|
||||
|
||||
function storageInitialized(callback) {
|
||||
let request = SpecialPowers._getQuotaManager().storageInitialized();
|
||||
request.callback = callback;
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
function temporaryStorageInitialized(callback) {
|
||||
let request = SpecialPowers._getQuotaManager().temporaryStorageInitialized();
|
||||
request.callback = callback;
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
function init(callback) {
|
||||
let request = SpecialPowers._getQuotaManager().init();
|
||||
request.callback = callback;
|
||||
|
@ -680,3 +694,39 @@ function verifyStorage(packageDefinitionRelativePaths, key) {
|
|||
|
||||
compareEntries(currentEntries, expectedEntries, key);
|
||||
}
|
||||
|
||||
async function verifyInitializationStatus(
|
||||
expectStorageIsInitialized,
|
||||
expectTemporaryStorageIsInitialized
|
||||
) {
|
||||
if (!expectStorageIsInitialized && expectTemporaryStorageIsInitialized) {
|
||||
throw new Error("Invalid expectation");
|
||||
}
|
||||
|
||||
let request = storageInitialized();
|
||||
await requestFinished(request);
|
||||
|
||||
const storageIsInitialized = request.result;
|
||||
|
||||
request = temporaryStorageInitialized();
|
||||
await requestFinished(request);
|
||||
|
||||
const temporaryStorageIsInitialized = request.result;
|
||||
|
||||
ok(
|
||||
!(!storageIsInitialized && temporaryStorageIsInitialized),
|
||||
"Initialization status is consistent"
|
||||
);
|
||||
|
||||
if (expectStorageIsInitialized) {
|
||||
ok(storageIsInitialized, "Storage is initialized");
|
||||
} else {
|
||||
ok(!storageIsInitialized, "Storage is not initialized");
|
||||
}
|
||||
|
||||
if (expectTemporaryStorageIsInitialized) {
|
||||
ok(temporaryStorageIsInitialized, "Temporary storage is initialized");
|
||||
} else {
|
||||
ok(!temporaryStorageIsInitialized, "Temporary storage is not initialized");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,11 @@ function* testSteps() {
|
|||
clear(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
info("Verifying initialization status");
|
||||
|
||||
verifyInitializationStatus(false, false).then(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
info("Getting usage");
|
||||
|
||||
getCurrentUsage(grabUsageAndContinueHandler);
|
||||
|
@ -42,11 +47,21 @@ function* testSteps() {
|
|||
|
||||
ok(usage == 0, "Usage is zero");
|
||||
|
||||
info("Verifying initialization status");
|
||||
|
||||
verifyInitializationStatus(true, false).then(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
info("Clearing");
|
||||
|
||||
clear(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
info("Verifying initialization status");
|
||||
|
||||
verifyInitializationStatus(false, false).then(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
info("Installing package");
|
||||
|
||||
// The profile contains just one empty IndexedDB database. The file
|
||||
|
@ -62,6 +77,11 @@ function* testSteps() {
|
|||
|
||||
ok(usage > 0, "Usage is not zero");
|
||||
|
||||
info("Verifying initialization status");
|
||||
|
||||
verifyInitializationStatus(true, false).then(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
info("Clearing");
|
||||
|
||||
clear(continueToNextStepSync);
|
||||
|
@ -74,9 +94,14 @@ function* testSteps() {
|
|||
let exists = file.exists();
|
||||
ok(!exists, "Storage file doesn't exist");
|
||||
|
||||
info("Verifying initialization status");
|
||||
|
||||
verifyInitializationStatus(false, false).then(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
info("Initializing");
|
||||
|
||||
let request = init(continueToNextStepSync);
|
||||
request = init(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
ok(request.resultCode == NS_OK, "Initialization succeeded");
|
||||
|
@ -84,6 +109,11 @@ function* testSteps() {
|
|||
exists = file.exists();
|
||||
ok(exists, "Storage file does exist");
|
||||
|
||||
info("Verifying initialization status");
|
||||
|
||||
verifyInitializationStatus(true, false).then(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
info("Initializing origin");
|
||||
|
||||
request = initStorageAndChromeOrigin("persistent", continueToNextStepSync);
|
||||
|
@ -105,5 +135,11 @@ function* testSteps() {
|
|||
}
|
||||
}
|
||||
|
||||
info("Verifying initialization status");
|
||||
|
||||
verifyInitializationStatus(true, false).then(continueToNextStepSync);
|
||||
|
||||
yield undefined;
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
|
|
@ -33,4 +33,8 @@ async function testSteps() {
|
|||
metadataFile.append(metadataFileName);
|
||||
|
||||
ok(metadataFile.exists(), "Directory metadata file does exist");
|
||||
|
||||
info("Verifying initialization status");
|
||||
|
||||
await verifyInitializationStatus(true, true);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче