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

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: fix Created 4 years, 5 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/mojo_async_resource_handler_test_util.h"
19 #include "content/browser/loader/resource_dispatcher_host_impl.h"
20 #include "content/browser/loader/resource_request_info_impl.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 FakeResourceDispatcherHostDelegate
57 : public ResourceDispatcherHostDelegate {
58 public:
59 FakeResourceDispatcherHostDelegate() {}
60 ~FakeResourceDispatcherHostDelegate() override {}
61
62 bool ShouldBeginRequest(const std::string& method,
63 const GURL& url,
64 ResourceType resource_type,
65 ResourceContext* resource_context) override {
66 ADD_FAILURE() << "ShouldBeginRequest should not be called.";
67 return false;
68 }
69
70 void RequestBeginning(net::URLRequest* request,
71 ResourceContext* resource_context,
72 AppCacheService* appcache_service,
73 ResourceType resource_type,
74 ScopedVector<ResourceThrottle>* throttles) override {
75 ADD_FAILURE() << "RequestBeginning should not be called.";
76 }
77
78 void DownloadStarting(net::URLRequest* request,
79 ResourceContext* resource_context,
80 int child_id,
81 int route_id,
82 bool is_content_initiated,
83 bool must_download,
84 ScopedVector<ResourceThrottle>* throttles) override {
85 ADD_FAILURE() << "DownloadStarting should not be called.";
86 }
87
88 ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(
89 net::AuthChallengeInfo* auth_info,
90 net::URLRequest* request) override {
91 ADD_FAILURE() << "CreateLoginDelegate should not be called.";
92 return nullptr;
93 }
94
95 bool HandleExternalProtocol(
96 const GURL& url,
97 int child_id,
98 const ResourceRequestInfo::WebContentsGetter& web_contents_getter,
99 bool is_main_frame,
100 ui::PageTransition page_transition,
101 bool has_user_gesture,
102 ResourceContext* resource_context) override {
103 ADD_FAILURE() << "HandleExternalProtocol should not be called.";
104 return false;
105 }
106
107 bool ShouldForceDownloadResource(const GURL& url,
108 const std::string& mime_type) override {
109 ADD_FAILURE() << "ShouldForceDownloadResource should not be called.";
110 return false;
111 }
112
113 bool ShouldInterceptResourceAsStream(net::URLRequest* request,
114 const base::FilePath& plugin_path,
115 const std::string& mime_type,
116 GURL* origin,
117 std::string* payload) override {
118 ADD_FAILURE() << "ShouldInterceptResourceAsStream should not be called.";
119 return false;
120 }
121
122 void OnStreamCreated(net::URLRequest* request,
123 std::unique_ptr<content::StreamInfo> stream) override {
124 ADD_FAILURE() << "OnStreamCreated should not be called.";
125 }
126
127 void OnResponseStarted(net::URLRequest* request,
128 ResourceContext* resource_context,
129 ResourceResponse* response) override {
130 is_on_response_started_called_ = true;
131 }
132
133 void OnRequestRedirected(const GURL& redirect_url,
134 net::URLRequest* request,
135 ResourceContext* resource_context,
136 ResourceResponse* response) override {
137 ADD_FAILURE() << "OnRequestRedirected should not be called.";
138 }
139
140 void RequestComplete(net::URLRequest* url_request) override {
141 ADD_FAILURE() << "RequestComplete should not be called.";
142 }
143
144 bool ShouldEnableLoFiMode(
145 const net::URLRequest& url_request,
146 content::ResourceContext* resource_context) override {
147 ADD_FAILURE() << "ShouldEnableLoFiMode should not be called.";
148 return false;
149 }
150
151 NavigationData* GetNavigationData(net::URLRequest* request) const override {
152 ADD_FAILURE() << "GetNavigationData should not be called.";
153 return nullptr;
154 }
155
156 std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
157 ResourceContext* resource_context) override {
158 ADD_FAILURE() << "CreateClientCertStore should not be called.";
159 return nullptr;
160 }
161
162 bool is_on_response_started_called() const {
163 return is_on_response_started_called_;
164 }
165
166 private:
167 bool is_on_response_started_called_ = false;
168
169 DISALLOW_COPY_AND_ASSIGN(FakeResourceDispatcherHostDelegate);
170 };
171
172 class FakeResourceController : public ResourceController {
173 public:
174 FakeResourceController() {}
175 ~FakeResourceController() override {}
176
177 void Cancel() override { ADD_FAILURE() << "Cancel should not be called."; }
178 void CancelAndIgnore() override {
179 ADD_FAILURE() << "CancelAndIgnore should not be called.";
180 }
181 void CancelWithError(int error_code) override {
182 is_cancel_with_error_called_ = true;
183 error_ = error_code;
184 if (quit_closure_)
185 quit_closure_.Run();
186 }
187 void Resume() override {
188 ++num_resume_calls_;
189 if (quit_closure_)
190 quit_closure_.Run();
191 }
192 void set_quit_closure(const base::Closure& quit_closure) {
193 quit_closure_ = quit_closure;
194 }
195
196 bool is_cancel_with_error_called() const {
197 return is_cancel_with_error_called_;
198 }
199 int error() const { return error_; }
200 unsigned num_resume_calls() const { return num_resume_calls_; }
201
202 private:
203 bool is_cancel_with_error_called_ = false;
204 int error_ = net::OK;
205 int num_resume_calls_ = 0;
206 base::Closure quit_closure_;
207
208 DISALLOW_COPY_AND_ASSIGN(FakeResourceController);
209 };
210
211 class MojoAsyncResourceHandlerWithCustomDataPipeOperations
212 : public MojoAsyncResourceHandler {
213 public:
214 MojoAsyncResourceHandlerWithCustomDataPipeOperations(
215 net::URLRequest* request,
216 ResourceDispatcherHostImpl* rdh,
217 mojo::InterfaceRequest<mojom::URLLoader> mojo_request,
218 mojom::URLLoaderClientPtr url_loader_client)
219 : MojoAsyncResourceHandler(request,
220 rdh,
221 std::move(mojo_request),
222 std::move(url_loader_client)) {}
223 ~MojoAsyncResourceHandlerWithCustomDataPipeOperations() override {}
224
225 void set_begin_write_expectation(MojoResult begin_write_expectation) {
226 is_begin_write_expectation_set_ = true;
227 begin_write_expectation_ = begin_write_expectation;
228 }
229 void set_end_write_expectation(MojoResult end_write_expectation) {
230 is_end_write_expectation_set_ = true;
231 end_write_expectation_ = end_write_expectation;
232 }
233
234 private:
235 MojoResult BeginWrite(void** data, uint32_t* available) override {
236 if (is_begin_write_expectation_set_)
237 return begin_write_expectation_;
238 return MojoAsyncResourceHandler::BeginWrite(data, available);
239 }
240 MojoResult EndWrite(uint32_t written) override {
241 if (is_end_write_expectation_set_)
242 return end_write_expectation_;
243 return MojoAsyncResourceHandler::EndWrite(written);
244 }
245
246 bool is_begin_write_expectation_set_ = false;
247 bool is_end_write_expectation_set_ = false;
248 MojoResult begin_write_expectation_ = MOJO_RESULT_UNKNOWN;
249 MojoResult end_write_expectation_ = MOJO_RESULT_UNKNOWN;
250
251 DISALLOW_COPY_AND_ASSIGN(
252 MojoAsyncResourceHandlerWithCustomDataPipeOperations);
253 };
254
255 class MojoAsyncResourceHandlerTestBase {
256 public:
257 MojoAsyncResourceHandlerTestBase()
258 : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
259 browser_context_(new TestBrowserContext()) {
260 MojoAsyncResourceHandler::SetAllocationSizeForTesting(32 * 1024);
261
262 // Calling this function creates a request context.
263 browser_context_->GetResourceContext()->GetRequestContext();
264 base::RunLoop().RunUntilIdle();
265
266 url_request_delegate_.reset(new net::TestDelegate());
267 net::URLRequestContext* request_context =
268 browser_context_->GetResourceContext()->GetRequestContext();
269 request_ = request_context->CreateRequest(
270 net::URLRequestFailedJob::GetMockHttpUrl(net::ERR_TIMED_OUT),
271 net::DEFAULT_PRIORITY, url_request_delegate_.get());
272 ResourceRequestInfo::AllocateForTesting(
273 request_.get(), RESOURCE_TYPE_XHR,
274 browser_context_->GetResourceContext(), 2, 0, 0, true, false, false,
275 true, false);
276 handler_.reset(new MojoAsyncResourceHandlerWithCustomDataPipeOperations(
277 request_.get(), &rdh_, nullptr,
278 url_loader_client_.CreateInterfacePtrAndBind()));
279 handler_->SetController(&resource_controller_);
280 }
281
282 virtual ~MojoAsyncResourceHandlerTestBase() {
283 rdh_.SetDelegate(nullptr);
284 net::URLRequestFilter::GetInstance()->ClearHandlers();
285 }
286
287 void GetContexts(ResourceType resource_type,
288 int origin_pid,
289 ResourceContext** resource_context,
290 net::URLRequestContext** request_context) {
291 *resource_context = browser_context_->GetResourceContext();
292 *request_context =
293 browser_context_->GetResourceContext()->GetRequestContext();
294 }
295
296 void RunUntilNextNotification() {
297 base::RunLoop run_loop;
298 url_loader_client_.set_quit_closure(run_loop.QuitClosure());
299 resource_controller_.set_quit_closure(run_loop.QuitClosure());
300 run_loop.Run();
301 }
302
303 TestBrowserThreadBundle thread_bundle_;
304 ResourceDispatcherHostImpl rdh_;
305 FakeURLLoaderClient url_loader_client_;
306 FakeResourceController resource_controller_;
307 std::unique_ptr<TestBrowserContext> browser_context_;
308 std::unique_ptr<net::TestDelegate> url_request_delegate_;
309 std::unique_ptr<net::URLRequest> request_;
310 std::unique_ptr<MojoAsyncResourceHandlerWithCustomDataPipeOperations>
311 handler_;
312
313 DISALLOW_COPY_AND_ASSIGN(MojoAsyncResourceHandlerTestBase);
314 };
315
316 class MojoAsyncResourceHandlerTest : public MojoAsyncResourceHandlerTestBase,
317 public ::testing::Test {};
318
319 // This test class is parametrized with MojoAsyncResourceHandler's allocation
320 // size.
321 class MojoAsyncResourceHandlerWithAllocationSizeTest
322 : public MojoAsyncResourceHandlerTestBase,
323 public ::testing::TestWithParam<size_t> {
324 protected:
325 MojoAsyncResourceHandlerWithAllocationSizeTest() {
326 MojoAsyncResourceHandler::SetAllocationSizeForTesting(GetParam());
327 }
328 };
329
330 TEST_F(MojoAsyncResourceHandlerTest, InFlightRequests) {
331 EXPECT_EQ(0, rdh_.num_in_flight_requests_for_testing());
332 handler_ = nullptr;
333 EXPECT_EQ(0, rdh_.num_in_flight_requests_for_testing());
334 }
335
336 TEST_F(MojoAsyncResourceHandlerTest, OnResponseStarted) {
337 scoped_refptr<ResourceResponse> response = new ResourceResponse();
338 FakeResourceDispatcherHostDelegate rdh_delegate;
339 response->head.content_length = 99;
340 response->head.request_start =
341 base::TimeTicks::UnixEpoch() + base::TimeDelta::FromDays(14);
342 response->head.response_start =
343 base::TimeTicks::UnixEpoch() + base::TimeDelta::FromDays(28);
344
345 bool defer = false;
346
347 base::TimeTicks now1 = base::TimeTicks::Now();
348 rdh_.SetDelegate(&rdh_delegate);
349 ASSERT_TRUE(handler_->OnResponseStarted(response.get(), &defer));
350 rdh_.SetDelegate(nullptr);
351 base::TimeTicks now2 = base::TimeTicks::Now();
352
353 EXPECT_FALSE(defer);
354 EXPECT_EQ(request_->creation_time(), response->head.request_start);
355 EXPECT_LE(now1, response->head.response_start);
356 EXPECT_LE(response->head.response_start, now2);
357 EXPECT_TRUE(rdh_delegate.is_on_response_started_called());
358
359 RunUntilNextNotification();
360 EXPECT_TRUE(url_loader_client_.has_received_response());
361 EXPECT_EQ(response->head.request_start,
362 url_loader_client_.response_head().request_start);
363 EXPECT_EQ(response->head.response_start,
364 url_loader_client_.response_head().response_start);
365 EXPECT_EQ(99, url_loader_client_.response_head().content_length);
366 }
367
368 TEST_F(MojoAsyncResourceHandlerTest, OnWillStart) {
369 bool defer = false;
370 EXPECT_TRUE(handler_->OnWillStart(request_->url(), &defer));
371 EXPECT_FALSE(defer);
372 }
373
374 TEST_F(MojoAsyncResourceHandlerTest, OnBeforeNetworkStart) {
375 bool defer = false;
376 EXPECT_TRUE(handler_->OnBeforeNetworkStart(request_->url(), &defer));
377 EXPECT_FALSE(defer);
378 }
379
380 TEST_F(MojoAsyncResourceHandlerTest, OnWillReadAndInFlightRequests) {
381 EXPECT_EQ(0, rdh_.num_in_flight_requests_for_testing());
382 scoped_refptr<net::IOBuffer> buffer;
383 int buf_size;
384 EXPECT_TRUE(handler_->OnWillRead(&buffer, &buf_size, -1));
385 EXPECT_EQ(1, rdh_.num_in_flight_requests_for_testing());
386 handler_ = nullptr;
387 EXPECT_EQ(0, rdh_.num_in_flight_requests_for_testing());
388 }
389
390 TEST_F(MojoAsyncResourceHandlerTest, OnWillReadWithInsufficientResource) {
391 rdh_.set_max_num_in_flight_requests_per_process(0);
392
393 scoped_refptr<net::IOBuffer> buffer;
394 int buf_size = 0;
395 EXPECT_FALSE(handler_->OnWillRead(&buffer, &buf_size, -1));
396 EXPECT_FALSE(buffer);
397 EXPECT_EQ(0, buf_size);
398 EXPECT_EQ(1, rdh_.num_in_flight_requests_for_testing());
399 EXPECT_TRUE(resource_controller_.is_cancel_with_error_called());
400 EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES, resource_controller_.error());
401 handler_ = nullptr;
402 EXPECT_EQ(0, rdh_.num_in_flight_requests_for_testing());
403 }
404
405 TEST_F(MojoAsyncResourceHandlerTest, OnWillReadAndOnReadCompleted) {
406 bool defer = false;
407 scoped_refptr<net::IOBuffer> buffer;
408 int buf_size;
409
410 ASSERT_TRUE(handler_->OnWillRead(&buffer, &buf_size, -1));
411 ASSERT_TRUE(buffer);
412 // The buffer size that the mime sniffer requires implicitly.
413 ASSERT_GE(buf_size, 2 * 1024);
414
415 RunUntilNextNotification();
416 ASSERT_TRUE(url_loader_client_.response_body().is_valid());
417
418 buffer->data()[0] = 'A';
419 buffer->data()[1] = 'B';
420 ASSERT_TRUE(handler_->OnReadCompleted(2, &defer));
421 EXPECT_FALSE(defer);
422
423 std::string contents;
424 do {
425 char buffer[16];
426 uint32_t read = sizeof(buffer);
427 MojoResult r = mojo::ReadDataRaw(url_loader_client_.response_body(), buffer,
428 &read, MOJO_READ_DATA_FLAG_NONE);
429 if (r == MOJO_RESULT_SHOULD_WAIT)
430 continue;
431 contents += std::string(buffer, read);
432 } while (contents.size() < 2);
433 EXPECT_EQ("AB", contents);
434 }
435
436 TEST_F(MojoAsyncResourceHandlerTest,
437 OnWillReadAndOnReadCompletedWithInsufficientInitialCapacity) {
438 MojoAsyncResourceHandler::SetAllocationSizeForTesting(2);
439
440 bool defer = false;
441 scoped_refptr<net::IOBuffer> buffer;
442 int buf_size;
443
444 ASSERT_TRUE(handler_->OnWillRead(&buffer, &buf_size, -1));
445 ASSERT_TRUE(buffer);
446 // The buffer size that the mime sniffer requires implicitly.
447 ASSERT_GE(buf_size, 2 * 1024);
448
449 RunUntilNextNotification();
450 ASSERT_TRUE(url_loader_client_.response_body().is_valid());
451
452 const std::string data("abcdefgh");
453 strcpy(buffer->data(), data.c_str());
454 ASSERT_TRUE(handler_->OnReadCompleted(data.size(), &defer));
455 EXPECT_TRUE(defer);
456
457 std::string contents;
458 do {
459 // This is needed for ResumeIfDeferred to be called.
460 base::RunLoop().RunUntilIdle();
461 char buffer[16];
462 uint32_t read = sizeof(buffer);
463 MojoResult r = mojo::ReadDataRaw(url_loader_client_.response_body(), buffer,
464 &read, MOJO_READ_DATA_FLAG_NONE);
465 if (r == MOJO_RESULT_SHOULD_WAIT)
466 continue;
467 ASSERT_EQ(MOJO_RESULT_OK, r);
468 contents += std::string(buffer, read);
469 } while (contents.size() < data.size());
470 EXPECT_EQ(data, contents);
471 EXPECT_EQ(0u, resource_controller_.num_resume_calls());
472 }
473
474 TEST_F(MojoAsyncResourceHandlerTest,
475 IOBufferFromOnWillReadShouldRemainValidEvenIfHandlerIsGone) {
476 scoped_refptr<net::IOBuffer> io_buffer;
477 int buf_size;
478
479 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
480 ASSERT_TRUE(io_buffer);
481 // The io_buffer size that the mime sniffer requires implicitly.
482 ASSERT_GE(buf_size, 2 * 1024);
483 handler_ = nullptr;
484
mmenke 2016/07/14 21:23:05 Any reason to delete url_loader_client_, too? Gue
485 // Hopefully ASAN checks this operation's validity.
486 io_buffer->data()[0] = 'A';
487 }
488
489 TEST_F(MojoAsyncResourceHandlerTest, OnResponseCompleted) {
490 scoped_refptr<ResourceResponse> response = new ResourceResponse();
491 bool defer = false;
492 ASSERT_TRUE(handler_->OnResponseStarted(response.get(), &defer));
493 EXPECT_FALSE(defer);
494 RunUntilNextNotification();
495 EXPECT_TRUE(url_loader_client_.has_received_response());
496
497 handler_->GetRequestInfoForTesting()->set_was_ignored_by_handler(false);
498 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, net::OK);
499 std::string security_info = "info0";
500
501 base::TimeTicks now1 = base::TimeTicks::Now();
502 handler_->OnResponseCompleted(status, security_info, &defer);
503 base::TimeTicks now2 = base::TimeTicks::Now();
504 EXPECT_FALSE(defer);
505
506 RunUntilNextNotification();
507 EXPECT_TRUE(url_loader_client_.has_received_completion());
508 EXPECT_EQ(net::OK, url_loader_client_.completion_status().error_code);
509 EXPECT_FALSE(url_loader_client_.completion_status().was_ignored_by_handler);
510 EXPECT_EQ("info0", url_loader_client_.completion_status().security_info);
511 EXPECT_LE(now1, url_loader_client_.completion_status().completion_time);
512 EXPECT_LE(url_loader_client_.completion_status().completion_time, now2);
513 EXPECT_EQ(request_->GetTotalReceivedBytes(),
514 url_loader_client_.completion_status().encoded_data_length);
515 }
516
517 // This test case sets different status values from OnResponseCompleted.
518 TEST_F(MojoAsyncResourceHandlerTest, OnResponseCompleted2) {
519 scoped_refptr<ResourceResponse> response = new ResourceResponse();
520 bool defer = false;
521 ASSERT_TRUE(handler_->OnResponseStarted(response.get(), &defer));
522 EXPECT_FALSE(defer);
523
524 handler_->GetRequestInfoForTesting()->set_was_ignored_by_handler(true);
525 net::URLRequestStatus status(net::URLRequestStatus::CANCELED,
526 net::ERR_ABORTED);
527 std::string security_info = "info1";
528
529 base::TimeTicks now1 = base::TimeTicks::Now();
530 handler_->OnResponseCompleted(status, security_info, &defer);
531 base::TimeTicks now2 = base::TimeTicks::Now();
532 EXPECT_FALSE(defer);
533
534 RunUntilNextNotification();
535 EXPECT_TRUE(url_loader_client_.has_received_completion());
536 EXPECT_EQ(net::ERR_ABORTED,
537 url_loader_client_.completion_status().error_code);
538 EXPECT_TRUE(url_loader_client_.completion_status().was_ignored_by_handler);
539 EXPECT_EQ("info1", url_loader_client_.completion_status().security_info);
540 EXPECT_LE(now1, url_loader_client_.completion_status().completion_time);
541 EXPECT_LE(url_loader_client_.completion_status().completion_time, now2);
542 EXPECT_EQ(request_->GetTotalReceivedBytes(),
543 url_loader_client_.completion_status().encoded_data_length);
544 }
545
546 TEST_F(MojoAsyncResourceHandlerTest, OnResponseCompletedWithCanceledTimedOut) {
547 net::URLRequestStatus status(net::URLRequestStatus::CANCELED,
548 net::ERR_TIMED_OUT);
549 bool defer = false;
550
551 handler_->OnResponseCompleted(status, "security_info", &defer);
552 EXPECT_FALSE(defer);
553
554 RunUntilNextNotification();
555 EXPECT_TRUE(url_loader_client_.has_received_completion());
556 EXPECT_EQ(net::ERR_TIMED_OUT,
557 url_loader_client_.completion_status().error_code);
558 }
559
560 TEST_F(MojoAsyncResourceHandlerTest, OnResponseCompletedWithFailedTimedOut) {
561 net::URLRequestStatus status(net::URLRequestStatus::FAILED,
562 net::ERR_TIMED_OUT);
563 bool defer = false;
564
565 handler_->OnResponseCompleted(status, "security_info", &defer);
566 EXPECT_FALSE(defer);
567
568 RunUntilNextNotification();
569 EXPECT_TRUE(url_loader_client_.has_received_completion());
570 EXPECT_EQ(net::ERR_TIMED_OUT,
571 url_loader_client_.completion_status().error_code);
572 }
573
574 TEST_F(MojoAsyncResourceHandlerTest, ResponseCompletionShouldCloseDataPipe) {
575 scoped_refptr<ResourceResponse> response = new ResourceResponse();
576 bool defer = false;
577 ASSERT_TRUE(handler_->OnResponseStarted(response.get(), &defer));
578 EXPECT_FALSE(defer);
579 RunUntilNextNotification();
580 EXPECT_TRUE(url_loader_client_.has_received_response());
581
582 scoped_refptr<net::IOBuffer> io_buffer;
583 int buf_size;
584 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
585 RunUntilNextNotification();
586 ASSERT_TRUE(url_loader_client_.response_body().is_valid());
587 ASSERT_TRUE(handler_->OnReadCompleted(0, &defer));
588 EXPECT_FALSE(defer);
589
590 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, net::OK);
591 handler_->OnResponseCompleted(status, "security_info", &defer);
592 EXPECT_FALSE(defer);
593
594 RunUntilNextNotification();
595 EXPECT_TRUE(url_loader_client_.has_received_completion());
596 EXPECT_EQ(net::OK, url_loader_client_.completion_status().error_code);
597
598 // This is needed because |*io_buffer| may keep the data producer alive.
599 io_buffer = nullptr;
600
601 char buffer[16];
602 uint32_t read = sizeof(buffer);
603 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
604 mojo::ReadDataRaw(url_loader_client_.response_body(), buffer, &read,
605 MOJO_READ_DATA_FLAG_NONE));
606 }
607
608 TEST_F(MojoAsyncResourceHandlerTest, ResponseErrorDuringBodyTransmission) {
609 scoped_refptr<ResourceResponse> response = new ResourceResponse();
610 bool defer = false;
611 ASSERT_TRUE(handler_->OnResponseStarted(response.get(), &defer));
612 EXPECT_FALSE(defer);
613 RunUntilNextNotification();
614 EXPECT_TRUE(url_loader_client_.has_received_response());
615
616 scoped_refptr<net::IOBuffer> io_buffer;
617 int buf_size;
618 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
619 RunUntilNextNotification();
620 ASSERT_TRUE(url_loader_client_.response_body().is_valid());
621 ASSERT_GT(buf_size, 0);
622 memset(io_buffer->data(), 'a', buf_size);
623 ASSERT_TRUE(handler_->OnReadCompleted(buf_size, &defer));
624
625 defer = false;
626 net::URLRequestStatus status(net::URLRequestStatus::FAILED, net::ERR_FAILED);
627 handler_->OnResponseCompleted(status, "security_info", &defer);
628 EXPECT_FALSE(defer);
629
630 RunUntilNextNotification();
631 EXPECT_TRUE(url_loader_client_.has_received_completion());
632 EXPECT_EQ(net::ERR_FAILED, url_loader_client_.completion_status().error_code);
633
634 // This is needed because |*io_buffer| may keep the data producer alive.
635 io_buffer = nullptr;
636
637 std::string actual;
638 while (true) {
639 char buf[16];
640 uint32_t read = sizeof(buf);
641 MojoResult r = mojo::ReadDataRaw(url_loader_client_.response_body(), buf,
642 &read, MOJO_READ_DATA_FLAG_NONE);
643 if (r == MOJO_RESULT_FAILED_PRECONDITION)
644 break;
645 if (r == MOJO_RESULT_SHOULD_WAIT)
646 continue;
647 EXPECT_EQ(MOJO_RESULT_OK, r);
648 actual += std::string(buf, read);
649 }
650 EXPECT_EQ(std::string(buf_size, 'a'), actual);
651 }
652
653 TEST_F(MojoAsyncResourceHandlerTest, BeginWriteFailsOnWillRead) {
654 handler_->set_begin_write_expectation(MOJO_RESULT_UNKNOWN);
655 scoped_refptr<net::IOBuffer> io_buffer;
656 int buf_size = 0;
657 ASSERT_FALSE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
658 EXPECT_FALSE(resource_controller_.is_cancel_with_error_called());
659 }
660
661 TEST_F(MojoAsyncResourceHandlerTest, BeginWriteReturnsShouldWaitOnWillRead) {
662 handler_->set_begin_write_expectation(MOJO_RESULT_SHOULD_WAIT);
663 scoped_refptr<net::IOBuffer> io_buffer;
664 int buf_size = 0;
665 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
666 EXPECT_TRUE(io_buffer);
667 EXPECT_GT(buf_size, 0);
668 }
669
670 TEST_F(MojoAsyncResourceHandlerTest,
671 EndWriteFailsOnWillReadWithInsufficientInitialCapacity) {
672 MojoAsyncResourceHandler::SetAllocationSizeForTesting(2);
673 handler_->set_end_write_expectation(MOJO_RESULT_UNKNOWN);
674 scoped_refptr<net::IOBuffer> io_buffer;
675 int buf_size = 0;
676 ASSERT_FALSE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
677 }
678
679 TEST_F(MojoAsyncResourceHandlerTest, EndWriteFailsOnReadCompleted) {
680 scoped_refptr<net::IOBuffer> io_buffer;
681 int buf_size = 0;
682 bool defer = false;
683 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
684
685 handler_->set_end_write_expectation(MOJO_RESULT_SHOULD_WAIT);
686 ASSERT_FALSE(handler_->OnReadCompleted(buf_size, &defer));
687 }
688
689 TEST_F(MojoAsyncResourceHandlerTest,
690 EndWriteFailsOnReadCompletedWithInsufficientInitialCapacity) {
691 MojoAsyncResourceHandler::SetAllocationSizeForTesting(2);
692 scoped_refptr<net::IOBuffer> io_buffer;
693 int buf_size = 0;
694 bool defer = false;
695 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
696
697 handler_->set_end_write_expectation(MOJO_RESULT_SHOULD_WAIT);
698 ASSERT_FALSE(handler_->OnReadCompleted(buf_size, &defer));
699 }
700
701 TEST_F(MojoAsyncResourceHandlerTest,
702 EndWriteFailsOnResumeIfDeferredWithInsufficientInitialCapacity) {
703 MojoAsyncResourceHandler::SetAllocationSizeForTesting(8);
704 scoped_refptr<net::IOBuffer> io_buffer;
705 int buf_size = 0;
706 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
707 RunUntilNextNotification();
708 ASSERT_TRUE(url_loader_client_.response_body().is_valid());
709
710 while (true) {
711 bool defer = false;
712 ASSERT_TRUE(handler_->OnReadCompleted(buf_size, &defer));
713 ASSERT_GE(buf_size, 0);
714 if (defer)
715 break;
716 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
717 }
718
719 while (true) {
720 char buf[16];
721 uint32_t read = sizeof(buf);
722 MojoResult r = mojo::ReadDataRaw(url_loader_client_.response_body(), buf,
723 &read, MOJO_READ_DATA_FLAG_NONE);
724 if (r == MOJO_RESULT_SHOULD_WAIT)
725 break;
726 ASSERT_EQ(MOJO_RESULT_OK, r);
727 }
728
729 handler_->set_end_write_expectation(MOJO_RESULT_SHOULD_WAIT);
730 RunUntilNextNotification();
731 EXPECT_FALSE(url_loader_client_.has_received_completion());
732 EXPECT_TRUE(resource_controller_.is_cancel_with_error_called());
733 EXPECT_EQ(net::ERR_FAILED, resource_controller_.error());
734 }
735
736 TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest,
737 OnWillReadWithLongContents) {
738 bool defer = false;
739 scoped_refptr<net::IOBuffer> io_buffer;
740 int buf_size = 0;
741
742 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
743 ASSERT_TRUE(io_buffer);
744 // The io_buffer size that the mime sniffer requires implicitly.
745 ASSERT_GE(buf_size, 2 * 1024);
746 const size_t contents_size = 3 * buf_size + 2;
747 ASSERT_TRUE(handler_->OnReadCompleted(0, &defer));
748 ASSERT_FALSE(defer);
749
750 RunUntilNextNotification();
751 ASSERT_TRUE(url_loader_client_.response_body().is_valid());
752
753 size_t written = 0;
754 std::string actual;
755 while (actual.size() < contents_size) {
756 while (written < contents_size && !defer) {
757 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
758 const size_t to_be_written =
759 std::min(static_cast<size_t>(buf_size), contents_size - written);
760 memset(io_buffer->data(), 'a', to_be_written);
761 ASSERT_TRUE(handler_->OnReadCompleted(to_be_written, &defer));
762 written += to_be_written;
763 }
764
765 char buf[16];
766 uint32_t read = sizeof(buf);
767 MojoResult r = mojo::ReadDataRaw(url_loader_client_.response_body(), buf,
768 &read, MOJO_READ_DATA_FLAG_NONE);
769 if (r != MOJO_RESULT_SHOULD_WAIT) {
770 ASSERT_EQ(MOJO_RESULT_OK, r);
771 actual += std::string(buf, read);
772 }
773 unsigned resume_count = resource_controller_.num_resume_calls();
774 base::RunLoop().RunUntilIdle();
775 defer = (resume_count == resource_controller_.num_resume_calls());
776 }
777 EXPECT_EQ(std::string(contents_size, 'a'), actual);
778 }
779
780 TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest,
781 BeginWriteFailsOnReadCompleted) {
782 scoped_refptr<net::IOBuffer> io_buffer;
783 int buf_size = 0;
784 bool defer = false;
785 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
786
787 handler_->set_begin_write_expectation(MOJO_RESULT_UNKNOWN);
788 ASSERT_FALSE(handler_->OnReadCompleted(buf_size, &defer));
789 }
790
791 TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest,
792 BeginWriteReturnsShouldWaitOnReadCompleted) {
793 scoped_refptr<net::IOBuffer> io_buffer;
794 int buf_size = 0;
795 bool defer = false;
796 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
797
798 handler_->set_begin_write_expectation(MOJO_RESULT_SHOULD_WAIT);
799 ASSERT_TRUE(handler_->OnReadCompleted(buf_size, &defer));
800 EXPECT_TRUE(defer);
801 }
802
803 TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest,
804 BeginWriteFailsOnResumeIfDeferred) {
805 bool defer = false;
806 int buf_size = 0;
807 scoped_refptr<net::IOBuffer> io_buffer;
808
809 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
810 ASSERT_TRUE(handler_->OnReadCompleted(0, &defer));
811 ASSERT_FALSE(defer);
812 RunUntilNextNotification();
813 ASSERT_TRUE(url_loader_client_.response_body().is_valid());
814
815 while (!defer) {
816 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
817 ASSERT_TRUE(handler_->OnReadCompleted(buf_size, &defer));
818 }
819 handler_->set_begin_write_expectation(MOJO_RESULT_UNKNOWN);
820
821 while (!resource_controller_.is_cancel_with_error_called()) {
822 char buf[256];
823 uint32_t read = sizeof(buf);
824 MojoResult r = mojo::ReadDataRaw(url_loader_client_.response_body(), buf,
825 &read, MOJO_READ_DATA_FLAG_NONE);
826 ASSERT_TRUE(r == MOJO_RESULT_OK || r == MOJO_RESULT_SHOULD_WAIT);
827 base::RunLoop().RunUntilIdle();
828 }
829
830 EXPECT_FALSE(url_loader_client_.has_received_completion());
831 EXPECT_EQ(net::ERR_FAILED, resource_controller_.error());
832 EXPECT_EQ(0u, resource_controller_.num_resume_calls());
833 }
834
835 INSTANTIATE_TEST_CASE_P(MojoAsyncResourceHandlerWithAllocationSizeTest,
836 MojoAsyncResourceHandlerWithAllocationSizeTest,
837 ::testing::Values(8, 32 * 2014));
838 } // namespace
839 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698