Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(880)

Side by Side Diff: content/browser/leveldb_wrapper_impl_unittest.cc

Issue 2583253002: Start adding tests for LevelDBWrapper, and fix a bunch of bugs. (Closed)
Patch Set: nicer Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/browser/leveldb_wrapper_impl.cc ('k') | content/test/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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 "content/browser/leveldb_wrapper_impl.h"
6
7 #include "base/debug/stack_trace.h"
8
9 #include "components/leveldb/public/cpp/util.h"
10 #include "content/public/test/test_browser_thread_bundle.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 using leveldb::StdStringToUint8Vector;
14 using leveldb::Uint8VectorToStdString;
15
16 namespace content {
17
18 namespace {
19
20 const char* kTestPrefix = "abc";
21 const char* kTestSource = "source";
22 const size_t kTestSizeLimit = 512;
23
24 leveldb::mojom::KeyValuePtr CreateKeyValue(std::vector<uint8_t> key,
25 std::vector<uint8_t> value) {
26 leveldb::mojom::KeyValuePtr result = leveldb::mojom::KeyValue::New();
27 result->key = std::move(key);
28 result->value = std::move(value);
29 return result;
30 }
31
32 base::StringPiece ToStringPiece(const std::vector<uint8_t> data) {
33 return base::StringPiece(reinterpret_cast<const char*>(data.data()),
34 data.size());
35 }
36
37 bool StartsWith(const std::vector<uint8_t>& key,
38 const std::vector<uint8_t>& prefix) {
39 return base::StartsWith(ToStringPiece(key), ToStringPiece(prefix),
40 base::CompareCase::SENSITIVE);
41 }
42
43 class MockLevelDBDatabase : public leveldb::mojom::LevelDBDatabase {
44 public:
45 explicit MockLevelDBDatabase(
jam 2016/12/19 19:19:09 nit: no need for explicit
Marijn Kruisselbrink 2016/12/20 01:19:46 Why not? It's a single argument constructor.
46 std::map<std::vector<uint8_t>, std::vector<uint8_t>>* mock_data)
47 : mock_data_(*mock_data) {}
48
49 void Put(const std::vector<uint8_t>& key,
50 const std::vector<uint8_t>& value,
51 const PutCallback& callback) override {
52 FAIL();
53 }
54
55 void Delete(const std::vector<uint8_t>& key,
56 const DeleteCallback& callback) override {
57 FAIL();
58 }
59
60 void DeletePrefixed(const std::vector<uint8_t>& key_prefix,
61 const DeletePrefixedCallback& callback) override {
62 FAIL();
63 }
64
65 void Write(std::vector<leveldb::mojom::BatchedOperationPtr> operations,
66 const WriteCallback& callback) override {
67 for (const auto& op : operations) {
68 switch (op->type) {
69 case leveldb::mojom::BatchOperationType::PUT_KEY:
70 mock_data_[op->key] = *op->value;
71 break;
72 case leveldb::mojom::BatchOperationType::DELETE_KEY:
73 mock_data_.erase(op->key);
74 break;
75 case leveldb::mojom::BatchOperationType::DELETE_PREFIXED_KEY:
76 FAIL();
77 break;
78 }
79 }
80 callback.Run(leveldb::mojom::DatabaseError::OK);
81 }
82
83 void Get(const std::vector<uint8_t>& key,
84 const GetCallback& callback) override {
85 FAIL();
86 }
87
88 void GetPrefixed(const std::vector<uint8_t>& key_prefix,
89 const GetPrefixedCallback& callback) override {
90 std::vector<leveldb::mojom::KeyValuePtr> data;
91 for (const auto& row : mock_data_) {
92 if (StartsWith(row.first, key_prefix)) {
93 data.push_back(CreateKeyValue(row.first, row.second));
94 }
95 }
96 callback.Run(leveldb::mojom::DatabaseError::OK, std::move(data));
97 }
98
99 void GetSnapshot(const GetSnapshotCallback& callback) override { FAIL(); }
100
101 void ReleaseSnapshot(const base::UnguessableToken& snapshot) override {
102 FAIL();
103 }
104
105 void GetFromSnapshot(const base::UnguessableToken& snapshot,
106 const std::vector<uint8_t>& key,
107 const GetCallback& callback) override {
108 FAIL();
109 }
110
111 void NewIterator(const NewIteratorCallback& callback) override { FAIL(); }
112
113 void NewIteratorFromSnapshot(
114 const base::UnguessableToken& snapshot,
115 const NewIteratorFromSnapshotCallback& callback) override {
116 FAIL();
117 }
118
119 void ReleaseIterator(const base::UnguessableToken& iterator) override {
120 FAIL();
121 }
122
123 void IteratorSeekToFirst(
124 const base::UnguessableToken& iterator,
125 const IteratorSeekToFirstCallback& callback) override {
126 FAIL();
127 }
128
129 void IteratorSeekToLast(const base::UnguessableToken& iterator,
130 const IteratorSeekToLastCallback& callback) override {
131 FAIL();
132 }
133
134 void IteratorSeek(const base::UnguessableToken& iterator,
135 const std::vector<uint8_t>& target,
136 const IteratorSeekToLastCallback& callback) override {
137 FAIL();
138 }
139
140 void IteratorNext(const base::UnguessableToken& iterator,
141 const IteratorNextCallback& callback) override {
142 FAIL();
143 }
144
145 void IteratorPrev(const base::UnguessableToken& iterator,
146 const IteratorPrevCallback& callback) override {
147 FAIL();
148 }
149
150 private:
151 std::map<std::vector<uint8_t>, std::vector<uint8_t>>& mock_data_;
152 };
153
154 void NoOp() {}
155
156 void GetCallback(bool* called,
157 bool* success_out,
158 std::vector<uint8_t>* value_out,
159 bool success,
160 const std::vector<uint8_t>& value) {
161 *called = true;
162 *success_out = success;
163 *value_out = value;
164 }
165
166 void GetAllCallback(bool* called,
167 leveldb::mojom::DatabaseError* status_out,
168 std::vector<mojom::KeyValuePtr>* data_out,
169 leveldb::mojom::DatabaseError status,
170 std::vector<mojom::KeyValuePtr> data) {
171 *called = true;
172 *status_out = status;
173 *data_out = std::move(data);
174 }
175
176 void SuccessCallback(bool* called, bool* success_out, bool success) {
177 *called = true;
178 *success_out = success;
179 }
180
181 void NoOpSuccess(bool success) {}
182
183 } // namespace
184
185 class LevelDBWrapperImplTest : public testing::Test {
186 public:
187 LevelDBWrapperImplTest()
188 : db_(&mock_data_),
189 level_db_wrapper_(&db_,
190 kTestPrefix,
191 kTestSizeLimit,
192 base::TimeDelta::FromSeconds(5),
193 10 * 1024 * 1024 /* max_bytes_per_hour */,
194 60 /* max_commits_per_hour */,
195 base::Bind(&NoOp)) {
196 set_mock_data(std::string(kTestPrefix) + "def", "defdata");
197 set_mock_data(std::string(kTestPrefix) + "123", "123data");
198 set_mock_data("123", "baddata");
199 }
200
201 void set_mock_data(const std::string& key, const std::string& value) {
202 mock_data_[StdStringToUint8Vector(key)] = StdStringToUint8Vector(value);
203 }
204
205 bool has_mock_data(const std::string& key) {
206 return mock_data_.find(StdStringToUint8Vector(key)) != mock_data_.end();
207 }
208
209 std::string get_mock_data(const std::string& key) {
210 return has_mock_data(key)
211 ? Uint8VectorToStdString(mock_data_[StdStringToUint8Vector(key)])
212 : "";
213 }
214
215 mojom::LevelDBWrapper* wrapper() { return &level_db_wrapper_; }
216
217 void CommitChanges() {
218 ASSERT_TRUE(level_db_wrapper_.commit_batch_);
219 level_db_wrapper_.CommitChanges();
220 }
221
222 private:
223 TestBrowserThreadBundle thread_bundle_;
224 std::map<std::vector<uint8_t>, std::vector<uint8_t>> mock_data_;
225 MockLevelDBDatabase db_;
226 LevelDBWrapperImpl level_db_wrapper_;
227 };
228
229 TEST_F(LevelDBWrapperImplTest, GetLoadedFromMap) {
230 bool called = false;
231 bool success;
232 std::vector<uint8_t> result;
233 wrapper()->Get(StdStringToUint8Vector("123"),
234 base::Bind(&GetCallback, &called, &success, &result));
235 ASSERT_TRUE(called);
236 EXPECT_TRUE(success);
237 EXPECT_EQ(StdStringToUint8Vector("123data"), result);
238
239 called = false;
240 wrapper()->Get(StdStringToUint8Vector("x"),
241 base::Bind(&GetCallback, &called, &success, &result));
242 ASSERT_TRUE(called);
243 EXPECT_FALSE(success);
244 }
245
246 TEST_F(LevelDBWrapperImplTest, GetFromPutOverwrite) {
247 std::vector<uint8_t> key = StdStringToUint8Vector("123");
248 std::vector<uint8_t> value = StdStringToUint8Vector("foo");
249
250 bool called = false;
251 bool success;
252 wrapper()->Put(key, value, kTestSource,
253 base::Bind(&SuccessCallback, &called, &success));
254 ASSERT_TRUE(called);
255 EXPECT_TRUE(success);
256
257 called = false;
258 std::vector<uint8_t> result;
259 wrapper()->Get(key, base::Bind(&GetCallback, &called, &success, &result));
260 ASSERT_TRUE(called);
261 EXPECT_TRUE(success);
262 EXPECT_EQ(value, result);
263 }
264
265 TEST_F(LevelDBWrapperImplTest, GetFromPutNewKey) {
266 std::vector<uint8_t> key = StdStringToUint8Vector("newkey");
267 std::vector<uint8_t> value = StdStringToUint8Vector("foo");
268
269 bool called = false;
270 bool success;
271 wrapper()->Put(key, value, kTestSource,
272 base::Bind(&SuccessCallback, &called, &success));
273 ASSERT_TRUE(called);
274 EXPECT_TRUE(success);
275
276 called = false;
277 std::vector<uint8_t> result;
278 wrapper()->Get(key, base::Bind(&GetCallback, &called, &success, &result));
279 ASSERT_TRUE(called);
280 EXPECT_TRUE(success);
281 EXPECT_EQ(value, result);
282 }
283
284 TEST_F(LevelDBWrapperImplTest, GetAll) {
285 bool called = false;
286 leveldb::mojom::DatabaseError status;
287 std::vector<mojom::KeyValuePtr> data;
288 wrapper()->GetAll(kTestSource,
289 base::Bind(&GetAllCallback, &called, &status, &data));
290 ASSERT_TRUE(called);
291 EXPECT_EQ(leveldb::mojom::DatabaseError::OK, status);
292 EXPECT_EQ(2u, data.size());
293 }
294
295 TEST_F(LevelDBWrapperImplTest, CommitPutToDB) {
296 std::string key1 = "123";
297 std::string value1 = "foo";
298 std::string key2 = "abc";
299 std::string value2 = "data abc";
300
301 wrapper()->Put(StdStringToUint8Vector(key1), StdStringToUint8Vector(value1),
302 kTestSource, base::Bind(&NoOpSuccess));
303 wrapper()->Put(StdStringToUint8Vector(key2),
304 StdStringToUint8Vector("old value"), kTestSource,
305 base::Bind(&NoOpSuccess));
306 wrapper()->Put(StdStringToUint8Vector(key2), StdStringToUint8Vector(value2),
307 kTestSource, base::Bind(&NoOpSuccess));
308
309 CommitChanges();
310
311 EXPECT_TRUE(has_mock_data(kTestPrefix + key1));
312 EXPECT_EQ(value1, get_mock_data(kTestPrefix + key1));
313 EXPECT_TRUE(has_mock_data(kTestPrefix + key2));
314 EXPECT_EQ(value2, get_mock_data(kTestPrefix + key2));
315 }
316
317 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/leveldb_wrapper_impl.cc ('k') | content/test/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698