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

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 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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698