OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/child/url_response_body_consumer.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/callback_forward.h" | |
9 #include "base/macros.h" | |
10 #include "base/memory/ptr_util.h" | |
11 #include "base/run_loop.h" | |
12 #include "content/child/request_info.h" | |
13 #include "content/child/resource_dispatcher.h" | |
14 #include "content/common/resource_messages.h" | |
15 #include "content/common/resource_request_completion_status.h" | |
16 #include "content/public/child/request_peer.h" | |
17 #include "testing/gtest/include/gtest/gtest.h" | |
18 | |
19 namespace content { | |
20 | |
21 namespace { | |
22 | |
23 class TestRequestPeer : public RequestPeer { | |
24 public: | |
25 struct Context; | |
26 explicit TestRequestPeer(Context* context) : context_(context) {} | |
27 | |
28 void OnUploadProgress(uint64_t position, uint64_t size) override { | |
29 EXPECT_TRUE(false); | |
kinuko
2016/08/04 16:07:03
nit: ADD_FAILURE ? (Here and below)
yhirano
2016/08/05 12:21:40
Done.
| |
30 } | |
31 | |
32 bool OnReceivedRedirect(const net::RedirectInfo& redirect_info, | |
33 const ResourceResponseInfo& info) override { | |
34 EXPECT_TRUE(false); | |
35 return false; | |
36 } | |
37 | |
38 void OnReceivedResponse(const ResourceResponseInfo& info) override { | |
39 EXPECT_TRUE(false); | |
40 } | |
41 | |
42 void OnDownloadedData(int len, int encoded_data_length) override { | |
43 EXPECT_TRUE(false); | |
44 } | |
45 | |
46 void OnReceivedData(std::unique_ptr<ReceivedData> data) override { | |
47 EXPECT_FALSE(context_->complete); | |
48 context_->data.append(data->payload(), data->length()); | |
49 context_->run_loop_quit_closure.Run(); | |
50 } | |
51 | |
52 void OnCompletedRequest(int error_code, | |
53 bool was_ignored_by_handler, | |
54 bool stale_copy_in_cache, | |
55 const std::string& security_info, | |
56 const base::TimeTicks& completion_time, | |
57 int64_t total_transfer_size) override { | |
58 EXPECT_FALSE(context_->complete); | |
59 context_->complete = true; | |
60 context_->error_code = error_code; | |
61 context_->run_loop_quit_closure.Run(); | |
62 } | |
63 | |
64 struct Context { | |
65 // Data received. If downloading to file, remains empty. | |
66 std::string data; | |
67 bool complete = false; | |
68 base::Closure run_loop_quit_closure; | |
69 int error_code = net::OK; | |
70 }; | |
71 | |
72 private: | |
73 Context* context_; | |
74 | |
75 DISALLOW_COPY_AND_ASSIGN(TestRequestPeer); | |
76 }; | |
77 | |
78 class URLResponseBodyConsumerTest : public ::testing::Test, | |
79 public ::IPC::Sender { | |
80 protected: | |
81 URLResponseBodyConsumerTest() | |
82 : dispatcher_(new ResourceDispatcher(this, message_loop_.task_runner())) { | |
83 } | |
84 | |
85 ~URLResponseBodyConsumerTest() override { | |
86 dispatcher_.reset(); | |
87 base::RunLoop().RunUntilIdle(); | |
88 } | |
89 | |
90 bool Send(IPC::Message* message) override { | |
91 delete message; | |
92 return true; | |
93 } | |
94 | |
95 std::unique_ptr<RequestInfo> CreateRequestInfo() { | |
96 std::unique_ptr<RequestInfo> request_info(new RequestInfo); | |
97 request_info->method = "GET"; | |
98 request_info->url = GURL("http://www.example.com/"); | |
99 return request_info; | |
100 } | |
101 | |
102 MojoCreateDataPipeOptions CreateDataPipeOptions() { | |
103 MojoCreateDataPipeOptions options; | |
104 options.struct_size = sizeof(MojoCreateDataPipeOptions); | |
105 options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; | |
106 options.element_num_bytes = 1; | |
107 options.capacity_num_bytes = 1024; | |
108 return options; | |
109 } | |
110 | |
111 void Run(TestRequestPeer::Context* context) { | |
112 base::RunLoop run_loop; | |
113 context->run_loop_quit_closure = run_loop.QuitClosure(); | |
114 run_loop.Run(); | |
115 } | |
116 | |
117 base::MessageLoop message_loop_; | |
118 std::unique_ptr<ResourceDispatcher> dispatcher_; | |
119 static const MojoWriteDataFlags kNone = MOJO_WRITE_DATA_FLAG_NONE; | |
120 }; | |
121 | |
122 TEST_F(URLResponseBodyConsumerTest, ReceiveData) { | |
123 TestRequestPeer::Context context; | |
124 std::unique_ptr<RequestInfo> request_info(CreateRequestInfo()); | |
125 int request_id = dispatcher_->StartAsync( | |
126 *request_info, nullptr, base::WrapUnique(new TestRequestPeer(&context)), | |
127 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.
| |
128 mojo::DataPipe data_pipe(CreateDataPipeOptions()); | |
129 | |
130 scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer( | |
131 request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle))); | |
132 | |
133 mojo::ScopedDataPipeProducerHandle writer = | |
134 std::move(data_pipe.producer_handle); | |
135 std::string buffer = "hello"; | |
136 uint32_t size = buffer.size(); | |
137 MojoResult result = | |
138 mojo::WriteDataRaw(writer.get(), buffer.c_str(), &size, kNone); | |
139 ASSERT_EQ(MOJO_RESULT_OK, result); | |
140 ASSERT_EQ(buffer.size(), size); | |
141 | |
142 Run(&context); | |
143 | |
144 EXPECT_FALSE(context.complete); | |
145 EXPECT_EQ("hello", context.data); | |
146 } | |
147 | |
148 TEST_F(URLResponseBodyConsumerTest, OnCompleteThenClose) { | |
149 TestRequestPeer::Context context; | |
150 std::unique_ptr<RequestInfo> request_info(CreateRequestInfo()); | |
151 int request_id = dispatcher_->StartAsync( | |
152 *request_info, nullptr, base::WrapUnique(new TestRequestPeer(&context)), | |
153 blink::WebURLRequest::LoadingIPCType::ChromeIPC, nullptr); | |
154 mojo::DataPipe data_pipe(CreateDataPipeOptions()); | |
155 | |
156 scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer( | |
157 request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle))); | |
158 | |
159 consumer->OnComplete(ResourceRequestCompletionStatus()); | |
160 mojo::ScopedDataPipeProducerHandle writer = | |
161 std::move(data_pipe.producer_handle); | |
162 std::string buffer = "hello"; | |
163 uint32_t size = buffer.size(); | |
164 MojoResult result = | |
165 mojo::WriteDataRaw(writer.get(), buffer.c_str(), &size, kNone); | |
166 ASSERT_EQ(MOJO_RESULT_OK, result); | |
167 ASSERT_EQ(buffer.size(), size); | |
168 writer.reset(); | |
169 | |
170 Run(&context); | |
171 | |
172 EXPECT_FALSE(context.complete); | |
173 EXPECT_EQ("hello", context.data); | |
174 | |
175 Run(&context); | |
176 | |
177 EXPECT_TRUE(context.complete); | |
178 EXPECT_EQ("hello", context.data); | |
179 } | |
180 | |
181 TEST_F(URLResponseBodyConsumerTest, CloseThenOnComplete) { | |
182 TestRequestPeer::Context context; | |
183 std::unique_ptr<RequestInfo> request_info(CreateRequestInfo()); | |
184 int request_id = dispatcher_->StartAsync( | |
185 *request_info, nullptr, base::WrapUnique(new TestRequestPeer(&context)), | |
186 blink::WebURLRequest::LoadingIPCType::ChromeIPC, nullptr); | |
187 mojo::DataPipe data_pipe(CreateDataPipeOptions()); | |
188 | |
189 scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer( | |
190 request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle))); | |
191 | |
192 ResourceRequestCompletionStatus status; | |
193 status.error_code = net::ERR_FAILED; | |
194 data_pipe.producer_handle.reset(); | |
195 consumer->OnComplete(status); | |
196 | |
197 Run(&context); | |
198 | |
199 EXPECT_TRUE(context.complete); | |
200 EXPECT_EQ(net::ERR_FAILED, context.error_code); | |
201 EXPECT_EQ("", context.data); | |
202 } | |
203 | |
204 } // namespace | |
205 | |
206 } // namespace content | |
OLD | NEW |