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

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

Issue 18023022: Blob support for IDB [Chromium] (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Use ScopedVector and stl_utils for BlobDataHandles. Created 7 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 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_backing_store.h" 5 #include "content/browser/indexed_db/indexed_db_backing_store.h"
6 6
7 #include "base/callback.h"
8 #include "base/file_util.h"
9 #include "base/files/scoped_temp_dir.h"
7 #include "base/logging.h" 10 #include "base/logging.h"
8 #include "base/strings/string16.h" 11 #include "base/strings/string16.h"
9 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "base/task_runner.h"
14 #include "base/test/test_simple_task_runner.h"
15 #include "content/browser/indexed_db/indexed_db_context_impl.h"
10 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" 16 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
17 #include "content/browser/indexed_db/indexed_db_value.h"
18 #include "net/url_request/url_request_test_util.h"
11 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
12 #include "third_party/WebKit/public/platform/WebIDBTypes.h" 20 #include "third_party/WebKit/public/platform/WebIDBTypes.h"
21 #include "webkit/browser/blob/blob_data_handle.h"
22 #include "webkit/browser/quota/mock_special_storage_policy.h"
23 #include "webkit/browser/quota/special_storage_policy.h"
13 24
14 namespace content { 25 namespace content {
15 26
16 namespace { 27 namespace {
17 28
29 class Comparator : public LevelDBComparator {
30 public:
31 virtual int Compare(const base::StringPiece& a,
32 const base::StringPiece& b) const OVERRIDE {
33 return content::Compare(a, b, false /*index_keys*/);
34 }
35 virtual const char* Name() const OVERRIDE { return "idb_cmp1"; }
36 };
37
38 class DefaultLevelDBFactory : public LevelDBFactory {
39 public:
40 virtual leveldb::Status OpenLevelDB(const base::FilePath& file_name,
41 const LevelDBComparator* comparator,
42 scoped_ptr<LevelDBDatabase>* db,
43 bool* is_disk_full) OVERRIDE {
44 return LevelDBDatabase::Open(file_name, comparator, db, is_disk_full);
45 }
46 virtual bool DestroyLevelDB(const base::FilePath& file_name) OVERRIDE {
47 return LevelDBDatabase::Destroy(file_name);
48 }
49 };
50
51 class TestableIndexedDBBackingStore : public IndexedDBBackingStore {
52 public:
53 static scoped_refptr<TestableIndexedDBBackingStore> Open(
54 IndexedDBFactory* indexed_db_factory,
55 const GURL& origin_url,
56 const base::FilePath& path_base,
57 net::URLRequestContext* request_context,
58 LevelDBFactory* leveldb_factory,
59 base::TaskRunner* task_runner) {
60 DCHECK(!path_base.empty());
61
62 scoped_ptr<LevelDBComparator> comparator(new Comparator());
63
64 if (!file_util::CreateDirectory(path_base))
65 return scoped_refptr<TestableIndexedDBBackingStore>();
66
67 const base::FilePath file_path = path_base.Append("test_db_path");
68 const base::FilePath blob_path = path_base.Append("test_blob_path");
69
70 scoped_ptr<LevelDBDatabase> db;
71 bool is_disk_full = false;
72 leveldb::Status status = leveldb_factory->OpenLevelDB(
73 file_path, comparator.get(), &db, &is_disk_full);
74
75 if (!db || !status.ok())
76 return scoped_refptr<TestableIndexedDBBackingStore>();
77
78 scoped_refptr<TestableIndexedDBBackingStore> backing_store(
79 new TestableIndexedDBBackingStore(indexed_db_factory, origin_url,
80 blob_path, request_context, db.Pass(), comparator.Pass(),
81 task_runner));
82
83 if (!backing_store->SetUpMetadata())
84 return scoped_refptr<TestableIndexedDBBackingStore>();
85
86 return backing_store;
87 }
88
89 const std::vector<IndexedDBBackingStore::Transaction::WriteDescriptor>&
90 writes() const { return writes_; }
91 const std::vector<int64> removals() const { return removals_; }
92
93 protected:
94 bool WriteBlobFile(int64 database_id,
95 const Transaction::WriteDescriptor& descriptor,
96 Transaction::ChainedBlobWriter* chained_blob_writer)
97 OVERRIDE {
98 if (KeyPrefix::IsValidDatabaseId(database_id_)) {
99 if (database_id_ != database_id) {
100 return false;
101 }
102 } else {
103 database_id_ = database_id;
104 }
105 writes_.push_back(descriptor);
106 task_runner()->PostTask(
107 FROM_HERE,
108 base::Bind(
109 &Transaction::ChainedBlobWriter::ReportWriteCompletion,
110 chained_blob_writer, true, 1));
111 return true;
112 }
113
114 bool RemoveBlobFile(int64 database_id, int64 key) OVERRIDE {
115 if (database_id_ != database_id ||
116 !KeyPrefix::IsValidDatabaseId(database_id)) {
117 return false;
118 }
119 removals_.push_back(key);
120 return true;
121 }
122
123 // Timers don't play nicely with unit tests.
124 void StartJournalCleaningTimer() OVERRIDE {
125 CleanPrimaryJournalIgnoreReturn();
126 }
127
128 private:
129 TestableIndexedDBBackingStore(
130 IndexedDBFactory* indexed_db_factory,
131 const GURL& origin_url,
132 const base::FilePath& blob_path,
133 net::URLRequestContext* request_context,
134 scoped_ptr<LevelDBDatabase> db,
135 scoped_ptr<LevelDBComparator> comparator,
136 base::TaskRunner* task_runner)
137 : IndexedDBBackingStore(indexed_db_factory,
138 origin_url,
139 blob_path,
140 request_context,
141 db.Pass(),
142 comparator.Pass(),
143 task_runner),
144 database_id_(0) {}
145
146 int64 database_id_;
147 std::vector<Transaction::WriteDescriptor> writes_;
148 std::vector<int64> removals_;
149 };
150
151 class TestIDBFactory : public IndexedDBFactory {
152 public:
153 TestIDBFactory(IndexedDBContextImpl* idb_context)
154 : IndexedDBFactory(idb_context) {}
155
156 scoped_refptr<TestableIndexedDBBackingStore> OpenBackingStoreForTest(
157 const GURL& origin,
158 net::URLRequestContext* url_request_context,
159 base::TaskRunner* task_runner) {
160 blink::WebIDBDataLoss data_loss;
161 std::string data_loss_reason;
162 bool disk_full;
163 scoped_refptr<IndexedDBBackingStore> backing_store = OpenBackingStore(
164 origin, context()->data_path(), url_request_context, &data_loss,
165 &data_loss_reason, &disk_full, task_runner);
166 scoped_refptr<TestableIndexedDBBackingStore> testable_store =
167 static_cast<TestableIndexedDBBackingStore*>(backing_store.get());
168 return testable_store;
169 }
170 protected:
171 scoped_refptr<IndexedDBBackingStore> OpenBackingStoreHelper(
172 const GURL& origin_url,
173 const base::FilePath& data_directory,
174 net::URLRequestContext* request_context,
175 blink::WebIDBDataLoss* data_loss,
176 std::string* data_loss_message,
177 bool* disk_full,
178 base::TaskRunner* task_runner,
179 bool first_time) {
180 DefaultLevelDBFactory leveldb_factory;
181 return TestableIndexedDBBackingStore::Open(this,
182 origin_url,
183 data_directory,
184 request_context,
185 &leveldb_factory,
186 task_runner);
187 }
188
189 };
190
18 class IndexedDBBackingStoreTest : public testing::Test { 191 class IndexedDBBackingStoreTest : public testing::Test {
19 public: 192 public:
20 IndexedDBBackingStoreTest() {} 193 IndexedDBBackingStoreTest() {}
21 virtual void SetUp() { 194 virtual void SetUp() {
22 const GURL origin("http://localhost:81"); 195 const GURL origin("http://localhost:81");
23 backing_store_ = IndexedDBBackingStore::OpenInMemory(origin); 196 task_runner_ = new base::TestSimpleTaskRunner();
197 special_storage_policy_ = new quota::MockSpecialStoragePolicy();
198 special_storage_policy_->SetAllUnlimited(true);
199 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
200 idb_context_ = new IndexedDBContextImpl(
201 temp_dir_.path(), special_storage_policy_, NULL, task_runner_);
202 idb_factory_ = new TestIDBFactory(idb_context_);
203 backing_store_ = idb_factory_->OpenBackingStoreForTest(
204 origin,
205 &url_request_context_,
206 task_runner_.get());
24 207
25 // useful keys and values during tests 208 // useful keys and values during tests
26 m_value1 = "value1"; 209 m_value1 = IndexedDBValue("value1", std::vector<IndexedDBBlobInfo>());
27 m_value2 = "value2"; 210 m_value2 = IndexedDBValue("value2", std::vector<IndexedDBBlobInfo>());
28 m_value3 = "value3"; 211
212 m_blobInfo.push_back(
213 IndexedDBBlobInfo("uuid 3", UTF8ToUTF16("blob type"), 1));
214 m_blobInfo.push_back(
215 IndexedDBBlobInfo(base::FilePath(FILE_PATH_LITERAL("path/to/file")),
216 UTF8ToUTF16("file name"), UTF8ToUTF16("file type")));
217 m_value3 = IndexedDBValue("value3", m_blobInfo);
218
29 m_key1 = IndexedDBKey(99, blink::WebIDBKeyTypeNumber); 219 m_key1 = IndexedDBKey(99, blink::WebIDBKeyTypeNumber);
30 m_key2 = IndexedDBKey(ASCIIToUTF16("key2")); 220 m_key2 = IndexedDBKey(ASCIIToUTF16("key2"));
31 m_key3 = IndexedDBKey(ASCIIToUTF16("key3")); 221 m_key3 = IndexedDBKey(ASCIIToUTF16("key3"));
222
223 }
224
225 // This just checks the data that survive getting stored and recalled, e.g.
226 // the file path and UUID will change and thus aren't verified.
227 bool CheckBlobInfoMatches(const std::vector<IndexedDBBlobInfo>& reads) const {
228 if (m_blobInfo.size() != reads.size())
229 return false;
230 for (size_t i = 0; i < m_blobInfo.size(); ++i) {
231 const IndexedDBBlobInfo& a = m_blobInfo[i];
232 const IndexedDBBlobInfo& b = reads[i];
233 if (a.is_file() != b.is_file())
234 return false;
235 if (a.type() != b.type())
236 return false;
237 if (a.is_file()) {
238 if (a.file_name() != b.file_name())
239 return false;
240 } else {
241 if (a.size() != b.size())
242 return false;
243 }
244 }
245 return true;
246 }
247
248 bool CheckBlobReadsMatchWrites(
249 const std::vector<IndexedDBBlobInfo>& reads) const {
250 if (backing_store_->writes().size() != reads.size())
251 return false;
252 std::set<int64> ids;
253 for (size_t i = 0; i < backing_store_->writes().size(); ++i)
254 ids.insert(backing_store_->writes()[i].key());
255 if (ids.size() != backing_store_->writes().size())
256 return false;
257 for (size_t i = 0; i < reads.size(); ++i)
258 if (ids.count(reads[i].key()) != 1)
259 return false;
260 return true;
261 }
262
263 bool CheckBlobWrites() const {
264 if (backing_store_->writes().size() != m_blobInfo.size())
265 return false;
266 for (size_t i = 0; i < backing_store_->writes().size(); ++i) {
267 const IndexedDBBackingStore::Transaction::WriteDescriptor& desc =
268 backing_store_->writes()[i];
269 const IndexedDBBlobInfo& info = m_blobInfo[i];
270 if (desc.is_file() != info.is_file())
271 return false;
272 if (desc.is_file()) {
273 if (desc.file_path() != info.file_path())
274 return false;
275 } else {
276 if (desc.url() != GURL("blob:uuid/" + info.uuid()))
277 return false;
278 }
279 }
280 return true;
281 }
282
283 bool CheckBlobRemovals() const {
284 if (backing_store_->removals().size() != backing_store_->writes().size())
285 return false;
286 for (size_t i = 0; i < backing_store_->writes().size(); ++i)
287 if (backing_store_->writes()[i].key() != backing_store_->removals()[i])
288 return false;
289 return true;
32 } 290 }
33 291
34 protected: 292 protected:
35 scoped_refptr<IndexedDBBackingStore> backing_store_; 293 base::ScopedTempDir temp_dir_;
294 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
295 scoped_refptr<quota::MockSpecialStoragePolicy> special_storage_policy_;
296 scoped_refptr<IndexedDBContextImpl> idb_context_;
297 scoped_refptr<TestIDBFactory> idb_factory_;
298 net::TestURLRequestContext url_request_context_;
299
300 scoped_refptr<TestableIndexedDBBackingStore> backing_store_;
36 301
37 // Sample keys and values that are consistent. 302 // Sample keys and values that are consistent.
38 IndexedDBKey m_key1; 303 IndexedDBKey m_key1;
39 IndexedDBKey m_key2; 304 IndexedDBKey m_key2;
40 IndexedDBKey m_key3; 305 IndexedDBKey m_key3;
41 std::string m_value1; 306 IndexedDBValue m_value1;
42 std::string m_value2; 307 IndexedDBValue m_value2;
43 std::string m_value3; 308 IndexedDBValue m_value3;
309 std::vector<IndexedDBBlobInfo> m_blobInfo;
44 310
45 private: 311 private:
46 DISALLOW_COPY_AND_ASSIGN(IndexedDBBackingStoreTest); 312 DISALLOW_COPY_AND_ASSIGN(IndexedDBBackingStoreTest);
47 }; 313 };
48 314
315 class TestCallback : public IndexedDBBackingStore::BlobWriteCallback {
316 public:
317 TestCallback()
318 : called(false),
319 succeeded(false) {
320 }
321 virtual ~TestCallback() {
322 }
323 virtual void didSucceed() {
324 called = true;
325 succeeded = true;
326 }
327 virtual void didFail() {
328 called = true;
329 succeeded = false;
330 }
331 bool called;
332 bool succeeded;
333 };
334
335
49 TEST_F(IndexedDBBackingStoreTest, PutGetConsistency) { 336 TEST_F(IndexedDBBackingStoreTest, PutGetConsistency) {
50 { 337 {
51 IndexedDBBackingStore::Transaction transaction1(backing_store_); 338 IndexedDBBackingStore::Transaction transaction1(backing_store_);
52 transaction1.Begin(); 339 transaction1.Begin();
340 ScopedVector<webkit_blob::BlobDataHandle> handles;
53 IndexedDBBackingStore::RecordIdentifier record; 341 IndexedDBBackingStore::RecordIdentifier record;
54 bool ok = backing_store_->PutRecord( 342 bool ok = backing_store_->PutRecord(
55 &transaction1, 1, 1, m_key1, m_value1, &record); 343 &transaction1, 1, 1, m_key1, m_value1, &handles, &record);
56 EXPECT_TRUE(ok); 344 EXPECT_TRUE(ok);
57 transaction1.Commit(); 345 scoped_refptr<TestCallback> callback(new TestCallback());
346 EXPECT_TRUE(transaction1.CommitPhaseOne(callback));
347 EXPECT_TRUE(callback->called);
348 EXPECT_TRUE(callback->succeeded);
349 EXPECT_TRUE(transaction1.CommitPhaseTwo());
58 } 350 }
59 351
60 { 352 {
61 IndexedDBBackingStore::Transaction transaction2(backing_store_); 353 IndexedDBBackingStore::Transaction transaction2(backing_store_);
62 transaction2.Begin(); 354 transaction2.Begin();
63 std::string result_value; 355 IndexedDBValue result_value;
64 bool ok = 356 bool ok =
65 backing_store_->GetRecord(&transaction2, 1, 1, m_key1, &result_value); 357 backing_store_->GetRecord(&transaction2, 1, 1, m_key1, &result_value);
66 transaction2.Commit(); 358 scoped_refptr<TestCallback> callback(new TestCallback());
67 EXPECT_TRUE(ok); 359 EXPECT_TRUE(transaction2.CommitPhaseOne(callback));
68 EXPECT_EQ(m_value1, result_value); 360 EXPECT_TRUE(ok);
361 EXPECT_TRUE(callback->called);
362 EXPECT_TRUE(callback->succeeded);
363 EXPECT_TRUE(transaction2.CommitPhaseTwo());
364 EXPECT_EQ(m_value1.bits, result_value.bits);
69 } 365 }
70 } 366 }
71 367
368 TEST_F(IndexedDBBackingStoreTest, PutGetConsistencyWithBlobs) {
369 {
370 IndexedDBBackingStore::Transaction transaction1(backing_store_);
371 transaction1.Begin();
372 ScopedVector<webkit_blob::BlobDataHandle> handles;
373 IndexedDBBackingStore::RecordIdentifier record;
374 bool ok = backing_store_->PutRecord(
375 &transaction1, 1, 1, m_key3, m_value3, &handles, &record);
376 EXPECT_TRUE(ok);
377 scoped_refptr<TestCallback> callback(new TestCallback());
378 EXPECT_TRUE(transaction1.CommitPhaseOne(callback));
379 task_runner_->RunUntilIdle();
380 EXPECT_TRUE(CheckBlobWrites());
381 EXPECT_TRUE(callback->called);
382 EXPECT_TRUE(callback->succeeded);
383 EXPECT_TRUE(transaction1.CommitPhaseTwo());
384 }
385
386 {
387 IndexedDBBackingStore::Transaction transaction2(backing_store_);
388 transaction2.Begin();
389 IndexedDBValue result_value;
390 bool ok =
391 backing_store_->GetRecord(&transaction2, 1, 1, m_key3, &result_value);
392 EXPECT_TRUE(ok);
393 scoped_refptr<TestCallback> callback(new TestCallback());
394 EXPECT_TRUE(transaction2.CommitPhaseOne(callback));
395 EXPECT_TRUE(callback->called);
396 EXPECT_TRUE(callback->succeeded);
397 EXPECT_TRUE(transaction2.CommitPhaseTwo());
398 EXPECT_EQ(m_value3.bits, result_value.bits);
399 EXPECT_TRUE(CheckBlobInfoMatches(result_value.blob_info));
400 EXPECT_TRUE(CheckBlobReadsMatchWrites(result_value.blob_info));
401 }
402
403 {
404 IndexedDBBackingStore::Transaction transaction3(backing_store_);
405 transaction3.Begin();
406 IndexedDBValue result_value;
407 bool ok = backing_store_->DeleteRange(
408 &transaction3, 1, 1, IndexedDBKeyRange(m_key3));
409 EXPECT_TRUE(ok);
410 scoped_refptr<TestCallback> callback(new TestCallback());
411 EXPECT_TRUE(transaction3.CommitPhaseOne(callback));
412 task_runner_->RunUntilIdle();
413 EXPECT_TRUE(callback->called);
414 EXPECT_TRUE(callback->succeeded);
415 EXPECT_TRUE(transaction3.CommitPhaseTwo());
416 EXPECT_TRUE(CheckBlobRemovals());
417 }
418 }
419
420 TEST_F(IndexedDBBackingStoreTest, LiveBlobJournal) {
421 {
422 IndexedDBBackingStore::Transaction transaction1(backing_store_);
423 transaction1.Begin();
424 ScopedVector<webkit_blob::BlobDataHandle> handles;
425 IndexedDBBackingStore::RecordIdentifier record;
426 bool ok = backing_store_->PutRecord(
427 &transaction1, 1, 1, m_key3, m_value3, &handles, &record);
428 EXPECT_TRUE(ok);
429 scoped_refptr<TestCallback> callback(new TestCallback());
430 EXPECT_TRUE(transaction1.CommitPhaseOne(callback));
431 task_runner_->RunUntilIdle();
432 EXPECT_TRUE(CheckBlobWrites());
433 EXPECT_TRUE(callback->called);
434 EXPECT_TRUE(callback->succeeded);
435 EXPECT_TRUE(transaction1.CommitPhaseTwo());
436 }
437
438 IndexedDBValue read_result_value;
439 {
440 IndexedDBBackingStore::Transaction transaction2(backing_store_);
441 transaction2.Begin();
442 bool ok = backing_store_->GetRecord(
443 &transaction2, 1, 1, m_key3, &read_result_value);
444 EXPECT_TRUE(ok);
445 scoped_refptr<TestCallback> callback(new TestCallback());
446 EXPECT_TRUE(transaction2.CommitPhaseOne(callback));
447 EXPECT_TRUE(callback->called);
448 EXPECT_TRUE(callback->succeeded);
449 EXPECT_TRUE(transaction2.CommitPhaseTwo());
450 EXPECT_EQ(m_value3.bits, read_result_value.bits);
451 EXPECT_TRUE(CheckBlobInfoMatches(read_result_value.blob_info));
452 EXPECT_TRUE(CheckBlobReadsMatchWrites(read_result_value.blob_info));
453 for (size_t i = 0; i < read_result_value.blob_info.size(); ++i) {
454 read_result_value.blob_info[i].mark_used_callback().Run();
455 }
456 }
457
458 {
459 IndexedDBBackingStore::Transaction transaction3(backing_store_);
460 transaction3.Begin();
461 bool ok = backing_store_->DeleteRange(
462 &transaction3, 1, 1, IndexedDBKeyRange(m_key3));
463 EXPECT_TRUE(ok);
464 scoped_refptr<TestCallback> callback(new TestCallback());
465 EXPECT_TRUE(transaction3.CommitPhaseOne(callback));
466 task_runner_->RunUntilIdle();
467 EXPECT_TRUE(callback->called);
468 EXPECT_TRUE(callback->succeeded);
469 EXPECT_TRUE(transaction3.CommitPhaseTwo());
470 EXPECT_EQ(0U, backing_store_->removals().size());
471 for (size_t i = 0; i < read_result_value.blob_info.size(); ++i) {
472 read_result_value.blob_info[i].release_callback().Run(
473 read_result_value.blob_info[i].file_path());
474 }
475 task_runner_->RunUntilIdle();
476 EXPECT_NE(0U, backing_store_->removals().size());
477 EXPECT_TRUE(CheckBlobRemovals());
478 }
479 }
480
72 // Make sure that using very high ( more than 32 bit ) values for database_id 481 // Make sure that using very high ( more than 32 bit ) values for database_id
73 // and object_store_id still work. 482 // and object_store_id still work.
74 TEST_F(IndexedDBBackingStoreTest, HighIds) { 483 TEST_F(IndexedDBBackingStoreTest, HighIds) {
75 const int64 high_database_id = 1ULL << 35; 484 const int64 high_database_id = 1ULL << 35;
76 const int64 high_object_store_id = 1ULL << 39; 485 const int64 high_object_store_id = 1ULL << 39;
77 // index_ids are capped at 32 bits for storage purposes. 486 // index_ids are capped at 32 bits for storage purposes.
78 const int64 high_index_id = 1ULL << 29; 487 const int64 high_index_id = 1ULL << 29;
79 488
80 const int64 invalid_high_index_id = 1ULL << 37; 489 const int64 invalid_high_index_id = 1ULL << 37;
81 490
82 const IndexedDBKey& index_key = m_key2; 491 const IndexedDBKey& index_key = m_key2;
83 std::string index_key_raw; 492 std::string index_key_raw;
84 EncodeIDBKey(index_key, &index_key_raw); 493 EncodeIDBKey(index_key, &index_key_raw);
85 { 494 {
86 IndexedDBBackingStore::Transaction transaction1(backing_store_); 495 IndexedDBBackingStore::Transaction transaction1(backing_store_);
87 transaction1.Begin(); 496 transaction1.Begin();
497 ScopedVector<webkit_blob::BlobDataHandle> handles;
88 IndexedDBBackingStore::RecordIdentifier record; 498 IndexedDBBackingStore::RecordIdentifier record;
89 bool ok = backing_store_->PutRecord(&transaction1, 499 bool ok = backing_store_->PutRecord(&transaction1,
90 high_database_id, 500 high_database_id,
91 high_object_store_id, 501 high_object_store_id,
92 m_key1, 502 m_key1,
93 m_value1, 503 m_value1,
504 &handles,
94 &record); 505 &record);
95 EXPECT_TRUE(ok); 506 EXPECT_TRUE(ok);
96 507
97 ok = backing_store_->PutIndexDataForRecord(&transaction1, 508 ok = backing_store_->PutIndexDataForRecord(&transaction1,
98 high_database_id, 509 high_database_id,
99 high_object_store_id, 510 high_object_store_id,
100 invalid_high_index_id, 511 invalid_high_index_id,
101 index_key, 512 index_key,
102 record); 513 record);
103 EXPECT_FALSE(ok); 514 EXPECT_FALSE(ok);
104 515
105 ok = backing_store_->PutIndexDataForRecord(&transaction1, 516 ok = backing_store_->PutIndexDataForRecord(&transaction1,
106 high_database_id, 517 high_database_id,
107 high_object_store_id, 518 high_object_store_id,
108 high_index_id, 519 high_index_id,
109 index_key, 520 index_key,
110 record); 521 record);
111 EXPECT_TRUE(ok); 522 EXPECT_TRUE(ok);
112 523
113 ok = transaction1.Commit(); 524 scoped_refptr<TestCallback> callback(new TestCallback());
525 ok = transaction1.CommitPhaseOne(callback);
114 EXPECT_TRUE(ok); 526 EXPECT_TRUE(ok);
527 EXPECT_TRUE(callback->called);
528 EXPECT_TRUE(callback->succeeded);
529 EXPECT_TRUE(transaction1.CommitPhaseTwo());
115 } 530 }
116 531
117 { 532 {
118 IndexedDBBackingStore::Transaction transaction2(backing_store_); 533 IndexedDBBackingStore::Transaction transaction2(backing_store_);
119 transaction2.Begin(); 534 transaction2.Begin();
120 std::string result_value; 535 IndexedDBValue result_value;
121 bool ok = backing_store_->GetRecord(&transaction2, 536 bool ok = backing_store_->GetRecord(&transaction2,
122 high_database_id, 537 high_database_id,
123 high_object_store_id, 538 high_object_store_id,
124 m_key1, 539 m_key1,
125 &result_value); 540 &result_value);
126 EXPECT_TRUE(ok); 541 EXPECT_TRUE(ok);
127 EXPECT_EQ(m_value1, result_value); 542 EXPECT_EQ(m_value1.bits, result_value.bits);
128 543
129 scoped_ptr<IndexedDBKey> new_primary_key; 544 scoped_ptr<IndexedDBKey> new_primary_key;
130 ok = backing_store_->GetPrimaryKeyViaIndex(&transaction2, 545 ok = backing_store_->GetPrimaryKeyViaIndex(&transaction2,
131 high_database_id, 546 high_database_id,
132 high_object_store_id, 547 high_object_store_id,
133 invalid_high_index_id, 548 invalid_high_index_id,
134 index_key, 549 index_key,
135 &new_primary_key); 550 &new_primary_key);
136 EXPECT_FALSE(ok); 551 EXPECT_FALSE(ok);
137 552
138 ok = backing_store_->GetPrimaryKeyViaIndex(&transaction2, 553 ok = backing_store_->GetPrimaryKeyViaIndex(&transaction2,
139 high_database_id, 554 high_database_id,
140 high_object_store_id, 555 high_object_store_id,
141 high_index_id, 556 high_index_id,
142 index_key, 557 index_key,
143 &new_primary_key); 558 &new_primary_key);
144 EXPECT_TRUE(ok); 559 EXPECT_TRUE(ok);
145 EXPECT_TRUE(new_primary_key->IsEqual(m_key1)); 560 EXPECT_TRUE(new_primary_key->IsEqual(m_key1));
146 561
147 ok = transaction2.Commit(); 562 scoped_refptr<TestCallback> callback(new TestCallback());
563 ok = transaction2.CommitPhaseOne(callback);
148 EXPECT_TRUE(ok); 564 EXPECT_TRUE(ok);
565 EXPECT_TRUE(callback->called);
566 EXPECT_TRUE(callback->succeeded);
567 EXPECT_TRUE(transaction2.CommitPhaseTwo());
149 } 568 }
150 } 569 }
151 570
152 // Make sure that other invalid ids do not crash. 571 // Make sure that other invalid ids do not crash.
153 TEST_F(IndexedDBBackingStoreTest, InvalidIds) { 572 TEST_F(IndexedDBBackingStoreTest, InvalidIds) {
154 // valid ids for use when testing invalid ids 573 // valid ids for use when testing invalid ids
155 const int64 database_id = 1; 574 const int64 database_id = 1;
156 const int64 object_store_id = 1; 575 const int64 object_store_id = 1;
157 const int64 index_id = kMinimumIndexId; 576 const int64 index_id = kMinimumIndexId;
158 const int64 invalid_low_index_id = 19; // index_ids must be > kMinimumIndexId 577 const int64 invalid_low_index_id = 19; // index_ids must be > kMinimumIndexId
159 578
160 std::string result_value; 579 IndexedDBValue result_value;
161 580
162 IndexedDBBackingStore::Transaction transaction1(backing_store_); 581 IndexedDBBackingStore::Transaction transaction1(backing_store_);
163 transaction1.Begin(); 582 transaction1.Begin();
164 583
584 ScopedVector<webkit_blob::BlobDataHandle> handles;
165 IndexedDBBackingStore::RecordIdentifier record; 585 IndexedDBBackingStore::RecordIdentifier record;
166 bool ok = backing_store_->PutRecord(&transaction1, 586 bool ok = backing_store_->PutRecord(&transaction1,
167 database_id, 587 database_id,
168 KeyPrefix::kInvalidId, 588 KeyPrefix::kInvalidId,
169 m_key1, 589 m_key1,
170 m_value1, 590 m_value1,
591 &handles,
171 &record); 592 &record);
172 EXPECT_FALSE(ok); 593 EXPECT_FALSE(ok);
173 ok = backing_store_->PutRecord( 594 ok = backing_store_->PutRecord(
174 &transaction1, database_id, 0, m_key1, m_value1, &record); 595 &transaction1, database_id, 0, m_key1, m_value1, &handles, &record);
175 EXPECT_FALSE(ok); 596 EXPECT_FALSE(ok);
176 ok = backing_store_->PutRecord(&transaction1, 597 ok = backing_store_->PutRecord(&transaction1,
177 KeyPrefix::kInvalidId, 598 KeyPrefix::kInvalidId,
178 object_store_id, 599 object_store_id,
179 m_key1, 600 m_key1,
180 m_value1, 601 m_value1,
602 &handles,
181 &record); 603 &record);
182 EXPECT_FALSE(ok); 604 EXPECT_FALSE(ok);
183 ok = backing_store_->PutRecord( 605 ok = backing_store_->PutRecord(
184 &transaction1, 0, object_store_id, m_key1, m_value1, &record); 606 &transaction1, 0, object_store_id, m_key1, m_value1, &handles, &record);
185 EXPECT_FALSE(ok); 607 EXPECT_FALSE(ok);
186 608
187 ok = backing_store_->GetRecord( 609 ok = backing_store_->GetRecord(
188 &transaction1, database_id, KeyPrefix::kInvalidId, m_key1, &result_value); 610 &transaction1, database_id, KeyPrefix::kInvalidId, m_key1, &result_value);
189 EXPECT_FALSE(ok); 611 EXPECT_FALSE(ok);
190 ok = backing_store_->GetRecord( 612 ok = backing_store_->GetRecord(
191 &transaction1, database_id, 0, m_key1, &result_value); 613 &transaction1, database_id, 0, m_key1, &result_value);
192 EXPECT_FALSE(ok); 614 EXPECT_FALSE(ok);
193 ok = backing_store_->GetRecord(&transaction1, 615 ok = backing_store_->GetRecord(&transaction1,
194 KeyPrefix::kInvalidId, 616 KeyPrefix::kInvalidId,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 ok = backing_store_->CreateIndex(&transaction, 695 ok = backing_store_->CreateIndex(&transaction,
274 database_id, 696 database_id,
275 object_store_id, 697 object_store_id,
276 index_id, 698 index_id,
277 index_name, 699 index_name,
278 index_key_path, 700 index_key_path,
279 unique, 701 unique,
280 multi_entry); 702 multi_entry);
281 EXPECT_TRUE(ok); 703 EXPECT_TRUE(ok);
282 704
283 ok = transaction.Commit(); 705 scoped_refptr<TestCallback> callback(new TestCallback());
706 ok = transaction.CommitPhaseOne(callback);
284 EXPECT_TRUE(ok); 707 EXPECT_TRUE(ok);
708 EXPECT_TRUE(callback->called);
709 EXPECT_TRUE(callback->succeeded);
710 EXPECT_TRUE(transaction.CommitPhaseTwo());
285 } 711 }
286 712
287 { 713 {
288 IndexedDBDatabaseMetadata database; 714 IndexedDBDatabaseMetadata database;
289 bool found; 715 bool found;
290 bool ok = backing_store_->GetIDBDatabaseMetaData( 716 bool ok = backing_store_->GetIDBDatabaseMetaData(
291 database_name, &database, &found); 717 database_name, &database, &found);
292 EXPECT_TRUE(ok); 718 EXPECT_TRUE(ok);
293 EXPECT_TRUE(found); 719 EXPECT_TRUE(found);
294 720
(...skipping 17 matching lines...) Expand all
312 EXPECT_EQ(index_name, index.name); 738 EXPECT_EQ(index_name, index.name);
313 EXPECT_EQ(index_key_path, index.key_path); 739 EXPECT_EQ(index_key_path, index.key_path);
314 EXPECT_EQ(unique, index.unique); 740 EXPECT_EQ(unique, index.unique);
315 EXPECT_EQ(multi_entry, index.multi_entry); 741 EXPECT_EQ(multi_entry, index.multi_entry);
316 } 742 }
317 } 743 }
318 744
319 } // namespace 745 } // namespace
320 746
321 } // namespace content 747 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698