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

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

Issue 2654893002: Add unit tests for RedirectToFileResourceHandler. (Closed)
Patch Set: Revise Created 3 years, 11 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 (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/resource_loader.h" 5 #include "content/browser/loader/resource_loader.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <deque> 10 #include <deque>
11 #include <memory> 11 #include <memory>
12 #include <utility> 12 #include <utility>
13 #include <vector> 13 #include <vector>
14 14
15 #include "base/files/file.h"
16 #include "base/files/file_util.h"
17 #include "base/location.h" 15 #include "base/location.h"
18 #include "base/macros.h" 16 #include "base/macros.h"
19 #include "base/memory/ptr_util.h" 17 #include "base/memory/ptr_util.h"
20 #include "base/memory/weak_ptr.h" 18 #include "base/memory/weak_ptr.h"
21 #include "base/run_loop.h" 19 #include "base/run_loop.h"
22 #include "base/single_thread_task_runner.h" 20 #include "base/single_thread_task_runner.h"
23 #include "base/threading/thread_task_runner_handle.h" 21 #include "base/threading/thread_task_runner_handle.h"
24 #include "content/browser/browser_thread_impl.h" 22 #include "content/browser/browser_thread_impl.h"
25 #include "content/browser/loader/redirect_to_file_resource_handler.h"
26 #include "content/browser/loader/resource_loader_delegate.h" 23 #include "content/browser/loader/resource_loader_delegate.h"
27 #include "content/browser/loader/test_resource_handler.h" 24 #include "content/browser/loader/test_resource_handler.h"
28 #include "content/public/browser/client_certificate_delegate.h" 25 #include "content/public/browser/client_certificate_delegate.h"
29 #include "content/public/browser/resource_request_info.h" 26 #include "content/public/browser/resource_request_info.h"
30 #include "content/public/common/content_paths.h" 27 #include "content/public/common/content_paths.h"
31 #include "content/public/common/resource_response.h" 28 #include "content/public/common/resource_response.h"
32 #include "content/public/common/resource_type.h" 29 #include "content/public/common/resource_type.h"
33 #include "content/public/test/mock_resource_context.h" 30 #include "content/public/test/mock_resource_context.h"
34 #include "content/public/test/test_browser_context.h" 31 #include "content/public/test/test_browser_context.h"
35 #include "content/public/test/test_browser_thread_bundle.h" 32 #include "content/public/test/test_browser_thread_bundle.h"
36 #include "content/public/test/test_renderer_host.h" 33 #include "content/public/test/test_renderer_host.h"
37 #include "content/test/test_content_browser_client.h" 34 #include "content/test/test_content_browser_client.h"
38 #include "content/test/test_web_contents.h" 35 #include "content/test/test_web_contents.h"
39 #include "ipc/ipc_message.h" 36 #include "ipc/ipc_message.h"
40 #include "net/base/chunked_upload_data_stream.h" 37 #include "net/base/chunked_upload_data_stream.h"
41 #include "net/base/io_buffer.h" 38 #include "net/base/io_buffer.h"
42 #include "net/base/mock_file_stream.h"
43 #include "net/base/net_errors.h" 39 #include "net/base/net_errors.h"
44 #include "net/base/request_priority.h" 40 #include "net/base/request_priority.h"
45 #include "net/base/upload_bytes_element_reader.h" 41 #include "net/base/upload_bytes_element_reader.h"
46 #include "net/cert/x509_certificate.h" 42 #include "net/cert/x509_certificate.h"
47 #include "net/nqe/effective_connection_type.h" 43 #include "net/nqe/effective_connection_type.h"
48 #include "net/nqe/network_quality_estimator_test_util.h" 44 #include "net/nqe/network_quality_estimator_test_util.h"
49 #include "net/ssl/client_cert_store.h" 45 #include "net/ssl/client_cert_store.h"
50 #include "net/ssl/ssl_cert_request_info.h" 46 #include "net/ssl/ssl_cert_request_info.h"
51 #include "net/ssl/ssl_private_key.h" 47 #include "net/ssl/ssl_private_key.h"
52 #include "net/test/cert_test_util.h" 48 #include "net/test/cert_test_util.h"
53 #include "net/test/embedded_test_server/embedded_test_server.h" 49 #include "net/test/embedded_test_server/embedded_test_server.h"
54 #include "net/test/test_data_directory.h" 50 #include "net/test/test_data_directory.h"
55 #include "net/test/url_request/url_request_failed_job.h" 51 #include "net/test/url_request/url_request_failed_job.h"
56 #include "net/url_request/url_request.h" 52 #include "net/url_request/url_request.h"
57 #include "net/url_request/url_request_filter.h" 53 #include "net/url_request/url_request_filter.h"
58 #include "net/url_request/url_request_interceptor.h" 54 #include "net/url_request/url_request_interceptor.h"
59 #include "net/url_request/url_request_job_factory.h" 55 #include "net/url_request/url_request_job_factory.h"
60 #include "net/url_request/url_request_job_factory_impl.h" 56 #include "net/url_request/url_request_job_factory_impl.h"
61 #include "net/url_request/url_request_test_job.h" 57 #include "net/url_request/url_request_test_job.h"
62 #include "net/url_request/url_request_test_util.h" 58 #include "net/url_request/url_request_test_util.h"
63 #include "storage/browser/blob/shareable_file_reference.h"
64 #include "testing/gtest/include/gtest/gtest.h" 59 #include "testing/gtest/include/gtest/gtest.h"
65 60
66 using storage::ShareableFileReference;
67
68 namespace content { 61 namespace content {
69 namespace { 62 namespace {
70 63
71 // Stub client certificate store that returns a preset list of certificates for 64 // Stub client certificate store that returns a preset list of certificates for
72 // each request and records the arguments of the most recent request for later 65 // each request and records the arguments of the most recent request for later
73 // inspection. 66 // inspection.
74 class ClientCertStoreStub : public net::ClientCertStore { 67 class ClientCertStoreStub : public net::ClientCertStore {
75 public: 68 public:
76 // Creates a new ClientCertStoreStub that returns |response| on query. It 69 // Creates a new ClientCertStoreStub that returns |response| on query. It
77 // saves the number of requests and most recently certificate authorities list 70 // saves the number of requests and most recently certificate authorities list
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 } 335 }
343 336
344 void ResetInternal() override { stream_.Reset(); } 337 void ResetInternal() override { stream_.Reset(); }
345 338
346 net::ChunkedUploadDataStream stream_; 339 net::ChunkedUploadDataStream stream_;
347 uint64_t size_; 340 uint64_t size_;
348 341
349 DISALLOW_COPY_AND_ASSIGN(NonChunkedUploadDataStream); 342 DISALLOW_COPY_AND_ASSIGN(NonChunkedUploadDataStream);
350 }; 343 };
351 344
352 // Fails to create a temporary file with the given error.
353 void CreateTemporaryError(
354 base::File::Error error,
355 const CreateTemporaryFileStreamCallback& callback) {
356 base::ThreadTaskRunnerHandle::Get()->PostTask(
357 FROM_HERE,
358 base::Bind(callback, error,
359 base::Passed(std::unique_ptr<net::FileStream>()), nullptr));
360 }
361
362 } // namespace 345 } // namespace
363 346
364 class ResourceLoaderTest : public testing::Test, 347 class ResourceLoaderTest : public testing::Test,
365 public ResourceLoaderDelegate { 348 public ResourceLoaderDelegate {
366 protected: 349 protected:
367 ResourceLoaderTest() 350 ResourceLoaderTest()
368 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), 351 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
369 test_url_request_context_(true), 352 test_url_request_context_(true),
370 resource_context_(&test_url_request_context_), 353 resource_context_(&test_url_request_context_),
371 raw_ptr_resource_handler_(NULL), 354 raw_ptr_resource_handler_(NULL),
(...skipping 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after
1434 } 1417 }
1435 1418
1436 TEST_F(ResourceLoaderTest, ResumeCanceledRequest) { 1419 TEST_F(ResourceLoaderTest, ResumeCanceledRequest) {
1437 raw_ptr_resource_handler_->set_defer_on_will_start(true); 1420 raw_ptr_resource_handler_->set_defer_on_will_start(true);
1438 1421
1439 loader_->StartRequest(); 1422 loader_->StartRequest();
1440 loader_->CancelRequest(true); 1423 loader_->CancelRequest(true);
1441 static_cast<ResourceController*>(loader_.get())->Resume(); 1424 static_cast<ResourceController*>(loader_.get())->Resume();
1442 } 1425 }
1443 1426
1444 class ResourceLoaderRedirectToFileTest : public ResourceLoaderTest {
1445 public:
1446 ResourceLoaderRedirectToFileTest()
1447 : file_stream_(NULL),
1448 redirect_to_file_resource_handler_(NULL) {
1449 }
1450
1451 ~ResourceLoaderRedirectToFileTest() override {
1452 // Releasing the loader should result in destroying the file asynchronously.
1453 file_stream_ = nullptr;
1454 deletable_file_ = nullptr;
1455 loader_.reset();
1456
1457 // Wait for the task to delete the file to run, and make sure the file is
1458 // cleaned up.
1459 base::RunLoop().RunUntilIdle();
1460 EXPECT_FALSE(base::PathExists(temp_path()));
1461 }
1462
1463 base::FilePath temp_path() const { return temp_path_; }
1464 ShareableFileReference* deletable_file() const {
1465 return deletable_file_.get();
1466 }
1467 net::testing::MockFileStream* file_stream() const { return file_stream_; }
1468 RedirectToFileResourceHandler* redirect_to_file_resource_handler() const {
1469 return redirect_to_file_resource_handler_;
1470 }
1471
1472 std::unique_ptr<ResourceHandler> WrapResourceHandler(
1473 std::unique_ptr<TestResourceHandler> leaf_handler,
1474 net::URLRequest* request) override {
1475 leaf_handler->set_expect_on_data_downloaded(true);
1476
1477 // Make a temporary file.
1478 CHECK(base::CreateTemporaryFile(&temp_path_));
1479 int flags = base::File::FLAG_WRITE | base::File::FLAG_TEMPORARY |
1480 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_ASYNC;
1481 base::File file(temp_path_, flags);
1482 CHECK(file.IsValid());
1483
1484 // Create mock file streams and a ShareableFileReference.
1485 std::unique_ptr<net::testing::MockFileStream> file_stream(
1486 new net::testing::MockFileStream(std::move(file),
1487 base::ThreadTaskRunnerHandle::Get()));
1488 file_stream_ = file_stream.get();
1489 deletable_file_ = ShareableFileReference::GetOrCreate(
1490 temp_path_, ShareableFileReference::DELETE_ON_FINAL_RELEASE,
1491 BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get());
1492
1493 // Inject them into the handler.
1494 std::unique_ptr<RedirectToFileResourceHandler> handler(
1495 new RedirectToFileResourceHandler(std::move(leaf_handler), request));
1496 redirect_to_file_resource_handler_ = handler.get();
1497 handler->SetCreateTemporaryFileStreamFunctionForTesting(
1498 base::Bind(&ResourceLoaderRedirectToFileTest::PostCallback,
1499 base::Unretained(this),
1500 base::Passed(&file_stream)));
1501 return std::move(handler);
1502 }
1503
1504 private:
1505 void PostCallback(std::unique_ptr<net::FileStream> file_stream,
1506 const CreateTemporaryFileStreamCallback& callback) {
1507 base::ThreadTaskRunnerHandle::Get()->PostTask(
1508 FROM_HERE,
1509 base::Bind(callback, base::File::FILE_OK, base::Passed(&file_stream),
1510 base::RetainedRef(deletable_file_)));
1511 }
1512
1513 base::FilePath temp_path_;
1514 scoped_refptr<ShareableFileReference> deletable_file_;
1515 // These are owned by the ResourceLoader.
1516 net::testing::MockFileStream* file_stream_;
1517 RedirectToFileResourceHandler* redirect_to_file_resource_handler_;
1518 };
1519
1520 // Tests that a RedirectToFileResourceHandler works and forwards everything
1521 // downstream.
1522 TEST_F(ResourceLoaderRedirectToFileTest, Basic) {
1523 // Run it to completion.
1524 loader_->StartRequest();
1525 raw_ptr_resource_handler_->WaitUntilResponseComplete();
1526
1527 // Check that the handler forwarded all information to the downstream handler.
1528 EXPECT_EQ(
1529 temp_path(),
1530 raw_ptr_resource_handler_->resource_response()->head.download_file_path);
1531 EXPECT_EQ(test_redirect_url(), raw_ptr_resource_handler_->start_url());
1532 EXPECT_EQ(net::URLRequestStatus::SUCCESS,
1533 raw_ptr_resource_handler_->final_status().status());
1534 EXPECT_EQ(test_data().size(), static_cast<size_t>(
1535 raw_ptr_resource_handler_->total_bytes_downloaded()));
1536
1537 // Check that the data was written to the file.
1538 std::string contents;
1539 ASSERT_TRUE(base::ReadFileToString(temp_path(), &contents));
1540 EXPECT_EQ(test_data(), contents);
1541 }
1542
1543 // Tests that RedirectToFileResourceHandler handles errors in creating the
1544 // temporary file.
1545 TEST_F(ResourceLoaderRedirectToFileTest, CreateTemporaryError) {
1546 // Swap out the create temporary function.
1547 redirect_to_file_resource_handler()->
1548 SetCreateTemporaryFileStreamFunctionForTesting(
1549 base::Bind(&CreateTemporaryError, base::File::FILE_ERROR_FAILED));
1550
1551 // Run it to completion.
1552 loader_->StartRequest();
1553 raw_ptr_resource_handler_->WaitUntilResponseComplete();
1554
1555 // To downstream, the request was canceled.
1556 EXPECT_EQ(net::URLRequestStatus::CANCELED,
1557 raw_ptr_resource_handler_->final_status().status());
1558 EXPECT_EQ(0, raw_ptr_resource_handler_->total_bytes_downloaded());
1559 }
1560
1561 // Tests that RedirectToFileResourceHandler handles synchronous write errors.
1562 TEST_F(ResourceLoaderRedirectToFileTest, WriteError) {
1563 file_stream()->set_forced_error(net::ERR_FAILED);
1564
1565 // Run it to completion.
1566 loader_->StartRequest();
1567 raw_ptr_resource_handler_->WaitUntilResponseComplete();
1568
1569 // To downstream, the request was canceled sometime after it started, but
1570 // before any data was written.
1571 EXPECT_EQ(
1572 temp_path(),
1573 raw_ptr_resource_handler_->resource_response()->head.download_file_path);
1574 EXPECT_EQ(test_redirect_url(), raw_ptr_resource_handler_->start_url());
1575 EXPECT_EQ(net::URLRequestStatus::CANCELED,
1576 raw_ptr_resource_handler_->final_status().status());
1577 EXPECT_EQ(0, raw_ptr_resource_handler_->total_bytes_downloaded());
1578 }
1579
1580 // Tests that RedirectToFileResourceHandler handles asynchronous write errors.
1581 TEST_F(ResourceLoaderRedirectToFileTest, WriteErrorAsync) {
1582 file_stream()->set_forced_error_async(net::ERR_FAILED);
1583
1584 // Run it to completion.
1585 loader_->StartRequest();
1586 raw_ptr_resource_handler_->WaitUntilResponseComplete();
1587
1588 // To downstream, the request was canceled sometime after it started, but
1589 // before any data was written.
1590 EXPECT_EQ(
1591 temp_path(),
1592 raw_ptr_resource_handler_->resource_response()->head.download_file_path);
1593 EXPECT_EQ(test_redirect_url(), raw_ptr_resource_handler_->start_url());
1594 EXPECT_EQ(net::URLRequestStatus::CANCELED,
1595 raw_ptr_resource_handler_->final_status().status());
1596 EXPECT_EQ(0, raw_ptr_resource_handler_->total_bytes_downloaded());
1597 }
1598
1599 // Tests that RedirectToFileHandler defers completion if there are outstanding
1600 // writes and accounts for errors which occur in that time.
1601 TEST_F(ResourceLoaderRedirectToFileTest, DeferCompletion) {
1602 // Program the MockFileStream to error asynchronously, but throttle the
1603 // callback.
1604 file_stream()->set_forced_error_async(net::ERR_FAILED);
1605 file_stream()->ThrottleCallbacks();
1606
1607 // Run it as far as it will go.
1608 loader_->StartRequest();
1609 base::RunLoop().RunUntilIdle();
1610
1611 // At this point, the request should have completed.
1612 EXPECT_EQ(net::URLRequestStatus::SUCCESS,
1613 raw_ptr_to_request_->status().status());
1614
1615 // However, the resource loader stack is stuck somewhere after receiving the
1616 // response.
1617 EXPECT_EQ(
1618 temp_path(),
1619 raw_ptr_resource_handler_->resource_response()->head.download_file_path);
1620 EXPECT_EQ(test_redirect_url(), raw_ptr_resource_handler_->start_url());
1621 EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_completed_called());
1622 EXPECT_EQ(0, raw_ptr_resource_handler_->total_bytes_downloaded());
1623
1624 // Now, release the floodgates.
1625 file_stream()->ReleaseCallbacks();
1626 raw_ptr_resource_handler_->WaitUntilResponseComplete();
1627
1628 // Although the URLRequest was successful, the leaf handler sees a failure
1629 // because the write never completed.
1630 EXPECT_EQ(net::URLRequestStatus::CANCELED,
1631 raw_ptr_resource_handler_->final_status().status());
1632 }
1633
1634 // Tests that a RedirectToFileResourceHandler behaves properly when the
1635 // downstream handler defers OnWillStart.
1636 TEST_F(ResourceLoaderRedirectToFileTest, DownstreamDeferStart) {
1637 // Defer OnWillStart.
1638 raw_ptr_resource_handler_->set_defer_on_will_start(true);
1639
1640 // Run as far as we'll go.
1641 loader_->StartRequest();
1642 raw_ptr_resource_handler_->WaitUntilDeferred();
1643
1644 // The request should have stopped at OnWillStart.
1645 EXPECT_EQ(test_redirect_url(), raw_ptr_resource_handler_->start_url());
1646 EXPECT_FALSE(raw_ptr_resource_handler_->resource_response());
1647 EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_completed_called());
1648 EXPECT_EQ(0, raw_ptr_resource_handler_->total_bytes_downloaded());
1649
1650 // Now resume the request. Now we complete.
1651 raw_ptr_resource_handler_->Resume();
1652 raw_ptr_resource_handler_->WaitUntilResponseComplete();
1653
1654 // Check that the handler forwarded all information to the downstream handler.
1655 EXPECT_EQ(
1656 temp_path(),
1657 raw_ptr_resource_handler_->resource_response()->head.download_file_path);
1658 EXPECT_EQ(test_redirect_url(), raw_ptr_resource_handler_->start_url());
1659 EXPECT_EQ(net::URLRequestStatus::SUCCESS,
1660 raw_ptr_resource_handler_->final_status().status());
1661 EXPECT_EQ(test_data().size(), static_cast<size_t>(
1662 raw_ptr_resource_handler_->total_bytes_downloaded()));
1663
1664 // Check that the data was written to the file.
1665 std::string contents;
1666 ASSERT_TRUE(base::ReadFileToString(temp_path(), &contents));
1667 EXPECT_EQ(test_data(), contents);
1668 }
1669
1670 class EffectiveConnectionTypeResourceLoaderTest : public ResourceLoaderTest { 1427 class EffectiveConnectionTypeResourceLoaderTest : public ResourceLoaderTest {
1671 public: 1428 public:
1672 void VerifyEffectiveConnectionType( 1429 void VerifyEffectiveConnectionType(
1673 ResourceType resource_type, 1430 ResourceType resource_type,
1674 bool belongs_to_main_frame, 1431 bool belongs_to_main_frame,
1675 net::EffectiveConnectionType set_type, 1432 net::EffectiveConnectionType set_type,
1676 net::EffectiveConnectionType expected_type) { 1433 net::EffectiveConnectionType expected_type) {
1677 network_quality_estimator()->set_effective_connection_type(set_type); 1434 network_quality_estimator()->set_effective_connection_type(set_type);
1678 1435
1679 // Start the request and wait for it to finish. 1436 // Start the request and wait for it to finish.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1719 1476
1720 // Tests that the effective connection type is not set on non-main frame 1477 // Tests that the effective connection type is not set on non-main frame
1721 // requests. 1478 // requests.
1722 TEST_F(EffectiveConnectionTypeResourceLoaderTest, DoesNotBelongToMainFrame) { 1479 TEST_F(EffectiveConnectionTypeResourceLoaderTest, DoesNotBelongToMainFrame) {
1723 VerifyEffectiveConnectionType(RESOURCE_TYPE_OBJECT, false, 1480 VerifyEffectiveConnectionType(RESOURCE_TYPE_OBJECT, false,
1724 net::EFFECTIVE_CONNECTION_TYPE_3G, 1481 net::EFFECTIVE_CONNECTION_TYPE_3G,
1725 net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN); 1482 net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN);
1726 } 1483 }
1727 1484
1728 } // namespace content 1485 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/loader/redirect_to_file_resource_handler_unittest.cc ('k') | content/browser/loader/test_resource_handler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698