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_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 leveldb::Status status
= leveldb
->Put(key
, &put_value
);
51 EXPECT_TRUE(status
.ok());
53 EXPECT_FALSE(leveldb
);
55 LevelDBDatabase::Open(temp_directory
.path(), &comparator
, &leveldb
);
58 status
= leveldb
->Get(key
, &got_value
, &found
);
59 EXPECT_TRUE(status
.ok());
61 EXPECT_EQ(value
, got_value
);
63 EXPECT_FALSE(leveldb
);
65 base::FilePath file_path
= temp_directory
.path().AppendASCII("CURRENT");
66 base::File
file(file_path
, base::File::FLAG_OPEN
| base::File::FLAG_WRITE
);
70 status
= LevelDBDatabase::Open(temp_directory
.path(), &comparator
, &leveldb
);
71 EXPECT_FALSE(leveldb
);
72 EXPECT_FALSE(status
.ok());
74 status
= LevelDBDatabase::Destroy(temp_directory
.path());
75 EXPECT_TRUE(status
.ok());
77 status
= LevelDBDatabase::Open(temp_directory
.path(), &comparator
, &leveldb
);
78 EXPECT_TRUE(status
.ok());
80 status
= leveldb
->Get(key
, &got_value
, &found
);
81 EXPECT_TRUE(status
.ok());
85 TEST(LevelDBDatabaseTest
, Transaction
) {
86 base::ScopedTempDir temp_directory
;
87 ASSERT_TRUE(temp_directory
.CreateUniqueTempDir());
89 const std::string
key("key");
90 std::string got_value
;
91 std::string put_value
;
92 SimpleComparator comparator
;
94 scoped_ptr
<LevelDBDatabase
> leveldb
;
95 LevelDBDatabase::Open(temp_directory
.path(), &comparator
, &leveldb
);
98 const std::string
old_value("value");
99 put_value
= old_value
;
100 leveldb::Status status
= leveldb
->Put(key
, &put_value
);
101 EXPECT_TRUE(status
.ok());
103 scoped_refptr
<LevelDBTransaction
> transaction
=
104 new LevelDBTransaction(leveldb
.get());
106 const std::string
new_value("new value");
107 put_value
= new_value
;
108 status
= leveldb
->Put(key
, &put_value
);
109 EXPECT_TRUE(status
.ok());
112 status
= transaction
->Get(key
, &got_value
, &found
);
113 EXPECT_TRUE(status
.ok());
115 EXPECT_EQ(comparator
.Compare(got_value
, old_value
), 0);
118 status
= leveldb
->Get(key
, &got_value
, &found
);
119 EXPECT_TRUE(status
.ok());
121 EXPECT_EQ(comparator
.Compare(got_value
, new_value
), 0);
123 const std::string
added_key("added key");
124 const std::string
added_value("added value");
125 put_value
= added_value
;
126 status
= leveldb
->Put(added_key
, &put_value
);
127 EXPECT_TRUE(status
.ok());
129 status
= leveldb
->Get(added_key
, &got_value
, &found
);
130 EXPECT_TRUE(status
.ok());
132 EXPECT_EQ(comparator
.Compare(got_value
, added_value
), 0);
134 status
= transaction
->Get(added_key
, &got_value
, &found
);
135 EXPECT_TRUE(status
.ok());
138 const std::string
another_key("another key");
139 const std::string
another_value("another value");
140 put_value
= another_value
;
141 transaction
->Put(another_key
, &put_value
);
143 status
= transaction
->Get(another_key
, &got_value
, &found
);
144 EXPECT_TRUE(status
.ok());
146 EXPECT_EQ(comparator
.Compare(got_value
, another_value
), 0);
149 TEST(LevelDBDatabaseTest
, TransactionIterator
) {
150 base::ScopedTempDir temp_directory
;
151 ASSERT_TRUE(temp_directory
.CreateUniqueTempDir());
153 const std::string
key1("key1");
154 const std::string
value1("value1");
155 const std::string
key2("key2");
156 const std::string
value2("value2");
157 std::string put_value
;
158 SimpleComparator comparator
;
160 scoped_ptr
<LevelDBDatabase
> leveldb
;
161 LevelDBDatabase::Open(temp_directory
.path(), &comparator
, &leveldb
);
162 EXPECT_TRUE(leveldb
);
165 leveldb::Status s
= leveldb
->Put(key1
, &put_value
);
168 s
= leveldb
->Put(key2
, &put_value
);
171 scoped_refptr
<LevelDBTransaction
> transaction
=
172 new LevelDBTransaction(leveldb
.get());
174 s
= leveldb
->Remove(key2
);
177 scoped_ptr
<LevelDBIterator
> it
= transaction
->CreateIterator();
179 it
->Seek(std::string());
181 EXPECT_TRUE(it
->IsValid());
182 EXPECT_EQ(comparator
.Compare(it
->Key(), key1
), 0);
183 EXPECT_EQ(comparator
.Compare(it
->Value(), value1
), 0);
187 EXPECT_TRUE(it
->IsValid());
188 EXPECT_EQ(comparator
.Compare(it
->Key(), key2
), 0);
189 EXPECT_EQ(comparator
.Compare(it
->Value(), value2
), 0);
193 EXPECT_FALSE(it
->IsValid());
196 TEST(LevelDBDatabaseTest
, TransactionCommitTest
) {
197 base::ScopedTempDir temp_directory
;
198 ASSERT_TRUE(temp_directory
.CreateUniqueTempDir());
200 const std::string
key1("key1");
201 const std::string
key2("key2");
202 const std::string
value1("value1");
203 const std::string
value2("value2");
204 const std::string
value3("value3");
206 std::string put_value
;
207 std::string got_value
;
208 SimpleComparator comparator
;
211 scoped_ptr
<LevelDBDatabase
> leveldb
;
212 LevelDBDatabase::Open(temp_directory
.path(), &comparator
, &leveldb
);
213 EXPECT_TRUE(leveldb
);
215 scoped_refptr
<LevelDBTransaction
> transaction
=
216 new LevelDBTransaction(leveldb
.get());
219 transaction
->Put(key1
, &put_value
);
222 transaction
->Put(key2
, &put_value
);
225 transaction
->Put(key2
, &put_value
);
227 leveldb::Status status
= transaction
->Commit();
228 EXPECT_TRUE(status
.ok());
230 status
= leveldb
->Get(key1
, &got_value
, &found
);
231 EXPECT_TRUE(status
.ok());
233 EXPECT_EQ(value1
, got_value
);
235 status
= leveldb
->Get(key2
, &got_value
, &found
);
236 EXPECT_TRUE(status
.ok());
238 EXPECT_EQ(value3
, got_value
);
241 TEST(LevelDB
, Locking
) {
242 base::ScopedTempDir temp_directory
;
243 ASSERT_TRUE(temp_directory
.CreateUniqueTempDir());
245 leveldb::Env
* env
= leveldb::IDBEnv();
246 base::FilePath file
= temp_directory
.path().AppendASCII("LOCK");
247 leveldb::FileLock
* lock
;
248 leveldb::Status status
= env
->LockFile(file
.AsUTF8Unsafe(), &lock
);
249 EXPECT_TRUE(status
.ok());
251 status
= env
->UnlockFile(lock
);
252 EXPECT_TRUE(status
.ok());
254 status
= env
->LockFile(file
.AsUTF8Unsafe(), &lock
);
255 EXPECT_TRUE(status
.ok());
257 leveldb::FileLock
* lock2
;
258 status
= env
->LockFile(file
.AsUTF8Unsafe(), &lock2
);
259 EXPECT_FALSE(status
.ok());
261 status
= env
->UnlockFile(lock
);
262 EXPECT_TRUE(status
.ok());
267 } // namespace content