2cf9f175774a24ea009a3b3303723d907eb97680
[platform/framework/web/crosswalk.git] / src / content / browser / quota / quota_backend_impl_unittest.cc
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 "storage/browser/fileapi/quota/quota_backend_impl.h"
6
7 #include <string>
8
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/message_loop/message_loop.h"
11 #include "storage/browser/fileapi/file_system_usage_cache.h"
12 #include "storage/browser/fileapi/obfuscated_file_util.h"
13 #include "storage/browser/quota/quota_manager_proxy.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
16 #include "third_party/leveldatabase/src/include/leveldb/env.h"
17
18 using storage::FileSystemUsageCache;
19 using storage::ObfuscatedFileUtil;
20 using storage::QuotaBackendImpl;
21 using storage::SandboxFileSystemBackendDelegate;
22
23 namespace content {
24
25 namespace {
26
27 const char kOrigin[] = "http://example.com";
28
29 bool DidReserveQuota(bool accepted,
30                      base::File::Error* error_out,
31                      int64* delta_out,
32                      base::File::Error error,
33                      int64 delta) {
34   DCHECK(error_out);
35   DCHECK(delta_out);
36   *error_out = error;
37   *delta_out = delta;
38   return accepted;
39 }
40
41 class MockQuotaManagerProxy : public storage::QuotaManagerProxy {
42  public:
43   MockQuotaManagerProxy()
44       : QuotaManagerProxy(NULL, NULL),
45         storage_modified_count_(0),
46         usage_(0), quota_(0) {}
47
48   // We don't mock them.
49   void NotifyOriginInUse(const GURL& origin) override {}
50   void NotifyOriginNoLongerInUse(const GURL& origin) override {}
51   void SetUsageCacheEnabled(storage::QuotaClient::ID client_id,
52                             const GURL& origin,
53                             storage::StorageType type,
54                             bool enabled) override {}
55
56   void NotifyStorageModified(storage::QuotaClient::ID client_id,
57                              const GURL& origin,
58                              storage::StorageType type,
59                              int64 delta) override {
60     ++storage_modified_count_;
61     usage_ += delta;
62     ASSERT_LE(usage_, quota_);
63   }
64
65   void GetUsageAndQuota(base::SequencedTaskRunner* original_task_runner,
66                         const GURL& origin,
67                         storage::StorageType type,
68                         const GetUsageAndQuotaCallback& callback) override {
69     callback.Run(storage::kQuotaStatusOk, usage_, quota_);
70   }
71
72   int storage_modified_count() { return storage_modified_count_; }
73   int64 usage() { return usage_; }
74   void set_usage(int64 usage) { usage_ = usage; }
75   void set_quota(int64 quota) { quota_ = quota; }
76
77  protected:
78   ~MockQuotaManagerProxy() override {}
79
80  private:
81   int storage_modified_count_;
82   int64 usage_;
83   int64 quota_;
84
85   DISALLOW_COPY_AND_ASSIGN(MockQuotaManagerProxy);
86 };
87
88 }  // namespace
89
90 class QuotaBackendImplTest : public testing::Test {
91  public:
92   QuotaBackendImplTest()
93       : file_system_usage_cache_(file_task_runner()),
94         quota_manager_proxy_(new MockQuotaManagerProxy) {}
95
96   void SetUp() override {
97     ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
98     in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
99     file_util_.reset(ObfuscatedFileUtil::CreateForTesting(
100         NULL, data_dir_.path(), in_memory_env_.get(), file_task_runner()));
101     backend_.reset(new QuotaBackendImpl(file_task_runner(),
102                                         file_util_.get(),
103                                         &file_system_usage_cache_,
104                                         quota_manager_proxy_.get()));
105   }
106
107   void TearDown() override {
108     backend_.reset();
109     quota_manager_proxy_ = NULL;
110     file_util_.reset();
111     message_loop_.RunUntilIdle();
112   }
113
114  protected:
115   void InitializeForOriginAndType(const GURL& origin,
116                                   storage::FileSystemType type) {
117     ASSERT_TRUE(file_util_->InitOriginDatabase(origin, true /* create */));
118     ASSERT_TRUE(file_util_->origin_database_ != NULL);
119
120     std::string type_string =
121         SandboxFileSystemBackendDelegate::GetTypeString(type);
122     base::File::Error error = base::File::FILE_ERROR_FAILED;
123     base::FilePath path = file_util_->GetDirectoryForOriginAndType(
124         origin, type_string, true /* create */, &error);
125     ASSERT_EQ(base::File::FILE_OK, error);
126
127     ASSERT_TRUE(file_system_usage_cache_.UpdateUsage(
128         GetUsageCachePath(origin, type), 0));
129   }
130
131   base::SequencedTaskRunner* file_task_runner() {
132     return base::MessageLoopProxy::current().get();
133   }
134
135   base::FilePath GetUsageCachePath(const GURL& origin,
136                                    storage::FileSystemType type) {
137     base::FilePath path;
138     base::File::Error error =
139         backend_->GetUsageCachePath(origin, type, &path);
140     EXPECT_EQ(base::File::FILE_OK, error);
141     EXPECT_FALSE(path.empty());
142     return path;
143   }
144
145   base::MessageLoop message_loop_;
146   base::ScopedTempDir data_dir_;
147   scoped_ptr<leveldb::Env> in_memory_env_;
148   scoped_ptr<ObfuscatedFileUtil> file_util_;
149   FileSystemUsageCache file_system_usage_cache_;
150   scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_;
151   scoped_ptr<QuotaBackendImpl> backend_;
152
153  private:
154   DISALLOW_COPY_AND_ASSIGN(QuotaBackendImplTest);
155 };
156
157 TEST_F(QuotaBackendImplTest, ReserveQuota_Basic) {
158   storage::FileSystemType type = storage::kFileSystemTypeTemporary;
159   InitializeForOriginAndType(GURL(kOrigin), type);
160   quota_manager_proxy_->set_quota(10000);
161
162   int64 delta = 0;
163
164   const int64 kDelta1 = 1000;
165   base::File::Error error = base::File::FILE_ERROR_FAILED;
166   backend_->ReserveQuota(GURL(kOrigin), type, kDelta1,
167                          base::Bind(&DidReserveQuota, true, &error, &delta));
168   EXPECT_EQ(base::File::FILE_OK, error);
169   EXPECT_EQ(kDelta1, delta);
170   EXPECT_EQ(kDelta1, quota_manager_proxy_->usage());
171
172   const int64 kDelta2 = -300;
173   error = base::File::FILE_ERROR_FAILED;
174   backend_->ReserveQuota(GURL(kOrigin), type, kDelta2,
175                          base::Bind(&DidReserveQuota, true, &error, &delta));
176   EXPECT_EQ(base::File::FILE_OK, error);
177   EXPECT_EQ(kDelta2, delta);
178   EXPECT_EQ(kDelta1 + kDelta2, quota_manager_proxy_->usage());
179
180   EXPECT_EQ(2, quota_manager_proxy_->storage_modified_count());
181 }
182
183 TEST_F(QuotaBackendImplTest, ReserveQuota_NoSpace) {
184   storage::FileSystemType type = storage::kFileSystemTypeTemporary;
185   InitializeForOriginAndType(GURL(kOrigin), type);
186   quota_manager_proxy_->set_quota(100);
187
188   int64 delta = 0;
189
190   const int64 kDelta = 1000;
191   base::File::Error error = base::File::FILE_ERROR_FAILED;
192   backend_->ReserveQuota(GURL(kOrigin), type, kDelta,
193                          base::Bind(&DidReserveQuota, true, &error, &delta));
194   EXPECT_EQ(base::File::FILE_OK, error);
195   EXPECT_EQ(100, delta);
196   EXPECT_EQ(100, quota_manager_proxy_->usage());
197
198   EXPECT_EQ(1, quota_manager_proxy_->storage_modified_count());
199 }
200
201 TEST_F(QuotaBackendImplTest, ReserveQuota_Revert) {
202   storage::FileSystemType type = storage::kFileSystemTypeTemporary;
203   InitializeForOriginAndType(GURL(kOrigin), type);
204   quota_manager_proxy_->set_quota(10000);
205
206   int64 delta = 0;
207
208   const int64 kDelta = 1000;
209   base::File::Error error = base::File::FILE_ERROR_FAILED;
210   backend_->ReserveQuota(GURL(kOrigin), type, kDelta,
211                          base::Bind(&DidReserveQuota, false, &error, &delta));
212   EXPECT_EQ(base::File::FILE_OK, error);
213   EXPECT_EQ(kDelta, delta);
214   EXPECT_EQ(0, quota_manager_proxy_->usage());
215
216   EXPECT_EQ(2, quota_manager_proxy_->storage_modified_count());
217 }
218
219 TEST_F(QuotaBackendImplTest, ReleaseReservedQuota) {
220   storage::FileSystemType type = storage::kFileSystemTypeTemporary;
221   InitializeForOriginAndType(GURL(kOrigin), type);
222   const int64 kInitialUsage = 2000;
223   quota_manager_proxy_->set_usage(kInitialUsage);
224   quota_manager_proxy_->set_quota(10000);
225
226   const int64 kSize = 1000;
227   backend_->ReleaseReservedQuota(GURL(kOrigin), type, kSize);
228   EXPECT_EQ(kInitialUsage - kSize, quota_manager_proxy_->usage());
229
230   EXPECT_EQ(1, quota_manager_proxy_->storage_modified_count());
231 }
232
233 TEST_F(QuotaBackendImplTest, CommitQuotaUsage) {
234   storage::FileSystemType type = storage::kFileSystemTypeTemporary;
235   InitializeForOriginAndType(GURL(kOrigin), type);
236   quota_manager_proxy_->set_quota(10000);
237   base::FilePath path = GetUsageCachePath(GURL(kOrigin), type);
238
239   const int64 kDelta1 = 1000;
240   backend_->CommitQuotaUsage(GURL(kOrigin), type, kDelta1);
241   EXPECT_EQ(kDelta1, quota_manager_proxy_->usage());
242   int64 usage = 0;
243   EXPECT_TRUE(file_system_usage_cache_.GetUsage(path, &usage));
244   EXPECT_EQ(kDelta1, usage);
245
246   const int64 kDelta2 = -300;
247   backend_->CommitQuotaUsage(GURL(kOrigin), type, kDelta2);
248   EXPECT_EQ(kDelta1 + kDelta2, quota_manager_proxy_->usage());
249   usage = 0;
250   EXPECT_TRUE(file_system_usage_cache_.GetUsage(path, &usage));
251   EXPECT_EQ(kDelta1 + kDelta2, usage);
252
253   EXPECT_EQ(2, quota_manager_proxy_->storage_modified_count());
254 }
255
256 TEST_F(QuotaBackendImplTest, DirtyCount) {
257   storage::FileSystemType type = storage::kFileSystemTypeTemporary;
258   InitializeForOriginAndType(GURL(kOrigin), type);
259   base::FilePath path = GetUsageCachePath(GURL(kOrigin), type);
260
261   backend_->IncrementDirtyCount(GURL(kOrigin), type);
262   uint32 dirty = 0;
263   ASSERT_TRUE(file_system_usage_cache_.GetDirty(path, &dirty));
264   EXPECT_EQ(1u, dirty);
265
266   backend_->DecrementDirtyCount(GURL(kOrigin), type);
267   ASSERT_TRUE(file_system_usage_cache_.GetDirty(path, &dirty));
268   EXPECT_EQ(0u, dirty);
269 }
270
271 }  // namespace content