| 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(const RequestQueue::UpdateMultipleRequestResults& results); |
| 71 // Callback used for reset. | 72 // Callback used for reset. |
| 72 void ResetDone(bool result); | 73 void ResetDone(bool result); |
| 73 | 74 |
| 74 LastResult last_result() const { return last_result_; } | 75 LastResult last_result() const { return last_result_; } |
| 75 UpdateStatus last_update_status() const { return last_update_status_; } | 76 UpdateStatus last_update_status() const { return last_update_status_; } |
| 76 int last_remove_count() const { return last_remove_count_; } | 77 const RequestQueue::UpdateMultipleRequestResults& last_remove_results() |
| 78 const { |
| 79 return last_remove_results_; |
| 80 } |
| 77 const std::vector<SavePageRequest>& last_requests() const { | 81 const std::vector<SavePageRequest>& last_requests() const { |
| 78 return last_requests_; | 82 return last_requests_; |
| 79 } | 83 } |
| 80 | 84 |
| 81 protected: | 85 protected: |
| 82 base::ScopedTempDir temp_directory_; | 86 base::ScopedTempDir temp_directory_; |
| 83 | 87 |
| 84 private: | 88 private: |
| 85 LastResult last_result_; | 89 LastResult last_result_; |
| 86 UpdateStatus last_update_status_; | 90 UpdateStatus last_update_status_; |
| 87 int last_remove_count_; | 91 RequestQueue::UpdateMultipleRequestResults last_remove_results_; |
| 88 std::vector<SavePageRequest> last_requests_; | 92 std::vector<SavePageRequest> last_requests_; |
| 89 | 93 |
| 90 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; | 94 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
| 91 base::ThreadTaskRunnerHandle task_runner_handle_; | 95 base::ThreadTaskRunnerHandle task_runner_handle_; |
| 92 }; | 96 }; |
| 93 | 97 |
| 94 RequestQueueStoreTestBase::RequestQueueStoreTestBase() | 98 RequestQueueStoreTestBase::RequestQueueStoreTestBase() |
| 95 : last_result_(LastResult::kNone), | 99 : last_result_(LastResult::kNone), |
| 96 last_update_status_(UpdateStatus::FAILED), | 100 last_update_status_(UpdateStatus::FAILED), |
| 97 last_remove_count_(0), | |
| 98 task_runner_(new base::TestSimpleTaskRunner), | 101 task_runner_(new base::TestSimpleTaskRunner), |
| 99 task_runner_handle_(task_runner_) { | 102 task_runner_handle_(task_runner_) { |
| 100 EXPECT_TRUE(temp_directory_.CreateUniqueTempDir()); | 103 EXPECT_TRUE(temp_directory_.CreateUniqueTempDir()); |
| 101 } | 104 } |
| 102 | 105 |
| 103 void RequestQueueStoreTestBase::TearDown() { | 106 void RequestQueueStoreTestBase::TearDown() { |
| 104 // Wait for all the pieces of the store to delete itself properly. | 107 // Wait for all the pieces of the store to delete itself properly. |
| 105 PumpLoop(); | 108 PumpLoop(); |
| 106 } | 109 } |
| 107 | 110 |
| 108 void RequestQueueStoreTestBase::PumpLoop() { | 111 void RequestQueueStoreTestBase::PumpLoop() { |
| 109 task_runner_->RunUntilIdle(); | 112 task_runner_->RunUntilIdle(); |
| 110 } | 113 } |
| 111 | 114 |
| 112 void RequestQueueStoreTestBase::ClearResults() { | 115 void RequestQueueStoreTestBase::ClearResults() { |
| 113 last_result_ = LastResult::kNone; | 116 last_result_ = LastResult::kNone; |
| 114 last_update_status_ = UpdateStatus::FAILED; | 117 last_update_status_ = UpdateStatus::FAILED; |
| 115 last_remove_count_ = 0; | 118 last_remove_results_.clear(); |
| 116 last_requests_.clear(); | 119 last_requests_.clear(); |
| 117 } | 120 } |
| 118 | 121 |
| 119 void RequestQueueStoreTestBase::GetRequestsDone( | 122 void RequestQueueStoreTestBase::GetRequestsDone( |
| 120 bool result, | 123 bool result, |
| 121 const std::vector<SavePageRequest>& requests) { | 124 const std::vector<SavePageRequest>& requests) { |
| 122 last_result_ = result ? LastResult::kTrue : LastResult::kFalse; | 125 last_result_ = result ? LastResult::kTrue : LastResult::kFalse; |
| 123 last_requests_ = requests; | 126 last_requests_ = requests; |
| 124 } | 127 } |
| 125 | 128 |
| 126 void RequestQueueStoreTestBase::AddOrUpdateDone(UpdateStatus status) { | 129 void RequestQueueStoreTestBase::AddOrUpdateDone(UpdateStatus status) { |
| 127 last_update_status_ = status; | 130 last_update_status_ = status; |
| 128 } | 131 } |
| 129 | 132 |
| 130 void RequestQueueStoreTestBase::RemoveDone(bool result, int count) { | 133 void RequestQueueStoreTestBase::RemoveDone( |
| 131 last_result_ = result ? LastResult::kTrue : LastResult::kFalse; | 134 const RequestQueue::UpdateMultipleRequestResults& results) { |
| 132 last_remove_count_ = count; | 135 last_remove_results_ = results; |
| 133 } | 136 } |
| 134 | 137 |
| 135 void RequestQueueStoreTestBase::ResetDone(bool result) { | 138 void RequestQueueStoreTestBase::ResetDone(bool result) { |
| 136 last_result_ = result ? LastResult::kTrue : LastResult::kFalse; | 139 last_result_ = result ? LastResult::kTrue : LastResult::kFalse; |
| 137 } | 140 } |
| 138 | 141 |
| 139 // Defines interface for the store factory. | 142 // Defines interface for the store factory. |
| 140 class RequestQueueStoreFactory { | 143 class RequestQueueStoreFactory { |
| 141 public: | 144 public: |
| 142 virtual RequestQueueStore* BuildStore(const base::FilePath& path) = 0; | 145 virtual RequestQueueStore* BuildStore(const base::FilePath& path) = 0; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 this->ClearResults(); | 253 this->ClearResults(); |
| 251 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, | 254 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, |
| 252 base::Unretained(this))); | 255 base::Unretained(this))); |
| 253 ASSERT_EQ(LastResult::kNone, this->last_result()); | 256 ASSERT_EQ(LastResult::kNone, this->last_result()); |
| 254 this->PumpLoop(); | 257 this->PumpLoop(); |
| 255 ASSERT_EQ(LastResult::kTrue, this->last_result()); | 258 ASSERT_EQ(LastResult::kTrue, this->last_result()); |
| 256 ASSERT_EQ(1ul, this->last_requests().size()); | 259 ASSERT_EQ(1ul, this->last_requests().size()); |
| 257 ASSERT_TRUE(updated_request == this->last_requests()[0]); | 260 ASSERT_TRUE(updated_request == this->last_requests()[0]); |
| 258 } | 261 } |
| 259 | 262 |
| 260 TYPED_TEST(RequestQueueStoreTest, RemoveRequest) { | 263 TYPED_TEST(RequestQueueStoreTest, RemoveRequests) { |
| 261 std::unique_ptr<RequestQueueStore> store(this->BuildStore()); | 264 std::unique_ptr<RequestQueueStore> store(this->BuildStore()); |
| 262 base::Time creation_time = base::Time::Now(); | 265 base::Time creation_time = base::Time::Now(); |
| 263 SavePageRequest original_request( | 266 SavePageRequest request1(kRequestId, kUrl, kClientId, creation_time, |
| 264 kRequestId, kUrl, kClientId, creation_time, kUserRequested); | 267 kUserRequested); |
| 265 store->AddOrUpdateRequest( | 268 store->AddOrUpdateRequest( |
| 266 original_request, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, | 269 request1, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, |
| 267 base::Unretained(this))); | 270 base::Unretained(this))); |
| 271 SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time, |
| 272 kUserRequested); |
| 273 store->AddOrUpdateRequest( |
| 274 request2, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, |
| 275 base::Unretained(this))); |
| 268 this->PumpLoop(); | 276 this->PumpLoop(); |
| 269 this->ClearResults(); | 277 this->ClearResults(); |
| 270 | 278 |
| 271 std::vector<int64_t> request_ids{kRequestId}; | 279 std::vector<int64_t> request_ids{kRequestId, kRequestId2}; |
| 272 store->RemoveRequests(request_ids, | 280 store->RemoveRequests(request_ids, |
| 273 base::Bind(&RequestQueueStoreTestBase::RemoveDone, | 281 base::Bind(&RequestQueueStoreTestBase::RemoveDone, |
| 274 base::Unretained(this))); | 282 base::Unretained(this))); |
| 275 ASSERT_EQ(LastResult::kNone, this->last_result()); | 283 ASSERT_EQ(0ul, this->last_remove_results().size()); |
| 276 ASSERT_EQ(0, this->last_remove_count()); | |
| 277 this->PumpLoop(); | 284 this->PumpLoop(); |
| 278 ASSERT_EQ(LastResult::kTrue, this->last_result()); | 285 ASSERT_EQ(2ul, this->last_remove_results().size()); |
| 279 ASSERT_EQ(1, this->last_remove_count()); | 286 ASSERT_EQ(RequestQueue::UpdateRequestResult::SUCCESS, |
| 287 this->last_remove_results().at(0).second); |
| 288 ASSERT_EQ(RequestQueue::UpdateRequestResult::SUCCESS, |
| 289 this->last_remove_results().at(1).second); |
| 280 this->ClearResults(); | 290 this->ClearResults(); |
| 281 | 291 |
| 282 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, | 292 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, |
| 283 base::Unretained(this))); | 293 base::Unretained(this))); |
| 284 this->PumpLoop(); | 294 this->PumpLoop(); |
| 285 ASSERT_EQ(LastResult::kTrue, this->last_result()); | 295 ASSERT_EQ(LastResult::kTrue, this->last_result()); |
| 286 ASSERT_TRUE(this->last_requests().empty()); | 296 ASSERT_TRUE(this->last_requests().empty()); |
| 287 this->ClearResults(); | 297 this->ClearResults(); |
| 288 | 298 |
| 289 // Try to remove a request that is not in the queue. | 299 // Try to remove a request that is not in the queue. |
| 290 store->RemoveRequests(request_ids, | 300 store->RemoveRequests(request_ids, |
| 291 base::Bind(&RequestQueueStoreTestBase::RemoveDone, | 301 base::Bind(&RequestQueueStoreTestBase::RemoveDone, |
| 292 base::Unretained(this))); | 302 base::Unretained(this))); |
| 293 ASSERT_EQ(LastResult::kNone, this->last_result()); | 303 ASSERT_EQ(LastResult::kNone, this->last_result()); |
| 294 ASSERT_EQ(0, this->last_remove_count()); | |
| 295 this->PumpLoop(); | 304 this->PumpLoop(); |
| 296 ASSERT_EQ(LastResult::kTrue, this->last_result()); | 305 ASSERT_EQ(2ul, this->last_remove_results().size()); |
| 297 ASSERT_EQ(0, this->last_remove_count()); | 306 // Since the SQL statement returns true on a delete of an item that isn't |
| 298 } | 307 // present, SQL is returning SUCCESS, but the memory is returning |
| 299 | 308 // REQUEST_DOES_NOT_EXIST, so we just check that the result is not failure. |
| 300 TYPED_TEST(RequestQueueStoreTest, RemoveRequestByClientId) { | 309 ASSERT_NE(RequestQueue::UpdateRequestResult::STORE_FAILURE, |
| 301 std::unique_ptr<RequestQueueStore> store(this->BuildStore()); | 310 this->last_remove_results().at(0).second); |
| 302 base::Time creation_time = base::Time::Now(); | 311 ASSERT_NE(RequestQueue::UpdateRequestResult::STORE_FAILURE, |
| 303 | 312 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 } | 313 } |
| 391 | 314 |
| 392 TYPED_TEST(RequestQueueStoreTest, ResetStore) { | 315 TYPED_TEST(RequestQueueStoreTest, ResetStore) { |
| 393 std::unique_ptr<RequestQueueStore> store(this->BuildStore()); | 316 std::unique_ptr<RequestQueueStore> store(this->BuildStore()); |
| 394 base::Time creation_time = base::Time::Now(); | 317 base::Time creation_time = base::Time::Now(); |
| 395 SavePageRequest original_request( | 318 SavePageRequest original_request( |
| 396 kRequestId, kUrl, kClientId, creation_time, kUserRequested); | 319 kRequestId, kUrl, kClientId, creation_time, kUserRequested); |
| 397 store->AddOrUpdateRequest( | 320 store->AddOrUpdateRequest( |
| 398 original_request, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, | 321 original_request, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, |
| 399 base::Unretained(this))); | 322 base::Unretained(this))); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, | 360 store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, |
| 438 base::Unretained(this))); | 361 base::Unretained(this))); |
| 439 ASSERT_EQ(LastResult::kNone, this->last_result()); | 362 ASSERT_EQ(LastResult::kNone, this->last_result()); |
| 440 this->PumpLoop(); | 363 this->PumpLoop(); |
| 441 ASSERT_EQ(LastResult::kTrue, this->last_result()); | 364 ASSERT_EQ(LastResult::kTrue, this->last_result()); |
| 442 ASSERT_EQ(1ul, this->last_requests().size()); | 365 ASSERT_EQ(1ul, this->last_requests().size()); |
| 443 ASSERT_TRUE(original_request == this->last_requests()[0]); | 366 ASSERT_TRUE(original_request == this->last_requests()[0]); |
| 444 } | 367 } |
| 445 | 368 |
| 446 } // offline_pages | 369 } // offline_pages |
| OLD | NEW |