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 35662e454f22dd90a9761b78a34e9af75ab312cf..2234a20675fe4cfaa3945c72f997ecc21da2d78e 100644 |
--- a/content/browser/indexed_db/indexed_db_database_unittest.cc |
+++ b/content/browser/indexed_db/indexed_db_database_unittest.cc |
@@ -150,26 +150,32 @@ TEST(IndexedDBDatabaseTest, ForcedClose) { |
EXPECT_TRUE(callbacks->abort_called()); |
} |
-class MockDeleteCallbacks : public IndexedDBCallbacks { |
+class MockCallbacks : public IndexedDBCallbacks { |
public: |
- MockDeleteCallbacks() |
- : IndexedDBCallbacks(NULL, 0, 0), |
- blocked_called_(false), |
- success_called_(false) {} |
+ MockCallbacks() |
+ : IndexedDBCallbacks(NULL, 0, 0) {} |
void OnBlocked(int64_t existing_version) override { blocked_called_ = true; } |
void OnSuccess(int64_t result) override { success_called_ = true; } |
+ void OnError(const IndexedDBDatabaseError& error) override { |
+ error_called_ = true; |
+ } |
+ bool IsValid() const override { return valid_; } |
bool blocked_called() const { return blocked_called_; } |
bool success_called() const { return success_called_; } |
+ bool error_called() const { return error_called_; } |
+ void set_valid(bool valid) { valid_ = valid; } |
private: |
- ~MockDeleteCallbacks() override {} |
+ ~MockCallbacks() override {} |
- bool blocked_called_; |
- bool success_called_; |
+ bool blocked_called_ = false; |
+ bool success_called_ = false; |
+ bool error_called_ = false; |
+ bool valid_ = true; |
- DISALLOW_COPY_AND_ASSIGN(MockDeleteCallbacks); |
+ DISALLOW_COPY_AND_ASSIGN(MockCallbacks); |
}; |
TEST(IndexedDBDatabaseTest, PendingDelete) { |
@@ -203,7 +209,7 @@ TEST(IndexedDBDatabaseTest, PendingDelete) { |
EXPECT_EQ(db->PendingOpenDeleteCount(), 0UL); |
EXPECT_FALSE(backing_store->HasOneRef()); // local and db |
- scoped_refptr<MockDeleteCallbacks> request2(new MockDeleteCallbacks()); |
+ scoped_refptr<MockCallbacks> request2(new MockCallbacks()); |
db->DeleteDatabase(request2); |
EXPECT_EQ(db->ConnectionCount(), 1UL); |
EXPECT_EQ(db->ActiveOpenDeleteCount(), 1UL); |
@@ -228,6 +234,108 @@ TEST(IndexedDBDatabaseTest, PendingDelete) { |
EXPECT_TRUE(request2->success_called()); |
} |
+TEST(IndexedDBDatabaseTest, ConnectionRequestsNoLongerValid) { |
+ scoped_refptr<IndexedDBFakeBackingStore> backing_store = |
+ new IndexedDBFakeBackingStore(); |
+ |
+ const int64_t transaction_id1 = 1; |
+ scoped_refptr<MockIndexedDBFactory> factory = new MockIndexedDBFactory(); |
+ leveldb::Status s; |
+ scoped_refptr<IndexedDBDatabase> db = |
+ IndexedDBDatabase::Create(ASCIIToUTF16("db"), |
+ backing_store.get(), |
+ factory.get(), |
+ IndexedDBDatabase::Identifier(), |
+ &s); |
+ |
+ // Make a connection request. This will be processed immediately. |
+ scoped_refptr<MockIndexedDBCallbacks> request1(new MockIndexedDBCallbacks()); |
+ { |
+ std::unique_ptr<IndexedDBPendingConnection> connection( |
+ base::MakeUnique<IndexedDBPendingConnection>( |
+ request1, make_scoped_refptr(new MockIndexedDBDatabaseCallbacks()), |
+ kFakeChildProcessId, transaction_id1, |
+ IndexedDBDatabaseMetadata::DEFAULT_VERSION)); |
+ db->OpenConnection(std::move(connection)); |
+ } |
+ |
+ EXPECT_EQ(db->ConnectionCount(), 1UL); |
+ EXPECT_EQ(db->ActiveOpenDeleteCount(), 0UL); |
+ EXPECT_EQ(db->PendingOpenDeleteCount(), 0UL); |
+ |
+ // Make a delete request. This will be blocked by the open. |
+ scoped_refptr<MockCallbacks> request2(new MockCallbacks()); |
+ db->DeleteDatabase(request2); |
+ |
+ EXPECT_EQ(db->ConnectionCount(), 1UL); |
+ EXPECT_EQ(db->ActiveOpenDeleteCount(), 1UL); |
+ EXPECT_EQ(db->PendingOpenDeleteCount(), 0UL); |
+ |
+ db->VersionChangeIgnored(); |
+ |
+ EXPECT_TRUE(request2->blocked_called()); |
+ |
+ // Make another delete request. This will be waiting in the queue. |
+ scoped_refptr<MockCallbacks> request3(new MockCallbacks()); |
+ db->DeleteDatabase(request3); |
+ EXPECT_FALSE(request3->HasOneRef()); // local, db |
+ |
+ EXPECT_EQ(db->ConnectionCount(), 1UL); |
+ EXPECT_EQ(db->ActiveOpenDeleteCount(), 1UL); |
+ EXPECT_EQ(db->PendingOpenDeleteCount(), 1UL); |
+ |
+ // Make another connection request. This will also be waiting in the queue. |
+ scoped_refptr<MockCallbacks> request4(new MockCallbacks()); |
+ { |
+ std::unique_ptr<IndexedDBPendingConnection> connection( |
+ base::MakeUnique<IndexedDBPendingConnection>( |
+ request4, make_scoped_refptr(new MockIndexedDBDatabaseCallbacks()), |
+ kFakeChildProcessId, transaction_id1, |
+ IndexedDBDatabaseMetadata::DEFAULT_VERSION)); |
+ db->OpenConnection(std::move(connection)); |
+ } |
+ |
+ EXPECT_EQ(db->ConnectionCount(), 1UL); |
+ EXPECT_EQ(db->ActiveOpenDeleteCount(), 1UL); |
+ EXPECT_EQ(db->PendingOpenDeleteCount(), 2UL); |
+ |
+ // Finally yet another delete request, also waiting in the queue. |
+ scoped_refptr<MockCallbacks> request5(new MockCallbacks()); |
+ db->DeleteDatabase(request2); |
+ |
+ EXPECT_EQ(db->ConnectionCount(), 1UL); |
+ EXPECT_EQ(db->ActiveOpenDeleteCount(), 1UL); |
+ EXPECT_EQ(db->PendingOpenDeleteCount(), 3UL); |
+ |
+ // Simulate renderer going away. |
+ request3->set_valid(false); |
+ request4->set_valid(false); |
+ |
+ // Close the blocking connection. First delete request should succeed. |
+ EXPECT_FALSE(request2->success_called()); |
+ db->Close(request1->connection(), true /* forced */); |
+ EXPECT_TRUE(request2->success_called()); |
+ |
+ // Invalid requests should be abandoned. |
+ EXPECT_FALSE(request3->blocked_called()); |
+ EXPECT_FALSE(request3->success_called()); |
+ EXPECT_FALSE(request3->error_called()); |
+ EXPECT_TRUE(request3->HasOneRef()); // local |
+ |
+ EXPECT_FALSE(request4->blocked_called()); |
+ EXPECT_FALSE(request4->success_called()); |
+ EXPECT_FALSE(request4->error_called()); |
+ EXPECT_TRUE(request4->HasOneRef()); // local |
+ |
+ // Final delete request should also run. |
+ EXPECT_TRUE(request2->success_called()); |
+ |
+ // And everything else should be complete. |
+ EXPECT_EQ(db->ConnectionCount(), 0UL); |
+ EXPECT_EQ(db->ActiveOpenDeleteCount(), 0UL); |
+ EXPECT_EQ(db->PendingOpenDeleteCount(), 0UL); |
+} |
+ |
void DummyOperation(IndexedDBTransaction* transaction) { |
} |