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