| 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 "content/browser/download/download_item_impl_delegate.h" | 11 #include "content/browser/download/download_item_impl_delegate.h" |
| 12 #include "content/browser/download/mock_download_item_impl.h" | 12 #include "content/browser/download/mock_download_item_impl.h" |
| 13 #include "content/browser/download/parallel_download_utils.h" |
| 13 #include "content/public/test/test_browser_thread_bundle.h" | 14 #include "content/public/test/test_browser_thread_bundle.h" |
| 14 #include "testing/gmock/include/gmock/gmock.h" | 15 #include "testing/gmock/include/gmock/gmock.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 16 | 17 |
| 17 using ::testing::NiceMock; | 18 using ::testing::NiceMock; |
| 18 | 19 |
| 19 namespace content { | 20 namespace content { |
| 20 | 21 |
| 21 namespace { | 22 namespace { |
| 22 | 23 |
| 23 class MockDownloadRequestHandle : public DownloadRequestHandleInterface { | 24 class MockDownloadRequestHandle : public DownloadRequestHandleInterface { |
| 24 public: | 25 public: |
| 25 MOCK_CONST_METHOD0(GetWebContents, WebContents*()); | 26 MOCK_CONST_METHOD0(GetWebContents, WebContents*()); |
| 26 MOCK_CONST_METHOD0(GetDownloadManager, DownloadManager*()); | 27 MOCK_CONST_METHOD0(GetDownloadManager, DownloadManager*()); |
| 27 MOCK_CONST_METHOD0(PauseRequest, void()); | 28 MOCK_CONST_METHOD0(PauseRequest, void()); |
| 28 MOCK_CONST_METHOD0(ResumeRequest, void()); | 29 MOCK_CONST_METHOD0(ResumeRequest, void()); |
| 29 MOCK_CONST_METHOD0(CancelRequest, void()); | 30 MOCK_CONST_METHOD0(CancelRequest, void()); |
| 30 MOCK_CONST_METHOD0(DebugString, std::string()); | 31 MOCK_CONST_METHOD0(DebugString, std::string()); |
| 31 }; | 32 }; |
| 32 | 33 |
| 33 } // namespace | 34 } // namespace |
| 34 | 35 |
| 35 class ParallelDownloadJobForTest : public ParallelDownloadJob { | 36 class ParallelDownloadJobForTest : public ParallelDownloadJob { |
| 36 public: | 37 public: |
| 37 ParallelDownloadJobForTest( | 38 ParallelDownloadJobForTest( |
| 38 DownloadItemImpl* download_item, | 39 DownloadItemImpl* download_item, |
| 39 std::unique_ptr<DownloadRequestHandleInterface> request_handle, | 40 std::unique_ptr<DownloadRequestHandleInterface> request_handle, |
| 40 const DownloadCreateInfo& create_info) | 41 const DownloadCreateInfo& create_info, |
| 41 : ParallelDownloadJob( | 42 int request_count) |
| 42 download_item, std::move(request_handle), create_info) {} | 43 : ParallelDownloadJob(download_item, |
| 44 std::move(request_handle), |
| 45 create_info), |
| 46 request_count_(request_count) {} |
| 43 | 47 |
| 44 void CreateRequest(int64_t offset, int64_t length) override { | 48 void CreateRequest(int64_t offset, int64_t length) override { |
| 45 fake_tasks_.push_back(std::pair<int64_t, int64_t>(offset, length)); | 49 fake_tasks_.push_back(std::pair<int64_t, int64_t>(offset, length)); |
| 46 } | 50 } |
| 47 | 51 |
| 52 int GetParallelRequestCount() const override { return request_count_; } |
| 53 |
| 48 std::vector<std::pair<int64_t, int64_t>> fake_tasks_; | 54 std::vector<std::pair<int64_t, int64_t>> fake_tasks_; |
| 49 | 55 |
| 50 private: | 56 private: |
| 57 int request_count_; |
| 51 DISALLOW_COPY_AND_ASSIGN(ParallelDownloadJobForTest); | 58 DISALLOW_COPY_AND_ASSIGN(ParallelDownloadJobForTest); |
| 52 }; | 59 }; |
| 53 | 60 |
| 54 class ParallelDownloadJobTest : public testing::Test { | 61 class ParallelDownloadJobTest : public testing::Test { |
| 55 public: | 62 public: |
| 56 void SetUp() override { | 63 void CreateParallelJob(int64_t offset, |
| 64 int64_t content_length, |
| 65 const DownloadItem::ReceivedSlices& slices, |
| 66 int request_count) { |
| 57 item_delegate_ = base::MakeUnique<DownloadItemImplDelegate>(); | 67 item_delegate_ = base::MakeUnique<DownloadItemImplDelegate>(); |
| 58 download_item_ = | 68 download_item_ = base::MakeUnique<NiceMock<MockDownloadItemImpl>>( |
| 59 base::MakeUnique<NiceMock<MockDownloadItemImpl>>(item_delegate_.get()); | 69 item_delegate_.get(), slices); |
| 70 DownloadCreateInfo info; |
| 71 info.offset = offset; |
| 72 info.total_bytes = content_length; |
| 60 job_ = base::MakeUnique<ParallelDownloadJobForTest>( | 73 job_ = base::MakeUnique<ParallelDownloadJobForTest>( |
| 61 download_item_.get(), base::MakeUnique<MockDownloadRequestHandle>(), | 74 download_item_.get(), base::MakeUnique<MockDownloadRequestHandle>(), |
| 62 DownloadCreateInfo()); | 75 info, request_count); |
| 63 } | 76 } |
| 64 | 77 |
| 65 void CreateNewDownloadRequests(int64_t total_bytes, | 78 void DestroyParallelJob() { |
| 66 int64_t bytes_received, | 79 job_.reset(); |
| 67 int request_num) { | 80 download_item_.reset(); |
| 68 job_->ForkRequestsForNewDownload(bytes_received, total_bytes, request_num); | 81 item_delegate_.reset(); |
| 69 } | 82 } |
| 70 | 83 |
| 84 void BuildParallelRequests() { job_->BuildParallelRequests(); } |
| 85 |
| 71 content::TestBrowserThreadBundle browser_threads_; | 86 content::TestBrowserThreadBundle browser_threads_; |
| 72 std::unique_ptr<DownloadItemImplDelegate> item_delegate_; | 87 std::unique_ptr<DownloadItemImplDelegate> item_delegate_; |
| 73 std::unique_ptr<MockDownloadItemImpl> download_item_; | 88 std::unique_ptr<MockDownloadItemImpl> download_item_; |
| 74 std::unique_ptr<ParallelDownloadJobForTest> job_; | 89 std::unique_ptr<ParallelDownloadJobForTest> job_; |
| 75 }; | 90 }; |
| 76 | 91 |
| 77 // Test if sub tasks are created correctly. | 92 // Test if parallel requests can be built correctly for a new download. |
| 78 TEST_F(ParallelDownloadJobTest, CreateNewDownloadRequests) { | 93 TEST_F(ParallelDownloadJobTest, CreateNewDownloadRequests) { |
| 79 EXPECT_TRUE(job_->fake_tasks_.empty()); | |
| 80 | |
| 81 // Totally 2 requests for 100 bytes. | 94 // Totally 2 requests for 100 bytes. |
| 82 // Original request: Range:0-49, for 50 bytes. | 95 // Original request: Range:0-49, for 50 bytes. |
| 83 // Task 1: Range:50-99, for 50 bytes. | 96 // Task 1: Range:50-, for 50 bytes. |
| 84 CreateNewDownloadRequests(100, 0, 2); | 97 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 2); |
| 98 BuildParallelRequests(); |
| 85 EXPECT_EQ(1, static_cast<int>(job_->fake_tasks_.size())); | 99 EXPECT_EQ(1, static_cast<int>(job_->fake_tasks_.size())); |
| 86 EXPECT_EQ(50, job_->fake_tasks_[0].first); | 100 EXPECT_EQ(50, job_->fake_tasks_[0].first); |
| 87 EXPECT_EQ(50, job_->fake_tasks_[0].second); | 101 EXPECT_EQ(0, job_->fake_tasks_[0].second); |
| 88 job_->fake_tasks_.clear(); | 102 job_->fake_tasks_.clear(); |
| 103 DestroyParallelJob(); |
| 89 | 104 |
| 90 // Totally 3 requests for 100 bytes. | 105 // Totally 3 requests for 100 bytes. |
| 91 // Original request: Range:0-32, for 33 bytes. | 106 // Original request: Range:0-32, for 33 bytes. |
| 92 // Task 1: Range:33-65, for 33 bytes. | 107 // Task 1: Range:33-65, for 33 bytes. |
| 93 // Task 2: Range:66-99, for 34 bytes. | 108 // Task 2: Range:66-, for 34 bytes. |
| 94 CreateNewDownloadRequests(100, 0, 3); | 109 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 3); |
| 110 BuildParallelRequests(); |
| 95 EXPECT_EQ(2, static_cast<int>(job_->fake_tasks_.size())); | 111 EXPECT_EQ(2, static_cast<int>(job_->fake_tasks_.size())); |
| 96 EXPECT_EQ(33, job_->fake_tasks_[0].first); | 112 EXPECT_EQ(33, job_->fake_tasks_[0].first); |
| 97 EXPECT_EQ(33, job_->fake_tasks_[0].second); | 113 EXPECT_EQ(33, job_->fake_tasks_[0].second); |
| 98 EXPECT_EQ(66, job_->fake_tasks_[1].first); | 114 EXPECT_EQ(66, job_->fake_tasks_[1].first); |
| 99 EXPECT_EQ(34, job_->fake_tasks_[1].second); | 115 EXPECT_EQ(0, job_->fake_tasks_[1].second); |
| 100 job_->fake_tasks_.clear(); | 116 job_->fake_tasks_.clear(); |
| 117 DestroyParallelJob(); |
| 101 | 118 |
| 102 // Totally 3 requests for 100 bytes. Start from the 17th byte. | 119 // Totally 3 requests for 100 bytes. Start from the 17th byte. |
| 103 // Original request: Range:17-43, for 27 bytes. | 120 // Original request: Range:17-43, for 27 bytes. |
| 104 // Task 1: Range:44-70, for 27 bytes. | 121 // Task 1: Range:44-70, for 27 bytes. |
| 105 // Task 2: Range:71-99, for 29 bytes. | 122 // Task 2: Range:71-99, for 29 bytes. |
| 106 CreateNewDownloadRequests(100, 17, 3); | 123 CreateParallelJob(17, 100, DownloadItem::ReceivedSlices(), 3); |
| 124 BuildParallelRequests(); |
| 107 EXPECT_EQ(2, static_cast<int>(job_->fake_tasks_.size())); | 125 EXPECT_EQ(2, static_cast<int>(job_->fake_tasks_.size())); |
| 108 EXPECT_EQ(44, job_->fake_tasks_[0].first); | 126 EXPECT_EQ(44, job_->fake_tasks_[0].first); |
| 109 EXPECT_EQ(27, job_->fake_tasks_[0].second); | 127 EXPECT_EQ(27, job_->fake_tasks_[0].second); |
| 110 EXPECT_EQ(71, job_->fake_tasks_[1].first); | 128 EXPECT_EQ(71, job_->fake_tasks_[1].first); |
| 111 EXPECT_EQ(29, job_->fake_tasks_[1].second); | 129 EXPECT_EQ(0, job_->fake_tasks_[1].second); |
| 112 job_->fake_tasks_.clear(); | 130 job_->fake_tasks_.clear(); |
| 131 DestroyParallelJob(); |
| 113 | 132 |
| 114 // Less than 2 requests, do nothing. | 133 // Less than 2 requests, do nothing. |
| 115 CreateNewDownloadRequests(100, 17, 1); | 134 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 1); |
| 135 BuildParallelRequests(); |
| 116 EXPECT_TRUE(job_->fake_tasks_.empty()); | 136 EXPECT_TRUE(job_->fake_tasks_.empty()); |
| 117 CreateNewDownloadRequests(100, 17, 0); | 137 DestroyParallelJob(); |
| 138 |
| 139 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 0); |
| 140 BuildParallelRequests(); |
| 118 EXPECT_TRUE(job_->fake_tasks_.empty()); | 141 EXPECT_TRUE(job_->fake_tasks_.empty()); |
| 142 DestroyParallelJob(); |
| 119 | 143 |
| 120 // Received bytes are no less than total bytes, do nothing. | 144 // Received bytes are no less than total bytes, do nothing. |
| 121 CreateNewDownloadRequests(100, 100, 3); | 145 CreateParallelJob(100, 100, DownloadItem::ReceivedSlices(), 3); |
| 146 BuildParallelRequests(); |
| 122 EXPECT_TRUE(job_->fake_tasks_.empty()); | 147 EXPECT_TRUE(job_->fake_tasks_.empty()); |
| 123 CreateNewDownloadRequests(100, 255, 3); | 148 DestroyParallelJob(); |
| 124 EXPECT_TRUE(job_->fake_tasks_.empty()); | |
| 125 | 149 |
| 126 // Edge cases for 0 bytes. | 150 // Edge cases for 0 bytes. |
| 127 CreateNewDownloadRequests(0, 0, 3); | 151 CreateParallelJob(0, 0, DownloadItem::ReceivedSlices(), 3); |
| 152 BuildParallelRequests(); |
| 128 EXPECT_TRUE(job_->fake_tasks_.empty()); | 153 EXPECT_TRUE(job_->fake_tasks_.empty()); |
| 154 DestroyParallelJob(); |
| 129 | 155 |
| 130 // 2 bytes left for 3 additional requests. Only 1 are built. | 156 // 2 bytes left for 3 additional requests. Only 1 are built. |
| 131 // Original request: Range:98-98, for 1 byte. | 157 // Original request: Range:98-98, for 1 byte. |
| 132 // Task 1: Range:99-99, for 1 byte. | 158 // Task 1: Range:99-, for 1 byte. |
| 133 CreateNewDownloadRequests(100, 98, 4); | 159 CreateParallelJob(98, 100, DownloadItem::ReceivedSlices(), 4); |
| 160 BuildParallelRequests(); |
| 134 EXPECT_EQ(1, static_cast<int>(job_->fake_tasks_.size())); | 161 EXPECT_EQ(1, static_cast<int>(job_->fake_tasks_.size())); |
| 135 EXPECT_EQ(99, job_->fake_tasks_[0].first); | 162 EXPECT_EQ(99, job_->fake_tasks_[0].first); |
| 136 EXPECT_EQ(1, job_->fake_tasks_[0].second); | 163 EXPECT_EQ(0, job_->fake_tasks_[0].second); |
| 137 job_->fake_tasks_.clear(); | 164 job_->fake_tasks_.clear(); |
| 165 DestroyParallelJob(); |
| 138 } | 166 } |
| 139 | 167 |
| 140 } // namespace content | 168 } // namespace content |
| OLD | NEW |