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

Side by Side Diff: components/leveldb_proto/core/proto_database_impl_unittest.cc

Issue 330833002: Extract protobuf database into a new 'leveldb_proto' component (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: components/ OWNERS Created 6 years, 6 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/dom_distiller/core/dom_distiller_database.h" 5 #include "components/leveldb_proto/core/proto_database_impl.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/files/scoped_temp_dir.h" 11 #include "base/files/scoped_temp_dir.h"
12 #include "base/run_loop.h" 12 #include "base/run_loop.h"
13 #include "base/threading/thread.h" 13 #include "base/threading/thread.h"
14 #include "components/dom_distiller/core/article_entry.h" 14 #include "components/leveldb_proto/testing/proto/test.pb.h"
15 #include "testing/gmock/include/gmock/gmock.h" 15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
17 17
18 using base::MessageLoop; 18 using base::MessageLoop;
19 using base::ScopedTempDir; 19 using base::ScopedTempDir;
20 using testing::Invoke; 20 using testing::Invoke;
21 using testing::Return; 21 using testing::Return;
22 using testing::_; 22 using testing::_;
23 23
24 namespace dom_distiller { 24 namespace leveldb_proto {
25 25
26 namespace { 26 namespace {
27 27
28 typedef std::map<std::string, ArticleEntry> EntryMap; 28 typedef std::map<std::string, TestProto> EntryMap;
29 29
30 class MockDB : public DomDistillerDatabase::Database { 30 class MockDB : public ProtoDatabaseImpl<TestProto>::Database {
31 public: 31 public:
32 MOCK_METHOD1(Init, bool(const base::FilePath&)); 32 MOCK_METHOD1(Init, bool(const base::FilePath&));
33 MOCK_METHOD2(Save, bool(const EntryVector&, const EntryVector&)); 33 MOCK_METHOD2(Save, bool(const ProtoDatabase<TestProto>::KeyEntryVector&,
34 MOCK_METHOD1(Load, bool(EntryVector*)); 34 const std::vector<std::string>&));
35 MOCK_METHOD1(Load, bool(std::vector<TestProto>*));
35 36
36 MockDB() { 37 MockDB() {
37 ON_CALL(*this, Init(_)).WillByDefault(Return(true)); 38 ON_CALL(*this, Init(_)).WillByDefault(Return(true));
38 ON_CALL(*this, Save(_, _)).WillByDefault(Return(true)); 39 ON_CALL(*this, Save(_, _)).WillByDefault(Return(true));
39 ON_CALL(*this, Load(_)).WillByDefault(Return(true)); 40 ON_CALL(*this, Load(_)).WillByDefault(Return(true));
40 } 41 }
41 42
42 bool LoadEntries(EntryVector* entries); 43 bool LoadEntries(std::vector<TestProto>* entries);
43 }; 44 };
44 45
45 class MockDatabaseCaller { 46 class MockDatabaseCaller {
46 public: 47 public:
47 MOCK_METHOD1(InitCallback, void(bool)); 48 MOCK_METHOD1(InitCallback, void(bool));
48 MOCK_METHOD1(SaveCallback, void(bool)); 49 MOCK_METHOD1(SaveCallback, void(bool));
49 void LoadCallback(bool success, scoped_ptr<EntryVector> entries) { 50 void LoadCallback(bool success, scoped_ptr<std::vector<TestProto>> entries) {
50 LoadCallback1(success, entries.get()); 51 LoadCallback1(success, entries.get());
51 } 52 }
52 MOCK_METHOD2(LoadCallback1, void(bool, EntryVector*)); 53 MOCK_METHOD2(LoadCallback1, void(bool, std::vector<TestProto>*));
53 }; 54 };
54 55
55 } // namespace 56 } // namespace
56 57
57 EntryMap GetSmallModel() { 58 EntryMap GetSmallModel() {
58 EntryMap model; 59 EntryMap model;
59 60
60 model["key0"].set_entry_id("key0"); 61 model["0"].set_id("0");
61 model["key0"].add_pages()->set_url("http://foo.com/1"); 62 model["0"].set_data("http://foo.com/1");
62 model["key0"].add_pages()->set_url("http://foo.com/2");
63 model["key0"].add_pages()->set_url("http://foo.com/3");
64 63
65 model["key1"].set_entry_id("key1"); 64 model["1"].set_id("1");
66 model["key1"].add_pages()->set_url("http://bar.com/all"); 65 model["1"].set_data("http://bar.com/all");
67 66
68 model["key2"].set_entry_id("key2"); 67 model["2"].set_id("2");
69 model["key2"].add_pages()->set_url("http://baz.com/1"); 68 model["2"].set_data("http://baz.com/1");
70 69
71 return model; 70 return model;
72 } 71 }
73 72
74 void ExpectEntryPointersEquals(EntryMap expected, const EntryVector& actual) { 73 void ExpectEntryPointersEquals(EntryMap expected,
74 const std::vector<TestProto>& actual) {
75 EXPECT_EQ(expected.size(), actual.size()); 75 EXPECT_EQ(expected.size(), actual.size());
76 for (size_t i = 0; i < actual.size(); i++) { 76 for (size_t i = 0; i < actual.size(); i++) {
77 EntryMap::iterator expected_it = 77 EntryMap::iterator expected_it = expected.find(actual[i].id());
78 expected.find(std::string(actual[i].entry_id()));
79 EXPECT_TRUE(expected_it != expected.end()); 78 EXPECT_TRUE(expected_it != expected.end());
80 std::string serialized_expected = expected_it->second.SerializeAsString(); 79 std::string serialized_expected = expected_it->second.SerializeAsString();
81 std::string serialized_actual = actual[i].SerializeAsString(); 80 std::string serialized_actual = actual[i].SerializeAsString();
82 EXPECT_EQ(serialized_expected, serialized_actual); 81 EXPECT_EQ(serialized_expected, serialized_actual);
83 expected.erase(expected_it); 82 expected.erase(expected_it);
84 } 83 }
85 } 84 }
86 85
87 class DomDistillerDatabaseTest : public testing::Test { 86 class ProtoDatabaseImplTest : public testing::Test {
88 public: 87 public:
89 virtual void SetUp() { 88 virtual void SetUp() {
90 main_loop_.reset(new MessageLoop()); 89 main_loop_.reset(new MessageLoop());
91 db_.reset(new DomDistillerDatabase(main_loop_->message_loop_proxy())); 90 db_.reset(
91 new ProtoDatabaseImpl<TestProto>(main_loop_->message_loop_proxy()));
92 } 92 }
93 93
94 virtual void TearDown() { 94 virtual void TearDown() {
95 db_.reset(); 95 db_.reset();
96 base::RunLoop().RunUntilIdle(); 96 base::RunLoop().RunUntilIdle();
97 main_loop_.reset(); 97 main_loop_.reset();
98 } 98 }
99 99
100 scoped_ptr<DomDistillerDatabase> db_; 100 scoped_ptr<ProtoDatabaseImpl<TestProto>> db_;
101 scoped_ptr<MessageLoop> main_loop_; 101 scoped_ptr<MessageLoop> main_loop_;
102 }; 102 };
103 103
104 // Test that DomDistillerDatabase calls Init on the underlying database and that 104 // Test that ProtoDatabaseImpl calls Init on the underlying database and that
105 // the caller's InitCallback is called with the correct value. 105 // the caller's InitCallback is called with the correct value.
106 TEST_F(DomDistillerDatabaseTest, TestDBInitSuccess) { 106 TEST_F(ProtoDatabaseImplTest, TestDBInitSuccess) {
107 base::FilePath path(FILE_PATH_LITERAL("/fake/path")); 107 base::FilePath path(FILE_PATH_LITERAL("/fake/path"));
108 108
109 MockDB* mock_db = new MockDB(); 109 MockDB* mock_db = new MockDB();
110 EXPECT_CALL(*mock_db, Init(path)).WillOnce(Return(true)); 110 EXPECT_CALL(*mock_db, Init(path)).WillOnce(Return(true));
111 111
112 MockDatabaseCaller caller; 112 MockDatabaseCaller caller;
113 EXPECT_CALL(caller, InitCallback(true)); 113 EXPECT_CALL(caller, InitCallback(true));
114 114
115 db_->InitWithDatabase( 115 db_->InitWithDatabase(
116 scoped_ptr<DomDistillerDatabase::Database>(mock_db), 116 scoped_ptr<ProtoDatabaseImpl<TestProto>::Database>(mock_db),
117 base::FilePath(path), 117 base::FilePath(path),
118 base::Bind(&MockDatabaseCaller::InitCallback, base::Unretained(&caller))); 118 base::Bind(&MockDatabaseCaller::InitCallback, base::Unretained(&caller)));
119 119
120 base::RunLoop().RunUntilIdle(); 120 base::RunLoop().RunUntilIdle();
121 } 121 }
122 122
123 TEST_F(DomDistillerDatabaseTest, TestDBInitFailure) { 123 TEST_F(ProtoDatabaseImplTest, TestDBInitFailure) {
124 base::FilePath path(FILE_PATH_LITERAL("/fake/path")); 124 base::FilePath path(FILE_PATH_LITERAL("/fake/path"));
125 125
126 MockDB* mock_db = new MockDB(); 126 MockDB* mock_db = new MockDB();
127 EXPECT_CALL(*mock_db, Init(path)).WillOnce(Return(false)); 127 EXPECT_CALL(*mock_db, Init(path)).WillOnce(Return(false));
128 128
129 MockDatabaseCaller caller; 129 MockDatabaseCaller caller;
130 EXPECT_CALL(caller, InitCallback(false)); 130 EXPECT_CALL(caller, InitCallback(false));
131 131
132 db_->InitWithDatabase( 132 db_->InitWithDatabase(
133 scoped_ptr<DomDistillerDatabase::Database>(mock_db), 133 scoped_ptr<ProtoDatabaseImpl<TestProto>::Database>(mock_db),
134 base::FilePath(path), 134 base::FilePath(path),
135 base::Bind(&MockDatabaseCaller::InitCallback, base::Unretained(&caller))); 135 base::Bind(&MockDatabaseCaller::InitCallback, base::Unretained(&caller)));
136 136
137 base::RunLoop().RunUntilIdle(); 137 base::RunLoop().RunUntilIdle();
138 } 138 }
139 139
140 ACTION_P(AppendLoadEntries, model) { 140 ACTION_P(AppendLoadEntries, model) {
141 EntryVector* output = arg0; 141 std::vector<TestProto>* output = arg0;
142 for (EntryMap::const_iterator it = model.begin(); it != model.end(); ++it) { 142 for (EntryMap::const_iterator it = model.begin(); it != model.end(); ++it) {
143 output->push_back(it->second); 143 output->push_back(it->second);
144 } 144 }
145 return true; 145 return true;
146 } 146 }
147 147
148 ACTION_P(VerifyLoadEntries, expected) { 148 ACTION_P(VerifyLoadEntries, expected) {
149 EntryVector* actual = arg1; 149 std::vector<TestProto>* actual = arg1;
150 ExpectEntryPointersEquals(expected, *actual); 150 ExpectEntryPointersEquals(expected, *actual);
151 } 151 }
152 152
153 // Test that DomDistillerDatabase calls Load on the underlying database and that 153 // Test that ProtoDatabaseImpl calls Load on the underlying database and that
154 // the caller's LoadCallback is called with the correct success value. Also 154 // the caller's LoadCallback is called with the correct success value. Also
155 // confirms that on success, the expected entries are passed to the caller's 155 // confirms that on success, the expected entries are passed to the caller's
156 // LoadCallback. 156 // LoadCallback.
157 TEST_F(DomDistillerDatabaseTest, TestDBLoadSuccess) { 157 TEST_F(ProtoDatabaseImplTest, TestDBLoadSuccess) {
158 base::FilePath path(FILE_PATH_LITERAL("/fake/path")); 158 base::FilePath path(FILE_PATH_LITERAL("/fake/path"));
159 159
160 MockDB* mock_db = new MockDB(); 160 MockDB* mock_db = new MockDB();
161 MockDatabaseCaller caller; 161 MockDatabaseCaller caller;
162 EntryMap model = GetSmallModel(); 162 EntryMap model = GetSmallModel();
163 163
164 EXPECT_CALL(*mock_db, Init(_)); 164 EXPECT_CALL(*mock_db, Init(_));
165 EXPECT_CALL(caller, InitCallback(_)); 165 EXPECT_CALL(caller, InitCallback(_));
166 db_->InitWithDatabase( 166 db_->InitWithDatabase(
167 scoped_ptr<DomDistillerDatabase::Database>(mock_db), 167 scoped_ptr<ProtoDatabaseImpl<TestProto>::Database>(mock_db),
168 base::FilePath(path), 168 base::FilePath(path),
169 base::Bind(&MockDatabaseCaller::InitCallback, base::Unretained(&caller))); 169 base::Bind(&MockDatabaseCaller::InitCallback, base::Unretained(&caller)));
170 170
171 EXPECT_CALL(*mock_db, Load(_)).WillOnce(AppendLoadEntries(model)); 171 EXPECT_CALL(*mock_db, Load(_)).WillOnce(AppendLoadEntries(model));
172 EXPECT_CALL(caller, LoadCallback1(true, _)) 172 EXPECT_CALL(caller, LoadCallback1(true, _))
173 .WillOnce(VerifyLoadEntries(testing::ByRef(model))); 173 .WillOnce(VerifyLoadEntries(testing::ByRef(model)));
174 db_->LoadEntries( 174 db_->LoadEntries(
175 base::Bind(&MockDatabaseCaller::LoadCallback, base::Unretained(&caller))); 175 base::Bind(&MockDatabaseCaller::LoadCallback, base::Unretained(&caller)));
176 176
177 base::RunLoop().RunUntilIdle(); 177 base::RunLoop().RunUntilIdle();
178 } 178 }
179 179
180 TEST_F(DomDistillerDatabaseTest, TestDBLoadFailure) { 180 TEST_F(ProtoDatabaseImplTest, TestDBLoadFailure) {
181 base::FilePath path(FILE_PATH_LITERAL("/fake/path")); 181 base::FilePath path(FILE_PATH_LITERAL("/fake/path"));
182 182
183 MockDB* mock_db = new MockDB(); 183 MockDB* mock_db = new MockDB();
184 MockDatabaseCaller caller; 184 MockDatabaseCaller caller;
185 185
186 EXPECT_CALL(*mock_db, Init(_)); 186 EXPECT_CALL(*mock_db, Init(_));
187 EXPECT_CALL(caller, InitCallback(_)); 187 EXPECT_CALL(caller, InitCallback(_));
188 db_->InitWithDatabase( 188 db_->InitWithDatabase(
189 scoped_ptr<DomDistillerDatabase::Database>(mock_db), 189 scoped_ptr<ProtoDatabaseImpl<TestProto>::Database>(mock_db),
190 base::FilePath(path), 190 base::FilePath(path),
191 base::Bind(&MockDatabaseCaller::InitCallback, base::Unretained(&caller))); 191 base::Bind(&MockDatabaseCaller::InitCallback, base::Unretained(&caller)));
192 192
193 EXPECT_CALL(*mock_db, Load(_)).WillOnce(Return(false)); 193 EXPECT_CALL(*mock_db, Load(_)).WillOnce(Return(false));
194 EXPECT_CALL(caller, LoadCallback1(false, _)); 194 EXPECT_CALL(caller, LoadCallback1(false, _));
195 db_->LoadEntries( 195 db_->LoadEntries(
196 base::Bind(&MockDatabaseCaller::LoadCallback, base::Unretained(&caller))); 196 base::Bind(&MockDatabaseCaller::LoadCallback, base::Unretained(&caller)));
197 197
198 base::RunLoop().RunUntilIdle(); 198 base::RunLoop().RunUntilIdle();
199 } 199 }
200 200
201 ACTION_P(VerifyUpdateEntries, expected) { 201 ACTION_P(VerifyUpdateEntries, expected) {
202 const EntryVector& actual = arg0; 202 const ProtoDatabase<TestProto>::KeyEntryVector& actual = arg0;
203 ExpectEntryPointersEquals(expected, actual); 203 // Create a vector of TestProto from |actual| to reuse the comparison
204 // function.
205 std::vector<TestProto> extracted_entries;
206 for (ProtoDatabase<TestProto>::KeyEntryVector::const_iterator it =
207 actual.begin();
208 it != actual.end(); ++it) {
209 extracted_entries.push_back(it->second);
210 }
211 ExpectEntryPointersEquals(expected, extracted_entries);
204 return true; 212 return true;
205 } 213 }
206 214
207 // Test that DomDistillerDatabase calls Save on the underlying database with the 215 // Test that ProtoDatabaseImpl calls Save on the underlying database with the
208 // correct entries to save and that the caller's SaveCallback is called with the 216 // correct entries to save and that the caller's SaveCallback is called with the
209 // correct success value. 217 // correct success value.
210 TEST_F(DomDistillerDatabaseTest, TestDBSaveSuccess) { 218 TEST_F(ProtoDatabaseImplTest, TestDBSaveSuccess) {
211 base::FilePath path(FILE_PATH_LITERAL("/fake/path")); 219 base::FilePath path(FILE_PATH_LITERAL("/fake/path"));
212 220
213 MockDB* mock_db = new MockDB(); 221 MockDB* mock_db = new MockDB();
214 MockDatabaseCaller caller; 222 MockDatabaseCaller caller;
215 EntryMap model = GetSmallModel(); 223 EntryMap model = GetSmallModel();
216 224
217 EXPECT_CALL(*mock_db, Init(_)); 225 EXPECT_CALL(*mock_db, Init(_));
218 EXPECT_CALL(caller, InitCallback(_)); 226 EXPECT_CALL(caller, InitCallback(_));
219 db_->InitWithDatabase( 227 db_->InitWithDatabase(
220 scoped_ptr<DomDistillerDatabase::Database>(mock_db), 228 scoped_ptr<ProtoDatabaseImpl<TestProto>::Database>(mock_db),
221 base::FilePath(path), 229 base::FilePath(path),
222 base::Bind(&MockDatabaseCaller::InitCallback, base::Unretained(&caller))); 230 base::Bind(&MockDatabaseCaller::InitCallback, base::Unretained(&caller)));
223 231
224 scoped_ptr<EntryVector> entries(new EntryVector()); 232 scoped_ptr<ProtoDatabase<TestProto>::KeyEntryVector> entries(
233 new ProtoDatabase<TestProto>::KeyEntryVector());
225 for (EntryMap::iterator it = model.begin(); it != model.end(); ++it) { 234 for (EntryMap::iterator it = model.begin(); it != model.end(); ++it) {
226 entries->push_back(it->second); 235 entries->push_back(std::make_pair(it->second.id(), it->second));
227 } 236 }
228 scoped_ptr<EntryVector> entries_to_remove(new EntryVector()); 237 scoped_ptr<std::vector<std::string>> keys_to_remove(
238 new std::vector<std::string>());
229 239
230 EXPECT_CALL(*mock_db, Save(_, _)).WillOnce(VerifyUpdateEntries(model)); 240 EXPECT_CALL(*mock_db, Save(_, _)).WillOnce(VerifyUpdateEntries(model));
231 EXPECT_CALL(caller, SaveCallback(true)); 241 EXPECT_CALL(caller, SaveCallback(true));
232 db_->UpdateEntries( 242 db_->UpdateEntries(
233 entries.Pass(), 243 entries.Pass(), keys_to_remove.Pass(),
234 entries_to_remove.Pass(),
235 base::Bind(&MockDatabaseCaller::SaveCallback, base::Unretained(&caller))); 244 base::Bind(&MockDatabaseCaller::SaveCallback, base::Unretained(&caller)));
236 245
237 base::RunLoop().RunUntilIdle(); 246 base::RunLoop().RunUntilIdle();
238 } 247 }
239 248
240 TEST_F(DomDistillerDatabaseTest, TestDBSaveFailure) { 249 TEST_F(ProtoDatabaseImplTest, TestDBSaveFailure) {
241 base::FilePath path(FILE_PATH_LITERAL("/fake/path")); 250 base::FilePath path(FILE_PATH_LITERAL("/fake/path"));
242 251
243 MockDB* mock_db = new MockDB(); 252 MockDB* mock_db = new MockDB();
244 MockDatabaseCaller caller; 253 MockDatabaseCaller caller;
245 scoped_ptr<EntryVector> entries(new EntryVector()); 254 scoped_ptr<ProtoDatabase<TestProto>::KeyEntryVector> entries(
246 scoped_ptr<EntryVector> entries_to_remove(new EntryVector()); 255 new ProtoDatabase<TestProto>::KeyEntryVector());
256 scoped_ptr<std::vector<std::string>> keys_to_remove(
257 new std::vector<std::string>());
247 258
248 EXPECT_CALL(*mock_db, Init(_)); 259 EXPECT_CALL(*mock_db, Init(_));
249 EXPECT_CALL(caller, InitCallback(_)); 260 EXPECT_CALL(caller, InitCallback(_));
250 db_->InitWithDatabase( 261 db_->InitWithDatabase(
251 scoped_ptr<DomDistillerDatabase::Database>(mock_db), 262 scoped_ptr<ProtoDatabaseImpl<TestProto>::Database>(mock_db),
252 base::FilePath(path), 263 base::FilePath(path),
253 base::Bind(&MockDatabaseCaller::InitCallback, base::Unretained(&caller))); 264 base::Bind(&MockDatabaseCaller::InitCallback, base::Unretained(&caller)));
254 265
255 EXPECT_CALL(*mock_db, Save(_, _)).WillOnce(Return(false)); 266 EXPECT_CALL(*mock_db, Save(_, _)).WillOnce(Return(false));
256 EXPECT_CALL(caller, SaveCallback(false)); 267 EXPECT_CALL(caller, SaveCallback(false));
257 db_->UpdateEntries( 268 db_->UpdateEntries(
258 entries.Pass(), 269 entries.Pass(), keys_to_remove.Pass(),
259 entries_to_remove.Pass(),
260 base::Bind(&MockDatabaseCaller::SaveCallback, base::Unretained(&caller))); 270 base::Bind(&MockDatabaseCaller::SaveCallback, base::Unretained(&caller)));
261 271
262 base::RunLoop().RunUntilIdle(); 272 base::RunLoop().RunUntilIdle();
263 } 273 }
264 274
265 ACTION_P(VerifyRemoveEntries, expected) { 275 // Test that ProtoDatabaseImpl calls Save on the underlying database with the
266 const EntryVector& actual = arg1;
267 ExpectEntryPointersEquals(expected, actual);
268 return true;
269 }
270
271 // Test that DomDistillerDatabase calls Save on the underlying database with the
272 // correct entries to delete and that the caller's SaveCallback is called with 276 // correct entries to delete and that the caller's SaveCallback is called with
273 // the correct success value. 277 // the correct success value.
274 TEST_F(DomDistillerDatabaseTest, TestDBRemoveSuccess) { 278 TEST_F(ProtoDatabaseImplTest, TestDBRemoveSuccess) {
275 base::FilePath path(FILE_PATH_LITERAL("/fake/path")); 279 base::FilePath path(FILE_PATH_LITERAL("/fake/path"));
276 280
277 MockDB* mock_db = new MockDB(); 281 MockDB* mock_db = new MockDB();
278 MockDatabaseCaller caller; 282 MockDatabaseCaller caller;
279 EntryMap model = GetSmallModel(); 283 EntryMap model = GetSmallModel();
280 284
281 EXPECT_CALL(*mock_db, Init(_)); 285 EXPECT_CALL(*mock_db, Init(_));
282 EXPECT_CALL(caller, InitCallback(_)); 286 EXPECT_CALL(caller, InitCallback(_));
283 db_->InitWithDatabase( 287 db_->InitWithDatabase(
284 scoped_ptr<DomDistillerDatabase::Database>(mock_db), 288 scoped_ptr<ProtoDatabaseImpl<TestProto>::Database>(mock_db),
285 base::FilePath(path), 289 base::FilePath(path),
286 base::Bind(&MockDatabaseCaller::InitCallback, base::Unretained(&caller))); 290 base::Bind(&MockDatabaseCaller::InitCallback, base::Unretained(&caller)));
287 291
288 scoped_ptr<EntryVector> entries(new EntryVector()); 292 scoped_ptr<ProtoDatabase<TestProto>::KeyEntryVector> entries(
289 scoped_ptr<EntryVector> entries_to_remove(new EntryVector()); 293 new ProtoDatabase<TestProto>::KeyEntryVector());
294 scoped_ptr<std::vector<std::string>> keys_to_remove(
295 new std::vector<std::string>());
290 for (EntryMap::iterator it = model.begin(); it != model.end(); ++it) { 296 for (EntryMap::iterator it = model.begin(); it != model.end(); ++it) {
291 entries_to_remove->push_back(it->second); 297 keys_to_remove->push_back(it->second.id());
292 } 298 }
293 299
294 EXPECT_CALL(*mock_db, Save(_, _)).WillOnce(VerifyRemoveEntries(model)); 300 std::vector<std::string> keys_copy(*keys_to_remove.get());
301 EXPECT_CALL(*mock_db, Save(_, keys_copy)).WillOnce(Return(true));
295 EXPECT_CALL(caller, SaveCallback(true)); 302 EXPECT_CALL(caller, SaveCallback(true));
296 db_->UpdateEntries( 303 db_->UpdateEntries(
297 entries.Pass(), 304 entries.Pass(), keys_to_remove.Pass(),
298 entries_to_remove.Pass(),
299 base::Bind(&MockDatabaseCaller::SaveCallback, base::Unretained(&caller))); 305 base::Bind(&MockDatabaseCaller::SaveCallback, base::Unretained(&caller)));
300 306
301 base::RunLoop().RunUntilIdle(); 307 base::RunLoop().RunUntilIdle();
302 } 308 }
303 309
304 TEST_F(DomDistillerDatabaseTest, TestDBRemoveFailure) { 310 TEST_F(ProtoDatabaseImplTest, TestDBRemoveFailure) {
305 base::FilePath path(FILE_PATH_LITERAL("/fake/path")); 311 base::FilePath path(FILE_PATH_LITERAL("/fake/path"));
306 312
307 MockDB* mock_db = new MockDB(); 313 MockDB* mock_db = new MockDB();
308 MockDatabaseCaller caller; 314 MockDatabaseCaller caller;
309 scoped_ptr<EntryVector> entries(new EntryVector()); 315 scoped_ptr<ProtoDatabase<TestProto>::KeyEntryVector> entries(
310 scoped_ptr<EntryVector> entries_to_remove(new EntryVector()); 316 new ProtoDatabase<TestProto>::KeyEntryVector());
317 scoped_ptr<std::vector<std::string>> keys_to_remove(
318 new std::vector<std::string>());
311 319
312 EXPECT_CALL(*mock_db, Init(_)); 320 EXPECT_CALL(*mock_db, Init(_));
313 EXPECT_CALL(caller, InitCallback(_)); 321 EXPECT_CALL(caller, InitCallback(_));
314 db_->InitWithDatabase( 322 db_->InitWithDatabase(
315 scoped_ptr<DomDistillerDatabase::Database>(mock_db), 323 scoped_ptr<ProtoDatabaseImpl<TestProto>::Database>(mock_db),
316 base::FilePath(path), 324 base::FilePath(path),
317 base::Bind(&MockDatabaseCaller::InitCallback, base::Unretained(&caller))); 325 base::Bind(&MockDatabaseCaller::InitCallback, base::Unretained(&caller)));
318 326
319 EXPECT_CALL(*mock_db, Save(_, _)).WillOnce(Return(false)); 327 EXPECT_CALL(*mock_db, Save(_, _)).WillOnce(Return(false));
320 EXPECT_CALL(caller, SaveCallback(false)); 328 EXPECT_CALL(caller, SaveCallback(false));
321 db_->UpdateEntries( 329 db_->UpdateEntries(
322 entries.Pass(), 330 entries.Pass(), keys_to_remove.Pass(),
323 entries_to_remove.Pass(),
324 base::Bind(&MockDatabaseCaller::SaveCallback, base::Unretained(&caller))); 331 base::Bind(&MockDatabaseCaller::SaveCallback, base::Unretained(&caller)));
325 332
326 base::RunLoop().RunUntilIdle(); 333 base::RunLoop().RunUntilIdle();
327 } 334 }
328 335
329
330 // This tests that normal usage of the real database does not cause any 336 // This tests that normal usage of the real database does not cause any
331 // threading violations. 337 // threading violations.
332 TEST(DomDistillerDatabaseThreadingTest, TestDBDestruction) { 338 TEST(ProtoDatabaseImplThreadingTest, TestDBDestruction) {
333 base::MessageLoop main_loop; 339 base::MessageLoop main_loop;
334 340
335 ScopedTempDir temp_dir; 341 ScopedTempDir temp_dir;
336 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 342 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
337 343
338 base::Thread db_thread("dbthread"); 344 base::Thread db_thread("dbthread");
339 ASSERT_TRUE(db_thread.Start()); 345 ASSERT_TRUE(db_thread.Start());
340 346
341 scoped_ptr<DomDistillerDatabase> db( 347 scoped_ptr<ProtoDatabaseImpl<TestProto>> db(
342 new DomDistillerDatabase(db_thread.message_loop_proxy())); 348 new ProtoDatabaseImpl<TestProto>(db_thread.message_loop_proxy()));
343 349
344 MockDatabaseCaller caller; 350 MockDatabaseCaller caller;
345 EXPECT_CALL(caller, InitCallback(_)); 351 EXPECT_CALL(caller, InitCallback(_));
346 db->Init( 352 db->Init(temp_dir.path(), base::Bind(&MockDatabaseCaller::InitCallback,
347 temp_dir.path(), 353 base::Unretained(&caller)));
348 base::Bind(&MockDatabaseCaller::InitCallback, base::Unretained(&caller)));
349 354
350 db.reset(); 355 db.reset();
351 356
352 base::RunLoop run_loop; 357 base::RunLoop run_loop;
353 db_thread.message_loop_proxy()->PostTaskAndReply( 358 db_thread.message_loop_proxy()->PostTaskAndReply(
354 FROM_HERE, base::Bind(base::DoNothing), run_loop.QuitClosure()); 359 FROM_HERE, base::Bind(base::DoNothing), run_loop.QuitClosure());
355 run_loop.Run(); 360 run_loop.Run();
356 } 361 }
357 362
358 // Test that the LevelDB properly saves entries and that load returns the saved 363 // Test that the LevelDB properly saves entries and that load returns the saved
359 // entries. If |close_after_save| is true, the database will be closed after 364 // entries. If |close_after_save| is true, the database will be closed after
360 // saving and then re-opened to ensure that the data is properly persisted. 365 // saving and then re-opened to ensure that the data is properly persisted.
361 void TestLevelDBSaveAndLoad(bool close_after_save) { 366 void TestLevelDBSaveAndLoad(bool close_after_save) {
362 ScopedTempDir temp_dir; 367 ScopedTempDir temp_dir;
363 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 368 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
364 369
365 EntryMap model = GetSmallModel(); 370 EntryMap model = GetSmallModel();
366 EntryVector save_entries; 371
367 EntryVector load_entries; 372 ProtoDatabase<TestProto>::KeyEntryVector save_entries;
368 EntryVector remove_entries; 373 std::vector<TestProto> load_entries;
374 std::vector<std::string> remove_keys;
369 375
370 for (EntryMap::iterator it = model.begin(); it != model.end(); ++it) { 376 for (EntryMap::iterator it = model.begin(); it != model.end(); ++it) {
371 save_entries.push_back(it->second); 377 save_entries.push_back(std::make_pair(it->second.id(), it->second));
372 } 378 }
373 379
374 scoped_ptr<DomDistillerDatabase::LevelDB> db( 380 scoped_ptr<ProtoDatabaseImpl<TestProto>::LevelDB> db(
375 new DomDistillerDatabase::LevelDB()); 381 new ProtoDatabaseImpl<TestProto>::LevelDB());
376 EXPECT_TRUE(db->Init(temp_dir.path())); 382 EXPECT_TRUE(db->Init(temp_dir.path()));
377 EXPECT_TRUE(db->Save(save_entries, remove_entries)); 383 EXPECT_TRUE(db->Save(save_entries, remove_keys));
378 384
379 if (close_after_save) { 385 if (close_after_save) {
380 db.reset(new DomDistillerDatabase::LevelDB()); 386 db.reset(new ProtoDatabaseImpl<TestProto>::LevelDB());
381 EXPECT_TRUE(db->Init(temp_dir.path())); 387 EXPECT_TRUE(db->Init(temp_dir.path()));
382 } 388 }
383 389
384 EXPECT_TRUE(db->Load(&load_entries)); 390 EXPECT_TRUE(db->Load(&load_entries));
385 391
386 ExpectEntryPointersEquals(model, load_entries); 392 ExpectEntryPointersEquals(model, load_entries);
387 } 393 }
388 394
389 TEST(DomDistillerDatabaseLevelDBTest, TestDBSaveAndLoad) { 395 TEST(ProtoDatabaseImplLevelDBTest, TestDBSaveAndLoad) {
390 TestLevelDBSaveAndLoad(false); 396 TestLevelDBSaveAndLoad(false);
391 } 397 }
392 398
393 TEST(DomDistillerDatabaseLevelDBTest, TestDBCloseAndReopen) { 399 TEST(ProtoDatabaseImplLevelDBTest, TestDBCloseAndReopen) {
394 TestLevelDBSaveAndLoad(true); 400 TestLevelDBSaveAndLoad(true);
395 } 401 }
396 402
397 } // namespace dom_distiller 403 } // namespace leveldb_proto
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698