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

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

Issue 2668603003: Make ResourceHandler::OnWillRead able to complete asynchronously. (Closed)
Patch Set: Fix merge (x2) Created 3 years, 9 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/loader/intercepting_resource_handler.h" 5 #include "content/browser/loader/intercepting_resource_handler.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <memory> 9 #include <memory>
10 #include <string> 10 #include <string>
(...skipping 18 matching lines...) Expand all
29 #include "net/url_request/url_request_context.h" 29 #include "net/url_request/url_request_context.h"
30 #include "net/url_request/url_request_status.h" 30 #include "net/url_request/url_request_status.h"
31 #include "net/url_request/url_request_test_util.h" 31 #include "net/url_request/url_request_test_util.h"
32 #include "testing/gtest/include/gtest/gtest.h" 32 #include "testing/gtest/include/gtest/gtest.h"
33 #include "url/gurl.h" 33 #include "url/gurl.h"
34 34
35 namespace content { 35 namespace content {
36 36
37 namespace { 37 namespace {
38 38
39 class TestResourceController : public ResourceController {
40 public:
41 TestResourceController() = default;
42 void Cancel() override {}
43 void CancelAndIgnore() override {}
44 void CancelWithError(int error_code) override {}
45 void Resume() override { ++resume_calls_; }
46
47 int resume_calls() const { return resume_calls_; }
48
49 private:
50 int resume_calls_ = 0;
51
52 DISALLOW_COPY_AND_ASSIGN(TestResourceController);
53 };
54
55 class InterceptingResourceHandlerTest : public testing::Test { 39 class InterceptingResourceHandlerTest : public testing::Test {
56 public: 40 public:
57 InterceptingResourceHandlerTest() 41 InterceptingResourceHandlerTest()
58 : request_(context_.CreateRequest(GURL("http://www.google.com"), 42 : request_(context_.CreateRequest(GURL("http://www.google.com"),
59 net::DEFAULT_PRIORITY, 43 net::DEFAULT_PRIORITY,
60 nullptr)), 44 nullptr)),
61 old_handler_status_( 45 old_handler_status_(
62 net::URLRequestStatus::FromError(net::ERR_IO_PENDING)) { 46 net::URLRequestStatus::FromError(net::ERR_IO_PENDING)) {
63 ResourceRequestInfo::AllocateForTesting(request_.get(), 47 ResourceRequestInfo::AllocateForTesting(request_.get(),
64 RESOURCE_TYPE_MAIN_FRAME, 48 RESOURCE_TYPE_MAIN_FRAME,
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 ASSERT_EQ(MockResourceLoader::Status::CANCELED, 360 ASSERT_EQ(MockResourceLoader::Status::CANCELED,
377 mock_loader_->OnReadCompleted(kData)); 361 mock_loader_->OnReadCompleted(kData));
378 EXPECT_EQ(net::ERR_ABORTED, mock_loader_->error_code()); 362 EXPECT_EQ(net::ERR_ABORTED, mock_loader_->error_code());
379 } 363 }
380 364
381 // The old handler sets |defer| to true in OnReadCompleted and 365 // The old handler sets |defer| to true in OnReadCompleted and
382 // OnResponseCompleted. The new handler sets |defer| to true in 366 // OnResponseCompleted. The new handler sets |defer| to true in
383 // OnResponseStarted and OnReadCompleted. 367 // OnResponseStarted and OnReadCompleted.
384 TEST_F(InterceptingResourceHandlerTest, DeferredOperations) { 368 TEST_F(InterceptingResourceHandlerTest, DeferredOperations) {
385 const char kData[] = "The data"; 369 const char kData[] = "The data";
386 const std::string kPayload = "The long long long long long payload"; 370 const char kPayload[] = "The long long long long long payload";
387 const int kOldHandlerBufferSize = 10; 371 // This should be less than half the size of the payload, so it needs at least
372 // 3 reads to receive.
373 const int kOldHandlerBufferSize = arraysize(kPayload) / 3;
388 374
389 // When sending a payload to the old ResourceHandler, the 375 // When sending a payload to the old ResourceHandler, the
390 // InterceptingResourceHandler doesn't send a final EOF read. 376 // InterceptingResourceHandler doesn't send a final EOF read.
391 // TODO(mmenke): Should it? Or can we just get rid of that 0-byte read 377 // TODO(mmenke): Should it? Or can we just get rid of that 0-byte read
392 // entirely? 378 // entirely?
393 old_handler_->set_expect_eof_read(false); 379 old_handler_->set_expect_eof_read(false);
394 old_handler_->SetBufferSize(kOldHandlerBufferSize); 380 old_handler_->SetBufferSize(kOldHandlerBufferSize);
381 old_handler_->set_defer_on_will_read(true);
395 old_handler_->set_defer_on_read_completed(true); 382 old_handler_->set_defer_on_read_completed(true);
396 scoped_refptr<net::IOBuffer> old_buffer = old_handler_->buffer(); 383 scoped_refptr<net::IOBuffer> old_buffer = old_handler_->buffer();
397 384
398 // Simulate the MimeSniffingResourceHandler buffering the data. 385 // Simulate the MimeSniffingResourceHandler buffering the data.
386
399 ASSERT_EQ(MockResourceLoader::Status::IDLE, 387 ASSERT_EQ(MockResourceLoader::Status::IDLE,
400 mock_loader_->OnWillStart(request_->url())); 388 mock_loader_->OnWillStart(request_->url()));
401 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead()); 389 // The old handler defers the read.
390 ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
391 mock_loader_->OnWillRead());
392 old_handler_->WaitUntilDeferred();
393
394 EXPECT_EQ(net::URLRequestStatus::IO_PENDING, old_handler_status_.status());
395 EXPECT_EQ(1, old_handler_->on_will_read_called());
396 EXPECT_EQ(0, old_handler_->on_read_completed_called());
397 EXPECT_EQ(0, old_handler_->on_response_completed_called());
398
399 // Defer the next OnWillRead, too. This is needed to test the case where
400 // OnWillRead completes asynchronously when passing the payload to the old
401 // handler.
402 old_handler_->set_defer_on_will_read(true);
403
404 // The old handle resumes the request.
405 old_handler_->Resume();
406
407 // Resume() call may do work asynchronously. Wait until that's done.
408 mock_loader_->WaitUntilIdleOrCanceled();
409 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status());
402 410
403 ASSERT_NE(mock_loader_->io_buffer(), old_buffer.get()); 411 ASSERT_NE(mock_loader_->io_buffer(), old_buffer.get());
404 412
405 // Simulate the MimeSniffingResourceHandler asking the 413 // Simulate the MimeSniffingResourceHandler asking the
406 // InterceptingResourceHandler to switch to a new handler. 414 // InterceptingResourceHandler to switch to a new handler.
407 net::URLRequestStatus new_handler_status = {net::URLRequestStatus::IO_PENDING, 415 net::URLRequestStatus new_handler_status = {net::URLRequestStatus::IO_PENDING,
408 0}; 416 0};
409 417
410 std::string new_handler_body; 418 std::string new_handler_body;
411 std::unique_ptr<TestResourceHandler> scoped_new_handler( 419 std::unique_ptr<TestResourceHandler> scoped_new_handler(
412 new TestResourceHandler(&new_handler_status, &new_handler_body)); 420 new TestResourceHandler(&new_handler_status, &new_handler_body));
413 base::WeakPtr<TestResourceHandler> new_handler = 421 base::WeakPtr<TestResourceHandler> new_handler =
414 scoped_new_handler->GetWeakPtr(); 422 scoped_new_handler->GetWeakPtr();
415 scoped_new_handler->SetBufferSize(1); 423 scoped_new_handler->SetBufferSize(1);
416 scoped_new_handler->set_defer_on_will_start(true); 424 scoped_new_handler->set_defer_on_will_start(true);
417 scoped_new_handler->set_defer_on_response_started(true); 425 scoped_new_handler->set_defer_on_response_started(true);
426 scoped_new_handler->set_defer_on_will_read(true);
418 scoped_new_handler->set_defer_on_read_completed(true); 427 scoped_new_handler->set_defer_on_read_completed(true);
419 scoped_new_handler->set_defer_on_response_completed(true); 428 scoped_new_handler->set_defer_on_response_completed(true);
420 intercepting_handler_->UseNewHandler(std::move(scoped_new_handler), kPayload); 429 intercepting_handler_->UseNewHandler(std::move(scoped_new_handler), kPayload);
421 430
422 // The response is received, and then deferred by the old handler's 431 // The response is received, and then deferred by the old handler's
423 // OnReadCompleted method. 432 // OnReadCompleted method.
424 ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING, 433 ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
425 mock_loader_->OnResponseStarted( 434 mock_loader_->OnResponseStarted(
426 make_scoped_refptr(new ResourceResponse()))); 435 make_scoped_refptr(new ResourceResponse())));
436 old_handler_->WaitUntilDeferred();
437
438 EXPECT_EQ(1, old_handler_->on_read_completed_called());
439 EXPECT_EQ(0, old_handler_->on_response_completed_called());
440 EXPECT_EQ(0, new_handler->on_response_started_called());
427 441
428 // The old handler has received the first N bytes of the payload synchronously 442 // The old handler has received the first N bytes of the payload synchronously
429 // where N is the size of the buffer exposed via OnWillRead. 443 // where N is the size of the buffer exposed via OnWillRead.
430 EXPECT_EQ(std::string(kPayload, 0, kOldHandlerBufferSize), old_handler_body_); 444 EXPECT_EQ(std::string(kPayload, 0, kOldHandlerBufferSize), old_handler_body_);
431 EXPECT_EQ(std::string(), new_handler_body); 445 EXPECT_EQ(std::string(), new_handler_body);
432 EXPECT_EQ(net::URLRequestStatus::IO_PENDING, old_handler_status_.status()); 446 EXPECT_EQ(net::URLRequestStatus::IO_PENDING, old_handler_status_.status());
433 EXPECT_EQ(net::URLRequestStatus::IO_PENDING, new_handler_status.status()); 447 EXPECT_EQ(net::URLRequestStatus::IO_PENDING, new_handler_status.status());
434 448
449 // Run until the old handler's OnWillRead method defers the request while
450 // replaying the payload.
451 old_handler_->Resume();
452 old_handler_->WaitUntilDeferred();
453 EXPECT_EQ(2, old_handler_->on_will_read_called());
454 EXPECT_EQ(1, old_handler_->on_read_completed_called());
455 EXPECT_EQ(0, old_handler_->on_response_completed_called());
456 EXPECT_EQ(std::string(kPayload, 0, kOldHandlerBufferSize), old_handler_body_);
457 EXPECT_EQ(std::string(), new_handler_body);
458 EXPECT_EQ(net::URLRequestStatus::IO_PENDING, old_handler_status_.status());
459 EXPECT_EQ(net::URLRequestStatus::IO_PENDING, new_handler_status.status());
460
435 // Run until the new handler's OnWillStart method defers the request. 461 // Run until the new handler's OnWillStart method defers the request.
436 old_handler_->Resume(); 462 old_handler_->Resume();
437 // Resume() call may do work asynchronously. Wait until that's done. 463 new_handler->WaitUntilDeferred();
438 base::RunLoop().RunUntilIdle(); 464
465 EXPECT_EQ(1, new_handler->on_will_start_called());
466 EXPECT_EQ(0, new_handler->on_response_started_called());
439 ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING, 467 ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
440 mock_loader_->status()); 468 mock_loader_->status());
441 EXPECT_EQ(kPayload, old_handler_body_); 469 EXPECT_EQ(kPayload, old_handler_body_);
442 EXPECT_EQ(net::URLRequestStatus::SUCCESS, old_handler_status_.status()); 470 EXPECT_EQ(net::URLRequestStatus::SUCCESS, old_handler_status_.status());
443 EXPECT_FALSE(old_handler_); 471 EXPECT_FALSE(old_handler_);
444 EXPECT_EQ(std::string(), new_handler_body); 472 EXPECT_EQ(std::string(), new_handler_body);
445 EXPECT_EQ(net::URLRequestStatus::IO_PENDING, new_handler_status.status()); 473 EXPECT_EQ(net::URLRequestStatus::IO_PENDING, new_handler_status.status());
446 474
447 // Run until the new handler's OnResponseStarted method defers the request. 475 // Run until the new handler's OnResponseStarted method defers the request.
448 new_handler->Resume(); 476 new_handler->Resume();
449 // Resume() call may do work asynchronously. Wait until that's done. 477 // Resume() call may do work asynchronously. Wait until that's done.
450 base::RunLoop().RunUntilIdle(); 478 new_handler->WaitUntilDeferred();
479
480 EXPECT_EQ(1, new_handler->on_response_started_called());
481 EXPECT_EQ(0, new_handler->on_will_read_called());
451 ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING, 482 ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
452 mock_loader_->status()); 483 mock_loader_->status());
453 EXPECT_EQ(std::string(), new_handler_body); 484 EXPECT_EQ(std::string(), new_handler_body);
454 EXPECT_EQ(net::URLRequestStatus::IO_PENDING, new_handler_status.status()); 485 EXPECT_EQ(net::URLRequestStatus::IO_PENDING, new_handler_status.status());
455 486
456 // Resuming should finally call back into the ResourceController. 487 // Resuming should finally call back into the ResourceController.
457 new_handler->Resume(); 488 new_handler->Resume();
458 mock_loader_->WaitUntilIdleOrCanceled(); 489 mock_loader_->WaitUntilIdleOrCanceled();
459 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status()); 490 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status());
460 491
461 // Data is read, the new handler defers completion of the read. 492 // Data is read, the new handler defers OnWillRead.
462 ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING, 493 ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
463 mock_loader_->OnReadCompleted(kData)); 494 mock_loader_->OnReadCompleted(kData));
495 new_handler->WaitUntilDeferred();
496 EXPECT_EQ(1, new_handler->on_will_read_called());
497 EXPECT_EQ(0, new_handler->on_read_completed_called());
498
499 // The new ResourceHandler resumes, and then defers again in OnReadCompleted.
500 new_handler->Resume();
501 new_handler->WaitUntilDeferred();
502 EXPECT_EQ(1, new_handler->on_will_read_called());
503 EXPECT_EQ(1, new_handler->on_read_completed_called());
504 EXPECT_EQ(0, new_handler->on_response_completed_called());
464 505
465 EXPECT_EQ("T", new_handler_body); 506 EXPECT_EQ("T", new_handler_body);
466 507
508 // New handler resumes again, everything continues synchronously until all
509 // written data is consumed.
467 new_handler->Resume(); 510 new_handler->Resume();
468 mock_loader_->WaitUntilIdleOrCanceled(); 511 mock_loader_->WaitUntilIdleOrCanceled();
469 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status()); 512 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status());
470 EXPECT_EQ(kData, new_handler_body); 513 EXPECT_EQ(kData, new_handler_body);
471 EXPECT_EQ(net::URLRequestStatus::IO_PENDING, new_handler_status.status()); 514 EXPECT_EQ(net::URLRequestStatus::IO_PENDING, new_handler_status.status());
515 EXPECT_EQ(0, new_handler->on_read_eof_called());
516 EXPECT_EQ(0, new_handler->on_response_completed_called());
472 517
473 // Final EOF byte is read. 518 // Final EOF byte is read.
474 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead()); 519 ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
475 ASSERT_EQ(MockResourceLoader::Status::IDLE, 520 ASSERT_EQ(MockResourceLoader::Status::IDLE,
476 mock_loader_->OnReadCompleted("")); 521 mock_loader_->OnReadCompleted(""));
522 EXPECT_EQ(1, new_handler->on_read_eof_called());
523 EXPECT_EQ(0, new_handler->on_response_completed_called());
477 524
478 ASSERT_EQ( 525 ASSERT_EQ(
479 MockResourceLoader::Status::CALLBACK_PENDING, 526 MockResourceLoader::Status::CALLBACK_PENDING,
480 mock_loader_->OnResponseCompleted({net::URLRequestStatus::SUCCESS, 0})); 527 mock_loader_->OnResponseCompleted({net::URLRequestStatus::SUCCESS, 0}));
481 EXPECT_EQ(net::URLRequestStatus::SUCCESS, new_handler_status.status()); 528 EXPECT_EQ(net::URLRequestStatus::SUCCESS, new_handler_status.status());
529 EXPECT_EQ(1, new_handler->on_response_completed_called());
482 } 530 }
483 531
484 // Test cancellation where there is only the old handler in an 532 // Test cancellation where there is only the old handler in an
485 // InterceptingResourceHandler. 533 // InterceptingResourceHandler.
486 TEST_F(InterceptingResourceHandlerTest, CancelOldHandler) { 534 TEST_F(InterceptingResourceHandlerTest, CancelOldHandler) {
487 ASSERT_EQ(MockResourceLoader::Status::IDLE, 535 ASSERT_EQ(MockResourceLoader::Status::IDLE,
488 mock_loader_->OnResponseCompletedFromExternalOutOfBandCancel( 536 mock_loader_->OnResponseCompletedFromExternalOutOfBandCancel(
489 {net::URLRequestStatus::CANCELED, net::ERR_FAILED})); 537 {net::URLRequestStatus::CANCELED, net::ERR_FAILED}));
490 EXPECT_EQ(net::URLRequestStatus::CANCELED, old_handler_status_.status()); 538 EXPECT_EQ(net::URLRequestStatus::CANCELED, old_handler_status_.status());
491 EXPECT_EQ(net::ERR_FAILED, old_handler_status_.error()); 539 EXPECT_EQ(net::ERR_FAILED, old_handler_status_.error());
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 {net::URLRequestStatus::CANCELED, net::ERR_FAILED})); 621 {net::URLRequestStatus::CANCELED, net::ERR_FAILED}));
574 EXPECT_EQ(net::URLRequestStatus::CANCELED, old_handler_status_.status()); 622 EXPECT_EQ(net::URLRequestStatus::CANCELED, old_handler_status_.status());
575 EXPECT_EQ(net::ERR_FAILED, old_handler_status_.error()); 623 EXPECT_EQ(net::ERR_FAILED, old_handler_status_.error());
576 EXPECT_EQ(net::URLRequestStatus::CANCELED, new_handler_status.status()); 624 EXPECT_EQ(net::URLRequestStatus::CANCELED, new_handler_status.status());
577 EXPECT_EQ(net::ERR_FAILED, new_handler_status.error()); 625 EXPECT_EQ(net::ERR_FAILED, new_handler_status.error());
578 } 626 }
579 627
580 } // namespace 628 } // namespace
581 629
582 } // namespace content 630 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698