Home | History | Annotate | Download | only in indexed_db
      1 // Copyright (c) 2011 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 <map>
      6 
      7 #include "base/bind.h"
      8 #include "base/file_util.h"
      9 #include "base/files/file_path.h"
     10 #include "base/files/scoped_temp_dir.h"
     11 #include "base/message_loop/message_loop.h"
     12 #include "base/test/test_simple_task_runner.h"
     13 #include "base/threading/thread.h"
     14 #include "content/browser/browser_thread_impl.h"
     15 #include "content/browser/indexed_db/indexed_db_context_impl.h"
     16 #include "content/browser/indexed_db/indexed_db_quota_client.h"
     17 #include "content/public/browser/storage_partition.h"
     18 #include "content/public/test/test_browser_context.h"
     19 #include "content/public/test/test_browser_thread_bundle.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 #include "webkit/browser/quota/mock_quota_manager.h"
     22 #include "webkit/common/database/database_identifier.h"
     23 
     24 // Declared to shorten the line lengths.
     25 static const quota::StorageType kTemp = quota::kStorageTypeTemporary;
     26 static const quota::StorageType kPerm = quota::kStorageTypePersistent;
     27 
     28 namespace content {
     29 
     30 // Base class for our test fixtures.
     31 class IndexedDBQuotaClientTest : public testing::Test {
     32  public:
     33   const GURL kOriginA;
     34   const GURL kOriginB;
     35   const GURL kOriginOther;
     36 
     37   IndexedDBQuotaClientTest()
     38       : kOriginA("http://host"),
     39         kOriginB("http://host:8000"),
     40         kOriginOther("http://other"),
     41         usage_(0),
     42         task_runner_(new base::TestSimpleTaskRunner),
     43         weak_factory_(this) {
     44     browser_context_.reset(new TestBrowserContext());
     45 
     46     scoped_refptr<quota::QuotaManager> quota_manager =
     47         new quota::MockQuotaManager(
     48             false /*in_memory*/,
     49             browser_context_->GetPath(),
     50             base::MessageLoop::current()->message_loop_proxy(),
     51             base::MessageLoop::current()->message_loop_proxy(),
     52             browser_context_->GetSpecialStoragePolicy());
     53 
     54     idb_context_ =
     55         new IndexedDBContextImpl(browser_context_->GetPath(),
     56                                  browser_context_->GetSpecialStoragePolicy(),
     57                                  quota_manager->proxy(),
     58                                  task_runner_);
     59     base::MessageLoop::current()->RunUntilIdle();
     60     setup_temp_dir();
     61   }
     62 
     63   void FlushIndexedDBTaskRunner() { task_runner_->RunUntilIdle(); }
     64 
     65   void setup_temp_dir() {
     66     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     67     base::FilePath indexeddb_dir =
     68         temp_dir_.path().Append(IndexedDBContextImpl::kIndexedDBDirectory);
     69     ASSERT_TRUE(file_util::CreateDirectory(indexeddb_dir));
     70     idb_context()->set_data_path_for_testing(indexeddb_dir);
     71   }
     72 
     73   virtual ~IndexedDBQuotaClientTest() {
     74     FlushIndexedDBTaskRunner();
     75     idb_context_ = NULL;
     76     browser_context_.reset();
     77     base::MessageLoop::current()->RunUntilIdle();
     78   }
     79 
     80   int64 GetOriginUsage(quota::QuotaClient* client,
     81                        const GURL& origin,
     82                        quota::StorageType type) {
     83     usage_ = -1;
     84     client->GetOriginUsage(
     85         origin,
     86         type,
     87         base::Bind(&IndexedDBQuotaClientTest::OnGetOriginUsageComplete,
     88                    weak_factory_.GetWeakPtr()));
     89     FlushIndexedDBTaskRunner();
     90     base::MessageLoop::current()->RunUntilIdle();
     91     EXPECT_GT(usage_, -1);
     92     return usage_;
     93   }
     94 
     95   const std::set<GURL>& GetOriginsForType(quota::QuotaClient* client,
     96                                           quota::StorageType type) {
     97     origins_.clear();
     98     client->GetOriginsForType(
     99         type,
    100         base::Bind(&IndexedDBQuotaClientTest::OnGetOriginsComplete,
    101                    weak_factory_.GetWeakPtr()));
    102     FlushIndexedDBTaskRunner();
    103     base::MessageLoop::current()->RunUntilIdle();
    104     return origins_;
    105   }
    106 
    107   const std::set<GURL>& GetOriginsForHost(quota::QuotaClient* client,
    108                                           quota::StorageType type,
    109                                           const std::string& host) {
    110     origins_.clear();
    111     client->GetOriginsForHost(
    112         type,
    113         host,
    114         base::Bind(&IndexedDBQuotaClientTest::OnGetOriginsComplete,
    115                    weak_factory_.GetWeakPtr()));
    116     FlushIndexedDBTaskRunner();
    117     base::MessageLoop::current()->RunUntilIdle();
    118     return origins_;
    119   }
    120 
    121   quota::QuotaStatusCode DeleteOrigin(quota::QuotaClient* client,
    122                                       const GURL& origin_url) {
    123     delete_status_ = quota::kQuotaStatusUnknown;
    124     client->DeleteOriginData(
    125         origin_url,
    126         kTemp,
    127         base::Bind(&IndexedDBQuotaClientTest::OnDeleteOriginComplete,
    128                    weak_factory_.GetWeakPtr()));
    129     FlushIndexedDBTaskRunner();
    130     base::MessageLoop::current()->RunUntilIdle();
    131     return delete_status_;
    132   }
    133 
    134   IndexedDBContextImpl* idb_context() { return idb_context_; }
    135 
    136   void SetFileSizeTo(const base::FilePath& path, int size) {
    137     std::string junk(size, 'a');
    138     ASSERT_EQ(size, file_util::WriteFile(path, junk.c_str(), size));
    139   }
    140 
    141   void AddFakeIndexedDB(const GURL& origin, int size) {
    142     base::FilePath file_path_origin = idb_context()->GetFilePathForTesting(
    143         webkit_database::GetIdentifierFromOrigin(origin));
    144     if (!file_util::CreateDirectory(file_path_origin)) {
    145       LOG(ERROR) << "failed to file_util::CreateDirectory "
    146                  << file_path_origin.value();
    147     }
    148     file_path_origin = file_path_origin.Append(FILE_PATH_LITERAL("fake_file"));
    149     SetFileSizeTo(file_path_origin, size);
    150     idb_context()->ResetCaches();
    151   }
    152 
    153  private:
    154   void OnGetOriginUsageComplete(int64 usage) { usage_ = usage; }
    155 
    156   void OnGetOriginsComplete(const std::set<GURL>& origins) {
    157     origins_ = origins;
    158   }
    159 
    160   void OnDeleteOriginComplete(quota::QuotaStatusCode code) {
    161     delete_status_ = code;
    162   }
    163 
    164   base::ScopedTempDir temp_dir_;
    165   int64 usage_;
    166   std::set<GURL> origins_;
    167   scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
    168   scoped_refptr<IndexedDBContextImpl> idb_context_;
    169   base::WeakPtrFactory<IndexedDBQuotaClientTest> weak_factory_;
    170   content::TestBrowserThreadBundle thread_bundle_;
    171   scoped_ptr<TestBrowserContext> browser_context_;
    172   quota::QuotaStatusCode delete_status_;
    173 };
    174 
    175 TEST_F(IndexedDBQuotaClientTest, GetOriginUsage) {
    176   IndexedDBQuotaClient client(idb_context());
    177 
    178   AddFakeIndexedDB(kOriginA, 6);
    179   AddFakeIndexedDB(kOriginB, 3);
    180   EXPECT_EQ(6, GetOriginUsage(&client, kOriginA, kTemp));
    181   EXPECT_EQ(0, GetOriginUsage(&client, kOriginA, kPerm));
    182   EXPECT_EQ(3, GetOriginUsage(&client, kOriginB, kTemp));
    183   EXPECT_EQ(0, GetOriginUsage(&client, kOriginB, kPerm));
    184 
    185   AddFakeIndexedDB(kOriginA, 1000);
    186   EXPECT_EQ(1000, GetOriginUsage(&client, kOriginA, kTemp));
    187   EXPECT_EQ(0, GetOriginUsage(&client, kOriginA, kPerm));
    188   EXPECT_EQ(3, GetOriginUsage(&client, kOriginB, kTemp));
    189   EXPECT_EQ(0, GetOriginUsage(&client, kOriginB, kPerm));
    190 }
    191 
    192 TEST_F(IndexedDBQuotaClientTest, GetOriginsForHost) {
    193   IndexedDBQuotaClient client(idb_context());
    194 
    195   EXPECT_EQ(kOriginA.host(), kOriginB.host());
    196   EXPECT_NE(kOriginA.host(), kOriginOther.host());
    197 
    198   std::set<GURL> origins = GetOriginsForHost(&client, kTemp, kOriginA.host());
    199   EXPECT_TRUE(origins.empty());
    200 
    201   AddFakeIndexedDB(kOriginA, 1000);
    202   origins = GetOriginsForHost(&client, kTemp, kOriginA.host());
    203   EXPECT_EQ(origins.size(), 1ul);
    204   EXPECT_TRUE(origins.find(kOriginA) != origins.end());
    205 
    206   AddFakeIndexedDB(kOriginB, 1000);
    207   origins = GetOriginsForHost(&client, kTemp, kOriginA.host());
    208   EXPECT_EQ(origins.size(), 2ul);
    209   EXPECT_TRUE(origins.find(kOriginA) != origins.end());
    210   EXPECT_TRUE(origins.find(kOriginB) != origins.end());
    211 
    212   EXPECT_TRUE(GetOriginsForHost(&client, kPerm, kOriginA.host()).empty());
    213   EXPECT_TRUE(GetOriginsForHost(&client, kTemp, kOriginOther.host()).empty());
    214 }
    215 
    216 TEST_F(IndexedDBQuotaClientTest, GetOriginsForType) {
    217   IndexedDBQuotaClient client(idb_context());
    218 
    219   EXPECT_TRUE(GetOriginsForType(&client, kTemp).empty());
    220   EXPECT_TRUE(GetOriginsForType(&client, kPerm).empty());
    221 
    222   AddFakeIndexedDB(kOriginA, 1000);
    223   std::set<GURL> origins = GetOriginsForType(&client, kTemp);
    224   EXPECT_EQ(origins.size(), 1ul);
    225   EXPECT_TRUE(origins.find(kOriginA) != origins.end());
    226 
    227   EXPECT_TRUE(GetOriginsForType(&client, kPerm).empty());
    228 }
    229 
    230 TEST_F(IndexedDBQuotaClientTest, DeleteOrigin) {
    231   IndexedDBQuotaClient client(idb_context());
    232 
    233   AddFakeIndexedDB(kOriginA, 1000);
    234   AddFakeIndexedDB(kOriginB, 50);
    235   EXPECT_EQ(1000, GetOriginUsage(&client, kOriginA, kTemp));
    236   EXPECT_EQ(50, GetOriginUsage(&client, kOriginB, kTemp));
    237 
    238   quota::QuotaStatusCode delete_status = DeleteOrigin(&client, kOriginA);
    239   EXPECT_EQ(quota::kQuotaStatusOk, delete_status);
    240   EXPECT_EQ(0, GetOriginUsage(&client, kOriginA, kTemp));
    241   EXPECT_EQ(50, GetOriginUsage(&client, kOriginB, kTemp));
    242 }
    243 
    244 }  // namespace content
    245