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

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

Issue 2062203004: IDBObserver: Lifetime Management: Adding Observer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Final architechture Created 4 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "content/browser/indexed_db/indexed_db_transaction.h" 5 #include "content/browser/indexed_db/indexed_db_transaction.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/message_loop/message_loop.h" 12 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h" 13 #include "base/run_loop.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "content/browser/indexed_db/indexed_db_connection.h"
15 #include "content/browser/indexed_db/indexed_db_fake_backing_store.h" 16 #include "content/browser/indexed_db/indexed_db_fake_backing_store.h"
16 #include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h" 17 #include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h"
17 #include "content/browser/indexed_db/mock_indexed_db_factory.h" 18 #include "content/browser/indexed_db/mock_indexed_db_factory.h"
18 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
19 20
20 namespace content { 21 namespace content {
21 22
22 class AbortObserver { 23 class AbortObserver {
23 public: 24 public:
24 AbortObserver() : abort_task_called_(false) {} 25 AbortObserver() : abort_task_called_(false) {}
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 public: 80 public:
80 IndexedDBTransactionTestMode() {} 81 IndexedDBTransactionTestMode() {}
81 private: 82 private:
82 DISALLOW_COPY_AND_ASSIGN(IndexedDBTransactionTestMode); 83 DISALLOW_COPY_AND_ASSIGN(IndexedDBTransactionTestMode);
83 }; 84 };
84 85
85 TEST_F(IndexedDBTransactionTest, Timeout) { 86 TEST_F(IndexedDBTransactionTest, Timeout) {
86 const int64_t id = 0; 87 const int64_t id = 0;
87 const std::set<int64_t> scope; 88 const std::set<int64_t> scope;
88 const leveldb::Status commit_success = leveldb::Status::OK(); 89 const leveldb::Status commit_success = leveldb::Status::OK();
90 std::unique_ptr<IndexedDBConnection> connection(
91 new IndexedDBConnection(db_, new MockIndexedDBDatabaseCallbacks()));
89 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction( 92 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
90 id, 93 id, connection->GetWeakPtr(), scope,
91 new MockIndexedDBDatabaseCallbacks(),
92 scope,
93 blink::WebIDBTransactionModeReadWrite, 94 blink::WebIDBTransactionModeReadWrite,
94 db_.get(),
95 new IndexedDBFakeBackingStore::FakeTransaction(commit_success)); 95 new IndexedDBFakeBackingStore::FakeTransaction(commit_success));
96 db_->TransactionCreated(transaction.get()); 96 db_->TransactionCreated(transaction.get());
97 97
98 // No conflicting transactions, so coordinator will start it immediately: 98 // No conflicting transactions, so coordinator will start it immediately:
99 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state()); 99 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state());
100 EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); 100 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
101 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled); 101 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
102 EXPECT_EQ(0, transaction->diagnostics().tasks_completed); 102 EXPECT_EQ(0, transaction->diagnostics().tasks_completed);
103 103
104 // Schedule a task - timer won't be started until it's processed. 104 // Schedule a task - timer won't be started until it's processed.
(...skipping 18 matching lines...) Expand all
123 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state()); 123 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
124 EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); 124 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
125 EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled); 125 EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
126 EXPECT_EQ(1, transaction->diagnostics().tasks_completed); 126 EXPECT_EQ(1, transaction->diagnostics().tasks_completed);
127 } 127 }
128 128
129 TEST_F(IndexedDBTransactionTest, NoTimeoutReadOnly) { 129 TEST_F(IndexedDBTransactionTest, NoTimeoutReadOnly) {
130 const int64_t id = 0; 130 const int64_t id = 0;
131 const std::set<int64_t> scope; 131 const std::set<int64_t> scope;
132 const leveldb::Status commit_success = leveldb::Status::OK(); 132 const leveldb::Status commit_success = leveldb::Status::OK();
133 std::unique_ptr<IndexedDBConnection> connection(
134 new IndexedDBConnection(db_, new MockIndexedDBDatabaseCallbacks()));
133 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction( 135 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
134 id, 136 id, connection->GetWeakPtr(), scope, blink::WebIDBTransactionModeReadOnly,
135 new MockIndexedDBDatabaseCallbacks(),
136 scope,
137 blink::WebIDBTransactionModeReadOnly,
138 db_.get(),
139 new IndexedDBFakeBackingStore::FakeTransaction(commit_success)); 137 new IndexedDBFakeBackingStore::FakeTransaction(commit_success));
140 db_->TransactionCreated(transaction.get()); 138 db_->TransactionCreated(transaction.get());
141 139
142 // No conflicting transactions, so coordinator will start it immediately: 140 // No conflicting transactions, so coordinator will start it immediately:
143 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state()); 141 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state());
144 EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); 142 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
145 143
146 // Schedule a task - timer won't be started until it's processed. 144 // Schedule a task - timer won't be started until it's processed.
147 transaction->ScheduleTask(base::Bind( 145 transaction->ScheduleTask(base::Bind(
148 &IndexedDBTransactionTest::DummyOperation, base::Unretained(this))); 146 &IndexedDBTransactionTest::DummyOperation, base::Unretained(this)));
149 EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); 147 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
150 148
151 // Transaction is read-only, so no need to time it out. 149 // Transaction is read-only, so no need to time it out.
152 RunPostedTasks(); 150 RunPostedTasks();
153 EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); 151 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
154 152
155 // Clean up to avoid leaks. 153 // Clean up to avoid leaks.
156 transaction->Abort(); 154 transaction->Abort();
157 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state()); 155 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
158 EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); 156 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
159 } 157 }
160 158
161 TEST_P(IndexedDBTransactionTestMode, ScheduleNormalTask) { 159 TEST_P(IndexedDBTransactionTestMode, ScheduleNormalTask) {
162 const int64_t id = 0; 160 const int64_t id = 0;
163 const std::set<int64_t> scope; 161 const std::set<int64_t> scope;
164 const leveldb::Status commit_success = leveldb::Status::OK(); 162 const leveldb::Status commit_success = leveldb::Status::OK();
163 std::unique_ptr<IndexedDBConnection> connection(
164 new IndexedDBConnection(db_, new MockIndexedDBDatabaseCallbacks()));
165 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction( 165 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
166 id, 166 id, connection->GetWeakPtr(), scope, GetParam(),
167 new MockIndexedDBDatabaseCallbacks(),
168 scope,
169 GetParam(),
170 db_.get(),
171 new IndexedDBFakeBackingStore::FakeTransaction(commit_success)); 167 new IndexedDBFakeBackingStore::FakeTransaction(commit_success));
172 168
173 EXPECT_FALSE(transaction->HasPendingTasks()); 169 EXPECT_FALSE(transaction->HasPendingTasks());
174 EXPECT_TRUE(transaction->IsTaskQueueEmpty()); 170 EXPECT_TRUE(transaction->IsTaskQueueEmpty());
175 EXPECT_TRUE(transaction->task_queue_.empty()); 171 EXPECT_TRUE(transaction->task_queue_.empty());
176 EXPECT_TRUE(transaction->preemptive_task_queue_.empty()); 172 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
177 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled); 173 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
178 EXPECT_EQ(0, transaction->diagnostics().tasks_completed); 174 EXPECT_EQ(0, transaction->diagnostics().tasks_completed);
179 175
180 db_->TransactionCreated(transaction.get()); 176 db_->TransactionCreated(transaction.get());
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 EXPECT_TRUE(transaction->task_queue_.empty()); 213 EXPECT_TRUE(transaction->task_queue_.empty());
218 EXPECT_TRUE(transaction->preemptive_task_queue_.empty()); 214 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
219 EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled); 215 EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
220 EXPECT_EQ(1, transaction->diagnostics().tasks_completed); 216 EXPECT_EQ(1, transaction->diagnostics().tasks_completed);
221 } 217 }
222 218
223 TEST_F(IndexedDBTransactionTest, SchedulePreemptiveTask) { 219 TEST_F(IndexedDBTransactionTest, SchedulePreemptiveTask) {
224 const int64_t id = 0; 220 const int64_t id = 0;
225 const std::set<int64_t> scope; 221 const std::set<int64_t> scope;
226 const leveldb::Status commit_failure = leveldb::Status::Corruption("Ouch."); 222 const leveldb::Status commit_failure = leveldb::Status::Corruption("Ouch.");
223 std::unique_ptr<IndexedDBConnection> connection(
224 new IndexedDBConnection(db_, new MockIndexedDBDatabaseCallbacks()));
227 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction( 225 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
228 id, 226 id, connection->GetWeakPtr(), scope,
229 new MockIndexedDBDatabaseCallbacks(),
230 scope,
231 blink::WebIDBTransactionModeVersionChange, 227 blink::WebIDBTransactionModeVersionChange,
232 db_.get(),
233 new IndexedDBFakeBackingStore::FakeTransaction(commit_failure)); 228 new IndexedDBFakeBackingStore::FakeTransaction(commit_failure));
234 229
235 EXPECT_FALSE(transaction->HasPendingTasks()); 230 EXPECT_FALSE(transaction->HasPendingTasks());
236 EXPECT_TRUE(transaction->IsTaskQueueEmpty()); 231 EXPECT_TRUE(transaction->IsTaskQueueEmpty());
237 EXPECT_TRUE(transaction->task_queue_.empty()); 232 EXPECT_TRUE(transaction->task_queue_.empty());
238 EXPECT_TRUE(transaction->preemptive_task_queue_.empty()); 233 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
239 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled); 234 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
240 EXPECT_EQ(0, transaction->diagnostics().tasks_completed); 235 EXPECT_EQ(0, transaction->diagnostics().tasks_completed);
241 236
242 db_->TransactionCreated(transaction.get()); 237 db_->TransactionCreated(transaction.get());
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 EXPECT_TRUE(transaction->task_queue_.empty()); 273 EXPECT_TRUE(transaction->task_queue_.empty());
279 EXPECT_TRUE(transaction->preemptive_task_queue_.empty()); 274 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
280 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled); 275 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
281 EXPECT_EQ(0, transaction->diagnostics().tasks_completed); 276 EXPECT_EQ(0, transaction->diagnostics().tasks_completed);
282 } 277 }
283 278
284 TEST_P(IndexedDBTransactionTestMode, AbortTasks) { 279 TEST_P(IndexedDBTransactionTestMode, AbortTasks) {
285 const int64_t id = 0; 280 const int64_t id = 0;
286 const std::set<int64_t> scope; 281 const std::set<int64_t> scope;
287 const leveldb::Status commit_failure = leveldb::Status::Corruption("Ouch."); 282 const leveldb::Status commit_failure = leveldb::Status::Corruption("Ouch.");
283 std::unique_ptr<IndexedDBConnection> connection(
284 new IndexedDBConnection(db_, new MockIndexedDBDatabaseCallbacks()));
288 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction( 285 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
289 id, 286 id, connection->GetWeakPtr(), scope, GetParam(),
290 new MockIndexedDBDatabaseCallbacks(),
291 scope,
292 GetParam(),
293 db_.get(),
294 new IndexedDBFakeBackingStore::FakeTransaction(commit_failure)); 287 new IndexedDBFakeBackingStore::FakeTransaction(commit_failure));
295 db_->TransactionCreated(transaction.get()); 288 db_->TransactionCreated(transaction.get());
296 289
297 AbortObserver observer; 290 AbortObserver observer;
298 transaction->ScheduleTask( 291 transaction->ScheduleTask(
299 base::Bind(&IndexedDBTransactionTest::AbortableOperation, 292 base::Bind(&IndexedDBTransactionTest::AbortableOperation,
300 base::Unretained(this), 293 base::Unretained(this),
301 base::Unretained(&observer))); 294 base::Unretained(&observer)));
302 295
303 // Pump the message loop so that the transaction completes all pending tasks, 296 // Pump the message loop so that the transaction completes all pending tasks,
304 // otherwise it will defer the commit. 297 // otherwise it will defer the commit.
305 base::RunLoop().RunUntilIdle(); 298 base::RunLoop().RunUntilIdle();
306 299
307 EXPECT_FALSE(observer.abort_task_called()); 300 EXPECT_FALSE(observer.abort_task_called());
308 transaction->Commit(); 301 transaction->Commit();
309 EXPECT_TRUE(observer.abort_task_called()); 302 EXPECT_TRUE(observer.abort_task_called());
310 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state()); 303 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
311 EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); 304 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
312 } 305 }
313 306
314 TEST_P(IndexedDBTransactionTestMode, AbortPreemptive) { 307 TEST_P(IndexedDBTransactionTestMode, AbortPreemptive) {
315 const int64_t id = 0; 308 const int64_t id = 0;
316 const std::set<int64_t> scope; 309 const std::set<int64_t> scope;
317 const leveldb::Status commit_success = leveldb::Status::OK(); 310 const leveldb::Status commit_success = leveldb::Status::OK();
311 std::unique_ptr<IndexedDBConnection> connection(
312 new IndexedDBConnection(db_, new MockIndexedDBDatabaseCallbacks()));
318 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction( 313 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
319 id, 314 id, connection->GetWeakPtr(), scope, GetParam(),
320 new MockIndexedDBDatabaseCallbacks(),
321 scope,
322 GetParam(),
323 db_.get(),
324 new IndexedDBFakeBackingStore::FakeTransaction(commit_success)); 315 new IndexedDBFakeBackingStore::FakeTransaction(commit_success));
325 db_->TransactionCreated(transaction.get()); 316 db_->TransactionCreated(transaction.get());
326 317
327 // No conflicting transactions, so coordinator will start it immediately: 318 // No conflicting transactions, so coordinator will start it immediately:
328 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state()); 319 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state());
329 EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); 320 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
330 321
331 transaction->ScheduleTask( 322 transaction->ScheduleTask(
332 blink::WebIDBTaskTypePreemptive, 323 blink::WebIDBTaskTypePreemptive,
333 base::Bind(&IndexedDBTransactionTest::DummyOperation, 324 base::Bind(&IndexedDBTransactionTest::DummyOperation,
(...skipping 21 matching lines...) Expand all
355 // This task will be ignored. 346 // This task will be ignored.
356 transaction->ScheduleTask(base::Bind( 347 transaction->ScheduleTask(base::Bind(
357 &IndexedDBTransactionTest::DummyOperation, base::Unretained(this))); 348 &IndexedDBTransactionTest::DummyOperation, base::Unretained(this)));
358 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state()); 349 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
359 EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); 350 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
360 EXPECT_FALSE(transaction->HasPendingTasks()); 351 EXPECT_FALSE(transaction->HasPendingTasks());
361 EXPECT_EQ(transaction->diagnostics().tasks_completed, 352 EXPECT_EQ(transaction->diagnostics().tasks_completed,
362 transaction->diagnostics().tasks_scheduled); 353 transaction->diagnostics().tasks_scheduled);
363 } 354 }
364 355
356 TEST_F(IndexedDBTransactionTest, IndexedDBObserver) {
357 const int64_t id = 0;
358 const std::set<int64_t> scope;
359 const leveldb::Status commit_success = leveldb::Status::OK();
360 std::unique_ptr<IndexedDBConnection> connection(
361 new IndexedDBConnection(db_, new MockIndexedDBDatabaseCallbacks()));
362 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
363 id, connection->GetWeakPtr(), scope,
364 blink::WebIDBTransactionModeReadWrite,
365 new IndexedDBFakeBackingStore::FakeTransaction(commit_success));
366 db_->TransactionCreated(transaction.get());
367
368 EXPECT_EQ(0UL, transaction->pending_observers_.size());
369 EXPECT_EQ(0UL, connection->active_observers().size());
370
371 // Add observers to pending observer list.
372 const int32_t observer_id1 = 1, observer_id2 = 2;
373 transaction->AddPendingObserver(observer_id1);
374 transaction->AddPendingObserver(observer_id2);
375 EXPECT_EQ(2UL, transaction->pending_observers_.size());
376 EXPECT_EQ(0UL, connection->active_observers().size());
377
378 // Before commit, observer would be in pending list of transaction.
379 std::vector<int32_t> observer_to_remove1 = {observer_id1};
380 connection->RemoveObservers(observer_to_remove1);
381 EXPECT_EQ(1UL, transaction->pending_observers_.size());
382 EXPECT_EQ(0UL, connection->active_observers().size());
383
384 // After commit, observer moved to connection's active observer.
385 transaction->Commit();
386 EXPECT_EQ(0UL, transaction->pending_observers_.size());
387 EXPECT_EQ(1UL, connection->active_observers().size());
388
389 // Observer does not exist, so no change to active_observers.
390 connection->RemoveObservers(observer_to_remove1);
391 EXPECT_EQ(1UL, connection->active_observers().size());
392
393 // Observer removed from connection's active observer.
394 std::vector<int32_t> observer_to_remove2 = {observer_id2};
395 connection->RemoveObservers(observer_to_remove2);
396 EXPECT_EQ(0UL, connection->active_observers().size());
397 }
398
365 static const blink::WebIDBTransactionMode kTestModes[] = { 399 static const blink::WebIDBTransactionMode kTestModes[] = {
366 blink::WebIDBTransactionModeReadOnly, blink::WebIDBTransactionModeReadWrite, 400 blink::WebIDBTransactionModeReadOnly, blink::WebIDBTransactionModeReadWrite,
367 blink::WebIDBTransactionModeVersionChange}; 401 blink::WebIDBTransactionModeVersionChange};
368 402
369 INSTANTIATE_TEST_CASE_P(IndexedDBTransactions, 403 INSTANTIATE_TEST_CASE_P(IndexedDBTransactions,
370 IndexedDBTransactionTestMode, 404 IndexedDBTransactionTestMode,
371 ::testing::ValuesIn(kTestModes)); 405 ::testing::ValuesIn(kTestModes));
372 406
373 } // namespace content 407 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698