| OLD | NEW |
| (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 RequestQueueStoreFactory { |
| 46 public: |
| 47 virtual RequestQueueStore* BuildStore(const base::FilePath& path) = 0; |
| 48 }; |
| 49 |
| 50 class RequestQueueInMemoryStoreFactory : public RequestQueueStoreFactory { |
| 51 public: |
| 52 RequestQueueStore* BuildStore(const base::FilePath& path) override { |
| 53 RequestQueueStore* store = new RequestQueueInMemoryStore(); |
| 54 return store; |
| 55 } |
| 56 }; |
| 57 |
| 58 class RequestQueueStoreSQLFactory : public RequestQueueStoreFactory { |
| 59 public: |
| 60 RequestQueueStore* BuildStore(const base::FilePath& path) override { |
| 61 RequestQueueStore* store = |
| 62 new RequestQueueStoreSQL(base::ThreadTaskRunnerHandle::Get(), path); |
| 63 return store; |
| 64 } |
| 65 }; |
| 66 |
| 67 class RequestQueueStoreTestBase : public testing::Test { |
| 68 public: |
| 69 RequestQueueStoreTestBase(); |
| 70 |
| 71 // Test overrides. |
| 72 void TearDown() override; |
| 73 |
| 74 void PumpLoop(); |
| 75 void ClearResults(); |
| 76 |
| 77 // Callback used for get requests. |
| 78 void GetRequestsDone(bool result, |
| 79 const std::vector<SavePageRequest>& requests); |
| 80 // Callback used for add/update request. |
| 81 void AddOrUpdateDone(UpdateStatus result); |
| 82 // Callback used for remove requests. |
| 83 void RemoveDone(bool result, int count); |
| 84 // Callback used for reset. |
| 85 void ResetDone(bool result); |
| 86 |
| 87 LastResult last_result() const { return last_result_; } |
| 88 UpdateStatus last_update_status() const { return last_update_status_; } |
| 89 int last_remove_count() const { return last_remove_count_; } |
| 90 const std::vector<SavePageRequest>& last_requests() const { |
| 91 return last_requests_; |
| 92 } |
| 93 |
| 94 protected: |
| 95 base::ScopedTempDir temp_directory_; |
| 96 |
| 97 private: |
| 98 LastResult last_result_; |
| 99 UpdateStatus last_update_status_; |
| 100 int last_remove_count_; |
| 101 std::vector<SavePageRequest> last_requests_; |
| 102 |
| 103 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
| 104 base::ThreadTaskRunnerHandle task_runner_handle_; |
| 105 }; |
| 106 |
| 107 RequestQueueStoreTestBase::RequestQueueStoreTestBase() |
| 108 : last_result_(LastResult::kNone), |
| 109 last_update_status_(UpdateStatus::FAILED), |
| 110 last_remove_count_(0), |
| 111 task_runner_(new base::TestSimpleTaskRunner), |
| 112 task_runner_handle_(task_runner_) { |
| 113 EXPECT_TRUE(temp_directory_.CreateUniqueTempDir()); |
| 114 } |
| 115 |
| 116 void RequestQueueStoreTestBase::TearDown() { |
| 117 // Wait for all the pieces of the store to delete itself properly. |
| 118 PumpLoop(); |
| 119 } |
| 120 |
| 121 void RequestQueueStoreTestBase::PumpLoop() { |
| 122 task_runner_->RunUntilIdle(); |
| 123 } |
| 124 |
| 125 void RequestQueueStoreTestBase::ClearResults() { |
| 126 last_result_ = LastResult::kNone; |
| 127 last_update_status_ = UpdateStatus::FAILED; |
| 128 last_remove_count_ = 0; |
| 129 last_requests_.clear(); |
| 130 } |
| 131 |
| 132 void RequestQueueStoreTestBase::GetRequestsDone( |
| 133 bool result, |
| 134 const std::vector<SavePageRequest>& requests) { |
| 135 last_result_ = result ? LastResult::kTrue : LastResult::kFalse; |
| 136 last_requests_ = requests; |
| 137 } |
| 138 |
| 139 void RequestQueueStoreTestBase::AddOrUpdateDone(UpdateStatus status) { |
| 140 last_update_status_ = status; |
| 141 } |
| 142 |
| 143 void RequestQueueStoreTestBase::RemoveDone(bool result, int count) { |
| 144 last_result_ = result ? LastResult::kTrue : LastResult::kFalse; |
| 145 last_remove_count_ = count; |
| 146 } |
| 147 |
| 148 void RequestQueueStoreTestBase::ResetDone(bool result) { |
| 149 last_result_ = result ? LastResult::kTrue : LastResult::kFalse; |
| 150 } |
| 151 |
| 152 template <typename T> |
| 153 class RequestQueueStoreTest : public RequestQueueStoreTestBase { |
| 154 public: |
| 155 std::unique_ptr<RequestQueueStore> BuildStore(); |
| 156 |
| 157 protected: |
| 158 T factory_; |
| 159 }; |
| 160 |
| 161 template <typename T> |
| 162 std::unique_ptr<RequestQueueStore> RequestQueueStoreTest<T>::BuildStore() { |
| 163 std::unique_ptr<RequestQueueStore> store( |
| 164 factory_.BuildStore(temp_directory_.path())); |
| 165 return store; |
| 166 } |
| 167 |
| 168 typedef testing::Types<RequestQueueInMemoryStoreFactory, |
| 169 RequestQueueStoreSQLFactory> |
| 170 StoreTypes; |
| 171 TYPED_TEST_CASE(RequestQueueStoreTest, StoreTypes); |
| 172 |
| 173 TYPED_TEST(RequestQueueStoreTest, GetRequestsEmpty) { |
| 174 std::unique_ptr<RequestQueueStore> store(this->BuildStore()); |
| 175 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, |
| 176 base::Unretained(this))); |
| 177 ASSERT_EQ(LastResult::kNone, this->last_result()); |
| 178 this->PumpLoop(); |
| 179 ASSERT_EQ(LastResult::kTrue, this->last_result()); |
| 180 ASSERT_TRUE(this->last_requests().empty()); |
| 181 } |
| 182 |
| 183 TYPED_TEST(RequestQueueStoreTest, AddRequest) { |
| 184 std::unique_ptr<RequestQueueStore> store(this->BuildStore()); |
| 185 base::Time creation_time = base::Time::Now(); |
| 186 SavePageRequest request(kRequestId, kUrl, kClientId, creation_time); |
| 187 |
| 188 store->AddOrUpdateRequest( |
| 189 request, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, |
| 190 base::Unretained(this))); |
| 191 ASSERT_EQ(UpdateStatus::FAILED, this->last_update_status()); |
| 192 this->PumpLoop(); |
| 193 ASSERT_EQ(UpdateStatus::ADDED, this->last_update_status()); |
| 194 |
| 195 // Verifying get reqeust results after a request was added. |
| 196 this->ClearResults(); |
| 197 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, |
| 198 base::Unretained(this))); |
| 199 ASSERT_EQ(LastResult::kNone, this->last_result()); |
| 200 this->PumpLoop(); |
| 201 ASSERT_EQ(LastResult::kTrue, this->last_result()); |
| 202 ASSERT_EQ(1ul, this->last_requests().size()); |
| 203 ASSERT_TRUE(request == this->last_requests()[0]); |
| 204 } |
| 205 |
| 206 TYPED_TEST(RequestQueueStoreTest, UpdateRequest) { |
| 207 std::unique_ptr<RequestQueueStore> store(this->BuildStore()); |
| 208 base::Time creation_time = base::Time::Now(); |
| 209 SavePageRequest original_request(kRequestId, kUrl, kClientId, creation_time); |
| 210 store->AddOrUpdateRequest( |
| 211 original_request, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, |
| 212 base::Unretained(this))); |
| 213 this->PumpLoop(); |
| 214 this->ClearResults(); |
| 215 |
| 216 base::Time new_creation_time = |
| 217 creation_time + base::TimeDelta::FromMinutes(1); |
| 218 base::Time activation_time = creation_time + base::TimeDelta::FromHours(6); |
| 219 SavePageRequest updated_request(kRequestId, kUrl, kClientId, |
| 220 new_creation_time, activation_time); |
| 221 store->AddOrUpdateRequest( |
| 222 updated_request, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, |
| 223 base::Unretained(this))); |
| 224 ASSERT_EQ(UpdateStatus::FAILED, this->last_update_status()); |
| 225 this->PumpLoop(); |
| 226 ASSERT_EQ(UpdateStatus::UPDATED, this->last_update_status()); |
| 227 |
| 228 // Verifying get reqeust results after a request was updated. |
| 229 this->ClearResults(); |
| 230 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, |
| 231 base::Unretained(this))); |
| 232 ASSERT_EQ(LastResult::kNone, this->last_result()); |
| 233 this->PumpLoop(); |
| 234 ASSERT_EQ(LastResult::kTrue, this->last_result()); |
| 235 ASSERT_EQ(1ul, this->last_requests().size()); |
| 236 ASSERT_TRUE(updated_request == this->last_requests()[0]); |
| 237 } |
| 238 |
| 239 TYPED_TEST(RequestQueueStoreTest, RemoveRequest) { |
| 240 std::unique_ptr<RequestQueueStore> store(this->BuildStore()); |
| 241 base::Time creation_time = base::Time::Now(); |
| 242 SavePageRequest original_request(kRequestId, kUrl, kClientId, creation_time); |
| 243 store->AddOrUpdateRequest( |
| 244 original_request, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, |
| 245 base::Unretained(this))); |
| 246 this->PumpLoop(); |
| 247 this->ClearResults(); |
| 248 |
| 249 std::vector<int64_t> request_ids{kRequestId}; |
| 250 store->RemoveRequests(request_ids, |
| 251 base::Bind(&RequestQueueStoreTestBase::RemoveDone, |
| 252 base::Unretained(this))); |
| 253 ASSERT_EQ(LastResult::kNone, this->last_result()); |
| 254 ASSERT_EQ(0, this->last_remove_count()); |
| 255 this->PumpLoop(); |
| 256 ASSERT_EQ(LastResult::kTrue, this->last_result()); |
| 257 ASSERT_EQ(1, this->last_remove_count()); |
| 258 ASSERT_EQ(0ul, this->last_requests().size()); |
| 259 this->ClearResults(); |
| 260 |
| 261 // Removing a request that is missing fails. |
| 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(0, this->last_remove_count()); |
| 270 } |
| 271 |
| 272 TYPED_TEST(RequestQueueStoreTest, ResetStore) { |
| 273 std::unique_ptr<RequestQueueStore> store(this->BuildStore()); |
| 274 base::Time creation_time = base::Time::Now(); |
| 275 SavePageRequest original_request(kRequestId, kUrl, kClientId, creation_time); |
| 276 store->AddOrUpdateRequest( |
| 277 original_request, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, |
| 278 base::Unretained(this))); |
| 279 this->PumpLoop(); |
| 280 this->ClearResults(); |
| 281 |
| 282 store->Reset(base::Bind(&RequestQueueStoreTestBase::ResetDone, |
| 283 base::Unretained(this))); |
| 284 ASSERT_EQ(LastResult::kNone, this->last_result()); |
| 285 this->PumpLoop(); |
| 286 ASSERT_EQ(LastResult::kTrue, this->last_result()); |
| 287 ASSERT_EQ(0ul, this->last_requests().size()); |
| 288 } |
| 289 |
| 290 } // offline_pages |
| OLD | NEW |