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