Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(254)

Side by Side Diff: content/browser/loader/mojo_async_resource_handler_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698