Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |