OLD | NEW |
---|---|
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_database.h" | 5 #include "content/browser/indexed_db/indexed_db_database.h" |
6 | 6 |
7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/strings/string16.h" | 9 #include "base/strings/string16.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
11 #include "content/browser/indexed_db/indexed_db.h" | 11 #include "content/browser/indexed_db/indexed_db.h" |
12 #include "content/browser/indexed_db/indexed_db_backing_store.h" | 12 #include "content/browser/indexed_db/indexed_db_backing_store.h" |
13 #include "content/browser/indexed_db/indexed_db_callbacks.h" | 13 #include "content/browser/indexed_db/indexed_db_callbacks.h" |
14 #include "content/browser/indexed_db/indexed_db_connection.h" | 14 #include "content/browser/indexed_db/indexed_db_connection.h" |
15 #include "content/browser/indexed_db/indexed_db_cursor.h" | 15 #include "content/browser/indexed_db/indexed_db_cursor.h" |
16 #include "content/browser/indexed_db/indexed_db_database.h" | 16 #include "content/browser/indexed_db/indexed_db_database.h" |
17 #include "content/browser/indexed_db/indexed_db_factory.h" | 17 #include "content/browser/indexed_db/indexed_db_factory.h" |
18 #include "content/browser/indexed_db/indexed_db_fake_backing_store.h" | 18 #include "content/browser/indexed_db/indexed_db_fake_backing_store.h" |
19 #include "content/browser/indexed_db/indexed_db_transaction.h" | 19 #include "content/browser/indexed_db/indexed_db_transaction.h" |
20 #include "content/browser/indexed_db/mock_indexed_db_callbacks.h" | 20 #include "content/browser/indexed_db/mock_indexed_db_callbacks.h" |
21 #include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h" | 21 #include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h" |
22 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
23 | 23 |
24 using base::ASCIIToUTF16; | 24 using base::ASCIIToUTF16; |
25 | 25 |
26 namespace { | 26 namespace { |
27 const int FAKE_CHILD_PROCESS_ID = 0; | 27 const int kFakeChildProcessId = 0; |
28 } | 28 } |
29 | 29 |
30 namespace content { | 30 namespace content { |
31 | 31 |
32 TEST(IndexedDBDatabaseTest, BackingStoreRetention) { | 32 TEST(IndexedDBDatabaseTest, BackingStoreRetention) { |
33 scoped_refptr<IndexedDBFakeBackingStore> backing_store = | 33 scoped_refptr<IndexedDBFakeBackingStore> backing_store = |
34 new IndexedDBFakeBackingStore(); | 34 new IndexedDBFakeBackingStore(); |
35 EXPECT_TRUE(backing_store->HasOneRef()); | 35 EXPECT_TRUE(backing_store->HasOneRef()); |
36 | 36 |
37 IndexedDBFactory* factory = 0; | 37 IndexedDBFactory* factory = 0; |
(...skipping 26 matching lines...) Expand all Loading... | |
64 ASSERT_TRUE(s.ok()); | 64 ASSERT_TRUE(s.ok()); |
65 EXPECT_FALSE(backing_store->HasOneRef()); // local and db | 65 EXPECT_FALSE(backing_store->HasOneRef()); // local and db |
66 | 66 |
67 scoped_refptr<MockIndexedDBCallbacks> request1(new MockIndexedDBCallbacks()); | 67 scoped_refptr<MockIndexedDBCallbacks> request1(new MockIndexedDBCallbacks()); |
68 scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1( | 68 scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1( |
69 new MockIndexedDBDatabaseCallbacks()); | 69 new MockIndexedDBDatabaseCallbacks()); |
70 const int64 transaction_id1 = 1; | 70 const int64 transaction_id1 = 1; |
71 IndexedDBPendingConnection connection1( | 71 IndexedDBPendingConnection connection1( |
72 request1, | 72 request1, |
73 callbacks1, | 73 callbacks1, |
74 FAKE_CHILD_PROCESS_ID, | 74 kFakeChildProcessId, |
75 transaction_id1, | 75 transaction_id1, |
76 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); | 76 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); |
77 db->OpenConnection(connection1); | 77 db->OpenConnection(connection1); |
78 | 78 |
79 EXPECT_FALSE(backing_store->HasOneRef()); // db, connection count > 0 | 79 EXPECT_FALSE(backing_store->HasOneRef()); // db, connection count > 0 |
80 | 80 |
81 scoped_refptr<MockIndexedDBCallbacks> request2(new MockIndexedDBCallbacks()); | 81 scoped_refptr<MockIndexedDBCallbacks> request2(new MockIndexedDBCallbacks()); |
82 scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks2( | 82 scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks2( |
83 new MockIndexedDBDatabaseCallbacks()); | 83 new MockIndexedDBDatabaseCallbacks()); |
84 const int64 transaction_id2 = 2; | 84 const int64 transaction_id2 = 2; |
85 IndexedDBPendingConnection connection2( | 85 IndexedDBPendingConnection connection2( |
86 request2, | 86 request2, |
87 callbacks2, | 87 callbacks2, |
88 FAKE_CHILD_PROCESS_ID, | 88 kFakeChildProcessId, |
89 transaction_id2, | 89 transaction_id2, |
90 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); | 90 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); |
91 db->OpenConnection(connection2); | 91 db->OpenConnection(connection2); |
92 | 92 |
93 EXPECT_FALSE(backing_store->HasOneRef()); // local and connection | 93 EXPECT_FALSE(backing_store->HasOneRef()); // local and connection |
94 | 94 |
95 request1->connection()->ForceClose(); | 95 request1->connection()->ForceClose(); |
96 EXPECT_FALSE(request1->connection()->IsConnected()); | 96 EXPECT_FALSE(request1->connection()->IsConnected()); |
97 | 97 |
98 EXPECT_FALSE(backing_store->HasOneRef()); // local and connection | 98 EXPECT_FALSE(backing_store->HasOneRef()); // local and connection |
(...skipping 23 matching lines...) Expand all Loading... | |
122 ASSERT_TRUE(s.ok()); | 122 ASSERT_TRUE(s.ok()); |
123 EXPECT_FALSE(backing_store->HasOneRef()); // local and db | 123 EXPECT_FALSE(backing_store->HasOneRef()); // local and db |
124 | 124 |
125 scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks( | 125 scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks( |
126 new MockIndexedDBDatabaseCallbacks()); | 126 new MockIndexedDBDatabaseCallbacks()); |
127 scoped_refptr<MockIndexedDBCallbacks> request(new MockIndexedDBCallbacks()); | 127 scoped_refptr<MockIndexedDBCallbacks> request(new MockIndexedDBCallbacks()); |
128 const int64 upgrade_transaction_id = 3; | 128 const int64 upgrade_transaction_id = 3; |
129 IndexedDBPendingConnection connection( | 129 IndexedDBPendingConnection connection( |
130 request, | 130 request, |
131 callbacks, | 131 callbacks, |
132 FAKE_CHILD_PROCESS_ID, | 132 kFakeChildProcessId, |
133 upgrade_transaction_id, | 133 upgrade_transaction_id, |
134 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); | 134 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); |
135 database->OpenConnection(connection); | 135 database->OpenConnection(connection); |
136 EXPECT_EQ(database, request->connection()->database()); | 136 EXPECT_EQ(database, request->connection()->database()); |
137 | 137 |
138 const int64 transaction_id = 123; | 138 const int64 transaction_id = 123; |
139 const std::vector<int64> scope; | 139 const std::vector<int64> scope; |
140 database->CreateTransaction(transaction_id, | 140 database->CreateTransaction(transaction_id, |
141 request->connection(), | 141 request->connection(), |
142 scope, | 142 scope, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
186 ASSERT_TRUE(s.ok()); | 186 ASSERT_TRUE(s.ok()); |
187 EXPECT_FALSE(backing_store->HasOneRef()); // local and db | 187 EXPECT_FALSE(backing_store->HasOneRef()); // local and db |
188 | 188 |
189 scoped_refptr<MockIndexedDBCallbacks> request1(new MockIndexedDBCallbacks()); | 189 scoped_refptr<MockIndexedDBCallbacks> request1(new MockIndexedDBCallbacks()); |
190 scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1( | 190 scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks1( |
191 new MockIndexedDBDatabaseCallbacks()); | 191 new MockIndexedDBDatabaseCallbacks()); |
192 const int64 transaction_id1 = 1; | 192 const int64 transaction_id1 = 1; |
193 IndexedDBPendingConnection connection( | 193 IndexedDBPendingConnection connection( |
194 request1, | 194 request1, |
195 callbacks1, | 195 callbacks1, |
196 FAKE_CHILD_PROCESS_ID, | 196 kFakeChildProcessId, |
197 transaction_id1, | 197 transaction_id1, |
198 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); | 198 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); |
199 db->OpenConnection(connection); | 199 db->OpenConnection(connection); |
200 | 200 |
201 EXPECT_FALSE(backing_store->HasOneRef()); // local and db | 201 EXPECT_FALSE(backing_store->HasOneRef()); // local and db |
202 | 202 |
203 scoped_refptr<MockDeleteCallbacks> request2(new MockDeleteCallbacks()); | 203 scoped_refptr<MockDeleteCallbacks> request2(new MockDeleteCallbacks()); |
204 db->DeleteDatabase(request2); | 204 db->DeleteDatabase(request2); |
205 | 205 |
206 EXPECT_TRUE(request2->blocked_called()); | 206 EXPECT_TRUE(request2->blocked_called()); |
207 EXPECT_FALSE(backing_store->HasOneRef()); // local and db | 207 EXPECT_FALSE(backing_store->HasOneRef()); // local and db |
208 | 208 |
209 db->Close(request1->connection(), true /* forced */); | 209 db->Close(request1->connection(), true /* forced */); |
210 | 210 |
211 EXPECT_FALSE(db->backing_store()); | 211 EXPECT_FALSE(db->backing_store()); |
212 EXPECT_TRUE(backing_store->HasOneRef()); // local | 212 EXPECT_TRUE(backing_store->HasOneRef()); // local |
213 EXPECT_TRUE(request2->success_called()); | 213 EXPECT_TRUE(request2->success_called()); |
214 } | 214 } |
215 | 215 |
216 void DummyOperation(IndexedDBTransaction* transaction) { | |
217 } | |
218 | |
219 class IndexedDBDatabaseOperationTest : public testing::Test { | |
220 public: | |
221 IndexedDBDatabaseOperationTest() : commit_success_(true) {} | |
222 | |
223 virtual void SetUp() { | |
224 backing_store_ = new IndexedDBFakeBackingStore(); | |
225 leveldb::Status s; | |
226 db_ = IndexedDBDatabase::Create(ASCIIToUTF16("db"), | |
227 backing_store_, | |
228 NULL /*factory*/, | |
229 IndexedDBDatabase::Identifier(), | |
230 &s); | |
231 ASSERT_TRUE(s.ok()); | |
232 | |
233 request_ = new MockIndexedDBCallbacks(); | |
234 callbacks_ = new MockIndexedDBDatabaseCallbacks(); | |
235 const int64 transaction_id = 1; | |
236 db_->OpenConnection(IndexedDBPendingConnection( | |
237 request_, | |
238 callbacks_, | |
239 kFakeChildProcessId, | |
240 transaction_id, | |
241 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION)); | |
242 EXPECT_EQ(IndexedDBDatabaseMetadata::NO_INT_VERSION, | |
243 db_->metadata().int_version); | |
244 | |
245 transaction_ = new IndexedDBTransaction( | |
246 transaction_id, | |
247 callbacks_, | |
248 std::set<int64>() /*scope*/, | |
249 indexed_db::TRANSACTION_VERSION_CHANGE, | |
250 db_, | |
251 new IndexedDBFakeBackingStore::FakeTransaction(commit_success_)); | |
252 db_->TransactionCreated(transaction_); | |
253 | |
254 // Add a dummy task which takes the place of the VersionChangeOperation | |
255 // which kicks off the upgrade. This ensures that the transaction has | |
256 // processed at least one task before the CreateObjectStore call. | |
ericu
2014/05/14 01:08:00
Why is that desirable?
jsbell
2014/05/14 11:05:52
The previous formulation of abort tasks was WEIRD.
| |
257 transaction_->ScheduleTask(base::Bind(&DummyOperation)); | |
258 } | |
259 | |
260 void RunPostedTasks() { message_loop_.RunUntilIdle(); } | |
ericu
2014/05/14 01:08:00
MessageLoop::RunUntilIdle is deprecated.
All the c
jsbell
2014/05/14 11:05:52
Will fix, thanks.
| |
261 | |
262 protected: | |
263 scoped_refptr<IndexedDBFakeBackingStore> backing_store_; | |
264 scoped_refptr<IndexedDBDatabase> db_; | |
265 scoped_refptr<MockIndexedDBCallbacks> request_; | |
266 scoped_refptr<MockIndexedDBDatabaseCallbacks> callbacks_; | |
267 scoped_refptr<IndexedDBTransaction> transaction_; | |
268 | |
269 bool commit_success_; | |
270 | |
271 private: | |
272 base::MessageLoop message_loop_; | |
273 | |
274 DISALLOW_COPY_AND_ASSIGN(IndexedDBDatabaseOperationTest); | |
275 }; | |
276 | |
277 TEST_F(IndexedDBDatabaseOperationTest, CreateObjectStore) { | |
278 EXPECT_EQ(0ULL, db_->metadata().object_stores.size()); | |
279 const int64 store_id = 1001; | |
280 db_->CreateObjectStore(transaction_->id(), | |
281 store_id, | |
282 ASCIIToUTF16("store"), | |
283 IndexedDBKeyPath(), | |
284 false /*auto_increment*/); | |
285 EXPECT_EQ(1ULL, db_->metadata().object_stores.size()); | |
286 RunPostedTasks(); | |
287 transaction_->Commit(); | |
288 EXPECT_EQ(1ULL, db_->metadata().object_stores.size()); | |
289 } | |
290 | |
ericu
2014/05/14 01:08:00
How about a test that captures the create-put-dele
jsbell
2014/05/14 11:05:52
Will add one. (I have a blink layout test, but can
| |
291 TEST_F(IndexedDBDatabaseOperationTest, CreateIndex) { | |
292 EXPECT_EQ(0ULL, db_->metadata().object_stores.size()); | |
293 const int64 store_id = 1001; | |
294 db_->CreateObjectStore(transaction_->id(), | |
295 store_id, | |
296 ASCIIToUTF16("store"), | |
297 IndexedDBKeyPath(), | |
298 false /*auto_increment*/); | |
299 EXPECT_EQ(1ULL, db_->metadata().object_stores.size()); | |
300 const int64 index_id = 2002; | |
301 db_->CreateIndex(transaction_->id(), | |
302 store_id, | |
303 index_id, | |
304 ASCIIToUTF16("index"), | |
305 IndexedDBKeyPath(), | |
306 false /*unique*/, | |
307 false /*multi_entry*/); | |
308 EXPECT_EQ( | |
309 1ULL, | |
310 db_->metadata().object_stores.find(store_id)->second.indexes.size()); | |
311 RunPostedTasks(); | |
312 transaction_->Commit(); | |
313 EXPECT_EQ(1ULL, db_->metadata().object_stores.size()); | |
314 EXPECT_EQ( | |
315 1ULL, | |
316 db_->metadata().object_stores.find(store_id)->second.indexes.size()); | |
317 } | |
318 | |
319 class IndexedDBDatabaseOperationAbortTest | |
320 : public IndexedDBDatabaseOperationTest { | |
321 public: | |
322 IndexedDBDatabaseOperationAbortTest() { commit_success_ = false; } | |
323 }; | |
324 | |
325 TEST_F(IndexedDBDatabaseOperationAbortTest, CreateObjectStore) { | |
326 EXPECT_EQ(0ULL, db_->metadata().object_stores.size()); | |
327 const int64 store_id = 1001; | |
328 db_->CreateObjectStore(transaction_->id(), | |
329 store_id, | |
330 ASCIIToUTF16("store"), | |
331 IndexedDBKeyPath(), | |
332 false /*auto_increment*/); | |
333 EXPECT_EQ(1ULL, db_->metadata().object_stores.size()); | |
334 RunPostedTasks(); | |
335 transaction_->Commit(); | |
336 EXPECT_EQ(0ULL, db_->metadata().object_stores.size()); | |
337 } | |
338 | |
339 TEST_F(IndexedDBDatabaseOperationAbortTest, CreateIndex) { | |
340 EXPECT_EQ(0ULL, db_->metadata().object_stores.size()); | |
341 const int64 store_id = 1001; | |
342 db_->CreateObjectStore(transaction_->id(), | |
343 store_id, | |
344 ASCIIToUTF16("store"), | |
345 IndexedDBKeyPath(), | |
346 false /*auto_increment*/); | |
347 EXPECT_EQ(1ULL, db_->metadata().object_stores.size()); | |
348 const int64 index_id = 2002; | |
349 db_->CreateIndex(transaction_->id(), | |
350 store_id, | |
351 index_id, | |
352 ASCIIToUTF16("index"), | |
353 IndexedDBKeyPath(), | |
354 false /*unique*/, | |
355 false /*multi_entry*/); | |
356 EXPECT_EQ( | |
357 1ULL, | |
358 db_->metadata().object_stores.find(store_id)->second.indexes.size()); | |
359 RunPostedTasks(); | |
360 transaction_->Commit(); | |
361 EXPECT_EQ(0ULL, db_->metadata().object_stores.size()); | |
362 } | |
363 | |
216 } // namespace content | 364 } // namespace content |
OLD | NEW |