623 lines
22 KiB
C++
623 lines
22 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "FileSystemParentTest.h"
|
|
#include "FileSystemParentTestHelpers.h"
|
|
#include "FileSystemParentTypes.h"
|
|
#include "gmock/gmock.h"
|
|
#include "gtest/gtest.h"
|
|
#include "mozilla/dom/FileSystemQuotaClient.h"
|
|
#include "mozilla/dom/FileSystemQuotaClientFactory.h"
|
|
#include "mozilla/dom/quota/UsageInfo.h"
|
|
#include "nsIPrefBranch.h"
|
|
#include "nsIPrefService.h"
|
|
|
|
// This file is intended for integration tests which verify origin
|
|
// initialization.
|
|
|
|
namespace mozilla::dom::fs::test {
|
|
|
|
using ::testing::_;
|
|
using ::testing::Expectation;
|
|
using ::testing::Sequence;
|
|
|
|
namespace {
|
|
|
|
class MockFileSystemQuotaClient : public FileSystemQuotaClient {
|
|
public:
|
|
MOCK_METHOD((Result<quota::UsageInfo, nsresult>), InitOrigin,
|
|
(quota::PersistenceType aPersistenceType,
|
|
const quota::OriginMetadata& aOriginMetadata,
|
|
const AtomicBool& aCanceled),
|
|
(override));
|
|
|
|
MOCK_METHOD((Result<quota::UsageInfo, nsresult>), GetUsageForOrigin,
|
|
(quota::PersistenceType aPersistenceType,
|
|
const quota::OriginMetadata& aOriginMetadata,
|
|
const AtomicBool& aCanceled),
|
|
(override));
|
|
|
|
void DelegateToBase() {
|
|
// This exists just to workaround the false positive:
|
|
// ERROR: Refcounted variable 'this' of type 'mozilla::dom::fs::test::
|
|
// (anonymous namespace)::MockFileSystemQuotaClient' cannot be captured by
|
|
// a lambda
|
|
bool dummy;
|
|
|
|
ON_CALL(*this, InitOrigin)
|
|
.WillByDefault(
|
|
[&dummy, this](quota::PersistenceType aPersistenceType,
|
|
const quota::OriginMetadata& aOriginMetadata,
|
|
const Atomic<bool>& aCanceled) {
|
|
(void)dummy;
|
|
return FileSystemQuotaClient::InitOrigin(
|
|
aPersistenceType, aOriginMetadata, aCanceled);
|
|
});
|
|
|
|
ON_CALL(*this, GetUsageForOrigin)
|
|
.WillByDefault(
|
|
[&dummy, this](quota::PersistenceType aPersistenceType,
|
|
const quota::OriginMetadata& aOriginMetadata,
|
|
const Atomic<bool>& aCanceled) {
|
|
(void)dummy;
|
|
return FileSystemQuotaClient::GetUsageForOrigin(
|
|
aPersistenceType, aOriginMetadata, aCanceled);
|
|
});
|
|
}
|
|
};
|
|
|
|
class TestFileSystemQuotaClientFactory final
|
|
: public FileSystemQuotaClientFactory {
|
|
public:
|
|
already_AddRefed<MockFileSystemQuotaClient> GetQuotaClient() {
|
|
return do_AddRef(mQuotaClient);
|
|
}
|
|
|
|
protected:
|
|
already_AddRefed<quota::Client> AllocQuotaClient() override {
|
|
mQuotaClient = MakeRefPtr<MockFileSystemQuotaClient>();
|
|
mQuotaClient->DelegateToBase();
|
|
return do_AddRef(mQuotaClient);
|
|
}
|
|
|
|
RefPtr<MockFileSystemQuotaClient> mQuotaClient;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
class TestFileSystemOriginInitialization : public FileSystemParentTest {
|
|
protected:
|
|
static void SetUpTestCase() {
|
|
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
|
prefs->SetBoolPref("dom.quotaManager.loadQuotaFromCache", false);
|
|
|
|
auto factory = MakeRefPtr<TestFileSystemQuotaClientFactory>();
|
|
|
|
FileSystemQuotaClientFactory::SetCustomFactory(factory);
|
|
|
|
ASSERT_NO_FATAL_FAILURE(FileSystemParentTest::SetUpTestCase());
|
|
|
|
sQuotaClient = factory->GetQuotaClient();
|
|
}
|
|
|
|
static void TearDownTestCase() {
|
|
sQuotaClient = nullptr;
|
|
|
|
ASSERT_NO_FATAL_FAILURE(FileSystemParentTest::TearDownTestCase());
|
|
|
|
FileSystemQuotaClientFactory::SetCustomFactory(nullptr);
|
|
}
|
|
|
|
MOZ_RUNINIT static inline RefPtr<MockFileSystemQuotaClient> sQuotaClient;
|
|
};
|
|
|
|
TEST_F(TestFileSystemOriginInitialization, EmptyOriginDirectory) {
|
|
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
|
|
|
// Set expectations
|
|
{
|
|
Sequence s;
|
|
|
|
EXPECT_CALL(*sQuotaClient, InitOrigin(_, _, _)).Times(0).InSequence(s);
|
|
|
|
EXPECT_CALL(*sQuotaClient, GetUsageForOrigin(_, _, _))
|
|
.Times(0)
|
|
.InSequence(s);
|
|
}
|
|
|
|
// Initialize origin
|
|
ASSERT_NO_FATAL_FAILURE(InitializeStorage());
|
|
ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage());
|
|
ASSERT_NO_FATAL_FAILURE(
|
|
InitializeTemporaryOrigin(/* aCreateIfNonExistent */ true));
|
|
|
|
// After initialization,
|
|
// * origin usage is nothing
|
|
// * cached origin usage is zero
|
|
quota::UsageInfo usageNow;
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageIsNothing(usageNow));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, 0u));
|
|
|
|
// Shutdown temporary storage
|
|
ASSERT_NO_FATAL_FAILURE(ShutdownTemporaryStorage());
|
|
|
|
// After temporary storage shutdown,
|
|
// * origin usage is still nothing
|
|
// * cached origin is still zero
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageIsNothing(usageNow));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, 0u));
|
|
|
|
// Initialize temporary storage again.
|
|
ASSERT_NO_FATAL_FAILURE(AssertTemporaryStorageNotInitialized());
|
|
ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage());
|
|
|
|
// After repeated temporary storage initialization,
|
|
// * origin usage is still nothing
|
|
// * cached origin is still zero
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageIsNothing(usageNow));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, 0u));
|
|
}
|
|
|
|
TEST_F(TestFileSystemOriginInitialization, EmptyFileSystemDirectory) {
|
|
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
|
|
|
// Set expectations
|
|
{
|
|
Sequence s;
|
|
|
|
EXPECT_CALL(*sQuotaClient, InitOrigin(_, _, _)).Times(0).InSequence(s);
|
|
|
|
EXPECT_CALL(*sQuotaClient, GetUsageForOrigin(_, _, _))
|
|
.Times(0)
|
|
.InSequence(s);
|
|
}
|
|
|
|
// Initialize client
|
|
ASSERT_NO_FATAL_FAILURE(InitializeStorage());
|
|
ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage());
|
|
ASSERT_NO_FATAL_FAILURE(InitializeTemporaryOrigin());
|
|
ASSERT_NO_FATAL_FAILURE(InitializeTemporaryClient());
|
|
|
|
// After initialization,
|
|
// * origin usage is nothing
|
|
// * cached origin usage is zero
|
|
quota::UsageInfo usageNow;
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageIsNothing(usageNow));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, 0u));
|
|
|
|
// Shutdown temporary storage.
|
|
ASSERT_NO_FATAL_FAILURE(ShutdownTemporaryStorage());
|
|
|
|
// After temporary storage shutdown,
|
|
// * origin usage is still nothing
|
|
// * cached origin usage is still zero
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageIsNothing(usageNow));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, 0u));
|
|
|
|
// Initialize temporary storage again.
|
|
ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage());
|
|
|
|
// After repeated temporary storage initialization,
|
|
// * origin usage is still nothing
|
|
// * cached origin usage is still zero
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageIsNothing(usageNow));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, 0u));
|
|
}
|
|
|
|
TEST_F(TestFileSystemOriginInitialization, EmptyFileSystemDatabase) {
|
|
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
|
|
|
// Set expectations
|
|
{
|
|
Sequence s;
|
|
|
|
// GetOriginUsage check after database initialization.
|
|
EXPECT_CALL(*sQuotaClient, GetUsageForOrigin(_, _, _)).InSequence(s);
|
|
|
|
// GetOriginUsage check when temporary storage is not initialized.
|
|
EXPECT_CALL(*sQuotaClient, InitOrigin(_, _, _)).InSequence(s);
|
|
|
|
// Repeated temporary storage initialization.
|
|
EXPECT_CALL(*sQuotaClient, InitOrigin(_, _, _)).InSequence(s);
|
|
|
|
// Final GetOriginUsage check.
|
|
EXPECT_CALL(*sQuotaClient, GetUsageForOrigin(_, _, _)).InSequence(s);
|
|
}
|
|
|
|
// Initialize database
|
|
ASSERT_NO_FATAL_FAILURE(EnsureDataManager());
|
|
|
|
// After initialization,
|
|
// * origin usage is not zero
|
|
// * GetOriginUsage and GetCachedOriginUsage should agree
|
|
quota::UsageInfo usageNow;
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageGreaterThan(usageNow, 0u));
|
|
|
|
uint64_t beforeShutdownUsage;
|
|
ASSERT_NO_FATAL_FAILURE(GetUsageValue(usageNow, beforeShutdownUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
|
|
// Shutdown temporary storage.
|
|
ASSERT_NO_FATAL_FAILURE(ReleaseDataManager());
|
|
ASSERT_NO_FATAL_FAILURE(ShutdownTemporaryStorage());
|
|
|
|
// After temporary storage shutdown,
|
|
// * origin usage is still the same as before shutdown
|
|
// * cached origin usage is zero
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, 0u));
|
|
|
|
// Initialize temporary storage again.
|
|
ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage());
|
|
|
|
// After repeated temporary storage initialization,
|
|
// * origin usage is still the same as before shutdown
|
|
// * GetOriginUsage and GetCachedOriginUsage should agree again
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
}
|
|
|
|
TEST_F(TestFileSystemOriginInitialization, EmptyFileSystemFile) {
|
|
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
|
|
|
// Set expectations
|
|
{
|
|
Sequence s;
|
|
|
|
// GetOriginUsage check after file creation.
|
|
EXPECT_CALL(*sQuotaClient, GetUsageForOrigin(_, _, _)).InSequence(s);
|
|
|
|
// GetOriginUsage check when temporary storage is not initialized.
|
|
EXPECT_CALL(*sQuotaClient, InitOrigin(_, _, _)).InSequence(s);
|
|
|
|
// Repeated temporary storage initialization.
|
|
EXPECT_CALL(*sQuotaClient, InitOrigin(_, _, _)).InSequence(s);
|
|
|
|
// Final GetOriginUsage check.
|
|
EXPECT_CALL(*sQuotaClient, GetUsageForOrigin(_, _, _)).InSequence(s);
|
|
}
|
|
|
|
// Initialize database
|
|
ASSERT_NO_FATAL_FAILURE(EnsureDataManager());
|
|
|
|
// Create a new empty file
|
|
EntryId testFileId;
|
|
ASSERT_NO_FATAL_FAILURE(CreateNewEmptyFile(testFileId));
|
|
|
|
// After a new file has been created (only in the database),
|
|
// * origin usage is not zero
|
|
// * GetOriginUsage and GetCachedOriginUsage should agree
|
|
quota::UsageInfo usageNow;
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageGreaterThan(usageNow, 0u));
|
|
|
|
uint64_t beforeShutdownUsage;
|
|
ASSERT_NO_FATAL_FAILURE(GetUsageValue(usageNow, beforeShutdownUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
|
|
// Shutdown temporary storage.
|
|
ASSERT_NO_FATAL_FAILURE(ReleaseDataManager());
|
|
ASSERT_NO_FATAL_FAILURE(ShutdownTemporaryStorage());
|
|
|
|
// After temporary storage shutdown,
|
|
// * origin usage is still the same as before shutdown
|
|
// * cached origin usage is zero
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, 0u));
|
|
|
|
// Initialize temporary storage again.
|
|
ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage());
|
|
|
|
// After repeated temporary storage initialization,
|
|
// * origin usage is still the same as before shutdown
|
|
// * GetOriginUsage and GetCachedOriginUsage should agree
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
}
|
|
|
|
TEST_F(TestFileSystemOriginInitialization, NonEmptyFileSystemFile) {
|
|
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
|
|
|
// Set expectations
|
|
{
|
|
Sequence s;
|
|
|
|
// GetOriginUsage check after filling the file with content.
|
|
EXPECT_CALL(*sQuotaClient, GetUsageForOrigin(_, _, _)).InSequence(s);
|
|
|
|
// GetOriginUsage check after unlocking the file..
|
|
EXPECT_CALL(*sQuotaClient, GetUsageForOrigin(_, _, _)).InSequence(s);
|
|
|
|
// GetOriginUsage check when temporary storage is not initialized.
|
|
EXPECT_CALL(*sQuotaClient, InitOrigin(_, _, _)).InSequence(s);
|
|
|
|
// Repeated temporary storage initialization.
|
|
EXPECT_CALL(*sQuotaClient, InitOrigin(_, _, _)).InSequence(s);
|
|
|
|
// Final GetOriginUsage check.
|
|
EXPECT_CALL(*sQuotaClient, GetUsageForOrigin(_, _, _)).InSequence(s);
|
|
}
|
|
|
|
// Initialize database
|
|
ASSERT_NO_FATAL_FAILURE(EnsureDataManager());
|
|
|
|
// Create a new empty file
|
|
EntryId testFileId;
|
|
ASSERT_NO_FATAL_FAILURE(CreateNewEmptyFile(testFileId));
|
|
|
|
// Fill the file with some content
|
|
ASSERT_NO_FATAL_FAILURE(LockExclusive(testFileId));
|
|
|
|
const nsCString& testData = GetTestData();
|
|
|
|
ASSERT_NO_FATAL_FAILURE(WriteDataToFile(testFileId, testData));
|
|
|
|
// After the content has been written to the file,
|
|
// * origin usage is not zero
|
|
// * GetOriginUsage and GetCachedOriginUsage should agree
|
|
quota::UsageInfo usageNow;
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageGreaterThan(usageNow, 0u));
|
|
|
|
uint64_t beforeShutdownUsage;
|
|
ASSERT_NO_FATAL_FAILURE(GetUsageValue(usageNow, beforeShutdownUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(UnlockExclusive(testFileId));
|
|
|
|
// After the file has been unlocked,
|
|
// * origin usage is still the same as before unlocking
|
|
// * GetOriginUsage and GetCachedOriginUsage should still agree
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
|
|
// Shutdown temporary storage.
|
|
ASSERT_NO_FATAL_FAILURE(ReleaseDataManager());
|
|
ASSERT_NO_FATAL_FAILURE(ShutdownTemporaryStorage());
|
|
|
|
// After temporary storage shutdown,
|
|
// * origin usage is still the same as before shutdown
|
|
// * cached origin usage is zero
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, 0u));
|
|
|
|
// Initialize temporary storage again.
|
|
ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage());
|
|
|
|
// After repeated temporary storage initialization,
|
|
// * origin usage is still the same as before shutdown
|
|
// * GetOriginUsage and GetCachedOriginUsage should agree again
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
}
|
|
|
|
TEST_F(TestFileSystemOriginInitialization,
|
|
NonEmptyFileSystemFile_UncleanShutdown) {
|
|
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
|
|
|
// Set expectations
|
|
{
|
|
Sequence s;
|
|
|
|
// GetOriginUsage check after file creation.
|
|
EXPECT_CALL(*sQuotaClient, GetUsageForOrigin(_, _, _)).InSequence(s);
|
|
|
|
// GetOriginUsage check after filling the file with content.
|
|
EXPECT_CALL(*sQuotaClient, GetUsageForOrigin(_, _, _)).InSequence(s);
|
|
|
|
// GetOriginUsage check when temporary storage is not initialized.
|
|
EXPECT_CALL(*sQuotaClient, InitOrigin(_, _, _)).InSequence(s);
|
|
|
|
// Repeated temporary storage initialization.
|
|
EXPECT_CALL(*sQuotaClient, InitOrigin(_, _, _)).InSequence(s);
|
|
|
|
// Final GetOriginUsage check.
|
|
EXPECT_CALL(*sQuotaClient, GetUsageForOrigin(_, _, _)).InSequence(s);
|
|
}
|
|
|
|
// Initialize database
|
|
ASSERT_NO_FATAL_FAILURE(EnsureDataManager());
|
|
|
|
// Create a new empty file
|
|
EntryId testFileId;
|
|
ASSERT_NO_FATAL_FAILURE(CreateNewEmptyFile(testFileId));
|
|
|
|
// After a new file has been created (only in the database),
|
|
// * origin usage is not zero
|
|
// * GetOriginUsage and GetCachedOriginUsage should agree
|
|
quota::UsageInfo usageNow;
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageGreaterThan(usageNow, 0u));
|
|
|
|
uint64_t beforeWriteUsage;
|
|
ASSERT_NO_FATAL_FAILURE(GetUsageValue(usageNow, beforeWriteUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeWriteUsage));
|
|
|
|
// Fill the file with some content
|
|
ASSERT_NO_FATAL_FAILURE(LockExclusive(testFileId));
|
|
|
|
const nsCString& testData = GetTestData();
|
|
|
|
ASSERT_NO_FATAL_FAILURE(WriteDataToFile(testFileId, testData));
|
|
|
|
// After the content has been written to the file,
|
|
// * origin usage is not the same as before writing
|
|
// * GetOriginUsage and GetCachedOriginUsage should still agree
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageGreaterThan(usageNow, beforeWriteUsage));
|
|
|
|
uint64_t beforeShutdownUsage;
|
|
ASSERT_NO_FATAL_FAILURE(GetUsageValue(usageNow, beforeShutdownUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
|
|
// UnlockExclusive is not called here on purpose to simmulate unclean
|
|
// shutdown.
|
|
|
|
// Shutdown temporary storage.
|
|
ASSERT_NO_FATAL_FAILURE(ReleaseDataManager());
|
|
ASSERT_NO_FATAL_FAILURE(ShutdownTemporaryStorage());
|
|
|
|
// After temporary storage shutdown,
|
|
// * static database usage is the same as before writing
|
|
// * origin usage is still the same as before shutdown
|
|
// * cached origin usage is zero
|
|
ASSERT_NO_FATAL_FAILURE(GetStaticDatabaseUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeWriteUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, 0u));
|
|
|
|
// Initialize temporary storage again.
|
|
ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage());
|
|
|
|
// After repeated temporary storage initialization,
|
|
// * static database usage is the same as before shutdown
|
|
// * GetStaticDatabaseUsage, GetOriginUsage and GetCachedOriginUsage should
|
|
// all agree again
|
|
ASSERT_NO_FATAL_FAILURE(GetStaticDatabaseUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
}
|
|
|
|
TEST_F(TestFileSystemOriginInitialization, RemovedFileSystemFile) {
|
|
ASSERT_NO_FATAL_FAILURE(ShutdownStorage());
|
|
|
|
// Set expectations
|
|
{
|
|
Sequence s;
|
|
|
|
// GetOriginUsage check after removing the file..
|
|
EXPECT_CALL(*sQuotaClient, GetUsageForOrigin(_, _, _)).InSequence(s);
|
|
|
|
// GetOriginUsage check when temporary storage is not initialized.
|
|
EXPECT_CALL(*sQuotaClient, InitOrigin(_, _, _)).InSequence(s);
|
|
|
|
// Repeated temporary storage initialization.
|
|
EXPECT_CALL(*sQuotaClient, InitOrigin(_, _, _)).InSequence(s);
|
|
|
|
// Final GetOriginUsage check.
|
|
EXPECT_CALL(*sQuotaClient, GetUsageForOrigin(_, _, _)).InSequence(s);
|
|
}
|
|
|
|
// Initialize database
|
|
ASSERT_NO_FATAL_FAILURE(EnsureDataManager());
|
|
|
|
// Create a new empty file
|
|
EntryId testFileId;
|
|
ASSERT_NO_FATAL_FAILURE(CreateNewEmptyFile(testFileId));
|
|
|
|
// Fill the file with some content
|
|
ASSERT_NO_FATAL_FAILURE(LockExclusive(testFileId));
|
|
|
|
const nsCString& testData = GetTestData();
|
|
|
|
ASSERT_NO_FATAL_FAILURE(WriteDataToFile(testFileId, testData));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(UnlockExclusive(testFileId));
|
|
|
|
// Remove the file
|
|
bool wasRemoved;
|
|
ASSERT_NO_FATAL_FAILURE(RemoveFile(wasRemoved));
|
|
ASSERT_TRUE(wasRemoved);
|
|
|
|
// After the file has been removed,
|
|
// * origin usage is not zero
|
|
// * GetOriginUsage and GetCachedOriginUsage should agree
|
|
quota::UsageInfo usageNow;
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageGreaterThan(usageNow, 0u));
|
|
|
|
uint64_t beforeShutdownUsage;
|
|
ASSERT_NO_FATAL_FAILURE(GetUsageValue(usageNow, beforeShutdownUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
|
|
// Shutdown temporary storage.
|
|
ASSERT_NO_FATAL_FAILURE(ReleaseDataManager());
|
|
ASSERT_NO_FATAL_FAILURE(ShutdownTemporaryStorage());
|
|
|
|
// After temporary storage shutdown,
|
|
// * origin usage is still the same as before shutdown
|
|
// * cached origin usage is zero
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, 0u));
|
|
|
|
// Initialize temporary storage again.
|
|
ASSERT_NO_FATAL_FAILURE(InitializeTemporaryStorage());
|
|
|
|
// After repeated temporary storage initialization,
|
|
// * origin usage is still the same as before shutdown
|
|
// * GetOriginUsage and GetCachedOriginUsage should agree again
|
|
ASSERT_NO_FATAL_FAILURE(GetOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
|
|
ASSERT_NO_FATAL_FAILURE(GetCachedOriginUsage(usageNow));
|
|
ASSERT_NO_FATAL_FAILURE(CheckUsageEqualTo(usageNow, beforeShutdownUsage));
|
|
}
|
|
|
|
} // namespace mozilla::dom::fs::test
|