Chromium Code Reviews| Index: content/browser/download/download_file_unittest.cc |
| diff --git a/content/browser/download/download_file_unittest.cc b/content/browser/download/download_file_unittest.cc |
| index 055b883e9364a894b1b77c7fe48a1220d93caefe..14c23d3587bd78723402869972a6b2f0800f16df 100644 |
| --- a/content/browser/download/download_file_unittest.cc |
| +++ b/content/browser/download/download_file_unittest.cc |
| @@ -39,6 +39,7 @@ using ::testing::AnyNumber; |
| using ::testing::DoAll; |
| using ::testing::InSequence; |
| using ::testing::Return; |
| +using ::testing::Sequence; |
| using ::testing::SetArgPointee; |
| using ::testing::StrictMock; |
| @@ -54,6 +55,13 @@ struct SourceStreamTestData { |
| bool finished; |
| }; |
| +int64_t GetBuffersLength(const char** buffers, size_t num_buffer) { |
| + int64_t result = 0; |
| + for (size_t i = 0; i < num_buffer; ++i) |
| + result += static_cast<int64_t>(strlen(buffers[i])); |
| + return result; |
| +} |
| + |
| std::string GetHexEncodedHashValue(crypto::SecureHash* hash_state) { |
| if (!hash_state) |
| return std::string(); |
| @@ -150,6 +158,8 @@ class DownloadFileTest : public testing::Test { |
| static const char kTestData3[]; |
| static const char kTestData4[]; |
| static const char kTestData5[]; |
| + static const char* kTestData6[]; |
| + static const char* kTestData7[]; |
| static const char kDataHash[]; |
| static const char kEmptyHash[]; |
| static const uint32_t kDummyDownloadId; |
| @@ -197,7 +207,9 @@ class DownloadFileTest : public testing::Test { |
| bool CreateDownloadFile(int offset, |
| bool calculate_hash, |
| - bool is_sparse_file = false) { |
| + bool is_sparse_file = false, |
| + const DownloadItem::ReceivedSlices& received_slices = |
| + DownloadItem::ReceivedSlices()) { |
| // There can be only one. |
| DCHECK(!download_file_.get()); |
| @@ -212,8 +224,7 @@ class DownloadFileTest : public testing::Test { |
| std::unique_ptr<DownloadSaveInfo> save_info(new DownloadSaveInfo()); |
| download_file_.reset(new TestDownloadFileImpl( |
| std::move(save_info), base::FilePath(), |
| - std::unique_ptr<ByteStreamReader>(input_stream_), |
| - std::vector<DownloadItem::ReceivedSlice>(), |
| + std::unique_ptr<ByteStreamReader>(input_stream_), received_slices, |
| net::NetLogWithSource(), is_sparse_file, |
| observer_factory_.GetWeakPtr())); |
| @@ -395,35 +406,15 @@ class DownloadFileTest : public testing::Test { |
| return result_reason; |
| } |
| - // Prepare two byte streams to write to the same file sink. |
| - void PrepareMultipleStreams(int64_t second_stream_length) { |
| - // Create a sparse file. |
| - ASSERT_TRUE(CreateDownloadFile(0, true, true)); |
| - base::FilePath initial_path(download_file_->FullPath()); |
| - EXPECT_TRUE(base::PathExists(initial_path)); |
| - DCHECK(download_file_); |
| - |
| - const char* stream_0_data[] = {kTestData1, kTestData2}; |
| - const char* stream_1_data[] = {kTestData4, kTestData5}; |
| - size_t stream_1_offset = strlen(kTestData1) + strlen(kTestData2); |
| - |
| - // Register second SourceStream entry for the second stream. |
| - // The first stream should be registered in ctor of DownloadFile. |
| - DownloadFileImpl::SourceStreams& source_streams = |
| - download_file_->source_streams_; |
| - EXPECT_EQ(static_cast<size_t>(1), source_streams.size()); |
| - source_streams[stream_1_offset] = |
| - base::MakeUnique<DownloadFileImpl::SourceStream>(stream_1_offset, |
| - second_stream_length); |
| - |
| - // Create the second byte stream. Will be moved to DownloadFile. |
| - input_stream_1_ = new MockByteStreamReader(); |
| - |
| - ::testing::Sequence s0; |
| - ::testing::Sequence s1; |
| - SetupDataAppend(stream_1_data, 2, input_stream_1_, s1, stream_1_offset); |
| - SetupDataAppend(stream_0_data, 2, input_stream_, s0, 0); |
| - SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, input_stream_, s0); |
| + // Prepare a byte stream to write to the file sink. |
| + void PrepareStream(StrictMock<MockByteStreamReader>** stream, |
| + int64_t offset, |
| + bool create_stream, |
| + bool will_finish, |
| + const char** buffers, |
| + size_t num_buffer) { |
| + if (create_stream) |
| + *stream = new StrictMock<MockByteStreamReader>(); |
| // Expectation on MockByteStreamReader for MultipleStreams tests: |
| // 1. RegisterCallback: Must called twice. One to set the callback, the |
| @@ -433,12 +424,10 @@ class DownloadFileTest : public testing::Test { |
| // The stream may terminate in the middle and less Read calls are expected. |
| // 3. GetStatus: Only called if the stream is completed and last Read call |
| // returns STREAM_COMPLETE. |
| - if (second_stream_length == 0) |
| - SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, input_stream_1_, s1); |
| - else |
| - EXPECT_CALL(*input_stream_1_, RegisterCallback(_)).RetiresOnSaturation(); |
| - |
| - EXPECT_CALL(*input_stream_1_, RegisterCallback(_)).RetiresOnSaturation(); |
| + Sequence seq; |
| + SetupDataAppend(buffers, num_buffer, *stream, seq, offset); |
| + if (will_finish) |
| + SetupFinishStream(DOWNLOAD_INTERRUPT_REASON_NONE, *stream, seq); |
| } |
| void VerifySourceStreamsStates(const SourceStreamTestData& data) { |
| @@ -468,7 +457,7 @@ class DownloadFileTest : public testing::Test { |
| StrictMock<MockByteStreamReader>* input_stream_; |
| // A second byte stream to test multiple stream write. |
| - MockByteStreamReader* input_stream_1_; |
| + StrictMock<MockByteStreamReader>* input_stream_1_; |
| // Sink callback data for stream. |
| base::Closure sink_callback_; |
| @@ -529,6 +518,9 @@ const char DownloadFileTest::kTestData2[] = "Writing more data.\n"; |
| const char DownloadFileTest::kTestData3[] = "Final line."; |
| const char DownloadFileTest::kTestData4[] = "abcdefg"; |
| const char DownloadFileTest::kTestData5[] = "01234"; |
| +const char* DownloadFileTest::kTestData6[] = {kTestData1, kTestData2}; |
| +const char* DownloadFileTest::kTestData7[] = {kTestData4, kTestData5}; |
| + |
| const char DownloadFileTest::kDataHash[] = |
| "CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8"; |
| const char DownloadFileTest::kEmptyHash[] = |
| @@ -903,16 +895,22 @@ TEST_F(DownloadFileTest, StreamNonEmptyError) { |
| // |
| // Activate both streams at the same time. |
| TEST_F(DownloadFileTest, MutipleStreamsWrite) { |
| - PrepareMultipleStreams(0); |
| - EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _)); |
| + ASSERT_TRUE(CreateDownloadFile(0, true, true)); |
| + int64_t stream_0_length = GetBuffersLength(kTestData6, 2); |
| + int64_t stream_1_length = GetBuffersLength(kTestData7, 2); |
| + |
| + PrepareStream(&input_stream_, 0, false, true, kTestData6, 2); |
| + PrepareStream(&input_stream_1_, stream_0_length, true, true, kTestData7, 2); |
| + 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.
|
| - int64_t stream_0_length = |
| - static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2)); |
| - int64_t stream_1_length = |
| - static_cast<int64_t>(strlen(kTestData4) + strlen(kTestData5)); |
| + EXPECT_CALL(*input_stream_1_, RegisterCallback(_)).RetiresOnSaturation(); |
| + EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _)); |
| download_file_->AddByteStream( |
| - std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length); |
| + std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length, |
| + 0); |
| + |
| + // Activate the streams. |
| sink_callback_.Run(); |
| base::RunLoop().RunUntilIdle(); |
| @@ -926,34 +924,35 @@ TEST_F(DownloadFileTest, MutipleStreamsWrite) { |
| } |
| // Activate and deplete one stream, later add the second stream. |
| -TEST_F(DownloadFileTest, MutipleStreamsOneStreamFirst) { |
| - PrepareMultipleStreams(0); |
| - |
| - int64_t stream_0_length = |
| - static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2)); |
| - int64_t stream_1_length = |
| - static_cast<int64_t>(strlen(kTestData4) + strlen(kTestData5)); |
| - |
| - // Deplete the first stream. |
| +// |
| +// Disabled because we are changing the download file completion logic. |
| +// The first stream will make the download file complete after it finished. |
| +TEST_F(DownloadFileTest, DISABLED_MutipleStreamsOneStreamFirst) { |
| + ASSERT_TRUE(CreateDownloadFile(0, true, true)); |
| + int64_t stream_0_length = GetBuffersLength(kTestData6, 2); |
| + int64_t stream_1_length = GetBuffersLength(kTestData7, 2); |
| + |
| + // Setup and deplete the first stream. |
| + PrepareStream(&input_stream_, 0, false, true, kTestData6, 2); |
| sink_callback_.Run(); |
| base::RunLoop().RunUntilIdle(); |
| - |
| SourceStreamTestData stream_data_0(0, stream_0_length, true); |
| - SourceStreamTestData stream_data_1(stream_0_length, 0, false); |
| VerifySourceStreamsStates(stream_data_0); |
| - VerifySourceStreamsStates(stream_data_1); |
| EXPECT_EQ(stream_0_length, TotalBytesReceived()); |
| + // Setup and activate the second stream. |
| + PrepareStream(&input_stream_1_, stream_0_length, true, true, kTestData7, 2); |
| + DCHECK(input_stream_1_); |
| + |
| + EXPECT_CALL(*input_stream_1_, RegisterCallback(_)).RetiresOnSaturation(); |
| // Won't inform the observer until the second stream is depleted. |
| EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _)); |
| - |
| - // Drain the second stream after the first stream is depleted. |
| download_file_->AddByteStream( |
| - std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length); |
| + std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length, |
| + 0); |
| base::RunLoop().RunUntilIdle(); |
| - stream_data_1.bytes_written = stream_1_length; |
| - stream_data_1.finished = true; |
| + SourceStreamTestData stream_data_1(stream_0_length, stream_1_length, true); |
| VerifySourceStreamsStates(stream_data_0); |
| VerifySourceStreamsStates(stream_data_1); |
| EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived()); |
| @@ -963,19 +962,24 @@ TEST_F(DownloadFileTest, MutipleStreamsOneStreamFirst) { |
| // Two streams write to one sink, the second stream has a limited length. |
| TEST_F(DownloadFileTest, MutipleStreamsLimitedLength) { |
| - // The second stream has two buffers, kTestData4 and kTestData5. |
| - // The length limit is set to less than the length of kTestData4. |
| - // kTestData4 should be partially written to disk, where kTestData5 should be |
| - // ignored. |
| - int64_t stream_0_length = |
| - static_cast<int64_t>(strlen(kTestData1) + strlen(kTestData2)); |
| - int64_t stream_1_length = static_cast<int64_t>(strlen(kTestData4)) - 1; |
| - PrepareMultipleStreams(stream_1_length); |
| - |
| + ASSERT_TRUE(CreateDownloadFile(0, true, true)); |
| + int64_t stream_0_length = GetBuffersLength(kTestData6, 2); |
| + // The second stream has a limited length and should be partially written |
| + // to disk. |
| + int64_t stream_1_length = GetBuffersLength(kTestData7, 2) - 1; |
| + |
| + PrepareStream(&input_stream_, 0, false, true, kTestData6, 2); |
| + PrepareStream(&input_stream_1_, stream_0_length, true, false, kTestData7, 2); |
| + |
| + EXPECT_CALL(*input_stream_1_, RegisterCallback(_)) |
| + .Times(2) |
| + .RetiresOnSaturation(); |
| EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _)); |
| + // Activate both streams. |
| download_file_->AddByteStream( |
| - std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length); |
| + std::unique_ptr<MockByteStreamReader>(input_stream_1_), stream_0_length, |
| + stream_1_length); |
| sink_callback_.Run(); |
| base::RunLoop().RunUntilIdle(); |
| @@ -985,18 +989,6 @@ TEST_F(DownloadFileTest, MutipleStreamsLimitedLength) { |
| VerifySourceStreamsStates(stream_data_1); |
| EXPECT_EQ(stream_0_length + stream_1_length, TotalBytesReceived()); |
| - std::string disk_data, expected_data; |
| - EXPECT_TRUE(base::ReadFileToString(download_file_->FullPath(), &disk_data)); |
| - expected_data.append(kTestData1).append(kTestData2).append(kTestData4); |
| - expected_data = expected_data.substr(0, stream_0_length + stream_1_length); |
| - EXPECT_EQ(expected_data, disk_data); |
| - |
| - // Finish the second stream. |
| - // TODO(xingliu): Refactor test code to deal with unfinished streams. |
| - scoped_refptr<net::IOBuffer> data = new net::IOBuffer(strlen(kTestData5)); |
| - size_t size; |
| - input_stream_1_->Read(&data, &size); |
| - |
| DestroyDownloadFile(0, false); |
| } |