Index: content/browser/indexed_db/indexed_db_database_unittest.cc |
diff --git a/content/browser/indexed_db/indexed_db_database_unittest.cc b/content/browser/indexed_db/indexed_db_database_unittest.cc |
index 7feed8201d7ac179ded65f9390f22d8b21885a45..c5f3a13aaceec2b316d3f8a43395e335bae33070 100644 |
--- a/content/browser/indexed_db/indexed_db_database_unittest.cc |
+++ b/content/browser/indexed_db/indexed_db_database_unittest.cc |
@@ -6,6 +6,7 @@ |
#include "base/auto_reset.h" |
#include "base/logging.h" |
+#include "base/run_loop.h" |
#include "base/strings/string16.h" |
#include "base/strings/utf_string_conversions.h" |
#include "content/browser/indexed_db/indexed_db.h" |
@@ -17,6 +18,7 @@ |
#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/indexed_db_value.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" |
@@ -24,7 +26,7 @@ |
using base::ASCIIToUTF16; |
namespace { |
-const int FAKE_CHILD_PROCESS_ID = 0; |
+const int kFakeChildProcessId = 0; |
} |
namespace content { |
@@ -71,7 +73,7 @@ TEST(IndexedDBDatabaseTest, ConnectionLifecycle) { |
IndexedDBPendingConnection connection1( |
request1, |
callbacks1, |
- FAKE_CHILD_PROCESS_ID, |
+ kFakeChildProcessId, |
transaction_id1, |
IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); |
db->OpenConnection(connection1); |
@@ -85,7 +87,7 @@ TEST(IndexedDBDatabaseTest, ConnectionLifecycle) { |
IndexedDBPendingConnection connection2( |
request2, |
callbacks2, |
- FAKE_CHILD_PROCESS_ID, |
+ kFakeChildProcessId, |
transaction_id2, |
IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); |
db->OpenConnection(connection2); |
@@ -129,7 +131,7 @@ TEST(IndexedDBDatabaseTest, ForcedClose) { |
IndexedDBPendingConnection connection( |
request, |
callbacks, |
- FAKE_CHILD_PROCESS_ID, |
+ kFakeChildProcessId, |
upgrade_transaction_id, |
IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); |
database->OpenConnection(connection); |
@@ -193,7 +195,7 @@ TEST(IndexedDBDatabaseTest, PendingDelete) { |
IndexedDBPendingConnection connection( |
request1, |
callbacks1, |
- FAKE_CHILD_PROCESS_ID, |
+ kFakeChildProcessId, |
transaction_id1, |
IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); |
db->OpenConnection(connection); |
@@ -213,4 +215,191 @@ TEST(IndexedDBDatabaseTest, PendingDelete) { |
EXPECT_TRUE(request2->success_called()); |
} |
+void DummyOperation(IndexedDBTransaction* transaction) { |
+} |
+ |
+class IndexedDBDatabaseOperationTest : public testing::Test { |
+ public: |
+ IndexedDBDatabaseOperationTest() : commit_success_(true) {} |
+ |
+ virtual void SetUp() { |
+ backing_store_ = new IndexedDBFakeBackingStore(); |
+ leveldb::Status s; |
+ db_ = IndexedDBDatabase::Create(ASCIIToUTF16("db"), |
+ backing_store_, |
+ NULL /*factory*/, |
+ IndexedDBDatabase::Identifier(), |
+ &s); |
+ ASSERT_TRUE(s.ok()); |
+ |
+ request_ = new MockIndexedDBCallbacks(); |
+ callbacks_ = new MockIndexedDBDatabaseCallbacks(); |
+ const int64 transaction_id = 1; |
+ db_->OpenConnection(IndexedDBPendingConnection( |
+ request_, |
+ callbacks_, |
+ kFakeChildProcessId, |
+ transaction_id, |
+ IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION)); |
+ EXPECT_EQ(IndexedDBDatabaseMetadata::NO_INT_VERSION, |
+ db_->metadata().int_version); |
+ |
+ transaction_ = new IndexedDBTransaction( |
+ transaction_id, |
+ callbacks_, |
+ std::set<int64>() /*scope*/, |
+ indexed_db::TRANSACTION_VERSION_CHANGE, |
+ db_, |
+ new IndexedDBFakeBackingStore::FakeTransaction(commit_success_)); |
+ db_->TransactionCreated(transaction_); |
+ |
+ // Add a dummy task which takes the place of the VersionChangeOperation |
+ // which kicks off the upgrade. This ensures that the transaction has |
+ // processed at least one task before the CreateObjectStore call. |
+ transaction_->ScheduleTask(base::Bind(&DummyOperation)); |
+ } |
+ |
+ void RunPostedTasks() { base::RunLoop().RunUntilIdle(); } |
+ |
+ protected: |
+ scoped_refptr<IndexedDBFakeBackingStore> backing_store_; |
+ scoped_refptr<IndexedDBDatabase> db_; |
+ scoped_refptr<MockIndexedDBCallbacks> request_; |
+ scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks_; |
+ scoped_refptr<IndexedDBTransaction> transaction_; |
+ |
+ bool commit_success_; |
+ |
+ private: |
+ base::MessageLoop message_loop_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(IndexedDBDatabaseOperationTest); |
+}; |
+ |
+TEST_F(IndexedDBDatabaseOperationTest, CreateObjectStore) { |
+ EXPECT_EQ(0ULL, db_->metadata().object_stores.size()); |
+ const int64 store_id = 1001; |
+ db_->CreateObjectStore(transaction_->id(), |
+ store_id, |
+ ASCIIToUTF16("store"), |
+ IndexedDBKeyPath(), |
+ false /*auto_increment*/); |
+ EXPECT_EQ(1ULL, db_->metadata().object_stores.size()); |
+ RunPostedTasks(); |
+ transaction_->Commit(); |
+ EXPECT_EQ(1ULL, db_->metadata().object_stores.size()); |
+} |
+ |
+TEST_F(IndexedDBDatabaseOperationTest, CreateIndex) { |
+ EXPECT_EQ(0ULL, db_->metadata().object_stores.size()); |
+ const int64 store_id = 1001; |
+ db_->CreateObjectStore(transaction_->id(), |
+ store_id, |
+ ASCIIToUTF16("store"), |
+ IndexedDBKeyPath(), |
+ false /*auto_increment*/); |
+ EXPECT_EQ(1ULL, db_->metadata().object_stores.size()); |
+ const int64 index_id = 2002; |
+ db_->CreateIndex(transaction_->id(), |
+ store_id, |
+ index_id, |
+ ASCIIToUTF16("index"), |
+ IndexedDBKeyPath(), |
+ false /*unique*/, |
+ false /*multi_entry*/); |
+ EXPECT_EQ( |
+ 1ULL, |
+ db_->metadata().object_stores.find(store_id)->second.indexes.size()); |
+ RunPostedTasks(); |
+ transaction_->Commit(); |
+ EXPECT_EQ(1ULL, db_->metadata().object_stores.size()); |
+ EXPECT_EQ( |
+ 1ULL, |
+ db_->metadata().object_stores.find(store_id)->second.indexes.size()); |
+} |
+ |
+class IndexedDBDatabaseOperationAbortTest |
+ : public IndexedDBDatabaseOperationTest { |
+ public: |
+ IndexedDBDatabaseOperationAbortTest() { commit_success_ = false; } |
+}; |
+ |
+TEST_F(IndexedDBDatabaseOperationAbortTest, CreateObjectStore) { |
+ EXPECT_EQ(0ULL, db_->metadata().object_stores.size()); |
+ const int64 store_id = 1001; |
+ db_->CreateObjectStore(transaction_->id(), |
+ store_id, |
+ ASCIIToUTF16("store"), |
+ IndexedDBKeyPath(), |
+ false /*auto_increment*/); |
+ EXPECT_EQ(1ULL, db_->metadata().object_stores.size()); |
+ RunPostedTasks(); |
+ transaction_->Commit(); |
+ EXPECT_EQ(0ULL, db_->metadata().object_stores.size()); |
+} |
+ |
+TEST_F(IndexedDBDatabaseOperationAbortTest, CreateIndex) { |
+ EXPECT_EQ(0ULL, db_->metadata().object_stores.size()); |
+ const int64 store_id = 1001; |
+ db_->CreateObjectStore(transaction_->id(), |
+ store_id, |
+ ASCIIToUTF16("store"), |
+ IndexedDBKeyPath(), |
+ false /*auto_increment*/); |
+ EXPECT_EQ(1ULL, db_->metadata().object_stores.size()); |
+ const int64 index_id = 2002; |
+ db_->CreateIndex(transaction_->id(), |
+ store_id, |
+ index_id, |
+ ASCIIToUTF16("index"), |
+ IndexedDBKeyPath(), |
+ false /*unique*/, |
+ false /*multi_entry*/); |
+ EXPECT_EQ( |
+ 1ULL, |
+ db_->metadata().object_stores.find(store_id)->second.indexes.size()); |
+ RunPostedTasks(); |
+ transaction_->Commit(); |
+ EXPECT_EQ(0ULL, db_->metadata().object_stores.size()); |
+} |
+ |
+TEST_F(IndexedDBDatabaseOperationTest, CreatePutDelete) { |
+ EXPECT_EQ(0ULL, db_->metadata().object_stores.size()); |
+ const int64 store_id = 1001; |
+ |
+ // Creation is synchronous. |
+ db_->CreateObjectStore(transaction_->id(), |
+ store_id, |
+ ASCIIToUTF16("store"), |
+ IndexedDBKeyPath(), |
+ false /*auto_increment*/); |
+ EXPECT_EQ(1ULL, db_->metadata().object_stores.size()); |
+ |
+ |
+ // Put is asynchronous |
+ IndexedDBValue value("value1", std::vector<IndexedDBBlobInfo>()); |
+ ScopedVector<webkit_blob::BlobDataHandle> handles; |
+ scoped_ptr<IndexedDBKey> key(new IndexedDBKey("key")); |
+ std::vector<IndexedDBDatabase::IndexKeys> index_keys; |
+ scoped_refptr<MockIndexedDBCallbacks> request( |
+ new MockIndexedDBCallbacks(false)); |
+ db_->Put(transaction_->id(), |
+ store_id, |
+ &value, |
+ &handles, |
+ key.Pass(), |
+ IndexedDBDatabase::ADD_ONLY, |
+ request, |
+ index_keys); |
+ |
+ // Deletion is asynchronous. |
+ db_->DeleteObjectStore(transaction_->id(), |
+ store_id); |
+ EXPECT_EQ(1ULL, db_->metadata().object_stores.size()); |
+ |
+ // This will execute the Put then Delete. |
+ RunPostedTasks(); |
+ EXPECT_EQ(0ULL, db_->metadata().object_stores.size()); |
+} |
+ |
} // namespace content |