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

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>
mmenke 2016/07/19 20:50:27 <string> is preferred (And then remove the blank l
yhirano 2016/07/20 13:38:36 This is not for std::string but for memset (<strin
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 MojoAsyncResourceHandler::SetAllocationSizeForTesting(
286 MojoAsyncResourceHandler::kDefaultAllocationSize);
287 }
288
289 void GetContexts(ResourceType resource_type,
290 int origin_pid,
291 ResourceContext** resource_context,
292 net::URLRequestContext** request_context) {
293 *resource_context = browser_context_->GetResourceContext();
294 *request_context =
295 browser_context_->GetResourceContext()->GetRequestContext();
296 }
297
298 void RunUntilNextNotification() {
299 base::RunLoop run_loop;
300 url_loader_client_.set_quit_closure(run_loop.QuitClosure());
301 resource_controller_.set_quit_closure(run_loop.QuitClosure());
302 run_loop.Run();
303 }
304
305 void CheckOnWillReadWithLongContents() {
306 bool defer = false;
307 scoped_refptr<net::IOBuffer> io_buffer;
308 int buf_size = 0;
309
310 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
311 ASSERT_TRUE(io_buffer);
312 // The io_buffer size that the mime sniffer requires implicitly.
313 ASSERT_GE(buf_size, 2 * 1024);
314 const size_t contents_size = 3 * buf_size + 2;
315 ASSERT_TRUE(handler_->OnReadCompleted(0, &defer));
316 ASSERT_FALSE(defer);
317
318 RunUntilNextNotification();
319 ASSERT_TRUE(url_loader_client_.response_body().is_valid());
320
321 size_t written = 0;
322 std::string actual;
323 while (actual.size() < contents_size) {
324 while (written < contents_size && !defer) {
325 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
326 const size_t to_be_written =
327 std::min(static_cast<size_t>(buf_size), contents_size - written);
328 memset(io_buffer->data(), 'a', to_be_written);
329 ASSERT_TRUE(handler_->OnReadCompleted(to_be_written, &defer));
330 written += to_be_written;
331 }
332
333 char buf[16];
334 uint32_t read = sizeof(buf);
335 MojoResult r = mojo::ReadDataRaw(url_loader_client_.response_body(), buf,
336 &read, MOJO_READ_DATA_FLAG_NONE);
337 if (r != MOJO_RESULT_SHOULD_WAIT) {
338 ASSERT_EQ(MOJO_RESULT_OK, r);
339 actual += std::string(buf, read);
340 }
341 unsigned resume_count = resource_controller_.num_resume_calls();
342 base::RunLoop().RunUntilIdle();
343 defer = (resume_count == resource_controller_.num_resume_calls());
344 }
345 EXPECT_EQ(std::string(contents_size, 'a'), actual);
346 }
347
348 void CheckBeginWriteFailsOnReadCompleted() {
349 scoped_refptr<net::IOBuffer> io_buffer;
350 int buf_size = 0;
351 bool defer = false;
352 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
353
354 handler_->set_begin_write_expectation(MOJO_RESULT_UNKNOWN);
355 ASSERT_FALSE(handler_->OnReadCompleted(buf_size, &defer));
356 }
357
358 void CheckBeginWriteReturnsShouldWaitOnReadCompleted() {
359 scoped_refptr<net::IOBuffer> io_buffer;
360 int buf_size = 0;
361 bool defer = false;
362 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
363
364 handler_->set_begin_write_expectation(MOJO_RESULT_SHOULD_WAIT);
365 ASSERT_TRUE(handler_->OnReadCompleted(buf_size, &defer));
366 EXPECT_TRUE(defer);
367 }
368
369 void CheckBeginWriteFailsOnResumeIfDeferred() {
370 bool defer = false;
371 int buf_size = 0;
372 scoped_refptr<net::IOBuffer> io_buffer;
373
374 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
375 ASSERT_TRUE(handler_->OnReadCompleted(0, &defer));
376 ASSERT_FALSE(defer);
377 RunUntilNextNotification();
378 ASSERT_TRUE(url_loader_client_.response_body().is_valid());
379
380 while (!defer) {
381 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
382 ASSERT_TRUE(handler_->OnReadCompleted(buf_size, &defer));
383 }
384 handler_->set_begin_write_expectation(MOJO_RESULT_UNKNOWN);
385
386 while (!resource_controller_.is_cancel_with_error_called()) {
387 char buf[256];
388 uint32_t read = sizeof(buf);
389 MojoResult r = mojo::ReadDataRaw(url_loader_client_.response_body(), buf,
390 &read, MOJO_READ_DATA_FLAG_NONE);
391 ASSERT_TRUE(r == MOJO_RESULT_OK || r == MOJO_RESULT_SHOULD_WAIT);
392 base::RunLoop().RunUntilIdle();
393 }
394
395 EXPECT_FALSE(url_loader_client_.has_received_completion());
396 EXPECT_EQ(net::ERR_FAILED, resource_controller_.error());
397 EXPECT_EQ(0u, resource_controller_.num_resume_calls());
398 }
399
400 TestBrowserThreadBundle thread_bundle_;
401 ResourceDispatcherHostImpl rdh_;
402 FakeURLLoaderClient url_loader_client_;
403 FakeResourceController resource_controller_;
404 std::unique_ptr<TestBrowserContext> browser_context_;
405 std::unique_ptr<net::TestDelegate> url_request_delegate_;
406 std::unique_ptr<net::URLRequest> request_;
407 std::unique_ptr<MojoAsyncResourceHandlerWithCustomDataPipeOperations>
408 handler_;
409
410 DISALLOW_COPY_AND_ASSIGN(MojoAsyncResourceHandlerTestBase);
411 };
412
413 class MojoAsyncResourceHandlerTest : public MojoAsyncResourceHandlerTestBase,
414 public ::testing::Test {};
415
416 // This test class is parametrized with MojoAsyncResourceHandler's allocation
417 // size.
418 class MojoAsyncResourceHandlerWithAllocationSizeTest
419 : public MojoAsyncResourceHandlerTestBase,
420 public ::testing::TestWithParam<size_t> {
421 protected:
422 MojoAsyncResourceHandlerWithAllocationSizeTest() {
423 MojoAsyncResourceHandler::SetAllocationSizeForTesting(GetParam());
424 }
425 };
426
427 TEST_F(MojoAsyncResourceHandlerTest, InFlightRequests) {
428 EXPECT_EQ(0, 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, OnResponseStarted) {
434 scoped_refptr<ResourceResponse> response = new ResourceResponse();
435 FakeResourceDispatcherHostDelegate rdh_delegate;
436 response->head.content_length = 99;
437 response->head.request_start =
438 base::TimeTicks::UnixEpoch() + base::TimeDelta::FromDays(14);
439 response->head.response_start =
440 base::TimeTicks::UnixEpoch() + base::TimeDelta::FromDays(28);
441
442 bool defer = false;
443
444 base::TimeTicks now1 = base::TimeTicks::Now();
445 rdh_.SetDelegate(&rdh_delegate);
446 ASSERT_TRUE(handler_->OnResponseStarted(response.get(), &defer));
447 rdh_.SetDelegate(nullptr);
448 base::TimeTicks now2 = base::TimeTicks::Now();
449
450 EXPECT_FALSE(defer);
451 EXPECT_EQ(request_->creation_time(), response->head.request_start);
452 EXPECT_LE(now1, response->head.response_start);
453 EXPECT_LE(response->head.response_start, now2);
454 EXPECT_TRUE(rdh_delegate.is_on_response_started_called());
455
456 RunUntilNextNotification();
457 EXPECT_TRUE(url_loader_client_.has_received_response());
458 EXPECT_EQ(response->head.request_start,
459 url_loader_client_.response_head().request_start);
460 EXPECT_EQ(response->head.response_start,
461 url_loader_client_.response_head().response_start);
462 EXPECT_EQ(99, url_loader_client_.response_head().content_length);
463 }
464
465 TEST_F(MojoAsyncResourceHandlerTest, OnWillStart) {
466 bool defer = false;
467 EXPECT_TRUE(handler_->OnWillStart(request_->url(), &defer));
468 EXPECT_FALSE(defer);
469 }
470
471 TEST_F(MojoAsyncResourceHandlerTest, OnBeforeNetworkStart) {
472 bool defer = false;
473 EXPECT_TRUE(handler_->OnBeforeNetworkStart(request_->url(), &defer));
474 EXPECT_FALSE(defer);
475 }
476
477 TEST_F(MojoAsyncResourceHandlerTest, OnWillReadAndInFlightRequests) {
478 EXPECT_EQ(0, rdh_.num_in_flight_requests_for_testing());
479 scoped_refptr<net::IOBuffer> buffer;
480 int buf_size;
481 EXPECT_TRUE(handler_->OnWillRead(&buffer, &buf_size, -1));
482 EXPECT_EQ(1, rdh_.num_in_flight_requests_for_testing());
483 handler_ = nullptr;
484 EXPECT_EQ(0, rdh_.num_in_flight_requests_for_testing());
485 }
486
487 TEST_F(MojoAsyncResourceHandlerTest, OnWillReadWithInsufficientResource) {
488 rdh_.set_max_num_in_flight_requests_per_process(0);
489
490 scoped_refptr<net::IOBuffer> buffer;
491 int buf_size = 0;
492 EXPECT_FALSE(handler_->OnWillRead(&buffer, &buf_size, -1));
493 EXPECT_FALSE(buffer);
494 EXPECT_EQ(0, buf_size);
495 EXPECT_EQ(1, rdh_.num_in_flight_requests_for_testing());
496 EXPECT_TRUE(resource_controller_.is_cancel_with_error_called());
497 EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES, resource_controller_.error());
498 handler_ = nullptr;
499 EXPECT_EQ(0, rdh_.num_in_flight_requests_for_testing());
500 }
501
502 TEST_F(MojoAsyncResourceHandlerTest, OnWillReadAndOnReadCompleted) {
503 bool defer = false;
504 scoped_refptr<net::IOBuffer> buffer;
505 int buf_size;
506
507 ASSERT_TRUE(handler_->OnWillRead(&buffer, &buf_size, -1));
508 ASSERT_TRUE(buffer);
509 // The buffer size that the mime sniffer requires implicitly.
510 ASSERT_GE(buf_size, 2 * 1024);
511
512 RunUntilNextNotification();
513 ASSERT_TRUE(url_loader_client_.response_body().is_valid());
514
515 buffer->data()[0] = 'A';
516 buffer->data()[1] = 'B';
517 ASSERT_TRUE(handler_->OnReadCompleted(2, &defer));
518 EXPECT_FALSE(defer);
519
520 std::string contents;
521 do {
522 char buffer[16];
523 uint32_t read = sizeof(buffer);
524 MojoResult r = mojo::ReadDataRaw(url_loader_client_.response_body(), buffer,
525 &read, MOJO_READ_DATA_FLAG_NONE);
526 if (r == MOJO_RESULT_SHOULD_WAIT)
527 continue;
528 contents += std::string(buffer, read);
529 } while (contents.size() < 2);
530 EXPECT_EQ("AB", contents);
531 }
532
533 TEST_F(MojoAsyncResourceHandlerTest,
534 OnWillReadAndOnReadCompletedWithInsufficientInitialCapacity) {
535 MojoAsyncResourceHandler::SetAllocationSizeForTesting(2);
536
537 bool defer = false;
538 scoped_refptr<net::IOBuffer> buffer;
539 int buf_size;
540
541 ASSERT_TRUE(handler_->OnWillRead(&buffer, &buf_size, -1));
542 ASSERT_TRUE(buffer);
543 // The buffer size that the mime sniffer requires implicitly.
544 ASSERT_GE(buf_size, 2 * 1024);
545
546 RunUntilNextNotification();
547 ASSERT_TRUE(url_loader_client_.response_body().is_valid());
548
549 const std::string data("abcdefgh");
550 strcpy(buffer->data(), data.c_str());
551 ASSERT_TRUE(handler_->OnReadCompleted(data.size(), &defer));
552 EXPECT_TRUE(defer);
553
554 std::string contents;
555 do {
556 // This is needed for ResumeIfDeferred to be called.
557 base::RunLoop().RunUntilIdle();
558 char buffer[16];
559 uint32_t read = sizeof(buffer);
560 MojoResult r = mojo::ReadDataRaw(url_loader_client_.response_body(), buffer,
561 &read, MOJO_READ_DATA_FLAG_NONE);
562 if (r == MOJO_RESULT_SHOULD_WAIT)
563 continue;
564 ASSERT_EQ(MOJO_RESULT_OK, r);
565 contents += std::string(buffer, read);
566 } while (contents.size() < data.size());
567 EXPECT_EQ(data, contents);
568 EXPECT_EQ(0u, resource_controller_.num_resume_calls());
569 }
570
571 TEST_F(MojoAsyncResourceHandlerTest,
572 OnWillReadAndOnReadCompletedWithLongContents) {
573 CheckOnWillReadWithLongContents();
574 }
575
576 TEST_F(MojoAsyncResourceHandlerTest,
577 OnWillReadAndOnReadCompletedWithInSufficientBufferSizeWithLongContents) {
578 MojoAsyncResourceHandler::SetAllocationSizeForTesting(32);
579 CheckOnWillReadWithLongContents();
580 }
581
582 TEST_F(MojoAsyncResourceHandlerTest,
583 IOBufferFromOnWillReadShouldRemainValidEvenIfHandlerIsGone) {
584 scoped_refptr<net::IOBuffer> io_buffer;
585 int buf_size;
586
587 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
588 ASSERT_TRUE(io_buffer);
589 // The io_buffer size that the mime sniffer requires implicitly.
590 ASSERT_GE(buf_size, 2 * 1024);
591
592 handler_ = nullptr;
593 url_loader_client_.Unbind();
594 base::RunLoop().RunUntilIdle();
595
596 // Hopefully ASAN checks this operation's validity.
597 io_buffer->data()[0] = 'A';
598 }
599
600 TEST_F(MojoAsyncResourceHandlerTest, OnResponseCompleted) {
601 scoped_refptr<ResourceResponse> response = new ResourceResponse();
602 bool defer = false;
603 ASSERT_TRUE(handler_->OnResponseStarted(response.get(), &defer));
604 EXPECT_FALSE(defer);
605 RunUntilNextNotification();
606 EXPECT_TRUE(url_loader_client_.has_received_response());
607
608 handler_->GetRequestInfoForTesting()->set_was_ignored_by_handler(false);
609 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, net::OK);
610 std::string security_info = "info0";
611
612 base::TimeTicks now1 = base::TimeTicks::Now();
613 handler_->OnResponseCompleted(status, security_info, &defer);
614 base::TimeTicks now2 = base::TimeTicks::Now();
615 EXPECT_FALSE(defer);
616
617 RunUntilNextNotification();
618 EXPECT_TRUE(url_loader_client_.has_received_completion());
619 EXPECT_EQ(net::OK, url_loader_client_.completion_status().error_code);
620 EXPECT_FALSE(url_loader_client_.completion_status().was_ignored_by_handler);
621 EXPECT_EQ("info0", url_loader_client_.completion_status().security_info);
622 EXPECT_LE(now1, url_loader_client_.completion_status().completion_time);
623 EXPECT_LE(url_loader_client_.completion_status().completion_time, now2);
624 EXPECT_EQ(request_->GetTotalReceivedBytes(),
625 url_loader_client_.completion_status().encoded_data_length);
626 }
627
628 // This test case sets different status values from OnResponseCompleted.
629 TEST_F(MojoAsyncResourceHandlerTest, OnResponseCompleted2) {
630 scoped_refptr<ResourceResponse> response = new ResourceResponse();
631 bool defer = false;
632 ASSERT_TRUE(handler_->OnResponseStarted(response.get(), &defer));
633 EXPECT_FALSE(defer);
634
635 handler_->GetRequestInfoForTesting()->set_was_ignored_by_handler(true);
636 net::URLRequestStatus status(net::URLRequestStatus::CANCELED,
637 net::ERR_ABORTED);
638 std::string security_info = "info1";
639
640 base::TimeTicks now1 = base::TimeTicks::Now();
641 handler_->OnResponseCompleted(status, security_info, &defer);
642 base::TimeTicks now2 = base::TimeTicks::Now();
643 EXPECT_FALSE(defer);
644
645 RunUntilNextNotification();
646 EXPECT_TRUE(url_loader_client_.has_received_completion());
647 EXPECT_EQ(net::ERR_ABORTED,
648 url_loader_client_.completion_status().error_code);
649 EXPECT_TRUE(url_loader_client_.completion_status().was_ignored_by_handler);
650 EXPECT_EQ("info1", url_loader_client_.completion_status().security_info);
651 EXPECT_LE(now1, url_loader_client_.completion_status().completion_time);
652 EXPECT_LE(url_loader_client_.completion_status().completion_time, now2);
653 EXPECT_EQ(request_->GetTotalReceivedBytes(),
654 url_loader_client_.completion_status().encoded_data_length);
655 }
656
657 TEST_F(MojoAsyncResourceHandlerTest, OnResponseCompletedWithCanceledTimedOut) {
658 net::URLRequestStatus status(net::URLRequestStatus::CANCELED,
659 net::ERR_TIMED_OUT);
660 bool defer = false;
661
662 handler_->OnResponseCompleted(status, "security_info", &defer);
663 EXPECT_FALSE(defer);
664
665 RunUntilNextNotification();
666 EXPECT_TRUE(url_loader_client_.has_received_completion());
667 EXPECT_EQ(net::ERR_TIMED_OUT,
668 url_loader_client_.completion_status().error_code);
669 }
670
671 TEST_F(MojoAsyncResourceHandlerTest, OnResponseCompletedWithFailedTimedOut) {
672 net::URLRequestStatus status(net::URLRequestStatus::FAILED,
673 net::ERR_TIMED_OUT);
674 bool defer = false;
675
676 handler_->OnResponseCompleted(status, "security_info", &defer);
677 EXPECT_FALSE(defer);
678
679 RunUntilNextNotification();
680 EXPECT_TRUE(url_loader_client_.has_received_completion());
681 EXPECT_EQ(net::ERR_TIMED_OUT,
682 url_loader_client_.completion_status().error_code);
683 }
684
685 TEST_F(MojoAsyncResourceHandlerTest, ResponseCompletionShouldCloseDataPipe) {
686 scoped_refptr<ResourceResponse> response = new ResourceResponse();
687 bool defer = false;
688 ASSERT_TRUE(handler_->OnResponseStarted(response.get(), &defer));
689 EXPECT_FALSE(defer);
690 RunUntilNextNotification();
691 EXPECT_TRUE(url_loader_client_.has_received_response());
692
693 scoped_refptr<net::IOBuffer> io_buffer;
694 int buf_size;
695 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
696 RunUntilNextNotification();
697 ASSERT_TRUE(url_loader_client_.response_body().is_valid());
698 ASSERT_TRUE(handler_->OnReadCompleted(0, &defer));
699 EXPECT_FALSE(defer);
700
701 net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, net::OK);
702 handler_->OnResponseCompleted(status, "security_info", &defer);
703 EXPECT_FALSE(defer);
704
705 RunUntilNextNotification();
706 EXPECT_TRUE(url_loader_client_.has_received_completion());
707 EXPECT_EQ(net::OK, url_loader_client_.completion_status().error_code);
708
709 // This is needed because |*io_buffer| may keep the data producer alive.
710 io_buffer = nullptr;
711
712 char buffer[16];
713 uint32_t read = sizeof(buffer);
714 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
715 mojo::ReadDataRaw(url_loader_client_.response_body(), buffer, &read,
716 MOJO_READ_DATA_FLAG_NONE));
717 }
718
719 TEST_F(MojoAsyncResourceHandlerTest, ResponseErrorDuringBodyTransmission) {
720 scoped_refptr<ResourceResponse> response = new ResourceResponse();
721 bool defer = false;
722 ASSERT_TRUE(handler_->OnResponseStarted(response.get(), &defer));
723 EXPECT_FALSE(defer);
724 RunUntilNextNotification();
725 EXPECT_TRUE(url_loader_client_.has_received_response());
726
727 scoped_refptr<net::IOBuffer> io_buffer;
728 int buf_size;
729 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
730 RunUntilNextNotification();
731 ASSERT_TRUE(url_loader_client_.response_body().is_valid());
732 ASSERT_GT(buf_size, 0);
733 memset(io_buffer->data(), 'a', buf_size);
734 ASSERT_TRUE(handler_->OnReadCompleted(buf_size, &defer));
735
736 defer = false;
737 net::URLRequestStatus status(net::URLRequestStatus::FAILED, net::ERR_FAILED);
738 handler_->OnResponseCompleted(status, "security_info", &defer);
739 EXPECT_FALSE(defer);
740
741 RunUntilNextNotification();
742 EXPECT_TRUE(url_loader_client_.has_received_completion());
743 EXPECT_EQ(net::ERR_FAILED, url_loader_client_.completion_status().error_code);
744
745 // This is needed because |*io_buffer| may keep the data producer alive.
746 io_buffer = nullptr;
747
748 std::string actual;
749 while (true) {
750 char buf[16];
751 uint32_t read = sizeof(buf);
752 MojoResult r = mojo::ReadDataRaw(url_loader_client_.response_body(), buf,
753 &read, MOJO_READ_DATA_FLAG_NONE);
754 if (r == MOJO_RESULT_FAILED_PRECONDITION)
755 break;
756 if (r == MOJO_RESULT_SHOULD_WAIT)
757 continue;
758 EXPECT_EQ(MOJO_RESULT_OK, r);
759 actual += std::string(buf, read);
760 }
761 EXPECT_EQ(std::string(buf_size, 'a'), actual);
762 }
763
764 TEST_F(MojoAsyncResourceHandlerTest, BeginWriteFailsOnWillRead) {
765 handler_->set_begin_write_expectation(MOJO_RESULT_UNKNOWN);
766 scoped_refptr<net::IOBuffer> io_buffer;
767 int buf_size = 0;
768 ASSERT_FALSE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
769 EXPECT_FALSE(resource_controller_.is_cancel_with_error_called());
770 }
771
772 TEST_F(MojoAsyncResourceHandlerTest, BeginWriteReturnsShouldWaitOnWillRead) {
773 handler_->set_begin_write_expectation(MOJO_RESULT_SHOULD_WAIT);
774 scoped_refptr<net::IOBuffer> io_buffer;
775 int buf_size = 0;
776 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
777 EXPECT_TRUE(io_buffer);
778 EXPECT_GT(buf_size, 0);
779 }
780
781 TEST_F(MojoAsyncResourceHandlerTest, BeginWriteFailsOnReadCompleted) {
782 CheckBeginWriteFailsOnReadCompleted();
783 }
784
785 TEST_F(MojoAsyncResourceHandlerTest,
786 BeginWriteFailsOnReadCompletedWithInsufficientInitialCapacity) {
787 MojoAsyncResourceHandler::SetAllocationSizeForTesting(2);
788 CheckBeginWriteFailsOnReadCompleted();
789 }
790
791 TEST_F(MojoAsyncResourceHandlerTest,
792 BeginWriteReturnsShouldWaitOnReadCompleted) {
793 CheckBeginWriteReturnsShouldWaitOnReadCompleted();
794 }
795
796 TEST_F(
797 MojoAsyncResourceHandlerTest,
798 BeginWriteReturnsShouldWaitOnReadCompletedWithInsufficientInitialCapacity) {
799 MojoAsyncResourceHandler::SetAllocationSizeForTesting(2);
800 CheckBeginWriteReturnsShouldWaitOnReadCompleted();
801 }
802
803 TEST_F(MojoAsyncResourceHandlerTest, BeginWriteFailsOnResumeIfDeferred) {
804 CheckBeginWriteFailsOnResumeIfDeferred();
805 }
806
807 TEST_F(MojoAsyncResourceHandlerTest,
808 BeginWriteFailsOnResumeIfDeferredWithInsufficientInitialCapacity) {
809 MojoAsyncResourceHandler::SetAllocationSizeForTesting(2);
810 CheckBeginWriteFailsOnResumeIfDeferred();
811 }
812
813 TEST_F(MojoAsyncResourceHandlerTest,
814 EndWriteFailsOnWillReadWithInsufficientInitialCapacity) {
815 MojoAsyncResourceHandler::SetAllocationSizeForTesting(2);
816 handler_->set_end_write_expectation(MOJO_RESULT_UNKNOWN);
817 scoped_refptr<net::IOBuffer> io_buffer;
818 int buf_size = 0;
819 ASSERT_FALSE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
820 }
821
822 TEST_F(MojoAsyncResourceHandlerTest, EndWriteFailsOnReadCompleted) {
823 scoped_refptr<net::IOBuffer> io_buffer;
824 int buf_size = 0;
825 bool defer = false;
826 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
827
828 handler_->set_end_write_expectation(MOJO_RESULT_SHOULD_WAIT);
829 ASSERT_FALSE(handler_->OnReadCompleted(buf_size, &defer));
830 }
831
832 TEST_F(MojoAsyncResourceHandlerTest,
833 EndWriteFailsOnReadCompletedWithInsufficientInitialCapacity) {
834 MojoAsyncResourceHandler::SetAllocationSizeForTesting(2);
835 scoped_refptr<net::IOBuffer> io_buffer;
836 int buf_size = 0;
837 bool defer = false;
838 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
839
840 handler_->set_end_write_expectation(MOJO_RESULT_SHOULD_WAIT);
841 ASSERT_FALSE(handler_->OnReadCompleted(buf_size, &defer));
842 }
843
844 TEST_F(MojoAsyncResourceHandlerTest,
845 EndWriteFailsOnResumeIfDeferredWithInsufficientInitialCapacity) {
846 MojoAsyncResourceHandler::SetAllocationSizeForTesting(8);
847 scoped_refptr<net::IOBuffer> io_buffer;
848 int buf_size = 0;
849 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
850 RunUntilNextNotification();
851 ASSERT_TRUE(url_loader_client_.response_body().is_valid());
852
853 while (true) {
854 bool defer = false;
855 ASSERT_TRUE(handler_->OnReadCompleted(buf_size, &defer));
856 ASSERT_GE(buf_size, 0);
857 if (defer)
858 break;
859 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
860 }
861
862 while (true) {
863 char buf[16];
864 uint32_t read = sizeof(buf);
865 MojoResult r = mojo::ReadDataRaw(url_loader_client_.response_body(), buf,
866 &read, MOJO_READ_DATA_FLAG_NONE);
867 if (r == MOJO_RESULT_SHOULD_WAIT)
868 break;
869 ASSERT_EQ(MOJO_RESULT_OK, r);
870 }
871
872 handler_->set_end_write_expectation(MOJO_RESULT_SHOULD_WAIT);
873 RunUntilNextNotification();
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 buf_size = 0;
884
885 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
886 ASSERT_TRUE(io_buffer);
887 // The io_buffer size that the mime sniffer requires implicitly.
888 ASSERT_GE(buf_size, 2 * 1024);
889 const size_t contents_size = 3 * buf_size + 2;
890 ASSERT_TRUE(handler_->OnReadCompleted(0, &defer));
891 ASSERT_FALSE(defer);
892
893 RunUntilNextNotification();
894 ASSERT_TRUE(url_loader_client_.response_body().is_valid());
895
896 size_t written = 0;
897 std::string actual;
898 while (actual.size() < contents_size) {
899 while (written < contents_size && !defer) {
900 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
901 const size_t to_be_written =
902 std::min(static_cast<size_t>(buf_size), contents_size - written);
903 memset(io_buffer->data(), 'a', to_be_written);
904 ASSERT_TRUE(handler_->OnReadCompleted(to_be_written, &defer));
905 written += to_be_written;
906 }
907
908 char buf[16];
909 uint32_t read = sizeof(buf);
910 MojoResult r = mojo::ReadDataRaw(url_loader_client_.response_body(), buf,
911 &read, MOJO_READ_DATA_FLAG_NONE);
912 if (r != MOJO_RESULT_SHOULD_WAIT) {
913 ASSERT_EQ(MOJO_RESULT_OK, r);
914 actual += std::string(buf, read);
915 }
916 unsigned resume_count = resource_controller_.num_resume_calls();
917 base::RunLoop().RunUntilIdle();
918 defer = (resume_count == resource_controller_.num_resume_calls());
919 }
920 EXPECT_EQ(std::string(contents_size, 'a'), actual);
921 }
922
923 TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest,
924 BeginWriteFailsOnReadCompleted) {
925 scoped_refptr<net::IOBuffer> io_buffer;
926 int buf_size = 0;
927 bool defer = false;
928 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
929
930 handler_->set_begin_write_expectation(MOJO_RESULT_UNKNOWN);
931 ASSERT_FALSE(handler_->OnReadCompleted(buf_size, &defer));
932 }
933
934 TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest,
935 BeginWriteReturnsShouldWaitOnReadCompleted) {
936 scoped_refptr<net::IOBuffer> io_buffer;
937 int buf_size = 0;
938 bool defer = false;
939 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
940
941 handler_->set_begin_write_expectation(MOJO_RESULT_SHOULD_WAIT);
942 ASSERT_TRUE(handler_->OnReadCompleted(buf_size, &defer));
943 EXPECT_TRUE(defer);
944 }
945
946 TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest,
947 BeginWriteFailsOnResumeIfDeferred) {
948 bool defer = false;
949 int buf_size = 0;
950 scoped_refptr<net::IOBuffer> io_buffer;
951
952 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
953 ASSERT_TRUE(handler_->OnReadCompleted(0, &defer));
954 ASSERT_FALSE(defer);
955 RunUntilNextNotification();
956 ASSERT_TRUE(url_loader_client_.response_body().is_valid());
957
958 while (!defer) {
959 ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &buf_size, -1));
960 ASSERT_TRUE(handler_->OnReadCompleted(buf_size, &defer));
961 }
962 handler_->set_begin_write_expectation(MOJO_RESULT_UNKNOWN);
963
964 while (!resource_controller_.is_cancel_with_error_called()) {
965 char buf[256];
966 uint32_t read = sizeof(buf);
967 MojoResult r = mojo::ReadDataRaw(url_loader_client_.response_body(), buf,
968 &read, MOJO_READ_DATA_FLAG_NONE);
969 ASSERT_TRUE(r == MOJO_RESULT_OK || r == MOJO_RESULT_SHOULD_WAIT);
970 base::RunLoop().RunUntilIdle();
971 }
972
973 EXPECT_FALSE(url_loader_client_.has_received_completion());
974 EXPECT_EQ(net::ERR_FAILED, resource_controller_.error());
975 EXPECT_EQ(0u, resource_controller_.num_resume_calls());
976 }
977
978 INSTANTIATE_TEST_CASE_P(MojoAsyncResourceHandlerWithAllocationSizeTest,
979 MojoAsyncResourceHandlerWithAllocationSizeTest,
980 ::testing::Values(8, 32 * 2014));
981 } // namespace
982 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698