| 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 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 loop_runner.QuitClosure(), | 390 loop_runner.QuitClosure(), |
| 391 &result_reason, | 391 &result_reason, |
| 392 result_path_p); | 392 result_path_p); |
| 393 InvokeRenameMethod(method, full_path, completion_callback); | 393 InvokeRenameMethod(method, full_path, completion_callback); |
| 394 loop_runner.Run(); | 394 loop_runner.Run(); |
| 395 return result_reason; | 395 return result_reason; |
| 396 } | 396 } |
| 397 | 397 |
| 398 // Prepare two byte streams to write to the same file sink. If | 398 // Prepare two byte streams to write to the same file sink. If |
| 399 // |first_stream_completes_early| is true, the first stream will complete | 399 // |first_stream_completes_early| is true, the first stream will complete |
| 400 // before the second stream starts. | 400 // before the second stream starts. If |first_stream_write_all_data| is true, |
| 401 // the first stream will write all the data before the 2nd stream starts. |
| 401 void PrepareMultipleStreams(bool first_stream_completes_early, | 402 void PrepareMultipleStreams(bool first_stream_completes_early, |
| 403 bool first_stream_write_all_data, |
| 402 int64_t second_stream_length) { | 404 int64_t second_stream_length) { |
| 403 // Create a sparse file. | 405 // Create a sparse file. |
| 404 ASSERT_TRUE(CreateDownloadFile(0, true, true)); | 406 ASSERT_TRUE(CreateDownloadFile(0, true, true)); |
| 405 base::FilePath initial_path(download_file_->FullPath()); | 407 base::FilePath initial_path(download_file_->FullPath()); |
| 406 EXPECT_TRUE(base::PathExists(initial_path)); | 408 EXPECT_TRUE(base::PathExists(initial_path)); |
| 407 DCHECK(download_file_); | 409 DCHECK(download_file_); |
| 408 | 410 |
| 409 const char* stream_0_data[] = {kTestData1, kTestData2}; | 411 const char* stream_0_data[] = {kTestData1, kTestData2}; |
| 410 const char* stream_1_data[] = {kTestData4, kTestData5}; | 412 const char* stream_1_data[] = {kTestData4, kTestData5}; |
| 413 const char* all_data[] = {kTestData1, kTestData2, kTestData4, kTestData5}; |
| 411 size_t stream_1_offset = strlen(kTestData1) + strlen(kTestData2); | 414 size_t stream_1_offset = strlen(kTestData1) + strlen(kTestData2); |
| 412 | 415 |
| 413 // Register second SourceStream entry for the second stream. | 416 // Register second SourceStream entry for the second stream. |
| 414 // The first stream should be registered in ctor of DownloadFile. | 417 // The first stream should be registered in ctor of DownloadFile. |
| 415 DownloadFileImpl::SourceStreams& source_streams = | 418 DownloadFileImpl::SourceStreams& source_streams = |
| 416 download_file_->source_streams_; | 419 download_file_->source_streams_; |
| 417 EXPECT_EQ(static_cast<size_t>(1), source_streams.size()); | 420 EXPECT_EQ(static_cast<size_t>(1), source_streams.size()); |
| 418 source_streams[stream_1_offset] = | 421 source_streams[stream_1_offset] = |
| 419 base::MakeUnique<DownloadFileImpl::SourceStream>(stream_1_offset, | 422 base::MakeUnique<DownloadFileImpl::SourceStream>(stream_1_offset, |
| 420 second_stream_length); | 423 second_stream_length); |
| 421 | 424 |
| 422 // Create the second byte stream. Will be moved to DownloadFile. | 425 // Create the second byte stream. Will be moved to DownloadFile. |
| 423 input_stream_1_ = new MockByteStreamReader(); | 426 input_stream_1_ = new MockByteStreamReader(); |
| 424 | 427 |
| 425 ::testing::Sequence s0; | 428 ::testing::Sequence s0; |
| 426 ::testing::Sequence s1; | 429 ::testing::Sequence s1; |
| 427 SetupDataAppend(stream_1_data, 2, input_stream_1_, s1, stream_1_offset); | 430 if (first_stream_write_all_data) { |
| 428 SetupDataAppend(stream_0_data, 2, input_stream_, s0, 0); | 431 SetupDataAppend(all_data, 4, input_stream_, s0, 0); |
| 432 // The 2nd stream will abort after the first read |
| 433 SetupDataAppend(stream_1_data, 1, input_stream_1_, s1, stream_1_offset); |
| 434 } else { |
| 435 SetupDataAppend(stream_0_data, 2, input_stream_, s0, 0); |
| 436 SetupDataAppend(stream_1_data, 2, input_stream_1_, s1, stream_1_offset); |
| 437 } |
| 438 |
| 429 // If the first stream doesn't finish before the second stream starts | 439 // If the first stream doesn't finish before the second stream starts |
| 430 // writing, its length will be cut short by the second stream. So | 440 // writing, its length will be cut short by the second stream. So |
| 431 // STREAM_COMPLETE will never get called. | 441 // STREAM_COMPLETE will never get called. |
| 432 if (first_stream_completes_early) | 442 if (first_stream_completes_early) |
| 433 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, input_stream_, s0); | 443 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, input_stream_, s0); |
| 434 else | 444 else |
| 435 EXPECT_CALL(*input_stream_, RegisterCallback(_)).RetiresOnSaturation(); | 445 EXPECT_CALL(*input_stream_, RegisterCallback(_)).RetiresOnSaturation(); |
| 436 | 446 |
| 437 // Expectation on MockByteStreamReader for MultipleStreams tests: | 447 // Expectation on MockByteStreamReader for MultipleStreams tests: |
| 438 // 1. RegisterCallback: Must called twice. One to set the callback, the | 448 // 1. RegisterCallback: Must called twice. One to set the callback, the |
| 439 // other to release the stream. | 449 // other to release the stream. |
| 440 // 2. Read: If filled with N buffer, called (N+1) times, where the last Read | 450 // 2. Read: If filled with N buffer, called (N+1) times, where the last Read |
| 441 // call doesn't read any data but returns STREAM_COMPLETE. | 451 // call doesn't read any data but returns STREAM_COMPLETE. |
| 442 // The stream may terminate in the middle and less Read calls are expected. | 452 // The stream may terminate in the middle and less Read calls are expected. |
| 443 // 3. GetStatus: Only called if the stream is completed and last Read call | 453 // 3. GetStatus: Only called if the stream is completed and last Read call |
| 444 // returns STREAM_COMPLETE. | 454 // returns STREAM_COMPLETE. |
| 445 if (second_stream_length == 0) | 455 if (second_stream_length == 0 && !first_stream_write_all_data) |
| 446 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, input_stream_1_, s1); | 456 SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, input_stream_1_, s1); |
| 447 else | 457 else |
| 448 EXPECT_CALL(*input_stream_1_, RegisterCallback(_)).RetiresOnSaturation(); | 458 EXPECT_CALL(*input_stream_1_, RegisterCallback(_)).RetiresOnSaturation(); |
| 449 | 459 |
| 450 EXPECT_CALL(*input_stream_1_, RegisterCallback(_)).RetiresOnSaturation(); | 460 EXPECT_CALL(*input_stream_1_, RegisterCallback(_)).RetiresOnSaturation(); |
| 451 } | 461 } |
| 452 | 462 |
| 453 void VerifySourceStreamsStates(const SourceStreamTestData& data) { | 463 void VerifySourceStreamsStates(const SourceStreamTestData& data) { |
| 454 DCHECK(download_file_->source_streams_.find(data.offset) != | 464 DCHECK(download_file_->source_streams_.find(data.offset) != |
| 455 download_file_->source_streams_.end()); | 465 download_file_->source_streams_.end()); |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 sink_callback_.Run(); | 915 sink_callback_.Run(); |
| 906 base::RunLoop().RunUntilIdle(); | 916 base::RunLoop().RunUntilIdle(); |
| 907 VerifyStreamAndSize(); | 917 VerifyStreamAndSize(); |
| 908 DestroyDownloadFile(0); | 918 DestroyDownloadFile(0); |
| 909 } | 919 } |
| 910 | 920 |
| 911 // Tests for concurrent streams handling, used for parallel download. | 921 // Tests for concurrent streams handling, used for parallel download. |
| 912 // | 922 // |
| 913 // Activate both streams at the same time. | 923 // Activate both streams at the same time. |
| 914 TEST_F(DownloadFileTest, MutipleStreamsWrite) { | 924 TEST_F(DownloadFileTest, MutipleStreamsWrite) { |
| 915 PrepareMultipleStreams(false, 0); | 925 PrepareMultipleStreams(false, false, 0); |
| 916 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _)); | 926 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _)); |
| 917 | 927 |
| 918 int64_t stream_0_length = | 928 int64_t stream_0_length = |
| 919 static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2)); | 929 static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2)); |
| 920 int64_t stream_1_length = | 930 int64_t stream_1_length = |
| 921 static_cast<int64_t>(strlen(kTestData4) + strlen(kTestData5)); | 931 static_cast<int64_t>(strlen(kTestData4) + strlen(kTestData5)); |
| 922 | 932 |
| 923 download_file_->AddByteStream( | 933 download_file_->AddByteStream( |
| 924 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length); | 934 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length); |
| 925 sink_callback_.Run(); | 935 sink_callback_.Run(); |
| 926 base::RunLoop().RunUntilIdle(); | 936 base::RunLoop().RunUntilIdle(); |
| 927 | 937 |
| 928 SourceStreamTestData stream_data_0(0, stream_0_length, true); | 938 SourceStreamTestData stream_data_0(0, stream_0_length, true); |
| 929 SourceStreamTestData stream_data_1(stream_0_length, stream_1_length, true); | 939 SourceStreamTestData stream_data_1(stream_0_length, stream_1_length, true); |
| 930 VerifySourceStreamsStates(stream_data_0); | 940 VerifySourceStreamsStates(stream_data_0); |
| 931 VerifySourceStreamsStates(stream_data_1); | 941 VerifySourceStreamsStates(stream_data_1); |
| 932 EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived()); | 942 EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived()); |
| 933 | 943 |
| 934 DestroyDownloadFile(0); | 944 DestroyDownloadFile(0); |
| 935 } | 945 } |
| 936 | 946 |
| 937 // Activate and deplete one stream, later add the second stream. | 947 // Activate and deplete one stream, later add the second stream. |
| 938 TEST_F(DownloadFileTest, MutipleStreamsOneStreamFirst) { | 948 TEST_F(DownloadFileTest, MutipleStreamsOneStreamFirst) { |
| 939 PrepareMultipleStreams(true, 0); | 949 PrepareMultipleStreams(true, false, 0); |
| 940 | 950 |
| 941 int64_t stream_0_length = | 951 int64_t stream_0_length = |
| 942 static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2)); | 952 static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2)); |
| 943 int64_t stream_1_length = | 953 int64_t stream_1_length = |
| 944 static_cast<int64_t>(strlen(kTestData4) + strlen(kTestData5)); | 954 static_cast<int64_t>(strlen(kTestData4) + strlen(kTestData5)); |
| 945 | 955 |
| 946 // Deplete the first stream. | 956 // Deplete the first stream. |
| 947 sink_callback_.Run(); | 957 sink_callback_.Run(); |
| 948 base::RunLoop().RunUntilIdle(); | 958 base::RunLoop().RunUntilIdle(); |
| 949 | 959 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 972 | 982 |
| 973 // Two streams write to one sink, the second stream has a limited length. | 983 // Two streams write to one sink, the second stream has a limited length. |
| 974 TEST_F(DownloadFileTest, MutipleStreamsLimitedLength) { | 984 TEST_F(DownloadFileTest, MutipleStreamsLimitedLength) { |
| 975 // The second stream has two buffers, kTestData4 and kTestData5. | 985 // The second stream has two buffers, kTestData4 and kTestData5. |
| 976 // The length limit is set to less than the length of kTestData4. | 986 // The length limit is set to less than the length of kTestData4. |
| 977 // kTestData4 should be partially written to disk, where kTestData5 should be | 987 // kTestData4 should be partially written to disk, where kTestData5 should be |
| 978 // ignored. | 988 // ignored. |
| 979 int64_t stream_0_length = | 989 int64_t stream_0_length = |
| 980 static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2)); | 990 static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2)); |
| 981 int64_t stream_1_length = static_cast<int64_t>(strlen(kTestData4)) - 1; | 991 int64_t stream_1_length = static_cast<int64_t>(strlen(kTestData4)) - 1; |
| 982 PrepareMultipleStreams(false, stream_1_length); | 992 PrepareMultipleStreams(false, false, stream_1_length); |
| 983 | 993 |
| 984 download_file_->AddByteStream( | 994 download_file_->AddByteStream( |
| 985 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length); | 995 std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length); |
| 986 sink_callback_.Run(); | 996 sink_callback_.Run(); |
| 987 base::RunLoop().RunUntilIdle(); | 997 base::RunLoop().RunUntilIdle(); |
| 988 | 998 |
| 989 SourceStreamTestData stream_data_0(0, stream_0_length, true); | 999 SourceStreamTestData stream_data_0(0, stream_0_length, true); |
| 990 SourceStreamTestData stream_data_1(stream_0_length, stream_1_length, true); | 1000 SourceStreamTestData stream_data_1(stream_0_length, stream_1_length, true); |
| 991 VerifySourceStreamsStates(stream_data_0); | 1001 VerifySourceStreamsStates(stream_data_0); |
| 992 VerifySourceStreamsStates(stream_data_1); | 1002 VerifySourceStreamsStates(stream_data_1); |
| 993 EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived()); | 1003 EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived()); |
| 994 | 1004 |
| 995 std::string disk_data, expected_data; | 1005 std::string disk_data, expected_data; |
| 996 EXPECT_TRUE(base::ReadFileToString(download_file_->FullPath(), &disk_data)); | 1006 EXPECT_TRUE(base::ReadFileToString(download_file_->FullPath(), &disk_data)); |
| 997 expected_data.append(kTestData1).append(kTestData2).append(kTestData4); | 1007 expected_data.append(kTestData1).append(kTestData2).append(kTestData4); |
| 998 expected_data = expected_data.substr(0, stream_0_length + stream_1_length); | 1008 expected_data = expected_data.substr(0, stream_0_length + stream_1_length); |
| 999 EXPECT_EQ(expected_data, disk_data); | 1009 EXPECT_EQ(expected_data, disk_data); |
| 1000 | 1010 |
| 1001 // Finish the second stream. | 1011 // Finish the second stream. |
| 1002 // TODO(xingliu): Refactor test code to deal with unfinished streams. | 1012 // TODO(xingliu): Refactor test code to deal with unfinished streams. |
| 1003 scoped_refptr<net::IOBuffer> data = new net::IOBuffer(strlen(kTestData5)); | 1013 scoped_refptr<net::IOBuffer> data = new net::IOBuffer(strlen(kTestData5)); |
| 1004 size_t size; | 1014 size_t size; |
| 1005 input_stream_1_->Read(&data, &size); | 1015 input_stream_1_->Read(&data, &size); |
| 1006 | 1016 |
| 1007 download_file_->Cancel(); | 1017 download_file_->Cancel(); |
| 1008 DestroyDownloadFile(0, false); | 1018 DestroyDownloadFile(0, false); |
| 1009 } | 1019 } |
| 1010 | 1020 |
| 1021 // Two streams write to one sink, the first stream writes the whole file before |
| 1022 // the seconds stream was able to start |
| 1023 TEST_F(DownloadFileTest, MutipleStreamsFirstStreamWriteAllData) { |
| 1024 PrepareMultipleStreams(true, true, 0); |
| 1025 int64_t stream_0_length = |
| 1026 static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2) + |
| 1027 strlen(kTestData4) + strlen(kTestData5)); |
| 1028 int64_t stream_1_length = |
| 1029 static_cast<int64_t>(strlen(kTestData4) + strlen(kTestData5)); |
| 1030 sink_callback_.Run(); |
| 1031 base::RunLoop().RunUntilIdle(); |
| 1032 |
| 1033 EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _)); |
| 1034 |
| 1035 download_file_->AddByteStream( |
| 1036 std::unique_ptr<MockByteStreamReader>(input_stream_1_), |
| 1037 stream_0_length - stream_1_length); |
| 1038 base::RunLoop().RunUntilIdle(); |
| 1039 |
| 1040 SourceStreamTestData stream_data_0(0, stream_0_length, true); |
| 1041 SourceStreamTestData stream_data_1(stream_0_length - stream_1_length, 0, |
| 1042 true); |
| 1043 VerifySourceStreamsStates(stream_data_0); |
| 1044 VerifySourceStreamsStates(stream_data_1); |
| 1045 EXPECT_EQ(stream_0_length, TotalBytesReceived()); |
| 1046 |
| 1047 DestroyDownloadFile(0); |
| 1048 } |
| 1049 |
| 1011 } // namespace content | 1050 } // namespace content |
| OLD | NEW |