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

Side by Side Diff: content/browser/indexed_db/indexed_db_unittest.cc

Issue 2930183002: Let IndexedDBContextImpl create its own task runner (Closed)
Patch Set: Use ScopedTaskEnvironment for most tests Created 3 years, 6 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 unified diff | Download patch
OLDNEW
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/test/scoped_task_environment.h"
14 #include "base/threading/thread.h" 14 #include "base/threading/sequenced_task_runner_handle.h"
15 #include "base/threading/thread_task_runner_handle.h"
16 #include "content/browser/indexed_db/indexed_db_connection.h" 15 #include "content/browser/indexed_db/indexed_db_connection.h"
17 #include "content/browser/indexed_db/indexed_db_context_impl.h" 16 #include "content/browser/indexed_db/indexed_db_context_impl.h"
18 #include "content/browser/indexed_db/indexed_db_factory_impl.h" 17 #include "content/browser/indexed_db/indexed_db_factory_impl.h"
19 #include "content/browser/indexed_db/mock_indexed_db_callbacks.h" 18 #include "content/browser/indexed_db/mock_indexed_db_callbacks.h"
20 #include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h" 19 #include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h"
21 #include "content/public/browser/storage_partition.h" 20 #include "content/public/browser/storage_partition.h"
22 #include "content/public/common/url_constants.h" 21 #include "content/public/common/url_constants.h"
23 #include "content/public/test/test_browser_context.h" 22 #include "content/public/test/test_browser_context.h"
24 #include "content/public/test/test_browser_thread_bundle.h" 23 #include "content/public/test/test_browser_thread_bundle.h"
24 #include "content/public/test/test_utils.h"
25 #include "storage/browser/quota/quota_manager.h" 25 #include "storage/browser/quota/quota_manager.h"
26 #include "storage/browser/quota/special_storage_policy.h" 26 #include "storage/browser/quota/special_storage_policy.h"
27 #include "storage/browser/test/mock_quota_manager_proxy.h" 27 #include "storage/browser/test/mock_quota_manager_proxy.h"
28 #include "storage/browser/test/mock_special_storage_policy.h" 28 #include "storage/browser/test/mock_special_storage_policy.h"
29 #include "testing/gtest/include/gtest/gtest.h" 29 #include "testing/gtest/include/gtest/gtest.h"
30 #include "url/origin.h" 30 #include "url/origin.h"
31 31
32 using url::Origin; 32 using url::Origin;
33 33
34 namespace content { 34 namespace content {
35 35
36 class IndexedDBTest : public testing::Test { 36 class IndexedDBTest : public testing::Test {
37 public: 37 public:
38 const Origin kNormalOrigin; 38 const Origin kNormalOrigin;
39 const Origin kSessionOnlyOrigin; 39 const Origin kSessionOnlyOrigin;
40 40
41 IndexedDBTest() 41 IndexedDBTest()
42 : kNormalOrigin(GURL("http://normal/")), 42 : kNormalOrigin(GURL("http://normal/")),
43 kSessionOnlyOrigin(GURL("http://session-only/")), 43 kSessionOnlyOrigin(GURL("http://session-only/")),
44 task_runner_(new base::TestSimpleTaskRunner), 44 scoped_task_environment_(
45 base::test::ScopedTaskEnvironment::MainThreadType::UI),
45 special_storage_policy_(new MockSpecialStoragePolicy), 46 special_storage_policy_(new MockSpecialStoragePolicy),
46 quota_manager_proxy_(new MockQuotaManagerProxy(nullptr, nullptr)) { 47 quota_manager_proxy_(new MockQuotaManagerProxy(nullptr, nullptr)) {
47 special_storage_policy_->AddSessionOnly(kSessionOnlyOrigin.GetURL()); 48 special_storage_policy_->AddSessionOnly(kSessionOnlyOrigin.GetURL());
48 } 49 }
49 ~IndexedDBTest() override { 50 ~IndexedDBTest() override {
50 quota_manager_proxy_->SimulateQuotaManagerDestroyed(); 51 quota_manager_proxy_->SimulateQuotaManagerDestroyed();
51 } 52 }
52 53
53 protected: 54 protected:
54 void FlushIndexedDBTaskRunner() { task_runner_->RunUntilIdle(); } 55 base::test::ScopedTaskEnvironment scoped_task_environment_;
55
56 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
57 scoped_refptr<MockSpecialStoragePolicy> special_storage_policy_; 56 scoped_refptr<MockSpecialStoragePolicy> special_storage_policy_;
58 scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_; 57 scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_;
59 58
60 private: 59 private:
61 TestBrowserThreadBundle thread_bundle_; 60 TestBrowserThreadBundle thread_bundle_;
gab 2017/06/13 15:31:23 TestBrowserThreadBundle includes a base::test::Sco
62 61
63 DISALLOW_COPY_AND_ASSIGN(IndexedDBTest); 62 DISALLOW_COPY_AND_ASSIGN(IndexedDBTest);
64 }; 63 };
65 64
66 TEST_F(IndexedDBTest, ClearSessionOnlyDatabases) { 65 TEST_F(IndexedDBTest, ClearSessionOnlyDatabases) {
67 base::ScopedTempDir temp_dir; 66 base::ScopedTempDir temp_dir;
68 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 67 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
69 68
70 base::FilePath normal_path; 69 base::FilePath normal_path;
71 base::FilePath session_only_path; 70 base::FilePath session_only_path;
72 71
73 // Create the scope which will ensure we run the destructor of the context 72 // Create the scope which will ensure we run the destructor of the context
74 // which should trigger the clean up. 73 // which should trigger the clean up.
75 { 74 {
76 scoped_refptr<IndexedDBContextImpl> idb_context = new IndexedDBContextImpl( 75 scoped_refptr<IndexedDBContextImpl> idb_context = new IndexedDBContextImpl(
77 temp_dir.GetPath(), special_storage_policy_.get(), 76 temp_dir.GetPath(), special_storage_policy_.get(),
78 quota_manager_proxy_.get(), task_runner_.get()); 77 quota_manager_proxy_.get());
79 78
80 normal_path = idb_context->GetFilePathForTesting(kNormalOrigin); 79 normal_path = idb_context->GetFilePathForTesting(kNormalOrigin);
81 session_only_path = idb_context->GetFilePathForTesting(kSessionOnlyOrigin); 80 session_only_path = idb_context->GetFilePathForTesting(kSessionOnlyOrigin);
82 ASSERT_TRUE(base::CreateDirectory(normal_path)); 81 ASSERT_TRUE(base::CreateDirectory(normal_path));
83 ASSERT_TRUE(base::CreateDirectory(session_only_path)); 82 ASSERT_TRUE(base::CreateDirectory(session_only_path));
84 FlushIndexedDBTaskRunner(); 83 RunAllBlockingPoolTasksUntilIdle();
85 base::RunLoop().RunUntilIdle();
86 quota_manager_proxy_->SimulateQuotaManagerDestroyed(); 84 quota_manager_proxy_->SimulateQuotaManagerDestroyed();
87 } 85 }
88 86
89 FlushIndexedDBTaskRunner(); 87 RunAllBlockingPoolTasksUntilIdle();
90 base::RunLoop().RunUntilIdle();
91 88
92 EXPECT_TRUE(base::DirectoryExists(normal_path)); 89 EXPECT_TRUE(base::DirectoryExists(normal_path));
93 EXPECT_FALSE(base::DirectoryExists(session_only_path)); 90 EXPECT_FALSE(base::DirectoryExists(session_only_path));
94 } 91 }
95 92
96 TEST_F(IndexedDBTest, SetForceKeepSessionState) { 93 TEST_F(IndexedDBTest, SetForceKeepSessionState) {
97 base::ScopedTempDir temp_dir; 94 base::ScopedTempDir temp_dir;
98 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 95 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
99 96
100 base::FilePath normal_path; 97 base::FilePath normal_path;
101 base::FilePath session_only_path; 98 base::FilePath session_only_path;
102 99
103 // Create the scope which will ensure we run the destructor of the context. 100 // Create the scope which will ensure we run the destructor of the context.
104 { 101 {
105 // Create some indexedDB paths. 102 // Create some indexedDB paths.
106 // With the levelDB backend, these are directories. 103 // With the levelDB backend, these are directories.
107 scoped_refptr<IndexedDBContextImpl> idb_context = new IndexedDBContextImpl( 104 scoped_refptr<IndexedDBContextImpl> idb_context = new IndexedDBContextImpl(
108 temp_dir.GetPath(), special_storage_policy_.get(), 105 temp_dir.GetPath(), special_storage_policy_.get(),
109 quota_manager_proxy_.get(), task_runner_.get()); 106 quota_manager_proxy_.get());
110 107
111 // Save session state. This should bypass the destruction-time deletion. 108 // Save session state. This should bypass the destruction-time deletion.
112 idb_context->SetForceKeepSessionState(); 109 idb_context->SetForceKeepSessionState();
113 110
114 normal_path = idb_context->GetFilePathForTesting(kNormalOrigin); 111 normal_path = idb_context->GetFilePathForTesting(kNormalOrigin);
115 session_only_path = idb_context->GetFilePathForTesting(kSessionOnlyOrigin); 112 session_only_path = idb_context->GetFilePathForTesting(kSessionOnlyOrigin);
116 ASSERT_TRUE(base::CreateDirectory(normal_path)); 113 ASSERT_TRUE(base::CreateDirectory(normal_path));
117 ASSERT_TRUE(base::CreateDirectory(session_only_path)); 114 ASSERT_TRUE(base::CreateDirectory(session_only_path));
118 base::RunLoop().RunUntilIdle(); 115 base::RunLoop().RunUntilIdle();
119 } 116 }
120 117
121 // Make sure we wait until the destructor has run. 118 // Make sure we wait until the destructor has run.
122 base::RunLoop().RunUntilIdle(); 119 base::RunLoop().RunUntilIdle();
123 120
124 // No data was cleared because of SetForceKeepSessionState. 121 // No data was cleared because of SetForceKeepSessionState.
125 EXPECT_TRUE(base::DirectoryExists(normal_path)); 122 EXPECT_TRUE(base::DirectoryExists(normal_path));
126 EXPECT_TRUE(base::DirectoryExists(session_only_path)); 123 EXPECT_TRUE(base::DirectoryExists(session_only_path));
127 } 124 }
128 125
129 class ForceCloseDBCallbacks : public IndexedDBCallbacks { 126 class ForceCloseDBCallbacks : public IndexedDBCallbacks {
130 public: 127 public:
131 ForceCloseDBCallbacks(scoped_refptr<IndexedDBContextImpl> idb_context, 128 ForceCloseDBCallbacks(scoped_refptr<IndexedDBContextImpl> idb_context,
132 const Origin& origin) 129 const Origin& origin)
133 : IndexedDBCallbacks(nullptr, 130 : IndexedDBCallbacks(nullptr, origin, nullptr, idb_context->TaskRunner()),
134 origin,
135 nullptr,
136 base::ThreadTaskRunnerHandle::Get()),
137 idb_context_(idb_context), 131 idb_context_(idb_context),
138 origin_(origin) {} 132 origin_(origin) {}
139 133
140 void OnSuccess() override {} 134 void OnSuccess() override {}
141 void OnSuccess(const std::vector<base::string16>&) override {} 135 void OnSuccess(const std::vector<base::string16>&) override {}
142 void OnSuccess(std::unique_ptr<IndexedDBConnection> connection, 136 void OnSuccess(std::unique_ptr<IndexedDBConnection> connection,
143 const IndexedDBDatabaseMetadata& metadata) override { 137 const IndexedDBDatabaseMetadata& metadata) override {
144 connection_ = std::move(connection); 138 connection_ = std::move(connection);
145 idb_context_->ConnectionOpened(origin_, connection_.get()); 139 idb_context_->ConnectionOpened(origin_, connection_.get());
146 } 140 }
(...skipping 22 matching lines...) Expand all
169 base::FilePath test_path; 163 base::FilePath test_path;
170 164
171 // Create the scope which will ensure we run the destructor of the context. 165 // Create the scope which will ensure we run the destructor of the context.
172 { 166 {
173 TestBrowserContext browser_context; 167 TestBrowserContext browser_context;
174 168
175 const Origin kTestOrigin(GURL("http://test/")); 169 const Origin kTestOrigin(GURL("http://test/"));
176 170
177 scoped_refptr<IndexedDBContextImpl> idb_context = new IndexedDBContextImpl( 171 scoped_refptr<IndexedDBContextImpl> idb_context = new IndexedDBContextImpl(
178 temp_dir.GetPath(), special_storage_policy_.get(), 172 temp_dir.GetPath(), special_storage_policy_.get(),
179 quota_manager_proxy_.get(), task_runner_.get()); 173 quota_manager_proxy_.get());
174
175 // Assign current task runner so that methods on context can be invoked
176 // directly from test body.
177 idb_context->SetTaskRunnerForTesting(
178 base::SequencedTaskRunnerHandle::Get());
gab 2017/06/13 15:31:23 A cleaner alternative to doing this would be to po
180 179
181 scoped_refptr<ForceCloseDBCallbacks> open_callbacks = 180 scoped_refptr<ForceCloseDBCallbacks> open_callbacks =
182 new ForceCloseDBCallbacks(idb_context, kTestOrigin); 181 new ForceCloseDBCallbacks(idb_context, kTestOrigin);
183 182
184 scoped_refptr<ForceCloseDBCallbacks> closed_callbacks = 183 scoped_refptr<ForceCloseDBCallbacks> closed_callbacks =
185 new ForceCloseDBCallbacks(idb_context, kTestOrigin); 184 new ForceCloseDBCallbacks(idb_context, kTestOrigin);
186 185
187 IndexedDBFactory* factory = idb_context->GetIDBFactory(); 186 IndexedDBFactory* factory = idb_context->GetIDBFactory();
188 187
189 test_path = idb_context->GetFilePathForTesting(kTestOrigin); 188 test_path = idb_context->GetFilePathForTesting(kTestOrigin);
(...skipping 14 matching lines...) Expand all
204 idb_context->data_path()); 203 idb_context->data_path());
205 204
206 closed_callbacks->connection()->Close(); 205 closed_callbacks->connection()->Close();
207 206
208 // TODO(jsbell): Remove static_cast<> when overloads are eliminated. 207 // TODO(jsbell): Remove static_cast<> when overloads are eliminated.
209 idb_context->TaskRunner()->PostTask( 208 idb_context->TaskRunner()->PostTask(
210 FROM_HERE, 209 FROM_HERE,
211 base::Bind(static_cast<void (IndexedDBContextImpl::*)(const Origin&)>( 210 base::Bind(static_cast<void (IndexedDBContextImpl::*)(const Origin&)>(
212 &IndexedDBContextImpl::DeleteForOrigin), 211 &IndexedDBContextImpl::DeleteForOrigin),
213 idb_context, kTestOrigin)); 212 idb_context, kTestOrigin));
214 FlushIndexedDBTaskRunner(); 213
215 base::RunLoop().RunUntilIdle(); 214 scoped_task_environment_.RunUntilIdle();
216 } 215 }
217 216
218 // Make sure we wait until the destructor has run. 217 // Make sure we wait until the destructor has run.
219 base::RunLoop().RunUntilIdle(); 218 scoped_task_environment_.RunUntilIdle();
220 219
221 EXPECT_TRUE(open_db_callbacks->forced_close_called()); 220 EXPECT_TRUE(open_db_callbacks->forced_close_called());
222 EXPECT_FALSE(closed_db_callbacks->forced_close_called()); 221 EXPECT_FALSE(closed_db_callbacks->forced_close_called());
223 EXPECT_FALSE(base::DirectoryExists(test_path)); 222 EXPECT_FALSE(base::DirectoryExists(test_path));
224 } 223 }
225 224
226 TEST_F(IndexedDBTest, DeleteFailsIfDirectoryLocked) { 225 TEST_F(IndexedDBTest, DeleteFailsIfDirectoryLocked) {
227 base::ScopedTempDir temp_dir; 226 base::ScopedTempDir temp_dir;
228 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 227 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
229 const Origin kTestOrigin(GURL("http://test/")); 228 const Origin kTestOrigin(GURL("http://test/"));
230 229
231 scoped_refptr<IndexedDBContextImpl> idb_context = new IndexedDBContextImpl( 230 scoped_refptr<IndexedDBContextImpl> idb_context = new IndexedDBContextImpl(
232 temp_dir.GetPath(), special_storage_policy_.get(), 231 temp_dir.GetPath(), special_storage_policy_.get(),
233 quota_manager_proxy_.get(), task_runner_.get()); 232 quota_manager_proxy_.get());
234 233
235 base::FilePath test_path = idb_context->GetFilePathForTesting(kTestOrigin); 234 base::FilePath test_path = idb_context->GetFilePathForTesting(kTestOrigin);
236 ASSERT_TRUE(base::CreateDirectory(test_path)); 235 ASSERT_TRUE(base::CreateDirectory(test_path));
237 236
238 std::unique_ptr<LevelDBLock> lock = 237 std::unique_ptr<LevelDBLock> lock =
239 LevelDBDatabase::LockForTesting(test_path); 238 LevelDBDatabase::LockForTesting(test_path);
240 ASSERT_TRUE(lock); 239 ASSERT_TRUE(lock);
241 240
242 // TODO(jsbell): Remove static_cast<> when overloads are eliminated. 241 // TODO(jsbell): Remove static_cast<> when overloads are eliminated.
243 void (IndexedDBContextImpl::* delete_for_origin)(const Origin&) = 242 void (IndexedDBContextImpl::* delete_for_origin)(const Origin&) =
244 &IndexedDBContextImpl::DeleteForOrigin; 243 &IndexedDBContextImpl::DeleteForOrigin;
245 idb_context->TaskRunner()->PostTask( 244 idb_context->TaskRunner()->PostTask(
246 FROM_HERE, 245 FROM_HERE,
247 base::Bind(delete_for_origin, idb_context, kTestOrigin)); 246 base::Bind(delete_for_origin, idb_context, kTestOrigin));
248 FlushIndexedDBTaskRunner(); 247 RunAllBlockingPoolTasksUntilIdle();
249 248
250 EXPECT_TRUE(base::DirectoryExists(test_path)); 249 EXPECT_TRUE(base::DirectoryExists(test_path));
251 } 250 }
252 251
253 TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnCommitFailure) { 252 TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnCommitFailure) {
254 const Origin kTestOrigin(GURL("http://test/")); 253 const Origin kTestOrigin(GURL("http://test/"));
255 254
256 base::ScopedTempDir temp_dir; 255 base::ScopedTempDir temp_dir;
257 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 256 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
258 257
259 scoped_refptr<IndexedDBContextImpl> context = new IndexedDBContextImpl( 258 scoped_refptr<IndexedDBContextImpl> context = new IndexedDBContextImpl(
260 temp_dir.GetPath(), special_storage_policy_.get(), 259 temp_dir.GetPath(), special_storage_policy_.get(),
261 quota_manager_proxy_.get(), task_runner_.get()); 260 quota_manager_proxy_.get());
261
262 // Assign current task runner so that methods on context can be invoked
263 // directly from test body.
264 context->SetTaskRunnerForTesting(base::SequencedTaskRunnerHandle::Get());
262 265
263 scoped_refptr<IndexedDBFactoryImpl> factory = 266 scoped_refptr<IndexedDBFactoryImpl> factory =
264 static_cast<IndexedDBFactoryImpl*>(context->GetIDBFactory()); 267 static_cast<IndexedDBFactoryImpl*>(context->GetIDBFactory());
265 268
266 scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks()); 269 scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks());
267 scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks( 270 scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks(
268 new MockIndexedDBDatabaseCallbacks()); 271 new MockIndexedDBDatabaseCallbacks());
269 const int64_t transaction_id = 1; 272 const int64_t transaction_id = 1;
270 std::unique_ptr<IndexedDBPendingConnection> connection( 273 std::unique_ptr<IndexedDBPendingConnection> connection(
271 base::MakeUnique<IndexedDBPendingConnection>( 274 base::MakeUnique<IndexedDBPendingConnection>(
(...skipping 12 matching lines...) Expand all
284 287
285 // Simulate the write failure. 288 // Simulate the write failure.
286 leveldb::Status status = leveldb::Status::IOError("Simulated failure"); 289 leveldb::Status status = leveldb::Status::IOError("Simulated failure");
287 context->GetIDBFactory()->HandleBackingStoreFailure(kTestOrigin); 290 context->GetIDBFactory()->HandleBackingStoreFailure(kTestOrigin);
288 291
289 EXPECT_TRUE(db_callbacks->forced_close_called()); 292 EXPECT_TRUE(db_callbacks->forced_close_called());
290 EXPECT_FALSE(factory->IsBackingStoreOpen(kTestOrigin)); 293 EXPECT_FALSE(factory->IsBackingStoreOpen(kTestOrigin));
291 } 294 }
292 295
293 } // namespace content 296 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698