| 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..f4ba6b5d84b89703b69d40bc1d9cf00313c5864b 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,21 @@ 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);
|
|
|
| - 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 +923,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 +961,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 +988,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);
|
| }
|
|
|
|
|