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

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

Issue 2930183002: Let IndexedDBContextImpl create its own task runner (Closed)
Patch Set: rebased Created 3 years, 5 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_factory_unittest.cc
diff --git a/content/browser/indexed_db/indexed_db_factory_unittest.cc b/content/browser/indexed_db/indexed_db_factory_unittest.cc
index 374143ad3b935d4c7102bb4ac0e1398f883329ad..1c872813917b94c3eab85a3507a5d29feb2ff4f3 100644
--- a/content/browser/indexed_db/indexed_db_factory_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_factory_unittest.cc
@@ -14,7 +14,7 @@
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_simple_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
+#include "base/threading/sequenced_task_runner_handle.h"
#include "content/browser/indexed_db/indexed_db_connection.h"
#include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/browser/indexed_db/indexed_db_data_format_version.h"
@@ -22,6 +22,7 @@
#include "content/browser/indexed_db/mock_indexed_db_callbacks.h"
#include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h"
#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_utils.h"
#include "storage/browser/test/mock_quota_manager_proxy.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseException.h"
@@ -72,14 +73,15 @@ class MockIDBFactory : public IndexedDBFactoryImpl {
class IndexedDBFactoryTest : public testing::Test {
public:
+ IndexedDBFactoryTest()
+ : quota_manager_proxy_(
+ base::MakeRefCounted<MockQuotaManagerProxy>(nullptr, nullptr)) {}
+
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- task_runner_ = new base::TestSimpleTaskRunner();
- quota_manager_proxy_ = new MockQuotaManagerProxy(nullptr, nullptr);
- context_ = new IndexedDBContextImpl(
+ context_ = base::MakeRefCounted<IndexedDBContextImpl>(
temp_dir_.GetPath(), nullptr /* special_storage_policy */,
- quota_manager_proxy_.get(), task_runner_.get());
- idb_factory_ = new MockIDBFactory(context_.get());
+ quota_manager_proxy_.get());
}
void TearDown() override {
@@ -87,127 +89,164 @@ class IndexedDBFactoryTest : public testing::Test {
}
protected:
- IndexedDBFactoryTest() {}
- MockIDBFactory* factory() const { return idb_factory_.get(); }
- void clear_factory() { idb_factory_ = nullptr; }
IndexedDBContextImpl* context() const { return context_.get(); }
private:
+ TestBrowserThreadBundle thread_bundle_;
+
base::ScopedTempDir temp_dir_;
- scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
- scoped_refptr<IndexedDBContextImpl> context_;
- scoped_refptr<MockIDBFactory> idb_factory_;
scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_;
- TestBrowserThreadBundle thread_bundle_;
+ scoped_refptr<IndexedDBContextImpl> context_;
DISALLOW_COPY_AND_ASSIGN(IndexedDBFactoryTest);
};
TEST_F(IndexedDBFactoryTest, BackingStoreLifetime) {
- const Origin origin1(GURL("http://localhost:81"));
- const Origin origin2(GURL("http://localhost:82"));
+ context()->TaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](IndexedDBContextImpl* context) {
+ scoped_refptr<MockIDBFactory> factory =
+ base::MakeRefCounted<MockIDBFactory>(context);
+
+ const Origin origin1(GURL("http://localhost:81"));
+ const Origin origin2(GURL("http://localhost:82"));
- base::ScopedTempDir temp_directory;
- ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
- scoped_refptr<IndexedDBBackingStore> disk_store1 =
- factory()->TestOpenBackingStore(origin1, temp_directory.GetPath());
+ scoped_refptr<IndexedDBBackingStore> disk_store1 =
+ factory->TestOpenBackingStore(origin1, context->data_path());
- scoped_refptr<IndexedDBBackingStore> disk_store2 =
- factory()->TestOpenBackingStore(origin1, temp_directory.GetPath());
- EXPECT_EQ(disk_store1.get(), disk_store2.get());
+ scoped_refptr<IndexedDBBackingStore> disk_store2 =
+ factory->TestOpenBackingStore(origin1, context->data_path());
+ EXPECT_EQ(disk_store1.get(), disk_store2.get());
- scoped_refptr<IndexedDBBackingStore> disk_store3 =
- factory()->TestOpenBackingStore(origin2, temp_directory.GetPath());
+ scoped_refptr<IndexedDBBackingStore> disk_store3 =
+ factory->TestOpenBackingStore(origin2, context->data_path());
- factory()->TestCloseBackingStore(disk_store1.get());
- factory()->TestCloseBackingStore(disk_store3.get());
+ factory->TestCloseBackingStore(disk_store1.get());
+ factory->TestCloseBackingStore(disk_store3.get());
- EXPECT_FALSE(disk_store1->HasOneRef());
- EXPECT_FALSE(disk_store2->HasOneRef());
- EXPECT_TRUE(disk_store3->HasOneRef());
+ EXPECT_FALSE(disk_store1->HasOneRef());
+ EXPECT_FALSE(disk_store2->HasOneRef());
+ EXPECT_TRUE(disk_store3->HasOneRef());
- disk_store2 = nullptr;
- EXPECT_TRUE(disk_store1->HasOneRef());
+ disk_store2 = nullptr;
+ EXPECT_TRUE(disk_store1->HasOneRef());
+ },
+ base::Unretained(context())));
+
+ RunAllBlockingPoolTasksUntilIdle();
}
TEST_F(IndexedDBFactoryTest, BackingStoreLazyClose) {
- const Origin origin(GURL("http://localhost:81"));
-
- base::ScopedTempDir temp_directory;
- ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
- scoped_refptr<IndexedDBBackingStore> store =
- factory()->TestOpenBackingStore(origin, temp_directory.GetPath());
-
- // Give up the local refptr so that the factory has the only
- // outstanding reference.
- IndexedDBBackingStore* store_ptr = store.get();
- store = nullptr;
- EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
- factory()->TestReleaseBackingStore(store_ptr, false);
- EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
-
- factory()->TestOpenBackingStore(origin, temp_directory.GetPath());
- EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
- factory()->TestReleaseBackingStore(store_ptr, false);
- EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
-
- // Take back a ref ptr and ensure that the actual close
- // stops a running timer.
- store = store_ptr;
- factory()->TestCloseBackingStore(store_ptr);
- EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
+ context()->TaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](IndexedDBContextImpl* context) {
+
+ scoped_refptr<MockIDBFactory> factory =
+ base::MakeRefCounted<MockIDBFactory>(context);
+
+ const Origin origin(GURL("http://localhost:81"));
+
+ scoped_refptr<IndexedDBBackingStore> store =
+ factory->TestOpenBackingStore(origin, context->data_path());
+
+ // Give up the local refptr so that the factory has the only
+ // outstanding reference.
+ IndexedDBBackingStore* store_ptr = store.get();
+ store = nullptr;
+ EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
+ factory->TestReleaseBackingStore(store_ptr, false);
+ EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
+
+ factory->TestOpenBackingStore(origin, context->data_path());
+ EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
+ factory->TestReleaseBackingStore(store_ptr, false);
+ EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
+
+ // Take back a ref ptr and ensure that the actual close
+ // stops a running timer.
+ store = store_ptr;
+ factory->TestCloseBackingStore(store_ptr);
+ EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
+ },
+ base::Unretained(context())));
+
+ RunAllBlockingPoolTasksUntilIdle();
}
TEST_F(IndexedDBFactoryTest, MemoryBackingStoreLifetime) {
- const Origin origin1(GURL("http://localhost:81"));
- const Origin origin2(GURL("http://localhost:82"));
+ context()->TaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](IndexedDBContextImpl* context) {
+
+ scoped_refptr<MockIDBFactory> factory =
+ base::MakeRefCounted<MockIDBFactory>(context);
- scoped_refptr<IndexedDBBackingStore> mem_store1 =
- factory()->TestOpenBackingStore(origin1, base::FilePath());
+ const Origin origin1(GURL("http://localhost:81"));
+ const Origin origin2(GURL("http://localhost:82"));
- scoped_refptr<IndexedDBBackingStore> mem_store2 =
- factory()->TestOpenBackingStore(origin1, base::FilePath());
- EXPECT_EQ(mem_store1.get(), mem_store2.get());
+ scoped_refptr<IndexedDBBackingStore> mem_store1 =
+ factory->TestOpenBackingStore(origin1, base::FilePath());
- scoped_refptr<IndexedDBBackingStore> mem_store3 =
- factory()->TestOpenBackingStore(origin2, base::FilePath());
+ scoped_refptr<IndexedDBBackingStore> mem_store2 =
+ factory->TestOpenBackingStore(origin1, base::FilePath());
+ EXPECT_EQ(mem_store1.get(), mem_store2.get());
- factory()->TestCloseBackingStore(mem_store1.get());
- factory()->TestCloseBackingStore(mem_store3.get());
+ scoped_refptr<IndexedDBBackingStore> mem_store3 =
+ factory->TestOpenBackingStore(origin2, base::FilePath());
- EXPECT_FALSE(mem_store1->HasOneRef());
- EXPECT_FALSE(mem_store2->HasOneRef());
- EXPECT_FALSE(mem_store3->HasOneRef());
+ factory->TestCloseBackingStore(mem_store1.get());
+ factory->TestCloseBackingStore(mem_store3.get());
- clear_factory();
- EXPECT_FALSE(mem_store1->HasOneRef()); // mem_store1 and 2
- EXPECT_FALSE(mem_store2->HasOneRef()); // mem_store1 and 2
- EXPECT_TRUE(mem_store3->HasOneRef());
+ EXPECT_FALSE(mem_store1->HasOneRef());
+ EXPECT_FALSE(mem_store2->HasOneRef());
+ EXPECT_FALSE(mem_store3->HasOneRef());
- mem_store2 = nullptr;
- EXPECT_TRUE(mem_store1->HasOneRef());
+ factory = nullptr;
+ EXPECT_FALSE(mem_store1->HasOneRef()); // mem_store1 and 2
+ EXPECT_FALSE(mem_store2->HasOneRef()); // mem_store1 and 2
+ EXPECT_TRUE(mem_store3->HasOneRef());
+
+ mem_store2 = nullptr;
+ EXPECT_TRUE(mem_store1->HasOneRef());
+ },
+ base::Unretained(context())));
+
+ RunAllBlockingPoolTasksUntilIdle();
}
TEST_F(IndexedDBFactoryTest, RejectLongOrigins) {
- base::ScopedTempDir temp_directory;
- ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
- const base::FilePath base_path = temp_directory.GetPath();
-
- int limit = base::GetMaximumPathComponentLength(base_path);
- EXPECT_GT(limit, 0);
-
- std::string origin(limit + 1, 'x');
- Origin too_long_origin(GURL("http://" + origin + ":81/"));
- scoped_refptr<IndexedDBBackingStore> diskStore1 =
- factory()->TestOpenBackingStore(too_long_origin, base_path);
- EXPECT_FALSE(diskStore1.get());
-
- Origin ok_origin(GURL("http://someorigin.com:82/"));
- scoped_refptr<IndexedDBBackingStore> diskStore2 =
- factory()->TestOpenBackingStore(ok_origin, base_path);
- EXPECT_TRUE(diskStore2.get());
- // We need a manual close or Windows can't delete the temp directory.
- factory()->TestCloseBackingStore(diskStore2.get());
+ context()->TaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](IndexedDBContextImpl* context) {
+ base::FilePath temp_dir = context->data_path().DirName();
+ int limit = base::GetMaximumPathComponentLength(temp_dir);
+ EXPECT_GT(limit, 0);
+
+ scoped_refptr<MockIDBFactory> factory =
+ base::MakeRefCounted<MockIDBFactory>(context);
+
+ std::string origin(limit + 1, 'x');
+ Origin too_long_origin(GURL("http://" + origin + ":81/"));
+ scoped_refptr<IndexedDBBackingStore> diskStore1 =
+ factory->TestOpenBackingStore(too_long_origin,
+ context->data_path());
+ EXPECT_FALSE(diskStore1.get());
+
+ Origin ok_origin(GURL("http://someorigin.com:82/"));
+ scoped_refptr<IndexedDBBackingStore> diskStore2 =
+ factory->TestOpenBackingStore(ok_origin, context->data_path());
+ EXPECT_TRUE(diskStore2.get());
+ // We need a manual close or Windows can't delete the temp
+ // directory.
+ factory->TestCloseBackingStore(diskStore2.get());
+ },
+ base::Unretained(context())));
+
+ RunAllBlockingPoolTasksUntilIdle();
}
class DiskFullFactory : public IndexedDBFactoryImpl {
@@ -238,7 +277,7 @@ class LookingForQuotaErrorMockCallbacks : public IndexedDBCallbacks {
: IndexedDBCallbacks(nullptr,
url::Origin(),
nullptr,
- base::ThreadTaskRunnerHandle::Get()),
+ base::SequencedTaskRunnerHandle::Get()),
error_called_(false) {}
void OnError(const IndexedDBDatabaseError& error) override {
error_called_ = true;
@@ -254,177 +293,232 @@ class LookingForQuotaErrorMockCallbacks : public IndexedDBCallbacks {
};
TEST_F(IndexedDBFactoryTest, QuotaErrorOnDiskFull) {
- const Origin origin(GURL("http://localhost:81"));
- base::ScopedTempDir temp_directory;
- ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
-
- scoped_refptr<DiskFullFactory> factory = new DiskFullFactory(context());
scoped_refptr<LookingForQuotaErrorMockCallbacks> callbacks =
- new LookingForQuotaErrorMockCallbacks;
+ base::MakeRefCounted<LookingForQuotaErrorMockCallbacks>();
scoped_refptr<IndexedDBDatabaseCallbacks> dummy_database_callbacks =
- new IndexedDBDatabaseCallbacks(nullptr, nullptr);
- const base::string16 name(ASCIIToUTF16("name"));
- std::unique_ptr<IndexedDBPendingConnection> connection(
- base::MakeUnique<IndexedDBPendingConnection>(
- callbacks, dummy_database_callbacks, 0 /* child_process_id */,
- 2 /* transaction_id */, 1 /* version */));
- factory->Open(name, std::move(connection), nullptr /* request_context */,
- origin, temp_directory.GetPath());
- EXPECT_TRUE(callbacks->error_called());
+ base::MakeRefCounted<IndexedDBDatabaseCallbacks>(nullptr, nullptr);
+
+ context()->TaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](IndexedDBContextImpl* context,
+ scoped_refptr<LookingForQuotaErrorMockCallbacks> callbacks,
+ scoped_refptr<IndexedDBDatabaseCallbacks>
+ dummy_database_callbacks) {
+
+ const Origin origin(GURL("http://localhost:81"));
+ scoped_refptr<DiskFullFactory> factory =
+ base::MakeRefCounted<DiskFullFactory>(context);
+ const base::string16 name(ASCIIToUTF16("name"));
+ std::unique_ptr<IndexedDBPendingConnection> connection(
+ base::MakeUnique<IndexedDBPendingConnection>(
+ callbacks, dummy_database_callbacks,
+ 0 /* child_process_id */, 2 /* transaction_id */,
+ 1 /* version */));
+ factory->Open(name, std::move(connection),
+ nullptr /* request_context */, origin,
+ context->data_path());
+ EXPECT_TRUE(callbacks->error_called());
+ },
+ base::Unretained(context()), std::move(callbacks),
+ std::move(dummy_database_callbacks)));
+ RunAllBlockingPoolTasksUntilIdle();
}
TEST_F(IndexedDBFactoryTest, BackingStoreReleasedOnForcedClose) {
- const Origin origin(GURL("http://localhost:81"));
-
- base::ScopedTempDir temp_directory;
- ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
-
- scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks());
- scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks(
- new MockIndexedDBDatabaseCallbacks());
- const int64_t transaction_id = 1;
- std::unique_ptr<IndexedDBPendingConnection> connection(
- base::MakeUnique<IndexedDBPendingConnection>(
- callbacks, db_callbacks, 0 /* child_process_id */, transaction_id,
- IndexedDBDatabaseMetadata::DEFAULT_VERSION));
- factory()->Open(ASCIIToUTF16("db"), std::move(connection),
- nullptr /* request_context */, origin,
- temp_directory.GetPath());
-
- EXPECT_TRUE(callbacks->connection());
-
- EXPECT_TRUE(factory()->IsBackingStoreOpen(origin));
- EXPECT_FALSE(factory()->IsBackingStorePendingClose(origin));
-
- callbacks->connection()->ForceClose();
-
- EXPECT_FALSE(factory()->IsBackingStoreOpen(origin));
- EXPECT_FALSE(factory()->IsBackingStorePendingClose(origin));
+ context()->TaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](IndexedDBContextImpl* context,
+ scoped_refptr<MockIndexedDBCallbacks> callbacks,
+ scoped_refptr<IndexedDBDatabaseCallbacks> db_callbacks) {
+
+ scoped_refptr<MockIDBFactory> factory =
+ base::MakeRefCounted<MockIDBFactory>(context);
+
+ const Origin origin(GURL("http://localhost:81"));
+ const int64_t transaction_id = 1;
+ std::unique_ptr<IndexedDBPendingConnection> connection(
+ base::MakeUnique<IndexedDBPendingConnection>(
+ callbacks, db_callbacks, 0 /* child_process_id */,
+ transaction_id,
+ IndexedDBDatabaseMetadata::DEFAULT_VERSION));
+ factory->Open(ASCIIToUTF16("db"), std::move(connection),
+ nullptr /* request_context */, origin,
+ context->data_path());
+
+ EXPECT_TRUE(callbacks->connection());
+
+ EXPECT_TRUE(factory->IsBackingStoreOpen(origin));
+ EXPECT_FALSE(factory->IsBackingStorePendingClose(origin));
+
+ callbacks->connection()->ForceClose();
+
+ EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
+ EXPECT_FALSE(factory->IsBackingStorePendingClose(origin));
+ },
+ base::Unretained(context()),
+ base::MakeRefCounted<MockIndexedDBCallbacks>(),
+ base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>()));
+ RunAllBlockingPoolTasksUntilIdle();
}
TEST_F(IndexedDBFactoryTest, BackingStoreReleaseDelayedOnClose) {
- const Origin origin(GURL("http://localhost:81"));
-
- base::ScopedTempDir temp_directory;
- ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
-
- scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks());
- scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks(
- new MockIndexedDBDatabaseCallbacks());
- const int64_t transaction_id = 1;
- std::unique_ptr<IndexedDBPendingConnection> connection(
- base::MakeUnique<IndexedDBPendingConnection>(
- callbacks, db_callbacks, 0 /* child_process_id */, transaction_id,
- IndexedDBDatabaseMetadata::DEFAULT_VERSION));
- factory()->Open(ASCIIToUTF16("db"), std::move(connection),
- nullptr /* request_context */, origin,
- temp_directory.GetPath());
-
- EXPECT_TRUE(callbacks->connection());
- IndexedDBBackingStore* store =
- callbacks->connection()->database()->backing_store();
- EXPECT_FALSE(store->HasOneRef()); // Factory and database.
-
- EXPECT_TRUE(factory()->IsBackingStoreOpen(origin));
- callbacks->connection()->Close();
- EXPECT_TRUE(store->HasOneRef()); // Factory.
- EXPECT_TRUE(factory()->IsBackingStoreOpen(origin));
- EXPECT_TRUE(factory()->IsBackingStorePendingClose(origin));
- EXPECT_TRUE(store->close_timer()->IsRunning());
-
- // Take a ref so it won't be destroyed out from under the test.
- scoped_refptr<IndexedDBBackingStore> store_ref = store;
- // Now simulate shutdown, which should stop the timer.
- factory()->ContextDestroyed();
- EXPECT_TRUE(store->HasOneRef()); // Local.
- EXPECT_FALSE(store->close_timer()->IsRunning());
- EXPECT_FALSE(factory()->IsBackingStoreOpen(origin));
- EXPECT_FALSE(factory()->IsBackingStorePendingClose(origin));
+ context()->TaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](IndexedDBContextImpl* context,
+ scoped_refptr<MockIndexedDBCallbacks> callbacks,
+ scoped_refptr<IndexedDBDatabaseCallbacks> db_callbacks) {
+
+ scoped_refptr<MockIDBFactory> factory =
+ base::MakeRefCounted<MockIDBFactory>(context);
+
+ const Origin origin(GURL("http://localhost:81"));
+ const int64_t transaction_id = 1;
+ std::unique_ptr<IndexedDBPendingConnection> connection(
+ base::MakeUnique<IndexedDBPendingConnection>(
+ callbacks, db_callbacks, 0 /* child_process_id */,
+ transaction_id,
+ IndexedDBDatabaseMetadata::DEFAULT_VERSION));
+ factory->Open(ASCIIToUTF16("db"), std::move(connection),
+ nullptr /* request_context */, origin,
+ context->data_path());
+
+ EXPECT_TRUE(callbacks->connection());
+ IndexedDBBackingStore* store =
+ callbacks->connection()->database()->backing_store();
+ EXPECT_FALSE(store->HasOneRef()); // Factory and database.
+
+ EXPECT_TRUE(factory->IsBackingStoreOpen(origin));
+ callbacks->connection()->Close();
+ EXPECT_TRUE(store->HasOneRef()); // Factory.
+ EXPECT_TRUE(factory->IsBackingStoreOpen(origin));
+ EXPECT_TRUE(factory->IsBackingStorePendingClose(origin));
+ EXPECT_TRUE(store->close_timer()->IsRunning());
+
+ // Take a ref so it won't be destroyed out from under the test.
+ scoped_refptr<IndexedDBBackingStore> store_ref = store;
+ // Now simulate shutdown, which should stop the timer.
+ factory->ContextDestroyed();
+ EXPECT_TRUE(store->HasOneRef()); // Local.
+ EXPECT_FALSE(store->close_timer()->IsRunning());
+ EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
+ EXPECT_FALSE(factory->IsBackingStorePendingClose(origin));
+ },
+ base::Unretained(context()),
+ base::MakeRefCounted<MockIndexedDBCallbacks>(),
+ base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>()));
+ RunAllBlockingPoolTasksUntilIdle();
}
TEST_F(IndexedDBFactoryTest, DeleteDatabaseClosesBackingStore) {
- const Origin origin(GURL("http://localhost:81"));
+ context()->TaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](IndexedDBContextImpl* context,
+ scoped_refptr<MockIndexedDBCallbacks> callbacks) {
+
+ scoped_refptr<MockIDBFactory> factory =
+ base::MakeRefCounted<MockIDBFactory>(context);
- base::ScopedTempDir temp_directory;
- ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
+ const Origin origin(GURL("http://localhost:81"));
+ EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
- EXPECT_FALSE(factory()->IsBackingStoreOpen(origin));
+ factory->DeleteDatabase(
+ ASCIIToUTF16("db"), nullptr /* request_context */, callbacks,
+ origin, context->data_path(), false /* force_close */);
- const bool expect_connection = false;
- scoped_refptr<MockIndexedDBCallbacks> callbacks(
- new MockIndexedDBCallbacks(expect_connection));
- factory()->DeleteDatabase(ASCIIToUTF16("db"), nullptr /* request_context */,
- callbacks, origin, temp_directory.GetPath(),
- false /* force_close */);
+ EXPECT_TRUE(factory->IsBackingStoreOpen(origin));
+ EXPECT_TRUE(factory->IsBackingStorePendingClose(origin));
- EXPECT_TRUE(factory()->IsBackingStoreOpen(origin));
- EXPECT_TRUE(factory()->IsBackingStorePendingClose(origin));
+ // Now simulate shutdown, which should stop the timer.
+ factory->ContextDestroyed();
- // Now simulate shutdown, which should stop the timer.
- factory()->ContextDestroyed();
+ EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
+ EXPECT_FALSE(factory->IsBackingStorePendingClose(origin));
- EXPECT_FALSE(factory()->IsBackingStoreOpen(origin));
- EXPECT_FALSE(factory()->IsBackingStorePendingClose(origin));
+ },
+ base::Unretained(context()),
+ base::MakeRefCounted<MockIndexedDBCallbacks>(
+ false /*expect_connection*/)));
+ RunAllBlockingPoolTasksUntilIdle();
}
TEST_F(IndexedDBFactoryTest, GetDatabaseNamesClosesBackingStore) {
- const Origin origin(GURL("http://localhost:81"));
-
- base::ScopedTempDir temp_directory;
- ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
-
- EXPECT_FALSE(factory()->IsBackingStoreOpen(origin));
-
- const bool expect_connection = false;
- scoped_refptr<MockIndexedDBCallbacks> callbacks(
- new MockIndexedDBCallbacks(expect_connection));
- factory()->GetDatabaseNames(callbacks, origin, temp_directory.GetPath(),
- nullptr /* request_context */);
-
- EXPECT_TRUE(factory()->IsBackingStoreOpen(origin));
- EXPECT_TRUE(factory()->IsBackingStorePendingClose(origin));
-
- // Now simulate shutdown, which should stop the timer.
- factory()->ContextDestroyed();
-
- EXPECT_FALSE(factory()->IsBackingStoreOpen(origin));
- EXPECT_FALSE(factory()->IsBackingStorePendingClose(origin));
+ context()->TaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](IndexedDBContextImpl* context,
+ scoped_refptr<MockIndexedDBCallbacks> callbacks) {
+ scoped_refptr<MockIDBFactory> factory =
+ base::MakeRefCounted<MockIDBFactory>(context);
+
+ const Origin origin(GURL("http://localhost:81"));
+ EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
+
+ factory->GetDatabaseNames(callbacks, origin, context->data_path(),
+ nullptr /* request_context */);
+
+ EXPECT_TRUE(factory->IsBackingStoreOpen(origin));
+ EXPECT_TRUE(factory->IsBackingStorePendingClose(origin));
+
+ // Now simulate shutdown, which should stop the timer.
+ factory->ContextDestroyed();
+
+ EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
+ EXPECT_FALSE(factory->IsBackingStorePendingClose(origin));
+
+ },
+ base::Unretained(context()),
+ base::MakeRefCounted<MockIndexedDBCallbacks>(
+ false /*expect_connection*/)));
+ RunAllBlockingPoolTasksUntilIdle();
}
TEST_F(IndexedDBFactoryTest, ForceCloseReleasesBackingStore) {
- const Origin origin(GURL("http://localhost:81"));
-
- base::ScopedTempDir temp_directory;
- ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
-
- scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks());
- scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks(
- new MockIndexedDBDatabaseCallbacks());
- const int64_t transaction_id = 1;
- std::unique_ptr<IndexedDBPendingConnection> connection(
- base::MakeUnique<IndexedDBPendingConnection>(
- callbacks, db_callbacks, 0 /* child_process_id */, transaction_id,
- IndexedDBDatabaseMetadata::DEFAULT_VERSION));
- factory()->Open(ASCIIToUTF16("db"), std::move(connection),
- nullptr /* request_context */, origin,
- temp_directory.GetPath());
-
- EXPECT_TRUE(callbacks->connection());
- EXPECT_TRUE(factory()->IsBackingStoreOpen(origin));
- EXPECT_FALSE(factory()->IsBackingStorePendingClose(origin));
-
- callbacks->connection()->Close();
-
- EXPECT_TRUE(factory()->IsBackingStoreOpen(origin));
- EXPECT_TRUE(factory()->IsBackingStorePendingClose(origin));
-
- factory()->ForceClose(origin);
-
- EXPECT_FALSE(factory()->IsBackingStoreOpen(origin));
- EXPECT_FALSE(factory()->IsBackingStorePendingClose(origin));
-
- // Ensure it is safe if the store is not open.
- factory()->ForceClose(origin);
+ context()->TaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](IndexedDBContextImpl* context,
+ scoped_refptr<MockIndexedDBCallbacks> callbacks,
+ scoped_refptr<IndexedDBDatabaseCallbacks> db_callbacks) {
+ scoped_refptr<MockIDBFactory> factory =
+ base::MakeRefCounted<MockIDBFactory>(context);
+
+ const Origin origin(GURL("http://localhost:81"));
+ const int64_t transaction_id = 1;
+ std::unique_ptr<IndexedDBPendingConnection> connection(
+ base::MakeUnique<IndexedDBPendingConnection>(
+ callbacks, db_callbacks, 0 /* child_process_id */,
+ transaction_id,
+ IndexedDBDatabaseMetadata::DEFAULT_VERSION));
+ factory->Open(ASCIIToUTF16("db"), std::move(connection),
+ nullptr /* request_context */, origin,
+ context->data_path());
+
+ EXPECT_TRUE(callbacks->connection());
+ EXPECT_TRUE(factory->IsBackingStoreOpen(origin));
+ EXPECT_FALSE(factory->IsBackingStorePendingClose(origin));
+
+ callbacks->connection()->Close();
+
+ EXPECT_TRUE(factory->IsBackingStoreOpen(origin));
+ EXPECT_TRUE(factory->IsBackingStorePendingClose(origin));
+
+ factory->ForceClose(origin);
+
+ EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
+ EXPECT_FALSE(factory->IsBackingStorePendingClose(origin));
+
+ // Ensure it is safe if the store is not open.
+ factory->ForceClose(origin);
+
+ },
+ base::Unretained(context()),
+ base::MakeRefCounted<MockIndexedDBCallbacks>(),
+ base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>()));
+ RunAllBlockingPoolTasksUntilIdle();
}
class UpgradeNeededCallbacks : public MockIndexedDBCallbacks {
@@ -469,56 +563,93 @@ class ErrorCallbacks : public MockIndexedDBCallbacks {
TEST_F(IndexedDBFactoryTest, DatabaseFailedOpen) {
const Origin origin(GURL("http://localhost:81"));
-
- base::ScopedTempDir temp_directory;
- ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
-
const base::string16 db_name(ASCIIToUTF16("db"));
- const int64_t db_version = 2;
const int64_t transaction_id = 1;
- scoped_refptr<IndexedDBDatabaseCallbacks> db_callbacks(
- new MockIndexedDBDatabaseCallbacks());
-
- // Open at version 2, then close.
- {
- scoped_refptr<UpgradeNeededCallbacks> callbacks(
- new UpgradeNeededCallbacks());
- std::unique_ptr<IndexedDBPendingConnection> connection(
- base::MakeUnique<IndexedDBPendingConnection>(
- callbacks, db_callbacks, 0 /* child_process_id */, transaction_id,
- db_version));
- factory()->Open(db_name, std::move(connection),
- nullptr /* request_context */, origin,
- temp_directory.GetPath());
- EXPECT_TRUE(factory()->IsDatabaseOpen(origin, db_name));
-
- // Pump the message loop so the upgrade transaction can run.
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(callbacks->connection());
- callbacks->connection()->database()->Commit(
- callbacks->connection()->GetTransaction(transaction_id));
-
- callbacks->connection()->Close();
- EXPECT_FALSE(factory()->IsDatabaseOpen(origin, db_name));
- }
-
- // Open at version < 2, which will fail; ensure factory doesn't retain
- // the database object.
- {
- scoped_refptr<ErrorCallbacks> callbacks(new ErrorCallbacks());
- std::unique_ptr<IndexedDBPendingConnection> connection(
- base::MakeUnique<IndexedDBPendingConnection>(
- callbacks, db_callbacks, 0 /* child_process_id */, transaction_id,
- db_version - 1));
- factory()->Open(db_name, std::move(connection),
- nullptr /* request_context */, origin,
- temp_directory.GetPath());
- EXPECT_TRUE(callbacks->saw_error());
- EXPECT_FALSE(factory()->IsDatabaseOpen(origin, db_name));
- }
- // Terminate all pending-close timers.
- factory()->ForceClose(origin);
+ // These objects are retained across posted tasks, so despite being used
+ // exclusively on the IDB sequence.
+
+ // Created and used on IDB sequence.
+ scoped_refptr<MockIDBFactory> factory;
+ // Created on IO thread, used on IDB sequence.
+ scoped_refptr<UpgradeNeededCallbacks> upgrade_callbacks =
+ base::MakeRefCounted<UpgradeNeededCallbacks>();
+
+ context()->TaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](IndexedDBContextImpl* context,
+ scoped_refptr<MockIDBFactory>* factory,
+ scoped_refptr<UpgradeNeededCallbacks>* upgrade_callbacks,
+ scoped_refptr<IndexedDBDatabaseCallbacks> db_callbacks,
+ const base::string16& db_name, int64_t transaction_id,
+ const Origin& origin) {
+
+ *factory = base::MakeRefCounted<MockIDBFactory>(context);
+
+ // Open at version 2.
+ const int64_t db_version = 2;
+ (*factory)->Open(
+ db_name,
+ base::MakeUnique<IndexedDBPendingConnection>(
+ *upgrade_callbacks, db_callbacks, 0 /* child_process_id */,
+ transaction_id, db_version),
+ nullptr /* request_context */, origin, context->data_path());
+
+ EXPECT_TRUE((*factory)->IsDatabaseOpen(origin, db_name));
+ },
+ base::Unretained(context()), base::Unretained(&factory),
+ base::Unretained(&upgrade_callbacks),
+ base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>(), db_name,
+ transaction_id, origin));
+
+ // Pump the message loop so the upgrade transaction can run.
+ RunAllBlockingPoolTasksUntilIdle();
+
+ context()->TaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](IndexedDBContextImpl* context,
+ scoped_refptr<MockIDBFactory> factory,
+ scoped_refptr<UpgradeNeededCallbacks> upgrade_callbacks,
+ scoped_refptr<ErrorCallbacks> failed_open_callbacks,
+ scoped_refptr<IndexedDBDatabaseCallbacks> db_callbacks,
+ const base::string16& db_name, int64_t transaction_id,
+ const Origin& origin) {
+ // Close the connection.
+ {
+ EXPECT_TRUE(upgrade_callbacks->connection());
+ upgrade_callbacks->connection()->database()->Commit(
+ upgrade_callbacks->connection()->GetTransaction(
+ transaction_id));
+ upgrade_callbacks->connection()->Close();
+ EXPECT_FALSE(factory->IsDatabaseOpen(origin, db_name));
+ }
+
+ // Open at version < 2, which will fail; ensure factory doesn't
+ // retain the database object.
+ {
+ const int64_t db_version = 1;
+ std::unique_ptr<IndexedDBPendingConnection> connection(
+ base::MakeUnique<IndexedDBPendingConnection>(
+ failed_open_callbacks, db_callbacks,
+ 0 /* child_process_id */, transaction_id, db_version));
+ factory->Open(db_name, std::move(connection),
+ nullptr /* request_context */, origin,
+ context->data_path());
+ EXPECT_TRUE(failed_open_callbacks->saw_error());
+ EXPECT_FALSE(factory->IsDatabaseOpen(origin, db_name));
+ }
+
+ // Terminate all pending-close timers.
+ factory->ForceClose(origin);
+ },
+ base::Unretained(context()), std::move(factory),
+ std::move(upgrade_callbacks), base::MakeRefCounted<ErrorCallbacks>(),
+ base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>(), db_name,
+ transaction_id, origin));
+
+ RunAllBlockingPoolTasksUntilIdle();
}
namespace {
@@ -552,22 +683,58 @@ TEST_F(IndexedDBFactoryTest, DataFormatVersion) {
const IndexedDBDataFormatVersion& version) {
base::AutoReset<IndexedDBDataFormatVersion> override_version(
&IndexedDBDataFormatVersion::GetMutableCurrentForTesting(), version);
- auto db_callbacks = base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>();
- auto callbacks = base::MakeRefCounted<DataLossCallbacks>();
+
+ // These objects are retained across posted tasks, so despite being used
+ // exclusively on the IDB sequence.
+
+ // Created and used on IDB sequence.
+ scoped_refptr<MockIDBFactory> factory;
+ // Created on IO thread, used on IDB sequence.
+ scoped_refptr<DataLossCallbacks> callbacks =
+ base::MakeRefCounted<DataLossCallbacks>();
+
const int64_t transaction_id = 1;
- factory()->Open(ASCIIToUTF16("test_db"),
- base::MakeUnique<IndexedDBPendingConnection>(
- callbacks, db_callbacks, 0 /* child_process_id */,
- transaction_id, 1 /* version */),
- nullptr /* request_context */, origin,
- context()->data_path());
- base::RunLoop().RunUntilIdle();
- auto* connection = callbacks->connection();
- EXPECT_TRUE(connection);
- connection->database()->Commit(connection->GetTransaction(transaction_id));
- connection->Close();
- factory()->ForceClose(origin);
- return callbacks->data_loss();
+ blink::WebIDBDataLoss result;
+
+ context()->TaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](IndexedDBContextImpl* context,
+ scoped_refptr<MockIDBFactory>* factory,
+ scoped_refptr<DataLossCallbacks>* callbacks,
+ scoped_refptr<IndexedDBDatabaseCallbacks> db_callbacks,
+ const Origin& origin, int64_t transaction_id) {
+ *factory = base::MakeRefCounted<MockIDBFactory>(context);
+ (*factory)->Open(
+ ASCIIToUTF16("test_db"),
+ base::MakeUnique<IndexedDBPendingConnection>(
+ *callbacks, db_callbacks, 0 /* child_process_id */,
+ transaction_id, 1 /* version */),
+ nullptr /* request_context */, origin, context->data_path());
+ },
+ base::Unretained(context()), base::Unretained(&factory),
+ base::Unretained(&callbacks),
+ base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>(), origin,
+ transaction_id));
+ RunAllBlockingPoolTasksUntilIdle();
+ context()->TaskRunner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ [](scoped_refptr<MockIDBFactory> factory,
+ scoped_refptr<DataLossCallbacks> callbacks, const Origin& origin,
+ int64_t transaction_id, blink::WebIDBDataLoss* result) {
+ auto* connection = callbacks->connection();
+ EXPECT_TRUE(connection);
+ connection->database()->Commit(
+ connection->GetTransaction(transaction_id));
+ connection->Close();
+ factory->ForceClose(origin);
+ *result = callbacks->data_loss();
+ },
+ std::move(factory), std::move(callbacks), origin, transaction_id,
+ base::Unretained(&result)));
+ RunAllBlockingPoolTasksUntilIdle();
+ return result;
};
using blink::kWebIDBDataLossNone;

Powered by Google App Engine
This is Rietveld 408576698