| 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 |
| 11 #include "base/callback.h" | 11 #include "base/callback.h" |
| 12 #include "base/files/file_util.h" | 12 #include "base/files/file_util.h" |
| 13 #include "base/files/scoped_temp_dir.h" | 13 #include "base/files/scoped_temp_dir.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/macros.h" | 15 #include "base/macros.h" |
| 16 #include "base/memory/ptr_util.h" | 16 #include "base/memory/ptr_util.h" |
| 17 #include "base/sequenced_task_runner.h" | 17 #include "base/sequenced_task_runner.h" |
| 18 #include "base/strings/string16.h" | 18 #include "base/strings/string16.h" |
| 19 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
| 20 #include "base/test/test_simple_task_runner.h" | |
| 21 #include "content/browser/indexed_db/indexed_db_context_impl.h" | 20 #include "content/browser/indexed_db/indexed_db_context_impl.h" |
| 22 #include "content/browser/indexed_db/indexed_db_factory_impl.h" | 21 #include "content/browser/indexed_db/indexed_db_factory_impl.h" |
| 23 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" | 22 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" |
| 24 #include "content/browser/indexed_db/indexed_db_value.h" | 23 #include "content/browser/indexed_db/indexed_db_value.h" |
| 25 #include "content/browser/indexed_db/leveldb/leveldb_factory.h" | 24 #include "content/browser/indexed_db/leveldb/leveldb_factory.h" |
| 26 #include "content/public/test/test_browser_thread_bundle.h" | 25 #include "content/public/test/test_browser_thread_bundle.h" |
| 26 #include "content/public/test/test_utils.h" |
| 27 #include "net/url_request/url_request_test_util.h" | 27 #include "net/url_request/url_request_test_util.h" |
| 28 #include "storage/browser/blob/blob_data_handle.h" | 28 #include "storage/browser/blob/blob_data_handle.h" |
| 29 #include "storage/browser/quota/special_storage_policy.h" | 29 #include "storage/browser/quota/special_storage_policy.h" |
| 30 #include "storage/browser/test/mock_quota_manager_proxy.h" | 30 #include "storage/browser/test/mock_quota_manager_proxy.h" |
| 31 #include "storage/browser/test/mock_special_storage_policy.h" | 31 #include "storage/browser/test/mock_special_storage_policy.h" |
| 32 #include "testing/gtest/include/gtest/gtest.h" | 32 #include "testing/gtest/include/gtest/gtest.h" |
| 33 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h" | 33 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBTypes.h" |
| 34 | 34 |
| 35 using base::ASCIIToUTF16; | 35 using base::ASCIIToUTF16; |
| 36 using url::Origin; | 36 using url::Origin; |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 this, origin, data_directory, request_context_getter, &leveldb_factory, | 225 this, origin, data_directory, request_context_getter, &leveldb_factory, |
| 226 context()->TaskRunner(), status); | 226 context()->TaskRunner(), status); |
| 227 } | 227 } |
| 228 | 228 |
| 229 private: | 229 private: |
| 230 DISALLOW_COPY_AND_ASSIGN(TestIDBFactory); | 230 DISALLOW_COPY_AND_ASSIGN(TestIDBFactory); |
| 231 }; | 231 }; |
| 232 | 232 |
| 233 class IndexedDBBackingStoreTest : public testing::Test { | 233 class IndexedDBBackingStoreTest : public testing::Test { |
| 234 public: | 234 public: |
| 235 IndexedDBBackingStoreTest() {} | 235 IndexedDBBackingStoreTest() |
| 236 : url_request_context_getter_( |
| 237 base::MakeRefCounted<net::TestURLRequestContextGetter>( |
| 238 BrowserThread::GetTaskRunnerForThread(BrowserThread::UI))), |
| 239 special_storage_policy_( |
| 240 base::MakeRefCounted<MockSpecialStoragePolicy>()), |
| 241 quota_manager_proxy_( |
| 242 base::MakeRefCounted<MockQuotaManagerProxy>(nullptr, nullptr)) {} |
| 243 |
| 236 void SetUp() override { | 244 void SetUp() override { |
| 237 const Origin origin(GURL("http://localhost:81")); | |
| 238 task_runner_ = new base::TestSimpleTaskRunner(); | |
| 239 url_request_context_getter_ = | |
| 240 new net::TestURLRequestContextGetter(task_runner_); | |
| 241 special_storage_policy_ = new MockSpecialStoragePolicy(); | |
| 242 quota_manager_proxy_ = new MockQuotaManagerProxy(nullptr, nullptr); | |
| 243 special_storage_policy_->SetAllUnlimited(true); | 245 special_storage_policy_->SetAllUnlimited(true); |
| 244 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 246 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 245 idb_context_ = new IndexedDBContextImpl( | 247 idb_context_ = base::MakeRefCounted<IndexedDBContextImpl>( |
| 246 temp_dir_.GetPath(), special_storage_policy_.get(), | 248 temp_dir_.GetPath(), special_storage_policy_, quota_manager_proxy_); |
| 247 quota_manager_proxy_.get(), task_runner_.get()); | 249 |
| 248 idb_factory_ = new TestIDBFactory(idb_context_.get()); | 250 // Factory and backing store must be created on IDB task runner. |
| 249 backing_store_ = idb_factory_->OpenBackingStoreForTest( | 251 idb_context_->TaskRunner()->PostTask( |
| 250 origin, url_request_context_getter_); | 252 FROM_HERE, base::BindOnce( |
| 253 [](IndexedDBBackingStoreTest* test) { |
| 254 const Origin origin(GURL("http://localhost:81")); |
| 255 test->idb_factory_ = |
| 256 base::MakeRefCounted<TestIDBFactory>( |
| 257 test->idb_context_.get()); |
| 258 test->backing_store_ = |
| 259 test->idb_factory_->OpenBackingStoreForTest( |
| 260 origin, test->url_request_context_getter_); |
| 261 }, |
| 262 base::Unretained(this))); |
| 263 RunAllBlockingPoolTasksUntilIdle(); |
| 251 | 264 |
| 252 // useful keys and values during tests | 265 // useful keys and values during tests |
| 253 value1_ = IndexedDBValue("value1", std::vector<IndexedDBBlobInfo>()); | 266 value1_ = IndexedDBValue("value1", std::vector<IndexedDBBlobInfo>()); |
| 254 value2_ = IndexedDBValue("value2", std::vector<IndexedDBBlobInfo>()); | 267 value2_ = IndexedDBValue("value2", std::vector<IndexedDBBlobInfo>()); |
| 255 | 268 |
| 269 key1_ = IndexedDBKey(99, blink::kWebIDBKeyTypeNumber); |
| 270 key2_ = IndexedDBKey(ASCIIToUTF16("key2")); |
| 271 } |
| 272 |
| 273 void TearDown() override { |
| 274 // Factory and backing store must be destroyed on IDB task runner. |
| 275 idb_context_->TaskRunner()->PostTask( |
| 276 FROM_HERE, base::BindOnce( |
| 277 [](IndexedDBBackingStoreTest* test) { |
| 278 test->idb_factory_ = nullptr; |
| 279 test->backing_store_ = nullptr; |
| 280 }, |
| 281 base::Unretained(this))); |
| 282 RunAllBlockingPoolTasksUntilIdle(); |
| 283 |
| 284 quota_manager_proxy_->SimulateQuotaManagerDestroyed(); |
| 285 } |
| 286 |
| 287 TestableIndexedDBBackingStore* backing_store() const { |
| 288 return backing_store_.get(); |
| 289 } |
| 290 |
| 291 // Sample keys and values that are consistent. Public so that posted lambdas |
| 292 // passed |this| can access them. |
| 293 IndexedDBKey key1_; |
| 294 IndexedDBKey key2_; |
| 295 IndexedDBValue value1_; |
| 296 IndexedDBValue value2_; |
| 297 |
| 298 protected: |
| 299 // Must be initialized before url_request_context_getter_ |
| 300 TestBrowserThreadBundle thread_bundle_; |
| 301 |
| 302 base::ScopedTempDir temp_dir_; |
| 303 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; |
| 304 scoped_refptr<MockSpecialStoragePolicy> special_storage_policy_; |
| 305 scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_; |
| 306 scoped_refptr<IndexedDBContextImpl> idb_context_; |
| 307 scoped_refptr<TestIDBFactory> idb_factory_; |
| 308 |
| 309 scoped_refptr<TestableIndexedDBBackingStore> backing_store_; |
| 310 |
| 311 private: |
| 312 DISALLOW_COPY_AND_ASSIGN(IndexedDBBackingStoreTest); |
| 313 }; |
| 314 |
| 315 class IndexedDBBackingStoreTestWithBlobs : public IndexedDBBackingStoreTest { |
| 316 public: |
| 317 IndexedDBBackingStoreTestWithBlobs() {} |
| 318 |
| 319 void SetUp() override { |
| 320 IndexedDBBackingStoreTest::SetUp(); |
| 321 |
| 322 // useful keys and values during tests |
| 256 blob_info_.push_back( | 323 blob_info_.push_back( |
| 257 IndexedDBBlobInfo("uuid 3", base::UTF8ToUTF16("blob type"), 1)); | 324 IndexedDBBlobInfo("uuid 3", base::UTF8ToUTF16("blob type"), 1)); |
| 258 blob_info_.push_back(IndexedDBBlobInfo( | 325 blob_info_.push_back(IndexedDBBlobInfo( |
| 259 "uuid 4", base::FilePath(FILE_PATH_LITERAL("path/to/file")), | 326 "uuid 4", base::FilePath(FILE_PATH_LITERAL("path/to/file")), |
| 260 base::UTF8ToUTF16("file name"), base::UTF8ToUTF16("file type"))); | 327 base::UTF8ToUTF16("file name"), base::UTF8ToUTF16("file type"))); |
| 261 blob_info_.push_back(IndexedDBBlobInfo("uuid 5", base::FilePath(), | 328 blob_info_.push_back(IndexedDBBlobInfo("uuid 5", base::FilePath(), |
| 262 base::UTF8ToUTF16("file name"), | 329 base::UTF8ToUTF16("file name"), |
| 263 base::UTF8ToUTF16("file type"))); | 330 base::UTF8ToUTF16("file type"))); |
| 264 value3_ = IndexedDBValue("value3", blob_info_); | 331 value3_ = IndexedDBValue("value3", blob_info_); |
| 265 | 332 |
| 266 key1_ = IndexedDBKey(99, blink::kWebIDBKeyTypeNumber); | |
| 267 key2_ = IndexedDBKey(ASCIIToUTF16("key2")); | |
| 268 key3_ = IndexedDBKey(ASCIIToUTF16("key3")); | 333 key3_ = IndexedDBKey(ASCIIToUTF16("key3")); |
| 269 } | 334 } |
| 270 | 335 |
| 271 void TearDown() override { | |
| 272 quota_manager_proxy_->SimulateQuotaManagerDestroyed(); | |
| 273 } | |
| 274 | |
| 275 // This just checks the data that survive getting stored and recalled, e.g. | 336 // This just checks the data that survive getting stored and recalled, e.g. |
| 276 // the file path and UUID will change and thus aren't verified. | 337 // the file path and UUID will change and thus aren't verified. |
| 277 bool CheckBlobInfoMatches(const std::vector<IndexedDBBlobInfo>& reads) const { | 338 bool CheckBlobInfoMatches(const std::vector<IndexedDBBlobInfo>& reads) const { |
| 339 DCHECK(idb_context_->TaskRunner()->RunsTasksInCurrentSequence()); |
| 340 |
| 278 if (blob_info_.size() != reads.size()) | 341 if (blob_info_.size() != reads.size()) |
| 279 return false; | 342 return false; |
| 280 for (size_t i = 0; i < blob_info_.size(); ++i) { | 343 for (size_t i = 0; i < blob_info_.size(); ++i) { |
| 281 const IndexedDBBlobInfo& a = blob_info_[i]; | 344 const IndexedDBBlobInfo& a = blob_info_[i]; |
| 282 const IndexedDBBlobInfo& b = reads[i]; | 345 const IndexedDBBlobInfo& b = reads[i]; |
| 283 if (a.is_file() != b.is_file()) | 346 if (a.is_file() != b.is_file()) |
| 284 return false; | 347 return false; |
| 285 if (a.type() != b.type()) | 348 if (a.type() != b.type()) |
| 286 return false; | 349 return false; |
| 287 if (a.is_file()) { | 350 if (a.is_file()) { |
| 288 if (a.file_name() != b.file_name()) | 351 if (a.file_name() != b.file_name()) |
| 289 return false; | 352 return false; |
| 290 } else { | 353 } else { |
| 291 if (a.size() != b.size()) | 354 if (a.size() != b.size()) |
| 292 return false; | 355 return false; |
| 293 } | 356 } |
| 294 } | 357 } |
| 295 return true; | 358 return true; |
| 296 } | 359 } |
| 297 | 360 |
| 298 bool CheckBlobReadsMatchWrites( | 361 bool CheckBlobReadsMatchWrites( |
| 299 const std::vector<IndexedDBBlobInfo>& reads) const { | 362 const std::vector<IndexedDBBlobInfo>& reads) const { |
| 363 DCHECK(idb_context_->TaskRunner()->RunsTasksInCurrentSequence()); |
| 364 |
| 300 if (backing_store_->writes().size() != reads.size()) | 365 if (backing_store_->writes().size() != reads.size()) |
| 301 return false; | 366 return false; |
| 302 std::set<int64_t> ids; | 367 std::set<int64_t> ids; |
| 303 for (const auto& write : backing_store_->writes()) | 368 for (const auto& write : backing_store_->writes()) |
| 304 ids.insert(write.key()); | 369 ids.insert(write.key()); |
| 305 if (ids.size() != backing_store_->writes().size()) | 370 if (ids.size() != backing_store_->writes().size()) |
| 306 return false; | 371 return false; |
| 307 for (const auto& read : reads) { | 372 for (const auto& read : reads) { |
| 308 if (ids.count(read.key()) != 1) | 373 if (ids.count(read.key()) != 1) |
| 309 return false; | 374 return false; |
| 310 } | 375 } |
| 311 return true; | 376 return true; |
| 312 } | 377 } |
| 313 | 378 |
| 314 bool CheckBlobWrites() const { | 379 bool CheckBlobWrites() const { |
| 380 DCHECK(idb_context_->TaskRunner()->RunsTasksInCurrentSequence()); |
| 381 |
| 315 if (backing_store_->writes().size() != blob_info_.size()) | 382 if (backing_store_->writes().size() != blob_info_.size()) |
| 316 return false; | 383 return false; |
| 317 for (size_t i = 0; i < backing_store_->writes().size(); ++i) { | 384 for (size_t i = 0; i < backing_store_->writes().size(); ++i) { |
| 318 const IndexedDBBackingStore::Transaction::WriteDescriptor& desc = | 385 const IndexedDBBackingStore::Transaction::WriteDescriptor& desc = |
| 319 backing_store_->writes()[i]; | 386 backing_store_->writes()[i]; |
| 320 const IndexedDBBlobInfo& info = blob_info_[i]; | 387 const IndexedDBBlobInfo& info = blob_info_[i]; |
| 321 if (desc.is_file() != info.is_file()) { | 388 if (desc.is_file() != info.is_file()) { |
| 322 if (!info.is_file() || !info.file_path().empty()) | 389 if (!info.is_file() || !info.file_path().empty()) |
| 323 return false; | 390 return false; |
| 324 } else if (desc.is_file()) { | 391 } else if (desc.is_file()) { |
| 325 if (desc.file_path() != info.file_path()) | 392 if (desc.file_path() != info.file_path()) |
| 326 return false; | 393 return false; |
| 327 } else { | 394 } else { |
| 328 if (desc.url() != GURL("blob:uuid/" + info.uuid())) | 395 if (desc.url() != GURL("blob:uuid/" + info.uuid())) |
| 329 return false; | 396 return false; |
| 330 } | 397 } |
| 331 } | 398 } |
| 332 return true; | 399 return true; |
| 333 } | 400 } |
| 334 | 401 |
| 335 bool CheckBlobRemovals() const { | 402 bool CheckBlobRemovals() const { |
| 403 DCHECK(idb_context_->TaskRunner()->RunsTasksInCurrentSequence()); |
| 404 |
| 336 if (backing_store_->removals().size() != backing_store_->writes().size()) | 405 if (backing_store_->removals().size() != backing_store_->writes().size()) |
| 337 return false; | 406 return false; |
| 338 for (size_t i = 0; i < backing_store_->writes().size(); ++i) { | 407 for (size_t i = 0; i < backing_store_->writes().size(); ++i) { |
| 339 if (backing_store_->writes()[i].key() != backing_store_->removals()[i]) | 408 if (backing_store_->writes()[i].key() != backing_store_->removals()[i]) |
| 340 return false; | 409 return false; |
| 341 } | 410 } |
| 342 return true; | 411 return true; |
| 343 } | 412 } |
| 344 | 413 |
| 345 protected: | 414 // Sample keys and values that are consistent. Public so that posted lambdas |
| 346 // Must be initialized before url_request_context_getter_ | 415 // passed |this| can access them. |
| 347 TestBrowserThreadBundle thread_bundle_; | 416 IndexedDBKey key3_; |
| 417 IndexedDBValue value3_; |
| 348 | 418 |
| 349 base::ScopedTempDir temp_dir_; | 419 private: |
| 350 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; | 420 // Blob details referenced by |value3_|. The various CheckBlob*() methods |
| 351 scoped_refptr<MockSpecialStoragePolicy> special_storage_policy_; | 421 // can be used to verify the state as a test progresses. |
| 352 scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_; | |
| 353 scoped_refptr<IndexedDBContextImpl> idb_context_; | |
| 354 scoped_refptr<TestIDBFactory> idb_factory_; | |
| 355 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; | |
| 356 | |
| 357 scoped_refptr<TestableIndexedDBBackingStore> backing_store_; | |
| 358 | |
| 359 // Sample keys and values that are consistent. | |
| 360 IndexedDBKey key1_; | |
| 361 IndexedDBKey key2_; | |
| 362 IndexedDBKey key3_; | |
| 363 IndexedDBValue value1_; | |
| 364 IndexedDBValue value2_; | |
| 365 IndexedDBValue value3_; | |
| 366 std::vector<IndexedDBBlobInfo> blob_info_; | 422 std::vector<IndexedDBBlobInfo> blob_info_; |
| 367 | 423 |
| 368 private: | 424 DISALLOW_COPY_AND_ASSIGN(IndexedDBBackingStoreTestWithBlobs); |
| 369 DISALLOW_COPY_AND_ASSIGN(IndexedDBBackingStoreTest); | |
| 370 }; | 425 }; |
| 371 | 426 |
| 372 class TestCallback : public IndexedDBBackingStore::BlobWriteCallback { | 427 class TestCallback : public IndexedDBBackingStore::BlobWriteCallback { |
| 373 public: | 428 public: |
| 374 TestCallback() : called(false), succeeded(false) {} | 429 TestCallback() : called(false), succeeded(false) {} |
| 375 leveldb::Status Run(IndexedDBBackingStore::BlobWriteResult result) override { | 430 leveldb::Status Run(IndexedDBBackingStore::BlobWriteResult result) override { |
| 376 called = true; | 431 called = true; |
| 377 switch (result) { | 432 switch (result) { |
| 378 case IndexedDBBackingStore::BlobWriteResult::FAILURE_ASYNC: | 433 case IndexedDBBackingStore::BlobWriteResult::FAILURE_ASYNC: |
| 379 succeeded = false; | 434 succeeded = false; |
| 380 break; | 435 break; |
| 381 case IndexedDBBackingStore::BlobWriteResult::SUCCESS_ASYNC: | 436 case IndexedDBBackingStore::BlobWriteResult::SUCCESS_ASYNC: |
| 382 case IndexedDBBackingStore::BlobWriteResult::SUCCESS_SYNC: | 437 case IndexedDBBackingStore::BlobWriteResult::SUCCESS_SYNC: |
| 383 succeeded = true; | 438 succeeded = true; |
| 384 break; | 439 break; |
| 385 } | 440 } |
| 386 return leveldb::Status::OK(); | 441 return leveldb::Status::OK(); |
| 387 } | 442 } |
| 388 bool called; | 443 bool called; |
| 389 bool succeeded; | 444 bool succeeded; |
| 390 | 445 |
| 391 protected: | 446 protected: |
| 392 ~TestCallback() override {} | 447 ~TestCallback() override {} |
| 393 | 448 |
| 394 private: | 449 private: |
| 395 DISALLOW_COPY_AND_ASSIGN(TestCallback); | 450 DISALLOW_COPY_AND_ASSIGN(TestCallback); |
| 396 }; | 451 }; |
| 397 | 452 |
| 398 TEST_F(IndexedDBBackingStoreTest, PutGetConsistency) { | 453 TEST_F(IndexedDBBackingStoreTest, PutGetConsistency) { |
| 399 { | 454 idb_context_->TaskRunner()->PostTask( |
| 400 IndexedDBBackingStore::Transaction transaction1(backing_store_.get()); | 455 FROM_HERE, |
| 401 transaction1.Begin(); | 456 base::BindOnce( |
| 402 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; | 457 [](IndexedDBBackingStore* backing_store, IndexedDBKey key, |
| 403 IndexedDBBackingStore::RecordIdentifier record; | 458 IndexedDBValue value) { |
| 404 leveldb::Status s = backing_store_->PutRecord(&transaction1, 1, 1, key1_, | 459 { |
| 405 &value1_, &handles, &record); | 460 IndexedDBBackingStore::Transaction transaction1(backing_store); |
| 406 EXPECT_TRUE(s.ok()); | 461 transaction1.Begin(); |
| 407 scoped_refptr<TestCallback> callback(new TestCallback()); | 462 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; |
| 408 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok()); | 463 IndexedDBBackingStore::RecordIdentifier record; |
| 409 EXPECT_TRUE(callback->called); | 464 leveldb::Status s = backing_store->PutRecord( |
| 410 EXPECT_TRUE(callback->succeeded); | 465 &transaction1, 1, 1, key, &value, &handles, &record); |
| 411 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok()); | 466 EXPECT_TRUE(s.ok()); |
| 467 scoped_refptr<TestCallback> callback( |
| 468 base::MakeRefCounted<TestCallback>()); |
| 469 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok()); |
| 470 EXPECT_TRUE(callback->called); |
| 471 EXPECT_TRUE(callback->succeeded); |
| 472 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok()); |
| 473 } |
| 474 |
| 475 { |
| 476 IndexedDBBackingStore::Transaction transaction2(backing_store); |
| 477 transaction2.Begin(); |
| 478 IndexedDBValue result_value; |
| 479 EXPECT_TRUE( |
| 480 backing_store |
| 481 ->GetRecord(&transaction2, 1, 1, key, &result_value) |
| 482 .ok()); |
| 483 scoped_refptr<TestCallback> callback( |
| 484 base::MakeRefCounted<TestCallback>()); |
| 485 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok()); |
| 486 EXPECT_TRUE(callback->called); |
| 487 EXPECT_TRUE(callback->succeeded); |
| 488 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok()); |
| 489 EXPECT_EQ(value.bits, result_value.bits); |
| 490 } |
| 491 }, |
| 492 base::Unretained(backing_store()), key1_, value1_)); |
| 493 RunAllBlockingPoolTasksUntilIdle(); |
| 494 } |
| 495 |
| 496 TEST_F(IndexedDBBackingStoreTestWithBlobs, PutGetConsistencyWithBlobs) { |
| 497 struct TestState { |
| 498 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction1; |
| 499 scoped_refptr<TestCallback> callback1; |
| 500 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction3; |
| 501 scoped_refptr<TestCallback> callback3; |
| 502 } state; |
| 503 |
| 504 idb_context_->TaskRunner()->PostTask( |
| 505 FROM_HERE, |
| 506 base::BindOnce( |
| 507 [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) { |
| 508 // Initiate transaction1 - writing blobs. |
| 509 state->transaction1 = |
| 510 base::MakeUnique<IndexedDBBackingStore::Transaction>( |
| 511 test->backing_store()); |
| 512 state->transaction1->Begin(); |
| 513 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; |
| 514 IndexedDBBackingStore::RecordIdentifier record; |
| 515 EXPECT_TRUE(test->backing_store() |
| 516 ->PutRecord(state->transaction1.get(), 1, 1, |
| 517 test->key3_, &test->value3_, &handles, |
| 518 &record) |
| 519 .ok()); |
| 520 state->callback1 = base::MakeRefCounted<TestCallback>(); |
| 521 EXPECT_TRUE( |
| 522 state->transaction1->CommitPhaseOne(state->callback1).ok()); |
| 523 }, |
| 524 base::Unretained(this), base::Unretained(&state))); |
| 525 RunAllBlockingPoolTasksUntilIdle(); |
| 526 |
| 527 idb_context_->TaskRunner()->PostTask( |
| 528 FROM_HERE, |
| 529 base::BindOnce( |
| 530 [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) { |
| 531 // Finish up transaction1, verifying blob writes. |
| 532 EXPECT_TRUE(state->callback1->called); |
| 533 EXPECT_TRUE(state->callback1->succeeded); |
| 534 EXPECT_TRUE(test->CheckBlobWrites()); |
| 535 EXPECT_TRUE(state->transaction1->CommitPhaseTwo().ok()); |
| 536 |
| 537 // Initiate transaction2, reading blobs. |
| 538 IndexedDBBackingStore::Transaction transaction2( |
| 539 test->backing_store()); |
| 540 transaction2.Begin(); |
| 541 IndexedDBValue result_value; |
| 542 EXPECT_TRUE( |
| 543 test->backing_store() |
| 544 ->GetRecord(&transaction2, 1, 1, test->key3_, &result_value) |
| 545 .ok()); |
| 546 |
| 547 // Finish up transaction2, verifying blob reads. |
| 548 scoped_refptr<TestCallback> callback( |
| 549 base::MakeRefCounted<TestCallback>()); |
| 550 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok()); |
| 551 EXPECT_TRUE(callback->called); |
| 552 EXPECT_TRUE(callback->succeeded); |
| 553 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok()); |
| 554 EXPECT_EQ(test->value3_.bits, result_value.bits); |
| 555 EXPECT_TRUE(test->CheckBlobInfoMatches(result_value.blob_info)); |
| 556 EXPECT_TRUE( |
| 557 test->CheckBlobReadsMatchWrites(result_value.blob_info)); |
| 558 |
| 559 // Initiate transaction3, deleting blobs. |
| 560 state->transaction3 = |
| 561 base::MakeUnique<IndexedDBBackingStore::Transaction>( |
| 562 test->backing_store()); |
| 563 state->transaction3->Begin(); |
| 564 EXPECT_TRUE(test->backing_store() |
| 565 ->DeleteRange(state->transaction3.get(), 1, 1, |
| 566 IndexedDBKeyRange(test->key3_)) |
| 567 .ok()); |
| 568 state->callback3 = base::MakeRefCounted<TestCallback>(); |
| 569 EXPECT_TRUE( |
| 570 state->transaction3->CommitPhaseOne(state->callback3).ok()); |
| 571 |
| 572 }, |
| 573 base::Unretained(this), base::Unretained(&state))); |
| 574 RunAllBlockingPoolTasksUntilIdle(); |
| 575 |
| 576 idb_context_->TaskRunner()->PostTask( |
| 577 FROM_HERE, |
| 578 base::BindOnce( |
| 579 [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) { |
| 580 // Finish up transaction 3, verifying blob deletes. |
| 581 EXPECT_TRUE(state->transaction3->CommitPhaseTwo().ok()); |
| 582 EXPECT_TRUE(test->CheckBlobRemovals()); |
| 583 }, |
| 584 base::Unretained(this), base::Unretained(&state))); |
| 585 RunAllBlockingPoolTasksUntilIdle(); |
| 586 } |
| 587 |
| 588 TEST_F(IndexedDBBackingStoreTest, DeleteRange) { |
| 589 const std::vector<IndexedDBKey> keys = { |
| 590 IndexedDBKey(ASCIIToUTF16("key0")), IndexedDBKey(ASCIIToUTF16("key1")), |
| 591 IndexedDBKey(ASCIIToUTF16("key2")), IndexedDBKey(ASCIIToUTF16("key3"))}; |
| 592 const IndexedDBKeyRange ranges[] = { |
| 593 IndexedDBKeyRange(keys[1], keys[2], false, false), |
| 594 IndexedDBKeyRange(keys[1], keys[2], false, false), |
| 595 IndexedDBKeyRange(keys[0], keys[2], true, false), |
| 596 IndexedDBKeyRange(keys[1], keys[3], false, true), |
| 597 IndexedDBKeyRange(keys[0], keys[3], true, true)}; |
| 598 |
| 599 for (size_t i = 0; i < arraysize(ranges); ++i) { |
| 600 const int64_t database_id = 1; |
| 601 const int64_t object_store_id = i + 1; |
| 602 const IndexedDBKeyRange& range = ranges[i]; |
| 603 |
| 604 struct TestState { |
| 605 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction1; |
| 606 scoped_refptr<TestCallback> callback1; |
| 607 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction2; |
| 608 scoped_refptr<TestCallback> callback2; |
| 609 } state; |
| 610 |
| 611 idb_context_->TaskRunner()->PostTask( |
| 612 FROM_HERE, |
| 613 base::BindOnce( |
| 614 [](TestableIndexedDBBackingStore* backing_store, TestState* state, |
| 615 const std::vector<IndexedDBKey>& keys, int64_t database_id, |
| 616 int64_t object_store_id) { |
| 617 // Reset from previous iteration. |
| 618 backing_store->ClearWrites(); |
| 619 backing_store->ClearRemovals(); |
| 620 |
| 621 std::vector<IndexedDBValue> values = { |
| 622 IndexedDBValue( |
| 623 "value0", {IndexedDBBlobInfo( |
| 624 "uuid 0", base::UTF8ToUTF16("type 0"), 1)}), |
| 625 IndexedDBValue( |
| 626 "value1", {IndexedDBBlobInfo( |
| 627 "uuid 1", base::UTF8ToUTF16("type 1"), 1)}), |
| 628 IndexedDBValue( |
| 629 "value2", {IndexedDBBlobInfo( |
| 630 "uuid 2", base::UTF8ToUTF16("type 2"), 1)}), |
| 631 IndexedDBValue( |
| 632 "value3", |
| 633 {IndexedDBBlobInfo("uuid 3", base::UTF8ToUTF16("type 3"), |
| 634 1)})}; |
| 635 ASSERT_GE(keys.size(), values.size()); |
| 636 |
| 637 // Initiate transaction1 - write records. |
| 638 state->transaction1 = |
| 639 base::MakeUnique<IndexedDBBackingStore::Transaction>( |
| 640 backing_store); |
| 641 state->transaction1->Begin(); |
| 642 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; |
| 643 IndexedDBBackingStore::RecordIdentifier record; |
| 644 for (size_t i = 0; i < values.size(); ++i) { |
| 645 EXPECT_TRUE(backing_store |
| 646 ->PutRecord(state->transaction1.get(), |
| 647 database_id, object_store_id, |
| 648 keys[i], &values[i], &handles, |
| 649 &record) |
| 650 .ok()); |
| 651 } |
| 652 |
| 653 // Start committing transaction1. |
| 654 state->callback1 = base::MakeRefCounted<TestCallback>(); |
| 655 EXPECT_TRUE( |
| 656 state->transaction1->CommitPhaseOne(state->callback1).ok()); |
| 657 }, |
| 658 base::Unretained(backing_store()), base::Unretained(&state), |
| 659 base::ConstRef(keys), database_id, object_store_id)); |
| 660 RunAllBlockingPoolTasksUntilIdle(); |
| 661 |
| 662 idb_context_->TaskRunner()->PostTask( |
| 663 FROM_HERE, |
| 664 base::BindOnce( |
| 665 [](TestableIndexedDBBackingStore* backing_store, TestState* state, |
| 666 IndexedDBKeyRange range, int64_t database_id, |
| 667 int64_t object_store_id) { |
| 668 // Finish committing transaction1. |
| 669 EXPECT_TRUE(state->callback1->called); |
| 670 EXPECT_TRUE(state->callback1->succeeded); |
| 671 EXPECT_TRUE(state->transaction1->CommitPhaseTwo().ok()); |
| 672 |
| 673 // Initiate transaction 2 - delete range. |
| 674 state->transaction2 = |
| 675 base::MakeUnique<IndexedDBBackingStore::Transaction>( |
| 676 backing_store); |
| 677 state->transaction2->Begin(); |
| 678 IndexedDBValue result_value; |
| 679 EXPECT_TRUE(backing_store |
| 680 ->DeleteRange(state->transaction2.get(), |
| 681 database_id, object_store_id, range) |
| 682 .ok()); |
| 683 |
| 684 // Start committing transaction2. |
| 685 state->callback2 = base::MakeRefCounted<TestCallback>(); |
| 686 EXPECT_TRUE( |
| 687 state->transaction2->CommitPhaseOne(state->callback2).ok()); |
| 688 }, |
| 689 base::Unretained(backing_store()), base::Unretained(&state), range, |
| 690 database_id, object_store_id)); |
| 691 RunAllBlockingPoolTasksUntilIdle(); |
| 692 |
| 693 idb_context_->TaskRunner()->PostTask( |
| 694 FROM_HERE, |
| 695 base::BindOnce( |
| 696 [](TestableIndexedDBBackingStore* backing_store, TestState* state) { |
| 697 // Finish committing transaction2. |
| 698 EXPECT_TRUE(state->callback2->called); |
| 699 EXPECT_TRUE(state->callback2->succeeded); |
| 700 EXPECT_TRUE(state->transaction2->CommitPhaseTwo().ok()); |
| 701 |
| 702 // Verify blob removals. |
| 703 ASSERT_EQ(2UL, backing_store->removals().size()); |
| 704 EXPECT_EQ(backing_store->writes()[1].key(), |
| 705 backing_store->removals()[0]); |
| 706 EXPECT_EQ(backing_store->writes()[2].key(), |
| 707 backing_store->removals()[1]); |
| 708 }, |
| 709 base::Unretained(backing_store()), base::Unretained(&state))); |
| 710 RunAllBlockingPoolTasksUntilIdle(); |
| 412 } | 711 } |
| 413 | 712 } |
| 414 { | 713 |
| 415 IndexedDBBackingStore::Transaction transaction2(backing_store_.get()); | 714 TEST_F(IndexedDBBackingStoreTest, DeleteRangeEmptyRange) { |
| 416 transaction2.Begin(); | 715 const std::vector<IndexedDBKey> keys = { |
| 417 IndexedDBValue result_value; | 716 IndexedDBKey(ASCIIToUTF16("key0")), IndexedDBKey(ASCIIToUTF16("key1")), |
| 418 EXPECT_TRUE( | 717 IndexedDBKey(ASCIIToUTF16("key2")), IndexedDBKey(ASCIIToUTF16("key3")), |
| 419 backing_store_->GetRecord(&transaction2, 1, 1, key1_, &result_value) | 718 IndexedDBKey(ASCIIToUTF16("key4"))}; |
| 420 .ok()); | 719 const IndexedDBKeyRange ranges[] = { |
| 421 scoped_refptr<TestCallback> callback(new TestCallback()); | 720 IndexedDBKeyRange(keys[3], keys[4], true, false), |
| 422 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok()); | 721 IndexedDBKeyRange(keys[2], keys[1], false, false), |
| 423 EXPECT_TRUE(callback->called); | 722 IndexedDBKeyRange(keys[2], keys[1], true, true)}; |
| 424 EXPECT_TRUE(callback->succeeded); | 723 |
| 425 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok()); | 724 for (size_t i = 0; i < arraysize(ranges); ++i) { |
| 426 EXPECT_EQ(value1_.bits, result_value.bits); | 725 const int64_t database_id = 1; |
| 726 const int64_t object_store_id = i + 1; |
| 727 const IndexedDBKeyRange& range = ranges[i]; |
| 728 |
| 729 struct TestState { |
| 730 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction1; |
| 731 scoped_refptr<TestCallback> callback1; |
| 732 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction2; |
| 733 scoped_refptr<TestCallback> callback2; |
| 734 } state; |
| 735 |
| 736 idb_context_->TaskRunner()->PostTask( |
| 737 FROM_HERE, |
| 738 base::BindOnce( |
| 739 [](TestableIndexedDBBackingStore* backing_store, TestState* state, |
| 740 const std::vector<IndexedDBKey>& keys, int64_t database_id, |
| 741 int64_t object_store_id) { |
| 742 // Reset from previous iteration. |
| 743 backing_store->ClearWrites(); |
| 744 backing_store->ClearRemovals(); |
| 745 |
| 746 std::vector<IndexedDBValue> values = { |
| 747 IndexedDBValue( |
| 748 "value0", {IndexedDBBlobInfo( |
| 749 "uuid 0", base::UTF8ToUTF16("type 0"), 1)}), |
| 750 IndexedDBValue( |
| 751 "value1", {IndexedDBBlobInfo( |
| 752 "uuid 1", base::UTF8ToUTF16("type 1"), 1)}), |
| 753 IndexedDBValue( |
| 754 "value2", {IndexedDBBlobInfo( |
| 755 "uuid 2", base::UTF8ToUTF16("type 2"), 1)}), |
| 756 IndexedDBValue( |
| 757 "value3", |
| 758 {IndexedDBBlobInfo("uuid 3", base::UTF8ToUTF16("type 3"), |
| 759 1)})}; |
| 760 ASSERT_GE(keys.size(), values.size()); |
| 761 |
| 762 // Initiate transaction1 - write records. |
| 763 state->transaction1 = |
| 764 base::MakeUnique<IndexedDBBackingStore::Transaction>( |
| 765 backing_store); |
| 766 state->transaction1->Begin(); |
| 767 |
| 768 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; |
| 769 IndexedDBBackingStore::RecordIdentifier record; |
| 770 for (size_t i = 0; i < values.size(); ++i) { |
| 771 EXPECT_TRUE(backing_store |
| 772 ->PutRecord(state->transaction1.get(), |
| 773 database_id, object_store_id, |
| 774 keys[i], &values[i], &handles, |
| 775 &record) |
| 776 .ok()); |
| 777 } |
| 778 // Start committing transaction1. |
| 779 state->callback1 = base::MakeRefCounted<TestCallback>(); |
| 780 EXPECT_TRUE( |
| 781 state->transaction1->CommitPhaseOne(state->callback1).ok()); |
| 782 }, |
| 783 base::Unretained(backing_store()), base::Unretained(&state), |
| 784 base::ConstRef(keys), database_id, object_store_id)); |
| 785 RunAllBlockingPoolTasksUntilIdle(); |
| 786 |
| 787 idb_context_->TaskRunner()->PostTask( |
| 788 FROM_HERE, |
| 789 base::BindOnce( |
| 790 [](TestableIndexedDBBackingStore* backing_store, TestState* state, |
| 791 IndexedDBKeyRange range, int64_t database_id, |
| 792 int64_t object_store_id) { |
| 793 // Finish committing transaction1. |
| 794 EXPECT_TRUE(state->callback1->called); |
| 795 EXPECT_TRUE(state->callback1->succeeded); |
| 796 EXPECT_TRUE(state->transaction1->CommitPhaseTwo().ok()); |
| 797 |
| 798 // Initiate transaction 2 - delete range. |
| 799 state->transaction2 = |
| 800 base::MakeUnique<IndexedDBBackingStore::Transaction>( |
| 801 backing_store); |
| 802 state->transaction2->Begin(); |
| 803 IndexedDBValue result_value; |
| 804 EXPECT_TRUE(backing_store |
| 805 ->DeleteRange(state->transaction2.get(), |
| 806 database_id, object_store_id, range) |
| 807 .ok()); |
| 808 |
| 809 // Start committing transaction2. |
| 810 state->callback2 = base::MakeRefCounted<TestCallback>(); |
| 811 EXPECT_TRUE( |
| 812 state->transaction2->CommitPhaseOne(state->callback2).ok()); |
| 813 }, |
| 814 base::Unretained(backing_store()), base::Unretained(&state), range, |
| 815 database_id, object_store_id)); |
| 816 RunAllBlockingPoolTasksUntilIdle(); |
| 817 |
| 818 idb_context_->TaskRunner()->PostTask( |
| 819 FROM_HERE, |
| 820 base::BindOnce( |
| 821 [](TestableIndexedDBBackingStore* backing_store, TestState* state) { |
| 822 // Finish committing transaction2. |
| 823 EXPECT_TRUE(state->callback2->called); |
| 824 EXPECT_TRUE(state->callback2->succeeded); |
| 825 EXPECT_TRUE(state->transaction2->CommitPhaseTwo().ok()); |
| 826 |
| 827 // Verify blob removals. |
| 828 EXPECT_EQ(0UL, backing_store->removals().size()); |
| 829 }, |
| 830 base::Unretained(backing_store()), base::Unretained(&state))); |
| 831 RunAllBlockingPoolTasksUntilIdle(); |
| 427 } | 832 } |
| 428 } | 833 } |
| 429 | 834 |
| 430 TEST_F(IndexedDBBackingStoreTest, PutGetConsistencyWithBlobs) { | 835 TEST_F(IndexedDBBackingStoreTestWithBlobs, BlobJournalInterleavedTransactions) { |
| 431 { | 836 struct TestState { |
| 432 IndexedDBBackingStore::Transaction transaction1(backing_store_.get()); | 837 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction1; |
| 433 transaction1.Begin(); | 838 scoped_refptr<TestCallback> callback1; |
| 434 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; | 839 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction2; |
| 435 IndexedDBBackingStore::RecordIdentifier record; | 840 scoped_refptr<TestCallback> callback2; |
| 436 EXPECT_TRUE( | 841 } state; |
| 437 backing_store_ | 842 |
| 438 ->PutRecord(&transaction1, 1, 1, key3_, &value3_, &handles, &record) | 843 idb_context_->TaskRunner()->PostTask( |
| 439 .ok()); | 844 FROM_HERE, |
| 440 scoped_refptr<TestCallback> callback(new TestCallback()); | 845 base::BindOnce( |
| 441 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok()); | 846 [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) { |
| 442 task_runner_->RunUntilIdle(); | 847 // Initiate transaction1. |
| 443 EXPECT_TRUE(CheckBlobWrites()); | 848 state->transaction1 = |
| 444 EXPECT_TRUE(callback->called); | 849 base::MakeUnique<IndexedDBBackingStore::Transaction>( |
| 445 EXPECT_TRUE(callback->succeeded); | 850 test->backing_store()); |
| 446 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok()); | 851 state->transaction1->Begin(); |
| 447 } | 852 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles1; |
| 448 | 853 IndexedDBBackingStore::RecordIdentifier record1; |
| 449 { | 854 EXPECT_TRUE(test->backing_store() |
| 450 IndexedDBBackingStore::Transaction transaction2(backing_store_.get()); | 855 ->PutRecord(state->transaction1.get(), 1, 1, |
| 451 transaction2.Begin(); | 856 test->key3_, &test->value3_, &handles1, |
| 452 IndexedDBValue result_value; | 857 &record1) |
| 453 EXPECT_TRUE( | 858 .ok()); |
| 454 backing_store_->GetRecord(&transaction2, 1, 1, key3_, &result_value) | 859 state->callback1 = base::MakeRefCounted<TestCallback>(); |
| 455 .ok()); | 860 EXPECT_TRUE( |
| 456 scoped_refptr<TestCallback> callback(new TestCallback()); | 861 state->transaction1->CommitPhaseOne(state->callback1).ok()); |
| 457 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok()); | 862 }, |
| 458 EXPECT_TRUE(callback->called); | 863 base::Unretained(this), base::Unretained(&state))); |
| 459 EXPECT_TRUE(callback->succeeded); | 864 RunAllBlockingPoolTasksUntilIdle(); |
| 460 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok()); | 865 |
| 461 EXPECT_EQ(value3_.bits, result_value.bits); | 866 idb_context_->TaskRunner()->PostTask( |
| 462 EXPECT_TRUE(CheckBlobInfoMatches(result_value.blob_info)); | 867 FROM_HERE, |
| 463 EXPECT_TRUE(CheckBlobReadsMatchWrites(result_value.blob_info)); | 868 base::BindOnce( |
| 464 } | 869 [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) { |
| 465 | 870 // Verify transaction1 phase one completed. |
| 466 { | 871 EXPECT_TRUE(state->callback1->called); |
| 467 IndexedDBBackingStore::Transaction transaction3(backing_store_.get()); | 872 EXPECT_TRUE(state->callback1->succeeded); |
| 468 transaction3.Begin(); | 873 EXPECT_TRUE(test->CheckBlobWrites()); |
| 469 IndexedDBValue result_value; | 874 EXPECT_EQ(0U, test->backing_store()->removals().size()); |
| 470 EXPECT_TRUE(backing_store_ | 875 |
| 471 ->DeleteRange(&transaction3, 1, 1, IndexedDBKeyRange(key3_)) | 876 // Initiate transaction2. |
| 472 .ok()); | 877 state->transaction2 = |
| 473 scoped_refptr<TestCallback> callback(new TestCallback()); | 878 base::MakeUnique<IndexedDBBackingStore::Transaction>( |
| 474 EXPECT_TRUE(transaction3.CommitPhaseOne(callback).ok()); | 879 test->backing_store()); |
| 475 task_runner_->RunUntilIdle(); | 880 state->transaction2->Begin(); |
| 476 EXPECT_TRUE(callback->called); | 881 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles2; |
| 477 EXPECT_TRUE(callback->succeeded); | 882 IndexedDBBackingStore::RecordIdentifier record2; |
| 478 EXPECT_TRUE(transaction3.CommitPhaseTwo().ok()); | 883 EXPECT_TRUE(test->backing_store() |
| 479 EXPECT_TRUE(CheckBlobRemovals()); | 884 ->PutRecord(state->transaction2.get(), 1, 1, |
| 480 } | 885 test->key1_, &test->value1_, &handles2, |
| 481 } | 886 &record2) |
| 482 | 887 .ok()); |
| 483 TEST_F(IndexedDBBackingStoreTest, DeleteRange) { | 888 state->callback2 = base::MakeRefCounted<TestCallback>(); |
| 484 IndexedDBKey key0 = IndexedDBKey(ASCIIToUTF16("key0")); | 889 EXPECT_TRUE( |
| 485 IndexedDBKey key1 = IndexedDBKey(ASCIIToUTF16("key1")); | 890 state->transaction2->CommitPhaseOne(state->callback2).ok()); |
| 486 IndexedDBKey key2 = IndexedDBKey(ASCIIToUTF16("key2")); | 891 }, |
| 487 IndexedDBKey key3 = IndexedDBKey(ASCIIToUTF16("key3")); | 892 base::Unretained(this), base::Unretained(&state))); |
| 488 IndexedDBBlobInfo blob0("uuid 0", base::UTF8ToUTF16("type 0"), 1); | 893 RunAllBlockingPoolTasksUntilIdle(); |
| 489 IndexedDBBlobInfo blob1("uuid 1", base::UTF8ToUTF16("type 1"), 1); | 894 |
| 490 IndexedDBBlobInfo blob2("uuid 2", base::UTF8ToUTF16("type 2"), 1); | 895 idb_context_->TaskRunner()->PostTask( |
| 491 IndexedDBBlobInfo blob3("uuid 3", base::UTF8ToUTF16("type 3"), 1); | 896 FROM_HERE, |
| 492 IndexedDBKeyRange ranges[] = {IndexedDBKeyRange(key1, key2, false, false), | 897 base::BindOnce( |
| 493 IndexedDBKeyRange(key1, key2, false, false), | 898 [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) { |
| 494 IndexedDBKeyRange(key0, key2, true, false), | 899 // Verify transaction2 phase one completed. |
| 495 IndexedDBKeyRange(key1, key3, false, true), | 900 EXPECT_TRUE(state->callback2->called); |
| 496 IndexedDBKeyRange(key0, key3, true, true)}; | 901 EXPECT_TRUE(state->callback2->succeeded); |
| 497 | 902 EXPECT_TRUE(test->CheckBlobWrites()); |
| 498 for (unsigned i = 0; i < sizeof(ranges) / sizeof(IndexedDBKeyRange); ++i) { | 903 EXPECT_EQ(0U, test->backing_store()->removals().size()); |
| 499 backing_store_->ClearWrites(); | 904 |
| 500 backing_store_->ClearRemovals(); | 905 // Finalize both transactions. |
| 501 | 906 EXPECT_TRUE(state->transaction1->CommitPhaseTwo().ok()); |
| 502 { | 907 EXPECT_EQ(0U, test->backing_store()->removals().size()); |
| 503 std::vector<IndexedDBBlobInfo> blob_info0, blob_info1, blob_info2, | 908 |
| 504 blob_info3; | 909 EXPECT_TRUE(state->transaction2->CommitPhaseTwo().ok()); |
| 505 blob_info0.push_back(blob0); | 910 EXPECT_EQ(0U, test->backing_store()->removals().size()); |
| 506 blob_info1.push_back(blob1); | 911 }, |
| 507 blob_info2.push_back(blob2); | 912 base::Unretained(this), base::Unretained(&state))); |
| 508 blob_info3.push_back(blob3); | 913 RunAllBlockingPoolTasksUntilIdle(); |
| 509 IndexedDBValue value0 = IndexedDBValue("value0", blob_info0); | 914 } |
| 510 IndexedDBValue value1 = IndexedDBValue("value1", blob_info1); | 915 |
| 511 IndexedDBValue value2 = IndexedDBValue("value2", blob_info2); | 916 TEST_F(IndexedDBBackingStoreTestWithBlobs, LiveBlobJournal) { |
| 512 IndexedDBValue value3 = IndexedDBValue("value3", blob_info3); | 917 struct TestState { |
| 513 IndexedDBBackingStore::Transaction transaction1(backing_store_.get()); | 918 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction1; |
| 514 transaction1.Begin(); | 919 scoped_refptr<TestCallback> callback1; |
| 515 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; | 920 std::unique_ptr<IndexedDBBackingStore::Transaction> transaction3; |
| 516 IndexedDBBackingStore::RecordIdentifier record; | 921 scoped_refptr<TestCallback> callback3; |
| 517 EXPECT_TRUE(backing_store_->PutRecord(&transaction1, | 922 IndexedDBValue read_result_value; |
| 518 1, | 923 } state; |
| 519 i + 1, | 924 |
| 520 key0, | 925 idb_context_->TaskRunner()->PostTask( |
| 521 &value0, | 926 FROM_HERE, |
| 522 &handles, | 927 base::BindOnce( |
| 523 &record).ok()); | 928 [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) { |
| 524 EXPECT_TRUE(backing_store_->PutRecord(&transaction1, | 929 state->transaction1 = |
| 525 1, | 930 base::MakeUnique<IndexedDBBackingStore::Transaction>( |
| 526 i + 1, | 931 test->backing_store()); |
| 527 key1, | 932 state->transaction1->Begin(); |
| 528 &value1, | 933 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; |
| 529 &handles, | 934 IndexedDBBackingStore::RecordIdentifier record; |
| 530 &record).ok()); | 935 EXPECT_TRUE(test->backing_store() |
| 531 EXPECT_TRUE(backing_store_->PutRecord(&transaction1, | 936 ->PutRecord(state->transaction1.get(), 1, 1, |
| 532 1, | 937 test->key3_, &test->value3_, &handles, |
| 533 i + 1, | 938 &record) |
| 534 key2, | 939 .ok()); |
| 535 &value2, | 940 state->callback1 = base::MakeRefCounted<TestCallback>(); |
| 536 &handles, | 941 EXPECT_TRUE( |
| 537 &record).ok()); | 942 state->transaction1->CommitPhaseOne(state->callback1).ok()); |
| 538 EXPECT_TRUE(backing_store_->PutRecord(&transaction1, | 943 }, |
| 539 1, | 944 base::Unretained(this), base::Unretained(&state))); |
| 540 i + 1, | 945 RunAllBlockingPoolTasksUntilIdle(); |
| 541 key3, | 946 |
| 542 &value3, | 947 idb_context_->TaskRunner()->PostTask( |
| 543 &handles, | 948 FROM_HERE, |
| 544 &record).ok()); | 949 base::BindOnce( |
| 545 scoped_refptr<TestCallback> callback(new TestCallback()); | 950 [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) { |
| 546 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok()); | 951 EXPECT_TRUE(state->callback1->called); |
| 547 task_runner_->RunUntilIdle(); | 952 EXPECT_TRUE(state->callback1->succeeded); |
| 548 EXPECT_TRUE(callback->called); | 953 EXPECT_TRUE(test->CheckBlobWrites()); |
| 549 EXPECT_TRUE(callback->succeeded); | 954 EXPECT_TRUE(state->transaction1->CommitPhaseTwo().ok()); |
| 550 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok()); | 955 |
| 551 } | 956 IndexedDBBackingStore::Transaction transaction2( |
| 552 | 957 test->backing_store()); |
| 553 { | 958 transaction2.Begin(); |
| 554 IndexedDBBackingStore::Transaction transaction2(backing_store_.get()); | 959 EXPECT_TRUE(test->backing_store() |
| 555 transaction2.Begin(); | 960 ->GetRecord(&transaction2, 1, 1, test->key3_, |
| 556 IndexedDBValue result_value; | 961 &state->read_result_value) |
| 557 EXPECT_TRUE( | 962 .ok()); |
| 558 backing_store_->DeleteRange(&transaction2, 1, i + 1, ranges[i]).ok()); | 963 scoped_refptr<TestCallback> callback( |
| 559 scoped_refptr<TestCallback> callback(new TestCallback()); | 964 base::MakeRefCounted<TestCallback>()); |
| 560 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok()); | 965 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok()); |
| 561 task_runner_->RunUntilIdle(); | 966 EXPECT_TRUE(callback->called); |
| 562 EXPECT_TRUE(callback->called); | 967 EXPECT_TRUE(callback->succeeded); |
| 563 EXPECT_TRUE(callback->succeeded); | 968 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok()); |
| 564 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok()); | 969 EXPECT_EQ(test->value3_.bits, state->read_result_value.bits); |
| 565 ASSERT_EQ(2UL, backing_store_->removals().size()); | 970 EXPECT_TRUE( |
| 566 EXPECT_EQ(backing_store_->writes()[1].key(), | 971 test->CheckBlobInfoMatches(state->read_result_value.blob_info)); |
| 567 backing_store_->removals()[0]); | 972 EXPECT_TRUE(test->CheckBlobReadsMatchWrites( |
| 568 EXPECT_EQ(backing_store_->writes()[2].key(), | 973 state->read_result_value.blob_info)); |
| 569 backing_store_->removals()[1]); | 974 for (size_t i = 0; i < state->read_result_value.blob_info.size(); |
| 570 } | 975 ++i) { |
| 571 } | 976 state->read_result_value.blob_info[i].mark_used_callback().Run(); |
| 572 } | 977 } |
| 573 | 978 |
| 574 TEST_F(IndexedDBBackingStoreTest, DeleteRangeEmptyRange) { | 979 state->transaction3 = |
| 575 IndexedDBKey key0 = IndexedDBKey(ASCIIToUTF16("key0")); | 980 base::MakeUnique<IndexedDBBackingStore::Transaction>( |
| 576 IndexedDBKey key1 = IndexedDBKey(ASCIIToUTF16("key1")); | 981 test->backing_store()); |
| 577 IndexedDBKey key2 = IndexedDBKey(ASCIIToUTF16("key2")); | 982 state->transaction3->Begin(); |
| 578 IndexedDBKey key3 = IndexedDBKey(ASCIIToUTF16("key3")); | 983 EXPECT_TRUE(test->backing_store() |
| 579 IndexedDBKey key4 = IndexedDBKey(ASCIIToUTF16("key4")); | 984 ->DeleteRange(state->transaction3.get(), 1, 1, |
| 580 IndexedDBBlobInfo blob0("uuid 0", base::UTF8ToUTF16("type 0"), 1); | 985 IndexedDBKeyRange(test->key3_)) |
| 581 IndexedDBBlobInfo blob1("uuid 1", base::UTF8ToUTF16("type 1"), 1); | 986 .ok()); |
| 582 IndexedDBBlobInfo blob2("uuid 2", base::UTF8ToUTF16("type 2"), 1); | 987 state->callback3 = base::MakeRefCounted<TestCallback>(); |
| 583 IndexedDBBlobInfo blob3("uuid 3", base::UTF8ToUTF16("type 3"), 1); | 988 EXPECT_TRUE( |
| 584 IndexedDBKeyRange ranges[] = {IndexedDBKeyRange(key3, key4, true, false), | 989 state->transaction3->CommitPhaseOne(state->callback3).ok()); |
| 585 IndexedDBKeyRange(key2, key1, false, false), | 990 }, |
| 586 IndexedDBKeyRange(key2, key1, true, true)}; | 991 base::Unretained(this), base::Unretained(&state))); |
| 587 | 992 RunAllBlockingPoolTasksUntilIdle(); |
| 588 for (unsigned i = 0; i < arraysize(ranges); ++i) { | 993 |
| 589 backing_store_->ClearWrites(); | 994 idb_context_->TaskRunner()->PostTask( |
| 590 backing_store_->ClearRemovals(); | 995 FROM_HERE, |
| 591 | 996 base::BindOnce( |
| 592 { | 997 [](IndexedDBBackingStoreTestWithBlobs* test, TestState* state) { |
| 593 std::vector<IndexedDBBlobInfo> blob_info0, blob_info1, blob_info2, | 998 EXPECT_TRUE(state->callback3->called); |
| 594 blob_info3; | 999 EXPECT_TRUE(state->callback3->succeeded); |
| 595 blob_info0.push_back(blob0); | 1000 EXPECT_TRUE(state->transaction3->CommitPhaseTwo().ok()); |
| 596 blob_info1.push_back(blob1); | 1001 EXPECT_EQ(0U, test->backing_store()->removals().size()); |
| 597 blob_info2.push_back(blob2); | 1002 for (size_t i = 0; i < state->read_result_value.blob_info.size(); |
| 598 blob_info3.push_back(blob3); | 1003 ++i) { |
| 599 IndexedDBValue value0 = IndexedDBValue("value0", blob_info0); | 1004 state->read_result_value.blob_info[i].release_callback().Run( |
| 600 IndexedDBValue value1 = IndexedDBValue("value1", blob_info1); | 1005 state->read_result_value.blob_info[i].file_path()); |
| 601 IndexedDBValue value2 = IndexedDBValue("value2", blob_info2); | 1006 } |
| 602 IndexedDBValue value3 = IndexedDBValue("value3", blob_info3); | 1007 }, |
| 603 IndexedDBBackingStore::Transaction transaction1(backing_store_.get()); | 1008 base::Unretained(this), base::Unretained(&state))); |
| 604 transaction1.Begin(); | 1009 RunAllBlockingPoolTasksUntilIdle(); |
| 605 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; | 1010 |
| 606 IndexedDBBackingStore::RecordIdentifier record; | 1011 idb_context_->TaskRunner()->PostTask( |
| 607 EXPECT_TRUE(backing_store_->PutRecord(&transaction1, | 1012 FROM_HERE, base::BindOnce( |
| 608 1, | 1013 [](IndexedDBBackingStoreTestWithBlobs* test) { |
| 609 i + 1, | 1014 EXPECT_NE(0U, test->backing_store()->removals().size()); |
| 610 key0, | 1015 EXPECT_TRUE(test->CheckBlobRemovals()); |
| 611 &value0, | 1016 }, |
| 612 &handles, | 1017 base::Unretained(this))); |
| 613 &record).ok()); | 1018 RunAllBlockingPoolTasksUntilIdle(); |
| 614 EXPECT_TRUE(backing_store_->PutRecord(&transaction1, | |
| 615 1, | |
| 616 i + 1, | |
| 617 key1, | |
| 618 &value1, | |
| 619 &handles, | |
| 620 &record).ok()); | |
| 621 EXPECT_TRUE(backing_store_->PutRecord(&transaction1, | |
| 622 1, | |
| 623 i + 1, | |
| 624 key2, | |
| 625 &value2, | |
| 626 &handles, | |
| 627 &record).ok()); | |
| 628 EXPECT_TRUE(backing_store_->PutRecord(&transaction1, | |
| 629 1, | |
| 630 i + 1, | |
| 631 key3, | |
| 632 &value3, | |
| 633 &handles, | |
| 634 &record).ok()); | |
| 635 scoped_refptr<TestCallback> callback(new TestCallback()); | |
| 636 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok()); | |
| 637 task_runner_->RunUntilIdle(); | |
| 638 EXPECT_TRUE(callback->called); | |
| 639 EXPECT_TRUE(callback->succeeded); | |
| 640 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok()); | |
| 641 } | |
| 642 | |
| 643 { | |
| 644 IndexedDBBackingStore::Transaction transaction2(backing_store_.get()); | |
| 645 transaction2.Begin(); | |
| 646 IndexedDBValue result_value; | |
| 647 EXPECT_TRUE( | |
| 648 backing_store_->DeleteRange(&transaction2, 1, i + 1, ranges[i]).ok()); | |
| 649 scoped_refptr<TestCallback> callback(new TestCallback()); | |
| 650 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok()); | |
| 651 task_runner_->RunUntilIdle(); | |
| 652 EXPECT_TRUE(callback->called); | |
| 653 EXPECT_TRUE(callback->succeeded); | |
| 654 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok()); | |
| 655 EXPECT_EQ(0UL, backing_store_->removals().size()); | |
| 656 } | |
| 657 } | |
| 658 } | |
| 659 | |
| 660 TEST_F(IndexedDBBackingStoreTest, BlobJournalInterleavedTransactions) { | |
| 661 IndexedDBBackingStore::Transaction transaction1(backing_store_.get()); | |
| 662 transaction1.Begin(); | |
| 663 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles1; | |
| 664 IndexedDBBackingStore::RecordIdentifier record1; | |
| 665 EXPECT_TRUE( | |
| 666 backing_store_ | |
| 667 ->PutRecord(&transaction1, 1, 1, key3_, &value3_, &handles1, &record1) | |
| 668 .ok()); | |
| 669 scoped_refptr<TestCallback> callback1(new TestCallback()); | |
| 670 EXPECT_TRUE(transaction1.CommitPhaseOne(callback1).ok()); | |
| 671 task_runner_->RunUntilIdle(); | |
| 672 EXPECT_TRUE(CheckBlobWrites()); | |
| 673 EXPECT_TRUE(callback1->called); | |
| 674 EXPECT_TRUE(callback1->succeeded); | |
| 675 EXPECT_EQ(0U, backing_store_->removals().size()); | |
| 676 | |
| 677 IndexedDBBackingStore::Transaction transaction2(backing_store_.get()); | |
| 678 transaction2.Begin(); | |
| 679 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles2; | |
| 680 IndexedDBBackingStore::RecordIdentifier record2; | |
| 681 EXPECT_TRUE( | |
| 682 backing_store_ | |
| 683 ->PutRecord(&transaction2, 1, 1, key1_, &value1_, &handles2, &record2) | |
| 684 .ok()); | |
| 685 scoped_refptr<TestCallback> callback2(new TestCallback()); | |
| 686 EXPECT_TRUE(transaction2.CommitPhaseOne(callback2).ok()); | |
| 687 task_runner_->RunUntilIdle(); | |
| 688 EXPECT_TRUE(CheckBlobWrites()); | |
| 689 EXPECT_TRUE(callback2->called); | |
| 690 EXPECT_TRUE(callback2->succeeded); | |
| 691 EXPECT_EQ(0U, backing_store_->removals().size()); | |
| 692 | |
| 693 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok()); | |
| 694 EXPECT_EQ(0U, backing_store_->removals().size()); | |
| 695 | |
| 696 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok()); | |
| 697 EXPECT_EQ(0U, backing_store_->removals().size()); | |
| 698 } | |
| 699 | |
| 700 TEST_F(IndexedDBBackingStoreTest, LiveBlobJournal) { | |
| 701 { | |
| 702 IndexedDBBackingStore::Transaction transaction1(backing_store_.get()); | |
| 703 transaction1.Begin(); | |
| 704 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; | |
| 705 IndexedDBBackingStore::RecordIdentifier record; | |
| 706 EXPECT_TRUE( | |
| 707 backing_store_ | |
| 708 ->PutRecord(&transaction1, 1, 1, key3_, &value3_, &handles, &record) | |
| 709 .ok()); | |
| 710 scoped_refptr<TestCallback> callback(new TestCallback()); | |
| 711 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok()); | |
| 712 task_runner_->RunUntilIdle(); | |
| 713 EXPECT_TRUE(CheckBlobWrites()); | |
| 714 EXPECT_TRUE(callback->called); | |
| 715 EXPECT_TRUE(callback->succeeded); | |
| 716 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok()); | |
| 717 } | |
| 718 | |
| 719 IndexedDBValue read_result_value; | |
| 720 { | |
| 721 IndexedDBBackingStore::Transaction transaction2(backing_store_.get()); | |
| 722 transaction2.Begin(); | |
| 723 EXPECT_TRUE(backing_store_ | |
| 724 ->GetRecord(&transaction2, 1, 1, key3_, &read_result_value) | |
| 725 .ok()); | |
| 726 scoped_refptr<TestCallback> callback(new TestCallback()); | |
| 727 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok()); | |
| 728 EXPECT_TRUE(callback->called); | |
| 729 EXPECT_TRUE(callback->succeeded); | |
| 730 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok()); | |
| 731 EXPECT_EQ(value3_.bits, read_result_value.bits); | |
| 732 EXPECT_TRUE(CheckBlobInfoMatches(read_result_value.blob_info)); | |
| 733 EXPECT_TRUE(CheckBlobReadsMatchWrites(read_result_value.blob_info)); | |
| 734 for (size_t i = 0; i < read_result_value.blob_info.size(); ++i) { | |
| 735 read_result_value.blob_info[i].mark_used_callback().Run(); | |
| 736 } | |
| 737 } | |
| 738 | |
| 739 { | |
| 740 IndexedDBBackingStore::Transaction transaction3(backing_store_.get()); | |
| 741 transaction3.Begin(); | |
| 742 EXPECT_TRUE(backing_store_ | |
| 743 ->DeleteRange(&transaction3, 1, 1, IndexedDBKeyRange(key3_)) | |
| 744 .ok()); | |
| 745 scoped_refptr<TestCallback> callback(new TestCallback()); | |
| 746 EXPECT_TRUE(transaction3.CommitPhaseOne(callback).ok()); | |
| 747 task_runner_->RunUntilIdle(); | |
| 748 EXPECT_TRUE(callback->called); | |
| 749 EXPECT_TRUE(callback->succeeded); | |
| 750 EXPECT_TRUE(transaction3.CommitPhaseTwo().ok()); | |
| 751 EXPECT_EQ(0U, backing_store_->removals().size()); | |
| 752 for (size_t i = 0; i < read_result_value.blob_info.size(); ++i) { | |
| 753 read_result_value.blob_info[i].release_callback().Run( | |
| 754 read_result_value.blob_info[i].file_path()); | |
| 755 } | |
| 756 task_runner_->RunUntilIdle(); | |
| 757 EXPECT_NE(0U, backing_store_->removals().size()); | |
| 758 EXPECT_TRUE(CheckBlobRemovals()); | |
| 759 } | |
| 760 } | 1019 } |
| 761 | 1020 |
| 762 // Make sure that using very high ( more than 32 bit ) values for database_id | 1021 // Make sure that using very high ( more than 32 bit ) values for database_id |
| 763 // and object_store_id still work. | 1022 // and object_store_id still work. |
| 764 TEST_F(IndexedDBBackingStoreTest, HighIds) { | 1023 TEST_F(IndexedDBBackingStoreTest, HighIds) { |
| 765 const int64_t high_database_id = 1ULL << 35; | 1024 idb_context_->TaskRunner()->PostTask( |
| 766 const int64_t high_object_store_id = 1ULL << 39; | 1025 FROM_HERE, |
| 767 // index_ids are capped at 32 bits for storage purposes. | 1026 base::BindOnce( |
| 768 const int64_t high_index_id = 1ULL << 29; | 1027 [](IndexedDBBackingStore* backing_store, IndexedDBKey key1, |
| 769 | 1028 IndexedDBKey key2, IndexedDBValue value1) { |
| 770 const int64_t invalid_high_index_id = 1ULL << 37; | 1029 const int64_t high_database_id = 1ULL << 35; |
| 771 | 1030 const int64_t high_object_store_id = 1ULL << 39; |
| 772 const IndexedDBKey& index_key = key2_; | 1031 // index_ids are capped at 32 bits for storage purposes. |
| 773 std::string index_key_raw; | 1032 const int64_t high_index_id = 1ULL << 29; |
| 774 EncodeIDBKey(index_key, &index_key_raw); | 1033 |
| 775 { | 1034 const int64_t invalid_high_index_id = 1ULL << 37; |
| 776 IndexedDBBackingStore::Transaction transaction1(backing_store_.get()); | 1035 |
| 777 transaction1.Begin(); | 1036 const IndexedDBKey& index_key = key2; |
| 778 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; | 1037 std::string index_key_raw; |
| 779 IndexedDBBackingStore::RecordIdentifier record; | 1038 EncodeIDBKey(index_key, &index_key_raw); |
| 780 leveldb::Status s = backing_store_->PutRecord( | 1039 { |
| 781 &transaction1, high_database_id, high_object_store_id, key1_, &value1_, | 1040 IndexedDBBackingStore::Transaction transaction1(backing_store); |
| 782 &handles, &record); | 1041 transaction1.Begin(); |
| 783 EXPECT_TRUE(s.ok()); | 1042 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; |
| 784 | 1043 IndexedDBBackingStore::RecordIdentifier record; |
| 785 s = backing_store_->PutIndexDataForRecord(&transaction1, | 1044 leveldb::Status s = backing_store->PutRecord( |
| 786 high_database_id, | 1045 &transaction1, high_database_id, high_object_store_id, key1, |
| 787 high_object_store_id, | 1046 &value1, &handles, &record); |
| 788 invalid_high_index_id, | 1047 EXPECT_TRUE(s.ok()); |
| 789 index_key, | 1048 |
| 790 record); | 1049 s = backing_store->PutIndexDataForRecord( |
| 791 EXPECT_FALSE(s.ok()); | 1050 &transaction1, high_database_id, high_object_store_id, |
| 792 | 1051 invalid_high_index_id, index_key, record); |
| 793 s = backing_store_->PutIndexDataForRecord(&transaction1, | 1052 EXPECT_FALSE(s.ok()); |
| 794 high_database_id, | 1053 |
| 795 high_object_store_id, | 1054 s = backing_store->PutIndexDataForRecord( |
| 796 high_index_id, | 1055 &transaction1, high_database_id, high_object_store_id, |
| 797 index_key, | 1056 high_index_id, index_key, record); |
| 798 record); | 1057 EXPECT_TRUE(s.ok()); |
| 799 EXPECT_TRUE(s.ok()); | 1058 |
| 800 | 1059 scoped_refptr<TestCallback> callback( |
| 801 scoped_refptr<TestCallback> callback(new TestCallback()); | 1060 base::MakeRefCounted<TestCallback>()); |
| 802 s = transaction1.CommitPhaseOne(callback); | 1061 EXPECT_TRUE(transaction1.CommitPhaseOne(callback).ok()); |
| 803 EXPECT_TRUE(s.ok()); | 1062 EXPECT_TRUE(callback->called); |
| 804 EXPECT_TRUE(callback->called); | 1063 EXPECT_TRUE(callback->succeeded); |
| 805 EXPECT_TRUE(callback->succeeded); | 1064 EXPECT_TRUE(transaction1.CommitPhaseTwo().ok()); |
| 806 s = transaction1.CommitPhaseTwo(); | 1065 } |
| 807 EXPECT_TRUE(s.ok()); | 1066 |
| 808 } | 1067 { |
| 809 | 1068 IndexedDBBackingStore::Transaction transaction2(backing_store); |
| 810 { | 1069 transaction2.Begin(); |
| 811 IndexedDBBackingStore::Transaction transaction2(backing_store_.get()); | 1070 IndexedDBValue result_value; |
| 812 transaction2.Begin(); | 1071 leveldb::Status s = backing_store->GetRecord( |
| 813 IndexedDBValue result_value; | 1072 &transaction2, high_database_id, high_object_store_id, key1, |
| 814 leveldb::Status s = | 1073 &result_value); |
| 815 backing_store_->GetRecord(&transaction2, high_database_id, | 1074 EXPECT_TRUE(s.ok()); |
| 816 high_object_store_id, key1_, &result_value); | 1075 EXPECT_EQ(value1.bits, result_value.bits); |
| 817 EXPECT_TRUE(s.ok()); | 1076 |
| 818 EXPECT_EQ(value1_.bits, result_value.bits); | 1077 std::unique_ptr<IndexedDBKey> new_primary_key; |
| 819 | 1078 s = backing_store->GetPrimaryKeyViaIndex( |
| 820 std::unique_ptr<IndexedDBKey> new_primary_key; | 1079 &transaction2, high_database_id, high_object_store_id, |
| 821 s = backing_store_->GetPrimaryKeyViaIndex(&transaction2, | 1080 invalid_high_index_id, index_key, &new_primary_key); |
| 822 high_database_id, | 1081 EXPECT_FALSE(s.ok()); |
| 823 high_object_store_id, | 1082 |
| 824 invalid_high_index_id, | 1083 s = backing_store->GetPrimaryKeyViaIndex( |
| 825 index_key, | 1084 &transaction2, high_database_id, high_object_store_id, |
| 826 &new_primary_key); | 1085 high_index_id, index_key, &new_primary_key); |
| 827 EXPECT_FALSE(s.ok()); | 1086 EXPECT_TRUE(s.ok()); |
| 828 | 1087 EXPECT_TRUE(new_primary_key->Equals(key1)); |
| 829 s = backing_store_->GetPrimaryKeyViaIndex(&transaction2, | 1088 |
| 830 high_database_id, | 1089 scoped_refptr<TestCallback> callback( |
| 831 high_object_store_id, | 1090 base::MakeRefCounted<TestCallback>()); |
| 832 high_index_id, | 1091 EXPECT_TRUE(transaction2.CommitPhaseOne(callback).ok()); |
| 833 index_key, | 1092 EXPECT_TRUE(callback->called); |
| 834 &new_primary_key); | 1093 EXPECT_TRUE(callback->succeeded); |
| 835 EXPECT_TRUE(s.ok()); | 1094 EXPECT_TRUE(transaction2.CommitPhaseTwo().ok()); |
| 836 EXPECT_TRUE(new_primary_key->Equals(key1_)); | 1095 } |
| 837 | 1096 }, |
| 838 scoped_refptr<TestCallback> callback(new TestCallback()); | 1097 base::Unretained(backing_store()), key1_, key2_, value1_)); |
| 839 s = transaction2.CommitPhaseOne(callback); | 1098 RunAllBlockingPoolTasksUntilIdle(); |
| 840 EXPECT_TRUE(s.ok()); | |
| 841 EXPECT_TRUE(callback->called); | |
| 842 EXPECT_TRUE(callback->succeeded); | |
| 843 s = transaction2.CommitPhaseTwo(); | |
| 844 EXPECT_TRUE(s.ok()); | |
| 845 } | |
| 846 } | 1099 } |
| 847 | 1100 |
| 848 // Make sure that other invalid ids do not crash. | 1101 // Make sure that other invalid ids do not crash. |
| 849 TEST_F(IndexedDBBackingStoreTest, InvalidIds) { | 1102 TEST_F(IndexedDBBackingStoreTest, InvalidIds) { |
| 850 // valid ids for use when testing invalid ids | 1103 idb_context_->TaskRunner()->PostTask( |
| 851 const int64_t database_id = 1; | 1104 FROM_HERE, |
| 852 const int64_t object_store_id = 1; | 1105 base::BindOnce( |
| 853 const int64_t index_id = kMinimumIndexId; | 1106 [](IndexedDBBackingStore* backing_store, IndexedDBKey key, |
| 854 const int64_t invalid_low_index_id = | 1107 IndexedDBValue value) { |
| 855 19; // index_ids must be > kMinimumIndexId | 1108 // valid ids for use when testing invalid ids |
| 856 | 1109 const int64_t database_id = 1; |
| 857 IndexedDBValue result_value; | 1110 const int64_t object_store_id = 1; |
| 858 | 1111 const int64_t index_id = kMinimumIndexId; |
| 859 IndexedDBBackingStore::Transaction transaction1(backing_store_.get()); | 1112 // index_ids must be > kMinimumIndexId |
| 860 transaction1.Begin(); | 1113 const int64_t invalid_low_index_id = 19; |
| 861 | 1114 IndexedDBValue result_value; |
| 862 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; | 1115 |
| 863 IndexedDBBackingStore::RecordIdentifier record; | 1116 IndexedDBBackingStore::Transaction transaction1(backing_store); |
| 864 leveldb::Status s = backing_store_->PutRecord(&transaction1, database_id, | 1117 transaction1.Begin(); |
| 865 KeyPrefix::kInvalidId, key1_, | 1118 |
| 866 &value1_, &handles, &record); | 1119 std::vector<std::unique_ptr<storage::BlobDataHandle>> handles; |
| 867 EXPECT_FALSE(s.ok()); | 1120 IndexedDBBackingStore::RecordIdentifier record; |
| 868 s = backing_store_->PutRecord(&transaction1, database_id, 0, key1_, &value1_, | 1121 leveldb::Status s = backing_store->PutRecord( |
| 869 &handles, &record); | 1122 &transaction1, database_id, KeyPrefix::kInvalidId, key, &value, |
| 870 EXPECT_FALSE(s.ok()); | 1123 &handles, &record); |
| 871 s = backing_store_->PutRecord(&transaction1, KeyPrefix::kInvalidId, | 1124 EXPECT_FALSE(s.ok()); |
| 872 object_store_id, key1_, &value1_, &handles, | 1125 s = backing_store->PutRecord(&transaction1, database_id, 0, key, |
| 873 &record); | 1126 &value, &handles, &record); |
| 874 EXPECT_FALSE(s.ok()); | 1127 EXPECT_FALSE(s.ok()); |
| 875 s = backing_store_->PutRecord(&transaction1, 0, object_store_id, key1_, | 1128 s = backing_store->PutRecord(&transaction1, KeyPrefix::kInvalidId, |
| 876 &value1_, &handles, &record); | 1129 object_store_id, key, &value, &handles, |
| 877 EXPECT_FALSE(s.ok()); | 1130 &record); |
| 878 | 1131 EXPECT_FALSE(s.ok()); |
| 879 s = backing_store_->GetRecord(&transaction1, database_id, | 1132 s = backing_store->PutRecord(&transaction1, 0, object_store_id, key, |
| 880 KeyPrefix::kInvalidId, key1_, &result_value); | 1133 &value, &handles, &record); |
| 881 EXPECT_FALSE(s.ok()); | 1134 EXPECT_FALSE(s.ok()); |
| 882 s = backing_store_->GetRecord(&transaction1, database_id, 0, key1_, | 1135 |
| 883 &result_value); | 1136 s = backing_store->GetRecord(&transaction1, database_id, |
| 884 EXPECT_FALSE(s.ok()); | 1137 KeyPrefix::kInvalidId, key, |
| 885 s = backing_store_->GetRecord(&transaction1, KeyPrefix::kInvalidId, | 1138 &result_value); |
| 886 object_store_id, key1_, &result_value); | 1139 EXPECT_FALSE(s.ok()); |
| 887 EXPECT_FALSE(s.ok()); | 1140 s = backing_store->GetRecord(&transaction1, database_id, 0, key, |
| 888 s = backing_store_->GetRecord(&transaction1, 0, object_store_id, key1_, | 1141 &result_value); |
| 889 &result_value); | 1142 EXPECT_FALSE(s.ok()); |
| 890 EXPECT_FALSE(s.ok()); | 1143 s = backing_store->GetRecord(&transaction1, KeyPrefix::kInvalidId, |
| 891 | 1144 object_store_id, key, &result_value); |
| 892 std::unique_ptr<IndexedDBKey> new_primary_key; | 1145 EXPECT_FALSE(s.ok()); |
| 893 s = backing_store_->GetPrimaryKeyViaIndex( | 1146 s = backing_store->GetRecord(&transaction1, 0, object_store_id, key, |
| 894 &transaction1, database_id, object_store_id, KeyPrefix::kInvalidId, key1_, | 1147 &result_value); |
| 895 &new_primary_key); | 1148 EXPECT_FALSE(s.ok()); |
| 896 EXPECT_FALSE(s.ok()); | 1149 |
| 897 s = backing_store_->GetPrimaryKeyViaIndex( | 1150 std::unique_ptr<IndexedDBKey> new_primary_key; |
| 898 &transaction1, database_id, object_store_id, invalid_low_index_id, key1_, | 1151 s = backing_store->GetPrimaryKeyViaIndex( |
| 899 &new_primary_key); | 1152 &transaction1, database_id, object_store_id, |
| 900 EXPECT_FALSE(s.ok()); | 1153 KeyPrefix::kInvalidId, key, &new_primary_key); |
| 901 s = backing_store_->GetPrimaryKeyViaIndex( | 1154 EXPECT_FALSE(s.ok()); |
| 902 &transaction1, database_id, object_store_id, 0, key1_, &new_primary_key); | 1155 s = backing_store->GetPrimaryKeyViaIndex( |
| 903 EXPECT_FALSE(s.ok()); | 1156 &transaction1, database_id, object_store_id, |
| 904 | 1157 invalid_low_index_id, key, &new_primary_key); |
| 905 s = backing_store_->GetPrimaryKeyViaIndex( | 1158 EXPECT_FALSE(s.ok()); |
| 906 &transaction1, KeyPrefix::kInvalidId, object_store_id, index_id, key1_, | 1159 s = backing_store->GetPrimaryKeyViaIndex(&transaction1, database_id, |
| 907 &new_primary_key); | 1160 object_store_id, 0, key, |
| 908 EXPECT_FALSE(s.ok()); | 1161 &new_primary_key); |
| 909 s = backing_store_->GetPrimaryKeyViaIndex(&transaction1, database_id, | 1162 EXPECT_FALSE(s.ok()); |
| 910 KeyPrefix::kInvalidId, index_id, | 1163 |
| 911 key1_, &new_primary_key); | 1164 s = backing_store->GetPrimaryKeyViaIndex( |
| 912 EXPECT_FALSE(s.ok()); | 1165 &transaction1, KeyPrefix::kInvalidId, object_store_id, index_id, |
| 1166 key, &new_primary_key); |
| 1167 EXPECT_FALSE(s.ok()); |
| 1168 s = backing_store->GetPrimaryKeyViaIndex( |
| 1169 &transaction1, database_id, KeyPrefix::kInvalidId, index_id, |
| 1170 key, &new_primary_key); |
| 1171 EXPECT_FALSE(s.ok()); |
| 1172 }, |
| 1173 base::Unretained(backing_store()), key1_, value1_)); |
| 1174 RunAllBlockingPoolTasksUntilIdle(); |
| 913 } | 1175 } |
| 914 | 1176 |
| 915 TEST_F(IndexedDBBackingStoreTest, CreateDatabase) { | 1177 TEST_F(IndexedDBBackingStoreTest, CreateDatabase) { |
| 916 const base::string16 database_name(ASCIIToUTF16("db1")); | 1178 idb_context_->TaskRunner()->PostTask( |
| 917 int64_t database_id; | 1179 FROM_HERE, |
| 918 const int64_t version = 9; | 1180 base::BindOnce( |
| 919 | 1181 [](IndexedDBBackingStore* backing_store) { |
| 920 const int64_t object_store_id = 99; | 1182 const base::string16 database_name(ASCIIToUTF16("db1")); |
| 921 const base::string16 object_store_name(ASCIIToUTF16("object_store1")); | 1183 int64_t database_id; |
| 922 const bool auto_increment = true; | 1184 const int64_t version = 9; |
| 923 const IndexedDBKeyPath object_store_key_path( | 1185 |
| 924 ASCIIToUTF16("object_store_key")); | 1186 const int64_t object_store_id = 99; |
| 925 | 1187 const base::string16 object_store_name( |
| 926 const int64_t index_id = 999; | 1188 ASCIIToUTF16("object_store1")); |
| 927 const base::string16 index_name(ASCIIToUTF16("index1")); | 1189 const bool auto_increment = true; |
| 928 const bool unique = true; | 1190 const IndexedDBKeyPath object_store_key_path( |
| 929 const bool multi_entry = true; | 1191 ASCIIToUTF16("object_store_key")); |
| 930 const IndexedDBKeyPath index_key_path(ASCIIToUTF16("index_key")); | 1192 |
| 931 | 1193 const int64_t index_id = 999; |
| 932 { | 1194 const base::string16 index_name(ASCIIToUTF16("index1")); |
| 933 leveldb::Status s = backing_store_->CreateIDBDatabaseMetaData( | 1195 const bool unique = true; |
| 934 database_name, version, &database_id); | 1196 const bool multi_entry = true; |
| 935 EXPECT_TRUE(s.ok()); | 1197 const IndexedDBKeyPath index_key_path(ASCIIToUTF16("index_key")); |
| 936 EXPECT_GT(database_id, 0); | 1198 |
| 937 | 1199 { |
| 938 IndexedDBBackingStore::Transaction transaction(backing_store_.get()); | 1200 leveldb::Status s = backing_store->CreateIDBDatabaseMetaData( |
| 939 transaction.Begin(); | 1201 database_name, version, &database_id); |
| 940 | 1202 EXPECT_TRUE(s.ok()); |
| 941 s = backing_store_->CreateObjectStore(&transaction, | 1203 EXPECT_GT(database_id, 0); |
| 942 database_id, | 1204 |
| 943 object_store_id, | 1205 IndexedDBBackingStore::Transaction transaction(backing_store); |
| 944 object_store_name, | 1206 transaction.Begin(); |
| 945 object_store_key_path, | 1207 |
| 946 auto_increment); | 1208 s = backing_store->CreateObjectStore( |
| 947 EXPECT_TRUE(s.ok()); | 1209 &transaction, database_id, object_store_id, object_store_name, |
| 948 | 1210 object_store_key_path, auto_increment); |
| 949 s = backing_store_->CreateIndex(&transaction, | 1211 EXPECT_TRUE(s.ok()); |
| 950 database_id, | 1212 |
| 951 object_store_id, | 1213 s = backing_store->CreateIndex( |
| 952 index_id, | 1214 &transaction, database_id, object_store_id, index_id, |
| 953 index_name, | 1215 index_name, index_key_path, unique, multi_entry); |
| 954 index_key_path, | 1216 EXPECT_TRUE(s.ok()); |
| 955 unique, | 1217 |
| 956 multi_entry); | 1218 scoped_refptr<TestCallback> callback( |
| 957 EXPECT_TRUE(s.ok()); | 1219 base::MakeRefCounted<TestCallback>()); |
| 958 | 1220 EXPECT_TRUE(transaction.CommitPhaseOne(callback).ok()); |
| 959 scoped_refptr<TestCallback> callback(new TestCallback()); | 1221 EXPECT_TRUE(callback->called); |
| 960 s = transaction.CommitPhaseOne(callback); | 1222 EXPECT_TRUE(callback->succeeded); |
| 961 EXPECT_TRUE(s.ok()); | 1223 EXPECT_TRUE(transaction.CommitPhaseTwo().ok()); |
| 962 EXPECT_TRUE(callback->called); | 1224 } |
| 963 EXPECT_TRUE(callback->succeeded); | 1225 |
| 964 s = transaction.CommitPhaseTwo(); | 1226 { |
| 965 EXPECT_TRUE(s.ok()); | 1227 IndexedDBDatabaseMetadata database; |
| 966 } | 1228 bool found; |
| 967 | 1229 leveldb::Status s = backing_store->GetIDBDatabaseMetaData( |
| 968 { | 1230 database_name, &database, &found); |
| 969 IndexedDBDatabaseMetadata database; | 1231 EXPECT_TRUE(s.ok()); |
| 970 bool found; | 1232 EXPECT_TRUE(found); |
| 971 leveldb::Status s = backing_store_->GetIDBDatabaseMetaData( | 1233 |
| 972 database_name, &database, &found); | 1234 // database.name is not filled in by the implementation. |
| 973 EXPECT_TRUE(s.ok()); | 1235 EXPECT_EQ(version, database.version); |
| 974 EXPECT_TRUE(found); | 1236 EXPECT_EQ(database_id, database.id); |
| 975 | 1237 |
| 976 // database.name is not filled in by the implementation. | 1238 s = backing_store->GetObjectStores(database.id, |
| 977 EXPECT_EQ(version, database.version); | 1239 &database.object_stores); |
| 978 EXPECT_EQ(database_id, database.id); | 1240 EXPECT_TRUE(s.ok()); |
| 979 | 1241 |
| 980 s = backing_store_->GetObjectStores(database.id, &database.object_stores); | 1242 EXPECT_EQ(1UL, database.object_stores.size()); |
| 981 EXPECT_TRUE(s.ok()); | 1243 IndexedDBObjectStoreMetadata object_store = |
| 982 | 1244 database.object_stores[object_store_id]; |
| 983 EXPECT_EQ(1UL, database.object_stores.size()); | 1245 EXPECT_EQ(object_store_name, object_store.name); |
| 984 IndexedDBObjectStoreMetadata object_store = | 1246 EXPECT_EQ(object_store_key_path, object_store.key_path); |
| 985 database.object_stores[object_store_id]; | 1247 EXPECT_EQ(auto_increment, object_store.auto_increment); |
| 986 EXPECT_EQ(object_store_name, object_store.name); | 1248 |
| 987 EXPECT_EQ(object_store_key_path, object_store.key_path); | 1249 EXPECT_EQ(1UL, object_store.indexes.size()); |
| 988 EXPECT_EQ(auto_increment, object_store.auto_increment); | 1250 IndexedDBIndexMetadata index = object_store.indexes[index_id]; |
| 989 | 1251 EXPECT_EQ(index_name, index.name); |
| 990 EXPECT_EQ(1UL, object_store.indexes.size()); | 1252 EXPECT_EQ(index_key_path, index.key_path); |
| 991 IndexedDBIndexMetadata index = object_store.indexes[index_id]; | 1253 EXPECT_EQ(unique, index.unique); |
| 992 EXPECT_EQ(index_name, index.name); | 1254 EXPECT_EQ(multi_entry, index.multi_entry); |
| 993 EXPECT_EQ(index_key_path, index.key_path); | 1255 } |
| 994 EXPECT_EQ(unique, index.unique); | 1256 }, |
| 995 EXPECT_EQ(multi_entry, index.multi_entry); | 1257 base::Unretained(backing_store()))); |
| 996 } | 1258 RunAllBlockingPoolTasksUntilIdle(); |
| 997 } | 1259 } |
| 998 | 1260 |
| 999 TEST_F(IndexedDBBackingStoreTest, GetDatabaseNames) { | 1261 TEST_F(IndexedDBBackingStoreTest, GetDatabaseNames) { |
| 1000 const base::string16 db1_name(ASCIIToUTF16("db1")); | 1262 idb_context_->TaskRunner()->PostTask( |
| 1001 const int64_t db1_version = 1LL; | 1263 FROM_HERE, base::BindOnce( |
| 1002 int64_t db1_id; | 1264 [](IndexedDBBackingStore* backing_store) { |
| 1003 | 1265 const base::string16 db1_name(ASCIIToUTF16("db1")); |
| 1004 // Database records with DEFAULT_VERSION represent stale data, | 1266 const int64_t db1_version = 1LL; |
| 1005 // and should not be enumerated. | 1267 int64_t db1_id; |
| 1006 const base::string16 db2_name(ASCIIToUTF16("db2")); | 1268 |
| 1007 const int64_t db2_version = IndexedDBDatabaseMetadata::DEFAULT_VERSION; | 1269 // Database records with DEFAULT_VERSION represent |
| 1008 int64_t db2_id; | 1270 // stale data, and should not be enumerated. |
| 1009 | 1271 const base::string16 db2_name(ASCIIToUTF16("db2")); |
| 1010 leveldb::Status s = | 1272 const int64_t db2_version = |
| 1011 backing_store_->CreateIDBDatabaseMetaData(db1_name, db1_version, &db1_id); | 1273 IndexedDBDatabaseMetadata::DEFAULT_VERSION; |
| 1012 EXPECT_TRUE(s.ok()); | 1274 int64_t db2_id; |
| 1013 EXPECT_GT(db1_id, 0LL); | 1275 |
| 1014 | 1276 leveldb::Status s = |
| 1015 s = backing_store_->CreateIDBDatabaseMetaData(db2_name, db2_version, &db2_id); | 1277 backing_store->CreateIDBDatabaseMetaData( |
| 1016 EXPECT_TRUE(s.ok()); | 1278 db1_name, db1_version, &db1_id); |
| 1017 EXPECT_GT(db2_id, db1_id); | 1279 EXPECT_TRUE(s.ok()); |
| 1018 | 1280 EXPECT_GT(db1_id, 0LL); |
| 1019 std::vector<base::string16> names = backing_store_->GetDatabaseNames(&s); | 1281 |
| 1020 EXPECT_TRUE(s.ok()); | 1282 s = backing_store->CreateIDBDatabaseMetaData( |
| 1021 ASSERT_EQ(1U, names.size()); | 1283 db2_name, db2_version, &db2_id); |
| 1022 EXPECT_EQ(db1_name, names[0]); | 1284 EXPECT_TRUE(s.ok()); |
| 1285 EXPECT_GT(db2_id, db1_id); |
| 1286 |
| 1287 std::vector<base::string16> names = |
| 1288 backing_store->GetDatabaseNames(&s); |
| 1289 EXPECT_TRUE(s.ok()); |
| 1290 ASSERT_EQ(1U, names.size()); |
| 1291 EXPECT_EQ(db1_name, names[0]); |
| 1292 }, |
| 1293 base::Unretained(backing_store()))); |
| 1294 RunAllBlockingPoolTasksUntilIdle(); |
| 1023 } | 1295 } |
| 1024 | 1296 |
| 1025 } // namespace | 1297 } // namespace |
| 1026 | 1298 |
| 1027 // Not in the anonymous namespace to friend IndexedDBBackingStore. | 1299 // Not in the anonymous namespace to friend IndexedDBBackingStore. |
| 1028 TEST_F(IndexedDBBackingStoreTest, ReadCorruptionInfo) { | 1300 TEST_F(IndexedDBBackingStoreTest, ReadCorruptionInfo) { |
| 1029 // No |path_base|. | 1301 // No |path_base|. |
| 1030 std::string message; | 1302 std::string message; |
| 1031 EXPECT_FALSE(IndexedDBBackingStore::ReadCorruptionInfo(base::FilePath(), | 1303 EXPECT_FALSE(IndexedDBBackingStore::ReadCorruptionInfo(base::FilePath(), |
| 1032 Origin(), &message)); | 1304 Origin(), &message)); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1109 | 1381 |
| 1110 // Dictionary, message key and more. | 1382 // Dictionary, message key and more. |
| 1111 ASSERT_TRUE(WriteFile(info_path, "{\"message\":\"foo\",\"bar\":5}")); | 1383 ASSERT_TRUE(WriteFile(info_path, "{\"message\":\"foo\",\"bar\":5}")); |
| 1112 EXPECT_TRUE( | 1384 EXPECT_TRUE( |
| 1113 IndexedDBBackingStore::ReadCorruptionInfo(path_base, origin, &message)); | 1385 IndexedDBBackingStore::ReadCorruptionInfo(path_base, origin, &message)); |
| 1114 EXPECT_FALSE(PathExists(info_path)); | 1386 EXPECT_FALSE(PathExists(info_path)); |
| 1115 EXPECT_EQ("foo", message); | 1387 EXPECT_EQ("foo", message); |
| 1116 } | 1388 } |
| 1117 | 1389 |
| 1118 } // namespace content | 1390 } // namespace content |
| OLD | NEW |