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.h"
8 #include "base/files/file_path.h"
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/strings/string16.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "content/browser/indexed_db/indexed_db_backing_store.h"
13 #include "content/browser/indexed_db/leveldb/leveldb_database.h"
14 #include "content/browser/indexed_db/leveldb/mock_leveldb_factory.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "third_party/leveldatabase/env_chromium.h"
19 using base::StringPiece;
20 using content::IndexedDBBackingStore;
21 using content::LevelDBComparator;
22 using content::LevelDBDatabase;
23 using content::LevelDBFactory;
24 using content::LevelDBSnapshot;
26 using testing::Exactly;
27 using testing::Invoke;
34 class IndexedDBFactory;
38 class URLRequestContext;
43 class BustedLevelDBDatabase : public LevelDBDatabase {
45 BustedLevelDBDatabase() {}
46 static scoped_ptr<LevelDBDatabase> Open(
47 const base::FilePath& file_name,
48 const LevelDBComparator* /*comparator*/) {
49 return scoped_ptr<LevelDBDatabase>(new BustedLevelDBDatabase);
51 leveldb::Status Get(const base::StringPiece& key,
54 const LevelDBSnapshot* = 0) override {
55 return leveldb::Status::IOError("It's busted!");
59 DISALLOW_COPY_AND_ASSIGN(BustedLevelDBDatabase);
62 class BustedLevelDBFactory : public LevelDBFactory {
64 leveldb::Status OpenLevelDB(const base::FilePath& file_name,
65 const LevelDBComparator* comparator,
66 scoped_ptr<LevelDBDatabase>* db,
67 bool* is_disk_full = 0) override {
69 *db = BustedLevelDBDatabase::Open(file_name, comparator);
72 leveldb::Status DestroyLevelDB(const base::FilePath& file_name) override {
73 return leveldb::Status::IOError("error");
75 void SetOpenError(const leveldb::Status& open_error) {
76 open_error_ = open_error;
80 leveldb::Status open_error_;
83 TEST(IndexedDBIOErrorTest, CleanUpTest) {
84 content::IndexedDBFactory* factory = NULL;
85 const GURL origin("http://localhost:81");
86 base::ScopedTempDir temp_directory;
87 ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
88 const base::FilePath path = temp_directory.path();
89 net::URLRequestContext* request_context = NULL;
91 BustedLevelDBFactory busted_factory;
92 content::MockLevelDBFactory mock_leveldb_factory;
93 ON_CALL(mock_leveldb_factory, OpenLevelDB(_, _, _, _)).WillByDefault(
94 Invoke(&busted_factory, &BustedLevelDBFactory::OpenLevelDB));
95 ON_CALL(mock_leveldb_factory, DestroyLevelDB(_)).WillByDefault(
96 Invoke(&busted_factory, &BustedLevelDBFactory::DestroyLevelDB));
98 EXPECT_CALL(mock_leveldb_factory, OpenLevelDB(_, _, _, _)).Times(Exactly(1));
99 EXPECT_CALL(mock_leveldb_factory, DestroyLevelDB(_)).Times(Exactly(1));
100 blink::WebIDBDataLoss data_loss = blink::WebIDBDataLossNone;
101 std::string data_loss_message;
102 bool disk_full = false;
103 base::SequencedTaskRunner* task_runner = NULL;
104 bool clean_journal = false;
106 scoped_refptr<IndexedDBBackingStore> backing_store =
107 IndexedDBBackingStore::Open(factory,
114 &mock_leveldb_factory,
120 TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) {
121 content::IndexedDBFactory* factory = NULL;
122 const GURL origin("http://localhost:81");
123 net::URLRequestContext* request_context = NULL;
124 base::ScopedTempDir temp_directory;
125 ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
126 const base::FilePath path = temp_directory.path();
127 blink::WebIDBDataLoss data_loss =
128 blink::WebIDBDataLossNone;
129 std::string data_loss_reason;
130 bool disk_full = false;
131 base::SequencedTaskRunner* task_runner = NULL;
132 bool clean_journal = false;
135 BustedLevelDBFactory busted_factory;
136 content::MockLevelDBFactory mock_leveldb_factory;
137 ON_CALL(mock_leveldb_factory, OpenLevelDB(_, _, _, _)).WillByDefault(
138 Invoke(&busted_factory, &BustedLevelDBFactory::OpenLevelDB));
139 ON_CALL(mock_leveldb_factory, DestroyLevelDB(_)).WillByDefault(
140 Invoke(&busted_factory, &BustedLevelDBFactory::DestroyLevelDB));
142 EXPECT_CALL(mock_leveldb_factory, OpenLevelDB(_, _, _, _)).Times(Exactly(4));
143 EXPECT_CALL(mock_leveldb_factory, DestroyLevelDB(_)).Times(Exactly(0));
145 busted_factory.SetOpenError(MakeIOError(
146 "some filename", "some message", leveldb_env::kNewLogger, ENOSPC));
147 scoped_refptr<IndexedDBBackingStore> backing_store =
148 IndexedDBBackingStore::Open(factory,
155 &mock_leveldb_factory,
159 ASSERT_TRUE(s.IsIOError());
161 busted_factory.SetOpenError(MakeIOError("some filename",
163 leveldb_env::kNewLogger,
164 base::File::FILE_ERROR_NO_MEMORY));
165 scoped_refptr<IndexedDBBackingStore> backing_store2 =
166 IndexedDBBackingStore::Open(factory,
173 &mock_leveldb_factory,
177 ASSERT_TRUE(s.IsIOError());
179 busted_factory.SetOpenError(MakeIOError(
180 "some filename", "some message", leveldb_env::kNewLogger, EIO));
181 scoped_refptr<IndexedDBBackingStore> backing_store3 =
182 IndexedDBBackingStore::Open(factory,
189 &mock_leveldb_factory,
193 ASSERT_TRUE(s.IsIOError());
195 busted_factory.SetOpenError(MakeIOError("some filename",
197 leveldb_env::kNewLogger,
198 base::File::FILE_ERROR_FAILED));
199 scoped_refptr<IndexedDBBackingStore> backing_store4 =
200 IndexedDBBackingStore::Open(factory,
207 &mock_leveldb_factory,
211 ASSERT_TRUE(s.IsIOError());