diff options
author | jsbell@chromium.org <jsbell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-31 01:36:56 +0000 |
---|---|---|
committer | jsbell@chromium.org <jsbell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-31 01:36:56 +0000 |
commit | 2f626ee3362fbda3404dc720c681afb8647f9323 (patch) | |
tree | aba7dad15783237eabb32091c01c88c2b0223ea9 /content/browser/indexed_db/indexed_db_unittest.cc | |
parent | c078461f8a6d45304f0edd5dacf10aa7074270e6 (diff) | |
download | chromium_src-2f626ee3362fbda3404dc720c681afb8647f9323.zip chromium_src-2f626ee3362fbda3404dc720c681afb8647f9323.tar.gz chromium_src-2f626ee3362fbda3404dc720c681afb8647f9323.tar.bz2 |
IndexedDB: Close backing store after a failed write
A failed write by leveldb can indicates either a transient I/O error by the foreground thread or that the background compaction thread has hit an error (I/O or corruption) which will make all future operations fail.
In lieu of being able to distinguish these for now, treat the write operation as fatal and force-close the backing store so that if the error was transient the store is not wedged until a browser restart. A well-behaved web app would be able to detect the close and re-open the connection.
BUG=251870
Review URL: https://codereview.chromium.org/48833005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@231974 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/indexed_db/indexed_db_unittest.cc')
-rw-r--r-- | content/browser/indexed_db/indexed_db_unittest.cc | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/content/browser/indexed_db/indexed_db_unittest.cc b/content/browser/indexed_db/indexed_db_unittest.cc index 6180c86..43613af 100644 --- a/content/browser/indexed_db/indexed_db_unittest.cc +++ b/content/browser/indexed_db/indexed_db_unittest.cc @@ -9,6 +9,8 @@ #include "content/browser/browser_thread_impl.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/mock_indexed_db_callbacks.h" +#include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h" #include "content/public/browser/storage_partition.h" #include "content/public/common/url_constants.h" #include "content/public/test/test_browser_context.h" @@ -221,4 +223,41 @@ TEST_F(IndexedDBTest, DeleteFailsIfDirectoryLocked) { EXPECT_TRUE(base::DirectoryExists(test_path)); } +TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnCommitFailure) { + const GURL kTestOrigin("http://test/"); + + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + + scoped_refptr<IndexedDBContextImpl> context = new IndexedDBContextImpl( + temp_dir.path(), special_storage_policy_, NULL, task_runner_); + + scoped_refptr<IndexedDBFactory> factory = context->GetIDBFactory(); + + scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks()); + scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks( + new MockIndexedDBDatabaseCallbacks()); + const int64 transaction_id = 1; + factory->Open(ASCIIToUTF16("db"), + IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION, + transaction_id, + callbacks, + db_callbacks, + kTestOrigin, + temp_dir.path()); + + EXPECT_TRUE(callbacks->connection()); + + // ConnectionOpened() is usually called by the dispatcher. + context->ConnectionOpened(kTestOrigin, callbacks->connection()); + + EXPECT_TRUE(factory->IsBackingStoreOpenForTesting(kTestOrigin)); + + // Simulate the write failure. + callbacks->connection()->database()->TransactionCommitFailed(); + + EXPECT_TRUE(db_callbacks->forced_close_called()); + EXPECT_FALSE(factory->IsBackingStoreOpenForTesting(kTestOrigin)); +} + } // namespace content |