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

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: Units tests added 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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
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();
89 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction( 90 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
90 id, 91 id, new IndexedDBConnection(db_, new MockIndexedDBDatabaseCallbacks()),
Marijn Kruisselbrink 2016/06/30 00:17:25 here too I believe you're leaking IndexedDBConnect
palakj1 2016/06/30 01:07:04 Done.
91 new MockIndexedDBDatabaseCallbacks(), 92 scope, blink::WebIDBTransactionModeReadWrite,
92 scope,
93 blink::WebIDBTransactionModeReadWrite,
94 db_.get(),
95 new IndexedDBFakeBackingStore::FakeTransaction(commit_success)); 93 new IndexedDBFakeBackingStore::FakeTransaction(commit_success));
96 db_->TransactionCreated(transaction.get()); 94 db_->TransactionCreated(transaction.get());
97 95
98 // No conflicting transactions, so coordinator will start it immediately: 96 // No conflicting transactions, so coordinator will start it immediately:
99 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state()); 97 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state());
100 EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); 98 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
101 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled); 99 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
102 EXPECT_EQ(0, transaction->diagnostics().tasks_completed); 100 EXPECT_EQ(0, transaction->diagnostics().tasks_completed);
103 101
104 // Schedule a task - timer won't be started until it's processed. 102 // Schedule a task - timer won't be started until it's processed.
(...skipping 19 matching lines...) Expand all
124 EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); 122 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
125 EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled); 123 EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
126 EXPECT_EQ(1, transaction->diagnostics().tasks_completed); 124 EXPECT_EQ(1, transaction->diagnostics().tasks_completed);
127 } 125 }
128 126
129 TEST_F(IndexedDBTransactionTest, NoTimeoutReadOnly) { 127 TEST_F(IndexedDBTransactionTest, NoTimeoutReadOnly) {
130 const int64_t id = 0; 128 const int64_t id = 0;
131 const std::set<int64_t> scope; 129 const std::set<int64_t> scope;
132 const leveldb::Status commit_success = leveldb::Status::OK(); 130 const leveldb::Status commit_success = leveldb::Status::OK();
133 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction( 131 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
134 id, 132 id, new IndexedDBConnection(db_, new MockIndexedDBDatabaseCallbacks()),
135 new MockIndexedDBDatabaseCallbacks(), 133 scope, blink::WebIDBTransactionModeReadOnly,
136 scope,
137 blink::WebIDBTransactionModeReadOnly,
138 db_.get(),
139 new IndexedDBFakeBackingStore::FakeTransaction(commit_success)); 134 new IndexedDBFakeBackingStore::FakeTransaction(commit_success));
140 db_->TransactionCreated(transaction.get()); 135 db_->TransactionCreated(transaction.get());
141 136
142 // No conflicting transactions, so coordinator will start it immediately: 137 // No conflicting transactions, so coordinator will start it immediately:
143 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state()); 138 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state());
144 EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); 139 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
145 140
146 // Schedule a task - timer won't be started until it's processed. 141 // Schedule a task - timer won't be started until it's processed.
147 transaction->ScheduleTask(base::Bind( 142 transaction->ScheduleTask(base::Bind(
148 &IndexedDBTransactionTest::DummyOperation, base::Unretained(this))); 143 &IndexedDBTransactionTest::DummyOperation, base::Unretained(this)));
149 EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); 144 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
150 145
151 // Transaction is read-only, so no need to time it out. 146 // Transaction is read-only, so no need to time it out.
152 RunPostedTasks(); 147 RunPostedTasks();
153 EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); 148 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
154 149
155 // Clean up to avoid leaks. 150 // Clean up to avoid leaks.
156 transaction->Abort(); 151 transaction->Abort();
157 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state()); 152 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
158 EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); 153 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
159 } 154 }
160 155
161 TEST_P(IndexedDBTransactionTestMode, ScheduleNormalTask) { 156 TEST_P(IndexedDBTransactionTestMode, ScheduleNormalTask) {
162 const int64_t id = 0; 157 const int64_t id = 0;
163 const std::set<int64_t> scope; 158 const std::set<int64_t> scope;
164 const leveldb::Status commit_success = leveldb::Status::OK(); 159 const leveldb::Status commit_success = leveldb::Status::OK();
165 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction( 160 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
166 id, 161 id, new IndexedDBConnection(db_, new MockIndexedDBDatabaseCallbacks()),
167 new MockIndexedDBDatabaseCallbacks(), 162 scope, GetParam(),
168 scope,
169 GetParam(),
170 db_.get(),
171 new IndexedDBFakeBackingStore::FakeTransaction(commit_success)); 163 new IndexedDBFakeBackingStore::FakeTransaction(commit_success));
172 164
173 EXPECT_FALSE(transaction->HasPendingTasks()); 165 EXPECT_FALSE(transaction->HasPendingTasks());
174 EXPECT_TRUE(transaction->IsTaskQueueEmpty()); 166 EXPECT_TRUE(transaction->IsTaskQueueEmpty());
175 EXPECT_TRUE(transaction->task_queue_.empty()); 167 EXPECT_TRUE(transaction->task_queue_.empty());
176 EXPECT_TRUE(transaction->preemptive_task_queue_.empty()); 168 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
177 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled); 169 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
178 EXPECT_EQ(0, transaction->diagnostics().tasks_completed); 170 EXPECT_EQ(0, transaction->diagnostics().tasks_completed);
179 171
180 db_->TransactionCreated(transaction.get()); 172 db_->TransactionCreated(transaction.get());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 EXPECT_TRUE(transaction->preemptive_task_queue_.empty()); 210 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
219 EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled); 211 EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
220 EXPECT_EQ(1, transaction->diagnostics().tasks_completed); 212 EXPECT_EQ(1, transaction->diagnostics().tasks_completed);
221 } 213 }
222 214
223 TEST_F(IndexedDBTransactionTest, SchedulePreemptiveTask) { 215 TEST_F(IndexedDBTransactionTest, SchedulePreemptiveTask) {
224 const int64_t id = 0; 216 const int64_t id = 0;
225 const std::set<int64_t> scope; 217 const std::set<int64_t> scope;
226 const leveldb::Status commit_failure = leveldb::Status::Corruption("Ouch."); 218 const leveldb::Status commit_failure = leveldb::Status::Corruption("Ouch.");
227 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction( 219 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
228 id, 220 id, new IndexedDBConnection(db_, new MockIndexedDBDatabaseCallbacks()),
229 new MockIndexedDBDatabaseCallbacks(), 221 scope, blink::WebIDBTransactionModeVersionChange,
230 scope,
231 blink::WebIDBTransactionModeVersionChange,
232 db_.get(),
233 new IndexedDBFakeBackingStore::FakeTransaction(commit_failure)); 222 new IndexedDBFakeBackingStore::FakeTransaction(commit_failure));
234 223
235 EXPECT_FALSE(transaction->HasPendingTasks()); 224 EXPECT_FALSE(transaction->HasPendingTasks());
236 EXPECT_TRUE(transaction->IsTaskQueueEmpty()); 225 EXPECT_TRUE(transaction->IsTaskQueueEmpty());
237 EXPECT_TRUE(transaction->task_queue_.empty()); 226 EXPECT_TRUE(transaction->task_queue_.empty());
238 EXPECT_TRUE(transaction->preemptive_task_queue_.empty()); 227 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
239 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled); 228 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
240 EXPECT_EQ(0, transaction->diagnostics().tasks_completed); 229 EXPECT_EQ(0, transaction->diagnostics().tasks_completed);
241 230
242 db_->TransactionCreated(transaction.get()); 231 db_->TransactionCreated(transaction.get());
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 EXPECT_TRUE(transaction->preemptive_task_queue_.empty()); 268 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
280 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled); 269 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
281 EXPECT_EQ(0, transaction->diagnostics().tasks_completed); 270 EXPECT_EQ(0, transaction->diagnostics().tasks_completed);
282 } 271 }
283 272
284 TEST_P(IndexedDBTransactionTestMode, AbortTasks) { 273 TEST_P(IndexedDBTransactionTestMode, AbortTasks) {
285 const int64_t id = 0; 274 const int64_t id = 0;
286 const std::set<int64_t> scope; 275 const std::set<int64_t> scope;
287 const leveldb::Status commit_failure = leveldb::Status::Corruption("Ouch."); 276 const leveldb::Status commit_failure = leveldb::Status::Corruption("Ouch.");
288 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction( 277 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
289 id, 278 id, new IndexedDBConnection(db_, new MockIndexedDBDatabaseCallbacks()),
290 new MockIndexedDBDatabaseCallbacks(), 279 scope, GetParam(),
291 scope,
292 GetParam(),
293 db_.get(),
294 new IndexedDBFakeBackingStore::FakeTransaction(commit_failure)); 280 new IndexedDBFakeBackingStore::FakeTransaction(commit_failure));
295 db_->TransactionCreated(transaction.get()); 281 db_->TransactionCreated(transaction.get());
296 282
297 AbortObserver observer; 283 AbortObserver observer;
298 transaction->ScheduleTask( 284 transaction->ScheduleTask(
299 base::Bind(&IndexedDBTransactionTest::AbortableOperation, 285 base::Bind(&IndexedDBTransactionTest::AbortableOperation,
300 base::Unretained(this), 286 base::Unretained(this),
301 base::Unretained(&observer))); 287 base::Unretained(&observer)));
302 288
303 // Pump the message loop so that the transaction completes all pending tasks, 289 // Pump the message loop so that the transaction completes all pending tasks,
304 // otherwise it will defer the commit. 290 // otherwise it will defer the commit.
305 base::RunLoop().RunUntilIdle(); 291 base::RunLoop().RunUntilIdle();
306 292
307 EXPECT_FALSE(observer.abort_task_called()); 293 EXPECT_FALSE(observer.abort_task_called());
308 transaction->Commit(); 294 transaction->Commit();
309 EXPECT_TRUE(observer.abort_task_called()); 295 EXPECT_TRUE(observer.abort_task_called());
310 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state()); 296 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
311 EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); 297 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
312 } 298 }
313 299
314 TEST_P(IndexedDBTransactionTestMode, AbortPreemptive) { 300 TEST_P(IndexedDBTransactionTestMode, AbortPreemptive) {
315 const int64_t id = 0; 301 const int64_t id = 0;
316 const std::set<int64_t> scope; 302 const std::set<int64_t> scope;
317 const leveldb::Status commit_success = leveldb::Status::OK(); 303 const leveldb::Status commit_success = leveldb::Status::OK();
318 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction( 304 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
319 id, 305 id, new IndexedDBConnection(db_, new MockIndexedDBDatabaseCallbacks()),
320 new MockIndexedDBDatabaseCallbacks(), 306 scope, GetParam(),
321 scope,
322 GetParam(),
323 db_.get(),
324 new IndexedDBFakeBackingStore::FakeTransaction(commit_success)); 307 new IndexedDBFakeBackingStore::FakeTransaction(commit_success));
325 db_->TransactionCreated(transaction.get()); 308 db_->TransactionCreated(transaction.get());
326 309
327 // No conflicting transactions, so coordinator will start it immediately: 310 // No conflicting transactions, so coordinator will start it immediately:
328 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state()); 311 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state());
329 EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); 312 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
330 313
331 transaction->ScheduleTask( 314 transaction->ScheduleTask(
332 blink::WebIDBTaskTypePreemptive, 315 blink::WebIDBTaskTypePreemptive,
333 base::Bind(&IndexedDBTransactionTest::DummyOperation, 316 base::Bind(&IndexedDBTransactionTest::DummyOperation,
(...skipping 21 matching lines...) Expand all
355 // This task will be ignored. 338 // This task will be ignored.
356 transaction->ScheduleTask(base::Bind( 339 transaction->ScheduleTask(base::Bind(
357 &IndexedDBTransactionTest::DummyOperation, base::Unretained(this))); 340 &IndexedDBTransactionTest::DummyOperation, base::Unretained(this)));
358 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state()); 341 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
359 EXPECT_FALSE(transaction->IsTimeoutTimerRunning()); 342 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
360 EXPECT_FALSE(transaction->HasPendingTasks()); 343 EXPECT_FALSE(transaction->HasPendingTasks());
361 EXPECT_EQ(transaction->diagnostics().tasks_completed, 344 EXPECT_EQ(transaction->diagnostics().tasks_completed,
362 transaction->diagnostics().tasks_scheduled); 345 transaction->diagnostics().tasks_scheduled);
363 } 346 }
364 347
348 TEST_F(IndexedDBTransactionTest, IndexedDBObserver) {
349 const int64_t id = 0;
350 const std::set<int64_t> scope;
351 const leveldb::Status commit_success = leveldb::Status::OK();
352 IndexedDBConnection* connection =
Marijn Kruisselbrink 2016/06/30 00:17:25 probably make this a std::unique_ptr<IndexedDBConn
palakj1 2016/06/30 01:07:04 Done.
353 new IndexedDBConnection(db_, new MockIndexedDBDatabaseCallbacks());
354
355 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
356 id, connection, scope, blink::WebIDBTransactionModeReadWrite,
357 new IndexedDBFakeBackingStore::FakeTransaction(commit_success));
358 db_->TransactionCreated(transaction.get());
359
360 EXPECT_EQ(0UL, transaction->pending_observers_.size());
361 EXPECT_EQ(0UL, connection->active_observers().size());
362
363 // Add observers to pending observer list.
364 const int32_t observer_id1 = 1, observer_id2 = 2;
365 transaction->AddPendingObserver(observer_id1);
366 transaction->AddPendingObserver(observer_id2);
367 EXPECT_EQ(2UL, transaction->pending_observers_.size());
368 EXPECT_EQ(0UL, connection->active_observers().size());
369
370 // Before commit, observer would be in pending list of transaction.
371 std::vector<int32_t> observer_to_remove1 = {observer_id1};
372 connection->RemoveObservers(observer_to_remove1);
373 EXPECT_EQ(1UL, transaction->pending_observers_.size());
374 EXPECT_EQ(0UL, connection->active_observers().size());
375
376 // After commit, observer moved to connection's active observer.
377 transaction->Commit();
378 EXPECT_EQ(0UL, transaction->pending_observers_.size());
379 EXPECT_EQ(1UL, connection->active_observers().size());
380
381 // Observer does not exist, so no change to active_observers.
382 connection->RemoveObservers(observer_to_remove1);
383 EXPECT_EQ(1UL, connection->active_observers().size());
384
385 // Observer removed from connection's active observer.
386 std::vector<int32_t> observer_to_remove2 = {observer_id2};
387 connection->RemoveObservers(observer_to_remove2);
388 EXPECT_EQ(0UL, connection->active_observers().size());
389 }
390
365 static const blink::WebIDBTransactionMode kTestModes[] = { 391 static const blink::WebIDBTransactionMode kTestModes[] = {
366 blink::WebIDBTransactionModeReadOnly, blink::WebIDBTransactionModeReadWrite, 392 blink::WebIDBTransactionModeReadOnly, blink::WebIDBTransactionModeReadWrite,
367 blink::WebIDBTransactionModeVersionChange}; 393 blink::WebIDBTransactionModeVersionChange};
368 394
369 INSTANTIATE_TEST_CASE_P(IndexedDBTransactions, 395 INSTANTIATE_TEST_CASE_P(IndexedDBTransactions,
370 IndexedDBTransactionTestMode, 396 IndexedDBTransactionTestMode,
371 ::testing::ValuesIn(kTestModes)); 397 ::testing::ValuesIn(kTestModes));
372 398
373 } // namespace content 399 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698