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.h"
10 #include "base/files/file_path.h"
11 #include "base/files/scoped_temp_dir.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_env.h"
17 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h"
18 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "third_party/leveldatabase/env_chromium.h"
26 class SimpleComparator
: public LevelDBComparator
{
28 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 const char* Name() const override
{ return "temp_comparator"; }
38 TEST(LevelDBDatabaseTest
, CorruptionTest
) {
39 base::ScopedTempDir temp_directory
;
40 ASSERT_TRUE(temp_directory
.CreateUniqueTempDir());
42 const std::string
key("key");
43 const std::string
value("value");
44 std::string put_value
;
45 std::string got_value
;
46 SimpleComparator comparator
;
48 scoped_ptr
<LevelDBDatabase
> leveldb
;
49 LevelDBDatabase::Open(temp_directory
.path(), &comparator
, &leveldb
);
52 leveldb::Status status
= leveldb
->Put(key
, &put_value
);
53 EXPECT_TRUE(status
.ok());
55 EXPECT_FALSE(leveldb
);
57 LevelDBDatabase::Open(temp_directory
.path(), &comparator
, &leveldb
);
60 status
= leveldb
->Get(key
, &got_value
, &found
);
61 EXPECT_TRUE(status
.ok());
63 EXPECT_EQ(value
, got_value
);
65 EXPECT_FALSE(leveldb
);
67 base::FilePath file_path
= temp_directory
.path().AppendASCII("CURRENT");
68 base::File
file(file_path
, base::File::FLAG_OPEN
| base::File::FLAG_WRITE
);
72 status
= LevelDBDatabase::Open(temp_directory
.path(), &comparator
, &leveldb
);
73 EXPECT_FALSE(leveldb
);
74 EXPECT_FALSE(status
.ok());
75 EXPECT_TRUE(status
.IsCorruption());
77 status
= LevelDBDatabase::Destroy(temp_directory
.path());
78 EXPECT_TRUE(status
.ok());
80 status
= LevelDBDatabase::Open(temp_directory
.path(), &comparator
, &leveldb
);
81 EXPECT_TRUE(status
.ok());
83 status
= leveldb
->Get(key
, &got_value
, &found
);
84 EXPECT_TRUE(status
.ok());
88 TEST(LevelDBDatabaseTest
, Transaction
) {
89 base::ScopedTempDir temp_directory
;
90 ASSERT_TRUE(temp_directory
.CreateUniqueTempDir());
92 const std::string
key("key");
93 std::string got_value
;
94 std::string put_value
;
95 SimpleComparator comparator
;
97 scoped_ptr
<LevelDBDatabase
> leveldb
;
98 LevelDBDatabase::Open(temp_directory
.path(), &comparator
, &leveldb
);
101 const std::string
old_value("value");
102 put_value
= old_value
;
103 leveldb::Status status
= leveldb
->Put(key
, &put_value
);
104 EXPECT_TRUE(status
.ok());
106 scoped_refptr
<LevelDBTransaction
> transaction
=
107 new LevelDBTransaction(leveldb
.get());
109 const std::string
new_value("new value");
110 put_value
= new_value
;
111 status
= leveldb
->Put(key
, &put_value
);
112 EXPECT_TRUE(status
.ok());
115 status
= transaction
->Get(key
, &got_value
, &found
);
116 EXPECT_TRUE(status
.ok());
118 EXPECT_EQ(comparator
.Compare(got_value
, old_value
), 0);
121 status
= leveldb
->Get(key
, &got_value
, &found
);
122 EXPECT_TRUE(status
.ok());
124 EXPECT_EQ(comparator
.Compare(got_value
, new_value
), 0);
126 const std::string
added_key("added key");
127 const std::string
added_value("added value");
128 put_value
= added_value
;
129 status
= leveldb
->Put(added_key
, &put_value
);
130 EXPECT_TRUE(status
.ok());
132 status
= leveldb
->Get(added_key
, &got_value
, &found
);
133 EXPECT_TRUE(status
.ok());
135 EXPECT_EQ(comparator
.Compare(got_value
, added_value
), 0);
137 status
= transaction
->Get(added_key
, &got_value
, &found
);
138 EXPECT_TRUE(status
.ok());
141 const std::string
another_key("another key");
142 const std::string
another_value("another value");
143 put_value
= another_value
;
144 transaction
->Put(another_key
, &put_value
);
146 status
= transaction
->Get(another_key
, &got_value
, &found
);
147 EXPECT_TRUE(status
.ok());
149 EXPECT_EQ(comparator
.Compare(got_value
, another_value
), 0);
152 TEST(LevelDBDatabaseTest
, TransactionIterator
) {
153 base::ScopedTempDir temp_directory
;
154 ASSERT_TRUE(temp_directory
.CreateUniqueTempDir());
156 const std::string
key1("key1");
157 const std::string
value1("value1");
158 const std::string
key2("key2");
159 const std::string
value2("value2");
160 std::string put_value
;
161 SimpleComparator comparator
;
163 scoped_ptr
<LevelDBDatabase
> leveldb
;
164 LevelDBDatabase::Open(temp_directory
.path(), &comparator
, &leveldb
);
165 EXPECT_TRUE(leveldb
);
168 leveldb::Status s
= leveldb
->Put(key1
, &put_value
);
171 s
= leveldb
->Put(key2
, &put_value
);
174 scoped_refptr
<LevelDBTransaction
> transaction
=
175 new LevelDBTransaction(leveldb
.get());
177 s
= leveldb
->Remove(key2
);
180 scoped_ptr
<LevelDBIterator
> it
= transaction
->CreateIterator();
182 it
->Seek(std::string());
184 EXPECT_TRUE(it
->IsValid());
185 EXPECT_EQ(comparator
.Compare(it
->Key(), key1
), 0);
186 EXPECT_EQ(comparator
.Compare(it
->Value(), value1
), 0);
190 EXPECT_TRUE(it
->IsValid());
191 EXPECT_EQ(comparator
.Compare(it
->Key(), key2
), 0);
192 EXPECT_EQ(comparator
.Compare(it
->Value(), value2
), 0);
196 EXPECT_FALSE(it
->IsValid());
199 TEST(LevelDBDatabaseTest
, TransactionCommitTest
) {
200 base::ScopedTempDir temp_directory
;
201 ASSERT_TRUE(temp_directory
.CreateUniqueTempDir());
203 const std::string
key1("key1");
204 const std::string
key2("key2");
205 const std::string
value1("value1");
206 const std::string
value2("value2");
207 const std::string
value3("value3");
209 std::string put_value
;
210 std::string got_value
;
211 SimpleComparator comparator
;
214 scoped_ptr
<LevelDBDatabase
> leveldb
;
215 LevelDBDatabase::Open(temp_directory
.path(), &comparator
, &leveldb
);
216 EXPECT_TRUE(leveldb
);
218 scoped_refptr
<LevelDBTransaction
> transaction
=
219 new LevelDBTransaction(leveldb
.get());
222 transaction
->Put(key1
, &put_value
);
225 transaction
->Put(key2
, &put_value
);
228 transaction
->Put(key2
, &put_value
);
230 leveldb::Status status
= transaction
->Commit();
231 EXPECT_TRUE(status
.ok());
233 status
= leveldb
->Get(key1
, &got_value
, &found
);
234 EXPECT_TRUE(status
.ok());
236 EXPECT_EQ(value1
, got_value
);
238 status
= leveldb
->Get(key2
, &got_value
, &found
);
239 EXPECT_TRUE(status
.ok());
241 EXPECT_EQ(value3
, got_value
);
244 TEST(LevelDB
, Locking
) {
245 base::ScopedTempDir temp_directory
;
246 ASSERT_TRUE(temp_directory
.CreateUniqueTempDir());
248 leveldb::Env
* env
= LevelDBEnv::Get();
249 base::FilePath file
= temp_directory
.path().AppendASCII("LOCK");
250 leveldb::FileLock
* lock
;
251 leveldb::Status status
= env
->LockFile(file
.AsUTF8Unsafe(), &lock
);
252 EXPECT_TRUE(status
.ok());
254 status
= env
->UnlockFile(lock
);
255 EXPECT_TRUE(status
.ok());
257 status
= env
->LockFile(file
.AsUTF8Unsafe(), &lock
);
258 EXPECT_TRUE(status
.ok());
260 leveldb::FileLock
* lock2
;
261 status
= env
->LockFile(file
.AsUTF8Unsafe(), &lock2
);
262 EXPECT_FALSE(status
.ok());
264 status
= env
->UnlockFile(lock
);
265 EXPECT_TRUE(status
.ok());
268 } // namespace content