blob: 3ba6b822b713cd4af5bf53309d0220d60853b7a7 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "storage/browser/test/mock_quota_manager.h"
#include <memory>
#include <set>
#include "base/bind.h"
#include "base/containers/flat_set.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "storage/browser/quota/quota_client_type.h"
#include "storage/browser/test/mock_special_storage_policy.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::blink::StorageKey;
using ::blink::mojom::StorageType;
namespace storage {
namespace {
constexpr StorageType kTemporary = StorageType::kTemporary;
constexpr StorageType kPersistent = StorageType::kPersistent;
constexpr QuotaClientType kClientFile = QuotaClientType::kFileSystem;
constexpr QuotaClientType kClientDB = QuotaClientType::kIndexedDatabase;
} // namespace
class MockQuotaManagerTest : public testing::Test {
public:
MockQuotaManagerTest() : deletion_callback_count_(0) {}
void SetUp() override {
ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
policy_ = new MockSpecialStoragePolicy;
manager_ = new MockQuotaManager(
false /* is_incognito */, data_dir_.GetPath(),
base::ThreadTaskRunnerHandle::Get().get(), policy_.get());
}
void TearDown() override {
// Make sure the quota manager cleans up correctly.
manager_ = nullptr;
base::RunLoop().RunUntilIdle();
}
void GetModifiedStorageKeys(StorageType type,
base::Time begin,
base::Time end) {
manager_->GetStorageKeysModifiedBetween(
type, begin, end,
base::BindOnce(&MockQuotaManagerTest::GotModifiedStorageKeys,
weak_factory_.GetWeakPtr()));
}
void GotModifiedStorageKeys(const std::set<StorageKey>& storage_keys,
StorageType type) {
storage_keys_ = storage_keys;
type_ = type;
}
void DeleteStorageKeyData(const StorageKey& storage_key,
StorageType type,
QuotaClientTypes quota_client_types) {
manager_->DeleteStorageKeyData(
storage_key, type, std::move(quota_client_types),
base::BindOnce(&MockQuotaManagerTest::DeletedStorageKeyData,
weak_factory_.GetWeakPtr()));
}
void DeletedStorageKeyData(blink::mojom::QuotaStatusCode status) {
++deletion_callback_count_;
EXPECT_EQ(blink::mojom::QuotaStatusCode::kOk, status);
}
int deletion_callback_count() const {
return deletion_callback_count_;
}
MockQuotaManager* manager() const {
return manager_.get();
}
const std::set<StorageKey>& storage_keys() const { return storage_keys_; }
const StorageType& type() const {
return type_;
}
private:
base::test::TaskEnvironment task_environment_;
base::ScopedTempDir data_dir_;
scoped_refptr<MockQuotaManager> manager_;
scoped_refptr<MockSpecialStoragePolicy> policy_;
int deletion_callback_count_;
std::set<StorageKey> storage_keys_;
StorageType type_;
base::WeakPtrFactory<MockQuotaManagerTest> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(MockQuotaManagerTest);
};
TEST_F(MockQuotaManagerTest, BasicStorageKeyManipulation) {
const StorageKey kStorageKey1 =
StorageKey::CreateFromStringForTesting("http://host1:1/");
const StorageKey kStorageKey2 =
StorageKey::CreateFromStringForTesting("http://host2:1/");
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey1, kTemporary, kClientFile));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey1, kTemporary, kClientDB));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey1, kPersistent, kClientFile));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey1, kPersistent, kClientDB));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey2, kTemporary, kClientFile));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey2, kTemporary, kClientDB));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey2, kPersistent, kClientFile));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey2, kPersistent, kClientDB));
manager()->AddStorageKey(kStorageKey1, kTemporary, {kClientFile},
base::Time::Now());
EXPECT_TRUE(
manager()->StorageKeyHasData(kStorageKey1, kTemporary, kClientFile));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey1, kTemporary, kClientDB));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey1, kPersistent, kClientFile));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey1, kPersistent, kClientDB));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey2, kTemporary, kClientFile));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey2, kTemporary, kClientDB));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey2, kPersistent, kClientFile));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey2, kPersistent, kClientDB));
manager()->AddStorageKey(kStorageKey1, kPersistent, {kClientFile},
base::Time::Now());
EXPECT_TRUE(
manager()->StorageKeyHasData(kStorageKey1, kTemporary, kClientFile));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey1, kTemporary, kClientDB));
EXPECT_TRUE(
manager()->StorageKeyHasData(kStorageKey1, kPersistent, kClientFile));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey1, kPersistent, kClientDB));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey2, kTemporary, kClientFile));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey2, kTemporary, kClientDB));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey2, kPersistent, kClientFile));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey2, kPersistent, kClientDB));
manager()->AddStorageKey(kStorageKey2, kTemporary, {kClientFile, kClientDB},
base::Time::Now());
EXPECT_TRUE(
manager()->StorageKeyHasData(kStorageKey1, kTemporary, kClientFile));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey1, kTemporary, kClientDB));
EXPECT_TRUE(
manager()->StorageKeyHasData(kStorageKey1, kPersistent, kClientFile));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey1, kPersistent, kClientDB));
EXPECT_TRUE(
manager()->StorageKeyHasData(kStorageKey2, kTemporary, kClientFile));
EXPECT_TRUE(
manager()->StorageKeyHasData(kStorageKey2, kTemporary, kClientDB));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey2, kPersistent, kClientFile));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey2, kPersistent, kClientDB));
}
TEST_F(MockQuotaManagerTest, StorageKeyDeletion) {
const StorageKey kStorageKey1 =
StorageKey::CreateFromStringForTesting("http://host1:1/");
const StorageKey kStorageKey2 =
StorageKey::CreateFromStringForTesting("http://host2:1/");
const StorageKey kStorageKey3 =
StorageKey::CreateFromStringForTesting("http://host3:1/");
manager()->AddStorageKey(kStorageKey1, kTemporary, {kClientFile},
base::Time::Now());
manager()->AddStorageKey(kStorageKey2, kTemporary, {kClientFile, kClientDB},
base::Time::Now());
manager()->AddStorageKey(kStorageKey3, kTemporary, {kClientFile, kClientDB},
base::Time::Now());
DeleteStorageKeyData(kStorageKey2, kTemporary, {kClientFile});
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, deletion_callback_count());
EXPECT_TRUE(
manager()->StorageKeyHasData(kStorageKey1, kTemporary, kClientFile));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey2, kTemporary, kClientFile));
EXPECT_TRUE(
manager()->StorageKeyHasData(kStorageKey2, kTemporary, kClientDB));
EXPECT_TRUE(
manager()->StorageKeyHasData(kStorageKey3, kTemporary, kClientFile));
EXPECT_TRUE(
manager()->StorageKeyHasData(kStorageKey3, kTemporary, kClientDB));
DeleteStorageKeyData(kStorageKey3, kTemporary, {kClientFile, kClientDB});
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2, deletion_callback_count());
EXPECT_TRUE(
manager()->StorageKeyHasData(kStorageKey1, kTemporary, kClientFile));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey2, kTemporary, kClientFile));
EXPECT_TRUE(
manager()->StorageKeyHasData(kStorageKey2, kTemporary, kClientDB));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey3, kTemporary, kClientFile));
EXPECT_FALSE(
manager()->StorageKeyHasData(kStorageKey3, kTemporary, kClientDB));
}
TEST_F(MockQuotaManagerTest, ModifiedStorageKeys) {
const StorageKey kStorageKey1 =
StorageKey::CreateFromStringForTesting("http://host1:1/");
const StorageKey kStorageKey2 =
StorageKey::CreateFromStringForTesting("http://host2:1/");
base::Time now = base::Time::Now();
base::Time then = base::Time();
base::TimeDelta an_hour = base::TimeDelta::FromMilliseconds(3600000);
base::TimeDelta a_minute = base::TimeDelta::FromMilliseconds(60000);
GetModifiedStorageKeys(kTemporary, then, base::Time::Max());
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(storage_keys().empty());
manager()->AddStorageKey(kStorageKey1, kTemporary, {kClientFile},
now - an_hour);
GetModifiedStorageKeys(kTemporary, then, base::Time::Max());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(kTemporary, type());
EXPECT_EQ(1UL, storage_keys().size());
EXPECT_EQ(1UL, storage_keys().count(kStorageKey1));
EXPECT_EQ(0UL, storage_keys().count(kStorageKey2));
manager()->AddStorageKey(kStorageKey2, kTemporary, {kClientFile}, now);
GetModifiedStorageKeys(kTemporary, then, base::Time::Max());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(kTemporary, type());
EXPECT_EQ(2UL, storage_keys().size());
EXPECT_EQ(1UL, storage_keys().count(kStorageKey1));
EXPECT_EQ(1UL, storage_keys().count(kStorageKey2));
GetModifiedStorageKeys(kTemporary, then, now);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(kTemporary, type());
EXPECT_EQ(1UL, storage_keys().size());
EXPECT_EQ(1UL, storage_keys().count(kStorageKey1));
EXPECT_EQ(0UL, storage_keys().count(kStorageKey2));
GetModifiedStorageKeys(kTemporary, now - a_minute, now + a_minute);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(kTemporary, type());
EXPECT_EQ(1UL, storage_keys().size());
EXPECT_EQ(0UL, storage_keys().count(kStorageKey1));
EXPECT_EQ(1UL, storage_keys().count(kStorageKey2));
}
} // namespace storage