| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdint.h> | 5 #include <stdint.h> |
| 6 #include <utility> | 6 #include <utility> |
| 7 | 7 |
| 8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
| 9 #include "base/files/scoped_temp_dir.h" | 9 #include "base/files/scoped_temp_dir.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
| 13 #include "base/test/test_simple_task_runner.h" | 13 #include "base/threading/sequenced_task_runner_handle.h" |
| 14 #include "base/threading/thread.h" | |
| 15 #include "base/threading/thread_task_runner_handle.h" | |
| 16 #include "content/browser/indexed_db/indexed_db_connection.h" | 14 #include "content/browser/indexed_db/indexed_db_connection.h" |
| 17 #include "content/browser/indexed_db/indexed_db_context_impl.h" | 15 #include "content/browser/indexed_db/indexed_db_context_impl.h" |
| 18 #include "content/browser/indexed_db/indexed_db_factory_impl.h" | 16 #include "content/browser/indexed_db/indexed_db_factory_impl.h" |
| 19 #include "content/browser/indexed_db/mock_indexed_db_callbacks.h" | 17 #include "content/browser/indexed_db/mock_indexed_db_callbacks.h" |
| 20 #include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h" | 18 #include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h" |
| 21 #include "content/public/browser/storage_partition.h" | 19 #include "content/public/browser/storage_partition.h" |
| 22 #include "content/public/common/url_constants.h" | 20 #include "content/public/common/url_constants.h" |
| 23 #include "content/public/test/test_browser_context.h" | |
| 24 #include "content/public/test/test_browser_thread_bundle.h" | 21 #include "content/public/test/test_browser_thread_bundle.h" |
| 22 #include "content/public/test/test_utils.h" |
| 25 #include "storage/browser/quota/quota_manager.h" | 23 #include "storage/browser/quota/quota_manager.h" |
| 26 #include "storage/browser/quota/special_storage_policy.h" | 24 #include "storage/browser/quota/special_storage_policy.h" |
| 27 #include "storage/browser/test/mock_quota_manager_proxy.h" | 25 #include "storage/browser/test/mock_quota_manager_proxy.h" |
| 28 #include "storage/browser/test/mock_special_storage_policy.h" | 26 #include "storage/browser/test/mock_special_storage_policy.h" |
| 29 #include "testing/gtest/include/gtest/gtest.h" | 27 #include "testing/gtest/include/gtest/gtest.h" |
| 30 #include "url/origin.h" | 28 #include "url/origin.h" |
| 31 | 29 |
| 32 using url::Origin; | 30 using url::Origin; |
| 33 | 31 |
| 34 namespace content { | 32 namespace content { |
| 35 | 33 |
| 36 class IndexedDBTest : public testing::Test { | 34 class IndexedDBTest : public testing::Test { |
| 37 public: | 35 public: |
| 38 const Origin kNormalOrigin; | 36 const Origin kNormalOrigin; |
| 39 const Origin kSessionOnlyOrigin; | 37 const Origin kSessionOnlyOrigin; |
| 40 | 38 |
| 41 IndexedDBTest() | 39 IndexedDBTest() |
| 42 : kNormalOrigin(GURL("http://normal/")), | 40 : kNormalOrigin(GURL("http://normal/")), |
| 43 kSessionOnlyOrigin(GURL("http://session-only/")), | 41 kSessionOnlyOrigin(GURL("http://session-only/")), |
| 44 task_runner_(new base::TestSimpleTaskRunner), | 42 special_storage_policy_( |
| 45 special_storage_policy_(new MockSpecialStoragePolicy), | 43 base::MakeRefCounted<MockSpecialStoragePolicy>()), |
| 46 quota_manager_proxy_(new MockQuotaManagerProxy(nullptr, nullptr)) { | 44 quota_manager_proxy_( |
| 45 base::MakeRefCounted<MockQuotaManagerProxy>(nullptr, nullptr)) { |
| 47 special_storage_policy_->AddSessionOnly(kSessionOnlyOrigin.GetURL()); | 46 special_storage_policy_->AddSessionOnly(kSessionOnlyOrigin.GetURL()); |
| 48 } | 47 } |
| 49 ~IndexedDBTest() override { | 48 ~IndexedDBTest() override { |
| 50 quota_manager_proxy_->SimulateQuotaManagerDestroyed(); | 49 quota_manager_proxy_->SimulateQuotaManagerDestroyed(); |
| 51 } | 50 } |
| 52 | 51 |
| 53 protected: | 52 protected: |
| 54 void FlushIndexedDBTaskRunner() { task_runner_->RunUntilIdle(); } | |
| 55 | |
| 56 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; | |
| 57 scoped_refptr<MockSpecialStoragePolicy> special_storage_policy_; | 53 scoped_refptr<MockSpecialStoragePolicy> special_storage_policy_; |
| 58 scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_; | 54 scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_; |
| 59 | 55 |
| 60 private: | 56 private: |
| 61 TestBrowserThreadBundle thread_bundle_; | 57 TestBrowserThreadBundle thread_bundle_; |
| 62 | 58 |
| 63 DISALLOW_COPY_AND_ASSIGN(IndexedDBTest); | 59 DISALLOW_COPY_AND_ASSIGN(IndexedDBTest); |
| 64 }; | 60 }; |
| 65 | 61 |
| 66 TEST_F(IndexedDBTest, ClearSessionOnlyDatabases) { | 62 TEST_F(IndexedDBTest, ClearSessionOnlyDatabases) { |
| 67 base::ScopedTempDir temp_dir; | 63 base::ScopedTempDir temp_dir; |
| 68 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 64 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 69 | 65 |
| 70 base::FilePath normal_path; | 66 base::FilePath normal_path; |
| 71 base::FilePath session_only_path; | 67 base::FilePath session_only_path; |
| 72 | 68 |
| 73 // Create the scope which will ensure we run the destructor of the context | 69 // Create the scope which will ensure we run the destructor of the context |
| 74 // which should trigger the clean up. | 70 // which should trigger the clean up. |
| 75 { | 71 { |
| 76 scoped_refptr<IndexedDBContextImpl> idb_context = new IndexedDBContextImpl( | 72 scoped_refptr<IndexedDBContextImpl> idb_context = |
| 77 temp_dir.GetPath(), special_storage_policy_.get(), | 73 base::MakeRefCounted<IndexedDBContextImpl>( |
| 78 quota_manager_proxy_.get(), task_runner_.get()); | 74 temp_dir.GetPath(), special_storage_policy_.get(), |
| 75 quota_manager_proxy_.get()); |
| 79 | 76 |
| 80 normal_path = idb_context->GetFilePathForTesting(kNormalOrigin); | 77 normal_path = idb_context->GetFilePathForTesting(kNormalOrigin); |
| 81 session_only_path = idb_context->GetFilePathForTesting(kSessionOnlyOrigin); | 78 session_only_path = idb_context->GetFilePathForTesting(kSessionOnlyOrigin); |
| 82 ASSERT_TRUE(base::CreateDirectory(normal_path)); | 79 ASSERT_TRUE(base::CreateDirectory(normal_path)); |
| 83 ASSERT_TRUE(base::CreateDirectory(session_only_path)); | 80 ASSERT_TRUE(base::CreateDirectory(session_only_path)); |
| 84 FlushIndexedDBTaskRunner(); | 81 RunAllBlockingPoolTasksUntilIdle(); |
| 85 base::RunLoop().RunUntilIdle(); | |
| 86 quota_manager_proxy_->SimulateQuotaManagerDestroyed(); | 82 quota_manager_proxy_->SimulateQuotaManagerDestroyed(); |
| 87 } | 83 } |
| 88 | 84 |
| 89 FlushIndexedDBTaskRunner(); | 85 RunAllBlockingPoolTasksUntilIdle(); |
| 90 base::RunLoop().RunUntilIdle(); | |
| 91 | 86 |
| 92 EXPECT_TRUE(base::DirectoryExists(normal_path)); | 87 EXPECT_TRUE(base::DirectoryExists(normal_path)); |
| 93 EXPECT_FALSE(base::DirectoryExists(session_only_path)); | 88 EXPECT_FALSE(base::DirectoryExists(session_only_path)); |
| 94 } | 89 } |
| 95 | 90 |
| 96 TEST_F(IndexedDBTest, SetForceKeepSessionState) { | 91 TEST_F(IndexedDBTest, SetForceKeepSessionState) { |
| 97 base::ScopedTempDir temp_dir; | 92 base::ScopedTempDir temp_dir; |
| 98 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 93 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 99 | 94 |
| 100 base::FilePath normal_path; | 95 base::FilePath normal_path; |
| 101 base::FilePath session_only_path; | 96 base::FilePath session_only_path; |
| 102 | 97 |
| 103 // Create the scope which will ensure we run the destructor of the context. | 98 // Create the scope which will ensure we run the destructor of the context. |
| 104 { | 99 { |
| 105 // Create some indexedDB paths. | 100 // Create some indexedDB paths. |
| 106 // With the levelDB backend, these are directories. | 101 // With the levelDB backend, these are directories. |
| 107 scoped_refptr<IndexedDBContextImpl> idb_context = new IndexedDBContextImpl( | 102 scoped_refptr<IndexedDBContextImpl> idb_context = |
| 108 temp_dir.GetPath(), special_storage_policy_.get(), | 103 base::MakeRefCounted<IndexedDBContextImpl>( |
| 109 quota_manager_proxy_.get(), task_runner_.get()); | 104 temp_dir.GetPath(), special_storage_policy_.get(), |
| 105 quota_manager_proxy_.get()); |
| 110 | 106 |
| 111 // Save session state. This should bypass the destruction-time deletion. | 107 // Save session state. This should bypass the destruction-time deletion. |
| 112 idb_context->SetForceKeepSessionState(); | 108 idb_context->SetForceKeepSessionState(); |
| 113 | 109 |
| 114 normal_path = idb_context->GetFilePathForTesting(kNormalOrigin); | 110 normal_path = idb_context->GetFilePathForTesting(kNormalOrigin); |
| 115 session_only_path = idb_context->GetFilePathForTesting(kSessionOnlyOrigin); | 111 session_only_path = idb_context->GetFilePathForTesting(kSessionOnlyOrigin); |
| 116 ASSERT_TRUE(base::CreateDirectory(normal_path)); | 112 ASSERT_TRUE(base::CreateDirectory(normal_path)); |
| 117 ASSERT_TRUE(base::CreateDirectory(session_only_path)); | 113 ASSERT_TRUE(base::CreateDirectory(session_only_path)); |
| 118 base::RunLoop().RunUntilIdle(); | 114 base::RunLoop().RunUntilIdle(); |
| 119 } | 115 } |
| 120 | 116 |
| 121 // Make sure we wait until the destructor has run. | 117 // Make sure we wait until the destructor has run. |
| 122 base::RunLoop().RunUntilIdle(); | 118 base::RunLoop().RunUntilIdle(); |
| 123 | 119 |
| 124 // No data was cleared because of SetForceKeepSessionState. | 120 // No data was cleared because of SetForceKeepSessionState. |
| 125 EXPECT_TRUE(base::DirectoryExists(normal_path)); | 121 EXPECT_TRUE(base::DirectoryExists(normal_path)); |
| 126 EXPECT_TRUE(base::DirectoryExists(session_only_path)); | 122 EXPECT_TRUE(base::DirectoryExists(session_only_path)); |
| 127 } | 123 } |
| 128 | 124 |
| 129 class ForceCloseDBCallbacks : public IndexedDBCallbacks { | 125 class ForceCloseDBCallbacks : public IndexedDBCallbacks { |
| 130 public: | 126 public: |
| 131 ForceCloseDBCallbacks(scoped_refptr<IndexedDBContextImpl> idb_context, | 127 ForceCloseDBCallbacks(scoped_refptr<IndexedDBContextImpl> idb_context, |
| 132 const Origin& origin) | 128 const Origin& origin) |
| 133 : IndexedDBCallbacks(nullptr, | 129 : IndexedDBCallbacks(nullptr, origin, nullptr, idb_context->TaskRunner()), |
| 134 origin, | |
| 135 nullptr, | |
| 136 base::ThreadTaskRunnerHandle::Get()), | |
| 137 idb_context_(idb_context), | 130 idb_context_(idb_context), |
| 138 origin_(origin) {} | 131 origin_(origin) {} |
| 139 | 132 |
| 140 void OnSuccess() override {} | 133 void OnSuccess() override {} |
| 141 void OnSuccess(const std::vector<base::string16>&) override {} | 134 void OnSuccess(const std::vector<base::string16>&) override {} |
| 142 void OnSuccess(std::unique_ptr<IndexedDBConnection> connection, | 135 void OnSuccess(std::unique_ptr<IndexedDBConnection> connection, |
| 143 const IndexedDBDatabaseMetadata& metadata) override { | 136 const IndexedDBDatabaseMetadata& metadata) override { |
| 144 connection_ = std::move(connection); | 137 connection_ = std::move(connection); |
| 145 idb_context_->ConnectionOpened(origin_, connection_.get()); | 138 idb_context_->ConnectionOpened(origin_, connection_.get()); |
| 146 } | 139 } |
| 147 | 140 |
| 148 IndexedDBConnection* connection() { return connection_.get(); } | 141 IndexedDBConnection* connection() { return connection_.get(); } |
| 149 | 142 |
| 150 protected: | 143 protected: |
| 151 ~ForceCloseDBCallbacks() override {} | 144 ~ForceCloseDBCallbacks() override {} |
| 152 | 145 |
| 153 private: | 146 private: |
| 154 scoped_refptr<IndexedDBContextImpl> idb_context_; | 147 scoped_refptr<IndexedDBContextImpl> idb_context_; |
| 155 Origin origin_; | 148 Origin origin_; |
| 156 std::unique_ptr<IndexedDBConnection> connection_; | 149 std::unique_ptr<IndexedDBConnection> connection_; |
| 157 DISALLOW_COPY_AND_ASSIGN(ForceCloseDBCallbacks); | 150 DISALLOW_COPY_AND_ASSIGN(ForceCloseDBCallbacks); |
| 158 }; | 151 }; |
| 159 | 152 |
| 160 TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnDelete) { | 153 TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnDelete) { |
| 161 base::ScopedTempDir temp_dir; | 154 base::ScopedTempDir temp_dir; |
| 162 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 155 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 163 | 156 |
| 164 scoped_refptr<MockIndexedDBDatabaseCallbacks> open_db_callbacks( | 157 scoped_refptr<IndexedDBContextImpl> idb_context = |
| 165 new MockIndexedDBDatabaseCallbacks()); | 158 base::MakeRefCounted<IndexedDBContextImpl>(temp_dir.GetPath(), |
| 166 scoped_refptr<MockIndexedDBDatabaseCallbacks> closed_db_callbacks( | 159 special_storage_policy_.get(), |
| 167 new MockIndexedDBDatabaseCallbacks()); | 160 quota_manager_proxy_.get()); |
| 168 | 161 |
| 169 base::FilePath test_path; | 162 const Origin kTestOrigin(GURL("http://test/")); |
| 163 idb_context->TaskRunner()->PostTask( |
| 164 FROM_HERE, |
| 165 base::BindOnce( |
| 166 [](IndexedDBContextImpl* idb_context, |
| 167 scoped_refptr<MockIndexedDBDatabaseCallbacks> open_db_callbacks, |
| 168 scoped_refptr<MockIndexedDBDatabaseCallbacks> closed_db_callbacks, |
| 169 scoped_refptr<ForceCloseDBCallbacks> open_callbacks, |
| 170 scoped_refptr<ForceCloseDBCallbacks> closed_callbacks, |
| 171 const Origin& origin) { |
| 170 | 172 |
| 171 // Create the scope which will ensure we run the destructor of the context. | 173 const int child_process_id = 0; |
| 172 { | 174 const int64_t host_transaction_id = 0; |
| 173 TestBrowserContext browser_context; | 175 const int64_t version = 0; |
| 176 const scoped_refptr<net::URLRequestContextGetter> request_context; |
| 174 | 177 |
| 175 const Origin kTestOrigin(GURL("http://test/")); | 178 IndexedDBFactory* factory = idb_context->GetIDBFactory(); |
| 176 | 179 |
| 177 scoped_refptr<IndexedDBContextImpl> idb_context = new IndexedDBContextImpl( | 180 base::FilePath test_path = |
| 178 temp_dir.GetPath(), special_storage_policy_.get(), | 181 idb_context->GetFilePathForTesting(origin); |
| 179 quota_manager_proxy_.get(), task_runner_.get()); | |
| 180 | 182 |
| 181 scoped_refptr<ForceCloseDBCallbacks> open_callbacks = | 183 factory->Open(base::ASCIIToUTF16("opendb"), |
| 182 new ForceCloseDBCallbacks(idb_context, kTestOrigin); | 184 base::MakeUnique<IndexedDBPendingConnection>( |
| 185 open_callbacks, open_db_callbacks, |
| 186 child_process_id, host_transaction_id, version), |
| 187 request_context, origin, idb_context->data_path()); |
| 188 EXPECT_TRUE(base::DirectoryExists(test_path)); |
| 183 | 189 |
| 184 scoped_refptr<ForceCloseDBCallbacks> closed_callbacks = | 190 factory->Open(base::ASCIIToUTF16("closeddb"), |
| 185 new ForceCloseDBCallbacks(idb_context, kTestOrigin); | 191 base::MakeUnique<IndexedDBPendingConnection>( |
| 192 closed_callbacks, closed_db_callbacks, |
| 193 child_process_id, host_transaction_id, version), |
| 194 request_context, origin, idb_context->data_path()); |
| 186 | 195 |
| 187 IndexedDBFactory* factory = idb_context->GetIDBFactory(); | 196 closed_callbacks->connection()->Close(); |
| 188 | 197 |
| 189 test_path = idb_context->GetFilePathForTesting(kTestOrigin); | 198 idb_context->DeleteForOrigin(origin); |
| 190 | 199 |
| 191 std::unique_ptr<IndexedDBPendingConnection> open_connection( | 200 EXPECT_TRUE(open_db_callbacks->forced_close_called()); |
| 192 base::MakeUnique<IndexedDBPendingConnection>( | 201 EXPECT_FALSE(closed_db_callbacks->forced_close_called()); |
| 193 open_callbacks, open_db_callbacks, 0 /* child_process_id */, | 202 EXPECT_FALSE(base::DirectoryExists(test_path)); |
| 194 0 /* host_transaction_id */, 0 /* version */)); | 203 }, |
| 195 factory->Open(base::ASCIIToUTF16("opendb"), std::move(open_connection), | 204 base::Unretained(idb_context.get()), |
| 196 nullptr /* request_context */, Origin(kTestOrigin), | 205 base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>(), |
| 197 idb_context->data_path()); | 206 base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>(), |
| 198 std::unique_ptr<IndexedDBPendingConnection> closed_connection( | 207 base::MakeRefCounted<ForceCloseDBCallbacks>(idb_context, kTestOrigin), |
| 199 base::MakeUnique<IndexedDBPendingConnection>( | 208 base::MakeRefCounted<ForceCloseDBCallbacks>(idb_context, kTestOrigin), |
| 200 closed_callbacks, closed_db_callbacks, 0 /* child_process_id */, | 209 kTestOrigin)); |
| 201 0 /* host_transaction_id */, 0 /* version */)); | 210 RunAllBlockingPoolTasksUntilIdle(); |
| 202 factory->Open(base::ASCIIToUTF16("closeddb"), std::move(closed_connection), | |
| 203 nullptr /* request_context */, Origin(kTestOrigin), | |
| 204 idb_context->data_path()); | |
| 205 | |
| 206 closed_callbacks->connection()->Close(); | |
| 207 | |
| 208 // TODO(jsbell): Remove static_cast<> when overloads are eliminated. | |
| 209 idb_context->TaskRunner()->PostTask( | |
| 210 FROM_HERE, | |
| 211 base::BindOnce( | |
| 212 static_cast<void (IndexedDBContextImpl::*)(const Origin&)>( | |
| 213 &IndexedDBContextImpl::DeleteForOrigin), | |
| 214 idb_context, kTestOrigin)); | |
| 215 FlushIndexedDBTaskRunner(); | |
| 216 base::RunLoop().RunUntilIdle(); | |
| 217 } | |
| 218 | |
| 219 // Make sure we wait until the destructor has run. | |
| 220 base::RunLoop().RunUntilIdle(); | |
| 221 | |
| 222 EXPECT_TRUE(open_db_callbacks->forced_close_called()); | |
| 223 EXPECT_FALSE(closed_db_callbacks->forced_close_called()); | |
| 224 EXPECT_FALSE(base::DirectoryExists(test_path)); | |
| 225 } | 211 } |
| 226 | 212 |
| 227 TEST_F(IndexedDBTest, DeleteFailsIfDirectoryLocked) { | 213 TEST_F(IndexedDBTest, DeleteFailsIfDirectoryLocked) { |
| 228 base::ScopedTempDir temp_dir; | 214 base::ScopedTempDir temp_dir; |
| 229 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 215 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 230 const Origin kTestOrigin(GURL("http://test/")); | 216 const Origin kTestOrigin(GURL("http://test/")); |
| 231 | 217 |
| 232 scoped_refptr<IndexedDBContextImpl> idb_context = new IndexedDBContextImpl( | 218 scoped_refptr<IndexedDBContextImpl> idb_context = |
| 233 temp_dir.GetPath(), special_storage_policy_.get(), | 219 base::MakeRefCounted<IndexedDBContextImpl>(temp_dir.GetPath(), |
| 234 quota_manager_proxy_.get(), task_runner_.get()); | 220 special_storage_policy_.get(), |
| 221 quota_manager_proxy_.get()); |
| 235 | 222 |
| 236 base::FilePath test_path = idb_context->GetFilePathForTesting(kTestOrigin); | 223 base::FilePath test_path = idb_context->GetFilePathForTesting(kTestOrigin); |
| 237 ASSERT_TRUE(base::CreateDirectory(test_path)); | 224 ASSERT_TRUE(base::CreateDirectory(test_path)); |
| 238 | 225 |
| 239 std::unique_ptr<LevelDBLock> lock = | 226 std::unique_ptr<LevelDBLock> lock = |
| 240 LevelDBDatabase::LockForTesting(test_path); | 227 LevelDBDatabase::LockForTesting(test_path); |
| 241 ASSERT_TRUE(lock); | 228 ASSERT_TRUE(lock); |
| 242 | 229 |
| 243 // TODO(jsbell): Remove static_cast<> when overloads are eliminated. | 230 // TODO(jsbell): Remove static_cast<> when overloads are eliminated. |
| 244 void (IndexedDBContextImpl::* delete_for_origin)(const Origin&) = | 231 void (IndexedDBContextImpl::* delete_for_origin)(const Origin&) = |
| 245 &IndexedDBContextImpl::DeleteForOrigin; | 232 &IndexedDBContextImpl::DeleteForOrigin; |
| 246 idb_context->TaskRunner()->PostTask( | 233 idb_context->TaskRunner()->PostTask( |
| 247 FROM_HERE, base::BindOnce(delete_for_origin, idb_context, kTestOrigin)); | 234 FROM_HERE, base::BindOnce(delete_for_origin, idb_context, kTestOrigin)); |
| 248 FlushIndexedDBTaskRunner(); | 235 RunAllBlockingPoolTasksUntilIdle(); |
| 249 | 236 |
| 250 EXPECT_TRUE(base::DirectoryExists(test_path)); | 237 EXPECT_TRUE(base::DirectoryExists(test_path)); |
| 251 } | 238 } |
| 252 | 239 |
| 253 TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnCommitFailure) { | 240 TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnCommitFailure) { |
| 254 const Origin kTestOrigin(GURL("http://test/")); | |
| 255 | |
| 256 base::ScopedTempDir temp_dir; | 241 base::ScopedTempDir temp_dir; |
| 257 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 242 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 258 | 243 |
| 259 scoped_refptr<IndexedDBContextImpl> context = new IndexedDBContextImpl( | 244 scoped_refptr<IndexedDBContextImpl> idb_context = |
| 260 temp_dir.GetPath(), special_storage_policy_.get(), | 245 base::MakeRefCounted<IndexedDBContextImpl>(temp_dir.GetPath(), |
| 261 quota_manager_proxy_.get(), task_runner_.get()); | 246 special_storage_policy_.get(), |
| 247 quota_manager_proxy_.get()); |
| 262 | 248 |
| 263 scoped_refptr<IndexedDBFactoryImpl> factory = | 249 idb_context->TaskRunner()->PostTask( |
| 264 static_cast<IndexedDBFactoryImpl*>(context->GetIDBFactory()); | 250 FROM_HERE, |
| 251 base::BindOnce( |
| 252 [](IndexedDBContextImpl* idb_context, const base::FilePath temp_path, |
| 253 scoped_refptr<MockIndexedDBCallbacks> callbacks, |
| 254 scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks) { |
| 255 const Origin kTestOrigin(GURL("http://test/")); |
| 265 | 256 |
| 266 scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks()); | 257 scoped_refptr<IndexedDBFactoryImpl> factory = |
| 267 scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks( | 258 static_cast<IndexedDBFactoryImpl*>( |
| 268 new MockIndexedDBDatabaseCallbacks()); | 259 idb_context->GetIDBFactory()); |
| 269 const int64_t transaction_id = 1; | |
| 270 std::unique_ptr<IndexedDBPendingConnection> connection( | |
| 271 base::MakeUnique<IndexedDBPendingConnection>( | |
| 272 callbacks, db_callbacks, 0 /* child_process_id */, transaction_id, | |
| 273 IndexedDBDatabaseMetadata::DEFAULT_VERSION)); | |
| 274 factory->Open(base::ASCIIToUTF16("db"), std::move(connection), | |
| 275 nullptr /* request_context */, Origin(kTestOrigin), | |
| 276 temp_dir.GetPath()); | |
| 277 | 260 |
| 278 EXPECT_TRUE(callbacks->connection()); | 261 const int child_process_id = 0; |
| 262 const int64_t transaction_id = 1; |
| 263 const scoped_refptr<net::URLRequestContextGetter> request_context; |
| 279 | 264 |
| 280 // ConnectionOpened() is usually called by the dispatcher. | 265 std::unique_ptr<IndexedDBPendingConnection> connection( |
| 281 context->ConnectionOpened(kTestOrigin, callbacks->connection()); | 266 base::MakeUnique<IndexedDBPendingConnection>( |
| 267 callbacks, db_callbacks, child_process_id, transaction_id, |
| 268 IndexedDBDatabaseMetadata::DEFAULT_VERSION)); |
| 269 factory->Open(base::ASCIIToUTF16("db"), std::move(connection), |
| 270 request_context, Origin(kTestOrigin), temp_path); |
| 282 | 271 |
| 283 EXPECT_TRUE(factory->IsBackingStoreOpen(kTestOrigin)); | 272 EXPECT_TRUE(callbacks->connection()); |
| 284 | 273 |
| 285 // Simulate the write failure. | 274 // ConnectionOpened() is usually called by the dispatcher. |
| 286 leveldb::Status status = leveldb::Status::IOError("Simulated failure"); | 275 idb_context->ConnectionOpened(kTestOrigin, callbacks->connection()); |
| 287 context->GetIDBFactory()->HandleBackingStoreFailure(kTestOrigin); | |
| 288 | 276 |
| 289 EXPECT_TRUE(db_callbacks->forced_close_called()); | 277 EXPECT_TRUE(factory->IsBackingStoreOpen(kTestOrigin)); |
| 290 EXPECT_FALSE(factory->IsBackingStoreOpen(kTestOrigin)); | 278 |
| 279 // Simulate the write failure. |
| 280 leveldb::Status status = |
| 281 leveldb::Status::IOError("Simulated failure"); |
| 282 idb_context->GetIDBFactory()->HandleBackingStoreFailure( |
| 283 kTestOrigin); |
| 284 |
| 285 EXPECT_TRUE(db_callbacks->forced_close_called()); |
| 286 EXPECT_FALSE(factory->IsBackingStoreOpen(kTestOrigin)); |
| 287 }, |
| 288 base::Unretained(idb_context.get()), temp_dir.GetPath(), |
| 289 |
| 290 base::MakeRefCounted<MockIndexedDBCallbacks>(), |
| 291 base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>())); |
| 292 RunAllBlockingPoolTasksUntilIdle(); |
| 291 } | 293 } |
| 292 | 294 |
| 293 } // namespace content | 295 } // namespace content |
| OLD | NEW |