| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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/offline_pages/background/request_queue_store.h" | 5 #include "components/offline_pages/background/request_queue_store.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 11 #include "base/files/scoped_temp_dir.h" | 11 #include "base/files/scoped_temp_dir.h" |
| 12 #include "base/test/test_simple_task_runner.h" | 12 #include "base/test/test_simple_task_runner.h" |
| 13 #include "base/threading/thread_task_runner_handle.h" | 13 #include "base/threading/thread_task_runner_handle.h" |
| 14 #include "components/offline_pages/background/request_queue.h" |
| 14 #include "components/offline_pages/background/request_queue_in_memory_store.h" | 15 #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/request_queue_store_sql.h" |
| 16 #include "components/offline_pages/background/save_page_request.h" | 17 #include "components/offline_pages/background/save_page_request.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 19 |
| 19 namespace offline_pages { | 20 namespace offline_pages { |
| 20 | 21 |
| 21 using UpdateStatus = RequestQueueStore::UpdateStatus; | 22 using UpdateStatus = RequestQueueStore::UpdateStatus; |
| 22 | 23 |
| 23 namespace { | 24 namespace { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 | 61 |
| 61 void PumpLoop(); | 62 void PumpLoop(); |
| 62 void ClearResults(); | 63 void ClearResults(); |
| 63 | 64 |
| 64 // Callback used for get requests. | 65 // Callback used for get requests. |
| 65 void GetRequestsDone(bool result, | 66 void GetRequestsDone(bool result, |
| 66 const std::vector<SavePageRequest>& requests); | 67 const std::vector<SavePageRequest>& requests); |
| 67 // Callback used for add/update request. | 68 // Callback used for add/update request. |
| 68 void AddOrUpdateDone(UpdateStatus result); | 69 void AddOrUpdateDone(UpdateStatus result); |
| 69 // Callback used for remove requests. | 70 // Callback used for remove requests. |
| 70 void RemoveDone(bool result, int count); | 71 void RemoveDone( |
| 72 const std::vector<std::pair<int64_t, RequestQueue::UpdateRequestResult>>& |
| 73 results); |
| 71 // Callback used for reset. | 74 // Callback used for reset. |
| 72 void ResetDone(bool result); | 75 void ResetDone(bool result); |
| 73 | 76 |
| 74 LastResult last_result() const { return last_result_; } | 77 LastResult last_result() const { return last_result_; } |
| 75 UpdateStatus last_update_status() const { return last_update_status_; } | 78 UpdateStatus last_update_status() const { return last_update_status_; } |
| 76 int last_remove_count() const { return last_remove_count_; } | 79 const std::vector<std::pair<int64_t, RequestQueue::UpdateRequestResult>>& |
| 80 last_remove_results() const { |
| 81 return last_remove_results_; |
| 82 } |
| 77 const std::vector<SavePageRequest>& last_requests() const { | 83 const std::vector<SavePageRequest>& last_requests() const { |
| 78 return last_requests_; | 84 return last_requests_; |
| 79 } | 85 } |
| 80 | 86 |
| 81 protected: | 87 protected: |
| 82 base::ScopedTempDir temp_directory_; | 88 base::ScopedTempDir temp_directory_; |
| 83 | 89 |
| 84 private: | 90 private: |
| 85 LastResult last_result_; | 91 LastResult last_result_; |
| 86 UpdateStatus last_update_status_; | 92 UpdateStatus last_update_status_; |
| 87 int last_remove_count_; | 93 std::vector<std::pair<int64_t, RequestQueue::UpdateRequestResult>> |
| 94 last_remove_results_; |
| 88 std::vector<SavePageRequest> last_requests_; | 95 std::vector<SavePageRequest> last_requests_; |
| 89 | 96 |
| 90 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; | 97 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
| 91 base::ThreadTaskRunnerHandle task_runner_handle_; | 98 base::ThreadTaskRunnerHandle task_runner_handle_; |
| 92 }; | 99 }; |
| 93 | 100 |
| 94 RequestQueueStoreTestBase::RequestQueueStoreTestBase() | 101 RequestQueueStoreTestBase::RequestQueueStoreTestBase() |
| 95 : last_result_(LastResult::kNone), | 102 : last_result_(LastResult::kNone), |
| 96 last_update_status_(UpdateStatus::FAILED), | 103 last_update_status_(UpdateStatus::FAILED), |
| 97 last_remove_count_(0), | |
| 98 task_runner_(new base::TestSimpleTaskRunner), | 104 task_runner_(new base::TestSimpleTaskRunner), |
| 99 task_runner_handle_(task_runner_) { | 105 task_runner_handle_(task_runner_) { |
| 100 EXPECT_TRUE(temp_directory_.CreateUniqueTempDir()); | 106 EXPECT_TRUE(temp_directory_.CreateUniqueTempDir()); |
| 101 } | 107 } |
| 102 | 108 |
| 103 void RequestQueueStoreTestBase::TearDown() { | 109 void RequestQueueStoreTestBase::TearDown() { |
| 104 // Wait for all the pieces of the store to delete itself properly. | 110 // Wait for all the pieces of the store to delete itself properly. |
| 105 PumpLoop(); | 111 PumpLoop(); |
| 106 } | 112 } |
| 107 | 113 |
| 108 void RequestQueueStoreTestBase::PumpLoop() { | 114 void RequestQueueStoreTestBase::PumpLoop() { |
| 109 task_runner_->RunUntilIdle(); | 115 task_runner_->RunUntilIdle(); |
| 110 } | 116 } |
| 111 | 117 |
| 112 void RequestQueueStoreTestBase::ClearResults() { | 118 void RequestQueueStoreTestBase::ClearResults() { |
| 113 last_result_ = LastResult::kNone; | 119 last_result_ = LastResult::kNone; |
| 114 last_update_status_ = UpdateStatus::FAILED; | 120 last_update_status_ = UpdateStatus::FAILED; |
| 115 last_remove_count_ = 0; | 121 last_remove_results_.clear(); |
| 116 last_requests_.clear(); | 122 last_requests_.clear(); |
| 117 } | 123 } |
| 118 | 124 |
| 119 void RequestQueueStoreTestBase::GetRequestsDone( | 125 void RequestQueueStoreTestBase::GetRequestsDone( |
| 120 bool result, | 126 bool result, |
| 121 const std::vector<SavePageRequest>& requests) { | 127 const std::vector<SavePageRequest>& requests) { |
| 122 last_result_ = result ? LastResult::kTrue : LastResult::kFalse; | 128 last_result_ = result ? LastResult::kTrue : LastResult::kFalse; |
| 123 last_requests_ = requests; | 129 last_requests_ = requests; |
| 124 } | 130 } |
| 125 | 131 |
| 126 void RequestQueueStoreTestBase::AddOrUpdateDone(UpdateStatus status) { | 132 void RequestQueueStoreTestBase::AddOrUpdateDone(UpdateStatus status) { |
| 127 last_update_status_ = status; | 133 last_update_status_ = status; |
| 128 } | 134 } |
| 129 | 135 |
| 130 void RequestQueueStoreTestBase::RemoveDone(bool result, int count) { | 136 void RequestQueueStoreTestBase::RemoveDone( |
| 131 last_result_ = result ? LastResult::kTrue : LastResult::kFalse; | 137 const std::vector<std::pair<int64_t, RequestQueue::UpdateRequestResult>>& |
| 132 last_remove_count_ = count; | 138 results) { |
| 139 last_remove_results_ = results; |
| 133 } | 140 } |
| 134 | 141 |
| 135 void RequestQueueStoreTestBase::ResetDone(bool result) { | 142 void RequestQueueStoreTestBase::ResetDone(bool result) { |
| 136 last_result_ = result ? LastResult::kTrue : LastResult::kFalse; | 143 last_result_ = result ? LastResult::kTrue : LastResult::kFalse; |
| 137 } | 144 } |
| 138 | 145 |
| 139 // Defines interface for the store factory. | 146 // Defines interface for the store factory. |
| 140 class RequestQueueStoreFactory { | 147 class RequestQueueStoreFactory { |
| 141 public: | 148 public: |
| 142 virtual RequestQueueStore* BuildStore(const base::FilePath& path) = 0; | 149 virtual RequestQueueStore* BuildStore(const base::FilePath& path) = 0; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 this->ClearResults(); | 257 this->ClearResults(); |
| 251 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, | 258 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, |
| 252 base::Unretained(this))); | 259 base::Unretained(this))); |
| 253 ASSERT_EQ(LastResult::kNone, this->last_result()); | 260 ASSERT_EQ(LastResult::kNone, this->last_result()); |
| 254 this->PumpLoop(); | 261 this->PumpLoop(); |
| 255 ASSERT_EQ(LastResult::kTrue, this->last_result()); | 262 ASSERT_EQ(LastResult::kTrue, this->last_result()); |
| 256 ASSERT_EQ(1ul, this->last_requests().size()); | 263 ASSERT_EQ(1ul, this->last_requests().size()); |
| 257 ASSERT_TRUE(updated_request == this->last_requests()[0]); | 264 ASSERT_TRUE(updated_request == this->last_requests()[0]); |
| 258 } | 265 } |
| 259 | 266 |
| 260 TYPED_TEST(RequestQueueStoreTest, RemoveRequest) { | 267 TYPED_TEST(RequestQueueStoreTest, RemoveRequests) { |
| 261 std::unique_ptr<RequestQueueStore> store(this->BuildStore()); | 268 std::unique_ptr<RequestQueueStore> store(this->BuildStore()); |
| 262 base::Time creation_time = base::Time::Now(); | 269 base::Time creation_time = base::Time::Now(); |
| 263 SavePageRequest original_request( | 270 SavePageRequest request1(kRequestId, kUrl, kClientId, creation_time, |
| 264 kRequestId, kUrl, kClientId, creation_time, kUserRequested); | 271 kUserRequested); |
| 265 store->AddOrUpdateRequest( | 272 store->AddOrUpdateRequest( |
| 266 original_request, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, | 273 request1, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, |
| 267 base::Unretained(this))); | 274 base::Unretained(this))); |
| 275 SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time, |
| 276 kUserRequested); |
| 277 store->AddOrUpdateRequest( |
| 278 request2, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, |
| 279 base::Unretained(this))); |
| 268 this->PumpLoop(); | 280 this->PumpLoop(); |
| 269 this->ClearResults(); | 281 this->ClearResults(); |
| 270 | 282 |
| 271 std::vector<int64_t> request_ids{kRequestId}; | 283 std::vector<int64_t> request_ids{kRequestId, kRequestId2}; |
| 272 store->RemoveRequests(request_ids, | 284 store->RemoveRequests(request_ids, |
| 273 base::Bind(&RequestQueueStoreTestBase::RemoveDone, | 285 base::Bind(&RequestQueueStoreTestBase::RemoveDone, |
| 274 base::Unretained(this))); | 286 base::Unretained(this))); |
| 275 ASSERT_EQ(LastResult::kNone, this->last_result()); | 287 ASSERT_EQ(0ul, this->last_remove_results().size()); |
| 276 ASSERT_EQ(0, this->last_remove_count()); | |
| 277 this->PumpLoop(); | 288 this->PumpLoop(); |
| 278 ASSERT_EQ(LastResult::kTrue, this->last_result()); | 289 ASSERT_EQ(2ul, this->last_remove_results().size()); |
| 279 ASSERT_EQ(1, this->last_remove_count()); | 290 ASSERT_EQ(RequestQueue::UpdateRequestResult::SUCCESS, |
| 291 this->last_remove_results().at(0).second); |
| 292 ASSERT_EQ(RequestQueue::UpdateRequestResult::SUCCESS, |
| 293 this->last_remove_results().at(1).second); |
| 280 this->ClearResults(); | 294 this->ClearResults(); |
| 281 | 295 |
| 282 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, | 296 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, |
| 283 base::Unretained(this))); | 297 base::Unretained(this))); |
| 284 this->PumpLoop(); | 298 this->PumpLoop(); |
| 285 ASSERT_EQ(LastResult::kTrue, this->last_result()); | 299 ASSERT_EQ(LastResult::kTrue, this->last_result()); |
| 286 ASSERT_TRUE(this->last_requests().empty()); | 300 ASSERT_TRUE(this->last_requests().empty()); |
| 287 this->ClearResults(); | 301 this->ClearResults(); |
| 288 | 302 |
| 289 // Try to remove a request that is not in the queue. | 303 // Try to remove a request that is not in the queue. |
| 290 store->RemoveRequests(request_ids, | 304 store->RemoveRequests(request_ids, |
| 291 base::Bind(&RequestQueueStoreTestBase::RemoveDone, | 305 base::Bind(&RequestQueueStoreTestBase::RemoveDone, |
| 292 base::Unretained(this))); | 306 base::Unretained(this))); |
| 293 ASSERT_EQ(LastResult::kNone, this->last_result()); | 307 ASSERT_EQ(LastResult::kNone, this->last_result()); |
| 294 ASSERT_EQ(0, this->last_remove_count()); | |
| 295 this->PumpLoop(); | 308 this->PumpLoop(); |
| 296 ASSERT_EQ(LastResult::kTrue, this->last_result()); | 309 ASSERT_EQ(2ul, this->last_remove_results().size()); |
| 297 ASSERT_EQ(0, this->last_remove_count()); | 310 // Since the SQL statement returns true on a delete of an item that isn't |
| 298 } | 311 // present, SQL is returning SUCCESS, but the memory is returning |
| 299 | 312 // REQUEST_DOES_NOT_EXIST, so we just check that the result is not failure. |
| 300 TYPED_TEST(RequestQueueStoreTest, RemoveRequestByClientId) { | 313 ASSERT_NE(RequestQueue::UpdateRequestResult::STORE_FAILURE, |
| 301 std::unique_ptr<RequestQueueStore> store(this->BuildStore()); | 314 this->last_remove_results().at(0).second); |
| 302 base::Time creation_time = base::Time::Now(); | 315 ASSERT_NE(RequestQueue::UpdateRequestResult::STORE_FAILURE, |
| 303 | 316 this->last_remove_results().at(1).second); |
| 304 // Create requests and add them to the queue. | |
| 305 SavePageRequest request1(kRequestId, kUrl, kClientId, creation_time, | |
| 306 kUserRequested); | |
| 307 SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time, | |
| 308 kUserRequested); | |
| 309 store->AddOrUpdateRequest( | |
| 310 request1, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, | |
| 311 base::Unretained(this))); | |
| 312 store->AddOrUpdateRequest( | |
| 313 request2, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, | |
| 314 base::Unretained(this))); | |
| 315 this->PumpLoop(); | |
| 316 this->ClearResults(); | |
| 317 | |
| 318 // Remove a request. | |
| 319 std::vector<ClientId> client_ids_to_delete{kClientId}; | |
| 320 store->RemoveRequestsByClientId( | |
| 321 client_ids_to_delete, | |
| 322 base::Bind( | |
| 323 &RequestQueueStoreTestBase::RemoveDone, base::Unretained(this))); | |
| 324 ASSERT_EQ(LastResult::kNone, this->last_result()); | |
| 325 ASSERT_EQ(0, this->last_remove_count()); | |
| 326 this->PumpLoop(); | |
| 327 ASSERT_EQ(LastResult::kTrue, this->last_result()); | |
| 328 ASSERT_EQ(1, this->last_remove_count()); | |
| 329 this->ClearResults(); | |
| 330 | |
| 331 // Check to see what remains in the queue. Removed request should be gone. | |
| 332 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, | |
| 333 base::Unretained(this))); | |
| 334 this->PumpLoop(); | |
| 335 ASSERT_EQ(LastResult::kTrue, this->last_result()); | |
| 336 // The other request should still be in the queue. | |
| 337 ASSERT_EQ(1UL, this->last_requests().size()); | |
| 338 ASSERT_EQ(kClientId2, this->last_requests().at(0).client_id()); | |
| 339 this->ClearResults(); | |
| 340 | |
| 341 // Try to remove a request that is not in the queue. | |
| 342 store->RemoveRequestsByClientId( | |
| 343 client_ids_to_delete, | |
| 344 base::Bind( | |
| 345 &RequestQueueStoreTestBase::RemoveDone, base::Unretained(this))); | |
| 346 this->PumpLoop(); | |
| 347 ASSERT_EQ(LastResult::kTrue, this->last_result()); | |
| 348 ASSERT_EQ(0, this->last_remove_count()); | |
| 349 } | |
| 350 | |
| 351 TYPED_TEST(RequestQueueStoreTest, RemoveRequestWithSameClientId) { | |
| 352 std::unique_ptr<RequestQueueStore> store(this->BuildStore()); | |
| 353 base::Time creation_time = base::Time::Now(); | |
| 354 | |
| 355 // Create requests and add them to the queue. | |
| 356 SavePageRequest request1(kRequestId, kUrl, kClientId, creation_time, | |
| 357 kUserRequested); | |
| 358 SavePageRequest request2(kRequestId2, kUrl2, kClientId, creation_time, | |
| 359 kUserRequested); | |
| 360 store->AddOrUpdateRequest( | |
| 361 request1, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, | |
| 362 base::Unretained(this))); | |
| 363 store->AddOrUpdateRequest( | |
| 364 request2, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, | |
| 365 base::Unretained(this))); | |
| 366 this->PumpLoop(); | |
| 367 this->ClearResults(); | |
| 368 | |
| 369 // Remove a request. | |
| 370 std::vector<ClientId> client_ids_to_delete{kClientId}; | |
| 371 store->RemoveRequestsByClientId( | |
| 372 client_ids_to_delete, | |
| 373 base::Bind( | |
| 374 &RequestQueueStoreTestBase::RemoveDone, base::Unretained(this))); | |
| 375 ASSERT_EQ(LastResult::kNone, this->last_result()); | |
| 376 ASSERT_EQ(0, this->last_remove_count()); | |
| 377 this->PumpLoop(); | |
| 378 ASSERT_EQ(LastResult::kTrue, this->last_result()); | |
| 379 ASSERT_EQ(2, this->last_remove_count()); | |
| 380 this->ClearResults(); | |
| 381 | |
| 382 // Check to see what remains in the queue. Removed request should be gone. | |
| 383 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, | |
| 384 base::Unretained(this))); | |
| 385 this->PumpLoop(); | |
| 386 ASSERT_EQ(LastResult::kTrue, this->last_result()); | |
| 387 // The other request should still be in the queue. | |
| 388 ASSERT_TRUE(this->last_requests().empty()); | |
| 389 this->ClearResults(); | |
| 390 } | 317 } |
| 391 | 318 |
| 392 TYPED_TEST(RequestQueueStoreTest, ResetStore) { | 319 TYPED_TEST(RequestQueueStoreTest, ResetStore) { |
| 393 std::unique_ptr<RequestQueueStore> store(this->BuildStore()); | 320 std::unique_ptr<RequestQueueStore> store(this->BuildStore()); |
| 394 base::Time creation_time = base::Time::Now(); | 321 base::Time creation_time = base::Time::Now(); |
| 395 SavePageRequest original_request( | 322 SavePageRequest original_request( |
| 396 kRequestId, kUrl, kClientId, creation_time, kUserRequested); | 323 kRequestId, kUrl, kClientId, creation_time, kUserRequested); |
| 397 store->AddOrUpdateRequest( | 324 store->AddOrUpdateRequest( |
| 398 original_request, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, | 325 original_request, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, |
| 399 base::Unretained(this))); | 326 base::Unretained(this))); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, | 364 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, |
| 438 base::Unretained(this))); | 365 base::Unretained(this))); |
| 439 ASSERT_EQ(LastResult::kNone, this->last_result()); | 366 ASSERT_EQ(LastResult::kNone, this->last_result()); |
| 440 this->PumpLoop(); | 367 this->PumpLoop(); |
| 441 ASSERT_EQ(LastResult::kTrue, this->last_result()); | 368 ASSERT_EQ(LastResult::kTrue, this->last_result()); |
| 442 ASSERT_EQ(1ul, this->last_requests().size()); | 369 ASSERT_EQ(1ul, this->last_requests().size()); |
| 443 ASSERT_TRUE(original_request == this->last_requests()[0]); | 370 ASSERT_TRUE(original_request == this->last_requests()[0]); |
| 444 } | 371 } |
| 445 | 372 |
| 446 } // offline_pages | 373 } // offline_pages |
| OLD | NEW |