Chromium Code Reviews| Index: content/child/url_response_body_consumer_unittest.cc |
| diff --git a/content/child/url_response_body_consumer_unittest.cc b/content/child/url_response_body_consumer_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..6c0a019bbdea9f1e90b36ed742d661824204bc31 |
| --- /dev/null |
| +++ b/content/child/url_response_body_consumer_unittest.cc |
| @@ -0,0 +1,206 @@ |
| +// Copyright 2016 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/child/url_response_body_consumer.h" |
| + |
| +#include "base/bind.h" |
| +#include "base/callback_forward.h" |
| +#include "base/macros.h" |
| +#include "base/memory/ptr_util.h" |
| +#include "base/run_loop.h" |
| +#include "content/child/request_info.h" |
| +#include "content/child/resource_dispatcher.h" |
| +#include "content/common/resource_messages.h" |
| +#include "content/common/resource_request_completion_status.h" |
| +#include "content/public/child/request_peer.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace content { |
| + |
| +namespace { |
| + |
| +class TestRequestPeer : public RequestPeer { |
| + public: |
| + struct Context; |
| + explicit TestRequestPeer(Context* context) : context_(context) {} |
| + |
| + void OnUploadProgress(uint64_t position, uint64_t size) override { |
| + EXPECT_TRUE(false); |
|
kinuko
2016/08/04 16:07:03
nit: ADD_FAILURE ? (Here and below)
yhirano
2016/08/05 12:21:40
Done.
|
| + } |
| + |
| + bool OnReceivedRedirect(const net::RedirectInfo& redirect_info, |
| + const ResourceResponseInfo& info) override { |
| + EXPECT_TRUE(false); |
| + return false; |
| + } |
| + |
| + void OnReceivedResponse(const ResourceResponseInfo& info) override { |
| + EXPECT_TRUE(false); |
| + } |
| + |
| + void OnDownloadedData(int len, int encoded_data_length) override { |
| + EXPECT_TRUE(false); |
| + } |
| + |
| + void OnReceivedData(std::unique_ptr<ReceivedData> data) override { |
| + EXPECT_FALSE(context_->complete); |
| + context_->data.append(data->payload(), data->length()); |
| + context_->run_loop_quit_closure.Run(); |
| + } |
| + |
| + void OnCompletedRequest(int error_code, |
| + bool was_ignored_by_handler, |
| + bool stale_copy_in_cache, |
| + const std::string& security_info, |
| + const base::TimeTicks& completion_time, |
| + int64_t total_transfer_size) override { |
| + EXPECT_FALSE(context_->complete); |
| + context_->complete = true; |
| + context_->error_code = error_code; |
| + context_->run_loop_quit_closure.Run(); |
| + } |
| + |
| + struct Context { |
| + // Data received. If downloading to file, remains empty. |
| + std::string data; |
| + bool complete = false; |
| + base::Closure run_loop_quit_closure; |
| + int error_code = net::OK; |
| + }; |
| + |
| + private: |
| + Context* context_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(TestRequestPeer); |
| +}; |
| + |
| +class URLResponseBodyConsumerTest : public ::testing::Test, |
| + public ::IPC::Sender { |
| + protected: |
| + URLResponseBodyConsumerTest() |
| + : dispatcher_(new ResourceDispatcher(this, message_loop_.task_runner())) { |
| + } |
| + |
| + ~URLResponseBodyConsumerTest() override { |
| + dispatcher_.reset(); |
| + base::RunLoop().RunUntilIdle(); |
| + } |
| + |
| + bool Send(IPC::Message* message) override { |
| + delete message; |
| + return true; |
| + } |
| + |
| + std::unique_ptr<RequestInfo> CreateRequestInfo() { |
| + std::unique_ptr<RequestInfo> request_info(new RequestInfo); |
| + request_info->method = "GET"; |
| + request_info->url = GURL("http://www.example.com/"); |
| + return request_info; |
| + } |
| + |
| + MojoCreateDataPipeOptions CreateDataPipeOptions() { |
| + MojoCreateDataPipeOptions options; |
| + options.struct_size = sizeof(MojoCreateDataPipeOptions); |
| + options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; |
| + options.element_num_bytes = 1; |
| + options.capacity_num_bytes = 1024; |
| + return options; |
| + } |
| + |
| + void Run(TestRequestPeer::Context* context) { |
| + base::RunLoop run_loop; |
| + context->run_loop_quit_closure = run_loop.QuitClosure(); |
| + run_loop.Run(); |
| + } |
| + |
| + base::MessageLoop message_loop_; |
| + std::unique_ptr<ResourceDispatcher> dispatcher_; |
| + static const MojoWriteDataFlags kNone = MOJO_WRITE_DATA_FLAG_NONE; |
| +}; |
| + |
| +TEST_F(URLResponseBodyConsumerTest, ReceiveData) { |
| + TestRequestPeer::Context context; |
| + std::unique_ptr<RequestInfo> request_info(CreateRequestInfo()); |
| + int request_id = dispatcher_->StartAsync( |
| + *request_info, nullptr, base::WrapUnique(new TestRequestPeer(&context)), |
| + blink::WebURLRequest::LoadingIPCType::ChromeIPC, nullptr); |
|
kinuko
2016/08/04 16:07:03
This StartAsync() might feel a bit counter-intuiti
yhirano
2016/08/05 12:21:40
Done.
|
| + mojo::DataPipe data_pipe(CreateDataPipeOptions()); |
| + |
| + scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer( |
| + request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle))); |
| + |
| + mojo::ScopedDataPipeProducerHandle writer = |
| + std::move(data_pipe.producer_handle); |
| + std::string buffer = "hello"; |
| + uint32_t size = buffer.size(); |
| + MojoResult result = |
| + mojo::WriteDataRaw(writer.get(), buffer.c_str(), &size, kNone); |
| + ASSERT_EQ(MOJO_RESULT_OK, result); |
| + ASSERT_EQ(buffer.size(), size); |
| + |
| + Run(&context); |
| + |
| + EXPECT_FALSE(context.complete); |
| + EXPECT_EQ("hello", context.data); |
| +} |
| + |
| +TEST_F(URLResponseBodyConsumerTest, OnCompleteThenClose) { |
| + TestRequestPeer::Context context; |
| + std::unique_ptr<RequestInfo> request_info(CreateRequestInfo()); |
| + int request_id = dispatcher_->StartAsync( |
| + *request_info, nullptr, base::WrapUnique(new TestRequestPeer(&context)), |
| + blink::WebURLRequest::LoadingIPCType::ChromeIPC, nullptr); |
| + mojo::DataPipe data_pipe(CreateDataPipeOptions()); |
| + |
| + scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer( |
| + request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle))); |
| + |
| + consumer->OnComplete(ResourceRequestCompletionStatus()); |
| + mojo::ScopedDataPipeProducerHandle writer = |
| + std::move(data_pipe.producer_handle); |
| + std::string buffer = "hello"; |
| + uint32_t size = buffer.size(); |
| + MojoResult result = |
| + mojo::WriteDataRaw(writer.get(), buffer.c_str(), &size, kNone); |
| + ASSERT_EQ(MOJO_RESULT_OK, result); |
| + ASSERT_EQ(buffer.size(), size); |
| + writer.reset(); |
| + |
| + Run(&context); |
| + |
| + EXPECT_FALSE(context.complete); |
| + EXPECT_EQ("hello", context.data); |
| + |
| + Run(&context); |
| + |
| + EXPECT_TRUE(context.complete); |
| + EXPECT_EQ("hello", context.data); |
| +} |
| + |
| +TEST_F(URLResponseBodyConsumerTest, CloseThenOnComplete) { |
| + TestRequestPeer::Context context; |
| + std::unique_ptr<RequestInfo> request_info(CreateRequestInfo()); |
| + int request_id = dispatcher_->StartAsync( |
| + *request_info, nullptr, base::WrapUnique(new TestRequestPeer(&context)), |
| + blink::WebURLRequest::LoadingIPCType::ChromeIPC, nullptr); |
| + mojo::DataPipe data_pipe(CreateDataPipeOptions()); |
| + |
| + scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer( |
| + request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle))); |
| + |
| + ResourceRequestCompletionStatus status; |
| + status.error_code = net::ERR_FAILED; |
| + data_pipe.producer_handle.reset(); |
| + consumer->OnComplete(status); |
| + |
| + Run(&context); |
| + |
| + EXPECT_TRUE(context.complete); |
| + EXPECT_EQ(net::ERR_FAILED, context.error_code); |
| + EXPECT_EQ("", context.data); |
| +} |
| + |
| +} // namespace |
| + |
| +} // namespace content |