| 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" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 | 33 |
| 34 } // namespace | 34 } // namespace |
| 35 | 35 |
| 36 class ParallelDownloadJobForTest : public ParallelDownloadJob { | 36 class ParallelDownloadJobForTest : public ParallelDownloadJob { |
| 37 public: | 37 public: |
| 38 ParallelDownloadJobForTest( | 38 ParallelDownloadJobForTest( |
| 39 DownloadItemImpl* download_item, | 39 DownloadItemImpl* download_item, |
| 40 std::unique_ptr<DownloadRequestHandleInterface> request_handle, | 40 std::unique_ptr<DownloadRequestHandleInterface> request_handle, |
| 41 const DownloadCreateInfo& create_info, | 41 const DownloadCreateInfo& create_info, |
| 42 int request_count, | 42 int request_count, |
| 43 int64_t min_slice_size) | 43 int64_t min_slice_size, |
| 44 int min_remaining_time) |
| 44 : ParallelDownloadJob(download_item, | 45 : ParallelDownloadJob(download_item, |
| 45 std::move(request_handle), | 46 std::move(request_handle), |
| 46 create_info), | 47 create_info), |
| 47 request_count_(request_count), | 48 request_count_(request_count), |
| 48 min_slice_size_(min_slice_size) {} | 49 min_slice_size_(min_slice_size), |
| 50 min_remaining_time_(min_remaining_time) {} |
| 49 | 51 |
| 50 void CreateRequest(int64_t offset, int64_t length) override { | 52 void CreateRequest(int64_t offset, int64_t length) override { |
| 51 std::unique_ptr<DownloadWorker> worker = | 53 std::unique_ptr<DownloadWorker> worker = |
| 52 base::MakeUnique<DownloadWorker>(this, offset, length); | 54 base::MakeUnique<DownloadWorker>(this, offset, length); |
| 53 | 55 |
| 54 DCHECK(workers_.find(offset) == workers_.end()); | 56 DCHECK(workers_.find(offset) == workers_.end()); |
| 55 workers_[offset] = std::move(worker); | 57 workers_[offset] = std::move(worker); |
| 56 } | 58 } |
| 57 | 59 |
| 58 ParallelDownloadJob::WorkerMap& workers() { return workers_; } | 60 ParallelDownloadJob::WorkerMap& workers() { return workers_; } |
| 59 | 61 |
| 60 int GetParallelRequestCount() const override { return request_count_; } | 62 int GetParallelRequestCount() const override { return request_count_; } |
| 61 int64_t GetMinSliceSize() const override { return min_slice_size_; } | 63 int64_t GetMinSliceSize() const override { return min_slice_size_; } |
| 64 int GetMinRemainingTimeInSeconds() const override { |
| 65 return min_remaining_time_; |
| 66 } |
| 62 | 67 |
| 63 void OnByteStreamReady( | 68 void OnByteStreamReady( |
| 64 DownloadWorker* worker, | 69 DownloadWorker* worker, |
| 65 std::unique_ptr<ByteStreamReader> stream_reader) override { | 70 std::unique_ptr<ByteStreamReader> stream_reader) override { |
| 66 CountOnByteStreamReady(); | 71 CountOnByteStreamReady(); |
| 67 } | 72 } |
| 68 | 73 |
| 69 MOCK_METHOD0(CountOnByteStreamReady, void()); | 74 MOCK_METHOD0(CountOnByteStreamReady, void()); |
| 70 | 75 |
| 71 private: | 76 private: |
| 72 int request_count_; | 77 int request_count_; |
| 73 int min_slice_size_; | 78 int min_slice_size_; |
| 79 int min_remaining_time_; |
| 74 DISALLOW_COPY_AND_ASSIGN(ParallelDownloadJobForTest); | 80 DISALLOW_COPY_AND_ASSIGN(ParallelDownloadJobForTest); |
| 75 }; | 81 }; |
| 76 | 82 |
| 77 class ParallelDownloadJobTest : public testing::Test { | 83 class ParallelDownloadJobTest : public testing::Test { |
| 78 public: | 84 public: |
| 79 void CreateParallelJob(int64_t initial_request_offset, | 85 void CreateParallelJob(int64_t initial_request_offset, |
| 80 int64_t content_length, | 86 int64_t content_length, |
| 81 const DownloadItem::ReceivedSlices& slices, | 87 const DownloadItem::ReceivedSlices& slices, |
| 82 int request_count, | 88 int request_count, |
| 83 int64_t min_slice_size) { | 89 int64_t min_slice_size, |
| 90 int min_remaining_time) { |
| 84 item_delegate_ = base::MakeUnique<DownloadItemImplDelegate>(); | 91 item_delegate_ = base::MakeUnique<DownloadItemImplDelegate>(); |
| 85 download_item_ = base::MakeUnique<NiceMock<MockDownloadItemImpl>>( | 92 download_item_ = base::MakeUnique<NiceMock<MockDownloadItemImpl>>( |
| 86 item_delegate_.get(), slices); | 93 item_delegate_.get(), slices); |
| 94 EXPECT_CALL(*download_item_, GetTotalBytes()) |
| 95 .WillRepeatedly( |
| 96 testing::Return(initial_request_offset + content_length)); |
| 97 EXPECT_CALL(*download_item_, GetReceivedBytes()) |
| 98 .WillRepeatedly(testing::Return(initial_request_offset)); |
| 99 |
| 87 DownloadCreateInfo info; | 100 DownloadCreateInfo info; |
| 88 info.offset = initial_request_offset; | 101 info.offset = initial_request_offset; |
| 89 info.total_bytes = content_length; | 102 info.total_bytes = content_length; |
| 90 std::unique_ptr<MockDownloadRequestHandle> request_handle = | 103 std::unique_ptr<MockDownloadRequestHandle> request_handle = |
| 91 base::MakeUnique<MockDownloadRequestHandle>(); | 104 base::MakeUnique<MockDownloadRequestHandle>(); |
| 92 mock_request_handle_ = request_handle.get(); | 105 mock_request_handle_ = request_handle.get(); |
| 93 job_ = base::MakeUnique<ParallelDownloadJobForTest>( | 106 job_ = base::MakeUnique<ParallelDownloadJobForTest>( |
| 94 download_item_.get(), std::move(request_handle), info, request_count, | 107 download_item_.get(), std::move(request_handle), info, request_count, |
| 95 min_slice_size); | 108 min_slice_size, min_remaining_time); |
| 96 } | 109 } |
| 97 | 110 |
| 98 void DestroyParallelJob() { | 111 void DestroyParallelJob() { |
| 99 job_.reset(); | 112 job_.reset(); |
| 100 download_item_.reset(); | 113 download_item_.reset(); |
| 101 item_delegate_.reset(); | 114 item_delegate_.reset(); |
| 102 mock_request_handle_ = nullptr; | 115 mock_request_handle_ = nullptr; |
| 103 } | 116 } |
| 104 | 117 |
| 105 void BuildParallelRequests() { job_->BuildParallelRequests(); } | 118 void BuildParallelRequests() { job_->BuildParallelRequests(); } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 132 // Request handle for the original request. | 145 // Request handle for the original request. |
| 133 MockDownloadRequestHandle* mock_request_handle_; | 146 MockDownloadRequestHandle* mock_request_handle_; |
| 134 }; | 147 }; |
| 135 | 148 |
| 136 // Test if parallel requests can be built correctly for a new download without | 149 // Test if parallel requests can be built correctly for a new download without |
| 137 // existing slices. | 150 // existing slices. |
| 138 TEST_F(ParallelDownloadJobTest, CreateNewDownloadRequestsWithoutSlices) { | 151 TEST_F(ParallelDownloadJobTest, CreateNewDownloadRequestsWithoutSlices) { |
| 139 // Totally 2 requests for 100 bytes. | 152 // Totally 2 requests for 100 bytes. |
| 140 // Original request: Range:0-49, for 50 bytes. | 153 // Original request: Range:0-49, for 50 bytes. |
| 141 // Task 1: Range:50-, for 50 bytes. | 154 // Task 1: Range:50-, for 50 bytes. |
| 142 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 2, 1); | 155 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 2, 1, 10); |
| 143 BuildParallelRequests(); | 156 BuildParallelRequests(); |
| 144 EXPECT_EQ(1, static_cast<int>(job_->workers().size())); | 157 EXPECT_EQ(1, static_cast<int>(job_->workers().size())); |
| 145 VerifyWorker(50, 0); | 158 VerifyWorker(50, 0); |
| 146 DestroyParallelJob(); | 159 DestroyParallelJob(); |
| 147 | 160 |
| 148 // Totally 3 requests for 100 bytes. | 161 // Totally 3 requests for 100 bytes. |
| 149 // Original request: Range:0-32, for 33 bytes. | 162 // Original request: Range:0-32, for 33 bytes. |
| 150 // Task 1: Range:33-65, for 33 bytes. | 163 // Task 1: Range:33-65, for 33 bytes. |
| 151 // Task 2: Range:66-, for 34 bytes. | 164 // Task 2: Range:66-, for 34 bytes. |
| 152 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 3, 1); | 165 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 3, 1, 10); |
| 153 BuildParallelRequests(); | 166 BuildParallelRequests(); |
| 154 EXPECT_EQ(2, static_cast<int>(job_->workers().size())); | 167 EXPECT_EQ(2, static_cast<int>(job_->workers().size())); |
| 155 VerifyWorker(33, 33); | 168 VerifyWorker(33, 33); |
| 156 VerifyWorker(66, 0); | 169 VerifyWorker(66, 0); |
| 157 DestroyParallelJob(); | 170 DestroyParallelJob(); |
| 158 | 171 |
| 159 // Less than 2 requests, do nothing. | 172 // Less than 2 requests, do nothing. |
| 160 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 1, 1); | 173 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 1, 1, 10); |
| 161 BuildParallelRequests(); | 174 BuildParallelRequests(); |
| 162 EXPECT_TRUE(job_->workers().empty()); | 175 EXPECT_TRUE(job_->workers().empty()); |
| 163 DestroyParallelJob(); | 176 DestroyParallelJob(); |
| 164 | 177 |
| 165 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 0, 1); | 178 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 0, 1, 10); |
| 166 BuildParallelRequests(); | 179 BuildParallelRequests(); |
| 167 EXPECT_TRUE(job_->workers().empty()); | 180 EXPECT_TRUE(job_->workers().empty()); |
| 168 DestroyParallelJob(); | 181 DestroyParallelJob(); |
| 169 | 182 |
| 170 // Content-length is 0, do nothing. | 183 // Content-length is 0, do nothing. |
| 171 CreateParallelJob(0, 0, DownloadItem::ReceivedSlices(), 3, 1); | 184 CreateParallelJob(0, 0, DownloadItem::ReceivedSlices(), 3, 1, 10); |
| 172 BuildParallelRequests(); | 185 BuildParallelRequests(); |
| 173 EXPECT_TRUE(job_->workers().empty()); | 186 EXPECT_TRUE(job_->workers().empty()); |
| 174 DestroyParallelJob(); | 187 DestroyParallelJob(); |
| 175 } | 188 } |
| 176 | 189 |
| 177 TEST_F(ParallelDownloadJobTest, CreateNewDownloadRequestsWithSlices) { | 190 TEST_F(ParallelDownloadJobTest, CreateNewDownloadRequestsWithSlices) { |
| 178 // File size: 100 bytes. | 191 // File size: 100 bytes. |
| 179 // Received slices: [0, 17] | 192 // Received slices: [0, 17] |
| 180 // Original request: Range:12-. Content-length: 88. | 193 // Original request: Range:12-. Content-length: 88. |
| 181 // Totally 3 requests for 83 bytes. | 194 // Totally 3 requests for 83 bytes. |
| 182 // Original request: Range:12-43. | 195 // Original request: Range:12-43. |
| 183 // Task 1: Range:44-70, for 27 bytes. | 196 // Task 1: Range:44-70, for 27 bytes. |
| 184 // Task 2: Range:71-, for 29 bytes. | 197 // Task 2: Range:71-, for 29 bytes. |
| 185 DownloadItem::ReceivedSlices slices = {DownloadItem::ReceivedSlice(0, 17)}; | 198 DownloadItem::ReceivedSlices slices = {DownloadItem::ReceivedSlice(0, 17)}; |
| 186 CreateParallelJob(12, 88, slices, 3, 1); | 199 CreateParallelJob(12, 88, slices, 3, 1, 10); |
| 187 BuildParallelRequests(); | 200 BuildParallelRequests(); |
| 188 EXPECT_EQ(2, static_cast<int>(job_->workers().size())); | 201 EXPECT_EQ(2, static_cast<int>(job_->workers().size())); |
| 189 VerifyWorker(44, 27); | 202 VerifyWorker(44, 27); |
| 190 VerifyWorker(71, 0); | 203 VerifyWorker(71, 0); |
| 191 DestroyParallelJob(); | 204 DestroyParallelJob(); |
| 192 | 205 |
| 193 // File size: 100 bytes. | 206 // File size: 100 bytes. |
| 194 // Received slices: [0, 98], Range:0-97. | 207 // Received slices: [0, 60], Range:0-59. |
| 195 // Original request: Range:98-. Content-length: 2. | 208 // Original request: Range:60-. Content-length: 40. |
| 196 // 2 bytes left for 4 requests. Only 1 additional request. | 209 // 40 bytes left for 4 requests. Only 1 additional request. |
| 197 // Original request: Range:98-99, for 1 bytes. | 210 // Original request: Range:60-79, for 20 bytes. |
| 198 // Task 1: Range:99-, for 1 bytes. | 211 // Task 1: Range:80-, for 20 bytes. |
| 199 slices = {DownloadItem::ReceivedSlice(0, 98)}; | 212 slices = {DownloadItem::ReceivedSlice(0, 60)}; |
| 200 CreateParallelJob(98, 2, slices, 4, 1); | 213 CreateParallelJob(60, 40, slices, 4, 20, 10); |
| 201 BuildParallelRequests(); | 214 BuildParallelRequests(); |
| 202 EXPECT_EQ(1, static_cast<int>(job_->workers().size())); | 215 EXPECT_EQ(1, static_cast<int>(job_->workers().size())); |
| 203 VerifyWorker(99, 0); | 216 VerifyWorker(80, 0); |
| 204 DestroyParallelJob(); | 217 DestroyParallelJob(); |
| 205 | 218 |
| 206 // Content-Length is 0, no additional requests. | 219 // Content-Length is 0, no additional requests. |
| 207 slices = {DownloadItem::ReceivedSlice(0, 100)}; | 220 slices = {DownloadItem::ReceivedSlice(0, 100)}; |
| 208 CreateParallelJob(100, 0, slices, 3, 1); | 221 CreateParallelJob(100, 0, slices, 3, 1, 10); |
| 209 BuildParallelRequests(); | 222 BuildParallelRequests(); |
| 210 EXPECT_TRUE(job_->workers().empty()); | 223 EXPECT_TRUE(job_->workers().empty()); |
| 211 DestroyParallelJob(); | 224 DestroyParallelJob(); |
| 212 | 225 |
| 213 // File size: 100 bytes. | 226 // File size: 100 bytes. |
| 214 // Original request: Range:0-. Content-length: 12(Incorrect server header). | 227 // Original request: Range:0-. Content-length: 12(Incorrect server header). |
| 215 // The request count is 2, however the file contains 3 holes, and we don't | 228 // The request count is 2, however the file contains 3 holes, and we don't |
| 216 // know if the last slice is completed, so there should be 3 requests in | 229 // know if the last slice is completed, so there should be 3 requests in |
| 217 // parallel and the last request is an out-of-range request. | 230 // parallel and the last request is an out-of-range request. |
| 218 slices = { | 231 slices = { |
| 219 DownloadItem::ReceivedSlice(10, 10), DownloadItem::ReceivedSlice(20, 10), | 232 DownloadItem::ReceivedSlice(10, 10), DownloadItem::ReceivedSlice(20, 10), |
| 220 DownloadItem::ReceivedSlice(40, 10), DownloadItem::ReceivedSlice(90, 10)}; | 233 DownloadItem::ReceivedSlice(40, 10), DownloadItem::ReceivedSlice(90, 10)}; |
| 221 CreateParallelJob(0, 12, slices, 2, 1); | 234 CreateParallelJob(0, 12, slices, 2, 1, 10); |
| 222 BuildParallelRequests(); | 235 BuildParallelRequests(); |
| 223 EXPECT_EQ(3, static_cast<int>(job_->workers().size())); | 236 EXPECT_EQ(3, static_cast<int>(job_->workers().size())); |
| 224 VerifyWorker(30, 10); | 237 VerifyWorker(30, 10); |
| 225 VerifyWorker(50, 40); | 238 VerifyWorker(50, 40); |
| 226 VerifyWorker(100, 0); | 239 VerifyWorker(100, 0); |
| 227 DestroyParallelJob(); | 240 DestroyParallelJob(); |
| 228 } | 241 } |
| 229 | 242 |
| 230 // Pause, cancel, resume can be called before or after the worker establish | 243 // Pause, cancel, resume can be called before or after the worker establish |
| 231 // the byte stream. | 244 // the byte stream. |
| 232 // These tests ensure the states consistency between the job and workers. | 245 // These tests ensure the states consistency between the job and workers. |
| 233 | 246 |
| 234 // Ensure cancel before building the requests will result in no requests are | 247 // Ensure cancel before building the requests will result in no requests are |
| 235 // built. | 248 // built. |
| 236 TEST_F(ParallelDownloadJobTest, EarlyCancelBeforeBuildRequests) { | 249 TEST_F(ParallelDownloadJobTest, EarlyCancelBeforeBuildRequests) { |
| 237 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 2, 1); | 250 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 2, 1, 10); |
| 238 EXPECT_CALL(*mock_request_handle_, CancelRequest()); | 251 EXPECT_CALL(*mock_request_handle_, CancelRequest()); |
| 239 | 252 |
| 240 // Job is canceled before building parallel requests. | 253 // Job is canceled before building parallel requests. |
| 241 job_->Cancel(true); | 254 job_->Cancel(true); |
| 242 EXPECT_TRUE(IsJobCanceled()); | 255 EXPECT_TRUE(IsJobCanceled()); |
| 243 | 256 |
| 244 BuildParallelRequests(); | 257 BuildParallelRequests(); |
| 245 EXPECT_TRUE(job_->workers().empty()); | 258 EXPECT_TRUE(job_->workers().empty()); |
| 246 | 259 |
| 247 DestroyParallelJob(); | 260 DestroyParallelJob(); |
| 248 } | 261 } |
| 249 | 262 |
| 250 // Ensure cancel before adding the byte stream will result in workers being | 263 // Ensure cancel before adding the byte stream will result in workers being |
| 251 // canceled. | 264 // canceled. |
| 252 TEST_F(ParallelDownloadJobTest, EarlyCancelBeforeByteStreamReady) { | 265 TEST_F(ParallelDownloadJobTest, EarlyCancelBeforeByteStreamReady) { |
| 253 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 2, 1); | 266 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 2, 1, 10); |
| 254 EXPECT_CALL(*mock_request_handle_, CancelRequest()); | 267 EXPECT_CALL(*mock_request_handle_, CancelRequest()); |
| 255 | 268 |
| 256 BuildParallelRequests(); | 269 BuildParallelRequests(); |
| 257 VerifyWorker(50, 0); | 270 VerifyWorker(50, 0); |
| 258 | 271 |
| 259 // Job is canceled after building parallel requests and before byte streams | 272 // Job is canceled after building parallel requests and before byte streams |
| 260 // are added to the file sink. | 273 // are added to the file sink. |
| 261 job_->Cancel(true); | 274 job_->Cancel(true); |
| 262 EXPECT_TRUE(IsJobCanceled()); | 275 EXPECT_TRUE(IsJobCanceled()); |
| 263 | 276 |
| 264 for (auto& worker : job_->workers()) { | 277 for (auto& worker : job_->workers()) { |
| 265 std::unique_ptr<MockDownloadRequestHandle> mock_handle = | 278 std::unique_ptr<MockDownloadRequestHandle> mock_handle = |
| 266 base::MakeUnique<MockDownloadRequestHandle>(); | 279 base::MakeUnique<MockDownloadRequestHandle>(); |
| 267 EXPECT_CALL(*mock_handle.get(), CancelRequest()); | 280 EXPECT_CALL(*mock_handle.get(), CancelRequest()); |
| 268 MakeWorkerReady(worker.second.get(), std::move(mock_handle)); | 281 MakeWorkerReady(worker.second.get(), std::move(mock_handle)); |
| 269 } | 282 } |
| 270 | 283 |
| 271 DestroyParallelJob(); | 284 DestroyParallelJob(); |
| 272 } | 285 } |
| 273 | 286 |
| 274 // Ensure pause before adding the byte stream will result in workers being | 287 // Ensure pause before adding the byte stream will result in workers being |
| 275 // paused. | 288 // paused. |
| 276 TEST_F(ParallelDownloadJobTest, EarlyPauseBeforeByteStreamReady) { | 289 TEST_F(ParallelDownloadJobTest, EarlyPauseBeforeByteStreamReady) { |
| 277 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 2, 1); | 290 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 2, 1, 10); |
| 278 EXPECT_CALL(*mock_request_handle_, PauseRequest()); | 291 EXPECT_CALL(*mock_request_handle_, PauseRequest()); |
| 279 | 292 |
| 280 BuildParallelRequests(); | 293 BuildParallelRequests(); |
| 281 VerifyWorker(50, 0); | 294 VerifyWorker(50, 0); |
| 282 | 295 |
| 283 // Job is paused after building parallel requests and before adding the byte | 296 // Job is paused after building parallel requests and before adding the byte |
| 284 // stream to the file sink. | 297 // stream to the file sink. |
| 285 job_->Pause(); | 298 job_->Pause(); |
| 286 EXPECT_TRUE(job_->is_paused()); | 299 EXPECT_TRUE(job_->is_paused()); |
| 287 | 300 |
| 288 for (auto& worker : job_->workers()) { | 301 for (auto& worker : job_->workers()) { |
| 289 EXPECT_CALL(*job_.get(), CountOnByteStreamReady()); | 302 EXPECT_CALL(*job_.get(), CountOnByteStreamReady()); |
| 290 std::unique_ptr<MockDownloadRequestHandle> mock_handle = | 303 std::unique_ptr<MockDownloadRequestHandle> mock_handle = |
| 291 base::MakeUnique<MockDownloadRequestHandle>(); | 304 base::MakeUnique<MockDownloadRequestHandle>(); |
| 292 EXPECT_CALL(*mock_handle.get(), PauseRequest()); | 305 EXPECT_CALL(*mock_handle.get(), PauseRequest()); |
| 293 MakeWorkerReady(worker.second.get(), std::move(mock_handle)); | 306 MakeWorkerReady(worker.second.get(), std::move(mock_handle)); |
| 294 } | 307 } |
| 295 | 308 |
| 296 DestroyParallelJob(); | 309 DestroyParallelJob(); |
| 297 } | 310 } |
| 298 | 311 |
| 312 // Test that parallel request is not created if the remaining content can be |
| 313 // finish downloading soon. |
| 314 TEST_F(ParallelDownloadJobTest, RemainingContentWillFinishSoon) { |
| 315 DownloadItem::ReceivedSlices slices = {DownloadItem::ReceivedSlice(0, 99)}; |
| 316 CreateParallelJob(99, 1, slices, 3, 1, 10); |
| 317 BuildParallelRequests(); |
| 318 EXPECT_EQ(0, static_cast<int>(job_->workers().size())); |
| 319 |
| 320 DestroyParallelJob(); |
| 321 } |
| 322 |
| 299 } // namespace content | 323 } // namespace content |
| OLD | NEW |