| 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/test/test_simple_task_runner.h" | 11 #include "base/test/test_simple_task_runner.h" |
| 12 #include "base/threading/thread.h" | 12 #include "base/threading/thread.h" |
| 13 #include "content/browser/browser_thread_impl.h" | 13 #include "content/browser/browser_thread_impl.h" |
| 14 #include "content/browser/indexed_db/indexed_db_connection.h" | 14 #include "content/browser/indexed_db/indexed_db_connection.h" |
| 15 #include "content/browser/indexed_db/indexed_db_context_impl.h" | 15 #include "content/browser/indexed_db/indexed_db_context_impl.h" |
| 16 #include "content/browser/indexed_db/indexed_db_factory_impl.h" | 16 #include "content/browser/indexed_db/indexed_db_factory_impl.h" |
| 17 #include "content/browser/indexed_db/mock_indexed_db_callbacks.h" | 17 #include "content/browser/indexed_db/mock_indexed_db_callbacks.h" |
| 18 #include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h" | 18 #include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h" |
| 19 #include "content/browser/quota/mock_quota_manager_proxy.h" | 19 #include "content/browser/quota/mock_quota_manager_proxy.h" |
| 20 #include "content/public/browser/storage_partition.h" | 20 #include "content/public/browser/storage_partition.h" |
| 21 #include "content/public/common/url_constants.h" | 21 #include "content/public/common/url_constants.h" |
| 22 #include "content/public/test/mock_special_storage_policy.h" | 22 #include "content/public/test/mock_special_storage_policy.h" |
| 23 #include "content/public/test/test_browser_context.h" | 23 #include "content/public/test/test_browser_context.h" |
| 24 #include "storage/browser/quota/quota_manager.h" | 24 #include "storage/browser/quota/quota_manager.h" |
| 25 #include "storage/browser/quota/special_storage_policy.h" | 25 #include "storage/browser/quota/special_storage_policy.h" |
| 26 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
| 27 #include "url/origin.h" | 27 #include "url/origin.h" |
| 28 | 28 |
| 29 using url::Origin; |
| 30 |
| 29 namespace content { | 31 namespace content { |
| 30 | 32 |
| 31 class IndexedDBTest : public testing::Test { | 33 class IndexedDBTest : public testing::Test { |
| 32 public: | 34 public: |
| 33 const GURL kNormalOrigin; | 35 const Origin kNormalOrigin; |
| 34 const GURL kSessionOnlyOrigin; | 36 const Origin kSessionOnlyOrigin; |
| 35 | 37 |
| 36 IndexedDBTest() | 38 IndexedDBTest() |
| 37 : kNormalOrigin("http://normal/"), | 39 : kNormalOrigin(GURL("http://normal/")), |
| 38 kSessionOnlyOrigin("http://session-only/"), | 40 kSessionOnlyOrigin(GURL("http://session-only/")), |
| 39 task_runner_(new base::TestSimpleTaskRunner), | 41 task_runner_(new base::TestSimpleTaskRunner), |
| 40 special_storage_policy_(new MockSpecialStoragePolicy), | 42 special_storage_policy_(new MockSpecialStoragePolicy), |
| 41 quota_manager_proxy_(new MockQuotaManagerProxy(nullptr, nullptr)), | 43 quota_manager_proxy_(new MockQuotaManagerProxy(nullptr, nullptr)), |
| 42 file_thread_(BrowserThread::FILE_USER_BLOCKING, &message_loop_), | 44 file_thread_(BrowserThread::FILE_USER_BLOCKING, &message_loop_), |
| 43 io_thread_(BrowserThread::IO, &message_loop_) { | 45 io_thread_(BrowserThread::IO, &message_loop_) { |
| 44 special_storage_policy_->AddSessionOnly(kSessionOnlyOrigin); | 46 special_storage_policy_->AddSessionOnly( |
| 47 GURL(kSessionOnlyOrigin.Serialize())); |
| 45 } | 48 } |
| 46 ~IndexedDBTest() override { | 49 ~IndexedDBTest() override { |
| 47 quota_manager_proxy_->SimulateQuotaManagerDestroyed(); | 50 quota_manager_proxy_->SimulateQuotaManagerDestroyed(); |
| 48 } | 51 } |
| 49 | 52 |
| 50 protected: | 53 protected: |
| 51 void FlushIndexedDBTaskRunner() { task_runner_->RunUntilIdle(); } | 54 void FlushIndexedDBTaskRunner() { task_runner_->RunUntilIdle(); } |
| 52 | 55 |
| 53 base::MessageLoopForIO message_loop_; | 56 base::MessageLoopForIO message_loop_; |
| 54 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; | 57 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 message_loop_.RunUntilIdle(); | 128 message_loop_.RunUntilIdle(); |
| 126 | 129 |
| 127 // No data was cleared because of SetForceKeepSessionState. | 130 // No data was cleared because of SetForceKeepSessionState. |
| 128 EXPECT_TRUE(base::DirectoryExists(normal_path)); | 131 EXPECT_TRUE(base::DirectoryExists(normal_path)); |
| 129 EXPECT_TRUE(base::DirectoryExists(session_only_path)); | 132 EXPECT_TRUE(base::DirectoryExists(session_only_path)); |
| 130 } | 133 } |
| 131 | 134 |
| 132 class ForceCloseDBCallbacks : public IndexedDBCallbacks { | 135 class ForceCloseDBCallbacks : public IndexedDBCallbacks { |
| 133 public: | 136 public: |
| 134 ForceCloseDBCallbacks(scoped_refptr<IndexedDBContextImpl> idb_context, | 137 ForceCloseDBCallbacks(scoped_refptr<IndexedDBContextImpl> idb_context, |
| 135 const GURL& origin_url) | 138 const Origin& origin) |
| 136 : IndexedDBCallbacks(NULL, 0, 0), | 139 : IndexedDBCallbacks(NULL, 0, 0), |
| 137 idb_context_(idb_context), | 140 idb_context_(idb_context), |
| 138 origin_url_(origin_url) {} | 141 origin_(origin) {} |
| 139 | 142 |
| 140 void OnSuccess() override {} | 143 void OnSuccess() override {} |
| 141 void OnSuccess(const std::vector<base::string16>&) override {} | 144 void OnSuccess(const std::vector<base::string16>&) override {} |
| 142 void OnSuccess(std::unique_ptr<IndexedDBConnection> connection, | 145 void OnSuccess(std::unique_ptr<IndexedDBConnection> connection, |
| 143 const IndexedDBDatabaseMetadata& metadata) override { | 146 const IndexedDBDatabaseMetadata& metadata) override { |
| 144 connection_ = std::move(connection); | 147 connection_ = std::move(connection); |
| 145 idb_context_->ConnectionOpened(origin_url_, connection_.get()); | 148 idb_context_->ConnectionOpened(origin_, connection_.get()); |
| 146 } | 149 } |
| 147 | 150 |
| 148 IndexedDBConnection* connection() { return connection_.get(); } | 151 IndexedDBConnection* connection() { return connection_.get(); } |
| 149 | 152 |
| 150 protected: | 153 protected: |
| 151 ~ForceCloseDBCallbacks() override {} | 154 ~ForceCloseDBCallbacks() override {} |
| 152 | 155 |
| 153 private: | 156 private: |
| 154 scoped_refptr<IndexedDBContextImpl> idb_context_; | 157 scoped_refptr<IndexedDBContextImpl> idb_context_; |
| 155 GURL origin_url_; | 158 Origin origin_; |
| 156 std::unique_ptr<IndexedDBConnection> connection_; | 159 std::unique_ptr<IndexedDBConnection> connection_; |
| 157 DISALLOW_COPY_AND_ASSIGN(ForceCloseDBCallbacks); | 160 DISALLOW_COPY_AND_ASSIGN(ForceCloseDBCallbacks); |
| 158 }; | 161 }; |
| 159 | 162 |
| 160 TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnDelete) { | 163 TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnDelete) { |
| 161 base::ScopedTempDir temp_dir; | 164 base::ScopedTempDir temp_dir; |
| 162 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 165 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 163 | 166 |
| 164 scoped_refptr<MockIndexedDBDatabaseCallbacks> open_db_callbacks( | 167 scoped_refptr<MockIndexedDBDatabaseCallbacks> open_db_callbacks( |
| 165 new MockIndexedDBDatabaseCallbacks()); | 168 new MockIndexedDBDatabaseCallbacks()); |
| 166 scoped_refptr<MockIndexedDBDatabaseCallbacks> closed_db_callbacks( | 169 scoped_refptr<MockIndexedDBDatabaseCallbacks> closed_db_callbacks( |
| 167 new MockIndexedDBDatabaseCallbacks()); | 170 new MockIndexedDBDatabaseCallbacks()); |
| 168 | 171 |
| 169 base::FilePath test_path; | 172 base::FilePath test_path; |
| 170 | 173 |
| 171 // Create the scope which will ensure we run the destructor of the context. | 174 // Create the scope which will ensure we run the destructor of the context. |
| 172 { | 175 { |
| 173 TestBrowserContext browser_context; | 176 TestBrowserContext browser_context; |
| 174 | 177 |
| 175 const GURL kTestOrigin("http://test/"); | 178 const Origin kTestOrigin(GURL("http://test/")); |
| 176 | 179 |
| 177 scoped_refptr<IndexedDBContextImpl> idb_context = | 180 scoped_refptr<IndexedDBContextImpl> idb_context = |
| 178 new IndexedDBContextImpl(temp_dir.path(), | 181 new IndexedDBContextImpl(temp_dir.path(), |
| 179 special_storage_policy_.get(), | 182 special_storage_policy_.get(), |
| 180 quota_manager_proxy_.get(), | 183 quota_manager_proxy_.get(), |
| 181 task_runner_.get()); | 184 task_runner_.get()); |
| 182 | 185 |
| 183 scoped_refptr<ForceCloseDBCallbacks> open_callbacks = | 186 scoped_refptr<ForceCloseDBCallbacks> open_callbacks = |
| 184 new ForceCloseDBCallbacks(idb_context, kTestOrigin); | 187 new ForceCloseDBCallbacks(idb_context, kTestOrigin); |
| 185 | 188 |
| 186 scoped_refptr<ForceCloseDBCallbacks> closed_callbacks = | 189 scoped_refptr<ForceCloseDBCallbacks> closed_callbacks = |
| 187 new ForceCloseDBCallbacks(idb_context, kTestOrigin); | 190 new ForceCloseDBCallbacks(idb_context, kTestOrigin); |
| 188 | 191 |
| 189 IndexedDBFactory* factory = idb_context->GetIDBFactory(); | 192 IndexedDBFactory* factory = idb_context->GetIDBFactory(); |
| 190 | 193 |
| 191 test_path = idb_context->GetFilePathForTesting(kTestOrigin); | 194 test_path = idb_context->GetFilePathForTesting(kTestOrigin); |
| 192 | 195 |
| 193 IndexedDBPendingConnection open_connection(open_callbacks, | 196 IndexedDBPendingConnection open_connection(open_callbacks, |
| 194 open_db_callbacks, | 197 open_db_callbacks, |
| 195 0 /* child_process_id */, | 198 0 /* child_process_id */, |
| 196 0 /* host_transaction_id */, | 199 0 /* host_transaction_id */, |
| 197 0 /* version */); | 200 0 /* version */); |
| 198 factory->Open(base::ASCIIToUTF16("opendb"), open_connection, | 201 factory->Open(base::ASCIIToUTF16("opendb"), open_connection, |
| 199 NULL /* request_context */, url::Origin(kTestOrigin), | 202 NULL /* request_context */, Origin(kTestOrigin), |
| 200 idb_context->data_path()); | 203 idb_context->data_path()); |
| 201 IndexedDBPendingConnection closed_connection(closed_callbacks, | 204 IndexedDBPendingConnection closed_connection(closed_callbacks, |
| 202 closed_db_callbacks, | 205 closed_db_callbacks, |
| 203 0 /* child_process_id */, | 206 0 /* child_process_id */, |
| 204 0 /* host_transaction_id */, | 207 0 /* host_transaction_id */, |
| 205 0 /* version */); | 208 0 /* version */); |
| 206 factory->Open(base::ASCIIToUTF16("closeddb"), closed_connection, | 209 factory->Open(base::ASCIIToUTF16("closeddb"), closed_connection, |
| 207 NULL /* request_context */, url::Origin(kTestOrigin), | 210 NULL /* request_context */, Origin(kTestOrigin), |
| 208 idb_context->data_path()); | 211 idb_context->data_path()); |
| 209 | 212 |
| 210 closed_callbacks->connection()->Close(); | 213 closed_callbacks->connection()->Close(); |
| 211 | 214 |
| 215 // TODO(jsbell): Remove static_cast<> when overloads are eliminated. |
| 212 idb_context->TaskRunner()->PostTask( | 216 idb_context->TaskRunner()->PostTask( |
| 213 FROM_HERE, | 217 FROM_HERE, |
| 214 base::Bind( | 218 base::Bind(static_cast<void (IndexedDBContextImpl::*)(const Origin&)>( |
| 215 &IndexedDBContextImpl::DeleteForOrigin, idb_context, kTestOrigin)); | 219 &IndexedDBContextImpl::DeleteForOrigin), |
| 220 idb_context, kTestOrigin)); |
| 216 FlushIndexedDBTaskRunner(); | 221 FlushIndexedDBTaskRunner(); |
| 217 message_loop_.RunUntilIdle(); | 222 message_loop_.RunUntilIdle(); |
| 218 } | 223 } |
| 219 | 224 |
| 220 // Make sure we wait until the destructor has run. | 225 // Make sure we wait until the destructor has run. |
| 221 message_loop_.RunUntilIdle(); | 226 message_loop_.RunUntilIdle(); |
| 222 | 227 |
| 223 EXPECT_TRUE(open_db_callbacks->forced_close_called()); | 228 EXPECT_TRUE(open_db_callbacks->forced_close_called()); |
| 224 EXPECT_FALSE(closed_db_callbacks->forced_close_called()); | 229 EXPECT_FALSE(closed_db_callbacks->forced_close_called()); |
| 225 EXPECT_FALSE(base::DirectoryExists(test_path)); | 230 EXPECT_FALSE(base::DirectoryExists(test_path)); |
| 226 } | 231 } |
| 227 | 232 |
| 228 TEST_F(IndexedDBTest, DeleteFailsIfDirectoryLocked) { | 233 TEST_F(IndexedDBTest, DeleteFailsIfDirectoryLocked) { |
| 229 base::ScopedTempDir temp_dir; | 234 base::ScopedTempDir temp_dir; |
| 230 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 235 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 231 const GURL kTestOrigin("http://test/"); | 236 const Origin kTestOrigin(GURL("http://test/")); |
| 232 | 237 |
| 233 scoped_refptr<IndexedDBContextImpl> idb_context = new IndexedDBContextImpl( | 238 scoped_refptr<IndexedDBContextImpl> idb_context = new IndexedDBContextImpl( |
| 234 temp_dir.path(), special_storage_policy_.get(), | 239 temp_dir.path(), special_storage_policy_.get(), |
| 235 quota_manager_proxy_.get(), task_runner_.get()); | 240 quota_manager_proxy_.get(), task_runner_.get()); |
| 236 | 241 |
| 237 base::FilePath test_path = idb_context->GetFilePathForTesting(kTestOrigin); | 242 base::FilePath test_path = idb_context->GetFilePathForTesting(kTestOrigin); |
| 238 ASSERT_TRUE(base::CreateDirectory(test_path)); | 243 ASSERT_TRUE(base::CreateDirectory(test_path)); |
| 239 | 244 |
| 240 std::unique_ptr<LevelDBLock> lock = | 245 std::unique_ptr<LevelDBLock> lock = |
| 241 LevelDBDatabase::LockForTesting(test_path); | 246 LevelDBDatabase::LockForTesting(test_path); |
| 242 ASSERT_TRUE(lock); | 247 ASSERT_TRUE(lock); |
| 243 | 248 |
| 249 // TODO(jsbell): Remove static_cast<> when overloads are eliminated. |
| 244 idb_context->TaskRunner()->PostTask( | 250 idb_context->TaskRunner()->PostTask( |
| 245 FROM_HERE, | 251 FROM_HERE, |
| 246 base::Bind( | 252 base::Bind(static_cast<void (IndexedDBContextImpl::*)(const Origin&)>( |
| 247 &IndexedDBContextImpl::DeleteForOrigin, idb_context, kTestOrigin)); | 253 &IndexedDBContextImpl::DeleteForOrigin), |
| 254 idb_context, kTestOrigin)); |
| 248 FlushIndexedDBTaskRunner(); | 255 FlushIndexedDBTaskRunner(); |
| 249 | 256 |
| 250 EXPECT_TRUE(base::DirectoryExists(test_path)); | 257 EXPECT_TRUE(base::DirectoryExists(test_path)); |
| 251 } | 258 } |
| 252 | 259 |
| 253 TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnCommitFailure) { | 260 TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnCommitFailure) { |
| 254 const GURL kTestOrigin("http://test/"); | 261 const Origin kTestOrigin(GURL("http://test/")); |
| 255 | 262 |
| 256 base::ScopedTempDir temp_dir; | 263 base::ScopedTempDir temp_dir; |
| 257 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 264 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 258 | 265 |
| 259 scoped_refptr<IndexedDBContextImpl> context = | 266 scoped_refptr<IndexedDBContextImpl> context = |
| 260 new IndexedDBContextImpl(temp_dir.path(), special_storage_policy_.get(), | 267 new IndexedDBContextImpl(temp_dir.path(), special_storage_policy_.get(), |
| 261 quota_manager_proxy_.get(), task_runner_.get()); | 268 quota_manager_proxy_.get(), task_runner_.get()); |
| 262 | 269 |
| 263 scoped_refptr<IndexedDBFactoryImpl> factory = | 270 scoped_refptr<IndexedDBFactoryImpl> factory = |
| 264 static_cast<IndexedDBFactoryImpl*>(context->GetIDBFactory()); | 271 static_cast<IndexedDBFactoryImpl*>(context->GetIDBFactory()); |
| 265 | 272 |
| 266 scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks()); | 273 scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks()); |
| 267 scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks( | 274 scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks( |
| 268 new MockIndexedDBDatabaseCallbacks()); | 275 new MockIndexedDBDatabaseCallbacks()); |
| 269 const int64_t transaction_id = 1; | 276 const int64_t transaction_id = 1; |
| 270 IndexedDBPendingConnection connection( | 277 IndexedDBPendingConnection connection( |
| 271 callbacks, db_callbacks, 0 /* child_process_id */, transaction_id, | 278 callbacks, db_callbacks, 0 /* child_process_id */, transaction_id, |
| 272 IndexedDBDatabaseMetadata::DEFAULT_VERSION); | 279 IndexedDBDatabaseMetadata::DEFAULT_VERSION); |
| 273 factory->Open(base::ASCIIToUTF16("db"), connection, | 280 factory->Open(base::ASCIIToUTF16("db"), connection, |
| 274 NULL /* request_context */, url::Origin(kTestOrigin), | 281 NULL /* request_context */, Origin(kTestOrigin), |
| 275 temp_dir.path()); | 282 temp_dir.path()); |
| 276 | 283 |
| 277 EXPECT_TRUE(callbacks->connection()); | 284 EXPECT_TRUE(callbacks->connection()); |
| 278 | 285 |
| 279 // ConnectionOpened() is usually called by the dispatcher. | 286 // ConnectionOpened() is usually called by the dispatcher. |
| 280 context->ConnectionOpened(kTestOrigin, callbacks->connection()); | 287 context->ConnectionOpened(kTestOrigin, callbacks->connection()); |
| 281 | 288 |
| 282 EXPECT_TRUE(factory->IsBackingStoreOpen(kTestOrigin)); | 289 EXPECT_TRUE(factory->IsBackingStoreOpen(kTestOrigin)); |
| 283 | 290 |
| 284 // Simulate the write failure. | 291 // Simulate the write failure. |
| 285 leveldb::Status status = leveldb::Status::IOError("Simulated failure"); | 292 leveldb::Status status = leveldb::Status::IOError("Simulated failure"); |
| 286 callbacks->connection()->database()->TransactionCommitFailed(status); | 293 callbacks->connection()->database()->TransactionCommitFailed(status); |
| 287 | 294 |
| 288 EXPECT_TRUE(db_callbacks->forced_close_called()); | 295 EXPECT_TRUE(db_callbacks->forced_close_called()); |
| 289 EXPECT_FALSE(factory->IsBackingStoreOpen(kTestOrigin)); | 296 EXPECT_FALSE(factory->IsBackingStoreOpen(kTestOrigin)); |
| 290 } | 297 } |
| 291 | 298 |
| 292 } // namespace content | 299 } // namespace content |
| OLD | NEW |