Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(583)

Side by Side Diff: content/browser/download/parallel_download_job_unittest.cc

Issue 2767593003: Handle early pause, cancel for parallel requests. (Closed)
Patch Set: Move is_canceled_ to subclass. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/browser/download/parallel_download_job.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 28 matching lines...) Expand all
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 : ParallelDownloadJob(download_item, 43 : ParallelDownloadJob(download_item,
44 std::move(request_handle), 44 std::move(request_handle),
45 create_info), 45 create_info),
46 request_count_(request_count) {} 46 request_count_(request_count) {}
47 47
48 void CreateRequest(int64_t offset, int64_t length) override { 48 void CreateRequest(int64_t offset, int64_t length) override {
49 fake_tasks_.push_back(std::pair<int64_t, int64_t>(offset, length)); 49 std::unique_ptr<DownloadWorker> worker =
50 base::MakeUnique<DownloadWorker>(this, offset, length);
51
52 DCHECK(workers_.find(offset) == workers_.end());
53 workers_[offset] = std::move(worker);
50 } 54 }
51 55
56 ParallelDownloadJob::WorkerMap& workers() { return workers_; }
57
52 int GetParallelRequestCount() const override { return request_count_; } 58 int GetParallelRequestCount() const override { return request_count_; }
53 59
54 std::vector<std::pair<int64_t, int64_t>> fake_tasks_; 60 void OnByteStreamReady(
61 DownloadWorker* worker,
62 std::unique_ptr<ByteStreamReader> stream_reader) override {
63 CountOnByteStreamReady();
64 }
65
66 MOCK_METHOD0(CountOnByteStreamReady, void());
55 67
56 private: 68 private:
57 int request_count_; 69 int request_count_;
58 DISALLOW_COPY_AND_ASSIGN(ParallelDownloadJobForTest); 70 DISALLOW_COPY_AND_ASSIGN(ParallelDownloadJobForTest);
59 }; 71 };
60 72
61 class ParallelDownloadJobTest : public testing::Test { 73 class ParallelDownloadJobTest : public testing::Test {
62 public: 74 public:
63 void CreateParallelJob(int64_t offset, 75 void CreateParallelJob(int64_t offset,
64 int64_t content_length, 76 int64_t content_length,
65 const DownloadItem::ReceivedSlices& slices, 77 const DownloadItem::ReceivedSlices& slices,
66 int request_count) { 78 int request_count) {
67 item_delegate_ = base::MakeUnique<DownloadItemImplDelegate>(); 79 item_delegate_ = base::MakeUnique<DownloadItemImplDelegate>();
68 download_item_ = base::MakeUnique<NiceMock<MockDownloadItemImpl>>( 80 download_item_ = base::MakeUnique<NiceMock<MockDownloadItemImpl>>(
69 item_delegate_.get(), slices); 81 item_delegate_.get(), slices);
70 DownloadCreateInfo info; 82 DownloadCreateInfo info;
71 info.offset = offset; 83 info.offset = offset;
72 info.total_bytes = content_length; 84 info.total_bytes = content_length;
85 std::unique_ptr<MockDownloadRequestHandle> request_handle =
86 base::MakeUnique<MockDownloadRequestHandle>();
87 mock_request_handle_ = request_handle.get();
73 job_ = base::MakeUnique<ParallelDownloadJobForTest>( 88 job_ = base::MakeUnique<ParallelDownloadJobForTest>(
74 download_item_.get(), base::MakeUnique<MockDownloadRequestHandle>(), 89 download_item_.get(), std::move(request_handle), info, request_count);
75 info, request_count);
76 } 90 }
77 91
78 void DestroyParallelJob() { 92 void DestroyParallelJob() {
79 job_.reset(); 93 job_.reset();
80 download_item_.reset(); 94 download_item_.reset();
81 item_delegate_.reset(); 95 item_delegate_.reset();
96 mock_request_handle_ = nullptr;
82 } 97 }
83 98
84 void BuildParallelRequests() { job_->BuildParallelRequests(); } 99 void BuildParallelRequests() { job_->BuildParallelRequests(); }
85 100
101 bool IsJobCanceled() const { return job_->is_canceled_; };
102
103 void MakeWorkerReady(
104 DownloadWorker* worker,
105 std::unique_ptr<MockDownloadRequestHandle> request_handle) {
106 UrlDownloader::Delegate* delegate =
107 static_cast<UrlDownloader::Delegate*>(worker);
108 std::unique_ptr<DownloadCreateInfo> create_info =
109 base::MakeUnique<DownloadCreateInfo>();
110 create_info->request_handle = std::move(request_handle);
111 delegate->OnUrlDownloaderStarted(
112 std::move(create_info), std::unique_ptr<ByteStreamReader>(),
113 DownloadUrlParameters::OnStartedCallback());
114 }
115
116 void VerifyWorker(int64_t offset, int64_t length) const {
117 EXPECT_TRUE(job_->workers_.find(offset) != job_->workers_.end());
118 EXPECT_EQ(offset, job_->workers_[offset]->offset());
119 EXPECT_EQ(length, job_->workers_[offset]->length());
120 }
121
86 content::TestBrowserThreadBundle browser_threads_; 122 content::TestBrowserThreadBundle browser_threads_;
87 std::unique_ptr<DownloadItemImplDelegate> item_delegate_; 123 std::unique_ptr<DownloadItemImplDelegate> item_delegate_;
88 std::unique_ptr<MockDownloadItemImpl> download_item_; 124 std::unique_ptr<MockDownloadItemImpl> download_item_;
89 std::unique_ptr<ParallelDownloadJobForTest> job_; 125 std::unique_ptr<ParallelDownloadJobForTest> job_;
126 // Request handle for the original request.
127 MockDownloadRequestHandle* mock_request_handle_;
90 }; 128 };
91 129
92 // Test if parallel requests can be built correctly for a new download. 130 // Test if parallel requests can be built correctly for a new download.
93 TEST_F(ParallelDownloadJobTest, CreateNewDownloadRequests) { 131 TEST_F(ParallelDownloadJobTest, CreateNewDownloadRequests) {
94 // Totally 2 requests for 100 bytes. 132 // Totally 2 requests for 100 bytes.
95 // Original request: Range:0-49, for 50 bytes. 133 // Original request: Range:0-49, for 50 bytes.
96 // Task 1: Range:50-, for 50 bytes. 134 // Task 1: Range:50-, for 50 bytes.
97 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 2); 135 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 2);
98 BuildParallelRequests(); 136 BuildParallelRequests();
99 EXPECT_EQ(1, static_cast<int>(job_->fake_tasks_.size())); 137 EXPECT_EQ(1, static_cast<int>(job_->workers().size()));
100 EXPECT_EQ(50, job_->fake_tasks_[0].first); 138 VerifyWorker(50, 0);
101 EXPECT_EQ(0, job_->fake_tasks_[0].second);
102 job_->fake_tasks_.clear();
103 DestroyParallelJob(); 139 DestroyParallelJob();
104 140
105 // Totally 3 requests for 100 bytes. 141 // Totally 3 requests for 100 bytes.
106 // Original request: Range:0-32, for 33 bytes. 142 // Original request: Range:0-32, for 33 bytes.
107 // Task 1: Range:33-65, for 33 bytes. 143 // Task 1: Range:33-65, for 33 bytes.
108 // Task 2: Range:66-, for 34 bytes. 144 // Task 2: Range:66-, for 34 bytes.
109 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 3); 145 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 3);
110 BuildParallelRequests(); 146 BuildParallelRequests();
111 EXPECT_EQ(2, static_cast<int>(job_->fake_tasks_.size())); 147 EXPECT_EQ(2, static_cast<int>(job_->workers().size()));
112 EXPECT_EQ(33, job_->fake_tasks_[0].first); 148 VerifyWorker(33, 33);
113 EXPECT_EQ(33, job_->fake_tasks_[0].second); 149 VerifyWorker(66, 0);
114 EXPECT_EQ(66, job_->fake_tasks_[1].first);
115 EXPECT_EQ(0, job_->fake_tasks_[1].second);
116 job_->fake_tasks_.clear();
117 DestroyParallelJob(); 150 DestroyParallelJob();
118 151
119 // Totally 3 requests for 100 bytes. Start from the 17th byte. 152 // Totally 3 requests for 100 bytes. Start from the 17th byte.
120 // Original request: Range:17-43, for 27 bytes. 153 // Original request: Range:17-43, for 27 bytes.
121 // Task 1: Range:44-70, for 27 bytes. 154 // Task 1: Range:44-70, for 27 bytes.
122 // Task 2: Range:71-99, for 29 bytes. 155 // Task 2: Range:71-99, for 29 bytes.
123 CreateParallelJob(17, 83, DownloadItem::ReceivedSlices(), 3); 156 CreateParallelJob(17, 83, DownloadItem::ReceivedSlices(), 3);
124 BuildParallelRequests(); 157 BuildParallelRequests();
125 EXPECT_EQ(2, static_cast<int>(job_->fake_tasks_.size())); 158 EXPECT_EQ(2, static_cast<int>(job_->workers().size()));
126 EXPECT_EQ(44, job_->fake_tasks_[0].first); 159 VerifyWorker(44, 27);
127 EXPECT_EQ(27, job_->fake_tasks_[0].second); 160 VerifyWorker(71, 0);
128 EXPECT_EQ(71, job_->fake_tasks_[1].first);
129 EXPECT_EQ(0, job_->fake_tasks_[1].second);
130 job_->fake_tasks_.clear();
131 DestroyParallelJob(); 161 DestroyParallelJob();
132 162
133 // Less than 2 requests, do nothing. 163 // Less than 2 requests, do nothing.
134 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 1); 164 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 1);
135 BuildParallelRequests(); 165 BuildParallelRequests();
136 EXPECT_TRUE(job_->fake_tasks_.empty()); 166 EXPECT_TRUE(job_->workers().empty());
137 DestroyParallelJob(); 167 DestroyParallelJob();
138 168
139 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 0); 169 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 0);
140 BuildParallelRequests(); 170 BuildParallelRequests();
141 EXPECT_TRUE(job_->fake_tasks_.empty()); 171 EXPECT_TRUE(job_->workers().empty());
142 DestroyParallelJob(); 172 DestroyParallelJob();
143 173
144 // Content-length is 0, do nothing. 174 // Content-length is 0, do nothing.
145 CreateParallelJob(100, 0, DownloadItem::ReceivedSlices(), 3); 175 CreateParallelJob(100, 0, DownloadItem::ReceivedSlices(), 3);
146 BuildParallelRequests(); 176 BuildParallelRequests();
147 EXPECT_TRUE(job_->fake_tasks_.empty()); 177 EXPECT_TRUE(job_->workers().empty());
148 DestroyParallelJob(); 178 DestroyParallelJob();
149 179
150 CreateParallelJob(0, 0, DownloadItem::ReceivedSlices(), 3); 180 CreateParallelJob(0, 0, DownloadItem::ReceivedSlices(), 3);
151 BuildParallelRequests(); 181 BuildParallelRequests();
152 EXPECT_TRUE(job_->fake_tasks_.empty()); 182 EXPECT_TRUE(job_->workers().empty());
153 DestroyParallelJob(); 183 DestroyParallelJob();
154 184
155 // 2 bytes left for 3 additional requests. Only 1 are built. 185 // 2 bytes left for 3 additional requests. Only 1 are built.
156 // Original request: Range:98-98, for 1 byte. 186 // Original request: Range:98-98, for 1 byte.
157 // Task 1: Range:99-, for 1 byte. 187 // Task 1: Range:99-, for 1 byte.
158 CreateParallelJob(98, 2, DownloadItem::ReceivedSlices(), 4); 188 CreateParallelJob(98, 2, DownloadItem::ReceivedSlices(), 4);
159 BuildParallelRequests(); 189 BuildParallelRequests();
160 EXPECT_EQ(1, static_cast<int>(job_->fake_tasks_.size())); 190 EXPECT_EQ(1, static_cast<int>(job_->workers().size()));
161 EXPECT_EQ(99, job_->fake_tasks_[0].first); 191 VerifyWorker(99, 0);
162 EXPECT_EQ(0, job_->fake_tasks_[0].second);
163 job_->fake_tasks_.clear();
164 DestroyParallelJob(); 192 DestroyParallelJob();
165 } 193 }
166 194
195 // Pause, cancel, resume can be called before or after the worker establish
196 // the byte stream.
197 // These tests ensure the states consistency between the job and workers.
198
199 // Ensure cancel before building the requests will result in no requests are
200 // built.
201 TEST_F(ParallelDownloadJobTest, EarlyCancelBeforeBuildRequests) {
202 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 2);
203 EXPECT_CALL(*mock_request_handle_, CancelRequest());
204
205 // Job is canceled before building parallel requests.
206 job_->Cancel(true);
207 EXPECT_TRUE(IsJobCanceled());
208
209 BuildParallelRequests();
210 EXPECT_TRUE(job_->workers().empty());
211
212 DestroyParallelJob();
213 }
214
215 // Ensure cancel before adding the byte stream will result in workers being
216 // canceled.
217 TEST_F(ParallelDownloadJobTest, EarlyCancelBeforeByteStreamReady) {
218 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 2);
219 EXPECT_CALL(*mock_request_handle_, CancelRequest());
220
221 BuildParallelRequests();
222 VerifyWorker(50, 0);
223
224 // Job is canceled after building parallel requests and before byte streams
225 // are added to the file sink.
226 job_->Cancel(true);
227 EXPECT_TRUE(IsJobCanceled());
228
229 for (auto& worker : job_->workers()) {
230 std::unique_ptr<MockDownloadRequestHandle> mock_handle =
231 base::MakeUnique<MockDownloadRequestHandle>();
232 EXPECT_CALL(*mock_handle.get(), CancelRequest());
233 MakeWorkerReady(worker.second.get(), std::move(mock_handle));
234 }
235
236 DestroyParallelJob();
237 }
238
239 // Ensure pause before adding the byte stream will result in workers being
240 // paused.
241 TEST_F(ParallelDownloadJobTest, EarlyPauseBeforeByteStreamReady) {
242 CreateParallelJob(0, 100, DownloadItem::ReceivedSlices(), 2);
243 EXPECT_CALL(*mock_request_handle_, PauseRequest());
244
245 BuildParallelRequests();
246 VerifyWorker(50, 0);
247
248 // Job is paused after building parallel requests and before adding the byte
249 // stream to the file sink.
250 job_->Pause();
251 EXPECT_TRUE(job_->is_paused());
252
253 for (auto& worker : job_->workers()) {
254 EXPECT_CALL(*job_.get(), CountOnByteStreamReady());
255 std::unique_ptr<MockDownloadRequestHandle> mock_handle =
256 base::MakeUnique<MockDownloadRequestHandle>();
257 EXPECT_CALL(*mock_handle.get(), PauseRequest());
258 MakeWorkerReady(worker.second.get(), std::move(mock_handle));
259 }
260
261 DestroyParallelJob();
262 }
263
167 } // namespace content 264 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/download/parallel_download_job.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698