Chromium Code Reviews| Index: content/browser/loader/resource_loader_unittest.cc |
| diff --git a/content/browser/loader/resource_loader_unittest.cc b/content/browser/loader/resource_loader_unittest.cc |
| index 8be5ec1d0ebdc82e3b30c215e976ef44f6ca83e0..bf662470a241c664346f9e53cdecae1e2a03fcbf 100644 |
| --- a/content/browser/loader/resource_loader_unittest.cc |
| +++ b/content/browser/loader/resource_loader_unittest.cc |
| @@ -14,6 +14,7 @@ |
| #include "content/browser/loader/resource_loader_delegate.h" |
| #include "content/public/browser/client_certificate_delegate.h" |
| #include "content/public/browser/resource_request_info.h" |
| +#include "content/public/common/content_paths.h" |
| #include "content/public/common/resource_response.h" |
| #include "content/public/test/mock_resource_context.h" |
| #include "content/public/test/test_browser_context.h" |
| @@ -22,13 +23,16 @@ |
| #include "content/test/test_content_browser_client.h" |
| #include "content/test/test_web_contents.h" |
| #include "ipc/ipc_message.h" |
| +#include "net/base/chunked_upload_data_stream.h" |
| #include "net/base/io_buffer.h" |
| #include "net/base/mock_file_stream.h" |
| #include "net/base/net_errors.h" |
| #include "net/base/request_priority.h" |
| +#include "net/base/upload_bytes_element_reader.h" |
| #include "net/cert/x509_certificate.h" |
| #include "net/ssl/client_cert_store.h" |
| #include "net/ssl/ssl_cert_request_info.h" |
| +#include "net/test/embedded_test_server/embedded_test_server.h" |
| #include "net/url_request/url_request.h" |
| #include "net/url_request/url_request_job_factory.h" |
| #include "net/url_request/url_request_job_factory_impl.h" |
| @@ -175,7 +179,8 @@ class ResourceHandlerStub : public ResourceHandler { |
| received_on_will_read_(false), |
| received_eof_(false), |
| received_response_completed_(false), |
| - total_bytes_downloaded_(0) { |
| + total_bytes_downloaded_(0), |
| + upload_position_(0) { |
| } |
| // If true, defers the resource load in OnWillStart. |
| @@ -207,9 +212,21 @@ class ResourceHandlerStub : public ResourceHandler { |
| controller()->Resume(); |
| } |
| + // Waits until OnUploadProgress is called and returns the upload position. |
| + uint64 WaitForUploadProgress() { |
| + wait_for_progress_loop_.reset(new base::RunLoop()); |
| + wait_for_progress_loop_->Run(); |
| + wait_for_progress_loop_.reset(); |
| + return upload_position_; |
| + } |
| + |
| // ResourceHandler implementation: |
| bool OnUploadProgress(uint64 position, uint64 size) override { |
| - NOTREACHED(); |
| + EXPECT_LE(position, size); |
| + EXPECT_GE(position, upload_position_); |
|
mmenke
2015/05/22 15:15:08
This should be GT, right? We never call it with t
Andre
2015/05/22 17:24:45
You're right, fixed.
|
| + upload_position_ = position; |
| + if (wait_for_progress_loop_) |
| + wait_for_progress_loop_->Quit(); |
| return true; |
| } |
| @@ -301,6 +318,8 @@ class ResourceHandlerStub : public ResourceHandler { |
| bool received_response_completed_; |
| net::URLRequestStatus status_; |
| int total_bytes_downloaded_; |
| + scoped_ptr<base::RunLoop> wait_for_progress_loop_; |
| + uint64 upload_position_; |
| }; |
| // Test browser client that captures calls to SelectClientCertificates and |
| @@ -351,6 +370,39 @@ class ResourceContextStub : public MockResourceContext { |
| scoped_ptr<net::ClientCertStore> dummy_cert_store_; |
| }; |
| +// Wraps a ChunkedUploadDataStream to behave as non-chunked to enable upload |
| +// progress reporting. |
| +class NonChunkedUploadDataStream : public net::UploadDataStream { |
|
mmenke
2015/05/22 15:15:08
Great idea!
|
| + public: |
| + explicit NonChunkedUploadDataStream(uint64 size) |
| + : net::UploadDataStream(false, 0), stream_(0), size_(size) {} |
| + |
| + void AppendData(const char* data) { |
| + stream_.AppendData(data, strlen(data), false); |
| + } |
| + |
| + private: |
| + int InitInternal() override { |
| + SetSize(size_); |
| + stream_.Init(base::Bind(&NonChunkedUploadDataStream::OnInitCompleted, |
| + base::Unretained(this))); |
| + return net::OK; |
| + } |
| + |
| + int ReadInternal(net::IOBuffer* buf, int buf_len) override { |
| + return stream_.Read(buf, buf_len, |
| + base::Bind(&NonChunkedUploadDataStream::OnReadCompleted, |
| + base::Unretained(this))); |
| + } |
| + |
| + void ResetInternal() override { stream_.Reset(); } |
| + |
| + net::ChunkedUploadDataStream stream_; |
| + uint64 size_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(NonChunkedUploadDataStream); |
| +}; |
| + |
| // Fails to create a temporary file with the given error. |
| void CreateTemporaryError( |
| base::File::Error error, |
| @@ -380,6 +432,17 @@ class ResourceLoaderTest : public testing::Test, |
| return net::URLRequestTestJob::test_data_1(); |
| } |
| + // Waits until upload progress reaches |target_position| |
| + void WaitForUploadProgress(uint64 target_position) { |
| + while (true) { |
| + uint64 position = raw_ptr_resource_handler_->WaitForUploadProgress(); |
| + EXPECT_LE(position, target_position); |
| + loader_->OnUploadProgressACK(); |
| + if (position == target_position) |
| + break; |
| + } |
| + } |
| + |
| virtual net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() { |
| return net::URLRequestTestJob::CreateProtocolHandler(); |
| } |
| @@ -390,22 +453,11 @@ class ResourceLoaderTest : public testing::Test, |
| return leaf_handler.Pass(); |
| } |
| - void SetUp() override { |
| - job_factory_.SetProtocolHandler("test", CreateProtocolHandler()); |
| + // Replaces loader_ with a new one for |request|. |
| + void SetUpResourceLoader(scoped_ptr<net::URLRequest> request) { |
| + raw_ptr_to_request_ = request.get(); |
| - browser_context_.reset(new TestBrowserContext()); |
| - scoped_refptr<SiteInstance> site_instance = |
| - SiteInstance::Create(browser_context_.get()); |
| - web_contents_.reset( |
| - TestWebContents::Create(browser_context_.get(), site_instance.get())); |
| RenderFrameHost* rfh = web_contents_->GetMainFrame(); |
| - |
| - scoped_ptr<net::URLRequest> request( |
| - resource_context_.GetRequestContext()->CreateRequest( |
| - test_url(), |
| - net::DEFAULT_PRIORITY, |
| - NULL /* delegate */)); |
| - raw_ptr_to_request_ = request.get(); |
| ResourceRequestInfo::AllocateForTesting( |
| request.get(), RESOURCE_TYPE_MAIN_FRAME, &resource_context_, |
| rfh->GetProcess()->GetID(), rfh->GetRenderViewHost()->GetRoutingID(), |
| @@ -421,6 +473,23 @@ class ResourceLoaderTest : public testing::Test, |
| this)); |
| } |
| + void SetUp() override { |
| + job_factory_.SetProtocolHandler("test", CreateProtocolHandler()); |
| + |
| + browser_context_.reset(new TestBrowserContext()); |
| + scoped_refptr<SiteInstance> site_instance = |
| + SiteInstance::Create(browser_context_.get()); |
| + web_contents_.reset( |
| + TestWebContents::Create(browser_context_.get(), site_instance.get())); |
| + |
| + scoped_ptr<net::URLRequest> request( |
| + resource_context_.GetRequestContext()->CreateRequest( |
| + test_url(), |
| + net::DEFAULT_PRIORITY, |
| + nullptr /* delegate */)); |
| + SetUpResourceLoader(request.Pass()); |
| + } |
| + |
| void TearDown() override { |
| // Destroy the WebContents and pump the event loop before destroying |
| // |rvh_test_enabler_| and |thread_bundle_|. This lets asynchronous cleanup |
| @@ -640,6 +709,39 @@ TEST_F(ResourceLoaderTest, DeferEOF) { |
| raw_ptr_resource_handler_->status().status()); |
| } |
| +// Tests that progress is reported correctly while uploading. |
| +// TODO(andresantoso): Add test for the redirect case. |
| +TEST_F(ResourceLoaderTest, UploadProgress) { |
| + // Set up a test server. |
| + net::test_server::EmbeddedTestServer server; |
| + ASSERT_TRUE(server.InitializeAndWaitUntilReady()); |
| + base::FilePath path; |
| + PathService::Get(content::DIR_TEST_DATA, &path); |
| + server.ServeFilesFromDirectory(path); |
| + |
| + scoped_ptr<net::URLRequest> request( |
| + resource_context_.GetRequestContext()->CreateRequest( |
| + server.GetURL("/title1.html"), |
| + net::DEFAULT_PRIORITY, |
| + nullptr /* delegate */)); |
| + |
| + // Start an upload. |
| + auto stream = new NonChunkedUploadDataStream(10); |
| + request->set_upload(make_scoped_ptr(stream)); |
| + |
| + SetUpResourceLoader(request.Pass()); |
| + loader_->StartRequest(); |
| + |
| + stream->AppendData("xx"); |
| + WaitForUploadProgress(2); |
| + |
| + stream->AppendData("yyy"); |
| + WaitForUploadProgress(5); |
| + |
| + stream->AppendData("zzzzz"); |
| + WaitForUploadProgress(10); |
| +} |
| + |
| class ResourceLoaderRedirectToFileTest : public ResourceLoaderTest { |
| public: |
| ResourceLoaderRedirectToFileTest() |