1// Copyright (c) 2012 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 "base/basictypes.h"
6#include "base/bind.h"
7#include "base/file_util.h"
8#include "base/files/scoped_temp_dir.h"
9#include "base/message_loop/message_loop.h"
10#include "base/message_loop/message_loop_proxy.h"
11#include "base/platform_file.h"
12#include "testing/gtest/include/gtest/gtest.h"
13#include "url/gurl.h"
14#include "webkit/browser/fileapi/file_system_context.h"
15#include "webkit/browser/fileapi/file_system_operation_context.h"
16#include "webkit/browser/fileapi/file_system_quota_client.h"
17#include "webkit/browser/fileapi/file_system_usage_cache.h"
18#include "webkit/browser/fileapi/mock_file_system_context.h"
19#include "webkit/browser/fileapi/obfuscated_file_util.h"
20#include "webkit/common/fileapi/file_system_types.h"
21#include "webkit/common/fileapi/file_system_util.h"
22#include "webkit/common/quota/quota_types.h"
23
24namespace fileapi {
25namespace {
26
27const char kDummyURL1[] = "http://www.dummy.org";
28const char kDummyURL2[] = "http://www.example.com";
29const char kDummyURL3[] = "http://www.bleh";
30
31// Declared to shorten the variable names.
32const quota::StorageType kTemporary = quota::kStorageTypeTemporary;
33const quota::StorageType kPersistent = quota::kStorageTypePersistent;
34
35}  // namespace
36
37class FileSystemQuotaClientTest : public testing::Test {
38 public:
39  FileSystemQuotaClientTest()
40      : weak_factory_(this),
41        additional_callback_count_(0),
42        deletion_status_(quota::kQuotaStatusUnknown) {
43  }
44
45  virtual void SetUp() {
46    ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
47    file_system_context_ = CreateFileSystemContextForTesting(
48            NULL, data_dir_.path());
49  }
50
51  struct TestFile {
52    bool isDirectory;
53    const char* name;
54    int64 size;
55    const char* origin_url;
56    quota::StorageType type;
57  };
58
59 protected:
60  FileSystemQuotaClient* NewQuotaClient(bool is_incognito) {
61    return new FileSystemQuotaClient(file_system_context_.get(), is_incognito);
62  }
63
64  void GetOriginUsageAsync(FileSystemQuotaClient* quota_client,
65                           const std::string& origin_url,
66                           quota::StorageType type) {
67    quota_client->GetOriginUsage(
68        GURL(origin_url), type,
69        base::Bind(&FileSystemQuotaClientTest::OnGetUsage,
70                   weak_factory_.GetWeakPtr()));
71  }
72
73  int64 GetOriginUsage(FileSystemQuotaClient* quota_client,
74                       const std::string& origin_url,
75                       quota::StorageType type) {
76    GetOriginUsageAsync(quota_client, origin_url, type);
77    base::MessageLoop::current()->RunUntilIdle();
78    return usage_;
79  }
80
81  const std::set<GURL>& GetOriginsForType(FileSystemQuotaClient* quota_client,
82                                          quota::StorageType type) {
83    origins_.clear();
84    quota_client->GetOriginsForType(
85        type,
86        base::Bind(&FileSystemQuotaClientTest::OnGetOrigins,
87                   weak_factory_.GetWeakPtr()));
88    base::MessageLoop::current()->RunUntilIdle();
89    return origins_;
90  }
91
92  const std::set<GURL>& GetOriginsForHost(FileSystemQuotaClient* quota_client,
93                                          quota::StorageType type,
94                                          const std::string& host) {
95    origins_.clear();
96    quota_client->GetOriginsForHost(
97        type, host,
98        base::Bind(&FileSystemQuotaClientTest::OnGetOrigins,
99                   weak_factory_.GetWeakPtr()));
100    base::MessageLoop::current()->RunUntilIdle();
101    return origins_;
102  }
103
104  void RunAdditionalOriginUsageTask(FileSystemQuotaClient* quota_client,
105                                    const std::string& origin_url,
106                                    quota::StorageType type) {
107    quota_client->GetOriginUsage(
108        GURL(origin_url), type,
109        base::Bind(&FileSystemQuotaClientTest::OnGetAdditionalUsage,
110                   weak_factory_.GetWeakPtr()));
111  }
112
113  FileSystemOperationContext* CreateFileSystemOperationContext(
114      FileSystemType type) {
115    FileSystemOperationContext* context =
116        new FileSystemOperationContext(file_system_context_.get());
117    context->set_allowed_bytes_growth(100000000);
118    context->set_update_observers(
119        *file_system_context_->GetUpdateObservers(type));
120    return context;
121  }
122
123  bool CreateFileSystemDirectory(const base::FilePath& file_path,
124                                 const std::string& origin_url,
125                                 quota::StorageType storage_type) {
126    FileSystemType type = QuotaStorageTypeToFileSystemType(storage_type);
127    FileSystemFileUtil* file_util = file_system_context_->GetFileUtil(type);
128
129    FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL(
130        GURL(origin_url), type, file_path);
131    scoped_ptr<FileSystemOperationContext> context(
132        CreateFileSystemOperationContext(type));
133
134    base::PlatformFileError result =
135        file_util->CreateDirectory(context.get(), url, false, false);
136    if (result != base::PLATFORM_FILE_OK)
137      return false;
138    return true;
139  }
140
141  bool CreateFileSystemFile(const base::FilePath& file_path,
142                            int64 file_size,
143                            const std::string& origin_url,
144                            quota::StorageType storage_type) {
145    if (file_path.empty())
146      return false;
147
148    FileSystemType type = QuotaStorageTypeToFileSystemType(storage_type);
149    FileSystemFileUtil* file_util = file_system_context_->GetFileUtil(type);
150
151    FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL(
152        GURL(origin_url), type, file_path);
153    scoped_ptr<FileSystemOperationContext> context(
154        CreateFileSystemOperationContext(type));
155
156    bool created = false;
157    if (base::PLATFORM_FILE_OK !=
158        file_util->EnsureFileExists(context.get(), url, &created))
159      return false;
160    EXPECT_TRUE(created);
161    if (base::PLATFORM_FILE_OK !=
162        file_util->Truncate(context.get(), url, file_size))
163      return false;
164    return true;
165  }
166
167  void InitializeOriginFiles(FileSystemQuotaClient* quota_client,
168                             const TestFile* files,
169                             int num_files) {
170    for (int i = 0; i < num_files; i++) {
171      base::FilePath path = base::FilePath().AppendASCII(files[i].name);
172      if (files[i].isDirectory) {
173        ASSERT_TRUE(CreateFileSystemDirectory(
174            path, files[i].origin_url, files[i].type));
175        if (path.empty()) {
176          // Create the usage cache.
177          // HACK--we always create the root [an empty path] first.  If we
178          // create it later, this will fail due to a quota mismatch.  If we
179          // call this before we create the root, it succeeds, but hasn't
180          // actually created the cache.
181          ASSERT_EQ(0, GetOriginUsage(
182              quota_client, files[i].origin_url, files[i].type));
183        }
184      } else {
185        ASSERT_TRUE(CreateFileSystemFile(
186            path, files[i].size, files[i].origin_url, files[i].type));
187      }
188    }
189  }
190
191  // This is a bit fragile--it depends on the test data always creating a
192  // directory before adding a file or directory to it, so that we can just
193  // count the basename of each addition.  A recursive creation of a path, which
194  // created more than one directory in a single shot, would break this.
195  int64 ComputeFilePathsCostForOriginAndType(const TestFile* files,
196                                             int num_files,
197                                             const std::string& origin_url,
198                                             quota::StorageType type) {
199    int64 file_paths_cost = 0;
200    for (int i = 0; i < num_files; i++) {
201      if (files[i].type == type &&
202          GURL(files[i].origin_url) == GURL(origin_url)) {
203        base::FilePath path = base::FilePath().AppendASCII(files[i].name);
204        if (!path.empty()) {
205          file_paths_cost += ObfuscatedFileUtil::ComputeFilePathCost(path);
206        }
207      }
208    }
209    return file_paths_cost;
210  }
211
212  void DeleteOriginData(FileSystemQuotaClient* quota_client,
213                        const std::string& origin,
214                        quota::StorageType type) {
215    deletion_status_ = quota::kQuotaStatusUnknown;
216    quota_client->DeleteOriginData(
217        GURL(origin), type,
218        base::Bind(&FileSystemQuotaClientTest::OnDeleteOrigin,
219                   weak_factory_.GetWeakPtr()));
220  }
221
222  int64 usage() const { return usage_; }
223  quota::QuotaStatusCode status() { return deletion_status_; }
224  int additional_callback_count() const { return additional_callback_count_; }
225  void set_additional_callback_count(int count) {
226    additional_callback_count_ = count;
227  }
228
229 private:
230  void OnGetUsage(int64 usage) {
231    usage_ = usage;
232  }
233
234  void OnGetOrigins(const std::set<GURL>& origins) {
235    origins_ = origins;
236  }
237
238  void OnGetAdditionalUsage(int64 usage_unused) {
239    ++additional_callback_count_;
240  }
241
242  void OnDeleteOrigin(quota::QuotaStatusCode status) {
243    deletion_status_ = status;
244  }
245
246  base::ScopedTempDir data_dir_;
247  base::MessageLoop message_loop_;
248  scoped_refptr<FileSystemContext> file_system_context_;
249  base::WeakPtrFactory<FileSystemQuotaClientTest> weak_factory_;
250  int64 usage_;
251  int additional_callback_count_;
252  std::set<GURL> origins_;
253  quota::QuotaStatusCode deletion_status_;
254
255  DISALLOW_COPY_AND_ASSIGN(FileSystemQuotaClientTest);
256};
257
258TEST_F(FileSystemQuotaClientTest, NoFileSystemTest) {
259  scoped_ptr<FileSystemQuotaClient> quota_client(NewQuotaClient(false));
260
261  EXPECT_EQ(0, GetOriginUsage(quota_client.get(), kDummyURL1, kTemporary));
262}
263
264TEST_F(FileSystemQuotaClientTest, NoFileTest) {
265  scoped_ptr<FileSystemQuotaClient> quota_client(NewQuotaClient(false));
266  const TestFile kFiles[] = {
267    {true, NULL, 0, kDummyURL1, kTemporary},
268  };
269  InitializeOriginFiles(quota_client.get(), kFiles, ARRAYSIZE_UNSAFE(kFiles));
270
271  for (int i = 0; i < 2; i++) {
272    EXPECT_EQ(0, GetOriginUsage(quota_client.get(), kDummyURL1, kTemporary));
273  }
274}
275
276TEST_F(FileSystemQuotaClientTest, OneFileTest) {
277  scoped_ptr<FileSystemQuotaClient> quota_client(NewQuotaClient(false));
278  const TestFile kFiles[] = {
279    {true, NULL, 0, kDummyURL1, kTemporary},
280    {false, "foo", 4921, kDummyURL1, kTemporary},
281  };
282  InitializeOriginFiles(quota_client.get(), kFiles, ARRAYSIZE_UNSAFE(kFiles));
283  const int64 file_paths_cost = ComputeFilePathsCostForOriginAndType(
284      kFiles, ARRAYSIZE_UNSAFE(kFiles), kDummyURL1, kTemporary);
285
286  for (int i = 0; i < 2; i++) {
287    EXPECT_EQ(4921 + file_paths_cost,
288        GetOriginUsage(quota_client.get(), kDummyURL1, kTemporary));
289  }
290}
291
292TEST_F(FileSystemQuotaClientTest, TwoFilesTest) {
293  scoped_ptr<FileSystemQuotaClient> quota_client(NewQuotaClient(false));
294  const TestFile kFiles[] = {
295    {true, NULL, 0, kDummyURL1, kTemporary},
296    {false, "foo", 10310, kDummyURL1, kTemporary},
297    {false, "bar", 41, kDummyURL1, kTemporary},
298  };
299  InitializeOriginFiles(quota_client.get(), kFiles, ARRAYSIZE_UNSAFE(kFiles));
300  const int64 file_paths_cost = ComputeFilePathsCostForOriginAndType(
301      kFiles, ARRAYSIZE_UNSAFE(kFiles), kDummyURL1, kTemporary);
302
303  for (int i = 0; i < 2; i++) {
304    EXPECT_EQ(10310 + 41 + file_paths_cost,
305        GetOriginUsage(quota_client.get(), kDummyURL1, kTemporary));
306  }
307}
308
309TEST_F(FileSystemQuotaClientTest, EmptyFilesTest) {
310  scoped_ptr<FileSystemQuotaClient> quota_client(NewQuotaClient(false));
311  const TestFile kFiles[] = {
312    {true, NULL, 0, kDummyURL1, kTemporary},
313    {false, "foo", 0, kDummyURL1, kTemporary},
314    {false, "bar", 0, kDummyURL1, kTemporary},
315    {false, "baz", 0, kDummyURL1, kTemporary},
316  };
317  InitializeOriginFiles(quota_client.get(), kFiles, ARRAYSIZE_UNSAFE(kFiles));
318  const int64 file_paths_cost = ComputeFilePathsCostForOriginAndType(
319      kFiles, ARRAYSIZE_UNSAFE(kFiles), kDummyURL1, kTemporary);
320
321  for (int i = 0; i < 2; i++) {
322    EXPECT_EQ(file_paths_cost,
323        GetOriginUsage(quota_client.get(), kDummyURL1, kTemporary));
324  }
325}
326
327TEST_F(FileSystemQuotaClientTest, SubDirectoryTest) {
328  scoped_ptr<FileSystemQuotaClient> quota_client(NewQuotaClient(false));
329  const TestFile kFiles[] = {
330    {true, NULL, 0, kDummyURL1, kTemporary},
331    {true, "dirtest", 0, kDummyURL1, kTemporary},
332    {false, "dirtest/foo", 11921, kDummyURL1, kTemporary},
333    {false, "bar", 4814, kDummyURL1, kTemporary},
334  };
335  InitializeOriginFiles(quota_client.get(), kFiles, ARRAYSIZE_UNSAFE(kFiles));
336  const int64 file_paths_cost = ComputeFilePathsCostForOriginAndType(
337      kFiles, ARRAYSIZE_UNSAFE(kFiles), kDummyURL1, kTemporary);
338
339  for (int i = 0; i < 2; i++) {
340    EXPECT_EQ(11921 + 4814 + file_paths_cost,
341        GetOriginUsage(quota_client.get(), kDummyURL1, kTemporary));
342  }
343}
344
345TEST_F(FileSystemQuotaClientTest, MultiTypeTest) {
346  scoped_ptr<FileSystemQuotaClient> quota_client(NewQuotaClient(false));
347  const TestFile kFiles[] = {
348    {true, NULL, 0, kDummyURL1, kTemporary},
349    {true, "dirtest", 0, kDummyURL1, kTemporary},
350    {false, "dirtest/foo", 133, kDummyURL1, kTemporary},
351    {false, "bar", 14, kDummyURL1, kTemporary},
352    {true, NULL, 0, kDummyURL1, kPersistent},
353    {true, "dirtest", 0, kDummyURL1, kPersistent},
354    {false, "dirtest/foo", 193, kDummyURL1, kPersistent},
355    {false, "bar", 9, kDummyURL1, kPersistent},
356  };
357  InitializeOriginFiles(quota_client.get(), kFiles, ARRAYSIZE_UNSAFE(kFiles));
358  const int64 file_paths_cost_temporary = ComputeFilePathsCostForOriginAndType(
359      kFiles, ARRAYSIZE_UNSAFE(kFiles), kDummyURL1, kTemporary);
360  const int64 file_paths_cost_persistent = ComputeFilePathsCostForOriginAndType(
361      kFiles, ARRAYSIZE_UNSAFE(kFiles), kDummyURL1, kTemporary);
362
363  for (int i = 0; i < 2; i++) {
364    EXPECT_EQ(133 + 14 + file_paths_cost_temporary,
365        GetOriginUsage(quota_client.get(), kDummyURL1, kTemporary));
366    EXPECT_EQ(193 + 9 + file_paths_cost_persistent,
367        GetOriginUsage(quota_client.get(), kDummyURL1, kPersistent));
368  }
369}
370
371TEST_F(FileSystemQuotaClientTest, MultiDomainTest) {
372  scoped_ptr<FileSystemQuotaClient> quota_client(NewQuotaClient(false));
373  const TestFile kFiles[] = {
374    {true, NULL, 0, kDummyURL1, kTemporary},
375    {true, "dir1", 0, kDummyURL1, kTemporary},
376    {false, "dir1/foo", 1331, kDummyURL1, kTemporary},
377    {false, "bar", 134, kDummyURL1, kTemporary},
378    {true, NULL, 0, kDummyURL1, kPersistent},
379    {true, "dir2", 0, kDummyURL1, kPersistent},
380    {false, "dir2/foo", 1903, kDummyURL1, kPersistent},
381    {false, "bar", 19, kDummyURL1, kPersistent},
382    {true, NULL, 0, kDummyURL2, kTemporary},
383    {true, "dom", 0, kDummyURL2, kTemporary},
384    {false, "dom/fan", 1319, kDummyURL2, kTemporary},
385    {false, "bar", 113, kDummyURL2, kTemporary},
386    {true, NULL, 0, kDummyURL2, kPersistent},
387    {true, "dom", 0, kDummyURL2, kPersistent},
388    {false, "dom/fan", 2013, kDummyURL2, kPersistent},
389    {false, "baz", 18, kDummyURL2, kPersistent},
390  };
391  InitializeOriginFiles(quota_client.get(), kFiles, ARRAYSIZE_UNSAFE(kFiles));
392  const int64 file_paths_cost_temporary1 = ComputeFilePathsCostForOriginAndType(
393      kFiles, ARRAYSIZE_UNSAFE(kFiles), kDummyURL1, kTemporary);
394  const int64 file_paths_cost_persistent1 =
395      ComputeFilePathsCostForOriginAndType(kFiles, ARRAYSIZE_UNSAFE(kFiles),
396          kDummyURL1, kPersistent);
397  const int64 file_paths_cost_temporary2 = ComputeFilePathsCostForOriginAndType(
398      kFiles, ARRAYSIZE_UNSAFE(kFiles), kDummyURL2, kTemporary);
399  const int64 file_paths_cost_persistent2 =
400      ComputeFilePathsCostForOriginAndType(kFiles, ARRAYSIZE_UNSAFE(kFiles),
401          kDummyURL2, kPersistent);
402
403  for (int i = 0; i < 2; i++) {
404    EXPECT_EQ(1331 + 134 + file_paths_cost_temporary1,
405        GetOriginUsage(quota_client.get(), kDummyURL1, kTemporary));
406    EXPECT_EQ(1903 + 19 + file_paths_cost_persistent1,
407        GetOriginUsage(quota_client.get(), kDummyURL1, kPersistent));
408    EXPECT_EQ(1319 + 113 + file_paths_cost_temporary2,
409        GetOriginUsage(quota_client.get(), kDummyURL2, kTemporary));
410    EXPECT_EQ(2013 + 18 + file_paths_cost_persistent2,
411        GetOriginUsage(quota_client.get(), kDummyURL2, kPersistent));
412  }
413}
414
415TEST_F(FileSystemQuotaClientTest, GetUsage_MultipleTasks) {
416  scoped_ptr<FileSystemQuotaClient> quota_client(NewQuotaClient(false));
417  const TestFile kFiles[] = {
418    {true, NULL, 0, kDummyURL1, kTemporary},
419    {false, "foo",   11, kDummyURL1, kTemporary},
420    {false, "bar",   22, kDummyURL1, kTemporary},
421  };
422  InitializeOriginFiles(quota_client.get(), kFiles, ARRAYSIZE_UNSAFE(kFiles));
423  const int64 file_paths_cost = ComputeFilePathsCostForOriginAndType(
424      kFiles, ARRAYSIZE_UNSAFE(kFiles), kDummyURL1, kTemporary);
425
426  // Dispatching three GetUsage tasks.
427  set_additional_callback_count(0);
428  GetOriginUsageAsync(quota_client.get(), kDummyURL1, kTemporary);
429  RunAdditionalOriginUsageTask(quota_client.get(), kDummyURL1, kTemporary);
430  RunAdditionalOriginUsageTask(quota_client.get(), kDummyURL1, kTemporary);
431  base::MessageLoop::current()->RunUntilIdle();
432  EXPECT_EQ(11 + 22 + file_paths_cost, usage());
433  EXPECT_EQ(2, additional_callback_count());
434
435  // Once more, in a different order.
436  set_additional_callback_count(0);
437  RunAdditionalOriginUsageTask(quota_client.get(), kDummyURL1, kTemporary);
438  GetOriginUsageAsync(quota_client.get(), kDummyURL1, kTemporary);
439  RunAdditionalOriginUsageTask(quota_client.get(), kDummyURL1, kTemporary);
440  base::MessageLoop::current()->RunUntilIdle();
441  EXPECT_EQ(11 + 22 + file_paths_cost, usage());
442  EXPECT_EQ(2, additional_callback_count());
443}
444
445TEST_F(FileSystemQuotaClientTest, GetOriginsForType) {
446  scoped_ptr<FileSystemQuotaClient> quota_client(NewQuotaClient(false));
447  const TestFile kFiles[] = {
448    {true, NULL, 0, kDummyURL1, kTemporary},
449    {true, NULL, 0, kDummyURL2, kTemporary},
450    {true, NULL, 0, kDummyURL3, kPersistent},
451  };
452  InitializeOriginFiles(quota_client.get(), kFiles, ARRAYSIZE_UNSAFE(kFiles));
453
454  std::set<GURL> origins = GetOriginsForType(quota_client.get(), kTemporary);
455  EXPECT_EQ(2U, origins.size());
456  EXPECT_TRUE(origins.find(GURL(kDummyURL1)) != origins.end());
457  EXPECT_TRUE(origins.find(GURL(kDummyURL2)) != origins.end());
458  EXPECT_TRUE(origins.find(GURL(kDummyURL3)) == origins.end());
459}
460
461TEST_F(FileSystemQuotaClientTest, GetOriginsForHost) {
462  scoped_ptr<FileSystemQuotaClient> quota_client(NewQuotaClient(false));
463  const char* kURL1 = "http://foo.com/";
464  const char* kURL2 = "https://foo.com/";
465  const char* kURL3 = "http://foo.com:1/";
466  const char* kURL4 = "http://foo2.com/";
467  const char* kURL5 = "http://foo.com:2/";
468  const TestFile kFiles[] = {
469    {true, NULL, 0, kURL1, kTemporary},
470    {true, NULL, 0, kURL2, kTemporary},
471    {true, NULL, 0, kURL3, kTemporary},
472    {true, NULL, 0, kURL4, kTemporary},
473    {true, NULL, 0, kURL5, kPersistent},
474  };
475  InitializeOriginFiles(quota_client.get(), kFiles, ARRAYSIZE_UNSAFE(kFiles));
476
477  std::set<GURL> origins = GetOriginsForHost(
478      quota_client.get(), kTemporary, "foo.com");
479  EXPECT_EQ(3U, origins.size());
480  EXPECT_TRUE(origins.find(GURL(kURL1)) != origins.end());
481  EXPECT_TRUE(origins.find(GURL(kURL2)) != origins.end());
482  EXPECT_TRUE(origins.find(GURL(kURL3)) != origins.end());
483  EXPECT_TRUE(origins.find(GURL(kURL4)) == origins.end());  // Different host.
484  EXPECT_TRUE(origins.find(GURL(kURL5)) == origins.end());  // Different type.
485}
486
487TEST_F(FileSystemQuotaClientTest, IncognitoTest) {
488  scoped_ptr<FileSystemQuotaClient> quota_client(NewQuotaClient(true));
489  const TestFile kFiles[] = {
490    {true, NULL, 0, kDummyURL1, kTemporary},
491    {false, "foo", 10, kDummyURL1, kTemporary},
492  };
493  InitializeOriginFiles(quota_client.get(), kFiles, ARRAYSIZE_UNSAFE(kFiles));
494
495  // Having files in the usual directory wouldn't affect the result
496  // queried in incognito mode.
497  EXPECT_EQ(0, GetOriginUsage(quota_client.get(), kDummyURL1, kTemporary));
498  EXPECT_EQ(0, GetOriginUsage(quota_client.get(), kDummyURL1, kPersistent));
499
500  std::set<GURL> origins = GetOriginsForType(quota_client.get(), kTemporary);
501  EXPECT_EQ(0U, origins.size());
502  origins = GetOriginsForHost(quota_client.get(), kTemporary, "www.dummy.org");
503  EXPECT_EQ(0U, origins.size());
504}
505
506TEST_F(FileSystemQuotaClientTest, DeleteOriginTest) {
507  scoped_ptr<FileSystemQuotaClient> quota_client(NewQuotaClient(false));
508  const TestFile kFiles[] = {
509    {true, NULL,  0, "http://foo.com/",  kTemporary},
510    {false, "a",  1, "http://foo.com/",  kTemporary},
511    {true, NULL,  0, "https://foo.com/", kTemporary},
512    {false, "b",  2, "https://foo.com/", kTemporary},
513    {true, NULL,  0, "http://foo.com/",  kPersistent},
514    {false, "c",  4, "http://foo.com/",  kPersistent},
515    {true, NULL,  0, "http://bar.com/",  kTemporary},
516    {false, "d",  8, "http://bar.com/",  kTemporary},
517    {true, NULL,  0, "http://bar.com/",  kPersistent},
518    {false, "e", 16, "http://bar.com/",  kPersistent},
519    {true, NULL,  0, "https://bar.com/", kPersistent},
520    {false, "f", 32, "https://bar.com/", kPersistent},
521    {true, NULL,  0, "https://bar.com/", kTemporary},
522    {false, "g", 64, "https://bar.com/", kTemporary},
523  };
524  InitializeOriginFiles(quota_client.get(), kFiles, ARRAYSIZE_UNSAFE(kFiles));
525  const int64 file_paths_cost_temporary_foo_https =
526      ComputeFilePathsCostForOriginAndType(kFiles, ARRAYSIZE_UNSAFE(kFiles),
527          "https://foo.com/", kTemporary);
528  const int64 file_paths_cost_persistent_foo =
529      ComputeFilePathsCostForOriginAndType(kFiles, ARRAYSIZE_UNSAFE(kFiles),
530          "http://foo.com/", kPersistent);
531  const int64 file_paths_cost_temporary_bar =
532      ComputeFilePathsCostForOriginAndType(kFiles, ARRAYSIZE_UNSAFE(kFiles),
533          "http://bar.com/", kTemporary);
534  const int64 file_paths_cost_temporary_bar_https =
535      ComputeFilePathsCostForOriginAndType(kFiles, ARRAYSIZE_UNSAFE(kFiles),
536          "https://bar.com/", kTemporary);
537  const int64 file_paths_cost_persistent_bar_https =
538      ComputeFilePathsCostForOriginAndType(kFiles, ARRAYSIZE_UNSAFE(kFiles),
539          "https://bar.com/", kPersistent);
540
541  DeleteOriginData(quota_client.get(), "http://foo.com/", kTemporary);
542  base::MessageLoop::current()->RunUntilIdle();
543  EXPECT_EQ(quota::kQuotaStatusOk, status());
544
545  DeleteOriginData(quota_client.get(), "http://bar.com/", kPersistent);
546  base::MessageLoop::current()->RunUntilIdle();
547  EXPECT_EQ(quota::kQuotaStatusOk, status());
548
549  DeleteOriginData(quota_client.get(), "http://buz.com/", kTemporary);
550  base::MessageLoop::current()->RunUntilIdle();
551  EXPECT_EQ(quota::kQuotaStatusOk, status());
552
553  EXPECT_EQ(0, GetOriginUsage(
554      quota_client.get(), "http://foo.com/", kTemporary));
555  EXPECT_EQ(0, GetOriginUsage(
556      quota_client.get(), "http://bar.com/", kPersistent));
557  EXPECT_EQ(0, GetOriginUsage(
558      quota_client.get(), "http://buz.com/", kTemporary));
559
560  EXPECT_EQ(2 + file_paths_cost_temporary_foo_https,
561            GetOriginUsage(quota_client.get(),
562                           "https://foo.com/",
563                           kTemporary));
564  EXPECT_EQ(4 + file_paths_cost_persistent_foo,
565            GetOriginUsage(quota_client.get(),
566                           "http://foo.com/",
567                           kPersistent));
568  EXPECT_EQ(8 + file_paths_cost_temporary_bar,
569            GetOriginUsage(quota_client.get(),
570                           "http://bar.com/",
571                           kTemporary));
572  EXPECT_EQ(32 + file_paths_cost_persistent_bar_https,
573            GetOriginUsage(quota_client.get(),
574                           "https://bar.com/",
575                           kPersistent));
576  EXPECT_EQ(64 + file_paths_cost_temporary_bar_https,
577            GetOriginUsage(quota_client.get(),
578                           "https://bar.com/",
579                           kTemporary));
580}
581
582}  // namespace fileapi
583