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

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

Issue 2712713007: Make DownloadFileImpl handle multiple byte streams. (Closed)
Patch Set: Export the new class for linking on windows. Created 3 years, 10 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <stddef.h> 5 #include <stddef.h>
6 #include <stdint.h> 6 #include <stdint.h>
7 7
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/files/file.h" 11 #include "base/files/file.h"
12 #include "base/files/file_util.h" 12 #include "base/files/file_util.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/memory/ptr_util.h"
14 #include "base/run_loop.h" 15 #include "base/run_loop.h"
15 #include "base/single_thread_task_runner.h" 16 #include "base/single_thread_task_runner.h"
16 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
17 #include "base/test/test_file_util.h" 18 #include "base/test/test_file_util.h"
18 #include "base/threading/thread_task_runner_handle.h" 19 #include "base/threading/thread_task_runner_handle.h"
19 #include "build/build_config.h" 20 #include "build/build_config.h"
20 #include "content/browser/byte_stream.h" 21 #include "content/browser/byte_stream.h"
21 #include "content/browser/download/download_create_info.h" 22 #include "content/browser/download/download_create_info.h"
22 #include "content/browser/download/download_destination_observer.h" 23 #include "content/browser/download/download_destination_observer.h"
23 #include "content/browser/download/download_file_impl.h" 24 #include "content/browser/download/download_file_impl.h"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 enum DownloadFileRenameMethodType { RENAME_AND_UNIQUIFY, RENAME_AND_ANNOTATE }; 97 enum DownloadFileRenameMethodType { RENAME_AND_UNIQUIFY, RENAME_AND_ANNOTATE };
97 98
98 // This is a test DownloadFileImpl that has no retry delay and, on Posix, 99 // This is a test DownloadFileImpl that has no retry delay and, on Posix,
99 // retries renames failed due to ACCESS_DENIED. 100 // retries renames failed due to ACCESS_DENIED.
100 class TestDownloadFileImpl : public DownloadFileImpl { 101 class TestDownloadFileImpl : public DownloadFileImpl {
101 public: 102 public:
102 TestDownloadFileImpl(std::unique_ptr<DownloadSaveInfo> save_info, 103 TestDownloadFileImpl(std::unique_ptr<DownloadSaveInfo> save_info,
103 const base::FilePath& default_downloads_directory, 104 const base::FilePath& default_downloads_directory,
104 std::unique_ptr<ByteStreamReader> stream, 105 std::unique_ptr<ByteStreamReader> stream,
105 const net::NetLogWithSource& net_log, 106 const net::NetLogWithSource& net_log,
107 bool is_sparse_file,
106 base::WeakPtr<DownloadDestinationObserver> observer) 108 base::WeakPtr<DownloadDestinationObserver> observer)
107 : DownloadFileImpl(std::move(save_info), 109 : DownloadFileImpl(std::move(save_info),
108 default_downloads_directory, 110 default_downloads_directory,
109 std::move(stream), 111 std::move(stream),
110 net_log, 112 net_log,
113 is_sparse_file,
111 observer) {} 114 observer) {}
112 115
113 protected: 116 protected:
114 base::TimeDelta GetRetryDelayForFailedRename(int attempt_count) override { 117 base::TimeDelta GetRetryDelayForFailedRename(int attempt_count) override {
115 return base::TimeDelta::FromMilliseconds(0); 118 return base::TimeDelta::FromMilliseconds(0);
116 } 119 }
117 120
118 #if !defined(OS_WIN) 121 #if !defined(OS_WIN)
119 // On Posix, we don't encounter transient errors during renames, except 122 // On Posix, we don't encounter transient errors during renames, except
120 // possibly EAGAIN, which is difficult to replicate reliably. So we resort to 123 // possibly EAGAIN, which is difficult to replicate reliably. So we resort to
121 // simulating a transient error using ACCESS_DENIED instead. 124 // simulating a transient error using ACCESS_DENIED instead.
122 bool ShouldRetryFailedRename(DownloadInterruptReason reason) override { 125 bool ShouldRetryFailedRename(DownloadInterruptReason reason) override {
123 return reason == DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED; 126 return reason == DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED;
124 } 127 }
125 #endif 128 #endif
126 }; 129 };
127 130
128 } // namespace 131 } // namespace
129 132
130 class DownloadFileTest : public testing::Test { 133 class DownloadFileTest : public testing::Test {
131 public: 134 public:
132 static const char kTestData1[]; 135 static const char kTestData1[];
133 static const char kTestData2[]; 136 static const char kTestData2[];
134 static const char kTestData3[]; 137 static const char kTestData3[];
138 static const char kTestData4[];
139 static const char kTestData5[];
135 static const char kDataHash[]; 140 static const char kDataHash[];
136 static const char kEmptyHash[]; 141 static const char kEmptyHash[];
137 static const uint32_t kDummyDownloadId; 142 static const uint32_t kDummyDownloadId;
138 static const int kDummyChildId; 143 static const int kDummyChildId;
139 static const int kDummyRequestId; 144 static const int kDummyRequestId;
140 145
141 DownloadFileTest() 146 DownloadFileTest()
142 : observer_(new StrictMock<MockDownloadDestinationObserver>), 147 : observer_(new StrictMock<MockDownloadDestinationObserver>),
143 observer_factory_(observer_.get()), 148 observer_factory_(observer_.get()),
144 input_stream_(NULL), 149 input_stream_(NULL),
150 input_stream_1_(NULL),
145 bytes_(-1), 151 bytes_(-1),
146 bytes_per_sec_(-1) {} 152 bytes_per_sec_(-1) {}
147 153
148 ~DownloadFileTest() override {} 154 ~DownloadFileTest() override {}
149 155
150 void SetUpdateDownloadInfo(int64_t bytes, int64_t bytes_per_sec) { 156 void SetUpdateDownloadInfo(int64_t bytes, int64_t bytes_per_sec) {
151 bytes_ = bytes; 157 bytes_ = bytes;
152 bytes_per_sec_ = bytes_per_sec; 158 bytes_per_sec_ = bytes_per_sec;
153 } 159 }
154 160
(...skipping 12 matching lines...) Expand all
167 sink_callback_ = sink_callback; 173 sink_callback_ = sink_callback;
168 } 174 }
169 175
170 void SetInterruptReasonCallback(const base::Closure& closure, 176 void SetInterruptReasonCallback(const base::Closure& closure,
171 DownloadInterruptReason* reason_p, 177 DownloadInterruptReason* reason_p,
172 DownloadInterruptReason reason) { 178 DownloadInterruptReason reason) {
173 *reason_p = reason; 179 *reason_p = reason;
174 closure.Run(); 180 closure.Run();
175 } 181 }
176 182
177 bool CreateDownloadFile(int offset, bool calculate_hash) { 183 bool CreateDownloadFile(int offset,
184 bool calculate_hash,
185 bool is_sparse_file = false) {
178 // There can be only one. 186 // There can be only one.
179 DCHECK(!download_file_.get()); 187 DCHECK(!download_file_.get());
180 188
181 input_stream_ = new StrictMock<MockByteStreamReader>(); 189 input_stream_ = new StrictMock<MockByteStreamReader>();
182 190
183 // TODO: Need to actually create a function that'll set the variables 191 // TODO: Need to actually create a function that'll set the variables
184 // based on the inputs from the callback. 192 // based on the inputs from the callback.
185 EXPECT_CALL(*input_stream_, RegisterCallback(_)) 193 EXPECT_CALL(*input_stream_, RegisterCallback(_))
186 .WillOnce(Invoke(this, &DownloadFileTest::RegisterCallback)) 194 .WillOnce(Invoke(this, &DownloadFileTest::RegisterCallback))
187 .RetiresOnSaturation(); 195 .RetiresOnSaturation();
188 196
189 std::unique_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo()); 197 std::unique_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo());
190 download_file_.reset(new TestDownloadFileImpl( 198 download_file_.reset(new TestDownloadFileImpl(
191 std::move(save_info), base::FilePath(), 199 std::move(save_info), base::FilePath(),
192 std::unique_ptr<ByteStreamReader>(input_stream_), 200 std::unique_ptr<ByteStreamReader>(input_stream_),
193 net::NetLogWithSource(), observer_factory_.GetWeakPtr())); 201 net::NetLogWithSource(), is_sparse_file,
202 observer_factory_.GetWeakPtr()));
194 203
195 EXPECT_CALL(*input_stream_, Read(_, _)) 204 EXPECT_CALL(*input_stream_, Read(_, _))
196 .WillOnce(Return(ByteStreamReader::STREAM_EMPTY)) 205 .WillOnce(Return(ByteStreamReader::STREAM_EMPTY))
197 .RetiresOnSaturation(); 206 .RetiresOnSaturation();
198 207
199 base::WeakPtrFactory<DownloadFileTest> weak_ptr_factory(this); 208 base::WeakPtrFactory<DownloadFileTest> weak_ptr_factory(this);
200 DownloadInterruptReason result = DOWNLOAD_INTERRUPT_REASON_NONE; 209 DownloadInterruptReason result = DOWNLOAD_INTERRUPT_REASON_NONE;
201 base::RunLoop loop_runner; 210 base::RunLoop loop_runner;
202 download_file_->Initialize(base::Bind( 211 download_file_->Initialize(base::Bind(
203 &DownloadFileTest::SetInterruptReasonCallback, 212 &DownloadFileTest::SetInterruptReasonCallback,
(...skipping 10 matching lines...) Expand all
214 // Make sure the data has been properly written to disk. 223 // Make sure the data has been properly written to disk.
215 std::string disk_data; 224 std::string disk_data;
216 EXPECT_TRUE(base::ReadFileToString(download_file_->FullPath(), &disk_data)); 225 EXPECT_TRUE(base::ReadFileToString(download_file_->FullPath(), &disk_data));
217 EXPECT_EQ(expected_data_, disk_data); 226 EXPECT_EQ(expected_data_, disk_data);
218 227
219 // Make sure the Browser and File threads outlive the DownloadFile 228 // Make sure the Browser and File threads outlive the DownloadFile
220 // to satisfy thread checks inside it. 229 // to satisfy thread checks inside it.
221 download_file_.reset(); 230 download_file_.reset();
222 } 231 }
223 232
224 // Setup the stream to do be a data append; don't actually trigger 233 // Setup the stream to append data or write from |offset| to the file.
225 // the callback or do verifications. 234 // Don't actually trigger the callback or do verifications.
226 void SetupDataAppend(const char **data_chunks, size_t num_chunks, 235 void SetupDataAppend(const char** data_chunks,
227 ::testing::Sequence s) { 236 size_t num_chunks,
228 DCHECK(input_stream_); 237 MockByteStreamReader* stream_reader,
238 ::testing::Sequence s,
239 int64_t offset = -1) {
240 DCHECK(stream_reader);
241 size_t current_pos = static_cast<size_t>(offset);
229 for (size_t i = 0; i < num_chunks; i++) { 242 for (size_t i = 0; i < num_chunks; i++) {
230 const char *source_data = data_chunks[i]; 243 const char *source_data = data_chunks[i];
231 size_t length = strlen(source_data); 244 size_t length = strlen(source_data);
232 scoped_refptr<net::IOBuffer> data = new net::IOBuffer(length); 245 scoped_refptr<net::IOBuffer> data = new net::IOBuffer(length);
233 memcpy(data->data(), source_data, length); 246 memcpy(data->data(), source_data, length);
234 EXPECT_CALL(*input_stream_, Read(_, _)) 247 EXPECT_CALL(*stream_reader, Read(_, _))
235 .InSequence(s) 248 .InSequence(s)
236 .WillOnce(DoAll(SetArgPointee<0>(data), 249 .WillOnce(DoAll(SetArgPointee<0>(data), SetArgPointee<1>(length),
237 SetArgPointee<1>(length),
238 Return(ByteStreamReader::STREAM_HAS_DATA))) 250 Return(ByteStreamReader::STREAM_HAS_DATA)))
239 .RetiresOnSaturation(); 251 .RetiresOnSaturation();
240 expected_data_ += source_data; 252
253 if (offset < 0) {
254 // Append data.
255 expected_data_ += source_data;
256 continue;
257 }
258
259 // Write from offset. May fill holes with '\0'.
260 size_t new_len = current_pos + length;
261 if (new_len > expected_data_.size())
262 expected_data_.append(new_len - expected_data_.size(), '\0');
263 expected_data_.replace(current_pos, length, source_data);
264 current_pos += length;
241 } 265 }
242 } 266 }
243 267
244 void VerifyStreamAndSize() { 268 void VerifyStreamAndSize() {
245 ::testing::Mock::VerifyAndClearExpectations(input_stream_); 269 ::testing::Mock::VerifyAndClearExpectations(input_stream_);
246 int64_t size; 270 int64_t size;
247 EXPECT_TRUE(base::GetFileSize(download_file_->FullPath(), &size)); 271 EXPECT_TRUE(base::GetFileSize(download_file_->FullPath(), &size));
248 EXPECT_EQ(expected_data_.size(), static_cast<size_t>(size)); 272 EXPECT_EQ(expected_data_.size(), static_cast<size_t>(size));
249 } 273 }
250 274
251 // TODO(rdsmith): Manage full percentage issues properly. 275 // TODO(rdsmith): Manage full percentage issues properly.
252 void AppendDataToFile(const char **data_chunks, size_t num_chunks) { 276 void AppendDataToFile(const char **data_chunks, size_t num_chunks) {
253 ::testing::Sequence s1; 277 ::testing::Sequence s1;
254 SetupDataAppend(data_chunks, num_chunks, s1); 278 SetupDataAppend(data_chunks, num_chunks, input_stream_, s1);
255 EXPECT_CALL(*input_stream_, Read(_, _)) 279 EXPECT_CALL(*input_stream_, Read(_, _))
256 .InSequence(s1) 280 .InSequence(s1)
257 .WillOnce(Return(ByteStreamReader::STREAM_EMPTY)) 281 .WillOnce(Return(ByteStreamReader::STREAM_EMPTY))
258 .RetiresOnSaturation(); 282 .RetiresOnSaturation();
259 sink_callback_.Run(); 283 sink_callback_.Run();
260 VerifyStreamAndSize(); 284 VerifyStreamAndSize();
261 } 285 }
262 286
263 void SetupFinishStream(DownloadInterruptReason interrupt_reason, 287 void SetupFinishStream(DownloadInterruptReason interrupt_reason,
264 ::testing::Sequence s) { 288 MockByteStreamReader* stream_reader,
265 EXPECT_CALL(*input_stream_, Read(_, _)) 289 ::testing::Sequence s) {
290 EXPECT_CALL(*stream_reader, Read(_, _))
266 .InSequence(s) 291 .InSequence(s)
267 .WillOnce(Return(ByteStreamReader::STREAM_COMPLETE)) 292 .WillOnce(Return(ByteStreamReader::STREAM_COMPLETE))
268 .RetiresOnSaturation(); 293 .RetiresOnSaturation();
269 EXPECT_CALL(*input_stream_, GetStatus()) 294 EXPECT_CALL(*stream_reader, GetStatus())
270 .InSequence(s) 295 .InSequence(s)
271 .WillOnce(Return(interrupt_reason)) 296 .WillOnce(Return(interrupt_reason))
272 .RetiresOnSaturation(); 297 .RetiresOnSaturation();
273 EXPECT_CALL(*input_stream_, RegisterCallback(_)) 298 EXPECT_CALL(*stream_reader, RegisterCallback(_)).RetiresOnSaturation();
274 .RetiresOnSaturation();
275 } 299 }
276 300
277 void FinishStream(DownloadInterruptReason interrupt_reason, 301 void FinishStream(DownloadInterruptReason interrupt_reason,
278 bool check_observer, 302 bool check_observer,
279 const std::string& expected_hash) { 303 const std::string& expected_hash) {
280 ::testing::Sequence s1; 304 ::testing::Sequence s1;
281 SetupFinishStream(interrupt_reason, s1); 305 SetupFinishStream(interrupt_reason, input_stream_, s1);
282 sink_callback_.Run(); 306 sink_callback_.Run();
283 VerifyStreamAndSize(); 307 VerifyStreamAndSize();
284 if (check_observer) { 308 if (check_observer) {
285 EXPECT_CALL(*(observer_.get()), 309 EXPECT_CALL(*(observer_.get()),
286 MockDestinationCompleted(_, expected_hash)); 310 MockDestinationCompleted(_, expected_hash));
287 base::RunLoop().RunUntilIdle(); 311 base::RunLoop().RunUntilIdle();
288 ::testing::Mock::VerifyAndClearExpectations(observer_.get()); 312 ::testing::Mock::VerifyAndClearExpectations(observer_.get());
289 EXPECT_CALL(*(observer_.get()), DestinationUpdate(_, _)) 313 EXPECT_CALL(*(observer_.get()), DestinationUpdate(_, _))
290 .Times(AnyNumber()) 314 .Times(AnyNumber())
291 .WillRepeatedly( 315 .WillRepeatedly(
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 base::Bind(&DownloadFileTest::SetRenameResult, 369 base::Bind(&DownloadFileTest::SetRenameResult,
346 base::Unretained(this), 370 base::Unretained(this),
347 loop_runner.QuitClosure(), 371 loop_runner.QuitClosure(),
348 &result_reason, 372 &result_reason,
349 result_path_p); 373 result_path_p);
350 InvokeRenameMethod(method, full_path, completion_callback); 374 InvokeRenameMethod(method, full_path, completion_callback);
351 loop_runner.Run(); 375 loop_runner.Run();
352 return result_reason; 376 return result_reason;
353 } 377 }
354 378
379 // Prepare two byte streams to write to the same file sink.
380 void PrepareMultipleStreams() {
381 // Create a sparse file.
382 ASSERT_TRUE(CreateDownloadFile(0, true, true));
383 base::FilePath initial_path(download_file_->FullPath());
384 EXPECT_TRUE(base::PathExists(initial_path));
385 DCHECK(download_file_);
386
387 const char* stream_0_data[] = {kTestData1, kTestData2};
388 const char* stream_1_data[] = {kTestData4, kTestData5};
389 size_t stream_1_offset = strlen(kTestData1) + strlen(kTestData2);
390
391 // Register second SourceStream entry for the second stream.
392 // The first stream should be registered in ctor of DownloadFile.
393 DownloadFileImpl::SourceStreams& source_streams =
394 DownloadFileTest::source_streams();
395 EXPECT_EQ(static_cast<size_t>(1), source_streams.size());
396 source_streams[stream_1_offset] =
397 base::MakeUnique<DownloadFileImpl::SourceStream>(stream_1_offset, 0);
398
399 // Create the second byte stream. Will be moved to DownloadFile.
400 input_stream_1_ = new MockByteStreamReader();
401
402 // Fill up two streams and setup expectation.
403 ::testing::Sequence s0;
404 ::testing::Sequence s1;
405 SetupDataAppend(stream_1_data, 2, input_stream_1_, s1, stream_1_offset);
406 SetupDataAppend(stream_0_data, 2, input_stream_, s0, 0);
407 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, input_stream_1_, s1);
408 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, input_stream_, s0);
409
410 // Every ByteStreamReader should call RegisterCallback twice.
411 // One to set the callback, the other to null the callback.
412 EXPECT_CALL(*input_stream_1_, RegisterCallback(_)).RetiresOnSaturation();
413 }
414
415 DownloadFileImpl::SourceStreams& source_streams() {
416 DCHECK(download_file_);
417 return download_file_->source_streams_;
418 }
419
420 int64_t TotalBytesReceived() const {
421 DCHECK(download_file_);
422 return download_file_->TotalBytesReceived();
423 }
424
355 std::unique_ptr<StrictMock<MockDownloadDestinationObserver>> observer_; 425 std::unique_ptr<StrictMock<MockDownloadDestinationObserver>> observer_;
356 base::WeakPtrFactory<DownloadDestinationObserver> observer_factory_; 426 base::WeakPtrFactory<DownloadDestinationObserver> observer_factory_;
357 427
358 // DownloadFile instance we are testing. 428 // DownloadFile instance we are testing.
359 std::unique_ptr<DownloadFile> download_file_; 429 std::unique_ptr<DownloadFileImpl> download_file_;
360 430
361 // Stream for sending data into the download file. 431 // Stream for sending data into the download file.
362 // Owned by download_file_; will be alive for lifetime of download_file_. 432 // Owned by download_file_; will be alive for lifetime of download_file_.
363 StrictMock<MockByteStreamReader>* input_stream_; 433 StrictMock<MockByteStreamReader>* input_stream_;
364 434
435 // A second byte stream to test multiple stream write.
436 MockByteStreamReader* input_stream_1_;
437
365 // Sink callback data for stream. 438 // Sink callback data for stream.
366 base::Closure sink_callback_; 439 base::Closure sink_callback_;
367 440
368 // Latest update sent to the observer. 441 // Latest update sent to the observer.
369 int64_t bytes_; 442 int64_t bytes_;
370 int64_t bytes_per_sec_; 443 int64_t bytes_per_sec_;
371 444
372 private: 445 private:
373 void SetRenameResult(const base::Closure& closure, 446 void SetRenameResult(const base::Closure& closure,
374 DownloadInterruptReason* reason_p, 447 DownloadInterruptReason* reason_p,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 // the value parameter. 485 // the value parameter.
413 INSTANTIATE_TEST_CASE_P(DownloadFile, 486 INSTANTIATE_TEST_CASE_P(DownloadFile,
414 DownloadFileTestWithRename, 487 DownloadFileTestWithRename,
415 ::testing::Values(RENAME_AND_ANNOTATE, 488 ::testing::Values(RENAME_AND_ANNOTATE,
416 RENAME_AND_UNIQUIFY)); 489 RENAME_AND_UNIQUIFY));
417 490
418 const char DownloadFileTest::kTestData1[] = 491 const char DownloadFileTest::kTestData1[] =
419 "Let's write some data to the file!\n"; 492 "Let's write some data to the file!\n";
420 const char DownloadFileTest::kTestData2[] = "Writing more data.\n"; 493 const char DownloadFileTest::kTestData2[] = "Writing more data.\n";
421 const char DownloadFileTest::kTestData3[] = "Final line."; 494 const char DownloadFileTest::kTestData3[] = "Final line.";
495 const char DownloadFileTest::kTestData4[] = "abcdefg";
496 const char DownloadFileTest::kTestData5[] = "01234";
422 const char DownloadFileTest::kDataHash[] = 497 const char DownloadFileTest::kDataHash[] =
423 "CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8"; 498 "CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8";
424 const char DownloadFileTest::kEmptyHash[] = 499 const char DownloadFileTest::kEmptyHash[] =
425 "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855"; 500 "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855";
426 501
427 const uint32_t DownloadFileTest::kDummyDownloadId = 23; 502 const uint32_t DownloadFileTest::kDummyDownloadId = 23;
428 const int DownloadFileTest::kDummyChildId = 3; 503 const int DownloadFileTest::kDummyChildId = 3;
429 const int DownloadFileTest::kDummyRequestId = 67; 504 const int DownloadFileTest::kDummyRequestId = 67;
430 505
431 // Rename the file before any data is downloaded, after some has, after it all 506 // Rename the file before any data is downloaded, after some has, after it all
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 DestroyDownloadFile(0); 817 DestroyDownloadFile(0);
743 } 818 }
744 819
745 TEST_F(DownloadFileTest, StreamNonEmptySuccess) { 820 TEST_F(DownloadFileTest, StreamNonEmptySuccess) {
746 ASSERT_TRUE(CreateDownloadFile(0, true)); 821 ASSERT_TRUE(CreateDownloadFile(0, true));
747 base::FilePath initial_path(download_file_->FullPath()); 822 base::FilePath initial_path(download_file_->FullPath());
748 EXPECT_TRUE(base::PathExists(initial_path)); 823 EXPECT_TRUE(base::PathExists(initial_path));
749 824
750 const char* chunks1[] = { kTestData1, kTestData2 }; 825 const char* chunks1[] = { kTestData1, kTestData2 };
751 ::testing::Sequence s1; 826 ::testing::Sequence s1;
752 SetupDataAppend(chunks1, 2, s1); 827 SetupDataAppend(chunks1, 2, input_stream_, s1);
753 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, s1); 828 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, input_stream_, s1);
754 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _)); 829 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _));
755 sink_callback_.Run(); 830 sink_callback_.Run();
756 VerifyStreamAndSize(); 831 VerifyStreamAndSize();
757 base::RunLoop().RunUntilIdle(); 832 base::RunLoop().RunUntilIdle();
758 DestroyDownloadFile(0); 833 DestroyDownloadFile(0);
759 } 834 }
760 835
761 TEST_F(DownloadFileTest, StreamNonEmptyError) { 836 TEST_F(DownloadFileTest, StreamNonEmptyError) {
762 ASSERT_TRUE(CreateDownloadFile(0, true)); 837 ASSERT_TRUE(CreateDownloadFile(0, true));
763 base::FilePath initial_path(download_file_->FullPath()); 838 base::FilePath initial_path(download_file_->FullPath());
764 EXPECT_TRUE(base::PathExists(initial_path)); 839 EXPECT_TRUE(base::PathExists(initial_path));
765 840
766 const char* chunks1[] = { kTestData1, kTestData2 }; 841 const char* chunks1[] = { kTestData1, kTestData2 };
767 ::testing::Sequence s1; 842 ::testing::Sequence s1;
768 SetupDataAppend(chunks1, 2, s1); 843 SetupDataAppend(chunks1, 2, input_stream_, s1);
769 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, s1); 844 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED,
845 input_stream_, s1);
770 846
771 EXPECT_CALL(*(observer_.get()), 847 EXPECT_CALL(*(observer_.get()),
772 MockDestinationError( 848 MockDestinationError(
773 DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, _, _)) 849 DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, _, _))
774 .WillOnce(InvokeWithoutArgs( 850 .WillOnce(InvokeWithoutArgs(
775 this, &DownloadFileTest::ConfirmUpdateDownloadInfo)); 851 this, &DownloadFileTest::ConfirmUpdateDownloadInfo));
776 852
777 // If this next EXPECT_CALL fails flakily, it's probably a real failure. 853 // If this next EXPECT_CALL fails flakily, it's probably a real failure.
778 // We'll be getting a stream of UpdateDownload calls from the timer, and 854 // We'll be getting a stream of UpdateDownload calls from the timer, and
779 // the last one may have the correct information even if the failure 855 // the last one may have the correct information even if the failure
780 // doesn't produce an update, as the timer update may have triggered at the 856 // doesn't produce an update, as the timer update may have triggered at the
781 // same time. 857 // same time.
782 EXPECT_CALL(*(observer_.get()), 858 EXPECT_CALL(*(observer_.get()),
783 CurrentUpdateStatus(strlen(kTestData1) + strlen(kTestData2), _)); 859 CurrentUpdateStatus(strlen(kTestData1) + strlen(kTestData2), _));
784 860
785 sink_callback_.Run(); 861 sink_callback_.Run();
786 base::RunLoop().RunUntilIdle(); 862 base::RunLoop().RunUntilIdle();
787 VerifyStreamAndSize(); 863 VerifyStreamAndSize();
788 DestroyDownloadFile(0); 864 DestroyDownloadFile(0);
789 } 865 }
790 866
867 // Tests for concurrent streams handling, used for parallel download.
868 //
869 // Activate both streams at the same time.
870 TEST_F(DownloadFileTest, MutipleStreamsWrite) {
871 PrepareMultipleStreams();
872 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _));
873
874 DownloadFileImpl::SourceStreams& source_streams =
875 DownloadFileTest::source_streams();
876 int64_t stream_0_length =
877 static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2));
878 int64_t stream_1_length =
879 static_cast<int64_t>(strlen(kTestData4) + strlen(kTestData5));
880 DownloadFileImpl::SourceStream* stream0 = source_streams[0].get();
881 DownloadFileImpl::SourceStream* stream1 =
882 source_streams[stream_0_length].get();
883
884 download_file_->AddByteStream(
885 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length);
886 sink_callback_.Run();
887 base::RunLoop().RunUntilIdle();
888
889 EXPECT_EQ(stream_0_length, stream0->bytes_received());
890 EXPECT_EQ(stream_1_length, stream1->bytes_received());
891 EXPECT_TRUE(stream0->is_finished());
892 EXPECT_TRUE(stream1->is_finished());
893 EXPECT_EQ(0, stream0->offset());
894 EXPECT_EQ(stream_0_length, stream1->offset());
895 EXPECT_EQ(stream0->bytes_received() + stream1->bytes_received(),
896 TotalBytesReceived());
897
898 DestroyDownloadFile(0);
899 }
900
901 // Activate and deplete one stream, later add the second stream.
902 TEST_F(DownloadFileTest, MutipleStreamsOneStreamFirst) {
903 PrepareMultipleStreams();
904
905 DownloadFileImpl::SourceStreams& source_streams =
906 DownloadFileTest::source_streams();
907 int64_t stream_0_length =
908 static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2));
909 int64_t stream_1_length =
910 static_cast<int64_t>(strlen(kTestData4) + strlen(kTestData5));
911 DownloadFileImpl::SourceStream* stream0 = source_streams[0].get();
912 DownloadFileImpl::SourceStream* stream1 =
913 source_streams[stream_0_length].get();
914
915 // Deplete the first stream.
916 sink_callback_.Run();
917 base::RunLoop().RunUntilIdle();
918 EXPECT_EQ(stream_0_length, stream0->bytes_received());
919 EXPECT_EQ(0, stream1->bytes_received());
920 EXPECT_TRUE(stream0->is_finished());
921 EXPECT_FALSE(stream1->is_finished());
922 EXPECT_EQ(stream_0_length, stream1->offset());
923 EXPECT_EQ(stream0->bytes_received(), TotalBytesReceived());
924
925 // Won't inform the observer utill the second stream is depleted.
926 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _));
927
928 // Drain the second stream after the first stream is depleted.
929 download_file_->AddByteStream(
930 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length);
931 base::RunLoop().RunUntilIdle();
932
933 EXPECT_EQ(stream_0_length, stream0->bytes_received());
934 EXPECT_EQ(stream_1_length, stream1->bytes_received());
935 EXPECT_TRUE(stream0->is_finished());
936 EXPECT_TRUE(stream1->is_finished());
937 EXPECT_EQ(0, stream0->offset());
938 EXPECT_EQ(stream_0_length, stream1->offset());
939 EXPECT_EQ(stream0->bytes_received() + stream1->bytes_received(),
940 TotalBytesReceived());
941
942 DestroyDownloadFile(0);
943 }
944
791 } // namespace content 945 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698