Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Unified Diff: content/browser/indexed_db/indexed_db_database_unittest.cc

Issue 2386683003: IndexedDB: Ignore open/delete requests from terminated renderers. (Closed)
Patch Set: Allow deletes to proceed Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..e558e7bc1110132041f185f40239a3e25a79d7f2 100644
--- a/content/browser/indexed_db/indexed_db_database_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_database_unittest.cc
@@ -150,26 +150,31 @@ 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 +208,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 +233,107 @@ 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());
+
+ // Delete requests that have lost dispatcher should still be processed so
+ // that e.g. a delete followed by a window close is not ignored.
+ EXPECT_FALSE(request3->blocked_called());
+ EXPECT_TRUE(request3->success_called());
+ EXPECT_FALSE(request3->error_called());
+ EXPECT_TRUE(request3->HasOneRef()); // local
+
+ // Open requests that have lost dispatcher should not be processed.
+ 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) {
}
« no previous file with comments | « content/browser/indexed_db/indexed_db_database.cc ('k') | content/browser/indexed_db/indexed_db_dispatcher_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698