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
3 // found in the LICENSE file.
7 #include "base/files/file_path.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/strings/string16.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "content/browser/indexed_db/indexed_db_backing_store.h"
12 #include "content/browser/indexed_db/leveldb/leveldb_database.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "third_party/leveldatabase/env_chromium.h"
16 using base::StringPiece;
17 using content::IndexedDBBackingStore;
18 using content::LevelDBComparator;
19 using content::LevelDBDatabase;
20 using content::LevelDBFactory;
21 using content::LevelDBSnapshot;
25 class BustedLevelDBDatabase : public LevelDBDatabase {
27 static scoped_ptr<LevelDBDatabase> Open(
28 const base::FilePath& file_name,
29 const LevelDBComparator* /*comparator*/) {
30 return scoped_ptr<LevelDBDatabase>(new BustedLevelDBDatabase);
32 virtual bool Get(const base::StringPiece& key,
35 const LevelDBSnapshot* = 0) OVERRIDE {
36 // false means IO error.
41 class MockLevelDBFactory : public LevelDBFactory {
43 MockLevelDBFactory() : destroy_called_(false) {}
44 virtual leveldb::Status OpenLevelDB(
45 const base::FilePath& file_name,
46 const LevelDBComparator* comparator,
47 scoped_ptr<LevelDBDatabase>* db,
48 bool* is_disk_full = 0) OVERRIDE {
49 *db = BustedLevelDBDatabase::Open(file_name, comparator);
50 return leveldb::Status::OK();
52 virtual bool DestroyLevelDB(const base::FilePath& file_name) OVERRIDE {
53 EXPECT_FALSE(destroy_called_);
54 destroy_called_ = true;
57 virtual ~MockLevelDBFactory() { EXPECT_TRUE(destroy_called_); }
63 TEST(IndexedDBIOErrorTest, CleanUpTest) {
64 const GURL origin("http://localhost:81");
65 base::ScopedTempDir temp_directory;
66 ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
67 const base::FilePath path = temp_directory.path();
68 MockLevelDBFactory mock_leveldb_factory;
69 WebKit::WebIDBCallbacks::DataLoss data_loss =
70 WebKit::WebIDBCallbacks::DataLossNone;
71 std::string data_loss_message;
72 bool disk_full = false;
73 scoped_refptr<IndexedDBBackingStore> backing_store =
74 IndexedDBBackingStore::Open(origin,
79 &mock_leveldb_factory);
82 // TODO(dgrogan): Remove expect_destroy if we end up not using it again. It is
83 // currently set to false in all 4 calls below.
85 class MockErrorLevelDBFactory : public LevelDBFactory {
87 MockErrorLevelDBFactory(T error, bool expect_destroy)
89 expect_destroy_(expect_destroy),
90 destroy_called_(false) {}
91 virtual leveldb::Status OpenLevelDB(
92 const base::FilePath& file_name,
93 const LevelDBComparator* comparator,
94 scoped_ptr<LevelDBDatabase>* db,
95 bool* is_disk_full = 0) OVERRIDE {
97 "some filename", "some message", leveldb_env::kNewLogger, error_);
99 virtual bool DestroyLevelDB(const base::FilePath& file_name) OVERRIDE {
100 EXPECT_FALSE(destroy_called_);
101 destroy_called_ = true;
104 virtual ~MockErrorLevelDBFactory() {
105 EXPECT_EQ(expect_destroy_, destroy_called_);
110 bool expect_destroy_;
111 bool destroy_called_;
114 TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) {
115 const GURL origin("http://localhost:81");
116 base::ScopedTempDir temp_directory;
117 ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
118 const base::FilePath path = temp_directory.path();
119 WebKit::WebIDBCallbacks::DataLoss data_loss =
120 WebKit::WebIDBCallbacks::DataLossNone;
121 std::string data_loss_reason;
122 bool disk_full = false;
124 MockErrorLevelDBFactory<int> mock_leveldb_factory(ENOSPC, false);
125 scoped_refptr<IndexedDBBackingStore> backing_store =
126 IndexedDBBackingStore::Open(origin,
131 &mock_leveldb_factory);
133 MockErrorLevelDBFactory<base::PlatformFileError> mock_leveldb_factory2(
134 base::PLATFORM_FILE_ERROR_NO_MEMORY, false);
135 scoped_refptr<IndexedDBBackingStore> backing_store2 =
136 IndexedDBBackingStore::Open(origin,
141 &mock_leveldb_factory2);
143 MockErrorLevelDBFactory<int> mock_leveldb_factory3(EIO, false);
144 scoped_refptr<IndexedDBBackingStore> backing_store3 =
145 IndexedDBBackingStore::Open(origin,
150 &mock_leveldb_factory3);
152 MockErrorLevelDBFactory<base::PlatformFileError> mock_leveldb_factory4(
153 base::PLATFORM_FILE_ERROR_FAILED, false);
154 scoped_refptr<IndexedDBBackingStore> backing_store4 =
155 IndexedDBBackingStore::Open(origin,
160 &mock_leveldb_factory4);