| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "content/browser/download/parallel_download_job.h" | 5 #include "content/browser/download/parallel_download_job.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 #include "base/run_loop.h" |
| 12 #include "content/browser/download/download_destination_observer.h" |
| 13 #include "content/browser/download/download_file_impl.h" |
| 11 #include "content/browser/download/download_item_impl_delegate.h" | 14 #include "content/browser/download/download_item_impl_delegate.h" |
| 12 #include "content/browser/download/mock_download_item_impl.h" | 15 #include "content/browser/download/mock_download_item_impl.h" |
| 13 #include "content/browser/download/parallel_download_utils.h" | 16 #include "content/browser/download/parallel_download_utils.h" |
| 14 #include "content/public/test/test_browser_thread_bundle.h" | 17 #include "content/public/test/test_browser_thread_bundle.h" |
| 15 #include "testing/gmock/include/gmock/gmock.h" | 18 #include "testing/gmock/include/gmock/gmock.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 20 |
| 21 using ::testing::_; |
| 18 using ::testing::NiceMock; | 22 using ::testing::NiceMock; |
| 23 using ::testing::StrictMock; |
| 19 | 24 |
| 20 namespace content { | 25 namespace content { |
| 21 | 26 |
| 22 namespace { | 27 namespace { |
| 23 | 28 |
| 24 class MockDownloadRequestHandle : public DownloadRequestHandleInterface { | 29 class MockDownloadRequestHandle : public DownloadRequestHandleInterface { |
| 25 public: | 30 public: |
| 26 MOCK_CONST_METHOD0(GetWebContents, WebContents*()); | 31 MOCK_CONST_METHOD0(GetWebContents, WebContents*()); |
| 27 MOCK_CONST_METHOD0(GetDownloadManager, DownloadManager*()); | 32 MOCK_CONST_METHOD0(GetDownloadManager, DownloadManager*()); |
| 28 MOCK_CONST_METHOD0(PauseRequest, void()); | 33 MOCK_CONST_METHOD0(PauseRequest, void()); |
| 29 MOCK_CONST_METHOD0(ResumeRequest, void()); | 34 MOCK_CONST_METHOD0(ResumeRequest, void()); |
| 30 MOCK_CONST_METHOD0(CancelRequest, void()); | 35 MOCK_CONST_METHOD0(CancelRequest, void()); |
| 31 MOCK_CONST_METHOD0(DebugString, std::string()); | 36 MOCK_CONST_METHOD0(DebugString, std::string()); |
| 32 }; | 37 }; |
| 33 | 38 |
| 39 class MockDownloadDestinationObserver : public DownloadDestinationObserver { |
| 40 public: |
| 41 MOCK_METHOD3(DestinationUpdate, |
| 42 void(int64_t, |
| 43 int64_t, |
| 44 const std::vector<DownloadItem::ReceivedSlice>&)); |
| 45 void DestinationError( |
| 46 DownloadInterruptReason reason, |
| 47 int64_t bytes_so_far, |
| 48 std::unique_ptr<crypto::SecureHash> hash_state) override {} |
| 49 void DestinationCompleted( |
| 50 int64_t total_bytes, |
| 51 std::unique_ptr<crypto::SecureHash> hash_state) override {} |
| 52 MOCK_METHOD2(CurrentUpdateStatus, void(int64_t, int64_t)); |
| 53 }; |
| 54 |
| 55 class MockByteStreamReader : public ByteStreamReader { |
| 56 public: |
| 57 MOCK_METHOD2(Read, |
| 58 ByteStreamReader::StreamState(scoped_refptr<net::IOBuffer>*, |
| 59 size_t*)); |
| 60 MOCK_CONST_METHOD0(GetStatus, int()); |
| 61 MOCK_METHOD1(RegisterCallback, void(const base::Closure&)); |
| 62 }; |
| 63 |
| 34 } // namespace | 64 } // namespace |
| 35 | 65 |
| 36 class ParallelDownloadJobForTest : public ParallelDownloadJob { | 66 class ParallelDownloadJobForTest : public ParallelDownloadJob { |
| 37 public: | 67 public: |
| 38 ParallelDownloadJobForTest( | 68 ParallelDownloadJobForTest( |
| 39 DownloadItemImpl* download_item, | 69 DownloadItemImpl* download_item, |
| 40 std::unique_ptr<DownloadRequestHandleInterface> request_handle, | 70 std::unique_ptr<DownloadRequestHandleInterface> request_handle, |
| 41 const DownloadCreateInfo& create_info, | 71 const DownloadCreateInfo& create_info, |
| 42 int request_count, | 72 int request_count, |
| 43 int64_t min_slice_size, | 73 int64_t min_slice_size, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 | 129 |
| 100 DownloadCreateInfo info; | 130 DownloadCreateInfo info; |
| 101 info.offset = initial_request_offset; | 131 info.offset = initial_request_offset; |
| 102 info.total_bytes = content_length; | 132 info.total_bytes = content_length; |
| 103 std::unique_ptr<MockDownloadRequestHandle> request_handle = | 133 std::unique_ptr<MockDownloadRequestHandle> request_handle = |
| 104 base::MakeUnique<MockDownloadRequestHandle>(); | 134 base::MakeUnique<MockDownloadRequestHandle>(); |
| 105 mock_request_handle_ = request_handle.get(); | 135 mock_request_handle_ = request_handle.get(); |
| 106 job_ = base::MakeUnique<ParallelDownloadJobForTest>( | 136 job_ = base::MakeUnique<ParallelDownloadJobForTest>( |
| 107 download_item_.get(), std::move(request_handle), info, request_count, | 137 download_item_.get(), std::move(request_handle), info, request_count, |
| 108 min_slice_size, min_remaining_time); | 138 min_slice_size, min_remaining_time); |
| 139 file_initialized_ = false; |
| 109 } | 140 } |
| 110 | 141 |
| 111 void DestroyParallelJob() { | 142 void DestroyParallelJob() { |
| 112 job_.reset(); | 143 job_.reset(); |
| 113 download_item_.reset(); | 144 download_item_.reset(); |
| 114 item_delegate_.reset(); | 145 item_delegate_.reset(); |
| 115 mock_request_handle_ = nullptr; | 146 mock_request_handle_ = nullptr; |
| 116 } | 147 } |
| 117 | 148 |
| 118 void BuildParallelRequests() { job_->BuildParallelRequests(); } | 149 void BuildParallelRequests() { job_->BuildParallelRequests(); } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 131 std::move(create_info), std::unique_ptr<ByteStreamReader>(), | 162 std::move(create_info), std::unique_ptr<ByteStreamReader>(), |
| 132 DownloadUrlParameters::OnStartedCallback()); | 163 DownloadUrlParameters::OnStartedCallback()); |
| 133 } | 164 } |
| 134 | 165 |
| 135 void VerifyWorker(int64_t offset, int64_t length) const { | 166 void VerifyWorker(int64_t offset, int64_t length) const { |
| 136 EXPECT_TRUE(job_->workers_.find(offset) != job_->workers_.end()); | 167 EXPECT_TRUE(job_->workers_.find(offset) != job_->workers_.end()); |
| 137 EXPECT_EQ(offset, job_->workers_[offset]->offset()); | 168 EXPECT_EQ(offset, job_->workers_[offset]->offset()); |
| 138 EXPECT_EQ(length, job_->workers_[offset]->length()); | 169 EXPECT_EQ(length, job_->workers_[offset]->length()); |
| 139 } | 170 } |
| 140 | 171 |
| 172 void OnFileInitialized(DownloadInterruptReason result) { |
| 173 file_initialized_ = true; |
| 174 } |
| 175 |
| 141 content::TestBrowserThreadBundle browser_threads_; | 176 content::TestBrowserThreadBundle browser_threads_; |
| 142 std::unique_ptr<DownloadItemImplDelegate> item_delegate_; | 177 std::unique_ptr<DownloadItemImplDelegate> item_delegate_; |
| 143 std::unique_ptr<MockDownloadItemImpl> download_item_; | 178 std::unique_ptr<MockDownloadItemImpl> download_item_; |
| 144 std::unique_ptr<ParallelDownloadJobForTest> job_; | 179 std::unique_ptr<ParallelDownloadJobForTest> job_; |
| 180 bool file_initialized_; |
| 145 // Request handle for the original request. | 181 // Request handle for the original request. |
| 146 MockDownloadRequestHandle* mock_request_handle_; | 182 MockDownloadRequestHandle* mock_request_handle_; |
| 147 }; | 183 }; |
| 148 | 184 |
| 149 // Test if parallel requests can be built correctly for a new download without | 185 // Test if parallel requests can be built correctly for a new download without |
| 150 // existing slices. | 186 // existing slices. |
| 151 TEST_F(ParallelDownloadJobTest, CreateNewDownloadRequestsWithoutSlices) { | 187 TEST_F(ParallelDownloadJobTest, CreateNewDownloadRequestsWithoutSlices) { |
| 152 // Totally 2 requests for 100 bytes. | 188 // Totally 2 requests for 100 bytes. |
| 153 // Original request: Range:0-49, for 50 bytes. | 189 // Original request: Range:0-49, for 50 bytes. |
| 154 // Task 1: Range:50-, for 50 bytes. | 190 // Task 1: Range:50-, for 50 bytes. |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 // finish downloading soon. | 349 // finish downloading soon. |
| 314 TEST_F(ParallelDownloadJobTest, RemainingContentWillFinishSoon) { | 350 TEST_F(ParallelDownloadJobTest, RemainingContentWillFinishSoon) { |
| 315 DownloadItem::ReceivedSlices slices = {DownloadItem::ReceivedSlice(0, 99)}; | 351 DownloadItem::ReceivedSlices slices = {DownloadItem::ReceivedSlice(0, 99)}; |
| 316 CreateParallelJob(99, 1, slices, 3, 1, 10); | 352 CreateParallelJob(99, 1, slices, 3, 1, 10); |
| 317 BuildParallelRequests(); | 353 BuildParallelRequests(); |
| 318 EXPECT_EQ(0, static_cast<int>(job_->workers().size())); | 354 EXPECT_EQ(0, static_cast<int>(job_->workers().size())); |
| 319 | 355 |
| 320 DestroyParallelJob(); | 356 DestroyParallelJob(); |
| 321 } | 357 } |
| 322 | 358 |
| 359 // Test that parallel request is not created until download file is initialized. |
| 360 TEST_F(ParallelDownloadJobTest, ParallelRequestNotCreatedUntilFileInitialized) { |
| 361 auto save_info = base::MakeUnique<DownloadSaveInfo>(); |
| 362 StrictMock<MockByteStreamReader>* input_stream = |
| 363 new StrictMock<MockByteStreamReader>(); |
| 364 auto observer = |
| 365 base::MakeUnique<StrictMock<MockDownloadDestinationObserver>>(); |
| 366 base::WeakPtrFactory<DownloadDestinationObserver> observer_factory( |
| 367 observer.get()); |
| 368 auto download_file = base::MakeUnique<DownloadFileImpl>( |
| 369 std::move(save_info), base::FilePath(), |
| 370 std::unique_ptr<ByteStreamReader>(input_stream), net::NetLogWithSource(), |
| 371 observer_factory.GetWeakPtr()); |
| 372 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 2, 0, 0); |
| 373 job_->Start(download_file.get(), |
| 374 base::Bind(&ParallelDownloadJobTest::OnFileInitialized, |
| 375 base::Unretained(this)), |
| 376 DownloadItem::ReceivedSlices()); |
| 377 EXPECT_FALSE(file_initialized_); |
| 378 EXPECT_EQ(0u, job_->workers().size()); |
| 379 EXPECT_CALL(*input_stream, RegisterCallback(_)); |
| 380 EXPECT_CALL(*input_stream, Read(_, _)); |
| 381 EXPECT_CALL(*(observer.get()), DestinationUpdate(_, _, _)); |
| 382 base::RunLoop().RunUntilIdle(); |
| 383 EXPECT_TRUE(file_initialized_); |
| 384 EXPECT_EQ(1u, job_->workers().size()); |
| 385 DestroyParallelJob(); |
| 386 } |
| 387 |
| 323 } // namespace content | 388 } // namespace content |
| OLD | NEW |