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

Side by Side Diff: components/offline_pages/background/request_queue_store_unittest.cc

Issue 2489443002: Move all components/offline_pages/ files into component/offline_pages/core (Closed)
Patch Set: rebase 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
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 "components/offline_pages/background/request_queue_store.h"
6
7 #include <memory>
8
9 #include "base/bind.h"
10 #include "base/files/file_path.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/test/test_simple_task_runner.h"
13 #include "base/threading/thread_task_runner_handle.h"
14 #include "components/offline_pages/background/request_queue.h"
15 #include "components/offline_pages/background/request_queue_in_memory_store.h"
16 #include "components/offline_pages/background/request_queue_store_sql.h"
17 #include "components/offline_pages/background/save_page_request.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 namespace offline_pages {
21
22 using UpdateStatus = RequestQueueStore::UpdateStatus;
23
24 namespace {
25 const int64_t kRequestId = 42;
26 const int64_t kRequestId2 = 44;
27 const int64_t kRequestId3 = 47;
28 const GURL kUrl("http://example.com");
29 const GURL kUrl2("http://another-example.com");
30 const ClientId kClientId("bookmark", "1234");
31 const ClientId kClientId2("async", "5678");
32 const bool kUserRequested = true;
33
34 enum class LastResult {
35 RESULT_NONE,
36 RESULT_FALSE,
37 RESULT_TRUE,
38 };
39
40 } // namespace
41
42 // Class that serves as a base for testing different implementations of the
43 // |RequestQueueStore|. Specific implementations extend the templatized version
44 // of this class and provide appropriate store factory.
45 class RequestQueueStoreTestBase : public testing::Test {
46 public:
47 RequestQueueStoreTestBase();
48
49 // Test overrides.
50 void TearDown() override;
51
52 void PumpLoop();
53 void ClearResults();
54 void InitializeStore(RequestQueueStore* store);
55
56 void InitializeCallback(bool success);
57 // Callback used for get requests.
58 void GetRequestsDone(bool result,
59 std::vector<std::unique_ptr<SavePageRequest>> requests);
60 // Callback used for add/update request.
61 void AddOrUpdateDone(UpdateStatus result);
62 void AddRequestDone(ItemActionStatus status);
63 void UpdateRequestDone(std::unique_ptr<UpdateRequestsResult> result);
64 // Callback used for reset.
65 void ResetDone(bool result);
66
67 LastResult last_result() const { return last_result_; }
68 UpdateStatus last_update_status() const { return last_update_status_; }
69 const std::vector<std::unique_ptr<SavePageRequest>>& last_requests() const {
70 return last_requests_;
71 }
72 ItemActionStatus last_add_status() const { return last_add_status_; }
73
74 UpdateRequestsResult* last_update_result() const {
75 return last_update_result_.get();
76 }
77
78 protected:
79 base::ScopedTempDir temp_directory_;
80
81 private:
82 LastResult last_result_;
83 UpdateStatus last_update_status_;
84 ItemActionStatus last_add_status_;
85 std::unique_ptr<UpdateRequestsResult> last_update_result_;
86 std::vector<std::unique_ptr<SavePageRequest>> last_requests_;
87
88 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
89 base::ThreadTaskRunnerHandle task_runner_handle_;
90 };
91
92 RequestQueueStoreTestBase::RequestQueueStoreTestBase()
93 : last_result_(LastResult::RESULT_NONE),
94 last_update_status_(UpdateStatus::FAILED),
95 last_add_status_(ItemActionStatus::NOT_FOUND),
96 task_runner_(new base::TestSimpleTaskRunner),
97 task_runner_handle_(task_runner_) {
98 EXPECT_TRUE(temp_directory_.CreateUniqueTempDir());
99 }
100
101 void RequestQueueStoreTestBase::TearDown() {
102 // Wait for all the pieces of the store to delete itself properly.
103 PumpLoop();
104 }
105
106 void RequestQueueStoreTestBase::PumpLoop() {
107 task_runner_->RunUntilIdle();
108 }
109
110 void RequestQueueStoreTestBase::ClearResults() {
111 last_result_ = LastResult::RESULT_NONE;
112 last_update_status_ = UpdateStatus::FAILED;
113 last_add_status_ = ItemActionStatus::NOT_FOUND;
114 last_requests_.clear();
115 last_update_result_.reset(nullptr);
116 }
117
118 void RequestQueueStoreTestBase::InitializeStore(RequestQueueStore* store) {
119 store->Initialize(base::Bind(&RequestQueueStoreTestBase::InitializeCallback,
120 base::Unretained(this)));
121 PumpLoop();
122 ASSERT_EQ(LastResult::RESULT_TRUE, this->last_result());
123 ClearResults();
124 }
125
126 void RequestQueueStoreTestBase::InitializeCallback(bool success) {
127 last_result_ = success ? LastResult::RESULT_TRUE : LastResult::RESULT_FALSE;
128 }
129
130 void RequestQueueStoreTestBase::GetRequestsDone(
131 bool result,
132 std::vector<std::unique_ptr<SavePageRequest>> requests) {
133 last_result_ = result ? LastResult::RESULT_TRUE : LastResult::RESULT_FALSE;
134 last_requests_ = std::move(requests);
135 }
136
137 void RequestQueueStoreTestBase::AddOrUpdateDone(UpdateStatus status) {
138 last_update_status_ = status;
139 }
140
141 void RequestQueueStoreTestBase::AddRequestDone(ItemActionStatus status) {
142 last_add_status_ = status;
143 }
144
145 void RequestQueueStoreTestBase::UpdateRequestDone(
146 std::unique_ptr<UpdateRequestsResult> result) {
147 last_update_result_ = std::move(result);
148 }
149
150 void RequestQueueStoreTestBase::ResetDone(bool result) {
151 last_result_ = result ? LastResult::RESULT_TRUE : LastResult::RESULT_FALSE;
152 }
153
154 // Defines interface for the store factory.
155 class RequestQueueStoreFactory {
156 public:
157 virtual RequestQueueStore* BuildStore(const base::FilePath& path) = 0;
158 };
159
160 // Implements a store factory for in memory store.
161 class RequestQueueInMemoryStoreFactory : public RequestQueueStoreFactory {
162 public:
163 RequestQueueStore* BuildStore(const base::FilePath& path) override {
164 RequestQueueStore* store = new RequestQueueInMemoryStore();
165 return store;
166 }
167 };
168
169 // Implements a store factory for SQLite based implementation of the store.
170 class RequestQueueStoreSQLFactory : public RequestQueueStoreFactory {
171 public:
172 RequestQueueStore* BuildStore(const base::FilePath& path) override {
173 RequestQueueStore* store =
174 new RequestQueueStoreSQL(base::ThreadTaskRunnerHandle::Get(), path);
175 return store;
176 }
177 };
178
179 // Defines a store test fixture templatized by the store factory.
180 template <typename T>
181 class RequestQueueStoreTest : public RequestQueueStoreTestBase {
182 public:
183 std::unique_ptr<RequestQueueStore> BuildStore();
184
185 protected:
186 T factory_;
187 };
188
189 template <typename T>
190 std::unique_ptr<RequestQueueStore> RequestQueueStoreTest<T>::BuildStore() {
191 std::unique_ptr<RequestQueueStore> store(
192 factory_.BuildStore(temp_directory_.GetPath()));
193 return store;
194 }
195
196 // |StoreTypes| lists all factories, based on which the tests will be created.
197 typedef testing::Types<RequestQueueInMemoryStoreFactory,
198 RequestQueueStoreSQLFactory>
199 StoreTypes;
200
201 // This portion causes test fixtures to be defined.
202 // Notice that in the store we are using "this->" to refer to the methods
203 // defined on the |RequestQuieueStoreBaseTest| class. That's by design.
204 TYPED_TEST_CASE(RequestQueueStoreTest, StoreTypes);
205
206 TYPED_TEST(RequestQueueStoreTest, GetRequestsEmpty) {
207 std::unique_ptr<RequestQueueStore> store(this->BuildStore());
208 this->InitializeStore(store.get());
209
210 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone,
211 base::Unretained(this)));
212 ASSERT_EQ(LastResult::RESULT_NONE, this->last_result());
213 this->PumpLoop();
214 ASSERT_EQ(LastResult::RESULT_TRUE, this->last_result());
215 ASSERT_TRUE(this->last_requests().empty());
216 }
217
218 TYPED_TEST(RequestQueueStoreTest, GetRequestsByIds) {
219 std::unique_ptr<RequestQueueStore> store(this->BuildStore());
220 this->InitializeStore(store.get());
221
222 base::Time creation_time = base::Time::Now();
223 SavePageRequest request1(kRequestId, kUrl, kClientId, creation_time,
224 kUserRequested);
225 store->AddRequest(request1,
226 base::Bind(&RequestQueueStoreTestBase::AddRequestDone,
227 base::Unretained(this)));
228 SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time,
229 kUserRequested);
230 store->AddRequest(request2,
231 base::Bind(&RequestQueueStoreTestBase::AddRequestDone,
232 base::Unretained(this)));
233 this->PumpLoop();
234 this->ClearResults();
235
236 std::vector<int64_t> request_ids{kRequestId, kRequestId2};
237 store->GetRequestsByIds(
238 request_ids, base::Bind(&RequestQueueStoreTestBase::UpdateRequestDone,
239 base::Unretained(this)));
240
241 ASSERT_FALSE(this->last_update_result());
242 this->PumpLoop();
243 ASSERT_TRUE(this->last_update_result());
244 EXPECT_EQ(2UL, this->last_update_result()->item_statuses.size());
245 EXPECT_EQ(kRequestId, this->last_update_result()->item_statuses[0].first);
246 EXPECT_EQ(ItemActionStatus::SUCCESS,
247 this->last_update_result()->item_statuses[0].second);
248 EXPECT_EQ(kRequestId2, this->last_update_result()->item_statuses[1].first);
249 EXPECT_EQ(ItemActionStatus::SUCCESS,
250 this->last_update_result()->item_statuses[1].second);
251 EXPECT_EQ(2UL, this->last_update_result()->updated_items.size());
252 EXPECT_EQ(request1, this->last_update_result()->updated_items.at(0));
253 EXPECT_EQ(request2, this->last_update_result()->updated_items.at(1));
254 this->ClearResults();
255
256 request_ids.clear();
257 request_ids.push_back(kRequestId);
258 request_ids.push_back(kRequestId3);
259 request_ids.push_back(kRequestId);
260
261 store->GetRequestsByIds(
262 request_ids, base::Bind(&RequestQueueStoreTestBase::UpdateRequestDone,
263 base::Unretained(this)));
264
265 ASSERT_FALSE(this->last_update_result());
266 this->PumpLoop();
267 ASSERT_TRUE(this->last_update_result());
268 EXPECT_EQ(2UL, this->last_update_result()->item_statuses.size());
269 EXPECT_EQ(kRequestId, this->last_update_result()->item_statuses[0].first);
270 EXPECT_EQ(ItemActionStatus::SUCCESS,
271 this->last_update_result()->item_statuses[0].second);
272 EXPECT_EQ(kRequestId3, this->last_update_result()->item_statuses[1].first);
273 EXPECT_EQ(ItemActionStatus::NOT_FOUND,
274 this->last_update_result()->item_statuses[1].second);
275 EXPECT_EQ(1UL, this->last_update_result()->updated_items.size());
276 EXPECT_EQ(request1, this->last_update_result()->updated_items.at(0));
277 }
278
279 TYPED_TEST(RequestQueueStoreTest, AddRequest) {
280 std::unique_ptr<RequestQueueStore> store(this->BuildStore());
281 this->InitializeStore(store.get());
282
283 base::Time creation_time = base::Time::Now();
284 SavePageRequest request(
285 kRequestId, kUrl, kClientId, creation_time, kUserRequested);
286
287 store->AddRequest(request,
288 base::Bind(&RequestQueueStoreTestBase::AddRequestDone,
289 base::Unretained(this)));
290 ASSERT_EQ(ItemActionStatus::NOT_FOUND, this->last_add_status());
291 this->PumpLoop();
292 ASSERT_EQ(ItemActionStatus::SUCCESS, this->last_add_status());
293
294 // Verifying get reqeust results after a request was added.
295 this->ClearResults();
296 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone,
297 base::Unretained(this)));
298 ASSERT_EQ(LastResult::RESULT_NONE, this->last_result());
299 this->PumpLoop();
300 ASSERT_EQ(LastResult::RESULT_TRUE, this->last_result());
301 ASSERT_EQ(1ul, this->last_requests().size());
302 ASSERT_EQ(request, *(this->last_requests()[0].get()));
303
304 // Verify it is not possible to add the same request twice.
305 this->ClearResults();
306 store->AddRequest(request,
307 base::Bind(&RequestQueueStoreTestBase::AddRequestDone,
308 base::Unretained(this)));
309 ASSERT_EQ(ItemActionStatus::NOT_FOUND, this->last_add_status());
310 this->PumpLoop();
311 ASSERT_EQ(ItemActionStatus::ALREADY_EXISTS, this->last_add_status());
312
313 // Check that there is still only one item in the store.
314 this->ClearResults();
315 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone,
316 base::Unretained(this)));
317 ASSERT_EQ(LastResult::RESULT_NONE, this->last_result());
318 this->PumpLoop();
319 ASSERT_EQ(LastResult::RESULT_TRUE, this->last_result());
320 ASSERT_EQ(1ul, this->last_requests().size());
321 }
322
323 TYPED_TEST(RequestQueueStoreTest, UpdateRequest) {
324 std::unique_ptr<RequestQueueStore> store(this->BuildStore());
325 this->InitializeStore(store.get());
326
327 base::Time creation_time = base::Time::Now();
328 SavePageRequest original_request(
329 kRequestId, kUrl, kClientId, creation_time, kUserRequested);
330 store->AddRequest(original_request,
331 base::Bind(&RequestQueueStoreTestBase::AddRequestDone,
332 base::Unretained(this)));
333 this->PumpLoop();
334 this->ClearResults();
335
336 base::Time new_creation_time =
337 creation_time + base::TimeDelta::FromMinutes(1);
338 base::Time activation_time = creation_time + base::TimeDelta::FromHours(6);
339 // Try updating an existing request.
340 SavePageRequest updated_request(kRequestId, kUrl, kClientId,
341 new_creation_time, activation_time,
342 kUserRequested);
343 // Try to update a non-existing request.
344 SavePageRequest updated_request2(kRequestId2, kUrl, kClientId,
345 new_creation_time, activation_time,
346 kUserRequested);
347 std::vector<SavePageRequest> requests_to_update{updated_request,
348 updated_request2};
349 store->UpdateRequests(
350 requests_to_update,
351 base::Bind(&RequestQueueStoreTestBase::UpdateRequestDone,
352 base::Unretained(this)));
353 ASSERT_FALSE(this->last_update_result());
354 this->PumpLoop();
355 ASSERT_TRUE(this->last_update_result());
356 EXPECT_EQ(2UL, this->last_update_result()->item_statuses.size());
357 EXPECT_EQ(kRequestId, this->last_update_result()->item_statuses[0].first);
358 EXPECT_EQ(ItemActionStatus::SUCCESS,
359 this->last_update_result()->item_statuses[0].second);
360 EXPECT_EQ(kRequestId2, this->last_update_result()->item_statuses[1].first);
361 EXPECT_EQ(ItemActionStatus::NOT_FOUND,
362 this->last_update_result()->item_statuses[1].second);
363 EXPECT_EQ(1UL, this->last_update_result()->updated_items.size());
364 EXPECT_EQ(updated_request,
365 *(this->last_update_result()->updated_items.begin()));
366
367 // Verifying get reqeust results after a request was updated.
368 this->ClearResults();
369 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone,
370 base::Unretained(this)));
371 ASSERT_EQ(LastResult::RESULT_NONE, this->last_result());
372 this->PumpLoop();
373 ASSERT_EQ(LastResult::RESULT_TRUE, this->last_result());
374 ASSERT_EQ(1ul, this->last_requests().size());
375 ASSERT_EQ(updated_request, *(this->last_requests()[0].get()));
376 }
377
378 TYPED_TEST(RequestQueueStoreTest, RemoveRequests) {
379 std::unique_ptr<RequestQueueStore> store(this->BuildStore());
380 this->InitializeStore(store.get());
381
382 base::Time creation_time = base::Time::Now();
383 SavePageRequest request1(kRequestId, kUrl, kClientId, creation_time,
384 kUserRequested);
385 store->AddRequest(request1,
386 base::Bind(&RequestQueueStoreTestBase::AddRequestDone,
387 base::Unretained(this)));
388 SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time,
389 kUserRequested);
390 store->AddRequest(request2,
391 base::Bind(&RequestQueueStoreTestBase::AddRequestDone,
392 base::Unretained(this)));
393 this->PumpLoop();
394 this->ClearResults();
395
396 std::vector<int64_t> request_ids{kRequestId, kRequestId2};
397 store->RemoveRequests(
398 request_ids, base::Bind(&RequestQueueStoreTestBase::UpdateRequestDone,
399 base::Unretained(this)));
400
401 ASSERT_FALSE(this->last_update_result());
402 this->PumpLoop();
403 ASSERT_TRUE(this->last_update_result());
404 EXPECT_EQ(2UL, this->last_update_result()->item_statuses.size());
405 EXPECT_EQ(kRequestId, this->last_update_result()->item_statuses[0].first);
406 EXPECT_EQ(ItemActionStatus::SUCCESS,
407 this->last_update_result()->item_statuses[0].second);
408 EXPECT_EQ(kRequestId2, this->last_update_result()->item_statuses[1].first);
409 EXPECT_EQ(ItemActionStatus::SUCCESS,
410 this->last_update_result()->item_statuses[1].second);
411 EXPECT_EQ(2UL, this->last_update_result()->updated_items.size());
412 EXPECT_EQ(request1, this->last_update_result()->updated_items.at(0));
413 EXPECT_EQ(request2, this->last_update_result()->updated_items.at(1));
414 this->ClearResults();
415
416 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone,
417 base::Unretained(this)));
418 this->PumpLoop();
419 ASSERT_EQ(LastResult::RESULT_TRUE, this->last_result());
420 ASSERT_TRUE(this->last_requests().empty());
421 this->ClearResults();
422
423 // Try to remove a request that is not in the queue.
424 store->RemoveRequests(
425 request_ids, base::Bind(&RequestQueueStoreTestBase::UpdateRequestDone,
426 base::Unretained(this)));
427 ASSERT_FALSE(this->last_update_result());
428 this->PumpLoop();
429 ASSERT_TRUE(this->last_update_result());
430 // When requests are missing, we expect the results to say so, but since they
431 // are missing, no requests should have been returned.
432 EXPECT_EQ(2UL, this->last_update_result()->item_statuses.size());
433 EXPECT_EQ(kRequestId, this->last_update_result()->item_statuses[0].first);
434 EXPECT_EQ(ItemActionStatus::NOT_FOUND,
435 this->last_update_result()->item_statuses[0].second);
436 EXPECT_EQ(kRequestId2, this->last_update_result()->item_statuses[1].first);
437 EXPECT_EQ(ItemActionStatus::NOT_FOUND,
438 this->last_update_result()->item_statuses[1].second);
439 EXPECT_EQ(0UL, this->last_update_result()->updated_items.size());
440 }
441
442 TYPED_TEST(RequestQueueStoreTest, ResetStore) {
443 std::unique_ptr<RequestQueueStore> store(this->BuildStore());
444 this->InitializeStore(store.get());
445
446 base::Time creation_time = base::Time::Now();
447 SavePageRequest original_request(
448 kRequestId, kUrl, kClientId, creation_time, kUserRequested);
449 store->AddRequest(original_request,
450 base::Bind(&RequestQueueStoreTestBase::AddRequestDone,
451 base::Unretained(this)));
452 this->PumpLoop();
453 this->ClearResults();
454
455 store->Reset(base::Bind(&RequestQueueStoreTestBase::ResetDone,
456 base::Unretained(this)));
457 ASSERT_EQ(LastResult::RESULT_NONE, this->last_result());
458 this->PumpLoop();
459 ASSERT_EQ(LastResult::RESULT_TRUE, this->last_result());
460 this->ClearResults();
461
462 this->InitializeStore(store.get());
463 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone,
464 base::Unretained(this)));
465 this->PumpLoop();
466 ASSERT_EQ(LastResult::RESULT_TRUE, this->last_result());
467 ASSERT_TRUE(this->last_requests().empty());
468 }
469
470 class RequestQueueStoreSQLTest
471 : public RequestQueueStoreTest<RequestQueueStoreSQLFactory> {};
472
473 // Makes sure that persistent DB is actually persisting requests across store
474 // restarts.
475 TEST_F(RequestQueueStoreSQLTest, SaveCloseReopenRead) {
476 std::unique_ptr<RequestQueueStore> store(BuildStore());
477 this->InitializeStore(store.get());
478
479 base::Time creation_time = base::Time::Now();
480 SavePageRequest original_request(
481 kRequestId, kUrl, kClientId, creation_time, kUserRequested);
482 store->AddRequest(original_request,
483 base::Bind(&RequestQueueStoreTestBase::AddRequestDone,
484 base::Unretained(this)));
485 PumpLoop();
486 ClearResults();
487
488 // Resets the store, using the same temp directory. The contents should be
489 // intact. First reset is done separately to release DB lock.
490 store.reset();
491 store = BuildStore();
492 this->InitializeStore(store.get());
493
494 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone,
495 base::Unretained(this)));
496 ASSERT_EQ(LastResult::RESULT_NONE, this->last_result());
497 this->PumpLoop();
498 ASSERT_EQ(LastResult::RESULT_TRUE, this->last_result());
499 ASSERT_EQ(1ul, this->last_requests().size());
500 ASSERT_TRUE(original_request == *(this->last_requests().at(0).get()));
501 }
502
503 } // offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698