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 <algorithm>
6#include <iterator>
7#include <set>
8
9#include "base/bind.h"
10#include "base/callback.h"
11#include "base/file_util.h"
12#include "base/files/scoped_temp_dir.h"
13#include "base/message_loop/message_loop.h"
14#include "sql/connection.h"
15#include "sql/meta_table.h"
16#include "sql/statement.h"
17#include "sql/transaction.h"
18#include "testing/gtest/include/gtest/gtest.h"
19#include "url/gurl.h"
20#include "webkit/browser/quota/mock_special_storage_policy.h"
21#include "webkit/browser/quota/quota_database.h"
22
23namespace quota {
24namespace {
25
26const base::Time kZeroTime;
27
28}  // namespace
29
30class QuotaDatabaseTest : public testing::Test {
31 protected:
32  typedef QuotaDatabase::QuotaTableEntry QuotaTableEntry;
33  typedef QuotaDatabase::QuotaTableCallback QuotaTableCallback;
34  typedef QuotaDatabase::OriginInfoTableCallback
35      OriginInfoTableCallback;
36
37  void LazyOpen(const base::FilePath& kDbFile) {
38    QuotaDatabase db(kDbFile);
39    EXPECT_FALSE(db.LazyOpen(false));
40    ASSERT_TRUE(db.LazyOpen(true));
41    EXPECT_TRUE(db.db_.get());
42    EXPECT_TRUE(kDbFile.empty() || base::PathExists(kDbFile));
43  }
44
45  void UpgradeSchemaV2toV3(const base::FilePath& kDbFile) {
46    const QuotaTableEntry entries[] = {
47      QuotaTableEntry("a", kStorageTypeTemporary,  1),
48      QuotaTableEntry("b", kStorageTypeTemporary,  2),
49      QuotaTableEntry("c", kStorageTypePersistent, 3),
50    };
51
52    CreateV2Database(kDbFile, entries, ARRAYSIZE_UNSAFE(entries));
53
54    QuotaDatabase db(kDbFile);
55    EXPECT_TRUE(db.LazyOpen(true));
56    EXPECT_TRUE(db.db_.get());
57
58    typedef EntryVerifier<QuotaTableEntry> Verifier;
59    Verifier verifier(entries, entries + ARRAYSIZE_UNSAFE(entries));
60    EXPECT_TRUE(db.DumpQuotaTable(
61        new QuotaTableCallback(
62            base::Bind(&Verifier::Run,
63                       base::Unretained(&verifier)))));
64    EXPECT_TRUE(verifier.table.empty());
65  }
66
67  void HostQuota(const base::FilePath& kDbFile) {
68    QuotaDatabase db(kDbFile);
69    ASSERT_TRUE(db.LazyOpen(true));
70
71    const char* kHost = "foo.com";
72    const int kQuota1 = 13579;
73    const int kQuota2 = kQuota1 + 1024;
74
75    int64 quota = -1;
76    EXPECT_FALSE(db.GetHostQuota(kHost, kStorageTypeTemporary, &quota));
77    EXPECT_FALSE(db.GetHostQuota(kHost, kStorageTypePersistent, &quota));
78
79    // Insert quota for temporary.
80    EXPECT_TRUE(db.SetHostQuota(kHost, kStorageTypeTemporary, kQuota1));
81    EXPECT_TRUE(db.GetHostQuota(kHost, kStorageTypeTemporary, &quota));
82    EXPECT_EQ(kQuota1, quota);
83
84    // Update quota for temporary.
85    EXPECT_TRUE(db.SetHostQuota(kHost, kStorageTypeTemporary, kQuota2));
86    EXPECT_TRUE(db.GetHostQuota(kHost, kStorageTypeTemporary, &quota));
87    EXPECT_EQ(kQuota2, quota);
88
89    // Quota for persistent must not be updated.
90    EXPECT_FALSE(db.GetHostQuota(kHost, kStorageTypePersistent, &quota));
91
92    // Delete temporary storage quota.
93    EXPECT_TRUE(db.DeleteHostQuota(kHost, kStorageTypeTemporary));
94    EXPECT_FALSE(db.GetHostQuota(kHost, kStorageTypeTemporary, &quota));
95  }
96
97  void GlobalQuota(const base::FilePath& kDbFile) {
98    QuotaDatabase db(kDbFile);
99    ASSERT_TRUE(db.LazyOpen(true));
100
101    const char* kTempQuotaKey = QuotaDatabase::kTemporaryQuotaOverrideKey;
102    const char* kAvailSpaceKey = QuotaDatabase::kDesiredAvailableSpaceKey;
103
104    int64 value = 0;
105    const int64 kValue1 = 456;
106    const int64 kValue2 = 123000;
107    EXPECT_FALSE(db.GetQuotaConfigValue(kTempQuotaKey, &value));
108    EXPECT_FALSE(db.GetQuotaConfigValue(kAvailSpaceKey, &value));
109
110    EXPECT_TRUE(db.SetQuotaConfigValue(kTempQuotaKey, kValue1));
111    EXPECT_TRUE(db.GetQuotaConfigValue(kTempQuotaKey, &value));
112    EXPECT_EQ(kValue1, value);
113
114    EXPECT_TRUE(db.SetQuotaConfigValue(kTempQuotaKey, kValue2));
115    EXPECT_TRUE(db.GetQuotaConfigValue(kTempQuotaKey, &value));
116    EXPECT_EQ(kValue2, value);
117
118    EXPECT_TRUE(db.SetQuotaConfigValue(kAvailSpaceKey, kValue1));
119    EXPECT_TRUE(db.GetQuotaConfigValue(kAvailSpaceKey, &value));
120    EXPECT_EQ(kValue1, value);
121
122    EXPECT_TRUE(db.SetQuotaConfigValue(kAvailSpaceKey, kValue2));
123    EXPECT_TRUE(db.GetQuotaConfigValue(kAvailSpaceKey, &value));
124    EXPECT_EQ(kValue2, value);
125  }
126
127  void OriginLastAccessTimeLRU(const base::FilePath& kDbFile) {
128    QuotaDatabase db(kDbFile);
129    ASSERT_TRUE(db.LazyOpen(true));
130
131    std::set<GURL> exceptions;
132    GURL origin;
133    EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions,
134                                NULL, &origin));
135    EXPECT_TRUE(origin.is_empty());
136
137    const GURL kOrigin1("http://a/");
138    const GURL kOrigin2("http://b/");
139    const GURL kOrigin3("http://c/");
140    const GURL kOrigin4("http://p/");
141
142    // Adding three temporary storages, and
143    EXPECT_TRUE(db.SetOriginLastAccessTime(
144        kOrigin1, kStorageTypeTemporary, base::Time::FromInternalValue(10)));
145    EXPECT_TRUE(db.SetOriginLastAccessTime(
146        kOrigin2, kStorageTypeTemporary, base::Time::FromInternalValue(20)));
147    EXPECT_TRUE(db.SetOriginLastAccessTime(
148        kOrigin3, kStorageTypeTemporary, base::Time::FromInternalValue(30)));
149
150    // one persistent.
151    EXPECT_TRUE(db.SetOriginLastAccessTime(
152        kOrigin4, kStorageTypePersistent, base::Time::FromInternalValue(40)));
153
154    EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions,
155                                NULL, &origin));
156    EXPECT_EQ(kOrigin1.spec(), origin.spec());
157
158    // Test that unlimited origins are exluded from eviction, but
159    // protected origins are not excluded.
160    scoped_refptr<MockSpecialStoragePolicy> policy(
161        new MockSpecialStoragePolicy);
162    policy->AddUnlimited(kOrigin1);
163    policy->AddProtected(kOrigin2);
164    EXPECT_TRUE(db.GetLRUOrigin(
165        kStorageTypeTemporary, exceptions, policy.get(), &origin));
166    EXPECT_EQ(kOrigin2.spec(), origin.spec());
167
168    exceptions.insert(kOrigin1);
169    EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions,
170                                NULL, &origin));
171    EXPECT_EQ(kOrigin2.spec(), origin.spec());
172
173    exceptions.insert(kOrigin2);
174    EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions,
175                                NULL, &origin));
176    EXPECT_EQ(kOrigin3.spec(), origin.spec());
177
178    exceptions.insert(kOrigin3);
179    EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions,
180                                NULL, &origin));
181    EXPECT_TRUE(origin.is_empty());
182
183    EXPECT_TRUE(db.SetOriginLastAccessTime(
184        kOrigin1, kStorageTypeTemporary, base::Time::Now()));
185
186    // Delete origin/type last access time information.
187    EXPECT_TRUE(db.DeleteOriginInfo(kOrigin3, kStorageTypeTemporary));
188
189    // Querying again to see if the deletion has worked.
190    exceptions.clear();
191    EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions,
192                                NULL, &origin));
193    EXPECT_EQ(kOrigin2.spec(), origin.spec());
194
195    exceptions.insert(kOrigin1);
196    exceptions.insert(kOrigin2);
197    EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions,
198                                NULL, &origin));
199    EXPECT_TRUE(origin.is_empty());
200  }
201
202  void OriginLastModifiedSince(const base::FilePath& kDbFile) {
203    QuotaDatabase db(kDbFile);
204    ASSERT_TRUE(db.LazyOpen(true));
205
206    std::set<GURL> origins;
207    EXPECT_TRUE(db.GetOriginsModifiedSince(
208        kStorageTypeTemporary, &origins, base::Time()));
209    EXPECT_TRUE(origins.empty());
210
211    const GURL kOrigin1("http://a/");
212    const GURL kOrigin2("http://b/");
213    const GURL kOrigin3("http://c/");
214
215    // Report last mod time for the test origins.
216    EXPECT_TRUE(db.SetOriginLastModifiedTime(
217        kOrigin1, kStorageTypeTemporary, base::Time::FromInternalValue(0)));
218    EXPECT_TRUE(db.SetOriginLastModifiedTime(
219        kOrigin2, kStorageTypeTemporary, base::Time::FromInternalValue(10)));
220    EXPECT_TRUE(db.SetOriginLastModifiedTime(
221        kOrigin3, kStorageTypeTemporary, base::Time::FromInternalValue(20)));
222
223    EXPECT_TRUE(db.GetOriginsModifiedSince(
224        kStorageTypeTemporary, &origins, base::Time()));
225    EXPECT_EQ(3U, origins.size());
226    EXPECT_EQ(1U, origins.count(kOrigin1));
227    EXPECT_EQ(1U, origins.count(kOrigin2));
228    EXPECT_EQ(1U, origins.count(kOrigin3));
229
230    EXPECT_TRUE(db.GetOriginsModifiedSince(
231        kStorageTypeTemporary, &origins, base::Time::FromInternalValue(5)));
232    EXPECT_EQ(2U, origins.size());
233    EXPECT_EQ(0U, origins.count(kOrigin1));
234    EXPECT_EQ(1U, origins.count(kOrigin2));
235    EXPECT_EQ(1U, origins.count(kOrigin3));
236
237    EXPECT_TRUE(db.GetOriginsModifiedSince(
238        kStorageTypeTemporary, &origins, base::Time::FromInternalValue(15)));
239    EXPECT_EQ(1U, origins.size());
240    EXPECT_EQ(0U, origins.count(kOrigin1));
241    EXPECT_EQ(0U, origins.count(kOrigin2));
242    EXPECT_EQ(1U, origins.count(kOrigin3));
243
244    EXPECT_TRUE(db.GetOriginsModifiedSince(
245        kStorageTypeTemporary, &origins, base::Time::FromInternalValue(25)));
246    EXPECT_TRUE(origins.empty());
247
248    // Update origin1's mod time but for persistent storage.
249    EXPECT_TRUE(db.SetOriginLastModifiedTime(
250        kOrigin1, kStorageTypePersistent, base::Time::FromInternalValue(30)));
251
252    // Must have no effects on temporary origins info.
253    EXPECT_TRUE(db.GetOriginsModifiedSince(
254        kStorageTypeTemporary, &origins, base::Time::FromInternalValue(5)));
255    EXPECT_EQ(2U, origins.size());
256    EXPECT_EQ(0U, origins.count(kOrigin1));
257    EXPECT_EQ(1U, origins.count(kOrigin2));
258    EXPECT_EQ(1U, origins.count(kOrigin3));
259
260    // One more update for persistent origin2.
261    EXPECT_TRUE(db.SetOriginLastModifiedTime(
262        kOrigin2, kStorageTypePersistent, base::Time::FromInternalValue(40)));
263
264    EXPECT_TRUE(db.GetOriginsModifiedSince(
265        kStorageTypePersistent, &origins, base::Time::FromInternalValue(25)));
266    EXPECT_EQ(2U, origins.size());
267    EXPECT_EQ(1U, origins.count(kOrigin1));
268    EXPECT_EQ(1U, origins.count(kOrigin2));
269    EXPECT_EQ(0U, origins.count(kOrigin3));
270
271    EXPECT_TRUE(db.GetOriginsModifiedSince(
272        kStorageTypePersistent, &origins, base::Time::FromInternalValue(35)));
273    EXPECT_EQ(1U, origins.size());
274    EXPECT_EQ(0U, origins.count(kOrigin1));
275    EXPECT_EQ(1U, origins.count(kOrigin2));
276    EXPECT_EQ(0U, origins.count(kOrigin3));
277  }
278
279  void RegisterInitialOriginInfo(const base::FilePath& kDbFile) {
280    QuotaDatabase db(kDbFile);
281
282    const GURL kOrigins[] = {
283      GURL("http://a/"),
284      GURL("http://b/"),
285      GURL("http://c/") };
286    std::set<GURL> origins(kOrigins, kOrigins + ARRAYSIZE_UNSAFE(kOrigins));
287
288    EXPECT_TRUE(db.RegisterInitialOriginInfo(origins, kStorageTypeTemporary));
289
290    int used_count = -1;
291    EXPECT_TRUE(db.FindOriginUsedCount(GURL("http://a/"),
292                                       kStorageTypeTemporary,
293                                       &used_count));
294    EXPECT_EQ(0, used_count);
295
296    EXPECT_TRUE(db.SetOriginLastAccessTime(
297        GURL("http://a/"), kStorageTypeTemporary,
298        base::Time::FromDoubleT(1.0)));
299    used_count = -1;
300    EXPECT_TRUE(db.FindOriginUsedCount(GURL("http://a/"),
301                                       kStorageTypeTemporary,
302                                       &used_count));
303    EXPECT_EQ(1, used_count);
304
305    EXPECT_TRUE(db.RegisterInitialOriginInfo(origins, kStorageTypeTemporary));
306
307    used_count = -1;
308    EXPECT_TRUE(db.FindOriginUsedCount(GURL("http://a/"),
309                                       kStorageTypeTemporary,
310                                       &used_count));
311    EXPECT_EQ(1, used_count);
312  }
313
314  template <typename EntryType>
315  struct EntryVerifier {
316    std::set<EntryType> table;
317
318    template <typename Iterator>
319    EntryVerifier(Iterator itr, Iterator end)
320        : table(itr, end) {}
321
322    bool Run(const EntryType& entry) {
323      EXPECT_EQ(1u, table.erase(entry));
324      return true;
325    }
326  };
327
328  void DumpQuotaTable(const base::FilePath& kDbFile) {
329    QuotaTableEntry kTableEntries[] = {
330      QuotaTableEntry("http://go/", kStorageTypeTemporary, 1),
331      QuotaTableEntry("http://oo/", kStorageTypeTemporary, 2),
332      QuotaTableEntry("http://gle/", kStorageTypePersistent, 3)
333    };
334    QuotaTableEntry* begin = kTableEntries;
335    QuotaTableEntry* end = kTableEntries + ARRAYSIZE_UNSAFE(kTableEntries);
336
337    QuotaDatabase db(kDbFile);
338    EXPECT_TRUE(db.LazyOpen(true));
339    AssignQuotaTable(db.db_.get(), begin, end);
340    db.Commit();
341
342    typedef EntryVerifier<QuotaTableEntry> Verifier;
343    Verifier verifier(begin, end);
344    EXPECT_TRUE(db.DumpQuotaTable(
345        new QuotaTableCallback(
346            base::Bind(&Verifier::Run,
347                       base::Unretained(&verifier)))));
348    EXPECT_TRUE(verifier.table.empty());
349  }
350
351  void DumpOriginInfoTable(const base::FilePath& kDbFile) {
352    base::Time now(base::Time::Now());
353    typedef QuotaDatabase::OriginInfoTableEntry Entry;
354    Entry kTableEntries[] = {
355      Entry(GURL("http://go/"), kStorageTypeTemporary, 2147483647, now, now),
356      Entry(GURL("http://oo/"), kStorageTypeTemporary, 0, now, now),
357      Entry(GURL("http://gle/"), kStorageTypeTemporary, 1, now, now),
358    };
359    Entry* begin = kTableEntries;
360    Entry* end = kTableEntries + ARRAYSIZE_UNSAFE(kTableEntries);
361
362    QuotaDatabase db(kDbFile);
363    EXPECT_TRUE(db.LazyOpen(true));
364    AssignOriginInfoTable(db.db_.get(), begin, end);
365    db.Commit();
366
367    typedef EntryVerifier<Entry> Verifier;
368    Verifier verifier(begin, end);
369    EXPECT_TRUE(db.DumpOriginInfoTable(
370        new OriginInfoTableCallback(
371            base::Bind(&Verifier::Run,
372                       base::Unretained(&verifier)))));
373    EXPECT_TRUE(verifier.table.empty());
374  }
375
376 private:
377  template <typename Iterator>
378  void AssignQuotaTable(sql::Connection* db, Iterator itr, Iterator end) {
379    ASSERT_NE(db, (sql::Connection*)NULL);
380    for (; itr != end; ++itr) {
381      const char* kSql =
382          "INSERT INTO HostQuotaTable"
383          " (host, type, quota)"
384          " VALUES (?, ?, ?)";
385      sql::Statement statement;
386      statement.Assign(db->GetCachedStatement(SQL_FROM_HERE, kSql));
387      ASSERT_TRUE(statement.is_valid());
388
389      statement.BindString(0, itr->host);
390      statement.BindInt(1, static_cast<int>(itr->type));
391      statement.BindInt64(2, itr->quota);
392      EXPECT_TRUE(statement.Run());
393    }
394  }
395
396  template <typename Iterator>
397  void AssignOriginInfoTable(sql::Connection* db, Iterator itr, Iterator end) {
398    ASSERT_NE(db, (sql::Connection*)NULL);
399    for (; itr != end; ++itr) {
400      const char* kSql =
401          "INSERT INTO OriginInfoTable"
402          " (origin, type, used_count, last_access_time, last_modified_time)"
403          " VALUES (?, ?, ?, ?, ?)";
404      sql::Statement statement;
405      statement.Assign(db->GetCachedStatement(SQL_FROM_HERE, kSql));
406      ASSERT_TRUE(statement.is_valid());
407
408      statement.BindString(0, itr->origin.spec());
409      statement.BindInt(1, static_cast<int>(itr->type));
410      statement.BindInt(2, itr->used_count);
411      statement.BindInt64(3, itr->last_access_time.ToInternalValue());
412      statement.BindInt64(4, itr->last_modified_time.ToInternalValue());
413      EXPECT_TRUE(statement.Run());
414    }
415  }
416
417  bool OpenDatabase(sql::Connection* db, const base::FilePath& kDbFile) {
418    if (kDbFile.empty()) {
419      return db->OpenInMemory();
420    }
421    if (!base::CreateDirectory(kDbFile.DirName()))
422      return false;
423    if (!db->Open(kDbFile))
424      return false;
425    db->Preload();
426    return true;
427  }
428
429  // Create V2 database and populate some data.
430  void CreateV2Database(
431      const base::FilePath& kDbFile,
432      const QuotaTableEntry* entries,
433      size_t entries_size) {
434    scoped_ptr<sql::Connection> db(new sql::Connection);
435    scoped_ptr<sql::MetaTable> meta_table(new sql::MetaTable);
436
437    // V2 schema definitions.
438    static const int kCurrentVersion = 2;
439    static const int kCompatibleVersion = 2;
440    static const char kHostQuotaTable[] = "HostQuotaTable";
441    static const char kOriginLastAccessTable[] = "OriginLastAccessTable";
442    static const QuotaDatabase::TableSchema kTables[] = {
443      { kHostQuotaTable,
444        "(host TEXT NOT NULL,"
445        " type INTEGER NOT NULL,"
446        " quota INTEGER,"
447        " UNIQUE(host, type))" },
448      { kOriginLastAccessTable,
449        "(origin TEXT NOT NULL,"
450        " type INTEGER NOT NULL,"
451        " used_count INTEGER,"
452        " last_access_time INTEGER,"
453        " UNIQUE(origin, type))" },
454    };
455    static const QuotaDatabase::IndexSchema kIndexes[] = {
456      { "HostIndex",
457        kHostQuotaTable,
458        "(host)",
459        false },
460      { "OriginLastAccessIndex",
461        kOriginLastAccessTable,
462        "(origin, last_access_time)",
463        false },
464    };
465
466    ASSERT_TRUE(OpenDatabase(db.get(), kDbFile));
467    EXPECT_TRUE(QuotaDatabase::CreateSchema(
468            db.get(), meta_table.get(),
469            kCurrentVersion, kCompatibleVersion,
470            kTables, ARRAYSIZE_UNSAFE(kTables),
471            kIndexes, ARRAYSIZE_UNSAFE(kIndexes)));
472
473    // V2 and V3 QuotaTable are compatible, so we can simply use
474    // AssignQuotaTable to poplulate v2 database here.
475    db->BeginTransaction();
476    AssignQuotaTable(db.get(), entries, entries + entries_size);
477    db->CommitTransaction();
478  }
479
480  base::MessageLoop message_loop_;
481};
482
483TEST_F(QuotaDatabaseTest, LazyOpen) {
484  base::ScopedTempDir data_dir;
485  ASSERT_TRUE(data_dir.CreateUniqueTempDir());
486  const base::FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db");
487  LazyOpen(kDbFile);
488  LazyOpen(base::FilePath());
489}
490
491TEST_F(QuotaDatabaseTest, UpgradeSchema) {
492  base::ScopedTempDir data_dir;
493  ASSERT_TRUE(data_dir.CreateUniqueTempDir());
494  const base::FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db");
495  UpgradeSchemaV2toV3(kDbFile);
496}
497
498TEST_F(QuotaDatabaseTest, HostQuota) {
499  base::ScopedTempDir data_dir;
500  ASSERT_TRUE(data_dir.CreateUniqueTempDir());
501  const base::FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db");
502  HostQuota(kDbFile);
503  HostQuota(base::FilePath());
504}
505
506TEST_F(QuotaDatabaseTest, GlobalQuota) {
507  base::ScopedTempDir data_dir;
508  ASSERT_TRUE(data_dir.CreateUniqueTempDir());
509  const base::FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db");
510  GlobalQuota(kDbFile);
511  GlobalQuota(base::FilePath());
512}
513
514TEST_F(QuotaDatabaseTest, OriginLastAccessTimeLRU) {
515  base::ScopedTempDir data_dir;
516  ASSERT_TRUE(data_dir.CreateUniqueTempDir());
517  const base::FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db");
518  OriginLastAccessTimeLRU(kDbFile);
519  OriginLastAccessTimeLRU(base::FilePath());
520}
521
522TEST_F(QuotaDatabaseTest, OriginLastModifiedSince) {
523  base::ScopedTempDir data_dir;
524  ASSERT_TRUE(data_dir.CreateUniqueTempDir());
525  const base::FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db");
526  OriginLastModifiedSince(kDbFile);
527  OriginLastModifiedSince(base::FilePath());
528}
529
530TEST_F(QuotaDatabaseTest, BootstrapFlag) {
531  base::ScopedTempDir data_dir;
532  ASSERT_TRUE(data_dir.CreateUniqueTempDir());
533
534  const base::FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db");
535  QuotaDatabase db(kDbFile);
536
537  EXPECT_FALSE(db.IsOriginDatabaseBootstrapped());
538  EXPECT_TRUE(db.SetOriginDatabaseBootstrapped(true));
539  EXPECT_TRUE(db.IsOriginDatabaseBootstrapped());
540  EXPECT_TRUE(db.SetOriginDatabaseBootstrapped(false));
541  EXPECT_FALSE(db.IsOriginDatabaseBootstrapped());
542}
543
544TEST_F(QuotaDatabaseTest, RegisterInitialOriginInfo) {
545  base::ScopedTempDir data_dir;
546  ASSERT_TRUE(data_dir.CreateUniqueTempDir());
547  const base::FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db");
548  RegisterInitialOriginInfo(kDbFile);
549  RegisterInitialOriginInfo(base::FilePath());
550}
551
552TEST_F(QuotaDatabaseTest, DumpQuotaTable) {
553  base::ScopedTempDir data_dir;
554  ASSERT_TRUE(data_dir.CreateUniqueTempDir());
555  const base::FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db");
556  DumpQuotaTable(kDbFile);
557  DumpQuotaTable(base::FilePath());
558}
559
560TEST_F(QuotaDatabaseTest, DumpOriginInfoTable) {
561  base::ScopedTempDir data_dir;
562  ASSERT_TRUE(data_dir.CreateUniqueTempDir());
563  const base::FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db");
564  DumpOriginInfoTable(kDbFile);
565  DumpOriginInfoTable(base::FilePath());
566}
567}  // namespace quota
568