leveldb_unittest.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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 <algorithm>
6#include <cstring>
7#include <vector>
8
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 "content/browser/indexed_db/leveldb/leveldb_comparator.h"
14#include "content/browser/indexed_db/leveldb/leveldb_database.h"
15#include "content/browser/indexed_db/leveldb/leveldb_iterator.h"
16#include "content/browser/indexed_db/leveldb/leveldb_slice.h"
17#include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
18#include "testing/gtest/include/gtest/gtest.h"
19
20namespace content {
21
22namespace {
23
24class SimpleComparator : public LevelDBComparator {
25 public:
26  virtual int Compare(const LevelDBSlice& a, const LevelDBSlice& b) const
27      OVERRIDE {
28    size_t len = std::min(a.end() - a.begin(), b.end() - b.begin());
29    return memcmp(a.begin(), b.begin(), len);
30  }
31  virtual const char* Name() const OVERRIDE { return "temp_comparator"; }
32};
33
34std::vector<char> EncodeString(const std::string& s) {
35  std::vector<char> ret(s.size());
36  for (size_t i = 0; i < s.size(); ++i)
37    ret[i] = s[i];
38  return ret;
39}
40
41TEST(LevelDBDatabaseTest, CorruptionTest) {
42  base::ScopedTempDir temp_directory;
43  ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
44
45  const std::vector<char> key = EncodeString("key");
46  const std::vector<char> value = EncodeString("value");
47  std::vector<char> put_value;
48  std::string got_value;
49  SimpleComparator comparator;
50
51  scoped_ptr<LevelDBDatabase> leveldb =
52      LevelDBDatabase::Open(temp_directory.path(), &comparator);
53  EXPECT_TRUE(leveldb);
54  put_value = value;
55  bool success = leveldb->Put(LevelDBSlice(key), &put_value);
56  EXPECT_TRUE(success);
57  leveldb.Pass();
58  EXPECT_FALSE(leveldb);
59
60  leveldb = LevelDBDatabase::Open(temp_directory.path(), &comparator);
61  EXPECT_TRUE(leveldb);
62  bool found = false;
63  success = leveldb->Get(LevelDBSlice(key), &got_value, &found);
64  EXPECT_TRUE(success);
65  EXPECT_TRUE(found);
66  EXPECT_EQ(value, std::vector<char>(got_value.begin(), got_value.end()));
67  leveldb.Pass();
68  EXPECT_FALSE(leveldb);
69
70  base::FilePath file_path = temp_directory.path().AppendASCII("CURRENT");
71  base::PlatformFile handle = base::CreatePlatformFile(
72      file_path,
73      base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE,
74      NULL,
75      NULL);
76  base::TruncatePlatformFile(handle, 0);
77  base::ClosePlatformFile(handle);
78
79  leveldb = LevelDBDatabase::Open(temp_directory.path(), &comparator);
80  EXPECT_FALSE(leveldb);
81
82  bool destroyed = LevelDBDatabase::Destroy(temp_directory.path());
83  EXPECT_TRUE(destroyed);
84
85  leveldb = LevelDBDatabase::Open(temp_directory.path(), &comparator);
86  EXPECT_TRUE(leveldb);
87  success = leveldb->Get(LevelDBSlice(key), &got_value, &found);
88  EXPECT_TRUE(success);
89  EXPECT_FALSE(found);
90}
91
92TEST(LevelDBDatabaseTest, Transaction) {
93  base::ScopedTempDir temp_directory;
94  ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
95
96  const std::vector<char> key = EncodeString("key");
97  std::string got_value;
98  std::vector<char> put_value;
99  SimpleComparator comparator;
100
101  scoped_ptr<LevelDBDatabase> leveldb =
102      LevelDBDatabase::Open(temp_directory.path(), &comparator);
103  EXPECT_TRUE(leveldb);
104
105  const std::vector<char> old_value = EncodeString("value");
106  put_value = old_value;
107  bool success = leveldb->Put(LevelDBSlice(key), &put_value);
108  EXPECT_TRUE(success);
109
110  scoped_refptr<LevelDBTransaction> transaction =
111      LevelDBTransaction::Create(leveldb.get());
112
113  const std::vector<char> new_value = EncodeString("new value");
114  put_value = new_value;
115  success = leveldb->Put(LevelDBSlice(key), &put_value);
116  EXPECT_TRUE(success);
117
118  bool found = false;
119  success = transaction->Get(LevelDBSlice(key), &got_value, &found);
120  EXPECT_TRUE(success);
121  EXPECT_TRUE(found);
122  EXPECT_EQ(
123      comparator.Compare(LevelDBSlice(got_value), LevelDBSlice(old_value)), 0);
124
125  found = false;
126  success = leveldb->Get(LevelDBSlice(key), &got_value, &found);
127  EXPECT_TRUE(success);
128  EXPECT_TRUE(found);
129  EXPECT_EQ(
130      comparator.Compare(LevelDBSlice(got_value), LevelDBSlice(new_value)), 0);
131
132  const std::vector<char> added_key = EncodeString("added key");
133  const std::vector<char> added_value = EncodeString("added value");
134  put_value = added_value;
135  success = leveldb->Put(LevelDBSlice(added_key), &put_value);
136  EXPECT_TRUE(success);
137
138  success = leveldb->Get(LevelDBSlice(added_key), &got_value, &found);
139  EXPECT_TRUE(success);
140  EXPECT_TRUE(found);
141  EXPECT_EQ(
142      comparator.Compare(LevelDBSlice(got_value), LevelDBSlice(added_value)),
143      0);
144
145  success = transaction->Get(LevelDBSlice(added_key), &got_value, &found);
146  EXPECT_TRUE(success);
147  EXPECT_FALSE(found);
148
149  const std::vector<char> another_key = EncodeString("another key");
150  const std::vector<char> another_value = EncodeString("another value");
151  put_value = another_value;
152  transaction->Put(LevelDBSlice(another_key), &put_value);
153
154  success = transaction->Get(LevelDBSlice(another_key), &got_value, &found);
155  EXPECT_TRUE(success);
156  EXPECT_TRUE(found);
157  EXPECT_EQ(
158      comparator.Compare(LevelDBSlice(got_value), LevelDBSlice(another_value)),
159      0);
160}
161
162TEST(LevelDBDatabaseTest, TransactionIterator) {
163  base::ScopedTempDir temp_directory;
164  ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
165
166  const std::vector<char> key1 = EncodeString("key1");
167  const std::vector<char> value1 = EncodeString("value1");
168  const std::vector<char> key2 = EncodeString("key2");
169  const std::vector<char> value2 = EncodeString("value2");
170  std::vector<char> put_value;
171  SimpleComparator comparator;
172  bool success;
173
174  scoped_ptr<LevelDBDatabase> leveldb =
175      LevelDBDatabase::Open(temp_directory.path(), &comparator);
176  EXPECT_TRUE(leveldb);
177
178  put_value = value1;
179  success = leveldb->Put(LevelDBSlice(key1), &put_value);
180  EXPECT_TRUE(success);
181  put_value = value2;
182  success = leveldb->Put(LevelDBSlice(key2), &put_value);
183  EXPECT_TRUE(success);
184
185  scoped_refptr<LevelDBTransaction> transaction =
186      LevelDBTransaction::Create(leveldb.get());
187
188  success = leveldb->Remove(LevelDBSlice(key2));
189  EXPECT_TRUE(success);
190
191  scoped_ptr<LevelDBIterator> it = transaction->CreateIterator();
192
193  it->Seek(LevelDBSlice(std::string()));
194
195  EXPECT_TRUE(it->IsValid());
196  EXPECT_EQ(comparator.Compare(LevelDBSlice(it->Key()), LevelDBSlice(key1)), 0);
197  EXPECT_EQ(comparator.Compare(it->Value(), LevelDBSlice(value1)), 0);
198
199  it->Next();
200
201  EXPECT_TRUE(it->IsValid());
202  EXPECT_EQ(comparator.Compare(it->Key(), LevelDBSlice(key2)), 0);
203  EXPECT_EQ(comparator.Compare(it->Value(), LevelDBSlice(value2)), 0);
204
205  it->Next();
206
207  EXPECT_FALSE(it->IsValid());
208}
209
210}  // namespace
211
212}  // namespace content
213