Battery Status API: add UMA logging for Linux.
[chromium-blink-merge.git] / content / browser / indexed_db / indexed_db_transaction_unittest.cc
blobe033dd79e64a9daf5b35e75d6e1d4981cc9ca3e2
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 "content/browser/indexed_db/mock_indexed_db_factory.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace content {
18 class AbortObserver {
19 public:
20 AbortObserver() : abort_task_called_(false) {}
22 void AbortTask(IndexedDBTransaction* transaction) {
23 abort_task_called_ = true;
26 bool abort_task_called() const { return abort_task_called_; }
28 private:
29 bool abort_task_called_;
30 DISALLOW_COPY_AND_ASSIGN(AbortObserver);
33 class IndexedDBTransactionTest : public testing::Test {
34 public:
35 IndexedDBTransactionTest() : factory_(new MockIndexedDBFactory()) {
36 backing_store_ = new IndexedDBFakeBackingStore();
37 CreateDB();
40 void CreateDB() {
41 // DB is created here instead of the constructor to workaround a
42 // "peculiarity of C++". More info at
43 // https://code.google.com/p/googletest/wiki/FAQ#My_compiler_complains_that_a_constructor_(or_destructor)_cannot
44 leveldb::Status s;
45 db_ = IndexedDBDatabase::Create(base::ASCIIToUTF16("db"),
46 backing_store_.get(),
47 factory_.get(),
48 IndexedDBDatabase::Identifier(),
49 &s);
50 ASSERT_TRUE(s.ok());
53 void RunPostedTasks() { message_loop_.RunUntilIdle(); }
54 void DummyOperation(IndexedDBTransaction* transaction) {}
55 void AbortableOperation(AbortObserver* observer,
56 IndexedDBTransaction* transaction) {
57 transaction->ScheduleAbortTask(
58 base::Bind(&AbortObserver::AbortTask, base::Unretained(observer)));
61 protected:
62 scoped_refptr<IndexedDBFakeBackingStore> backing_store_;
63 scoped_refptr<IndexedDBDatabase> db_;
65 private:
66 base::MessageLoop message_loop_;
67 scoped_refptr<MockIndexedDBFactory> factory_;
69 DISALLOW_COPY_AND_ASSIGN(IndexedDBTransactionTest);
72 class IndexedDBTransactionTestMode
73 : public IndexedDBTransactionTest,
74 public testing::WithParamInterface<blink::WebIDBTransactionMode> {
75 public:
76 IndexedDBTransactionTestMode() {}
77 private:
78 DISALLOW_COPY_AND_ASSIGN(IndexedDBTransactionTestMode);
81 TEST_F(IndexedDBTransactionTest, Timeout) {
82 const int64 id = 0;
83 const std::set<int64> scope;
84 const leveldb::Status commit_success = leveldb::Status::OK();
85 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
86 id,
87 new MockIndexedDBDatabaseCallbacks(),
88 scope,
89 blink::WebIDBTransactionModeReadWrite,
90 db_.get(),
91 new IndexedDBFakeBackingStore::FakeTransaction(commit_success));
92 db_->TransactionCreated(transaction.get());
94 // No conflicting transactions, so coordinator will start it immediately:
95 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state());
96 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
97 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
98 EXPECT_EQ(0, transaction->diagnostics().tasks_completed);
100 // Schedule a task - timer won't be started until it's processed.
101 transaction->ScheduleTask(base::Bind(
102 &IndexedDBTransactionTest::DummyOperation, base::Unretained(this)));
103 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
104 EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
105 EXPECT_EQ(0, transaction->diagnostics().tasks_completed);
107 RunPostedTasks();
108 EXPECT_TRUE(transaction->IsTimeoutTimerRunning());
110 transaction->Timeout();
111 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
112 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
113 EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
114 EXPECT_EQ(1, transaction->diagnostics().tasks_completed);
116 // This task will be ignored.
117 transaction->ScheduleTask(base::Bind(
118 &IndexedDBTransactionTest::DummyOperation, base::Unretained(this)));
119 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
120 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
121 EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
122 EXPECT_EQ(1, transaction->diagnostics().tasks_completed);
125 TEST_F(IndexedDBTransactionTest, NoTimeoutReadOnly) {
126 const int64 id = 0;
127 const std::set<int64> scope;
128 const leveldb::Status commit_success = leveldb::Status::OK();
129 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
131 new MockIndexedDBDatabaseCallbacks(),
132 scope,
133 blink::WebIDBTransactionModeReadOnly,
134 db_.get(),
135 new IndexedDBFakeBackingStore::FakeTransaction(commit_success));
136 db_->TransactionCreated(transaction.get());
138 // No conflicting transactions, so coordinator will start it immediately:
139 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state());
140 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
142 // Schedule a task - timer won't be started until it's processed.
143 transaction->ScheduleTask(base::Bind(
144 &IndexedDBTransactionTest::DummyOperation, base::Unretained(this)));
145 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
147 // Transaction is read-only, so no need to time it out.
148 RunPostedTasks();
149 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
151 // Clean up to avoid leaks.
152 transaction->Abort();
153 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
154 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
157 TEST_P(IndexedDBTransactionTestMode, ScheduleNormalTask) {
158 const int64 id = 0;
159 const std::set<int64> scope;
160 const leveldb::Status commit_success = leveldb::Status::OK();
161 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
163 new MockIndexedDBDatabaseCallbacks(),
164 scope,
165 GetParam(),
166 db_.get(),
167 new IndexedDBFakeBackingStore::FakeTransaction(commit_success));
169 EXPECT_FALSE(transaction->HasPendingTasks());
170 EXPECT_TRUE(transaction->IsTaskQueueEmpty());
171 EXPECT_TRUE(transaction->task_queue_.empty());
172 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
173 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
174 EXPECT_EQ(0, transaction->diagnostics().tasks_completed);
176 db_->TransactionCreated(transaction.get());
178 EXPECT_FALSE(transaction->HasPendingTasks());
179 EXPECT_TRUE(transaction->IsTaskQueueEmpty());
180 EXPECT_TRUE(transaction->task_queue_.empty());
181 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
183 transaction->ScheduleTask(
184 blink::WebIDBTaskTypeNormal,
185 base::Bind(&IndexedDBTransactionTest::DummyOperation,
186 base::Unretained(this)));
188 EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
189 EXPECT_EQ(0, transaction->diagnostics().tasks_completed);
191 EXPECT_TRUE(transaction->HasPendingTasks());
192 EXPECT_FALSE(transaction->IsTaskQueueEmpty());
193 EXPECT_FALSE(transaction->task_queue_.empty());
194 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
196 // Pump the message loop so that the transaction completes all pending tasks,
197 // otherwise it will defer the commit.
198 base::MessageLoop::current()->RunUntilIdle();
199 EXPECT_FALSE(transaction->HasPendingTasks());
200 EXPECT_TRUE(transaction->IsTaskQueueEmpty());
201 EXPECT_TRUE(transaction->task_queue_.empty());
202 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
203 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state());
204 EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
205 EXPECT_EQ(1, transaction->diagnostics().tasks_completed);
207 transaction->Commit();
209 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
210 EXPECT_FALSE(transaction->HasPendingTasks());
211 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
212 EXPECT_TRUE(transaction->IsTaskQueueEmpty());
213 EXPECT_TRUE(transaction->task_queue_.empty());
214 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
215 EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
216 EXPECT_EQ(1, transaction->diagnostics().tasks_completed);
219 TEST_F(IndexedDBTransactionTest, SchedulePreemptiveTask) {
220 const int64 id = 0;
221 const std::set<int64> scope;
222 const leveldb::Status commit_failure = leveldb::Status::Corruption("Ouch.");
223 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
225 new MockIndexedDBDatabaseCallbacks(),
226 scope,
227 blink::WebIDBTransactionModeVersionChange,
228 db_.get(),
229 new IndexedDBFakeBackingStore::FakeTransaction(commit_failure));
231 EXPECT_FALSE(transaction->HasPendingTasks());
232 EXPECT_TRUE(transaction->IsTaskQueueEmpty());
233 EXPECT_TRUE(transaction->task_queue_.empty());
234 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
235 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
236 EXPECT_EQ(0, transaction->diagnostics().tasks_completed);
238 db_->TransactionCreated(transaction.get());
240 EXPECT_FALSE(transaction->HasPendingTasks());
241 EXPECT_TRUE(transaction->IsTaskQueueEmpty());
242 EXPECT_TRUE(transaction->task_queue_.empty());
243 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
245 transaction->ScheduleTask(
246 blink::WebIDBTaskTypePreemptive,
247 base::Bind(&IndexedDBTransactionTest::DummyOperation,
248 base::Unretained(this)));
249 transaction->AddPreemptiveEvent();
251 EXPECT_TRUE(transaction->HasPendingTasks());
252 EXPECT_FALSE(transaction->IsTaskQueueEmpty());
253 EXPECT_TRUE(transaction->task_queue_.empty());
254 EXPECT_FALSE(transaction->preemptive_task_queue_.empty());
256 // Pump the message loop so that the transaction completes all pending tasks,
257 // otherwise it will defer the commit.
258 base::MessageLoop::current()->RunUntilIdle();
259 EXPECT_TRUE(transaction->HasPendingTasks());
260 EXPECT_TRUE(transaction->IsTaskQueueEmpty());
261 EXPECT_TRUE(transaction->task_queue_.empty());
262 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
263 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state());
264 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
265 EXPECT_EQ(0, transaction->diagnostics().tasks_completed);
267 transaction->DidCompletePreemptiveEvent();
268 transaction->Commit();
270 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
271 EXPECT_FALSE(transaction->HasPendingTasks());
272 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
273 EXPECT_TRUE(transaction->IsTaskQueueEmpty());
274 EXPECT_TRUE(transaction->task_queue_.empty());
275 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
276 EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
277 EXPECT_EQ(0, transaction->diagnostics().tasks_completed);
280 TEST_P(IndexedDBTransactionTestMode, AbortTasks) {
281 const int64 id = 0;
282 const std::set<int64> scope;
283 const leveldb::Status commit_failure = leveldb::Status::Corruption("Ouch.");
284 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
286 new MockIndexedDBDatabaseCallbacks(),
287 scope,
288 GetParam(),
289 db_.get(),
290 new IndexedDBFakeBackingStore::FakeTransaction(commit_failure));
291 db_->TransactionCreated(transaction.get());
293 AbortObserver observer;
294 transaction->ScheduleTask(
295 base::Bind(&IndexedDBTransactionTest::AbortableOperation,
296 base::Unretained(this),
297 base::Unretained(&observer)));
299 // Pump the message loop so that the transaction completes all pending tasks,
300 // otherwise it will defer the commit.
301 base::MessageLoop::current()->RunUntilIdle();
303 EXPECT_FALSE(observer.abort_task_called());
304 transaction->Commit();
305 EXPECT_TRUE(observer.abort_task_called());
306 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
307 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
310 TEST_P(IndexedDBTransactionTestMode, AbortPreemptive) {
311 const int64 id = 0;
312 const std::set<int64> scope;
313 const leveldb::Status commit_success = leveldb::Status::OK();
314 scoped_refptr<IndexedDBTransaction> transaction = new IndexedDBTransaction(
316 new MockIndexedDBDatabaseCallbacks(),
317 scope,
318 GetParam(),
319 db_.get(),
320 new IndexedDBFakeBackingStore::FakeTransaction(commit_success));
321 db_->TransactionCreated(transaction.get());
323 // No conflicting transactions, so coordinator will start it immediately:
324 EXPECT_EQ(IndexedDBTransaction::STARTED, transaction->state());
325 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
327 transaction->ScheduleTask(
328 blink::WebIDBTaskTypePreemptive,
329 base::Bind(&IndexedDBTransactionTest::DummyOperation,
330 base::Unretained(this)));
331 EXPECT_EQ(0, transaction->pending_preemptive_events_);
332 transaction->AddPreemptiveEvent();
333 EXPECT_EQ(1, transaction->pending_preemptive_events_);
335 RunPostedTasks();
337 transaction->Abort();
338 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
339 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
340 EXPECT_EQ(0, transaction->pending_preemptive_events_);
341 EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
342 EXPECT_TRUE(transaction->task_queue_.empty());
343 EXPECT_FALSE(transaction->HasPendingTasks());
344 EXPECT_EQ(transaction->diagnostics().tasks_completed,
345 transaction->diagnostics().tasks_scheduled);
346 EXPECT_FALSE(transaction->should_process_queue_);
347 EXPECT_TRUE(transaction->backing_store_transaction_begun_);
348 EXPECT_TRUE(transaction->used_);
349 EXPECT_FALSE(transaction->commit_pending_);
351 // This task will be ignored.
352 transaction->ScheduleTask(base::Bind(
353 &IndexedDBTransactionTest::DummyOperation, base::Unretained(this)));
354 EXPECT_EQ(IndexedDBTransaction::FINISHED, transaction->state());
355 EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
356 EXPECT_FALSE(transaction->HasPendingTasks());
357 EXPECT_EQ(transaction->diagnostics().tasks_completed,
358 transaction->diagnostics().tasks_scheduled);
361 static const blink::WebIDBTransactionMode kTestModes[] = {
362 blink::WebIDBTransactionModeReadOnly, blink::WebIDBTransactionModeReadWrite,
363 blink::WebIDBTransactionModeVersionChange};
365 INSTANTIATE_TEST_CASE_P(IndexedDBTransactions,
366 IndexedDBTransactionTestMode,
367 ::testing::ValuesIn(kTestModes));
369 } // namespace content