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.
9 #include "base/files/file_path.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/platform_file.h"
12 #include "base/strings/string16.h"
13 #include "base/strings/string_piece.h"
14 #include "content/browser/indexed_db/leveldb/leveldb_comparator.h"
15 #include "content/browser/indexed_db/leveldb/leveldb_database.h"
16 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h"
17 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "third_party/leveldatabase/env_chromium.h"
20 #include "third_party/leveldatabase/env_idb.h"
26 class SimpleComparator : public LevelDBComparator {
28 virtual int Compare(const base::StringPiece& a,
29 const base::StringPiece& b) const OVERRIDE {
30 size_t len = std::min(a.size(), b.size());
31 return memcmp(a.begin(), b.begin(), len);
33 virtual const char* Name() const OVERRIDE { return "temp_comparator"; }
36 TEST(LevelDBDatabaseTest, CorruptionTest) {
37 base::ScopedTempDir temp_directory;
38 ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
40 const std::string key("key");
41 const std::string value("value");
42 std::string put_value;
43 std::string got_value;
44 SimpleComparator comparator;
46 scoped_ptr<LevelDBDatabase> leveldb;
47 LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb);
50 bool success = leveldb->Put(key, &put_value);
53 EXPECT_FALSE(leveldb);
55 LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb);
58 success = leveldb->Get(key, &got_value, &found);
61 EXPECT_EQ(value, got_value);
63 EXPECT_FALSE(leveldb);
65 base::FilePath file_path = temp_directory.path().AppendASCII("CURRENT");
66 base::PlatformFile handle = base::CreatePlatformFile(
68 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE,
71 base::TruncatePlatformFile(handle, 0);
72 base::ClosePlatformFile(handle);
74 leveldb::Status status =
75 LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb);
76 EXPECT_FALSE(leveldb);
77 EXPECT_FALSE(status.ok());
79 bool destroyed = LevelDBDatabase::Destroy(temp_directory.path());
80 EXPECT_TRUE(destroyed);
82 status = LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb);
83 EXPECT_TRUE(status.ok());
85 success = leveldb->Get(key, &got_value, &found);
90 TEST(LevelDBDatabaseTest, Transaction) {
91 base::ScopedTempDir temp_directory;
92 ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
94 const std::string key("key");
95 std::string got_value;
96 std::string put_value;
97 SimpleComparator comparator;
99 scoped_ptr<LevelDBDatabase> leveldb;
100 LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb);
101 EXPECT_TRUE(leveldb);
103 const std::string old_value("value");
104 put_value = old_value;
105 bool success = leveldb->Put(key, &put_value);
106 EXPECT_TRUE(success);
108 scoped_refptr<LevelDBTransaction> transaction =
109 new LevelDBTransaction(leveldb.get());
111 const std::string new_value("new value");
112 put_value = new_value;
113 success = leveldb->Put(key, &put_value);
114 EXPECT_TRUE(success);
117 success = transaction->Get(key, &got_value, &found);
118 EXPECT_TRUE(success);
120 EXPECT_EQ(comparator.Compare(got_value, old_value), 0);
123 success = leveldb->Get(key, &got_value, &found);
124 EXPECT_TRUE(success);
126 EXPECT_EQ(comparator.Compare(got_value, new_value), 0);
128 const std::string added_key("added key");
129 const std::string added_value("added value");
130 put_value = added_value;
131 success = leveldb->Put(added_key, &put_value);
132 EXPECT_TRUE(success);
134 success = leveldb->Get(added_key, &got_value, &found);
135 EXPECT_TRUE(success);
137 EXPECT_EQ(comparator.Compare(got_value, added_value), 0);
139 success = transaction->Get(added_key, &got_value, &found);
140 EXPECT_TRUE(success);
143 const std::string another_key("another key");
144 const std::string another_value("another value");
145 put_value = another_value;
146 transaction->Put(another_key, &put_value);
148 success = transaction->Get(another_key, &got_value, &found);
149 EXPECT_TRUE(success);
151 EXPECT_EQ(comparator.Compare(got_value, another_value), 0);
154 TEST(LevelDBDatabaseTest, TransactionIterator) {
155 base::ScopedTempDir temp_directory;
156 ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
158 const std::string key1("key1");
159 const std::string value1("value1");
160 const std::string key2("key2");
161 const std::string value2("value2");
162 std::string put_value;
163 SimpleComparator comparator;
166 scoped_ptr<LevelDBDatabase> leveldb;
167 LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb);
168 EXPECT_TRUE(leveldb);
171 success = leveldb->Put(key1, &put_value);
172 EXPECT_TRUE(success);
174 success = leveldb->Put(key2, &put_value);
175 EXPECT_TRUE(success);
177 scoped_refptr<LevelDBTransaction> transaction =
178 new LevelDBTransaction(leveldb.get());
180 success = leveldb->Remove(key2);
181 EXPECT_TRUE(success);
183 scoped_ptr<LevelDBIterator> it = transaction->CreateIterator();
185 it->Seek(std::string());
187 EXPECT_TRUE(it->IsValid());
188 EXPECT_EQ(comparator.Compare(it->Key(), key1), 0);
189 EXPECT_EQ(comparator.Compare(it->Value(), value1), 0);
193 EXPECT_TRUE(it->IsValid());
194 EXPECT_EQ(comparator.Compare(it->Key(), key2), 0);
195 EXPECT_EQ(comparator.Compare(it->Value(), value2), 0);
199 EXPECT_FALSE(it->IsValid());
202 TEST(LevelDBDatabaseTest, TransactionCommitTest) {
203 base::ScopedTempDir temp_directory;
204 ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
206 const std::string key1("key1");
207 const std::string key2("key2");
208 const std::string value1("value1");
209 const std::string value2("value2");
210 const std::string value3("value3");
212 std::string put_value;
213 std::string got_value;
214 SimpleComparator comparator;
218 scoped_ptr<LevelDBDatabase> leveldb;
219 LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb);
220 EXPECT_TRUE(leveldb);
222 scoped_refptr<LevelDBTransaction> transaction =
223 new LevelDBTransaction(leveldb.get());
226 transaction->Put(key1, &put_value);
229 transaction->Put(key2, &put_value);
232 transaction->Put(key2, &put_value);
234 success = transaction->Commit();
235 EXPECT_TRUE(success);
237 success = leveldb->Get(key1, &got_value, &found);
238 EXPECT_TRUE(success);
240 EXPECT_EQ(value1, got_value);
242 success = leveldb->Get(key2, &got_value, &found);
243 EXPECT_TRUE(success);
245 EXPECT_EQ(value3, got_value);
248 TEST(LevelDB, Locking) {
249 base::ScopedTempDir temp_directory;
250 ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
252 leveldb::Env* env = leveldb::IDBEnv();
253 base::FilePath file = temp_directory.path().AppendASCII("LOCK");
254 leveldb::FileLock* lock;
255 leveldb::Status status = env->LockFile(file.AsUTF8Unsafe(), &lock);
256 EXPECT_TRUE(status.ok());
258 status = env->UnlockFile(lock);
259 EXPECT_TRUE(status.ok());
261 status = env->LockFile(file.AsUTF8Unsafe(), &lock);
262 EXPECT_TRUE(status.ok());
264 leveldb::FileLock* lock2;
265 status = env->LockFile(file.AsUTF8Unsafe(), &lock2);
266 EXPECT_FALSE(status.ok());
268 status = env->UnlockFile(lock);
269 EXPECT_TRUE(status.ok());
274 } // namespace content