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

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

Powered by Google App Engine
This is Rietveld 408576698