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

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

Issue 2053163002: [Offline pages] Adding persistent request queue based on SQLite (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Updating documentation and moving code around per Doug's review Created 4 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
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_in_memory_store.h"
15 #include "components/offline_pages/background/request_queue_store_sql.h"
16 #include "components/offline_pages/background/save_page_request.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace offline_pages {
20
21 using UpdateStatus = RequestQueueStore::UpdateStatus;
22
23 namespace {
24 const int64_t kRequestId = 42;
25 const GURL kUrl("http://example.com");
26 const ClientId kClientId("bookmark", "1234");
27
28 enum class LastResult {
29 kNone,
30 kFalse,
31 kTrue,
32 };
33
34 bool operator==(const SavePageRequest& lhs, const SavePageRequest& rhs) {
35 return lhs.request_id() == rhs.request_id() && lhs.url() == rhs.url() &&
36 lhs.client_id() == rhs.client_id() &&
37 lhs.creation_time() == rhs.creation_time() &&
38 lhs.activation_time() == rhs.activation_time() &&
39 lhs.attempt_count() == rhs.attempt_count() &&
40 lhs.last_attempt_time() == rhs.last_attempt_time();
41 }
42
43 } // namespace
44
45 // Class that serves as a base for testing different implementations of the
46 // |RequestQueueStore|. Specific implementations extend the templatized version
47 // of this class and provide appropriate store factory.
48 class RequestQueueStoreTestBase : public testing::Test {
49 public:
50 RequestQueueStoreTestBase();
51
52 // Test overrides.
53 void TearDown() override;
54
55 void PumpLoop();
56 void ClearResults();
57
58 // Callback used for get requests.
59 void GetRequestsDone(bool result,
60 const std::vector<SavePageRequest>& requests);
61 // Callback used for add/update request.
62 void AddOrUpdateDone(UpdateStatus result);
63 // Callback used for remove requests.
64 void RemoveDone(bool result, int count);
65 // Callback used for reset.
66 void ResetDone(bool result);
67
68 LastResult last_result() const { return last_result_; }
69 UpdateStatus last_update_status() const { return last_update_status_; }
70 int last_remove_count() const { return last_remove_count_; }
71 const std::vector<SavePageRequest>& last_requests() const {
72 return last_requests_;
73 }
74
75 protected:
76 base::ScopedTempDir temp_directory_;
77
78 private:
79 LastResult last_result_;
80 UpdateStatus last_update_status_;
81 int last_remove_count_;
82 std::vector<SavePageRequest> last_requests_;
83
84 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
85 base::ThreadTaskRunnerHandle task_runner_handle_;
86 };
87
88 RequestQueueStoreTestBase::RequestQueueStoreTestBase()
89 : last_result_(LastResult::kNone),
90 last_update_status_(UpdateStatus::FAILED),
91 last_remove_count_(0),
92 task_runner_(new base::TestSimpleTaskRunner),
93 task_runner_handle_(task_runner_) {
94 EXPECT_TRUE(temp_directory_.CreateUniqueTempDir());
95 }
96
97 void RequestQueueStoreTestBase::TearDown() {
98 // Wait for all the pieces of the store to delete itself properly.
99 PumpLoop();
100 }
101
102 void RequestQueueStoreTestBase::PumpLoop() {
103 task_runner_->RunUntilIdle();
104 }
105
106 void RequestQueueStoreTestBase::ClearResults() {
107 last_result_ = LastResult::kNone;
108 last_update_status_ = UpdateStatus::FAILED;
109 last_remove_count_ = 0;
110 last_requests_.clear();
111 }
112
113 void RequestQueueStoreTestBase::GetRequestsDone(
114 bool result,
115 const std::vector<SavePageRequest>& requests) {
116 last_result_ = result ? LastResult::kTrue : LastResult::kFalse;
117 last_requests_ = requests;
118 }
119
120 void RequestQueueStoreTestBase::AddOrUpdateDone(UpdateStatus status) {
121 last_update_status_ = status;
122 }
123
124 void RequestQueueStoreTestBase::RemoveDone(bool result, int count) {
125 last_result_ = result ? LastResult::kTrue : LastResult::kFalse;
126 last_remove_count_ = count;
127 }
128
129 void RequestQueueStoreTestBase::ResetDone(bool result) {
130 last_result_ = result ? LastResult::kTrue : LastResult::kFalse;
131 }
132
133 // Defines interface for the store factory.
134 class RequestQueueStoreFactory {
135 public:
136 virtual RequestQueueStore* BuildStore(const base::FilePath& path) = 0;
137 };
138
139 // Implements a store factory for in memory store.
140 class RequestQueueInMemoryStoreFactory : public RequestQueueStoreFactory {
141 public:
142 RequestQueueStore* BuildStore(const base::FilePath& path) override {
143 RequestQueueStore* store = new RequestQueueInMemoryStore();
144 return store;
145 }
146 };
147
148 // Implements a store factory for SQLite based implementation of the store.
149 class RequestQueueStoreSQLFactory : public RequestQueueStoreFactory {
150 public:
151 RequestQueueStore* BuildStore(const base::FilePath& path) override {
152 RequestQueueStore* store =
153 new RequestQueueStoreSQL(base::ThreadTaskRunnerHandle::Get(), path);
154 return store;
155 }
156 };
157
158 // Defines a store test fixture templatized by the store factory.
159 template <typename T>
160 class RequestQueueStoreTest : public RequestQueueStoreTestBase {
161 public:
162 std::unique_ptr<RequestQueueStore> BuildStore();
163
164 protected:
165 T factory_;
166 };
167
168 template <typename T>
169 std::unique_ptr<RequestQueueStore> RequestQueueStoreTest<T>::BuildStore() {
170 std::unique_ptr<RequestQueueStore> store(
171 factory_.BuildStore(temp_directory_.path()));
172 return store;
173 }
174
175 // |StoreTypes| lists all factories, based on which the tests will be created.
176 typedef testing::Types<RequestQueueInMemoryStoreFactory,
177 RequestQueueStoreSQLFactory>
178 StoreTypes;
179
180 // This portion causes test fixtures to be defined.
181 // Notice that in the store we are using "this->" to refer to the methods
182 // defined on the |RequestQuieueStoreBaseTest| class. That's by design.
183 TYPED_TEST_CASE(RequestQueueStoreTest, StoreTypes);
Pete Williamson 2016/06/15 23:37:05 Nifty! I like seeing the code only once for both
fgorski 2016/06/16 16:41:08 Acknowledged.
184
185 TYPED_TEST(RequestQueueStoreTest, GetRequestsEmpty) {
186 std::unique_ptr<RequestQueueStore> store(this->BuildStore());
187 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone,
188 base::Unretained(this)));
189 ASSERT_EQ(LastResult::kNone, this->last_result());
190 this->PumpLoop();
191 ASSERT_EQ(LastResult::kTrue, this->last_result());
192 ASSERT_TRUE(this->last_requests().empty());
193 }
194
195 TYPED_TEST(RequestQueueStoreTest, AddRequest) {
196 std::unique_ptr<RequestQueueStore> store(this->BuildStore());
197 base::Time creation_time = base::Time::Now();
198 SavePageRequest request(kRequestId, kUrl, kClientId, creation_time);
199
200 store->AddOrUpdateRequest(
201 request, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone,
202 base::Unretained(this)));
203 ASSERT_EQ(UpdateStatus::FAILED, this->last_update_status());
Pete Williamson 2016/06/15 23:37:05 Nit - I'm not sure this assert (and others like it
fgorski 2016/06/16 16:41:08 Because we use the UpdateStatus enum verbatim, we
204 this->PumpLoop();
205 ASSERT_EQ(UpdateStatus::ADDED, this->last_update_status());
206
207 // Verifying get reqeust results after a request was added.
208 this->ClearResults();
209 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone,
210 base::Unretained(this)));
211 ASSERT_EQ(LastResult::kNone, this->last_result());
212 this->PumpLoop();
213 ASSERT_EQ(LastResult::kTrue, this->last_result());
214 ASSERT_EQ(1ul, this->last_requests().size());
215 ASSERT_TRUE(request == this->last_requests()[0]);
216 }
217
218 TYPED_TEST(RequestQueueStoreTest, UpdateRequest) {
219 std::unique_ptr<RequestQueueStore> store(this->BuildStore());
220 base::Time creation_time = base::Time::Now();
221 SavePageRequest original_request(kRequestId, kUrl, kClientId, creation_time);
222 store->AddOrUpdateRequest(
223 original_request, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone,
224 base::Unretained(this)));
225 this->PumpLoop();
226 this->ClearResults();
227
228 base::Time new_creation_time =
229 creation_time + base::TimeDelta::FromMinutes(1);
230 base::Time activation_time = creation_time + base::TimeDelta::FromHours(6);
231 SavePageRequest updated_request(kRequestId, kUrl, kClientId,
232 new_creation_time, activation_time);
233 store->AddOrUpdateRequest(
234 updated_request, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone,
235 base::Unretained(this)));
236 ASSERT_EQ(UpdateStatus::FAILED, this->last_update_status());
237 this->PumpLoop();
238 ASSERT_EQ(UpdateStatus::UPDATED, this->last_update_status());
239
240 // Verifying get reqeust results after a request was updated.
241 this->ClearResults();
242 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone,
243 base::Unretained(this)));
244 ASSERT_EQ(LastResult::kNone, this->last_result());
245 this->PumpLoop();
246 ASSERT_EQ(LastResult::kTrue, this->last_result());
247 ASSERT_EQ(1ul, this->last_requests().size());
248 ASSERT_TRUE(updated_request == this->last_requests()[0]);
249 }
250
251 TYPED_TEST(RequestQueueStoreTest, RemoveRequest) {
252 std::unique_ptr<RequestQueueStore> store(this->BuildStore());
253 base::Time creation_time = base::Time::Now();
254 SavePageRequest original_request(kRequestId, kUrl, kClientId, creation_time);
255 store->AddOrUpdateRequest(
256 original_request, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone,
257 base::Unretained(this)));
258 this->PumpLoop();
259 this->ClearResults();
260
261 std::vector<int64_t> request_ids{kRequestId};
262 store->RemoveRequests(request_ids,
263 base::Bind(&RequestQueueStoreTestBase::RemoveDone,
264 base::Unretained(this)));
265 ASSERT_EQ(LastResult::kNone, this->last_result());
266 ASSERT_EQ(0, this->last_remove_count());
267 this->PumpLoop();
268 ASSERT_EQ(LastResult::kTrue, this->last_result());
269 ASSERT_EQ(1, this->last_remove_count());
270 ASSERT_EQ(0ul, this->last_requests().size());
271 this->ClearResults();
272
Pete Williamson 2016/06/15 23:37:05 We could also do a Get and make sure the request i
fgorski 2016/06/16 16:41:08 Good point. Done
273 // Removing a request that is missing fails.
274 store->RemoveRequests(request_ids,
275 base::Bind(&RequestQueueStoreTestBase::RemoveDone,
276 base::Unretained(this)));
277 ASSERT_EQ(LastResult::kNone, this->last_result());
278 ASSERT_EQ(0, this->last_remove_count());
279 this->PumpLoop();
280 ASSERT_EQ(LastResult::kTrue, this->last_result());
281 ASSERT_EQ(0, this->last_remove_count());
282 }
283
284 TYPED_TEST(RequestQueueStoreTest, ResetStore) {
285 std::unique_ptr<RequestQueueStore> store(this->BuildStore());
286 base::Time creation_time = base::Time::Now();
287 SavePageRequest original_request(kRequestId, kUrl, kClientId, creation_time);
288 store->AddOrUpdateRequest(
289 original_request, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone,
290 base::Unretained(this)));
291 this->PumpLoop();
292 this->ClearResults();
293
294 store->Reset(base::Bind(&RequestQueueStoreTestBase::ResetDone,
295 base::Unretained(this)));
296 ASSERT_EQ(LastResult::kNone, this->last_result());
297 this->PumpLoop();
298 ASSERT_EQ(LastResult::kTrue, this->last_result());
299 ASSERT_EQ(0ul, this->last_requests().size());
Pete Williamson 2016/06/15 23:37:05 Should we do a get here to verify that the store a
fgorski 2016/06/16 16:41:08 Done. I actually update the reset/recovery functio
300 }
301
302 } // offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698