Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / indexed_db / indexed_db_cleanup_on_io_error_unittest.cc
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.
4
5 #include <cerrno>
6
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 "testing/gtest/include/gtest/gtest.h"
15 #include "third_party/leveldatabase/env_chromium.h"
16
17 using base::StringPiece;
18 using content::IndexedDBBackingStore;
19 using content::LevelDBComparator;
20 using content::LevelDBDatabase;
21 using content::LevelDBFactory;
22 using content::LevelDBSnapshot;
23
24 namespace base {
25 class TaskRunner;
26 }
27
28 namespace content {
29 class IndexedDBFactory;
30 }
31
32 namespace net {
33 class URLRequestContext;
34 }
35
36 namespace {
37
38 class BustedLevelDBDatabase : public LevelDBDatabase {
39  public:
40   static scoped_ptr<LevelDBDatabase> Open(
41       const base::FilePath& file_name,
42       const LevelDBComparator* /*comparator*/) {
43     return scoped_ptr<LevelDBDatabase>(new BustedLevelDBDatabase);
44   }
45   virtual leveldb::Status Get(const base::StringPiece& key,
46                               std::string* value,
47                               bool* found,
48                               const LevelDBSnapshot* = 0) OVERRIDE {
49     return leveldb::Status::IOError("It's busted!");
50   }
51 };
52
53 class MockLevelDBFactory : public LevelDBFactory {
54  public:
55   MockLevelDBFactory() : destroy_called_(false) {}
56   virtual leveldb::Status OpenLevelDB(
57       const base::FilePath& file_name,
58       const LevelDBComparator* comparator,
59       scoped_ptr<LevelDBDatabase>* db,
60       bool* is_disk_full = 0) OVERRIDE {
61     *db = BustedLevelDBDatabase::Open(file_name, comparator);
62     return leveldb::Status::OK();
63   }
64   virtual leveldb::Status DestroyLevelDB(const base::FilePath& file_name)
65       OVERRIDE {
66     EXPECT_FALSE(destroy_called_);
67     destroy_called_ = true;
68     return leveldb::Status::IOError("error");
69   }
70   virtual ~MockLevelDBFactory() { EXPECT_TRUE(destroy_called_); }
71
72  private:
73   bool destroy_called_;
74 };
75
76 TEST(IndexedDBIOErrorTest, CleanUpTest) {
77   content::IndexedDBFactory* factory = NULL;
78   const GURL origin("http://localhost:81");
79   base::ScopedTempDir temp_directory;
80   ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
81   const base::FilePath path = temp_directory.path();
82   net::URLRequestContext* request_context = NULL;
83   MockLevelDBFactory mock_leveldb_factory;
84   blink::WebIDBDataLoss data_loss =
85       blink::WebIDBDataLossNone;
86   std::string data_loss_message;
87   bool disk_full = false;
88   base::TaskRunner* task_runner = NULL;
89   bool clean_journal = false;
90   scoped_refptr<IndexedDBBackingStore> backing_store =
91       IndexedDBBackingStore::Open(factory,
92                                   origin,
93                                   path,
94                                   request_context,
95                                   &data_loss,
96                                   &data_loss_message,
97                                   &disk_full,
98                                   &mock_leveldb_factory,
99                                   task_runner,
100                                   clean_journal);
101 }
102
103 // TODO(dgrogan): Remove expect_destroy if we end up not using it again. It is
104 // currently set to false in all 4 calls below.
105 template <class T>
106 class MockErrorLevelDBFactory : public LevelDBFactory {
107  public:
108   MockErrorLevelDBFactory(T error, bool expect_destroy)
109       : error_(error),
110         expect_destroy_(expect_destroy),
111         destroy_called_(false) {}
112   virtual leveldb::Status OpenLevelDB(
113       const base::FilePath& file_name,
114       const LevelDBComparator* comparator,
115       scoped_ptr<LevelDBDatabase>* db,
116       bool* is_disk_full = 0) OVERRIDE {
117     return MakeIOError(
118         "some filename", "some message", leveldb_env::kNewLogger, error_);
119   }
120   virtual leveldb::Status DestroyLevelDB(const base::FilePath& file_name)
121       OVERRIDE {
122     EXPECT_FALSE(destroy_called_);
123     destroy_called_ = true;
124     return leveldb::Status::IOError("error");
125   }
126   virtual ~MockErrorLevelDBFactory() {
127     EXPECT_EQ(expect_destroy_, destroy_called_);
128   }
129
130  private:
131   T error_;
132   bool expect_destroy_;
133   bool destroy_called_;
134 };
135
136 TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) {
137   content::IndexedDBFactory* factory = NULL;
138   const GURL origin("http://localhost:81");
139   net::URLRequestContext* request_context = NULL;
140   base::ScopedTempDir temp_directory;
141   ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
142   const base::FilePath path = temp_directory.path();
143   blink::WebIDBDataLoss data_loss =
144       blink::WebIDBDataLossNone;
145   std::string data_loss_reason;
146   bool disk_full = false;
147   base::TaskRunner* task_runner = NULL;
148   bool clean_journal = false;
149
150   MockErrorLevelDBFactory<int> mock_leveldb_factory(ENOSPC, false);
151   scoped_refptr<IndexedDBBackingStore> backing_store =
152       IndexedDBBackingStore::Open(factory,
153                                   origin,
154                                   path,
155                                   request_context,
156                                   &data_loss,
157                                   &data_loss_reason,
158                                   &disk_full,
159                                   &mock_leveldb_factory,
160                                   task_runner,
161                                   clean_journal);
162
163   MockErrorLevelDBFactory<base::File::Error> mock_leveldb_factory2(
164       base::File::FILE_ERROR_NO_MEMORY, false);
165   scoped_refptr<IndexedDBBackingStore> backing_store2 =
166       IndexedDBBackingStore::Open(factory,
167                                   origin,
168                                   path,
169                                   request_context,
170                                   &data_loss,
171                                   &data_loss_reason,
172                                   &disk_full,
173                                   &mock_leveldb_factory2,
174                                   task_runner,
175                                   clean_journal);
176
177   MockErrorLevelDBFactory<int> mock_leveldb_factory3(EIO, false);
178   scoped_refptr<IndexedDBBackingStore> backing_store3 =
179       IndexedDBBackingStore::Open(factory,
180                                   origin,
181                                   path,
182                                   request_context,
183                                   &data_loss,
184                                   &data_loss_reason,
185                                   &disk_full,
186                                   &mock_leveldb_factory3,
187                                   task_runner,
188                                   clean_journal);
189
190   MockErrorLevelDBFactory<base::File::Error> mock_leveldb_factory4(
191       base::File::FILE_ERROR_FAILED, false);
192   scoped_refptr<IndexedDBBackingStore> backing_store4 =
193       IndexedDBBackingStore::Open(factory,
194                                   origin,
195                                   path,
196                                   request_context,
197                                   &data_loss,
198                                   &data_loss_reason,
199                                   &disk_full,
200                                   &mock_leveldb_factory4,
201                                   task_runner,
202                                   clean_journal);
203 }
204
205 }  // namespace