Resetting pending_preemptive_events_ in IndexedDBTransaction::Abort.
[chromium-blink-merge.git] / content / browser / indexed_db / indexed_db_transaction_unittest.cc
blob56dfd7c519f97d5c727deb7317dc6357d0d0ae49
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
3 // found in the LICENSE file.
5 #include "content/browser/indexed_db/indexed_db_transaction.h"
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "content/browser/indexed_db/indexed_db_fake_backing_store.h"
12 #include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 namespace content {
17 class IndexedDBTransactionTest : public testing::Test {
18 public:
19 IndexedDBTransactionTest() {
20 IndexedDBFactory* factory = NULL;
21 backing_store_ = new IndexedDBFakeBackingStore();
22 db_ = IndexedDBDatabase::Create(base::ASCIIToUTF16("db"),
23 backing_store_,
24 factory,
25 IndexedDBDatabase::Identifier());
28 void RunPostedTasks() { message_loop_.RunUntilIdle(); }
29 void DummyOperation(IndexedDBTransaction* transaction) {}
31 protected:
32 scoped_refptr<IndexedDBFakeBackingStore> backing_store_;
33 scoped_refptr<IndexedDBDatabase> db_;
35 private:
36 base::MessageLoop message_loop_;
38 DISALLOW_COPY_AND_ASSIGN(IndexedDBTransactionTest);
41 class IndexedDBTransactionTestMode : public IndexedDBTransactionTest,
42 public testing::WithParamInterface<indexed_db::TransactionMode> {
43 public:
44 IndexedDBTransactionTestMode() {}
45 private:
46 DISALLOW_COPY_AND_ASSIGN(IndexedDBTransactionTestMode);
49 TEST_F(IndexedDBTransactionTest, Timeout) {
50 const int64 id = 0;
51 const std::set<int64> scope;
52 const bool commit_success = true;
53 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
54 id,
55 new MockIndexedDBDatabaseCallbacks(),
56 scope,
57 indexed_db::TRANSACTION_READ_WRITE,
58 db_,
59 new IndexedDBFakeBackingStore::FakeTransaction(commit_success));
60 db_->TransactionCreated(transaction);
62 // No conflicting transactions, so coordinator will start it immediately:
63 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state());
64 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
66 // Schedule a task - timer won't be started until it's processed.
67 transaction->ScheduleTask(base::Bind(
68 &IndexedDBTransactionTest::DummyOperation, base::Unretained(this)));
69 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
71 RunPostedTasks();
72 EXPECT_TRUE(transaction->IsTimeoutTimerRunning());
74 // Abort should cancel the timer.
75 transaction->Abort();
76 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
77 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
79 // This task will be ignored.
80 transaction->ScheduleTask(base::Bind(
81 &IndexedDBTransactionTest::DummyOperation, base::Unretained(this)));
82 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
83 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
86 TEST_F(IndexedDBTransactionTest, NoTimeoutReadOnly) {
87 const int64 id = 0;
88 const std::set<int64> scope;
89 const bool commit_success = true;
90 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
91 id,
92 new MockIndexedDBDatabaseCallbacks(),
93 scope,
94 indexed_db::TRANSACTION_READ_ONLY,
95 db_,
96 new IndexedDBFakeBackingStore::FakeTransaction(commit_success));
97 db_->TransactionCreated(transaction);
99 // No conflicting transactions, so coordinator will start it immediately:
100 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state());
101 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
103 // Schedule a task - timer won't be started until it's processed.
104 transaction->ScheduleTask(base::Bind(
105 &IndexedDBTransactionTest::DummyOperation, base::Unretained(this)));
106 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
108 // Transaction is read-only, so no need to time it out.
109 RunPostedTasks();
110 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
112 // Clean up to avoid leaks.
113 transaction->Abort();
114 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
115 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
118 class AbortObserver {
119 public:
120 AbortObserver() : abort_task_called_(false) {}
122 void AbortTask(IndexedDBTransaction* transaction) {
123 abort_task_called_ = true;
126 bool abort_task_called() const { return abort_task_called_; }
128 private:
129 bool abort_task_called_;
130 DISALLOW_COPY_AND_ASSIGN(AbortObserver);
133 TEST_P(IndexedDBTransactionTestMode, AbortTasks) {
134 const int64 id = 0;
135 const std::set<int64> scope;
136 const bool commit_failure = false;
137 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
139 new MockIndexedDBDatabaseCallbacks(),
140 scope,
141 GetParam(),
142 db_,
143 new IndexedDBFakeBackingStore::FakeTransaction(commit_failure));
144 db_->TransactionCreated(transaction);
146 AbortObserver observer;
147 transaction->ScheduleTask(
148 base::Bind(&IndexedDBTransactionTest::DummyOperation,
149 base::Unretained(this)),
150 base::Bind(&AbortObserver::AbortTask, base::Unretained(&observer)));
152 // Pump the message loop so that the transaction completes all pending tasks,
153 // otherwise it will defer the commit.
154 base::MessageLoop::current()->RunUntilIdle();
156 EXPECT_FALSE(observer.abort_task_called());
157 transaction->Commit();
158 EXPECT_TRUE(observer.abort_task_called());
159 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
160 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
163 TEST_P(IndexedDBTransactionTestMode, AbortPreemptive) {
164 const int64 id = 0;
165 const std::set<int64> scope;
166 const bool commit_success = true;
167 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
169 new MockIndexedDBDatabaseCallbacks(),
170 scope,
171 GetParam(),
172 db_,
173 new IndexedDBFakeBackingStore::FakeTransaction(commit_success));
174 db_->TransactionCreated(transaction);
176 // No conflicting transactions, so coordinator will start it immediately:
177 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state());
178 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
180 transaction->ScheduleTask(
181 IndexedDBDatabase::PREEMPTIVE_TASK,
182 base::Bind(&IndexedDBTransactionTest::DummyOperation,
183 base::Unretained(this)));
184 EXPECT_EQ(0, transaction->pending_preemptive_events_);
185 transaction->AddPreemptiveEvent();
186 EXPECT_EQ(1, transaction->pending_preemptive_events_);
188 RunPostedTasks();
190 transaction->Abort();
191 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
192 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
193 EXPECT_EQ(0, transaction->pending_preemptive_events_);
194 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
195 EXPECT_TRUE(transaction->task_queue_.empty());
196 EXPECT_FALSE(transaction->HasPendingTasks());
197 EXPECT_EQ(transaction->diagnostics().tasks_completed,
198 transaction->diagnostics().tasks_scheduled);
199 EXPECT_FALSE(transaction->should_process_queue_);
200 EXPECT_TRUE(transaction->backing_store_transaction_begun_);
201 EXPECT_TRUE(transaction->used_);
202 EXPECT_FALSE(transaction->commit_pending_);
204 // This task will be ignored.
205 transaction->ScheduleTask(base::Bind(
206 &IndexedDBTransactionTest::DummyOperation, base::Unretained(this)));
207 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
208 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
209 EXPECT_FALSE(transaction->HasPendingTasks());
210 EXPECT_EQ(transaction->diagnostics().tasks_completed,
211 transaction->diagnostics().tasks_scheduled);
214 static const indexed_db::TransactionMode kTestModes[] = {
215 indexed_db::TRANSACTION_READ_ONLY,
216 indexed_db::TRANSACTION_READ_WRITE,
217 indexed_db::TRANSACTION_VERSION_CHANGE
220 INSTANTIATE_TEST_CASE_P(IndexedDBTransactions,
221 IndexedDBTransactionTestMode,
222 ::testing::ValuesIn(kTestModes));
224 } // namespace content