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