| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/indexed_db/indexed_db_backing_store.h" | 5 #include "content/browser/indexed_db/indexed_db_backing_store.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 #include "content/browser/quota/mock_quota_manager_proxy.h" | 25 #include "content/browser/quota/mock_quota_manager_proxy.h" |
| 26 #include "content/public/test/mock_special_storage_policy.h" | 26 #include "content/public/test/mock_special_storage_policy.h" |
| 27 #include "content/public/test/test_browser_thread_bundle.h" | 27 #include "content/public/test/test_browser_thread_bundle.h" |
| 28 #include "net/url_request/url_request_test_util.h" | 28 #include "net/url_request/url_request_test_util.h" |
| 29 #include "storage/browser/blob/blob_data_handle.h" | 29 #include "storage/browser/blob/blob_data_handle.h" |
| 30 #include "storage/browser/quota/special_storage_policy.h" | 30 #include "storage/browser/quota/special_storage_policy.h" |
| 31 #include "testing/gtest/include/gtest/gtest.h" | 31 #include "testing/gtest/include/gtest/gtest.h" |
| 32 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h" | 32 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h" |
| 33 | 33 |
| 34 using base::ASCIIToUTF16; | 34 using base::ASCIIToUTF16; |
| 35 using url::Origin; |
| 35 | 36 |
| 36 namespace content { | 37 namespace content { |
| 37 | 38 |
| 38 namespace { | 39 namespace { |
| 39 | 40 |
| 40 class Comparator : public LevelDBComparator { | 41 class Comparator : public LevelDBComparator { |
| 41 public: | 42 public: |
| 42 int Compare(const base::StringPiece& a, | 43 int Compare(const base::StringPiece& a, |
| 43 const base::StringPiece& b) const override { | 44 const base::StringPiece& b) const override { |
| 44 return content::Compare(a, b, false /*index_keys*/); | 45 return content::Compare(a, b, false /*index_keys*/); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 60 } | 61 } |
| 61 | 62 |
| 62 private: | 63 private: |
| 63 DISALLOW_COPY_AND_ASSIGN(DefaultLevelDBFactory); | 64 DISALLOW_COPY_AND_ASSIGN(DefaultLevelDBFactory); |
| 64 }; | 65 }; |
| 65 | 66 |
| 66 class TestableIndexedDBBackingStore : public IndexedDBBackingStore { | 67 class TestableIndexedDBBackingStore : public IndexedDBBackingStore { |
| 67 public: | 68 public: |
| 68 static scoped_refptr<TestableIndexedDBBackingStore> Open( | 69 static scoped_refptr<TestableIndexedDBBackingStore> Open( |
| 69 IndexedDBFactory* indexed_db_factory, | 70 IndexedDBFactory* indexed_db_factory, |
| 70 const GURL& origin_url, | 71 const Origin& origin, |
| 71 const base::FilePath& path_base, | 72 const base::FilePath& path_base, |
| 72 net::URLRequestContext* request_context, | 73 net::URLRequestContext* request_context, |
| 73 LevelDBFactory* leveldb_factory, | 74 LevelDBFactory* leveldb_factory, |
| 74 base::SequencedTaskRunner* task_runner, | 75 base::SequencedTaskRunner* task_runner, |
| 75 leveldb::Status* status) { | 76 leveldb::Status* status) { |
| 76 DCHECK(!path_base.empty()); | 77 DCHECK(!path_base.empty()); |
| 77 | 78 |
| 78 std::unique_ptr<LevelDBComparator> comparator(new Comparator()); | 79 std::unique_ptr<LevelDBComparator> comparator(new Comparator()); |
| 79 | 80 |
| 80 if (!base::CreateDirectory(path_base)) { | 81 if (!base::CreateDirectory(path_base)) { |
| 81 *status = leveldb::Status::IOError("Unable to create base dir"); | 82 *status = leveldb::Status::IOError("Unable to create base dir"); |
| 82 return scoped_refptr<TestableIndexedDBBackingStore>(); | 83 return scoped_refptr<TestableIndexedDBBackingStore>(); |
| 83 } | 84 } |
| 84 | 85 |
| 85 const base::FilePath file_path = path_base.AppendASCII("test_db_path"); | 86 const base::FilePath file_path = path_base.AppendASCII("test_db_path"); |
| 86 const base::FilePath blob_path = path_base.AppendASCII("test_blob_path"); | 87 const base::FilePath blob_path = path_base.AppendASCII("test_blob_path"); |
| 87 | 88 |
| 88 std::unique_ptr<LevelDBDatabase> db; | 89 std::unique_ptr<LevelDBDatabase> db; |
| 89 bool is_disk_full = false; | 90 bool is_disk_full = false; |
| 90 *status = leveldb_factory->OpenLevelDB( | 91 *status = leveldb_factory->OpenLevelDB( |
| 91 file_path, comparator.get(), &db, &is_disk_full); | 92 file_path, comparator.get(), &db, &is_disk_full); |
| 92 | 93 |
| 93 if (!db || !status->ok()) | 94 if (!db || !status->ok()) |
| 94 return scoped_refptr<TestableIndexedDBBackingStore>(); | 95 return scoped_refptr<TestableIndexedDBBackingStore>(); |
| 95 | 96 |
| 96 scoped_refptr<TestableIndexedDBBackingStore> backing_store( | 97 scoped_refptr<TestableIndexedDBBackingStore> backing_store( |
| 97 new TestableIndexedDBBackingStore( | 98 new TestableIndexedDBBackingStore(indexed_db_factory, origin, blob_path, |
| 98 indexed_db_factory, origin_url, blob_path, request_context, | 99 request_context, std::move(db), |
| 99 std::move(db), std::move(comparator), task_runner)); | 100 std::move(comparator), task_runner)); |
| 100 | 101 |
| 101 *status = backing_store->SetUpMetadata(); | 102 *status = backing_store->SetUpMetadata(); |
| 102 if (!status->ok()) | 103 if (!status->ok()) |
| 103 return scoped_refptr<TestableIndexedDBBackingStore>(); | 104 return scoped_refptr<TestableIndexedDBBackingStore>(); |
| 104 | 105 |
| 105 return backing_store; | 106 return backing_store; |
| 106 } | 107 } |
| 107 | 108 |
| 108 const std::vector<IndexedDBBackingStore::Transaction::WriteDescriptor>& | 109 const std::vector<IndexedDBBackingStore::Transaction::WriteDescriptor>& |
| 109 writes() const { | 110 writes() const { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 return true; | 147 return true; |
| 147 } | 148 } |
| 148 | 149 |
| 149 // Timers don't play nicely with unit tests. | 150 // Timers don't play nicely with unit tests. |
| 150 void StartJournalCleaningTimer() override { | 151 void StartJournalCleaningTimer() override { |
| 151 CleanPrimaryJournalIgnoreReturn(); | 152 CleanPrimaryJournalIgnoreReturn(); |
| 152 } | 153 } |
| 153 | 154 |
| 154 private: | 155 private: |
| 155 TestableIndexedDBBackingStore(IndexedDBFactory* indexed_db_factory, | 156 TestableIndexedDBBackingStore(IndexedDBFactory* indexed_db_factory, |
| 156 const GURL& origin_url, | 157 const Origin& origin, |
| 157 const base::FilePath& blob_path, | 158 const base::FilePath& blob_path, |
| 158 net::URLRequestContext* request_context, | 159 net::URLRequestContext* request_context, |
| 159 std::unique_ptr<LevelDBDatabase> db, | 160 std::unique_ptr<LevelDBDatabase> db, |
| 160 std::unique_ptr<LevelDBComparator> comparator, | 161 std::unique_ptr<LevelDBComparator> comparator, |
| 161 base::SequencedTaskRunner* task_runner) | 162 base::SequencedTaskRunner* task_runner) |
| 162 : IndexedDBBackingStore(indexed_db_factory, | 163 : IndexedDBBackingStore(indexed_db_factory, |
| 163 origin_url, | 164 origin, |
| 164 blob_path, | 165 blob_path, |
| 165 request_context, | 166 request_context, |
| 166 std::move(db), | 167 std::move(db), |
| 167 std::move(comparator), | 168 std::move(comparator), |
| 168 task_runner), | 169 task_runner), |
| 169 database_id_(0) {} | 170 database_id_(0) {} |
| 170 | 171 |
| 171 int64_t database_id_; | 172 int64_t database_id_; |
| 172 std::vector<Transaction::WriteDescriptor> writes_; | 173 std::vector<Transaction::WriteDescriptor> writes_; |
| 173 | 174 |
| 174 // This is modified in an overridden virtual function that is properly const | 175 // This is modified in an overridden virtual function that is properly const |
| 175 // in the real implementation, therefore must be mutable here. | 176 // in the real implementation, therefore must be mutable here. |
| 176 mutable std::vector<int64_t> removals_; | 177 mutable std::vector<int64_t> removals_; |
| 177 | 178 |
| 178 DISALLOW_COPY_AND_ASSIGN(TestableIndexedDBBackingStore); | 179 DISALLOW_COPY_AND_ASSIGN(TestableIndexedDBBackingStore); |
| 179 }; | 180 }; |
| 180 | 181 |
| 181 class TestIDBFactory : public IndexedDBFactoryImpl { | 182 class TestIDBFactory : public IndexedDBFactoryImpl { |
| 182 public: | 183 public: |
| 183 explicit TestIDBFactory(IndexedDBContextImpl* idb_context) | 184 explicit TestIDBFactory(IndexedDBContextImpl* idb_context) |
| 184 : IndexedDBFactoryImpl(idb_context) {} | 185 : IndexedDBFactoryImpl(idb_context) {} |
| 185 | 186 |
| 186 scoped_refptr<TestableIndexedDBBackingStore> OpenBackingStoreForTest( | 187 scoped_refptr<TestableIndexedDBBackingStore> OpenBackingStoreForTest( |
| 187 const GURL& origin, | 188 const Origin& origin, |
| 188 net::URLRequestContext* url_request_context) { | 189 net::URLRequestContext* url_request_context) { |
| 189 blink::WebIDBDataLoss data_loss; | 190 blink::WebIDBDataLoss data_loss; |
| 190 std::string data_loss_reason; | 191 std::string data_loss_reason; |
| 191 bool disk_full; | 192 bool disk_full; |
| 192 leveldb::Status status; | 193 leveldb::Status status; |
| 193 scoped_refptr<IndexedDBBackingStore> backing_store = | 194 scoped_refptr<IndexedDBBackingStore> backing_store = |
| 194 OpenBackingStore(origin, | 195 OpenBackingStore(origin, |
| 195 context()->data_path(), | 196 context()->data_path(), |
| 196 url_request_context, | 197 url_request_context, |
| 197 &data_loss, | 198 &data_loss, |
| 198 &data_loss_reason, | 199 &data_loss_reason, |
| 199 &disk_full, | 200 &disk_full, |
| 200 &status); | 201 &status); |
| 201 scoped_refptr<TestableIndexedDBBackingStore> testable_store = | 202 scoped_refptr<TestableIndexedDBBackingStore> testable_store = |
| 202 static_cast<TestableIndexedDBBackingStore*>(backing_store.get()); | 203 static_cast<TestableIndexedDBBackingStore*>(backing_store.get()); |
| 203 return testable_store; | 204 return testable_store; |
| 204 } | 205 } |
| 205 | 206 |
| 206 protected: | 207 protected: |
| 207 ~TestIDBFactory() override {} | 208 ~TestIDBFactory() override {} |
| 208 | 209 |
| 209 scoped_refptr<IndexedDBBackingStore> OpenBackingStoreHelper( | 210 scoped_refptr<IndexedDBBackingStore> OpenBackingStoreHelper( |
| 210 const GURL& origin_url, | 211 const Origin& origin, |
| 211 const base::FilePath& data_directory, | 212 const base::FilePath& data_directory, |
| 212 net::URLRequestContext* request_context, | 213 net::URLRequestContext* request_context, |
| 213 blink::WebIDBDataLoss* data_loss, | 214 blink::WebIDBDataLoss* data_loss, |
| 214 std::string* data_loss_message, | 215 std::string* data_loss_message, |
| 215 bool* disk_full, | 216 bool* disk_full, |
| 216 bool first_time, | 217 bool first_time, |
| 217 leveldb::Status* status) override { | 218 leveldb::Status* status) override { |
| 218 DefaultLevelDBFactory leveldb_factory; | 219 DefaultLevelDBFactory leveldb_factory; |
| 219 return TestableIndexedDBBackingStore::Open(this, | 220 return TestableIndexedDBBackingStore::Open( |
| 220 origin_url, | 221 this, origin, data_directory, request_context, &leveldb_factory, |
| 221 data_directory, | 222 context()->TaskRunner(), status); |
| 222 request_context, | |
| 223 &leveldb_factory, | |
| 224 context()->TaskRunner(), | |
| 225 status); | |
| 226 } | 223 } |
| 227 | 224 |
| 228 private: | 225 private: |
| 229 DISALLOW_COPY_AND_ASSIGN(TestIDBFactory); | 226 DISALLOW_COPY_AND_ASSIGN(TestIDBFactory); |
| 230 }; | 227 }; |
| 231 | 228 |
| 232 class IndexedDBBackingStoreTest : public testing::Test { | 229 class IndexedDBBackingStoreTest : public testing::Test { |
| 233 public: | 230 public: |
| 234 IndexedDBBackingStoreTest() {} | 231 IndexedDBBackingStoreTest() {} |
| 235 void SetUp() override { | 232 void SetUp() override { |
| 236 const GURL origin("http://localhost:81"); | 233 const Origin origin(GURL("http://localhost:81")); |
| 237 task_runner_ = new base::TestSimpleTaskRunner(); | 234 task_runner_ = new base::TestSimpleTaskRunner(); |
| 238 special_storage_policy_ = new MockSpecialStoragePolicy(); | 235 special_storage_policy_ = new MockSpecialStoragePolicy(); |
| 239 quota_manager_proxy_ = new MockQuotaManagerProxy(nullptr, nullptr); | 236 quota_manager_proxy_ = new MockQuotaManagerProxy(nullptr, nullptr); |
| 240 special_storage_policy_->SetAllUnlimited(true); | 237 special_storage_policy_->SetAllUnlimited(true); |
| 241 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 238 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 242 idb_context_ = new IndexedDBContextImpl( | 239 idb_context_ = new IndexedDBContextImpl( |
| 243 temp_dir_.path(), special_storage_policy_.get(), | 240 temp_dir_.path(), special_storage_policy_.get(), |
| 244 quota_manager_proxy_.get(), task_runner_.get()); | 241 quota_manager_proxy_.get(), task_runner_.get()); |
| 245 idb_factory_ = new TestIDBFactory(idb_context_.get()); | 242 idb_factory_ = new TestIDBFactory(idb_context_.get()); |
| 246 backing_store_ = | 243 backing_store_ = |
| (...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1044 | 1041 |
| 1045 std::vector<base::string16> names = backing_store_->GetDatabaseNames(&s); | 1042 std::vector<base::string16> names = backing_store_->GetDatabaseNames(&s); |
| 1046 EXPECT_TRUE(s.ok()); | 1043 EXPECT_TRUE(s.ok()); |
| 1047 EXPECT_EQ(names.size(), 1ULL); | 1044 EXPECT_EQ(names.size(), 1ULL); |
| 1048 EXPECT_EQ(names[0], db1_name); | 1045 EXPECT_EQ(names[0], db1_name); |
| 1049 } | 1046 } |
| 1050 | 1047 |
| 1051 } // namespace | 1048 } // namespace |
| 1052 | 1049 |
| 1053 } // namespace content | 1050 } // namespace content |
| OLD | NEW |