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/browser/loader/mojo_async_resource_handler.h" | |
6 | |
7 #include <string.h> | |
8 | |
9 #include <utility> | |
10 | |
11 #include "base/bind.h" | |
12 #include "base/callback.h" | |
13 #include "base/files/file_path.h" | |
14 #include "base/memory/ptr_util.h" | |
15 #include "base/memory/scoped_vector.h" | |
16 #include "base/memory/weak_ptr.h" | |
17 #include "base/run_loop.h" | |
18 #include "content/browser/loader/resource_dispatcher_host_impl.h" | |
19 #include "content/browser/loader/resource_request_info_impl.h" | |
20 #include "content/browser/loader/test_url_loader_client.h" | |
21 #include "content/common/resource_request_completion_status.h" | |
22 #include "content/common/url_loader.mojom.h" | |
23 #include "content/public/browser/appcache_service.h" | |
24 #include "content/public/browser/navigation_data.h" | |
25 #include "content/public/browser/resource_context.h" | |
26 #include "content/public/browser/resource_controller.h" | |
27 #include "content/public/browser/resource_dispatcher_host_delegate.h" | |
28 #include "content/public/browser/resource_throttle.h" | |
29 #include "content/public/browser/stream_info.h" | |
30 #include "content/public/common/resource_response.h" | |
31 #include "content/public/common/resource_type.h" | |
32 #include "content/public/test/test_browser_context.h" | |
33 #include "content/public/test/test_browser_thread_bundle.h" | |
34 #include "mojo/public/c/system/data_pipe.h" | |
35 #include "mojo/public/c/system/types.h" | |
36 #include "mojo/public/cpp/system/data_pipe.h" | |
37 #include "net/base/auth.h" | |
38 #include "net/base/net_errors.h" | |
39 #include "net/http/http_response_headers.h" | |
40 #include "net/http/http_response_info.h" | |
41 #include "net/http/http_status_code.h" | |
42 #include "net/http/http_util.h" | |
43 #include "net/ssl/client_cert_store.h" | |
44 #include "net/test/url_request/url_request_failed_job.h" | |
45 #include "net/url_request/url_request.h" | |
46 #include "net/url_request/url_request_context.h" | |
47 #include "net/url_request/url_request_filter.h" | |
48 #include "net/url_request/url_request_status.h" | |
49 #include "net/url_request/url_request_test_util.h" | |
50 #include "testing/gtest/include/gtest/gtest.h" | |
51 #include "ui/base/page_transition_types.h" | |
52 | |
53 namespace content { | |
54 namespace { | |
55 | |
56 class TestResourceDispatcherHostDelegate final | |
57 : public ResourceDispatcherHostDelegate { | |
58 public: | |
59 TestResourceDispatcherHostDelegate() = default; | |
60 ~TestResourceDispatcherHostDelegate() override { | |
61 EXPECT_EQ(num_on_response_started_calls_expectation_, | |
62 num_on_response_started_calls_); | |
63 } | |
64 | |
65 bool ShouldBeginRequest(const std::string& method, | |
66 const GURL& url, | |
67 ResourceType resource_type, | |
68 ResourceContext* resource_context) override { | |
69 ADD_FAILURE() << "ShouldBeginRequest should not be called."; | |
70 return false; | |
71 } | |
72 | |
73 void RequestBeginning(net::URLRequest* request, | |
74 ResourceContext* resource_context, | |
75 AppCacheService* appcache_service, | |
76 ResourceType resource_type, | |
77 ScopedVector<ResourceThrottle>* throttles) override { | |
78 ADD_FAILURE() << "RequestBeginning should not be called."; | |
79 } | |
80 | |
81 void DownloadStarting(net::URLRequest* request, | |
82 ResourceContext* resource_context, | |
83 int child_id, | |
84 int route_id, | |
85 bool is_content_initiated, | |
86 bool must_download, | |
87 ScopedVector<ResourceThrottle>* throttles) override { | |
88 ADD_FAILURE() << "DownloadStarting should not be called."; | |
89 } | |
90 | |
91 ResourceDispatcherHostLoginDelegate* CreateLoginDelegate( | |
92 net::AuthChallengeInfo* auth_info, | |
93 net::URLRequest* request) override { | |
94 ADD_FAILURE() << "CreateLoginDelegate should not be called."; | |
95 return nullptr; | |
96 } | |
97 | |
98 bool HandleExternalProtocol( | |
99 const GURL& url, | |
100 int child_id, | |
101 const ResourceRequestInfo::WebContentsGetter& web_contents_getter, | |
102 bool is_main_frame, | |
103 ui::PageTransition page_transition, | |
104 bool has_user_gesture, | |
105 ResourceContext* resource_context) override { | |
106 ADD_FAILURE() << "HandleExternalProtocol should not be called."; | |
107 return false; | |
108 } | |
109 | |
110 bool ShouldForceDownloadResource(const GURL& url, | |
111 const std::string& mime_type) override { | |
112 ADD_FAILURE() << "ShouldForceDownloadResource should not be called."; | |
113 return false; | |
114 } | |
115 | |
116 bool ShouldInterceptResourceAsStream(net::URLRequest* request, | |
117 const base::FilePath& plugin_path, | |
118 const std::string& mime_type, | |
119 GURL* origin, | |
120 std::string* payload) override { | |
121 ADD_FAILURE() << "ShouldInterceptResourceAsStream should not be called."; | |
122 return false; | |
123 } | |
124 | |
125 void OnStreamCreated(net::URLRequest* request, | |
126 std::unique_ptr<content::StreamInfo> stream) override { | |
127 ADD_FAILURE() << "OnStreamCreated should not be called."; | |
128 } | |
129 | |
130 void OnResponseStarted(net::URLRequest* request, | |
131 ResourceContext* resource_context, | |
132 ResourceResponse* response) override { | |
133 ++num_on_response_started_calls_; | |
134 } | |
135 | |
136 void OnRequestRedirected(const GURL& redirect_url, | |
137 net::URLRequest* request, | |
138 ResourceContext* resource_context, | |
139 ResourceResponse* response) override { | |
140 ADD_FAILURE() << "OnRequestRedirected should not be called."; | |
141 } | |
142 | |
143 void RequestComplete(net::URLRequest* url_request) override { | |
144 ADD_FAILURE() << "RequestComplete should not be called."; | |
145 } | |
146 | |
147 bool ShouldEnableLoFiMode( | |
148 const net::URLRequest& url_request, | |
149 content::ResourceContext* resource_context) override { | |
150 ADD_FAILURE() << "ShouldEnableLoFiMode should not be called."; | |
151 return false; | |
152 } | |
153 | |
154 NavigationData* GetNavigationData(net::URLRequest* request) const override { | |
155 ADD_FAILURE() << "GetNavigationData should not be called."; | |
156 return nullptr; | |
157 } | |
158 | |
159 std::unique_ptr<net::ClientCertStore> CreateClientCertStore( | |
160 ResourceContext* resource_context) override { | |
161 ADD_FAILURE() << "CreateClientCertStore should not be called."; | |
162 return nullptr; | |
163 } | |
164 | |
165 int num_on_response_started_calls() const { | |
166 return num_on_response_started_calls_; | |
167 } | |
168 void set_num_on_response_started_calls_expectation(int expectation) { | |
169 num_on_response_started_calls_expectation_ = expectation; | |
170 } | |
171 | |
172 private: | |
173 int num_on_response_started_calls_ = 0; | |
174 int num_on_response_started_calls_expectation_ = 0; | |
175 | |
176 DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherHostDelegate); | |
177 }; | |
178 | |
179 class TestResourceController : public ResourceController { | |
180 public: | |
181 TestResourceController() {} | |
182 ~TestResourceController() override {} | |
183 | |
184 void Cancel() override { ADD_FAILURE() << "Cancel should not be called."; } | |
185 | |
186 void CancelAndIgnore() override { | |
187 ADD_FAILURE() << "CancelAndIgnore should not be called."; | |
188 } | |
189 | |
190 void CancelWithError(int error_code) override { | |
191 is_cancel_with_error_called_ = true; | |
192 error_ = error_code; | |
193 if (quit_closure_) | |
194 quit_closure_.Run(); | |
195 } | |
196 | |
197 void Resume() override { ++num_resume_calls_; } | |
198 | |
199 void RunUntilCancelWithErrorCalled() { | |
200 base::RunLoop run_loop; | |
201 quit_closure_ = run_loop.QuitClosure(); | |
202 run_loop.Run(); | |
203 } | |
204 | |
205 void set_quit_closure(const base::Closure& quit_closure) { | |
206 quit_closure_ = quit_closure; | |
207 } | |
208 | |
209 bool is_cancel_with_error_called() const { | |
210 return is_cancel_with_error_called_; | |
211 } | |
212 int error() const { return error_; } | |
213 int num_resume_calls() const { return num_resume_calls_; } | |
214 | |
215 private: | |
216 bool is_cancel_with_error_called_ = false; | |
217 int error_ = net::OK; | |
218 int num_resume_calls_ = 0; | |
219 base::Closure quit_closure_; | |
220 | |
221 DISALLOW_COPY_AND_ASSIGN(TestResourceController); | |
222 }; | |
223 | |
224 class MojoAsyncResourceHandlerWithCustomDataPipeOperations | |
225 : public MojoAsyncResourceHandler { | |
226 public: | |
227 MojoAsyncResourceHandlerWithCustomDataPipeOperations( | |
228 net::URLRequest* request, | |
229 ResourceDispatcherHostImpl* rdh, | |
230 mojo::InterfaceRequest<mojom::URLLoader> mojo_request, | |
231 mojom::URLLoaderClientPtr url_loader_client) | |
232 : MojoAsyncResourceHandler(request, | |
233 rdh, | |
234 std::move(mojo_request), | |
235 std::move(url_loader_client)) {} | |
236 ~MojoAsyncResourceHandlerWithCustomDataPipeOperations() override {} | |
237 | |
238 void ResetBeginWriteExpectation() { is_begin_write_expectation_set_ = false; } | |
239 | |
240 void set_begin_write_expectation(MojoResult begin_write_expectation) { | |
241 is_begin_write_expectation_set_ = true; | |
242 begin_write_expectation_ = begin_write_expectation; | |
243 } | |
244 void set_end_write_expectation(MojoResult end_write_expectation) { | |
245 is_end_write_expectation_set_ = true; | |
246 end_write_expectation_ = end_write_expectation; | |
247 } | |
248 | |
249 private: | |
250 MojoResult BeginWrite(void** data, uint32_t* available) override { | |
251 if (is_begin_write_expectation_set_) | |
252 return begin_write_expectation_; | |
253 return MojoAsyncResourceHandler::BeginWrite(data, available); | |
254 } | |
255 MojoResult EndWrite(uint32_t written) override { | |
256 if (is_end_write_expectation_set_) | |
257 return end_write_expectation_; | |
258 return MojoAsyncResourceHandler::EndWrite(written); | |
259 } | |
260 | |
261 bool is_begin_write_expectation_set_ = false; | |
262 bool is_end_write_expectation_set_ = false; | |
263 MojoResult begin_write_expectation_ = MOJO_RESULT_UNKNOWN; | |
264 MojoResult end_write_expectation_ = MOJO_RESULT_UNKNOWN; | |
265 | |
266 DISALLOW_COPY_AND_ASSIGN( | |
267 MojoAsyncResourceHandlerWithCustomDataPipeOperations); | |
268 }; | |
269 | |
270 class MojoAsyncResourceHandlerTestBase { | |
271 public: | |
272 MojoAsyncResourceHandlerTestBase() | |
273 : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), | |
274 browser_context_(new TestBrowserContext()) { | |
275 MojoAsyncResourceHandler::SetAllocationSizeForTesting(32 * 1024); | |
276 rdh_.SetDelegate(&rdh_delegate_); | |
277 | |
278 // Calling this function creates a request context. | |
279 browser_context_->GetResourceContext()->GetRequestContext(); | |
kinuko
2016/08/04 16:07:02
We get request_context right below on line 283, do
yhirano
2016/08/05 12:21:39
I needed them but it looks we don't need them any
| |
280 base::RunLoop().RunUntilIdle(); | |
281 | |
282 url_request_delegate_.reset(new net::TestDelegate()); | |
283 net::URLRequestContext* request_context = | |
284 browser_context_->GetResourceContext()->GetRequestContext(); | |
285 request_ = request_context->CreateRequest( | |
286 net::URLRequestFailedJob::GetMockHttpUrl(net::ERR_TIMED_OUT), | |
287 net::DEFAULT_PRIORITY, url_request_delegate_.get()); | |
288 ResourceRequestInfo::AllocateForTesting( | |
289 request_.get(), RESOURCE_TYPE_XHR, | |
290 browser_context_->GetResourceContext(), 2, 0, 0, true, false, false, | |
291 true, false); | |
kinuko
2016/08/04 16:07:02
nit: would be nice to have short comments for some
yhirano
2016/08/05 12:21:39
Done.
| |
292 handler_.reset(new MojoAsyncResourceHandlerWithCustomDataPipeOperations( | |
293 request_.get(), &rdh_, nullptr, | |
294 url_loader_client_.CreateInterfacePtrAndBind())); | |
295 handler_->SetController(&resource_controller_); | |
296 } | |
297 | |
298 virtual ~MojoAsyncResourceHandlerTestBase() { | |
299 net::URLRequestFilter::GetInstance()->ClearHandlers(); | |
300 MojoAsyncResourceHandler::SetAllocationSizeForTesting( | |
301 MojoAsyncResourceHandler::kDefaultAllocationSize); | |
302 } | |
303 | |
304 // Returns false if something bad happens. | |
305 bool CallOnWillStart() { | |
306 bool defer = false; | |
307 if (!handler_->OnWillStart(request_->url(), &defer)) { | |
308 ADD_FAILURE() << "OnWillStart returns false."; | |
309 return false; | |
310 } | |
311 if (defer) { | |
312 ADD_FAILURE() << "OnWillStart sets |defer| true."; | |
313 return false; | |
314 } | |
315 return true; | |
316 } | |
317 | |
318 // Returns false if something bad happens. | |
319 bool CallOnWillStartAndOnResponseStarted() { | |
320 rdh_delegate_.set_num_on_response_started_calls_expectation(1); | |
321 if (!CallOnWillStart()) | |
322 return false; | |
323 | |
324 scoped_refptr<ResourceResponse> response = new ResourceResponse(); | |
325 bool defer = false; | |
326 if (!handler_->OnResponseStarted(response.get(), &defer)) { | |
327 ADD_FAILURE() << "OnResponseStarted returns false."; | |
328 return false; | |
329 } | |
330 if (defer) { | |
331 ADD_FAILURE() << "OnResponseStarted sets |defer| true."; | |
332 return false; | |
333 } | |
334 if (url_loader_client_.has_received_response()) { | |
335 ADD_FAILURE() << "URLLoaderClient unexpectedly gets a response."; | |
336 return false; | |
337 } | |
338 url_loader_client_.RunUntilResponseReceived(); | |
339 return true; | |
340 } | |
341 | |
342 TestBrowserThreadBundle thread_bundle_; | |
343 TestResourceDispatcherHostDelegate rdh_delegate_; | |
344 ResourceDispatcherHostImpl rdh_; | |
345 TestURLLoaderClient url_loader_client_; | |
346 TestResourceController resource_controller_; | |
347 std::unique_ptr<TestBrowserContext> browser_context_; | |
348 std::unique_ptr<net::TestDelegate> url_request_delegate_; | |
349 std::unique_ptr<net::URLRequest> request_; | |
350 std::unique_ptr<MojoAsyncResourceHandlerWithCustomDataPipeOperations> | |
351 handler_; | |
352 | |
353 DISALLOW_COPY_AND_ASSIGN(MojoAsyncResourceHandlerTestBase); | |
354 }; | |
355 | |
356 class MojoAsyncResourceHandlerTest : public MojoAsyncResourceHandlerTestBase, | |
357 public ::testing::Test {}; | |
358 | |
359 // This test class is parameterized with MojoAsyncResourceHandler's allocation | |
360 // size. | |
361 class MojoAsyncResourceHandlerWithAllocationSizeTest | |
362 : public MojoAsyncResourceHandlerTestBase, | |
363 public ::testing::TestWithParam<size_t> { | |
364 protected: | |
365 MojoAsyncResourceHandlerWithAllocationSizeTest() { | |
366 MojoAsyncResourceHandler::SetAllocationSizeForTesting(GetParam()); | |
367 } | |
368 }; | |
369 | |
370 TEST_F(MojoAsyncResourceHandlerTest, InFlightRequests) { | |
371 EXPECT_EQ(0, rdh_.num_in_flight_requests_for_testing()); | |
372 handler_ = nullptr; | |
373 EXPECT_EQ(0, rdh_.num_in_flight_requests_for_testing()); | |
374 } | |
375 | |
376 TEST_F(MojoAsyncResourceHandlerTest, OnWillStart) { | |
377 bool defer = false; | |
378 EXPECT_TRUE(handler_->OnWillStart(request_->url(), &defer)); | |
379 EXPECT_FALSE(defer); | |
380 } | |
381 | |
382 TEST_F(MojoAsyncResourceHandlerTest, OnResponseStarted) { | |
383 rdh_delegate_.set_num_on_response_started_calls_expectation(1); | |
384 ASSERT_TRUE(CallOnWillStart()); | |
385 | |
386 scoped_refptr<ResourceResponse> response = new ResourceResponse(); | |
387 response->head.content_length = 99; | |
388 response->head.request_start = | |
389 base::TimeTicks::UnixEpoch() + base::TimeDelta::FromDays(14); | |
390 response->head.response_start = | |
391 base::TimeTicks::UnixEpoch() + base::TimeDelta::FromDays(28); | |
392 | |
393 bool defer = false; | |
394 | |
395 EXPECT_EQ(0, rdh_delegate_.num_on_response_started_calls()); | |
396 base::TimeTicks now1 = base::TimeTicks::Now(); | |
397 ASSERT_TRUE(handler_->OnResponseStarted(response.get(), &defer)); | |
398 base::TimeTicks now2 = base::TimeTicks::Now(); | |
399 | |
400 EXPECT_FALSE(defer); | |
401 EXPECT_EQ(request_->creation_time(), response->head.request_start); | |
402 EXPECT_LE(now1, response->head.response_start); | |
403 EXPECT_LE(response->head.response_start, now2); | |
404 EXPECT_EQ(1, rdh_delegate_.num_on_response_started_calls()); | |
405 | |
406 url_loader_client_.RunUntilResponseReceived(); | |
407 EXPECT_EQ(response->head.request_start, | |
408 url_loader_client_.response_head().request_start); | |
409 EXPECT_EQ(response->head.response_start, | |
410 url_loader_client_.response_head().response_start); | |
411 EXPECT_EQ(99, url_loader_client_.response_head().content_length); | |
412 } | |
413 | |
414 TEST_F(MojoAsyncResourceHandlerTest, OnWillReadAndInFlightRequests) { | |
415 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
416 EXPECT_EQ(0, rdh_.num_in_flight_requests_for_testing()); | |
417 scoped_refptr<net::IOBuffer> io_buffer; | |
418 int io_buffer_size; | |
419 EXPECT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
420 EXPECT_EQ(1, rdh_.num_in_flight_requests_for_testing()); | |
421 handler_ = nullptr; | |
422 EXPECT_EQ(0, rdh_.num_in_flight_requests_for_testing()); | |
423 } | |
424 | |
425 TEST_F(MojoAsyncResourceHandlerTest, OnWillReadWithInsufficientResource) { | |
426 rdh_.set_max_num_in_flight_requests_per_process(0); | |
427 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
428 | |
429 scoped_refptr<net::IOBuffer> io_buffer; | |
430 int io_buffer_size = 0; | |
431 EXPECT_FALSE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
432 EXPECT_FALSE(io_buffer); | |
433 EXPECT_EQ(0, io_buffer_size); | |
434 EXPECT_EQ(1, rdh_.num_in_flight_requests_for_testing()); | |
435 EXPECT_TRUE(resource_controller_.is_cancel_with_error_called()); | |
436 EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES, resource_controller_.error()); | |
437 handler_ = nullptr; | |
438 EXPECT_EQ(0, rdh_.num_in_flight_requests_for_testing()); | |
439 } | |
440 | |
441 TEST_F(MojoAsyncResourceHandlerTest, OnWillReadAndOnReadCompleted) { | |
442 bool defer = false; | |
443 scoped_refptr<net::IOBuffer> io_buffer; | |
444 int io_buffer_size; | |
445 | |
446 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
447 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
448 ASSERT_TRUE(io_buffer); | |
449 // The buffer size that the mime sniffer requires implicitly. | |
450 ASSERT_GE(io_buffer_size, 2 * 1024); | |
kinuko
2016/08/04 16:07:02
Do you mean kMinAllocationSize? Could we refer to
yhirano
2016/08/05 12:21:39
Done.
| |
451 | |
452 url_loader_client_.RunUntilResponseBodyArrived(); | |
453 ASSERT_TRUE(url_loader_client_.response_body().is_valid()); | |
454 | |
455 io_buffer->data()[0] = 'A'; | |
456 io_buffer->data()[1] = 'B'; | |
457 ASSERT_TRUE(handler_->OnReadCompleted(2, &defer)); | |
458 EXPECT_FALSE(defer); | |
459 | |
460 std::string contents; | |
461 while (contents.size() < 2) { | |
462 char buffer[16]; | |
463 uint32_t read = sizeof(buffer); | |
kinuko
2016/08/04 16:07:03
nit: 'read' -> 'read_size' for clarity?
yhirano
2016/08/05 12:21:39
Done.
| |
464 MojoResult result = | |
465 mojo::ReadDataRaw(url_loader_client_.response_body(), buffer, &read, | |
466 MOJO_READ_DATA_FLAG_NONE); | |
467 if (result == MOJO_RESULT_SHOULD_WAIT) { | |
468 base::RunLoop().RunUntilIdle(); | |
469 continue; | |
470 } | |
471 contents.append(buffer, read); | |
472 } | |
473 EXPECT_EQ("AB", contents); | |
474 } | |
475 | |
476 TEST_F(MojoAsyncResourceHandlerTest, | |
477 OnWillReadAndOnReadCompletedWithInsufficientInitialCapacity) { | |
478 MojoAsyncResourceHandler::SetAllocationSizeForTesting(2); | |
479 | |
480 bool defer = false; | |
481 scoped_refptr<net::IOBuffer> io_buffer; | |
482 int io_buffer_size; | |
483 | |
484 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
485 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
486 ASSERT_TRUE(io_buffer); | |
487 // The buffer size that the mime sniffer requires implicitly. | |
488 ASSERT_GE(io_buffer_size, 2 * 1024); | |
kinuko
2016/08/04 16:07:02
ditto
yhirano
2016/08/05 12:21:39
Done.
| |
489 | |
490 url_loader_client_.RunUntilResponseBodyArrived(); | |
491 ASSERT_TRUE(url_loader_client_.response_body().is_valid()); | |
492 | |
493 const std::string data("abcdefgh"); | |
494 strcpy(io_buffer->data(), data.c_str()); | |
495 ASSERT_TRUE(handler_->OnReadCompleted(data.size(), &defer)); | |
496 EXPECT_TRUE(defer); | |
497 | |
498 std::string contents; | |
499 while (contents.size() < data.size()) { | |
500 // This is needed for Resume to be called. | |
501 base::RunLoop().RunUntilIdle(); | |
kinuko
2016/08/04 16:07:02
We call this in MOJO_RESULT_SHOULD_WAIT condition
mmenke
2016/08/04 16:12:44
If we get MOJO_RESULT_SHOULD_WAIT in the ReadDataR
kinuko
2016/08/04 16:57:09
Uh, yeah... wasn't really reading the code. Thank
| |
502 char buffer[16]; | |
503 uint32_t read = sizeof(buffer); | |
kinuko
2016/08/04 16:07:02
ditto
yhirano
2016/08/05 12:21:39
Done.
| |
504 MojoResult result = | |
505 mojo::ReadDataRaw(url_loader_client_.response_body(), buffer, &read, | |
506 MOJO_READ_DATA_FLAG_NONE); | |
507 if (result == MOJO_RESULT_SHOULD_WAIT) | |
508 continue; | |
509 ASSERT_EQ(MOJO_RESULT_OK, result); | |
510 contents.append(buffer, read); | |
511 } | |
512 EXPECT_EQ(data, contents); | |
513 EXPECT_EQ(0, resource_controller_.num_resume_calls()); | |
514 } | |
515 | |
516 TEST_F(MojoAsyncResourceHandlerTest, | |
517 IOBufferFromOnWillReadShouldRemainValidEvenIfHandlerIsGone) { | |
518 scoped_refptr<net::IOBuffer> io_buffer; | |
519 int io_buffer_size; | |
520 | |
521 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
522 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
523 ASSERT_TRUE(io_buffer); | |
524 // The io_buffer size that the mime sniffer requires implicitly. | |
525 ASSERT_GE(io_buffer_size, 2 * 1024); | |
kinuko
2016/08/04 16:07:02
ditto... or if we use this magic number repeatedly
yhirano
2016/08/05 12:21:39
Done.
| |
526 | |
527 handler_ = nullptr; | |
528 url_loader_client_.Unbind(); | |
529 base::RunLoop().RunUntilIdle(); | |
530 | |
531 // Hopefully ASAN checks this operation's validity. | |
532 io_buffer->data()[0] = 'A'; | |
533 } | |
534 | |
535 TEST_F(MojoAsyncResourceHandlerTest, OnResponseCompleted) { | |
536 bool defer = false; | |
537 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
538 | |
539 ResourceRequestInfoImpl::ForRequest(request_.get()) | |
540 ->set_was_ignored_by_handler(false); | |
541 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, net::OK); | |
542 std::string security_info = "info0"; | |
543 | |
544 base::TimeTicks now1 = base::TimeTicks::Now(); | |
545 handler_->OnResponseCompleted(status, security_info, &defer); | |
546 base::TimeTicks now2 = base::TimeTicks::Now(); | |
547 EXPECT_FALSE(defer); | |
548 | |
549 url_loader_client_.RunUntilComplete(); | |
550 EXPECT_TRUE(url_loader_client_.has_received_completion()); | |
551 EXPECT_EQ(net::OK, url_loader_client_.completion_status().error_code); | |
552 EXPECT_FALSE(url_loader_client_.completion_status().was_ignored_by_handler); | |
553 EXPECT_EQ("info0", url_loader_client_.completion_status().security_info); | |
554 EXPECT_LE(now1, url_loader_client_.completion_status().completion_time); | |
555 EXPECT_LE(url_loader_client_.completion_status().completion_time, now2); | |
556 EXPECT_EQ(request_->GetTotalReceivedBytes(), | |
557 url_loader_client_.completion_status().encoded_data_length); | |
558 } | |
559 | |
560 // This test case sets different status values from OnResponseCompleted. | |
561 TEST_F(MojoAsyncResourceHandlerTest, OnResponseCompleted2) { | |
562 rdh_.SetDelegate(nullptr); | |
563 bool defer = false; | |
564 // Don't use CallOnWillStartAndOnResponseStarted as this test case manually | |
565 // sets the null delegate. | |
566 ASSERT_TRUE(CallOnWillStart()); | |
567 scoped_refptr<ResourceResponse> response = new ResourceResponse(); | |
568 ASSERT_TRUE(handler_->OnResponseStarted(response.get(), &defer)); | |
569 ASSERT_FALSE(defer); | |
570 ASSERT_FALSE(url_loader_client_.has_received_response()); | |
571 url_loader_client_.RunUntilResponseReceived(); | |
572 | |
573 ResourceRequestInfoImpl::ForRequest(request_.get()) | |
574 ->set_was_ignored_by_handler(true); | |
575 net::URLRequestStatus status(net::URLRequestStatus::CANCELED, | |
576 net::ERR_ABORTED); | |
577 std::string security_info = "info1"; | |
578 | |
579 base::TimeTicks now1 = base::TimeTicks::Now(); | |
580 handler_->OnResponseCompleted(status, security_info, &defer); | |
581 base::TimeTicks now2 = base::TimeTicks::Now(); | |
582 EXPECT_FALSE(defer); | |
583 | |
584 url_loader_client_.RunUntilComplete(); | |
585 EXPECT_TRUE(url_loader_client_.has_received_completion()); | |
586 EXPECT_EQ(net::ERR_ABORTED, | |
587 url_loader_client_.completion_status().error_code); | |
588 EXPECT_TRUE(url_loader_client_.completion_status().was_ignored_by_handler); | |
589 EXPECT_EQ("info1", url_loader_client_.completion_status().security_info); | |
590 EXPECT_LE(now1, url_loader_client_.completion_status().completion_time); | |
591 EXPECT_LE(url_loader_client_.completion_status().completion_time, now2); | |
592 EXPECT_EQ(request_->GetTotalReceivedBytes(), | |
593 url_loader_client_.completion_status().encoded_data_length); | |
594 } | |
595 | |
596 TEST_F(MojoAsyncResourceHandlerTest, OnResponseCompletedWithCanceledTimedOut) { | |
597 net::URLRequestStatus status(net::URLRequestStatus::CANCELED, | |
598 net::ERR_TIMED_OUT); | |
599 bool defer = false; | |
600 | |
601 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
602 handler_->OnResponseCompleted(status, "security_info", &defer); | |
603 EXPECT_FALSE(defer); | |
604 | |
605 url_loader_client_.RunUntilComplete(); | |
606 EXPECT_TRUE(url_loader_client_.has_received_completion()); | |
607 EXPECT_EQ(net::ERR_TIMED_OUT, | |
608 url_loader_client_.completion_status().error_code); | |
609 } | |
610 | |
611 TEST_F(MojoAsyncResourceHandlerTest, OnResponseCompletedWithFailedTimedOut) { | |
612 net::URLRequestStatus status(net::URLRequestStatus::FAILED, | |
613 net::ERR_TIMED_OUT); | |
614 bool defer = false; | |
615 | |
616 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
617 handler_->OnResponseCompleted(status, "security_info", &defer); | |
618 EXPECT_FALSE(defer); | |
619 | |
620 url_loader_client_.RunUntilComplete(); | |
621 EXPECT_TRUE(url_loader_client_.has_received_completion()); | |
622 EXPECT_EQ(net::ERR_TIMED_OUT, | |
623 url_loader_client_.completion_status().error_code); | |
624 } | |
625 | |
626 TEST_F(MojoAsyncResourceHandlerTest, ResponseCompletionShouldCloseDataPipe) { | |
627 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
628 | |
629 scoped_refptr<net::IOBuffer> io_buffer; | |
630 int io_buffer_size; | |
631 bool defer = false; | |
632 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
633 url_loader_client_.RunUntilResponseBodyArrived(); | |
634 ASSERT_TRUE(url_loader_client_.response_body().is_valid()); | |
635 ASSERT_TRUE(handler_->OnReadCompleted(0, &defer)); | |
636 EXPECT_FALSE(defer); | |
637 | |
638 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, net::OK); | |
639 handler_->OnResponseCompleted(status, "security_info", &defer); | |
640 EXPECT_FALSE(defer); | |
641 | |
642 url_loader_client_.RunUntilComplete(); | |
643 EXPECT_TRUE(url_loader_client_.has_received_completion()); | |
644 EXPECT_EQ(net::OK, url_loader_client_.completion_status().error_code); | |
645 | |
646 // This is needed because |*io_buffer| may keep the data producer alive. | |
647 io_buffer = nullptr; | |
648 | |
649 while (true) { | |
650 char buffer[16]; | |
651 uint32_t read = sizeof(buffer); | |
kinuko
2016/08/04 16:07:03
ditto
yhirano
2016/08/05 12:21:39
Done.
| |
652 MojoResult result = | |
653 mojo::ReadDataRaw(url_loader_client_.response_body(), buffer, &read, | |
654 MOJO_READ_DATA_FLAG_NONE); | |
655 if (result == MOJO_RESULT_FAILED_PRECONDITION) | |
656 break; | |
657 ASSERT_EQ(result, MOJO_RESULT_SHOULD_WAIT); | |
658 } | |
659 } | |
660 | |
661 TEST_F(MojoAsyncResourceHandlerTest, ResponseErrorDuringBodyTransmission) { | |
662 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
663 | |
664 scoped_refptr<net::IOBuffer> io_buffer; | |
665 int io_buffer_size; | |
666 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
667 url_loader_client_.RunUntilResponseBodyArrived(); | |
668 ASSERT_TRUE(url_loader_client_.response_body().is_valid()); | |
669 ASSERT_GT(io_buffer_size, 0); | |
670 memset(io_buffer->data(), 'a', io_buffer_size); | |
671 bool defer = false; | |
672 ASSERT_TRUE(handler_->OnReadCompleted(io_buffer_size, &defer)); | |
673 // We don't care |defer|'s value here. | |
674 | |
675 defer = false; | |
676 net::URLRequestStatus status(net::URLRequestStatus::FAILED, net::ERR_FAILED); | |
677 handler_->OnResponseCompleted(status, "security_info", &defer); | |
678 EXPECT_FALSE(defer); | |
679 | |
680 url_loader_client_.RunUntilComplete(); | |
681 EXPECT_TRUE(url_loader_client_.has_received_completion()); | |
682 EXPECT_EQ(net::ERR_FAILED, url_loader_client_.completion_status().error_code); | |
683 | |
684 // This is needed because |*io_buffer| may keep the data producer alive. | |
685 io_buffer = nullptr; | |
686 | |
687 std::string actual; | |
688 while (true) { | |
689 char buf[16]; | |
690 uint32_t read = sizeof(buf); | |
691 MojoResult result = mojo::ReadDataRaw(url_loader_client_.response_body(), | |
692 buf, &read, MOJO_READ_DATA_FLAG_NONE); | |
693 if (result == MOJO_RESULT_FAILED_PRECONDITION) | |
694 break; | |
695 if (result == MOJO_RESULT_SHOULD_WAIT) { | |
696 base::RunLoop().RunUntilIdle(); | |
697 continue; | |
698 } | |
699 EXPECT_EQ(MOJO_RESULT_OK, result); | |
700 actual.append(buf, read); | |
701 } | |
702 EXPECT_EQ(std::string(io_buffer_size, 'a'), actual); | |
703 } | |
704 | |
705 // In this case, an error is notified after OnWillRead, before OnReadCompleted. | |
706 TEST_F(MojoAsyncResourceHandlerTest, ResponseErrorDuringBodyTransmission2) { | |
707 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
708 | |
709 scoped_refptr<net::IOBuffer> io_buffer; | |
710 int io_buffer_size; | |
711 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
712 url_loader_client_.RunUntilResponseBodyArrived(); | |
713 ASSERT_TRUE(url_loader_client_.response_body().is_valid()); | |
714 bool defer = false; | |
715 net::URLRequestStatus status(net::URLRequestStatus::FAILED, net::ERR_FAILED); | |
716 handler_->OnResponseCompleted(status, "security_info", &defer); | |
717 EXPECT_FALSE(defer); | |
718 | |
719 url_loader_client_.RunUntilComplete(); | |
720 EXPECT_TRUE(url_loader_client_.has_received_completion()); | |
721 EXPECT_EQ(net::ERR_FAILED, url_loader_client_.completion_status().error_code); | |
722 | |
723 // This is needed because |*io_buffer| may keep the data producer alive. | |
724 io_buffer = nullptr; | |
725 | |
726 while (true) { | |
727 char buf[16]; | |
728 uint32_t read = sizeof(buf); | |
729 MojoResult result = mojo::ReadDataRaw(url_loader_client_.response_body(), | |
730 buf, &read, MOJO_READ_DATA_FLAG_NONE); | |
731 if (result == MOJO_RESULT_FAILED_PRECONDITION) | |
732 break; | |
733 ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT, result); | |
734 base::RunLoop().RunUntilIdle(); | |
735 } | |
736 } | |
737 | |
738 TEST_F(MojoAsyncResourceHandlerTest, BeginWriteFailsOnWillRead) { | |
739 handler_->set_begin_write_expectation(MOJO_RESULT_UNKNOWN); | |
740 scoped_refptr<net::IOBuffer> io_buffer; | |
741 int io_buffer_size = 0; | |
742 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
743 ASSERT_FALSE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
744 EXPECT_FALSE(resource_controller_.is_cancel_with_error_called()); | |
745 } | |
746 | |
747 TEST_F(MojoAsyncResourceHandlerTest, BeginWriteReturnsShouldWaitOnWillRead) { | |
748 handler_->set_begin_write_expectation(MOJO_RESULT_SHOULD_WAIT); | |
749 scoped_refptr<net::IOBuffer> io_buffer; | |
750 int io_buffer_size = 0; | |
751 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
752 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
753 EXPECT_TRUE(io_buffer); | |
754 EXPECT_GT(io_buffer_size, 0); | |
755 } | |
756 | |
757 TEST_F(MojoAsyncResourceHandlerTest, | |
758 BeginWriteReturnsShouldWaitOnWillReadAndThenReturnsOK) { | |
759 handler_->set_begin_write_expectation(MOJO_RESULT_SHOULD_WAIT); | |
760 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
761 size_t written = 0; | |
762 std::string actual; | |
kinuko
2016/08/04 16:07:02
nit: actual's not used until line 782, maybe move
yhirano
2016/08/05 12:21:39
Done.
| |
763 while (true) { | |
764 scoped_refptr<net::IOBuffer> io_buffer; | |
765 int io_buffer_size = 0; | |
766 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
767 EXPECT_TRUE(io_buffer); | |
768 EXPECT_GT(io_buffer_size, 0); | |
769 memset(io_buffer->data(), 'X', io_buffer_size); | |
770 written += io_buffer_size; | |
771 bool defer = false; | |
772 ASSERT_TRUE(handler_->OnReadCompleted(io_buffer_size, &defer)); | |
773 if (defer) | |
774 break; | |
775 } | |
776 | |
777 url_loader_client_.RunUntilResponseBodyArrived(); | |
778 ASSERT_TRUE(url_loader_client_.response_body().is_valid()); | |
779 handler_->ResetBeginWriteExpectation(); | |
780 handler_->ResumeForTesting(); | |
781 | |
782 while (actual.size() < written) { | |
783 char buf[16]; | |
784 uint32_t read = sizeof(buf); | |
785 MojoResult result = mojo::ReadDataRaw(url_loader_client_.response_body(), | |
786 buf, &read, MOJO_READ_DATA_FLAG_NONE); | |
787 ASSERT_TRUE(result == MOJO_RESULT_OK || result == MOJO_RESULT_SHOULD_WAIT); | |
788 if (result == MOJO_RESULT_OK) | |
789 actual.append(buf, read); | |
790 base::RunLoop().RunUntilIdle(); | |
791 } | |
792 | |
793 base::RunLoop().RunUntilIdle(); | |
kinuko
2016/08/04 16:07:02
nit: we always seem to run loop at the end of whil
yhirano
2016/08/05 12:21:39
Done.
| |
794 | |
795 EXPECT_EQ(std::string(written, 'X'), actual); | |
796 EXPECT_EQ(1, resource_controller_.num_resume_calls()); | |
797 } | |
798 | |
799 TEST_F(MojoAsyncResourceHandlerTest, | |
800 EndWriteFailsOnWillReadWithInsufficientInitialCapacity) { | |
801 MojoAsyncResourceHandler::SetAllocationSizeForTesting(2); | |
802 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
803 handler_->set_end_write_expectation(MOJO_RESULT_UNKNOWN); | |
804 scoped_refptr<net::IOBuffer> io_buffer; | |
805 int io_buffer_size = 0; | |
kinuko
2016/08/04 16:07:02
nit: we initialize io_buffer_size before calling O
yhirano
2016/08/05 12:21:39
Done.
| |
806 ASSERT_FALSE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
807 } | |
808 | |
809 TEST_F(MojoAsyncResourceHandlerTest, EndWriteFailsOnReadCompleted) { | |
810 scoped_refptr<net::IOBuffer> io_buffer; | |
811 int io_buffer_size = 0; | |
812 bool defer = false; | |
813 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
814 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
815 | |
816 handler_->set_end_write_expectation(MOJO_RESULT_SHOULD_WAIT); | |
817 ASSERT_FALSE(handler_->OnReadCompleted(io_buffer_size, &defer)); | |
818 } | |
819 | |
820 TEST_F(MojoAsyncResourceHandlerTest, | |
821 EndWriteFailsOnReadCompletedWithInsufficientInitialCapacity) { | |
822 MojoAsyncResourceHandler::SetAllocationSizeForTesting(2); | |
823 scoped_refptr<net::IOBuffer> io_buffer; | |
824 int io_buffer_size = 0; | |
825 bool defer = false; | |
826 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
827 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
828 | |
829 handler_->set_end_write_expectation(MOJO_RESULT_SHOULD_WAIT); | |
830 ASSERT_FALSE(handler_->OnReadCompleted(io_buffer_size, &defer)); | |
831 } | |
832 | |
833 TEST_F(MojoAsyncResourceHandlerTest, | |
834 EndWriteFailsOnResumeWithInsufficientInitialCapacity) { | |
835 MojoAsyncResourceHandler::SetAllocationSizeForTesting(8); | |
836 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
837 scoped_refptr<net::IOBuffer> io_buffer; | |
838 int io_buffer_size = 0; | |
839 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
840 url_loader_client_.RunUntilResponseBodyArrived(); | |
841 ASSERT_TRUE(url_loader_client_.response_body().is_valid()); | |
842 | |
843 while (true) { | |
844 bool defer = false; | |
845 ASSERT_TRUE(handler_->OnReadCompleted(io_buffer_size, &defer)); | |
846 ASSERT_GE(io_buffer_size, 0); | |
847 if (defer) | |
848 break; | |
849 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
850 } | |
851 | |
852 while (true) { | |
853 char buf[16]; | |
854 uint32_t read = sizeof(buf); | |
kinuko
2016/08/04 16:07:03
ditto
yhirano
2016/08/05 12:21:39
Done.
| |
855 MojoResult result = mojo::ReadDataRaw(url_loader_client_.response_body(), | |
856 buf, &read, MOJO_READ_DATA_FLAG_NONE); | |
857 if (result == MOJO_RESULT_SHOULD_WAIT) | |
858 break; | |
859 ASSERT_EQ(MOJO_RESULT_OK, result); | |
860 } | |
861 | |
862 handler_->set_end_write_expectation(MOJO_RESULT_SHOULD_WAIT); | |
863 resource_controller_.RunUntilCancelWithErrorCalled(); | |
864 EXPECT_FALSE(url_loader_client_.has_received_completion()); | |
865 EXPECT_TRUE(resource_controller_.is_cancel_with_error_called()); | |
866 EXPECT_EQ(net::ERR_FAILED, resource_controller_.error()); | |
867 } | |
868 | |
869 TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest, | |
870 OnWillReadWithLongContents) { | |
871 bool defer = false; | |
872 scoped_refptr<net::IOBuffer> io_buffer; | |
873 int io_buffer_size = 0; | |
874 | |
875 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
876 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
877 ASSERT_TRUE(io_buffer); | |
878 // The io_buffer size that the mime sniffer requires implicitly. | |
879 ASSERT_GE(io_buffer_size, 2 * 1024); | |
kinuko
2016/08/04 16:07:02
ditto
yhirano
2016/08/05 12:21:39
Done.
| |
880 std::string expected; | |
881 for (int i = 0; i < 3 * io_buffer_size + 2; ++i) | |
882 expected += ('A' + i % 26); | |
883 | |
884 ASSERT_TRUE(handler_->OnReadCompleted(0, &defer)); | |
885 ASSERT_FALSE(defer); | |
886 | |
887 url_loader_client_.RunUntilResponseBodyArrived(); | |
888 ASSERT_TRUE(url_loader_client_.response_body().is_valid()); | |
889 | |
890 size_t written = 0; | |
891 std::string actual; | |
892 while (actual.size() < expected.size()) { | |
893 while (written < expected.size() && !defer) { | |
894 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
895 const size_t to_be_written = std::min(static_cast<size_t>(io_buffer_size), | |
896 expected.size() - written); | |
897 memcpy(io_buffer->data(), &expected[written], to_be_written); | |
898 ASSERT_TRUE(handler_->OnReadCompleted(to_be_written, &defer)); | |
899 written += to_be_written; | |
900 } | |
901 | |
902 char buf[16]; | |
903 uint32_t read = sizeof(buf); | |
904 MojoResult result = mojo::ReadDataRaw(url_loader_client_.response_body(), | |
905 buf, &read, MOJO_READ_DATA_FLAG_NONE); | |
906 if (result != MOJO_RESULT_SHOULD_WAIT) { | |
907 ASSERT_EQ(MOJO_RESULT_OK, result); | |
908 actual.append(buf, read); | |
909 } | |
910 int resume_count = resource_controller_.num_resume_calls(); | |
911 base::RunLoop().RunUntilIdle(); | |
912 // Continue writing if controller->Resume() is called. | |
913 defer = (resume_count == resource_controller_.num_resume_calls()); | |
914 } | |
915 EXPECT_EQ(expected, actual); | |
916 } | |
917 | |
918 TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest, | |
919 BeginWriteFailsOnReadCompleted) { | |
920 scoped_refptr<net::IOBuffer> io_buffer; | |
921 int io_buffer_size = 0; | |
922 bool defer = false; | |
923 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
924 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
925 | |
926 handler_->set_begin_write_expectation(MOJO_RESULT_UNKNOWN); | |
927 ASSERT_FALSE(handler_->OnReadCompleted(io_buffer_size, &defer)); | |
928 } | |
929 | |
930 TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest, | |
931 BeginWriteReturnsShouldWaitOnReadCompleted) { | |
932 scoped_refptr<net::IOBuffer> io_buffer; | |
933 int io_buffer_size = 0; | |
934 bool defer = false; | |
935 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
936 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
937 | |
938 handler_->set_begin_write_expectation(MOJO_RESULT_SHOULD_WAIT); | |
939 ASSERT_TRUE(handler_->OnReadCompleted(io_buffer_size, &defer)); | |
940 EXPECT_TRUE(defer); | |
941 } | |
942 | |
943 TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest, | |
944 BeginWriteFailsOnResume) { | |
945 bool defer = false; | |
946 int io_buffer_size = 0; | |
947 scoped_refptr<net::IOBuffer> io_buffer; | |
948 | |
949 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
950 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
951 ASSERT_TRUE(handler_->OnReadCompleted(0, &defer)); | |
952 ASSERT_FALSE(defer); | |
953 url_loader_client_.RunUntilResponseBodyArrived(); | |
954 ASSERT_TRUE(url_loader_client_.response_body().is_valid()); | |
955 | |
956 while (!defer) { | |
957 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
958 ASSERT_TRUE(handler_->OnReadCompleted(io_buffer_size, &defer)); | |
959 } | |
960 handler_->set_begin_write_expectation(MOJO_RESULT_UNKNOWN); | |
961 | |
962 while (!resource_controller_.is_cancel_with_error_called()) { | |
963 char buf[256]; | |
964 uint32_t read = sizeof(buf); | |
965 MojoResult result = mojo::ReadDataRaw(url_loader_client_.response_body(), | |
966 buf, &read, MOJO_READ_DATA_FLAG_NONE); | |
967 ASSERT_TRUE(result == MOJO_RESULT_OK || result == MOJO_RESULT_SHOULD_WAIT); | |
968 base::RunLoop().RunUntilIdle(); | |
969 } | |
970 | |
971 EXPECT_FALSE(url_loader_client_.has_received_completion()); | |
972 EXPECT_EQ(net::ERR_FAILED, resource_controller_.error()); | |
973 EXPECT_EQ(0, resource_controller_.num_resume_calls()); | |
974 } | |
975 | |
976 TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest, CancelWhileWaiting) { | |
977 bool defer = false; | |
978 ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); | |
979 | |
980 while (!defer) { | |
981 scoped_refptr<net::IOBuffer> io_buffer; | |
982 int io_buffer_size = 0; | |
983 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
984 ASSERT_TRUE(handler_->OnReadCompleted(io_buffer_size, &defer)); | |
985 } | |
986 | |
987 url_loader_client_.RunUntilResponseBodyArrived(); | |
988 ASSERT_TRUE(url_loader_client_.response_body().is_valid()); | |
989 | |
990 defer = false; | |
991 net::URLRequestStatus status(net::URLRequestStatus::CANCELED, | |
992 net::ERR_ABORTED); | |
993 handler_->OnResponseCompleted(status, "security_info", &defer); | |
994 | |
995 ASSERT_FALSE(url_loader_client_.has_received_completion()); | |
996 url_loader_client_.RunUntilComplete(); | |
997 EXPECT_EQ(net::ERR_ABORTED, | |
998 url_loader_client_.completion_status().error_code); | |
999 | |
1000 while (true) { | |
1001 char buffer[16]; | |
1002 uint32_t read = sizeof(buffer); | |
1003 MojoResult result = | |
1004 mojo::ReadDataRaw(url_loader_client_.response_body(), buffer, &read, | |
1005 MOJO_READ_DATA_FLAG_NONE); | |
1006 if (result == MOJO_RESULT_FAILED_PRECONDITION) | |
1007 break; | |
1008 base::RunLoop().RunUntilIdle(); | |
1009 DCHECK(result == MOJO_RESULT_SHOULD_WAIT || result == MOJO_RESULT_OK); | |
1010 } | |
1011 | |
1012 base::RunLoop().RunUntilIdle(); | |
1013 EXPECT_EQ(0, resource_controller_.num_resume_calls()); | |
1014 } | |
1015 | |
1016 // Typically ResourceHandler methods are called in this order. | |
1017 TEST_P( | |
1018 MojoAsyncResourceHandlerWithAllocationSizeTest, | |
1019 OnWillStartThenOnResponseStartedThenOnWillReadThenOnReadCompletedThenOnRespo nseCompleted) { | |
kinuko
2016/08/04 16:07:02
o_O
| |
1020 rdh_delegate_.set_num_on_response_started_calls_expectation(1); | |
1021 bool defer = false; | |
1022 | |
1023 ASSERT_TRUE(handler_->OnWillStart(request_->url(), &defer)); | |
1024 ASSERT_FALSE(defer); | |
1025 scoped_refptr<ResourceResponse> response = new ResourceResponse(); | |
1026 ASSERT_TRUE(handler_->OnResponseStarted(response.get(), &defer)); | |
1027 ASSERT_FALSE(defer); | |
1028 | |
1029 ASSERT_FALSE(url_loader_client_.has_received_response()); | |
1030 url_loader_client_.RunUntilResponseReceived(); | |
1031 | |
1032 int io_buffer_size = 0; | |
1033 scoped_refptr<net::IOBuffer> io_buffer; | |
1034 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
1035 ASSERT_TRUE(io_buffer); | |
1036 ASSERT_GT(io_buffer_size, 0); | |
1037 io_buffer->data()[0] = 'A'; | |
1038 | |
1039 ASSERT_FALSE(url_loader_client_.response_body().is_valid()); | |
1040 url_loader_client_.RunUntilResponseBodyArrived(); | |
1041 ASSERT_TRUE(url_loader_client_.response_body().is_valid()); | |
1042 | |
1043 ASSERT_TRUE(handler_->OnReadCompleted(1, &defer)); | |
1044 ASSERT_FALSE(defer); | |
1045 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, net::OK); | |
1046 handler_->OnResponseCompleted(status, "security info", &defer); | |
1047 ASSERT_FALSE(defer); | |
1048 | |
1049 ASSERT_FALSE(url_loader_client_.has_received_completion()); | |
1050 url_loader_client_.RunUntilComplete(); | |
1051 EXPECT_EQ(net::OK, url_loader_client_.completion_status().error_code); | |
1052 | |
1053 // This is needed because |*io_buffer| may keep the data producer alive. | |
1054 io_buffer = nullptr; | |
1055 | |
1056 std::string body; | |
1057 while (true) { | |
1058 char buffer[16]; | |
1059 uint32_t read = sizeof(buffer); | |
1060 MojoResult result = | |
1061 mojo::ReadDataRaw(url_loader_client_.response_body(), buffer, &read, | |
1062 MOJO_READ_DATA_FLAG_NONE); | |
1063 if (result == MOJO_RESULT_FAILED_PRECONDITION) | |
1064 break; | |
1065 if (result == MOJO_RESULT_SHOULD_WAIT) { | |
1066 base::RunLoop().RunUntilIdle(); | |
1067 } else { | |
1068 ASSERT_EQ(result, MOJO_RESULT_OK); | |
1069 body.append(buffer, read); | |
1070 } | |
1071 } | |
1072 EXPECT_EQ("A", body); | |
1073 } | |
1074 | |
1075 // MimeResourceHandler calls delegated ResourceHandler's methods in this order. | |
1076 TEST_P( | |
1077 MojoAsyncResourceHandlerWithAllocationSizeTest, | |
1078 OnWillStartThenOnWillReadThenOnResponseStartedThenOnReadCompletedThenOnRespo nseCompleted) { | |
1079 rdh_delegate_.set_num_on_response_started_calls_expectation(1); | |
1080 bool defer = false; | |
1081 | |
1082 ASSERT_TRUE(handler_->OnWillStart(request_->url(), &defer)); | |
1083 ASSERT_FALSE(defer); | |
1084 | |
1085 int io_buffer_size = 0; | |
1086 scoped_refptr<net::IOBuffer> io_buffer; | |
1087 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); | |
1088 ASSERT_TRUE(io_buffer); | |
1089 ASSERT_GT(io_buffer_size, 0); | |
1090 io_buffer->data()[0] = 'B'; | |
1091 | |
1092 ASSERT_FALSE(url_loader_client_.response_body().is_valid()); | |
1093 url_loader_client_.RunUntilResponseBodyArrived(); | |
1094 ASSERT_TRUE(url_loader_client_.response_body().is_valid()); | |
1095 | |
1096 scoped_refptr<ResourceResponse> response = new ResourceResponse(); | |
1097 ASSERT_TRUE(handler_->OnResponseStarted(response.get(), &defer)); | |
1098 ASSERT_FALSE(defer); | |
1099 | |
1100 ASSERT_FALSE(url_loader_client_.has_received_response()); | |
1101 url_loader_client_.RunUntilResponseReceived(); | |
1102 | |
1103 ASSERT_TRUE(handler_->OnReadCompleted(1, &defer)); | |
1104 ASSERT_FALSE(defer); | |
1105 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, net::OK); | |
1106 handler_->OnResponseCompleted(status, "security info", &defer); | |
1107 ASSERT_FALSE(defer); | |
1108 | |
1109 ASSERT_FALSE(url_loader_client_.has_received_completion()); | |
1110 url_loader_client_.RunUntilComplete(); | |
1111 EXPECT_EQ(net::OK, url_loader_client_.completion_status().error_code); | |
1112 | |
1113 // This is needed because |*io_buffer| may keep the data producer alive. | |
1114 io_buffer = nullptr; | |
1115 | |
1116 std::string body; | |
1117 while (true) { | |
1118 char buffer[16]; | |
1119 uint32_t read = sizeof(buffer); | |
1120 MojoResult result = | |
1121 mojo::ReadDataRaw(url_loader_client_.response_body(), buffer, &read, | |
1122 MOJO_READ_DATA_FLAG_NONE); | |
1123 if (result == MOJO_RESULT_FAILED_PRECONDITION) | |
1124 break; | |
1125 if (result == MOJO_RESULT_SHOULD_WAIT) { | |
1126 base::RunLoop().RunUntilIdle(); | |
1127 } else { | |
1128 ASSERT_EQ(result, MOJO_RESULT_OK); | |
1129 body.append(buffer, read); | |
1130 } | |
1131 } | |
1132 EXPECT_EQ("B", body); | |
1133 } | |
1134 | |
1135 INSTANTIATE_TEST_CASE_P(MojoAsyncResourceHandlerWithAllocationSizeTest, | |
1136 MojoAsyncResourceHandlerWithAllocationSizeTest, | |
1137 ::testing::Values(8, 32 * 2014)); | |
1138 } // namespace | |
1139 } // namespace content | |
OLD | NEW |