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

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 25 matching lines...) Expand all
188 sink_callback_ = sink_callback; 198 sink_callback_ = sink_callback;
189 } 199 }
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(
199 bool calculate_hash, 209 int offset,
200 bool is_sparse_file = false) { 210 bool calculate_hash,
211 bool is_sparse_file = false,
212 const std::vector<DownloadItem::ReceivedSlice>& received_slices =
David Trainor- moved to gerrit 2017/03/14 17:59:10 Should we pull this out to a def at some point? e
xingliu 2017/03/14 18:26:31 Done, forgot to use DownloadItem::ReceivedSlices i
213 std::vector<DownloadItem::ReceivedSlice>()) {
201 // There can be only one. 214 // There can be only one.
202 DCHECK(!download_file_.get()); 215 DCHECK(!download_file_.get());
203 216
204 input_stream_ = new StrictMock<MockByteStreamReader>(); 217 input_stream_ = new StrictMock<MockByteStreamReader>();
205 218
206 // TODO: Need to actually create a function that'll set the variables 219 // TODO: Need to actually create a function that'll set the variables
207 // based on the inputs from the callback. 220 // based on the inputs from the callback.
208 EXPECT_CALL(*input_stream_, RegisterCallback(_)) 221 EXPECT_CALL(*input_stream_, RegisterCallback(_))
209 .WillOnce(Invoke(this, &DownloadFileTest::RegisterCallback)) 222 .WillOnce(Invoke(this, &DownloadFileTest::RegisterCallback))
210 .RetiresOnSaturation(); 223 .RetiresOnSaturation();
211 224
212 std::unique_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo()); 225 std::unique_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo());
213 download_file_.reset(new TestDownloadFileImpl( 226 download_file_.reset(new TestDownloadFileImpl(
214 std::move(save_info), base::FilePath(), 227 std::move(save_info), base::FilePath(),
215 std::unique_ptr<ByteStreamReader>(input_stream_), 228 std::unique_ptr<ByteStreamReader>(input_stream_), received_slices,
216 std::vector<DownloadItem::ReceivedSlice>(),
217 net::NetLogWithSource(), is_sparse_file, 229 net::NetLogWithSource(), is_sparse_file,
218 observer_factory_.GetWeakPtr())); 230 observer_factory_.GetWeakPtr()));
219 231
220 EXPECT_CALL(*input_stream_, Read(_, _)) 232 EXPECT_CALL(*input_stream_, Read(_, _))
221 .WillOnce(Return(ByteStreamReader::STREAM_EMPTY)) 233 .WillOnce(Return(ByteStreamReader::STREAM_EMPTY))
222 .RetiresOnSaturation(); 234 .RetiresOnSaturation();
223 235
224 base::WeakPtrFactory<DownloadFileTest> weak_ptr_factory(this); 236 base::WeakPtrFactory<DownloadFileTest> weak_ptr_factory(this);
225 DownloadInterruptReason result = DOWNLOAD_INTERRUPT_REASON_NONE; 237 DownloadInterruptReason result = DOWNLOAD_INTERRUPT_REASON_NONE;
226 base::RunLoop loop_runner; 238 base::RunLoop loop_runner;
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 base::Bind(&DownloadFileTest::SetRenameResult, 400 base::Bind(&DownloadFileTest::SetRenameResult,
389 base::Unretained(this), 401 base::Unretained(this),
390 loop_runner.QuitClosure(), 402 loop_runner.QuitClosure(),
391 &result_reason, 403 &result_reason,
392 result_path_p); 404 result_path_p);
393 InvokeRenameMethod(method, full_path, completion_callback); 405 InvokeRenameMethod(method, full_path, completion_callback);
394 loop_runner.Run(); 406 loop_runner.Run();
395 return result_reason; 407 return result_reason;
396 } 408 }
397 409
398 // Prepare two byte streams to write to the same file sink. 410 // Prepare a byte stream to write to the file sink.
399 void PrepareMultipleStreams(int64_t second_stream_length) { 411 void PrepareStream(StrictMock<MockByteStreamReader>** stream,
400 // Create a sparse file. 412 int64_t offset,
401 ASSERT_TRUE(CreateDownloadFile(0, true, true)); 413 bool create_stream,
402 base::FilePath initial_path(download_file_->FullPath()); 414 bool will_finish,
403 EXPECT_TRUE(base::PathExists(initial_path)); 415 const char** buffers,
404 DCHECK(download_file_); 416 size_t num_buffer) {
405 417 if (create_stream)
406 const char* stream_0_data[] = {kTestData1, kTestData2}; 418 *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 419
428 // Expectation on MockByteStreamReader for MultipleStreams tests: 420 // Expectation on MockByteStreamReader for MultipleStreams tests:
429 // 1. RegisterCallback: Must called twice. One to set the callback, the 421 // 1. RegisterCallback: Must called twice. One to set the callback, the
430 // other to release the stream. 422 // other to release the stream.
431 // 2. Read: If filled with N buffer, called (N+1) times, where the last Read 423 // 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. 424 // call doesn't read any data but returns STRAM_COMPLETE.
433 // The stream may terminate in the middle and less Read calls are expected. 425 // 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 426 // 3. GetStatus: Only called if the stream is completed and last Read call
435 // returns STREAM_COMPLETE. 427 // returns STREAM_COMPLETE.
436 if (second_stream_length == 0) 428 Sequence seq;
437 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, input_stream_1_, s1); 429 SetupDataAppend(buffers, num_buffer, *stream, seq, offset);
438 else 430 if (will_finish)
439 EXPECT_CALL(*input_stream_1_, RegisterCallback(_)).RetiresOnSaturation(); 431 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, *stream, seq);
440
441 EXPECT_CALL(*input_stream_1_, RegisterCallback(_)).RetiresOnSaturation();
442 } 432 }
443 433
444 void VerifySourceStreamsStates(const SourceStreamTestData& data) { 434 void VerifySourceStreamsStates(const SourceStreamTestData& data) {
445 DCHECK(download_file_->source_streams_.find(data.offset) != 435 DCHECK(download_file_->source_streams_.find(data.offset) !=
446 download_file_->source_streams_.end()); 436 download_file_->source_streams_.end());
447 DownloadFileImpl::SourceStream* stream = 437 DownloadFileImpl::SourceStream* stream =
448 download_file_->source_streams_[data.offset].get(); 438 download_file_->source_streams_[data.offset].get();
449 DCHECK(stream); 439 DCHECK(stream);
450 EXPECT_EQ(data.offset, stream->offset()); 440 EXPECT_EQ(data.offset, stream->offset());
451 EXPECT_EQ(data.bytes_written, stream->bytes_written()); 441 EXPECT_EQ(data.bytes_written, stream->bytes_written());
452 EXPECT_EQ(data.finished, stream->is_finished()); 442 EXPECT_EQ(data.finished, stream->is_finished());
453 } 443 }
454 444
455 int64_t TotalBytesReceived() const { 445 int64_t TotalBytesReceived() const {
456 DCHECK(download_file_); 446 DCHECK(download_file_);
457 return download_file_->TotalBytesReceived(); 447 return download_file_->TotalBytesReceived();
458 } 448 }
459 449
460 std::unique_ptr<StrictMock<MockDownloadDestinationObserver>> observer_; 450 std::unique_ptr<StrictMock<MockDownloadDestinationObserver>> observer_;
461 base::WeakPtrFactory<DownloadDestinationObserver> observer_factory_; 451 base::WeakPtrFactory<DownloadDestinationObserver> observer_factory_;
462 452
463 // DownloadFile instance we are testing. 453 // DownloadFile instance we are testing.
464 std::unique_ptr<DownloadFileImpl> download_file_; 454 std::unique_ptr<DownloadFileImpl> download_file_;
465 455
466 // Stream for sending data into the download file. 456 // Stream for sending data into the download file.
467 // Owned by download_file_; will be alive for lifetime of download_file_. 457 // Owned by download_file_; will be alive for lifetime of download_file_.
468 StrictMock<MockByteStreamReader>* input_stream_; 458 StrictMock<MockByteStreamReader>* input_stream_;
469 459
470 // A second byte stream to test multiple stream write. 460 // A second byte stream to test multiple stream write.
471 MockByteStreamReader* input_stream_1_; 461 StrictMock<MockByteStreamReader>* input_stream_1_;
472 462
473 // Sink callback data for stream. 463 // Sink callback data for stream.
474 base::Closure sink_callback_; 464 base::Closure sink_callback_;
475 465
476 // Latest update sent to the observer. 466 // Latest update sent to the observer.
477 int64_t bytes_; 467 int64_t bytes_;
478 int64_t bytes_per_sec_; 468 int64_t bytes_per_sec_;
479 469
480 private: 470 private:
481 void SetRenameResult(const base::Closure& closure, 471 void SetRenameResult(const base::Closure& closure,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 DownloadFileTestWithRename, 512 DownloadFileTestWithRename,
523 ::testing::Values(RENAME_AND_ANNOTATE, 513 ::testing::Values(RENAME_AND_ANNOTATE,
524 RENAME_AND_UNIQUIFY)); 514 RENAME_AND_UNIQUIFY));
525 515
526 const char DownloadFileTest::kTestData1[] = 516 const char DownloadFileTest::kTestData1[] =
527 "Let's write some data to the file!\n"; 517 "Let's write some data to the file!\n";
528 const char DownloadFileTest::kTestData2[] = "Writing more data.\n"; 518 const char DownloadFileTest::kTestData2[] = "Writing more data.\n";
529 const char DownloadFileTest::kTestData3[] = "Final line."; 519 const char DownloadFileTest::kTestData3[] = "Final line.";
530 const char DownloadFileTest::kTestData4[] = "abcdefg"; 520 const char DownloadFileTest::kTestData4[] = "abcdefg";
531 const char DownloadFileTest::kTestData5[] = "01234"; 521 const char DownloadFileTest::kTestData5[] = "01234";
522 const char* DownloadFileTest::kTestData6[] = {kTestData1, kTestData2};
523 const char* DownloadFileTest::kTestData7[] = {kTestData4, kTestData5};
524
532 const char DownloadFileTest::kDataHash[] = 525 const char DownloadFileTest::kDataHash[] =
533 "CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8"; 526 "CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8";
534 const char DownloadFileTest::kEmptyHash[] = 527 const char DownloadFileTest::kEmptyHash[] =
535 "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855"; 528 "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855";
536 529
537 const uint32_t DownloadFileTest::kDummyDownloadId = 23; 530 const uint32_t DownloadFileTest::kDummyDownloadId = 23;
538 const int DownloadFileTest::kDummyChildId = 3; 531 const int DownloadFileTest::kDummyChildId = 3;
539 const int DownloadFileTest::kDummyRequestId = 67; 532 const int DownloadFileTest::kDummyRequestId = 67;
540 533
541 // Rename the file before any data is downloaded, after some has, after it all 534 // 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(); 889 sink_callback_.Run();
897 base::RunLoop().RunUntilIdle(); 890 base::RunLoop().RunUntilIdle();
898 VerifyStreamAndSize(); 891 VerifyStreamAndSize();
899 DestroyDownloadFile(0); 892 DestroyDownloadFile(0);
900 } 893 }
901 894
902 // Tests for concurrent streams handling, used for parallel download. 895 // Tests for concurrent streams handling, used for parallel download.
903 // 896 //
904 // Activate both streams at the same time. 897 // Activate both streams at the same time.
905 TEST_F(DownloadFileTest, MutipleStreamsWrite) { 898 TEST_F(DownloadFileTest, MutipleStreamsWrite) {
906 PrepareMultipleStreams(0); 899 ASSERT_TRUE(CreateDownloadFile(0, true, true));
900 int64_t stream_0_length = GetBuffersLength(kTestData6, 2);
901 int64_t stream_1_length = GetBuffersLength(kTestData7, 2);
902
903 PrepareStream(&input_stream_, 0, false, true, kTestData6, 2);
904 PrepareStream(&input_stream_1_, stream_0_length, true, true, kTestData7, 2);
905 DCHECK(input_stream_1_);
906
907 EXPECT_CALL(*input_stream_1_, RegisterCallback(_)).RetiresOnSaturation();
907 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _)); 908 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _));
908 909
909 int64_t stream_0_length = 910 download_file_->AddByteStream(
910 static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2)); 911 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length,
911 int64_t stream_1_length = 912 0);
912 static_cast<int64_t>(strlen(kTestData4) + strlen(kTestData5));
913 913
914 download_file_->AddByteStream( 914 // Activate the streams.
915 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length);
916 sink_callback_.Run(); 915 sink_callback_.Run();
917 base::RunLoop().RunUntilIdle(); 916 base::RunLoop().RunUntilIdle();
918 917
919 SourceStreamTestData stream_data_0(0, stream_0_length, true); 918 SourceStreamTestData stream_data_0(0, stream_0_length, true);
920 SourceStreamTestData stream_data_1(stream_0_length, stream_1_length, true); 919 SourceStreamTestData stream_data_1(stream_0_length, stream_1_length, true);
921 VerifySourceStreamsStates(stream_data_0); 920 VerifySourceStreamsStates(stream_data_0);
922 VerifySourceStreamsStates(stream_data_1); 921 VerifySourceStreamsStates(stream_data_1);
923 EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived()); 922 EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived());
924 923
925 DestroyDownloadFile(0); 924 DestroyDownloadFile(0);
926 } 925 }
927 926
928 // Activate and deplete one stream, later add the second stream. 927 // Activate and deplete one stream, later add the second stream.
929 TEST_F(DownloadFileTest, MutipleStreamsOneStreamFirst) { 928 //
930 PrepareMultipleStreams(0); 929 // Disabled because we are changing the download file completion logic.
930 // The first stream will make the download file complete after it finished.
931 TEST_F(DownloadFileTest, DISABLED_MutipleStreamsOneStreamFirst) {
932 ASSERT_TRUE(CreateDownloadFile(0, true, true));
933 int64_t stream_0_length = GetBuffersLength(kTestData6, 2);
934 int64_t stream_1_length = GetBuffersLength(kTestData7, 2);
931 935
932 int64_t stream_0_length = 936 // Setup and deplete the first stream.
933 static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2)); 937 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(); 938 sink_callback_.Run();
939 base::RunLoop().RunUntilIdle(); 939 base::RunLoop().RunUntilIdle();
940
941 SourceStreamTestData stream_data_0(0, stream_0_length, true); 940 SourceStreamTestData stream_data_0(0, stream_0_length, true);
942 SourceStreamTestData stream_data_1(stream_0_length, 0, false);
943 VerifySourceStreamsStates(stream_data_0); 941 VerifySourceStreamsStates(stream_data_0);
944 VerifySourceStreamsStates(stream_data_1);
945 EXPECT_EQ(stream_0_length, TotalBytesReceived()); 942 EXPECT_EQ(stream_0_length, TotalBytesReceived());
946 943
944 // Setup and activate the second stream.
945 PrepareStream(&input_stream_1_, stream_0_length, true, true, kTestData7, 2);
946 DCHECK(input_stream_1_);
947
948 EXPECT_CALL(*input_stream_1_, RegisterCallback(_)).RetiresOnSaturation();
947 // Won't inform the observer until the second stream is depleted. 949 // Won't inform the observer until the second stream is depleted.
948 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _)); 950 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _));
949
950 // Drain the second stream after the first stream is depleted.
951 download_file_->AddByteStream( 951 download_file_->AddByteStream(
952 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length); 952 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length,
953 0);
953 base::RunLoop().RunUntilIdle(); 954 base::RunLoop().RunUntilIdle();
954 955
955 stream_data_1.bytes_written = stream_1_length; 956 SourceStreamTestData stream_data_1(stream_0_length, stream_1_length, true);
956 stream_data_1.finished = true;
957 VerifySourceStreamsStates(stream_data_0); 957 VerifySourceStreamsStates(stream_data_0);
958 VerifySourceStreamsStates(stream_data_1); 958 VerifySourceStreamsStates(stream_data_1);
959 EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived()); 959 EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived());
960 960
961 DestroyDownloadFile(0); 961 DestroyDownloadFile(0);
962 } 962 }
963 963
964 // Two streams write to one sink, the second stream has a limited length. 964 // Two streams write to one sink, the second stream has a limited length.
965 TEST_F(DownloadFileTest, MutipleStreamsLimitedLength) { 965 TEST_F(DownloadFileTest, MutipleStreamsLimitedLength) {
966 // The second stream has two buffers, kTestData4 and kTestData5. 966 ASSERT_TRUE(CreateDownloadFile(0, true, true));
967 // The length limit is set to less than the length of kTestData4. 967 int64_t stream_0_length = GetBuffersLength(kTestData6, 2);
968 // kTestData4 should be partially written to disk, where kTestData5 should be 968 // The second stream has a limited length and should be partially written
969 // ignored. 969 // to disk.
970 int64_t stream_0_length = 970 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 971
972 PrepareStream(&input_stream_, 0, false, true, kTestData6, 2);
973 PrepareStream(&input_stream_1_, stream_0_length, true, false, kTestData7, 2);
974
975 EXPECT_CALL(*input_stream_1_, RegisterCallback(_))
976 .Times(2)
977 .RetiresOnSaturation();
975 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _)); 978 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _));
976 979
980 // Activate both streams.
977 download_file_->AddByteStream( 981 download_file_->AddByteStream(
978 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length); 982 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length,
983 stream_1_length);
979 sink_callback_.Run(); 984 sink_callback_.Run();
980 base::RunLoop().RunUntilIdle(); 985 base::RunLoop().RunUntilIdle();
981 986
982 SourceStreamTestData stream_data_0(0, stream_0_length, true); 987 SourceStreamTestData stream_data_0(0, stream_0_length, true);
983 SourceStreamTestData stream_data_1(stream_0_length, stream_1_length, true); 988 SourceStreamTestData stream_data_1(stream_0_length, stream_1_length, true);
984 VerifySourceStreamsStates(stream_data_0); 989 VerifySourceStreamsStates(stream_data_0);
985 VerifySourceStreamsStates(stream_data_1); 990 VerifySourceStreamsStates(stream_data_1);
986 EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived()); 991 EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived());
987 992
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); 993 DestroyDownloadFile(0, false);
1001 } 994 }
1002 995
1003 } // namespace content 996 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698