Commit 1a4ff06e authored by Min Qin's avatar Min Qin Committed by Commit Bot

Rewrite download unittests that uses ByteStreamReader

ByteStreamReader is in content/ and download should avoid such dependency.
Replace all the ByteStreamReader mocks with mocks of download::InputStream

Bug: 803135
Change-Id: I3650d482943c604bedc39c0db8ec7b1021656fe4
Reviewed-on: https://chromium-review.googlesource.com/957446Reviewed-by: default avatarXing Liu <xingliu@chromium.org>
Commit-Queue: Min Qin <qinmin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#542293}
parent bd0cb3c1
......@@ -100,12 +100,7 @@ DownloadInterruptReason StreamHandleInputStream::GetCompletionStatus() {
void StreamHandleInputStream::OnStreamCompleted(
mojom::NetworkRequestStatus status) {
// This can be called before or after data pipe is completely drained.
OnResponseCompleted(ConvertMojoNetworkRequestStatusToInterruptReason(status));
}
void StreamHandleInputStream::OnResponseCompleted(
DownloadInterruptReason status) {
completion_status_ = status;
completion_status_ = ConvertMojoNetworkRequestStatusToInterruptReason(status);
is_response_completed_ = true;
if (completion_callback_)
std::move(completion_callback_).Run();
......
......@@ -38,6 +38,7 @@ component("public") {
"download_url_parameters.cc",
"download_url_parameters.h",
"download_utils.h",
"input_stream.cc",
"input_stream.h",
"rate_estimator.h",
"resume_mode.h",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/download/public/common/input_stream.h"
namespace download {
InputStream::~InputStream() = default;
void InputStream::Initialize() {}
void InputStream::RegisterDataReadyCallback(
const mojo::SimpleWatcher::ReadyCallback& callback) {}
void InputStream::ClearDataReadyCallback() {}
void InputStream::RegisterCompletionCallback(base::OnceClosure callback) {}
} // namespace download
......@@ -24,21 +24,21 @@ class COMPONENTS_DOWNLOAD_EXPORT InputStream {
COMPLETE,
};
virtual ~InputStream() = default;
virtual ~InputStream();
// Initializes the inputStream object.
virtual void Initialize() {}
virtual void Initialize();
// Returns true if the input stream contains no data, or false otherwise.
virtual bool IsEmpty() = 0;
// Register/clear callbacks when data become available.
virtual void RegisterDataReadyCallback(
const mojo::SimpleWatcher::ReadyCallback& callback) {}
virtual void ClearDataReadyCallback() {}
const mojo::SimpleWatcher::ReadyCallback& callback);
virtual void ClearDataReadyCallback();
// Registers stream completion callback if needed.
virtual void RegisterCompletionCallback(base::OnceClosure callback) {}
virtual void RegisterCompletionCallback(base::OnceClosure callback);
// Reads data from the stream into |data|, |length| is the number of bytes
// returned.
......@@ -47,9 +47,6 @@ class COMPONENTS_DOWNLOAD_EXPORT InputStream {
// Returns the completion status.
virtual DownloadInterruptReason GetCompletionStatus() = 0;
// Mark the InputStream as completed and set the completion status.
virtual void OnResponseCompleted(DownloadInterruptReason status){};
};
} // namespace download
......
......@@ -32,7 +32,6 @@ class COMPONENTS_DOWNLOAD_EXPORT StreamHandleInputStream
InputStream::StreamState Read(scoped_refptr<net::IOBuffer>* data,
size_t* length) override;
DownloadInterruptReason GetCompletionStatus() override;
void OnResponseCompleted(DownloadInterruptReason status) override;
// mojom::DownloadStreamClient
void OnStreamCompleted(mojom::NetworkRequestStatus status) override;
......
......@@ -56,9 +56,4 @@ download::DownloadInterruptReason ByteStreamInputStream::GetCompletionStatus() {
return completion_status_;
}
void ByteStreamInputStream::OnResponseCompleted(
download::DownloadInterruptReason status) {
completion_status_ = status;
}
} // namespace content
......@@ -27,7 +27,6 @@ class CONTENT_EXPORT ByteStreamInputStream : public download::InputStream {
download::InputStream::StreamState Read(scoped_refptr<net::IOBuffer>* data,
size_t* length) override;
download::DownloadInterruptReason GetCompletionStatus() override;
void OnResponseCompleted(download::DownloadInterruptReason status) override;
private:
// ByteStreamReader to read from.
......
......@@ -102,11 +102,6 @@ void DownloadFileImpl::SourceStream::ClearDataReadyCallback() {
input_stream_->ClearDataReadyCallback();
}
void DownloadFileImpl::SourceStream::OnResponseCompleted(
download::DownloadInterruptReason reason) {
input_stream_->OnResponseCompleted(reason);
}
download::DownloadInterruptReason
DownloadFileImpl::SourceStream::GetCompletionStatus() const {
return input_stream_->GetCompletionStatus();
......
......@@ -95,9 +95,6 @@ class CONTENT_EXPORT DownloadFileImpl : public DownloadFile {
void Initialize();
// Called when response is completed.
void OnResponseCompleted(download::DownloadInterruptReason reason);
// Called after successfully writing a buffer to disk.
void OnWriteBytesToDisk(int64_t bytes_write);
......
......@@ -23,9 +23,8 @@
#include "components/download/public/common/download_create_info.h"
#include "components/download/public/common/download_destination_observer.h"
#include "components/download/public/common/download_interrupt_reasons.h"
#include "content/browser/byte_stream.h"
#include "content/browser/download/byte_stream_input_stream.h"
#include "content/browser/download/download_file_impl.h"
#include "content/browser/download/mock_input_stream.h"
#include "content/public/browser/download_manager.h"
#include "content/public/test/mock_download_manager.h"
#include "net/base/file_stream.h"
......@@ -70,18 +69,6 @@ std::string GetHexEncodedHashValue(crypto::SecureHash* hash_state) {
return base::HexEncode(&hash_value.front(), hash_value.size());
}
class MockByteStreamReader : public ByteStreamReader {
public:
MockByteStreamReader() {}
~MockByteStreamReader() {}
// ByteStream functions
MOCK_METHOD2(Read, ByteStreamReader::StreamState(
scoped_refptr<net::IOBuffer>*, size_t*));
MOCK_CONST_METHOD0(GetStatus, int());
MOCK_METHOD1(RegisterCallback, void(const base::Closure&));
};
class MockDownloadDestinationObserver
: public download::DownloadDestinationObserver {
public:
......@@ -115,8 +102,6 @@ class MockDownloadDestinationObserver
MOCK_METHOD2(CurrentUpdateStatus, void(int64_t, int64_t));
};
MATCHER(IsNullCallback, "") { return (arg.is_null()); }
enum DownloadFileRenameMethodType { RENAME_AND_UNIQUIFY, RENAME_AND_ANNOTATE };
// This is a test DownloadFileImpl that has no retry delay and, on Posix,
......@@ -174,7 +159,7 @@ class DownloadFileTest : public testing::Test {
observer_factory_(observer_.get()),
input_stream_(nullptr),
additional_streams_(
std::vector<StrictMock<MockByteStreamReader>*>{nullptr, nullptr}),
std::vector<StrictMock<MockInputStream>*>{nullptr, nullptr}),
bytes_(-1),
bytes_per_sec_(-1) {}
......@@ -202,10 +187,13 @@ class DownloadFileTest : public testing::Test {
}
// Mock calls to this function are forwarded here.
void RegisterCallback(const base::Closure& sink_callback) {
void RegisterCallback(
const mojo::SimpleWatcher::ReadyCallback& sink_callback) {
sink_callback_ = sink_callback;
}
void ClearCallback() { sink_callback_.Reset(); }
void SetInterruptReasonCallback(const base::Closure& closure,
download::DownloadInterruptReason* reason_p,
download::DownloadInterruptReason reason,
......@@ -227,11 +215,11 @@ class DownloadFileTest : public testing::Test {
// There can be only one.
DCHECK(!download_file_.get());
input_stream_ = new StrictMock<MockByteStreamReader>();
input_stream_ = new StrictMock<MockInputStream>();
// TODO: Need to actually create a function that'll set the variables
// based on the inputs from the callback.
EXPECT_CALL(*input_stream_, RegisterCallback(_))
EXPECT_CALL(*input_stream_, RegisterDataReadyCallback(_))
.WillOnce(Invoke(this, &DownloadFileTest::RegisterCallback))
.RetiresOnSaturation();
......@@ -242,12 +230,11 @@ class DownloadFileTest : public testing::Test {
download_file_.reset(new TestDownloadFileImpl(
std::move(save_info), download_dir_.GetPath(),
std::make_unique<ByteStreamInputStream>(
std::unique_ptr<ByteStreamReader>(input_stream_)),
std::unique_ptr<MockInputStream>(input_stream_),
download::DownloadItem::kInvalidId, observer_factory_.GetWeakPtr()));
EXPECT_CALL(*input_stream_, Read(_, _))
.WillOnce(Return(ByteStreamReader::STREAM_EMPTY))
.WillOnce(Return(download::InputStream::EMPTY))
.RetiresOnSaturation();
base::WeakPtrFactory<DownloadFileTest> weak_ptr_factory(this);
......@@ -285,20 +272,20 @@ class DownloadFileTest : public testing::Test {
// Don't actually trigger the callback or do verifications.
void SetupDataAppend(const char** data_chunks,
size_t num_chunks,
MockByteStreamReader* stream_reader,
MockInputStream* input_stream,
::testing::Sequence s,
int64_t offset = -1) {
DCHECK(stream_reader);
DCHECK(input_stream);
size_t current_pos = static_cast<size_t>(offset);
for (size_t i = 0; i < num_chunks; i++) {
const char *source_data = data_chunks[i];
size_t length = strlen(source_data);
scoped_refptr<net::IOBuffer> data = new net::IOBuffer(length);
memcpy(data->data(), source_data, length);
EXPECT_CALL(*stream_reader, Read(_, _))
EXPECT_CALL(*input_stream, Read(_, _))
.InSequence(s)
.WillOnce(DoAll(SetArgPointee<0>(data), SetArgPointee<1>(length),
Return(ByteStreamReader::STREAM_HAS_DATA)))
Return(download::InputStream::HAS_DATA)))
.RetiresOnSaturation();
if (offset < 0) {
......@@ -329,24 +316,24 @@ class DownloadFileTest : public testing::Test {
SetupDataAppend(data_chunks, num_chunks, input_stream_, s1);
EXPECT_CALL(*input_stream_, Read(_, _))
.InSequence(s1)
.WillOnce(Return(ByteStreamReader::STREAM_EMPTY))
.WillOnce(Return(download::InputStream::EMPTY))
.RetiresOnSaturation();
sink_callback_.Run();
sink_callback_.Run(MOJO_RESULT_OK);
VerifyStreamAndSize();
}
void SetupFinishStream(download::DownloadInterruptReason interrupt_reason,
MockByteStreamReader* stream_reader,
MockInputStream* input_stream,
::testing::Sequence s) {
EXPECT_CALL(*stream_reader, Read(_, _))
EXPECT_CALL(*input_stream, Read(_, _))
.InSequence(s)
.WillOnce(Return(ByteStreamReader::STREAM_COMPLETE))
.WillOnce(Return(download::InputStream::COMPLETE))
.RetiresOnSaturation();
EXPECT_CALL(*stream_reader, GetStatus())
EXPECT_CALL(*input_stream, GetCompletionStatus())
.InSequence(s)
.WillOnce(Return(interrupt_reason))
.RetiresOnSaturation();
EXPECT_CALL(*stream_reader, RegisterCallback(_)).RetiresOnSaturation();
EXPECT_CALL(*input_stream, ClearDataReadyCallback()).RetiresOnSaturation();
}
void FinishStream(download::DownloadInterruptReason interrupt_reason,
......@@ -354,7 +341,7 @@ class DownloadFileTest : public testing::Test {
const std::string& expected_hash) {
::testing::Sequence s1;
SetupFinishStream(interrupt_reason, input_stream_, s1);
sink_callback_.Run();
sink_callback_.Run(MOJO_RESULT_OK);
VerifyStreamAndSize();
if (check_observer) {
EXPECT_CALL(*(observer_.get()),
......@@ -430,16 +417,16 @@ class DownloadFileTest : public testing::Test {
}
// Prepare a byte stream to write to the file sink.
void PrepareStream(StrictMock<MockByteStreamReader>** stream,
void PrepareStream(StrictMock<MockInputStream>** stream,
int64_t offset,
bool create_stream,
bool will_finish,
const char** buffers,
size_t num_buffer) {
if (create_stream)
*stream = new StrictMock<MockByteStreamReader>();
*stream = new StrictMock<MockInputStream>();
// Expectation on MockByteStreamReader for MultipleStreams tests:
// Expectation on MockInputStream for MultipleStreams tests:
// 1. RegisterCallback: Must called twice. One to set the callback, the
// other to release the stream.
// 2. Read: If filled with N buffer, called (N+1) times, where the last Read
......@@ -483,13 +470,13 @@ class DownloadFileTest : public testing::Test {
// Stream for sending data into the download file.
// Owned by download_file_; will be alive for lifetime of download_file_.
StrictMock<MockByteStreamReader>* input_stream_;
StrictMock<MockInputStream>* input_stream_;
// Additional streams to test multiple stream write.
std::vector<StrictMock<MockByteStreamReader>*> additional_streams_;
std::vector<StrictMock<MockInputStream>*> additional_streams_;
// Sink callback data for stream.
base::Closure sink_callback_;
mojo::SimpleWatcher::ReadyCallback sink_callback_;
base::ScopedTempDir download_dir_;
......@@ -729,7 +716,7 @@ TEST_P(DownloadFileTestWithRename, RenameError) {
ASSERT_TRUE(base::MakeFileUnwritable(target_dir));
// Expect nulling out of further processing.
EXPECT_CALL(*input_stream_, RegisterCallback(IsNullCallback()));
EXPECT_CALL(*input_stream_, ClearDataReadyCallback());
ExpectPermissionError(InvokeSelectedRenameMethod(target_path, nullptr));
EXPECT_FALSE(base::PathExists(target_path_suffixed));
}
......@@ -890,7 +877,7 @@ TEST_F(DownloadFileTest, StreamNonEmptySuccess) {
SetupFinishStream(download::DOWNLOAD_INTERRUPT_REASON_NONE, input_stream_,
s1);
EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _));
sink_callback_.Run();
sink_callback_.Run(MOJO_RESULT_OK);
VerifyStreamAndSize();
base::RunLoop().RunUntilIdle();
DestroyDownloadFile(0);
......@@ -922,7 +909,7 @@ TEST_F(DownloadFileTest, StreamNonEmptyError) {
EXPECT_CALL(*(observer_.get()),
CurrentUpdateStatus(strlen(kTestData1) + strlen(kTestData2), _));
sink_callback_.Run();
sink_callback_.Run(MOJO_RESULT_OK);
base::RunLoop().RunUntilIdle();
VerifyStreamAndSize();
DestroyDownloadFile(0);
......@@ -942,16 +929,15 @@ TEST_F(DownloadFileTest, MultipleStreamsWrite) {
PrepareStream(&additional_streams_[0], stream_0_length, true, true,
kTestData7, 2);
EXPECT_CALL(*additional_streams_[0], RegisterCallback(_))
EXPECT_CALL(*additional_streams_[0], RegisterDataReadyCallback(_))
.RetiresOnSaturation();
EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _));
// Activate the streams.
download_file_->AddInputStream(
std::make_unique<ByteStreamInputStream>(
std::unique_ptr<ByteStreamReader>(additional_streams_[0])),
stream_0_length, download::DownloadSaveInfo::kLengthFullContent);
sink_callback_.Run();
std::unique_ptr<MockInputStream>(additional_streams_[0]), stream_0_length,
download::DownloadSaveInfo::kLengthFullContent);
sink_callback_.Run(MOJO_RESULT_OK);
base::RunLoop().RunUntilIdle();
SourceStreamTestData stream_data_0(0, stream_0_length, true);
......@@ -984,26 +970,28 @@ TEST_F(DownloadFileTest, MutipleStreamsLimitedLength) {
PrepareStream(&additional_streams_[1], stream_0_length + stream_1_length,
true, true, kTestData6, 2);
EXPECT_CALL(*additional_streams_[0], RegisterCallback(_))
.Times(2)
EXPECT_CALL(*additional_streams_[0], RegisterDataReadyCallback(_))
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(*additional_streams_[0], ClearDataReadyCallback())
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(*additional_streams_[1], RegisterCallback(_))
EXPECT_CALL(*additional_streams_[1], RegisterDataReadyCallback(_))
.RetiresOnSaturation();
EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _));
// Activate all the streams.
download_file_->AddInputStream(
std::make_unique<ByteStreamInputStream>(
std::unique_ptr<ByteStreamReader>(additional_streams_[0])),
stream_0_length, stream_1_length);
std::unique_ptr<MockInputStream>(additional_streams_[0]), stream_0_length,
stream_1_length);
download_file_->AddInputStream(
std::make_unique<ByteStreamInputStream>(
std::unique_ptr<ByteStreamReader>(additional_streams_[1])),
std::unique_ptr<MockInputStream>(additional_streams_[1]),
stream_0_length + stream_1_length,
download::DownloadSaveInfo::kLengthFullContent);
sink_callback_.Run();
sink_callback_.Run(MOJO_RESULT_OK);
base::RunLoop().RunUntilIdle();
SourceStreamTestData stream_data_0(0, stream_0_length, true);
......@@ -1034,17 +1022,16 @@ TEST_F(DownloadFileTest, MultipleStreamsFirstStreamWriteAllData) {
EXPECT_CALL(*(observer_.get()), MockDestinationCompleted(_, _));
sink_callback_.Run();
sink_callback_.Run(MOJO_RESULT_OK);
base::RunLoop().RunUntilIdle();
// Add another stream, the file is already closed, so nothing should be
// called.
EXPECT_FALSE(download_file_->InProgress());
additional_streams_[0] = new StrictMock<MockByteStreamReader>();
additional_streams_[0] = new StrictMock<MockInputStream>();
download_file_->AddInputStream(
std::make_unique<ByteStreamInputStream>(
std::unique_ptr<ByteStreamReader>(additional_streams_[0])),
std::unique_ptr<MockInputStream>(additional_streams_[0]),
stream_0_length - 1, download::DownloadSaveInfo::kLengthFullContent);
base::RunLoop().RunUntilIdle();
......@@ -1069,23 +1056,25 @@ TEST_F(DownloadFileTest, SecondStreamStartingOffsetAlreadyWritten) {
EXPECT_CALL(*input_stream_, Read(_, _))
.InSequence(seq)
.WillOnce(Return(ByteStreamReader::STREAM_EMPTY))
.WillOnce(Return(download::InputStream::EMPTY))
.RetiresOnSaturation();
sink_callback_.Run();
sink_callback_.Run(MOJO_RESULT_OK);
base::RunLoop().RunUntilIdle();
additional_streams_[0] = new StrictMock<MockByteStreamReader>();
EXPECT_CALL(*additional_streams_[0], RegisterCallback(_))
additional_streams_[0] = new StrictMock<MockInputStream>();
EXPECT_CALL(*additional_streams_[0], RegisterDataReadyCallback(_))
.WillRepeatedly(Invoke(this, &DownloadFileTest::RegisterCallback))
.RetiresOnSaturation();
EXPECT_CALL(*additional_streams_[0], ClearDataReadyCallback())
.WillRepeatedly(Invoke(this, &DownloadFileTest::ClearCallback))
.RetiresOnSaturation();
EXPECT_CALL(*additional_streams_[0], Read(_, _))
.WillOnce(Return(ByteStreamReader::STREAM_EMPTY))
.WillOnce(Return(download::InputStream::EMPTY))
.RetiresOnSaturation();
download_file_->AddInputStream(
std::make_unique<ByteStreamInputStream>(
std::unique_ptr<ByteStreamReader>(additional_streams_[0])),
0, download::DownloadSaveInfo::kLengthFullContent);
std::unique_ptr<MockInputStream>(additional_streams_[0]), 0,
download::DownloadSaveInfo::kLengthFullContent);
// The stream should get terminated and reset the callback.
EXPECT_TRUE(sink_callback_.is_null());
......
......@@ -10,7 +10,6 @@
#include "base/time/time.h"
#include "components/download/public/common/download_interrupt_reasons.h"
#include "components/download/public/common/download_request_handle_interface.h"
#include "content/browser/byte_stream.h"
#include "content/browser/download/download_file.h"
#include "content/common/content_export.h"
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/download/mock_input_stream.h"
namespace content {
MockInputStream::MockInputStream() = default;
MockInputStream::~MockInputStream() = default;
} // namespace content
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_DOWNLOAD_MOCK_INPUT_STREAM_H_
#define CONTENT_BROWSER_DOWNLOAD_MOCK_INPUT_STREAM_H_
#include "components/download/public/common/input_stream.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace content {
class MockInputStream : public download::InputStream {
public:
MockInputStream();
~MockInputStream() override;
// download::InputStream functions
MOCK_METHOD0(IsEmpty, bool());
MOCK_METHOD1(RegisterDataReadyCallback,
void(const mojo::SimpleWatcher::ReadyCallback&));
MOCK_METHOD0(ClearDataReadyCallback, void());
MOCK_METHOD2(Read,
download::InputStream::StreamState(scoped_refptr<net::IOBuffer>*,
size_t*));
MOCK_METHOD0(GetCompletionStatus, download::DownloadInterruptReason());
};
} // namespace content
#endif // CONTENT_BROWSER_DOWNLOAD_MOCK_INPUT_STREAM_H_
......@@ -13,10 +13,10 @@
#include "base/test/scoped_task_environment.h"
#include "components/download/public/common/download_destination_observer.h"
#include "components/download/public/common/download_task_runner.h"
#include "content/browser/download/byte_stream_input_stream.h"
#include "content/browser/download/download_file_impl.h"
#include "content/browser/download/download_item_impl_delegate.h"
#include "content/browser/download/mock_download_item_impl.h"
#include "content/browser/download/mock_input_stream.h"
#include "content/browser/download/parallel_download_utils.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gmock/include/gmock/gmock.h"
......@@ -57,15 +57,6 @@ class MockDownloadDestinationObserver
MOCK_METHOD2(CurrentUpdateStatus, void(int64_t, int64_t));
};
class MockByteStreamReader : public ByteStreamReader {
public:
MOCK_METHOD2(Read,
ByteStreamReader::StreamState(scoped_refptr<net::IOBuffer>*,
size_t*));
MOCK_CONST_METHOD0(GetStatus, int());
MOCK_METHOD1(RegisterCallback, void(const base::Closure&));
};
} // namespace
class ParallelDownloadJobForTest : public ParallelDownloadJob {
......@@ -182,9 +173,7 @@ class ParallelDownloadJobTest : public testing::Test {
std::make_unique<download::DownloadCreateInfo>();
create_info->request_handle = std::move(request_handle);
delegate->OnUrlDownloadStarted(
std::move(create_info),
std::make_unique<ByteStreamInputStream>(
std::make_unique<MockByteStreamReader>()),
std::move(create_info), std::make_unique<MockInputStream>(),
download::DownloadUrlParameters::OnStartedCallback());
}
......@@ -486,16 +475,14 @@ TEST_F(ParallelDownloadJobTest, RemainingContentWillFinishSoon) {
// Test that parallel request is not created until download file is initialized.
TEST_F(ParallelDownloadJobTest, ParallelRequestNotCreatedUntilFileInitialized) {
auto save_info = std::make_unique<download::DownloadSaveInfo>();
StrictMock<MockByteStreamReader>* input_stream =
new StrictMock<MockByteStreamReader>();
StrictMock<MockInputStream>* input_stream = new StrictMock<MockInputStream>();
auto observer =
std::make_unique<StrictMock<MockDownloadDestinationObserver>>();
base::WeakPtrFactory<download::DownloadDestinationObserver> observer_factory(
observer.get());
auto download_file = std::make_unique<DownloadFileImpl>(
std::move(save_info), base::FilePath(),
std::make_unique<ByteStreamInputStream>(
std::unique_ptr<ByteStreamReader>(input_stream)),
std::unique_ptr<MockInputStream>(input_stream),
download::DownloadItem::kInvalidId, observer_factory.GetWeakPtr());
CreateParallelJob(0, 100, download::DownloadItem::ReceivedSlices(), 2, 0, 0);
job_->Start(download_file.get(),
......@@ -504,7 +491,7 @@ TEST_F(ParallelDownloadJobTest, ParallelRequestNotCreatedUntilFileInitialized) {
download::DownloadItem::ReceivedSlices());
EXPECT_FALSE(file_initialized_);
EXPECT_EQ(0u, job_->workers().size());
EXPECT_CALL(*input_stream, RegisterCallback(_));
EXPECT_CALL(*input_stream, RegisterDataReadyCallback(_));
EXPECT_CALL(*input_stream, Read(_, _));
EXPECT_CALL(*(observer.get()), DestinationUpdate(_, _, _));
task_environment_.RunUntilIdle();
......
......@@ -11,47 +11,44 @@
#include "base/test/scoped_feature_list.h"
#include "components/download/public/common/download_features.h"
#include "components/download/public/common/download_save_info.h"
#include "content/browser/byte_stream.h"
#include "content/browser/download/byte_stream_input_stream.h"
#include "content/browser/download/mock_input_stream.h"
#include "content/public/browser/download_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::Return;
using ::testing::StrictMock;
namespace content {
namespace {
const int kErrorStreamOffset = 100;
class MockByteStreamReader : public ByteStreamReader {
} // namespace
class ParallelDownloadUtilsTest : public testing::Test {};
class ParallelDownloadUtilsRecoverErrorTest
: public ::testing::TestWithParam<int64_t> {
public:
MockByteStreamReader() {}
~MockByteStreamReader() override {}
// ByteStream functions
MOCK_METHOD2(Read,
ByteStreamReader::StreamState(scoped_refptr<net::IOBuffer>*,
size_t*));
MOCK_CONST_METHOD0(GetStatus, int());
MOCK_METHOD1(RegisterCallback, void(const base::Closure&));
};
ParallelDownloadUtilsRecoverErrorTest() : input_stream_(nullptr) {}
// Creates a source stream to test.
std::unique_ptr<DownloadFileImpl::SourceStream> CreateSourceStream(
// Creates a source stream to test.
std::unique_ptr<DownloadFileImpl::SourceStream> CreateSourceStream(
int64_t offset,
int64_t length) {
auto input_stream = std::make_unique<ByteStreamInputStream>(
std::make_unique<MockByteStreamReader>());
input_stream_ = new StrictMock<MockInputStream>();
EXPECT_CALL(*input_stream_, GetCompletionStatus())
.WillRepeatedly(Return(download::DOWNLOAD_INTERRUPT_REASON_NONE));
return std::make_unique<DownloadFileImpl::SourceStream>(
offset, length, std::move(input_stream));
}
} // namespace
class ParallelDownloadUtilsTest : public testing::Test {};
offset, length, std::unique_ptr<MockInputStream>(input_stream_));
}
class ParallelDownloadUtilsRecoverErrorTest
: public ::testing::TestWithParam<int64_t> {};
protected:
// Stream for sending data into the SourceStream.
StrictMock<MockInputStream>* input_stream_;
};
TEST_F(ParallelDownloadUtilsTest, FindSlicesToDownload) {
std::vector<download::DownloadItem::ReceivedSlice> downloaded_slices;
......@@ -265,6 +262,7 @@ TEST_P(ParallelDownloadUtilsRecoverErrorTest,
RecoverErrorForHalfOpenErrorStream) {
// Create a stream that will work on byte range "100-".
const int kErrorStreamOffset = 100;
auto error_stream = CreateSourceStream(
kErrorStreamOffset, download::DownloadSaveInfo::kLengthFullContent);
error_stream->set_finished(true);
......@@ -287,8 +285,9 @@ TEST_P(ParallelDownloadUtilsRecoverErrorTest,
// Half open finished preceding stream with error, should be treated as
// failed.
preceding_stream->OnResponseCompleted(
download::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE);
EXPECT_CALL(*input_stream_, GetCompletionStatus())
.WillRepeatedly(
Return(download::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE));
EXPECT_FALSE(CanRecoverFromError(error_stream.get(), preceding_stream.get()));
// Even if it has written some data.
......@@ -308,8 +307,9 @@ TEST_P(ParallelDownloadUtilsRecoverErrorTest,
// Inject an error results in failure, even if data written exceeds the first
// byte of error stream.
preceding_stream->OnResponseCompleted(
download::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE);
EXPECT_CALL(*input_stream_, GetCompletionStatus())
.WillRepeatedly(
Return(download::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE));
preceding_stream->OnWriteBytesToDisk(1000u);
EXPECT_FALSE(CanRecoverFromError(error_stream.get(), preceding_stream.get()));
......@@ -383,8 +383,9 @@ TEST_P(ParallelDownloadUtilsRecoverErrorTest,
// Even if inject an error, since data written has cover the upper bound of
// the error stream, it should succeed.
preceding_stream->OnResponseCompleted(
download::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE);
EXPECT_CALL(*input_stream_, GetCompletionStatus())
.WillRepeatedly(
Return(download::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE));
EXPECT_TRUE(CanRecoverFromError(error_stream.get(), preceding_stream.get()));
// Preceding stream that never download data won't recover the error stream.
......
......@@ -50,6 +50,8 @@ jumbo_static_library("test_support") {
"../browser/download/mock_download_item_impl.h",
"../browser/download/mock_download_job.cc",
"../browser/download/mock_download_job.h",
"../browser/download/mock_input_stream.cc",
"../browser/download/mock_input_stream.h",
"../browser/media/session/mock_media_session_observer.cc",
"../browser/media/session/mock_media_session_observer.h",
"../browser/service_worker/embedded_worker_test_helper.cc",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment