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

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

Issue 2742093002: Glue parallel download job and download file together. (Closed)
Patch Set: Work on feedback. Created 3 years, 9 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
(...skipping 21 matching lines...) Expand all
32 #include "net/base/net_errors.h" 32 #include "net/base/net_errors.h"
33 #include "net/log/net_log_with_source.h" 33 #include "net/log/net_log_with_source.h"
34 #include "testing/gmock/include/gmock/gmock.h" 34 #include "testing/gmock/include/gmock/gmock.h"
35 #include "testing/gtest/include/gtest/gtest.h" 35 #include "testing/gtest/include/gtest/gtest.h"
36 36
37 using ::testing::_; 37 using ::testing::_;
38 using ::testing::AnyNumber; 38 using ::testing::AnyNumber;
39 using ::testing::DoAll; 39 using ::testing::DoAll;
40 using ::testing::InSequence; 40 using ::testing::InSequence;
41 using ::testing::Return; 41 using ::testing::Return;
42 using ::testing::Sequence;
42 using ::testing::SetArgPointee; 43 using ::testing::SetArgPointee;
43 using ::testing::StrictMock; 44 using ::testing::StrictMock;
44 45
45 namespace content { 46 namespace content {
46 namespace { 47 namespace {
47 48
48 // Struct for SourceStream states verification. 49 // Struct for SourceStream states verification.
49 struct SourceStreamTestData { 50 struct SourceStreamTestData {
50 SourceStreamTestData(int64_t offset, int64_t bytes_written, bool finished) 51 SourceStreamTestData(int64_t offset, int64_t bytes_written, bool finished)
51 : offset(offset), bytes_written(bytes_written), finished(finished) {} 52 : offset(offset), bytes_written(bytes_written), finished(finished) {}
52 int64_t offset; 53 int64_t offset;
53 int64_t bytes_written; 54 int64_t bytes_written;
54 bool finished; 55 bool finished;
55 }; 56 };
56 57
58 int64_t GetBuffersLength(const char** buffers, size_t num_buffer) {
59 int64_t result = 0;
60 for (size_t i = 0; i < num_buffer; ++i)
61 result += static_cast<int64_t>(strlen(buffers[i]));
62 return result;
63 }
64
57 std::string GetHexEncodedHashValue(crypto::SecureHash* hash_state) { 65 std::string GetHexEncodedHashValue(crypto::SecureHash* hash_state) {
58 if (!hash_state) 66 if (!hash_state)
59 return std::string(); 67 return std::string();
60 std::vector<char> hash_value(hash_state->GetHashLength()); 68 std::vector<char> hash_value(hash_state->GetHashLength());
61 hash_state->Finish(&hash_value.front(), hash_value.size()); 69 hash_state->Finish(&hash_value.front(), hash_value.size());
62 return base::HexEncode(&hash_value.front(), hash_value.size()); 70 return base::HexEncode(&hash_value.front(), hash_value.size());
63 } 71 }
64 72
65 class MockByteStreamReader : public ByteStreamReader { 73 class MockByteStreamReader : public ByteStreamReader {
66 public: 74 public:
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 151
144 } // namespace 152 } // namespace
145 153
146 class DownloadFileTest : public testing::Test { 154 class DownloadFileTest : public testing::Test {
147 public: 155 public:
148 static const char kTestData1[]; 156 static const char kTestData1[];
149 static const char kTestData2[]; 157 static const char kTestData2[];
150 static const char kTestData3[]; 158 static const char kTestData3[];
151 static const char kTestData4[]; 159 static const char kTestData4[];
152 static const char kTestData5[]; 160 static const char kTestData5[];
161 static const char* kTestData6[];
162 static const char* kTestData7[];
153 static const char kDataHash[]; 163 static const char kDataHash[];
154 static const char kEmptyHash[]; 164 static const char kEmptyHash[];
155 static const uint32_t kDummyDownloadId; 165 static const uint32_t kDummyDownloadId;
156 static const int kDummyChildId; 166 static const int kDummyChildId;
157 static const int kDummyRequestId; 167 static const int kDummyRequestId;
158 168
159 DownloadFileTest() 169 DownloadFileTest()
160 : observer_(new StrictMock<MockDownloadDestinationObserver>), 170 : observer_(new StrictMock<MockDownloadDestinationObserver>),
161 observer_factory_(observer_.get()), 171 observer_factory_(observer_.get()),
162 input_stream_(NULL), 172 input_stream_(NULL),
(...skipping 27 matching lines...) Expand all
190 200
191 void SetInterruptReasonCallback(const base::Closure& closure, 201 void SetInterruptReasonCallback(const base::Closure& closure,
192 DownloadInterruptReason* reason_p, 202 DownloadInterruptReason* reason_p,
193 DownloadInterruptReason reason) { 203 DownloadInterruptReason reason) {
194 *reason_p = reason; 204 *reason_p = reason;
195 closure.Run(); 205 closure.Run();
196 } 206 }
197 207
198 bool CreateDownloadFile(int offset, 208 bool CreateDownloadFile(int offset,
199 bool calculate_hash, 209 bool calculate_hash,
200 bool is_sparse_file = false) { 210 bool is_sparse_file = false,
211 const DownloadItem::ReceivedSlices& received_slices =
212 DownloadItem::ReceivedSlices()) {
201 // There can be only one. 213 // There can be only one.
202 DCHECK(!download_file_.get()); 214 DCHECK(!download_file_.get());
203 215
204 input_stream_ = new StrictMock<MockByteStreamReader>(); 216 input_stream_ = new StrictMock<MockByteStreamReader>();
205 217
206 // TODO: Need to actually create a function that'll set the variables 218 // TODO: Need to actually create a function that'll set the variables
207 // based on the inputs from the callback. 219 // based on the inputs from the callback.
208 EXPECT_CALL(*input_stream_, RegisterCallback(_)) 220 EXPECT_CALL(*input_stream_, RegisterCallback(_))
209 .WillOnce(Invoke(this, &DownloadFileTest::RegisterCallback)) 221 .WillOnce(Invoke(this, &DownloadFileTest::RegisterCallback))
210 .RetiresOnSaturation(); 222 .RetiresOnSaturation();
211 223
212 std::unique_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo()); 224 std::unique_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo());
213 download_file_.reset(new TestDownloadFileImpl( 225 download_file_.reset(new TestDownloadFileImpl(
214 std::move(save_info), base::FilePath(), 226 std::move(save_info), base::FilePath(),
215 std::unique_ptr<ByteStreamReader>(input_stream_), 227 std::unique_ptr<ByteStreamReader>(input_stream_), received_slices,
216 std::vector<DownloadItem::ReceivedSlice>(),
217 net::NetLogWithSource(), is_sparse_file, 228 net::NetLogWithSource(), is_sparse_file,
218 observer_factory_.GetWeakPtr())); 229 observer_factory_.GetWeakPtr()));
219 230
220 EXPECT_CALL(*input_stream_, Read(_, _)) 231 EXPECT_CALL(*input_stream_, Read(_, _))
221 .WillOnce(Return(ByteStreamReader::STREAM_EMPTY)) 232 .WillOnce(Return(ByteStreamReader::STREAM_EMPTY))
222 .RetiresOnSaturation(); 233 .RetiresOnSaturation();
223 234
224 base::WeakPtrFactory<DownloadFileTest> weak_ptr_factory(this); 235 base::WeakPtrFactory<DownloadFileTest> weak_ptr_factory(this);
225 DownloadInterruptReason result = DOWNLOAD_INTERRUPT_REASON_NONE; 236 DownloadInterruptReason result = DOWNLOAD_INTERRUPT_REASON_NONE;
226 base::RunLoop loop_runner; 237 base::RunLoop loop_runner;
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 base::Bind(&DownloadFileTest::SetRenameResult, 399 base::Bind(&DownloadFileTest::SetRenameResult,
389 base::Unretained(this), 400 base::Unretained(this),
390 loop_runner.QuitClosure(), 401 loop_runner.QuitClosure(),
391 &result_reason, 402 &result_reason,
392 result_path_p); 403 result_path_p);
393 InvokeRenameMethod(method, full_path, completion_callback); 404 InvokeRenameMethod(method, full_path, completion_callback);
394 loop_runner.Run(); 405 loop_runner.Run();
395 return result_reason; 406 return result_reason;
396 } 407 }
397 408
398 // Prepare two byte streams to write to the same file sink. 409 // Prepare a byte stream to write to the file sink.
399 void PrepareMultipleStreams(int64_t second_stream_length) { 410 void PrepareStream(StrictMock<MockByteStreamReader>** stream,
400 // Create a sparse file. 411 int64_t offset,
401 ASSERT_TRUE(CreateDownloadFile(0, true, true)); 412 bool create_stream,
402 base::FilePath initial_path(download_file_->FullPath()); 413 bool will_finish,
403 EXPECT_TRUE(base::PathExists(initial_path)); 414 const char** buffers,
404 DCHECK(download_file_); 415 size_t num_buffer) {
405 416 if (create_stream)
406 const char* stream_0_data[] = {kTestData1, kTestData2}; 417 *stream = new StrictMock<MockByteStreamReader>();
407 const char* stream_1_data[] = {kTestData4, kTestData5};
408 size_t stream_1_offset = strlen(kTestData1) + strlen(kTestData2);
409
410 // Register second SourceStream entry for the second stream.
411 // The first stream should be registered in ctor of DownloadFile.
412 DownloadFileImpl::SourceStreams& source_streams =
413 download_file_->source_streams_;
414 EXPECT_EQ(static_cast<size_t>(1), source_streams.size());
415 source_streams[stream_1_offset] =
416 base::MakeUnique<DownloadFileImpl::SourceStream>(stream_1_offset,
417 second_stream_length);
418
419 // Create the second byte stream. Will be moved to DownloadFile.
420 input_stream_1_ = new MockByteStreamReader();
421
422 ::testing::Sequence s0;
423 ::testing::Sequence s1;
424 SetupDataAppend(stream_1_data, 2, input_stream_1_, s1, stream_1_offset);
425 SetupDataAppend(stream_0_data, 2, input_stream_, s0, 0);
426 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, input_stream_, s0);
427 418
428 // Expectation on MockByteStreamReader for MultipleStreams tests: 419 // Expectation on MockByteStreamReader for MultipleStreams tests:
429 // 1. RegisterCallback: Must called twice. One to set the callback, the 420 // 1. RegisterCallback: Must called twice. One to set the callback, the
430 // other to release the stream. 421 // other to release the stream.
431 // 2. Read: If filled with N buffer, called (N+1) times, where the last Read 422 // 2. Read: If filled with N buffer, called (N+1) times, where the last Read
432 // call doesn't read any data but returns STRAM_COMPLETE. 423 // call doesn't read any data but returns STRAM_COMPLETE.
433 // The stream may terminate in the middle and less Read calls are expected. 424 // The stream may terminate in the middle and less Read calls are expected.
434 // 3. GetStatus: Only called if the stream is completed and last Read call 425 // 3. GetStatus: Only called if the stream is completed and last Read call
435 // returns STREAM_COMPLETE. 426 // returns STREAM_COMPLETE.
436 if (second_stream_length == 0) 427 Sequence seq;
437 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, input_stream_1_, s1); 428 SetupDataAppend(buffers, num_buffer, *stream, seq, offset);
438 else 429 if (will_finish)
439 EXPECT_CALL(*input_stream_1_, RegisterCallback(_)).RetiresOnSaturation(); 430 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, *stream, seq);
440
441 EXPECT_CALL(*input_stream_1_, RegisterCallback(_)).RetiresOnSaturation();
442 } 431 }
443 432
444 void VerifySourceStreamsStates(const SourceStreamTestData& data) { 433 void VerifySourceStreamsStates(const SourceStreamTestData& data) {
445 DCHECK(download_file_->source_streams_.find(data.offset) != 434 DCHECK(download_file_->source_streams_.find(data.offset) !=
446 download_file_->source_streams_.end()); 435 download_file_->source_streams_.end());
447 DownloadFileImpl::SourceStream* stream = 436 DownloadFileImpl::SourceStream* stream =
448 download_file_->source_streams_[data.offset].get(); 437 download_file_->source_streams_[data.offset].get();
449 DCHECK(stream); 438 DCHECK(stream);
450 EXPECT_EQ(data.offset, stream->offset()); 439 EXPECT_EQ(data.offset, stream->offset());
451 EXPECT_EQ(data.bytes_written, stream->bytes_written()); 440 EXPECT_EQ(data.bytes_written, stream->bytes_written());
452 EXPECT_EQ(data.finished, stream->is_finished()); 441 EXPECT_EQ(data.finished, stream->is_finished());
453 } 442 }
454 443
455 int64_t TotalBytesReceived() const { 444 int64_t TotalBytesReceived() const {
456 DCHECK(download_file_); 445 DCHECK(download_file_);
457 return download_file_->TotalBytesReceived(); 446 return download_file_->TotalBytesReceived();
458 } 447 }
459 448
460 std::unique_ptr<StrictMock<MockDownloadDestinationObserver>> observer_; 449 std::unique_ptr<StrictMock<MockDownloadDestinationObserver>> observer_;
461 base::WeakPtrFactory<DownloadDestinationObserver> observer_factory_; 450 base::WeakPtrFactory<DownloadDestinationObserver> observer_factory_;
462 451
463 // DownloadFile instance we are testing. 452 // DownloadFile instance we are testing.
464 std::unique_ptr<DownloadFileImpl> download_file_; 453 std::unique_ptr<DownloadFileImpl> download_file_;
465 454
466 // Stream for sending data into the download file. 455 // Stream for sending data into the download file.
467 // Owned by download_file_; will be alive for lifetime of download_file_. 456 // Owned by download_file_; will be alive for lifetime of download_file_.
468 StrictMock<MockByteStreamReader>* input_stream_; 457 StrictMock<MockByteStreamReader>* input_stream_;
469 458
470 // A second byte stream to test multiple stream write. 459 // A second byte stream to test multiple stream write.
471 MockByteStreamReader* input_stream_1_; 460 StrictMock<MockByteStreamReader>* input_stream_1_;
472 461
473 // Sink callback data for stream. 462 // Sink callback data for stream.
474 base::Closure sink_callback_; 463 base::Closure sink_callback_;
475 464
476 // Latest update sent to the observer. 465 // Latest update sent to the observer.
477 int64_t bytes_; 466 int64_t bytes_;
478 int64_t bytes_per_sec_; 467 int64_t bytes_per_sec_;
479 468
480 private: 469 private:
481 void SetRenameResult(const base::Closure& closure, 470 void SetRenameResult(const base::Closure& closure,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 DownloadFileTestWithRename, 511 DownloadFileTestWithRename,
523 ::testing::Values(RENAME_AND_ANNOTATE, 512 ::testing::Values(RENAME_AND_ANNOTATE,
524 RENAME_AND_UNIQUIFY)); 513 RENAME_AND_UNIQUIFY));
525 514
526 const char DownloadFileTest::kTestData1[] = 515 const char DownloadFileTest::kTestData1[] =
527 "Let's write some data to the file!\n"; 516 "Let's write some data to the file!\n";
528 const char DownloadFileTest::kTestData2[] = "Writing more data.\n"; 517 const char DownloadFileTest::kTestData2[] = "Writing more data.\n";
529 const char DownloadFileTest::kTestData3[] = "Final line."; 518 const char DownloadFileTest::kTestData3[] = "Final line.";
530 const char DownloadFileTest::kTestData4[] = "abcdefg"; 519 const char DownloadFileTest::kTestData4[] = "abcdefg";
531 const char DownloadFileTest::kTestData5[] = "01234"; 520 const char DownloadFileTest::kTestData5[] = "01234";
521 const char* DownloadFileTest::kTestData6[] = {kTestData1, kTestData2};
522 const char* DownloadFileTest::kTestData7[] = {kTestData4, kTestData5};
523
532 const char DownloadFileTest::kDataHash[] = 524 const char DownloadFileTest::kDataHash[] =
533 "CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8"; 525 "CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8";
534 const char DownloadFileTest::kEmptyHash[] = 526 const char DownloadFileTest::kEmptyHash[] =
535 "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855"; 527 "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855";
536 528
537 const uint32_t DownloadFileTest::kDummyDownloadId = 23; 529 const uint32_t DownloadFileTest::kDummyDownloadId = 23;
538 const int DownloadFileTest::kDummyChildId = 3; 530 const int DownloadFileTest::kDummyChildId = 3;
539 const int DownloadFileTest::kDummyRequestId = 67; 531 const int DownloadFileTest::kDummyRequestId = 67;
540 532
541 // Rename the file before any data is downloaded, after some has, after it all 533 // Rename the file before any data is downloaded, after some has, after it all
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 sink_callback_.Run(); 888 sink_callback_.Run();
897 base::RunLoop().RunUntilIdle(); 889 base::RunLoop().RunUntilIdle();
898 VerifyStreamAndSize(); 890 VerifyStreamAndSize();
899 DestroyDownloadFile(0); 891 DestroyDownloadFile(0);
900 } 892 }
901 893
902 // Tests for concurrent streams handling, used for parallel download. 894 // Tests for concurrent streams handling, used for parallel download.
903 // 895 //
904 // Activate both streams at the same time. 896 // Activate both streams at the same time.
905 TEST_F(DownloadFileTest, MutipleStreamsWrite) { 897 TEST_F(DownloadFileTest, MutipleStreamsWrite) {
906 PrepareMultipleStreams(0); 898 ASSERT_TRUE(CreateDownloadFile(0, true, true));
899 int64_t stream_0_length = GetBuffersLength(kTestData6, 2);
900 int64_t stream_1_length = GetBuffersLength(kTestData7, 2);
901
902 PrepareStream(&input_stream_, 0, false, true, kTestData6, 2);
903 PrepareStream(&input_stream_1_, stream_0_length, true, true, kTestData7, 2);
904 DCHECK(input_stream_1_);
asanka 2017/03/14 19:44:01 DCHECK isn't necessary since the code will reliabl
xingliu 2017/03/14 22:48:29 Done.
905
906 EXPECT_CALL(*input_stream_1_, RegisterCallback(_)).RetiresOnSaturation();
907 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _)); 907 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _));
908 908
909 int64_t stream_0_length = 909 download_file_->AddByteStream(
910 static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2)); 910 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length,
911 int64_t stream_1_length = 911 0);
912 static_cast<int64_t>(strlen(kTestData4) + strlen(kTestData5));
913 912
914 download_file_->AddByteStream( 913 // Activate the streams.
915 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length);
916 sink_callback_.Run(); 914 sink_callback_.Run();
917 base::RunLoop().RunUntilIdle(); 915 base::RunLoop().RunUntilIdle();
918 916
919 SourceStreamTestData stream_data_0(0, stream_0_length, true); 917 SourceStreamTestData stream_data_0(0, stream_0_length, true);
920 SourceStreamTestData stream_data_1(stream_0_length, stream_1_length, true); 918 SourceStreamTestData stream_data_1(stream_0_length, stream_1_length, true);
921 VerifySourceStreamsStates(stream_data_0); 919 VerifySourceStreamsStates(stream_data_0);
922 VerifySourceStreamsStates(stream_data_1); 920 VerifySourceStreamsStates(stream_data_1);
923 EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived()); 921 EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived());
924 922
925 DestroyDownloadFile(0); 923 DestroyDownloadFile(0);
926 } 924 }
927 925
928 // Activate and deplete one stream, later add the second stream. 926 // Activate and deplete one stream, later add the second stream.
929 TEST_F(DownloadFileTest, MutipleStreamsOneStreamFirst) { 927 //
930 PrepareMultipleStreams(0); 928 // Disabled because we are changing the download file completion logic.
929 // The first stream will make the download file complete after it finished.
930 TEST_F(DownloadFileTest, DISABLED_MutipleStreamsOneStreamFirst) {
931 ASSERT_TRUE(CreateDownloadFile(0, true, true));
932 int64_t stream_0_length = GetBuffersLength(kTestData6, 2);
933 int64_t stream_1_length = GetBuffersLength(kTestData7, 2);
931 934
932 int64_t stream_0_length = 935 // Setup and deplete the first stream.
933 static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2)); 936 PrepareStream(&input_stream_, 0, false, true, kTestData6, 2);
934 int64_t stream_1_length =
935 static_cast<int64_t>(strlen(kTestData4) + strlen(kTestData5));
936
937 // Deplete the first stream.
938 sink_callback_.Run(); 937 sink_callback_.Run();
939 base::RunLoop().RunUntilIdle(); 938 base::RunLoop().RunUntilIdle();
940
941 SourceStreamTestData stream_data_0(0, stream_0_length, true); 939 SourceStreamTestData stream_data_0(0, stream_0_length, true);
942 SourceStreamTestData stream_data_1(stream_0_length, 0, false);
943 VerifySourceStreamsStates(stream_data_0); 940 VerifySourceStreamsStates(stream_data_0);
944 VerifySourceStreamsStates(stream_data_1);
945 EXPECT_EQ(stream_0_length, TotalBytesReceived()); 941 EXPECT_EQ(stream_0_length, TotalBytesReceived());
946 942
943 // Setup and activate the second stream.
944 PrepareStream(&input_stream_1_, stream_0_length, true, true, kTestData7, 2);
945 DCHECK(input_stream_1_);
946
947 EXPECT_CALL(*input_stream_1_, RegisterCallback(_)).RetiresOnSaturation();
947 // Won't inform the observer until the second stream is depleted. 948 // Won't inform the observer until the second stream is depleted.
948 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _)); 949 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _));
949
950 // Drain the second stream after the first stream is depleted.
951 download_file_->AddByteStream( 950 download_file_->AddByteStream(
952 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length); 951 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length,
952 0);
953 base::RunLoop().RunUntilIdle(); 953 base::RunLoop().RunUntilIdle();
954 954
955 stream_data_1.bytes_written = stream_1_length; 955 SourceStreamTestData stream_data_1(stream_0_length, stream_1_length, true);
956 stream_data_1.finished = true;
957 VerifySourceStreamsStates(stream_data_0); 956 VerifySourceStreamsStates(stream_data_0);
958 VerifySourceStreamsStates(stream_data_1); 957 VerifySourceStreamsStates(stream_data_1);
959 EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived()); 958 EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived());
960 959
961 DestroyDownloadFile(0); 960 DestroyDownloadFile(0);
962 } 961 }
963 962
964 // Two streams write to one sink, the second stream has a limited length. 963 // Two streams write to one sink, the second stream has a limited length.
965 TEST_F(DownloadFileTest, MutipleStreamsLimitedLength) { 964 TEST_F(DownloadFileTest, MutipleStreamsLimitedLength) {
966 // The second stream has two buffers, kTestData4 and kTestData5. 965 ASSERT_TRUE(CreateDownloadFile(0, true, true));
967 // The length limit is set to less than the length of kTestData4. 966 int64_t stream_0_length = GetBuffersLength(kTestData6, 2);
968 // kTestData4 should be partially written to disk, where kTestData5 should be 967 // The second stream has a limited length and should be partially written
969 // ignored. 968 // to disk.
970 int64_t stream_0_length = 969 int64_t stream_1_length = GetBuffersLength(kTestData7, 2) - 1;
971 static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2));
972 int64_t stream_1_length = static_cast<int64_t>(strlen(kTestData4)) - 1;
973 PrepareMultipleStreams(stream_1_length);
974 970
971 PrepareStream(&input_stream_, 0, false, true, kTestData6, 2);
972 PrepareStream(&input_stream_1_, stream_0_length, true, false, kTestData7, 2);
973
974 EXPECT_CALL(*input_stream_1_, RegisterCallback(_))
975 .Times(2)
976 .RetiresOnSaturation();
975 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _)); 977 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _));
976 978
979 // Activate both streams.
977 download_file_->AddByteStream( 980 download_file_->AddByteStream(
978 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length); 981 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length,
982 stream_1_length);
979 sink_callback_.Run(); 983 sink_callback_.Run();
980 base::RunLoop().RunUntilIdle(); 984 base::RunLoop().RunUntilIdle();
981 985
982 SourceStreamTestData stream_data_0(0, stream_0_length, true); 986 SourceStreamTestData stream_data_0(0, stream_0_length, true);
983 SourceStreamTestData stream_data_1(stream_0_length, stream_1_length, true); 987 SourceStreamTestData stream_data_1(stream_0_length, stream_1_length, true);
984 VerifySourceStreamsStates(stream_data_0); 988 VerifySourceStreamsStates(stream_data_0);
985 VerifySourceStreamsStates(stream_data_1); 989 VerifySourceStreamsStates(stream_data_1);
986 EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived()); 990 EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived());
987 991
988 std::string disk_data, expected_data;
989 EXPECT_TRUE(base::ReadFileToString(download_file_->FullPath(), &disk_data));
990 expected_data.append(kTestData1).append(kTestData2).append(kTestData4);
991 expected_data = expected_data.substr(0, stream_0_length + stream_1_length);
992 EXPECT_EQ(expected_data, disk_data);
993
994 // Finish the second stream.
995 // TODO(xingliu): Refactor test code to deal with unfinished streams.
996 scoped_refptr<net::IOBuffer> data = new net::IOBuffer(strlen(kTestData5));
997 size_t size;
998 input_stream_1_->Read(&data, &size);
999
1000 DestroyDownloadFile(0, false); 992 DestroyDownloadFile(0, false);
1001 } 993 }
1002 994
1003 } // namespace content 995 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698