| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/browser/indexed_db/indexed_db_database.h" |
| |
| #include "base/auto_reset.h" |
| #include "base/logging.h" |
| #include "base/strings/string16.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "content/browser/indexed_db/indexed_db.h" |
| #include "content/browser/indexed_db/indexed_db_backing_store.h" |
| #include "content/browser/indexed_db/indexed_db_callbacks.h" |
| #include "content/browser/indexed_db/indexed_db_connection.h" |
| #include "content/browser/indexed_db/indexed_db_cursor.h" |
| #include "content/browser/indexed_db/indexed_db_database.h" |
| #include "content/browser/indexed_db/indexed_db_factory.h" |
| #include "content/browser/indexed_db/indexed_db_fake_backing_store.h" |
| #include "content/browser/indexed_db/indexed_db_transaction.h" |
| #include "content/browser/indexed_db/mock_indexed_db_callbacks.h" |
| #include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using base::ASCIIToUTF16; |
| |
| namespace content { |
| |
| TEST(IndexedDBDatabaseTest, BackingStoreRetention) { |
| scoped_refptr<IndexedDBFakeBackingStore> backing_store = |
| new IndexedDBFakeBackingStore(); |
| EXPECT_TRUE(backing_store->HasOneRef()); |
| |
| IndexedDBFactory* factory = 0; |
| scoped_refptr<IndexedDBDatabase> db = IndexedDBDatabase::Create( |
| ASCIIToUTF16("db"), |
| backing_store, |
| factory, |
| IndexedDBDatabase::Identifier()); |
| EXPECT_FALSE(backing_store->HasOneRef()); // local and db |
| db = NULL; |
| EXPECT_TRUE(backing_store->HasOneRef()); // local |
| } |
| |
| TEST(IndexedDBDatabaseTest, ConnectionLifecycle) { |
| scoped_refptr<IndexedDBFakeBackingStore> backing_store = |
| new IndexedDBFakeBackingStore(); |
| EXPECT_TRUE(backing_store->HasOneRef()); // local |
| |
| IndexedDBFactory* factory = 0; |
| scoped_refptr<IndexedDBDatabase> db = |
| IndexedDBDatabase::Create(ASCIIToUTF16("db"), |
| backing_store, |
| factory, |
| IndexedDBDatabase::Identifier()); |
| |
| EXPECT_FALSE(backing_store->HasOneRef()); // local and db |
| |
| scoped_refptr<MockIndexedDBCallbacks> request1(new MockIndexedDBCallbacks()); |
| scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1( |
| new MockIndexedDBDatabaseCallbacks()); |
| const int64 transaction_id1 = 1; |
| db->OpenConnection(request1, |
| callbacks1, |
| transaction_id1, |
| IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); |
| |
| EXPECT_FALSE(backing_store->HasOneRef()); // db, connection count > 0 |
| |
| scoped_refptr<MockIndexedDBCallbacks> request2(new MockIndexedDBCallbacks()); |
| scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks2( |
| new MockIndexedDBDatabaseCallbacks()); |
| const int64 transaction_id2 = 2; |
| db->OpenConnection(request2, |
| callbacks2, |
| transaction_id2, |
| IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); |
| |
| EXPECT_FALSE(backing_store->HasOneRef()); // local and connection |
| |
| request1->connection()->ForceClose(); |
| EXPECT_FALSE(request1->connection()->IsConnected()); |
| |
| EXPECT_FALSE(backing_store->HasOneRef()); // local and connection |
| |
| request2->connection()->ForceClose(); |
| EXPECT_FALSE(request2->connection()->IsConnected()); |
| |
| EXPECT_TRUE(backing_store->HasOneRef()); |
| EXPECT_FALSE(db->backing_store()); |
| |
| db = NULL; |
| } |
| |
| TEST(IndexedDBDatabaseTest, ForcedClose) { |
| scoped_refptr<IndexedDBFakeBackingStore> backing_store = |
| new IndexedDBFakeBackingStore(); |
| EXPECT_TRUE(backing_store->HasOneRef()); |
| |
| IndexedDBFactory* factory = 0; |
| scoped_refptr<IndexedDBDatabase> database = |
| IndexedDBDatabase::Create(ASCIIToUTF16("db"), |
| backing_store, |
| factory, |
| IndexedDBDatabase::Identifier()); |
| |
| EXPECT_FALSE(backing_store->HasOneRef()); // local and db |
| |
| scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks( |
| new MockIndexedDBDatabaseCallbacks()); |
| scoped_refptr<MockIndexedDBCallbacks> request(new MockIndexedDBCallbacks()); |
| const int64 upgrade_transaction_id = 3; |
| database->OpenConnection(request, |
| callbacks, |
| upgrade_transaction_id, |
| IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); |
| EXPECT_EQ(database, request->connection()->database()); |
| |
| const int64 transaction_id = 123; |
| const std::vector<int64> scope; |
| database->CreateTransaction(transaction_id, |
| request->connection(), |
| scope, |
| indexed_db::TRANSACTION_READ_ONLY); |
| |
| request->connection()->ForceClose(); |
| |
| EXPECT_TRUE(backing_store->HasOneRef()); // local |
| EXPECT_TRUE(callbacks->abort_called()); |
| } |
| |
| class MockDeleteCallbacks : public IndexedDBCallbacks { |
| public: |
| MockDeleteCallbacks() |
| : IndexedDBCallbacks(NULL, 0, 0), |
| blocked_called_(false), |
| success_void_called_(false) {} |
| |
| virtual void OnBlocked(int64 existing_version) OVERRIDE { |
| blocked_called_ = true; |
| } |
| virtual void OnSuccess() OVERRIDE { success_void_called_ = true; } |
| |
| bool blocked_called() const { return blocked_called_; } |
| |
| private: |
| virtual ~MockDeleteCallbacks() { EXPECT_TRUE(success_void_called_); } |
| |
| bool blocked_called_; |
| bool success_void_called_; |
| }; |
| |
| TEST(IndexedDBDatabaseTest, PendingDelete) { |
| scoped_refptr<IndexedDBFakeBackingStore> backing_store = |
| new IndexedDBFakeBackingStore(); |
| EXPECT_TRUE(backing_store->HasOneRef()); // local |
| |
| IndexedDBFactory* factory = 0; |
| scoped_refptr<IndexedDBDatabase> db = |
| IndexedDBDatabase::Create(ASCIIToUTF16("db"), |
| backing_store, |
| factory, |
| IndexedDBDatabase::Identifier()); |
| |
| EXPECT_FALSE(backing_store->HasOneRef()); // local and db |
| |
| scoped_refptr<MockIndexedDBCallbacks> request1(new MockIndexedDBCallbacks()); |
| scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1( |
| new MockIndexedDBDatabaseCallbacks()); |
| const int64 transaction_id1 = 1; |
| db->OpenConnection(request1, |
| callbacks1, |
| transaction_id1, |
| IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); |
| |
| EXPECT_FALSE(backing_store->HasOneRef()); // local and db |
| |
| scoped_refptr<MockDeleteCallbacks> request2(new MockDeleteCallbacks()); |
| db->DeleteDatabase(request2); |
| |
| EXPECT_TRUE(request2->blocked_called()); |
| EXPECT_FALSE(backing_store->HasOneRef()); // local and db |
| |
| db->Close(request1->connection(), true /* forced */); |
| |
| EXPECT_FALSE(db->backing_store()); |
| EXPECT_TRUE(backing_store->HasOneRef()); // local |
| } |
| |
| } // namespace content |