1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <set>
6
7#include "base/bind.h"
8#include "base/files/file_util.h"
9#include "base/files/scoped_temp_dir.h"
10#include "base/memory/scoped_ptr.h"
11#include "base/message_loop/message_loop_proxy.h"
12#include "base/run_loop.h"
13#include "content/browser/quota/mock_quota_manager.h"
14#include "content/public/test/mock_special_storage_policy.h"
15#include "content/public/test/mock_storage_client.h"
16#include "testing/gtest/include/gtest/gtest.h"
17
18using storage::kQuotaStatusOk;
19using storage::kStorageTypePersistent;
20using storage::kStorageTypeTemporary;
21
22namespace content {
23
24const char kTestOrigin1[] = "http://host1:1/";
25const char kTestOrigin2[] = "http://host2:1/";
26const char kTestOrigin3[] = "http://host3:1/";
27
28const GURL kOrigin1(kTestOrigin1);
29const GURL kOrigin2(kTestOrigin2);
30const GURL kOrigin3(kTestOrigin3);
31
32const StorageType kTemporary = kStorageTypeTemporary;
33const StorageType kPersistent = kStorageTypePersistent;
34
35const QuotaClient::ID kClientFile = QuotaClient::kFileSystem;
36const QuotaClient::ID kClientDB = QuotaClient::kIndexedDatabase;
37
38class MockQuotaManagerTest : public testing::Test {
39 public:
40  MockQuotaManagerTest()
41    : deletion_callback_count_(0),
42      weak_factory_(this) {
43  }
44
45  virtual void SetUp() {
46    ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
47    policy_ = new MockSpecialStoragePolicy;
48    manager_ = new MockQuotaManager(false /* is_incognito */,
49                                    data_dir_.path(),
50                                    base::MessageLoopProxy::current().get(),
51                                    base::MessageLoopProxy::current().get(),
52                                    policy_.get());
53  }
54
55  virtual void TearDown() {
56    // Make sure the quota manager cleans up correctly.
57    manager_ = NULL;
58    base::RunLoop().RunUntilIdle();
59  }
60
61  void GetModifiedOrigins(StorageType type, base::Time since) {
62    manager_->GetOriginsModifiedSince(
63        type, since,
64        base::Bind(&MockQuotaManagerTest::GotModifiedOrigins,
65                   weak_factory_.GetWeakPtr()));
66  }
67
68  void GotModifiedOrigins(const std::set<GURL>& origins, StorageType type) {
69    origins_ = origins;
70    type_ = type;
71  }
72
73  void DeleteOriginData(const GURL& origin, StorageType type,
74      int quota_client_mask) {
75    manager_->DeleteOriginData(
76        origin, type, quota_client_mask,
77        base::Bind(&MockQuotaManagerTest::DeletedOriginData,
78                   weak_factory_.GetWeakPtr()));
79  }
80
81  void DeletedOriginData(QuotaStatusCode status) {
82    ++deletion_callback_count_;
83    EXPECT_EQ(kQuotaStatusOk, status);
84  }
85
86  int deletion_callback_count() const {
87    return deletion_callback_count_;
88  }
89
90  MockQuotaManager* manager() const {
91    return manager_.get();
92  }
93
94  const std::set<GURL>& origins() const {
95    return origins_;
96  }
97
98  const StorageType& type() const {
99    return type_;
100  }
101
102 private:
103  base::MessageLoop message_loop_;
104  base::ScopedTempDir data_dir_;
105  scoped_refptr<MockQuotaManager> manager_;
106  scoped_refptr<MockSpecialStoragePolicy> policy_;
107
108  int deletion_callback_count_;
109
110  std::set<GURL> origins_;
111  StorageType type_;
112
113  base::WeakPtrFactory<MockQuotaManagerTest> weak_factory_;
114
115  DISALLOW_COPY_AND_ASSIGN(MockQuotaManagerTest);
116};
117
118TEST_F(MockQuotaManagerTest, BasicOriginManipulation) {
119  EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kTemporary, kClientFile));
120  EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kTemporary, kClientDB));
121  EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kPersistent, kClientFile));
122  EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kPersistent, kClientDB));
123  EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kTemporary, kClientFile));
124  EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kTemporary, kClientDB));
125  EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kPersistent, kClientFile));
126  EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kPersistent, kClientDB));
127
128  manager()->AddOrigin(kOrigin1, kTemporary, kClientFile, base::Time::Now());
129  EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kTemporary, kClientFile));
130  EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kTemporary, kClientDB));
131  EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kPersistent, kClientFile));
132  EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kPersistent, kClientDB));
133  EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kTemporary, kClientFile));
134  EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kTemporary, kClientDB));
135  EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kPersistent, kClientFile));
136  EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kPersistent, kClientDB));
137
138  manager()->AddOrigin(kOrigin1, kPersistent, kClientFile, base::Time::Now());
139  EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kTemporary, kClientFile));
140  EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kTemporary, kClientDB));
141  EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kPersistent, kClientFile));
142  EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kPersistent, kClientDB));
143  EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kTemporary, kClientFile));
144  EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kTemporary, kClientDB));
145  EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kPersistent, kClientFile));
146  EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kPersistent, kClientDB));
147
148  manager()->AddOrigin(kOrigin2, kTemporary, kClientFile | kClientDB,
149      base::Time::Now());
150  EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kTemporary, kClientFile));
151  EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kTemporary, kClientDB));
152  EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kPersistent, kClientFile));
153  EXPECT_FALSE(manager()->OriginHasData(kOrigin1, kPersistent, kClientDB));
154  EXPECT_TRUE(manager()->OriginHasData(kOrigin2, kTemporary, kClientFile));
155  EXPECT_TRUE(manager()->OriginHasData(kOrigin2, kTemporary, kClientDB));
156  EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kPersistent, kClientFile));
157  EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kPersistent, kClientDB));
158}
159
160TEST_F(MockQuotaManagerTest, OriginDeletion) {
161  manager()->AddOrigin(kOrigin1, kTemporary, kClientFile, base::Time::Now());
162  manager()->AddOrigin(kOrigin2, kTemporary, kClientFile | kClientDB,
163      base::Time::Now());
164  manager()->AddOrigin(kOrigin3, kTemporary, kClientFile | kClientDB,
165      base::Time::Now());
166
167  DeleteOriginData(kOrigin2, kTemporary, kClientFile);
168  base::RunLoop().RunUntilIdle();
169
170  EXPECT_EQ(1, deletion_callback_count());
171  EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kTemporary, kClientFile));
172  EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kTemporary, kClientFile));
173  EXPECT_TRUE(manager()->OriginHasData(kOrigin2, kTemporary, kClientDB));
174  EXPECT_TRUE(manager()->OriginHasData(kOrigin3, kTemporary, kClientFile));
175  EXPECT_TRUE(manager()->OriginHasData(kOrigin3, kTemporary, kClientDB));
176
177  DeleteOriginData(kOrigin3, kTemporary, kClientFile | kClientDB);
178  base::RunLoop().RunUntilIdle();
179
180  EXPECT_EQ(2, deletion_callback_count());
181  EXPECT_TRUE(manager()->OriginHasData(kOrigin1, kTemporary, kClientFile));
182  EXPECT_FALSE(manager()->OriginHasData(kOrigin2, kTemporary, kClientFile));
183  EXPECT_TRUE(manager()->OriginHasData(kOrigin2, kTemporary, kClientDB));
184  EXPECT_FALSE(manager()->OriginHasData(kOrigin3, kTemporary, kClientFile));
185  EXPECT_FALSE(manager()->OriginHasData(kOrigin3, kTemporary, kClientDB));
186}
187
188TEST_F(MockQuotaManagerTest, ModifiedOrigins) {
189  base::Time now = base::Time::Now();
190  base::Time then = base::Time();
191  base::TimeDelta an_hour = base::TimeDelta::FromMilliseconds(3600000);
192  base::TimeDelta a_minute = base::TimeDelta::FromMilliseconds(60000);
193
194  GetModifiedOrigins(kTemporary, then);
195  base::RunLoop().RunUntilIdle();
196  EXPECT_TRUE(origins().empty());
197
198  manager()->AddOrigin(kOrigin1, kTemporary, kClientFile, now - an_hour);
199
200  GetModifiedOrigins(kTemporary, then);
201  base::RunLoop().RunUntilIdle();
202
203  EXPECT_EQ(kTemporary, type());
204  EXPECT_EQ(1UL, origins().size());
205  EXPECT_EQ(1UL, origins().count(kOrigin1));
206  EXPECT_EQ(0UL, origins().count(kOrigin2));
207
208  manager()->AddOrigin(kOrigin2, kTemporary, kClientFile, now);
209
210  GetModifiedOrigins(kTemporary, then);
211  base::RunLoop().RunUntilIdle();
212
213  EXPECT_EQ(kTemporary, type());
214  EXPECT_EQ(2UL, origins().size());
215  EXPECT_EQ(1UL, origins().count(kOrigin1));
216  EXPECT_EQ(1UL, origins().count(kOrigin2));
217
218  GetModifiedOrigins(kTemporary, now - a_minute);
219  base::RunLoop().RunUntilIdle();
220
221  EXPECT_EQ(kTemporary, type());
222  EXPECT_EQ(1UL, origins().size());
223  EXPECT_EQ(0UL, origins().count(kOrigin1));
224  EXPECT_EQ(1UL, origins().count(kOrigin2));
225}
226}  // namespace content
227