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

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

Issue 1130343006: Don't share ResourceDispatcherHostImpl's timer for reporting upload progress. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@safari-backend
Patch Set: Created 5 years, 7 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 "base/files/file.h" 7 #include "base/files/file.h"
8 #include "base/files/file_util.h" 8 #include "base/files/file_util.h"
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/message_loop/message_loop_proxy.h" 10 #include "base/message_loop/message_loop_proxy.h"
11 #include "base/run_loop.h" 11 #include "base/run_loop.h"
12 #include "content/browser/browser_thread_impl.h" 12 #include "content/browser/browser_thread_impl.h"
13 #include "content/browser/loader/redirect_to_file_resource_handler.h" 13 #include "content/browser/loader/redirect_to_file_resource_handler.h"
14 #include "content/browser/loader/resource_loader_delegate.h" 14 #include "content/browser/loader/resource_loader_delegate.h"
15 #include "content/public/browser/client_certificate_delegate.h" 15 #include "content/public/browser/client_certificate_delegate.h"
16 #include "content/public/browser/resource_request_info.h" 16 #include "content/public/browser/resource_request_info.h"
17 #include "content/public/common/content_paths.h"
17 #include "content/public/common/resource_response.h" 18 #include "content/public/common/resource_response.h"
18 #include "content/public/test/mock_resource_context.h" 19 #include "content/public/test/mock_resource_context.h"
19 #include "content/public/test/test_browser_context.h" 20 #include "content/public/test/test_browser_context.h"
20 #include "content/public/test/test_browser_thread_bundle.h" 21 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "content/public/test/test_renderer_host.h" 22 #include "content/public/test/test_renderer_host.h"
22 #include "content/test/test_content_browser_client.h" 23 #include "content/test/test_content_browser_client.h"
23 #include "content/test/test_web_contents.h" 24 #include "content/test/test_web_contents.h"
24 #include "ipc/ipc_message.h" 25 #include "ipc/ipc_message.h"
26 #include "net/base/chunked_upload_data_stream.h"
25 #include "net/base/io_buffer.h" 27 #include "net/base/io_buffer.h"
26 #include "net/base/mock_file_stream.h" 28 #include "net/base/mock_file_stream.h"
27 #include "net/base/net_errors.h" 29 #include "net/base/net_errors.h"
28 #include "net/base/request_priority.h" 30 #include "net/base/request_priority.h"
31 #include "net/base/upload_bytes_element_reader.h"
29 #include "net/cert/x509_certificate.h" 32 #include "net/cert/x509_certificate.h"
30 #include "net/ssl/client_cert_store.h" 33 #include "net/ssl/client_cert_store.h"
31 #include "net/ssl/ssl_cert_request_info.h" 34 #include "net/ssl/ssl_cert_request_info.h"
35 #include "net/test/embedded_test_server/embedded_test_server.h"
32 #include "net/url_request/url_request.h" 36 #include "net/url_request/url_request.h"
33 #include "net/url_request/url_request_job_factory.h" 37 #include "net/url_request/url_request_job_factory.h"
34 #include "net/url_request/url_request_job_factory_impl.h" 38 #include "net/url_request/url_request_job_factory_impl.h"
35 #include "net/url_request/url_request_test_job.h" 39 #include "net/url_request/url_request_test_job.h"
36 #include "net/url_request/url_request_test_util.h" 40 #include "net/url_request/url_request_test_util.h"
37 #include "storage/browser/blob/shareable_file_reference.h" 41 #include "storage/browser/blob/shareable_file_reference.h"
38 #include "testing/gtest/include/gtest/gtest.h" 42 #include "testing/gtest/include/gtest/gtest.h"
39 43
40 using storage::ShareableFileReference; 44 using storage::ShareableFileReference;
41 45
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 explicit ResourceHandlerStub(net::URLRequest* request) 172 explicit ResourceHandlerStub(net::URLRequest* request)
169 : ResourceHandler(request), 173 : ResourceHandler(request),
170 read_buffer_(new net::IOBuffer(kReadBufSize)), 174 read_buffer_(new net::IOBuffer(kReadBufSize)),
171 defer_request_on_will_start_(false), 175 defer_request_on_will_start_(false),
172 expect_reads_(true), 176 expect_reads_(true),
173 cancel_on_read_completed_(false), 177 cancel_on_read_completed_(false),
174 defer_eof_(false), 178 defer_eof_(false),
175 received_on_will_read_(false), 179 received_on_will_read_(false),
176 received_eof_(false), 180 received_eof_(false),
177 received_response_completed_(false), 181 received_response_completed_(false),
178 total_bytes_downloaded_(0) { 182 total_bytes_downloaded_(0),
183 upload_position_(0) {
179 } 184 }
180 185
181 // If true, defers the resource load in OnWillStart. 186 // If true, defers the resource load in OnWillStart.
182 void set_defer_request_on_will_start(bool defer_request_on_will_start) { 187 void set_defer_request_on_will_start(bool defer_request_on_will_start) {
183 defer_request_on_will_start_ = defer_request_on_will_start; 188 defer_request_on_will_start_ = defer_request_on_will_start;
184 } 189 }
185 190
186 // If true, expect OnWillRead / OnReadCompleted pairs for handling 191 // If true, expect OnWillRead / OnReadCompleted pairs for handling
187 // data. Otherwise, expect OnDataDownloaded. 192 // data. Otherwise, expect OnDataDownloaded.
188 void set_expect_reads(bool expect_reads) { expect_reads_ = expect_reads; } 193 void set_expect_reads(bool expect_reads) { expect_reads_ = expect_reads; }
(...skipping 11 matching lines...) Expand all
200 bool received_response_completed() const { 205 bool received_response_completed() const {
201 return received_response_completed_; 206 return received_response_completed_;
202 } 207 }
203 const net::URLRequestStatus& status() const { return status_; } 208 const net::URLRequestStatus& status() const { return status_; }
204 int total_bytes_downloaded() const { return total_bytes_downloaded_; } 209 int total_bytes_downloaded() const { return total_bytes_downloaded_; }
205 210
206 void Resume() { 211 void Resume() {
207 controller()->Resume(); 212 controller()->Resume();
208 } 213 }
209 214
215 // Waits until OnUploadProgress is called and returns the upload position.
216 uint64 WaitForUploadProgress() {
217 wait_for_progress_loop_.reset(new base::RunLoop());
218 wait_for_progress_loop_->Run();
219 wait_for_progress_loop_.reset();
220 return upload_position_;
221 }
222
210 // ResourceHandler implementation: 223 // ResourceHandler implementation:
211 bool OnUploadProgress(uint64 position, uint64 size) override { 224 bool OnUploadProgress(uint64 position, uint64 size) override {
212 NOTREACHED(); 225 EXPECT_LE(position, size);
226 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.
227 upload_position_ = position;
228 if (wait_for_progress_loop_)
229 wait_for_progress_loop_->Quit();
213 return true; 230 return true;
214 } 231 }
215 232
216 bool OnRequestRedirected(const net::RedirectInfo& redirect_info, 233 bool OnRequestRedirected(const net::RedirectInfo& redirect_info,
217 ResourceResponse* response, 234 ResourceResponse* response,
218 bool* defer) override { 235 bool* defer) override {
219 NOTREACHED(); 236 NOTREACHED();
220 return true; 237 return true;
221 } 238 }
222 239
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 bool cancel_on_read_completed_; 311 bool cancel_on_read_completed_;
295 bool defer_eof_; 312 bool defer_eof_;
296 313
297 GURL start_url_; 314 GURL start_url_;
298 scoped_refptr<ResourceResponse> response_; 315 scoped_refptr<ResourceResponse> response_;
299 bool received_on_will_read_; 316 bool received_on_will_read_;
300 bool received_eof_; 317 bool received_eof_;
301 bool received_response_completed_; 318 bool received_response_completed_;
302 net::URLRequestStatus status_; 319 net::URLRequestStatus status_;
303 int total_bytes_downloaded_; 320 int total_bytes_downloaded_;
321 scoped_ptr<base::RunLoop> wait_for_progress_loop_;
322 uint64 upload_position_;
304 }; 323 };
305 324
306 // Test browser client that captures calls to SelectClientCertificates and 325 // Test browser client that captures calls to SelectClientCertificates and
307 // records the arguments of the most recent call for later inspection. 326 // records the arguments of the most recent call for later inspection.
308 class SelectCertificateBrowserClient : public TestContentBrowserClient { 327 class SelectCertificateBrowserClient : public TestContentBrowserClient {
309 public: 328 public:
310 SelectCertificateBrowserClient() : call_count_(0) {} 329 SelectCertificateBrowserClient() : call_count_(0) {}
311 330
312 void SelectClientCertificate( 331 void SelectClientCertificate(
313 WebContents* web_contents, 332 WebContents* web_contents,
(...skipping 30 matching lines...) Expand all
344 } 363 }
345 364
346 void SetClientCertStore(scoped_ptr<net::ClientCertStore> store) { 365 void SetClientCertStore(scoped_ptr<net::ClientCertStore> store) {
347 dummy_cert_store_ = store.Pass(); 366 dummy_cert_store_ = store.Pass();
348 } 367 }
349 368
350 private: 369 private:
351 scoped_ptr<net::ClientCertStore> dummy_cert_store_; 370 scoped_ptr<net::ClientCertStore> dummy_cert_store_;
352 }; 371 };
353 372
373 // Wraps a ChunkedUploadDataStream to behave as non-chunked to enable upload
374 // progress reporting.
375 class NonChunkedUploadDataStream : public net::UploadDataStream {
mmenke 2015/05/22 15:15:08 Great idea!
376 public:
377 explicit NonChunkedUploadDataStream(uint64 size)
378 : net::UploadDataStream(false, 0), stream_(0), size_(size) {}
379
380 void AppendData(const char* data) {
381 stream_.AppendData(data, strlen(data), false);
382 }
383
384 private:
385 int InitInternal() override {
386 SetSize(size_);
387 stream_.Init(base::Bind(&NonChunkedUploadDataStream::OnInitCompleted,
388 base::Unretained(this)));
389 return net::OK;
390 }
391
392 int ReadInternal(net::IOBuffer* buf, int buf_len) override {
393 return stream_.Read(buf, buf_len,
394 base::Bind(&NonChunkedUploadDataStream::OnReadCompleted,
395 base::Unretained(this)));
396 }
397
398 void ResetInternal() override { stream_.Reset(); }
399
400 net::ChunkedUploadDataStream stream_;
401 uint64 size_;
402
403 DISALLOW_COPY_AND_ASSIGN(NonChunkedUploadDataStream);
404 };
405
354 // Fails to create a temporary file with the given error. 406 // Fails to create a temporary file with the given error.
355 void CreateTemporaryError( 407 void CreateTemporaryError(
356 base::File::Error error, 408 base::File::Error error,
357 const CreateTemporaryFileStreamCallback& callback) { 409 const CreateTemporaryFileStreamCallback& callback) {
358 base::MessageLoop::current()->PostTask( 410 base::MessageLoop::current()->PostTask(
359 FROM_HERE, 411 FROM_HERE,
360 base::Bind(callback, error, base::Passed(scoped_ptr<net::FileStream>()), 412 base::Bind(callback, error, base::Passed(scoped_ptr<net::FileStream>()),
361 scoped_refptr<ShareableFileReference>())); 413 scoped_refptr<ShareableFileReference>()));
362 } 414 }
363 415
364 } // namespace 416 } // namespace
365 417
366 class ResourceLoaderTest : public testing::Test, 418 class ResourceLoaderTest : public testing::Test,
367 public ResourceLoaderDelegate { 419 public ResourceLoaderDelegate {
368 protected: 420 protected:
369 ResourceLoaderTest() 421 ResourceLoaderTest()
370 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), 422 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
371 resource_context_(&test_url_request_context_), 423 resource_context_(&test_url_request_context_),
372 raw_ptr_resource_handler_(NULL), 424 raw_ptr_resource_handler_(NULL),
373 raw_ptr_to_request_(NULL) { 425 raw_ptr_to_request_(NULL) {
374 test_url_request_context_.set_job_factory(&job_factory_); 426 test_url_request_context_.set_job_factory(&job_factory_);
375 } 427 }
376 428
377 GURL test_url() const { return net::URLRequestTestJob::test_url_1(); } 429 GURL test_url() const { return net::URLRequestTestJob::test_url_1(); }
378 430
379 std::string test_data() const { 431 std::string test_data() const {
380 return net::URLRequestTestJob::test_data_1(); 432 return net::URLRequestTestJob::test_data_1();
381 } 433 }
382 434
435 // Waits until upload progress reaches |target_position|
436 void WaitForUploadProgress(uint64 target_position) {
437 while (true) {
438 uint64 position = raw_ptr_resource_handler_->WaitForUploadProgress();
439 EXPECT_LE(position, target_position);
440 loader_->OnUploadProgressACK();
441 if (position == target_position)
442 break;
443 }
444 }
445
383 virtual net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() { 446 virtual net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() {
384 return net::URLRequestTestJob::CreateProtocolHandler(); 447 return net::URLRequestTestJob::CreateProtocolHandler();
385 } 448 }
386 449
387 virtual scoped_ptr<ResourceHandler> WrapResourceHandler( 450 virtual scoped_ptr<ResourceHandler> WrapResourceHandler(
388 scoped_ptr<ResourceHandlerStub> leaf_handler, 451 scoped_ptr<ResourceHandlerStub> leaf_handler,
389 net::URLRequest* request) { 452 net::URLRequest* request) {
390 return leaf_handler.Pass(); 453 return leaf_handler.Pass();
391 } 454 }
392 455
393 void SetUp() override { 456 // Replaces loader_ with a new one for |request|.
394 job_factory_.SetProtocolHandler("test", CreateProtocolHandler()); 457 void SetUpResourceLoader(scoped_ptr<net::URLRequest> request) {
458 raw_ptr_to_request_ = request.get();
395 459
396 browser_context_.reset(new TestBrowserContext());
397 scoped_refptr<SiteInstance> site_instance =
398 SiteInstance::Create(browser_context_.get());
399 web_contents_.reset(
400 TestWebContents::Create(browser_context_.get(), site_instance.get()));
401 RenderFrameHost* rfh = web_contents_->GetMainFrame(); 460 RenderFrameHost* rfh = web_contents_->GetMainFrame();
402
403 scoped_ptr<net::URLRequest> request(
404 resource_context_.GetRequestContext()->CreateRequest(
405 test_url(),
406 net::DEFAULT_PRIORITY,
407 NULL /* delegate */));
408 raw_ptr_to_request_ = request.get();
409 ResourceRequestInfo::AllocateForTesting( 461 ResourceRequestInfo::AllocateForTesting(
410 request.get(), RESOURCE_TYPE_MAIN_FRAME, &resource_context_, 462 request.get(), RESOURCE_TYPE_MAIN_FRAME, &resource_context_,
411 rfh->GetProcess()->GetID(), rfh->GetRenderViewHost()->GetRoutingID(), 463 rfh->GetProcess()->GetID(), rfh->GetRenderViewHost()->GetRoutingID(),
412 rfh->GetRoutingID(), true /* is_main_frame */, 464 rfh->GetRoutingID(), true /* is_main_frame */,
413 false /* parent_is_main_frame */, true /* allow_download */, 465 false /* parent_is_main_frame */, true /* allow_download */,
414 false /* is_async */); 466 false /* is_async */);
415 scoped_ptr<ResourceHandlerStub> resource_handler( 467 scoped_ptr<ResourceHandlerStub> resource_handler(
416 new ResourceHandlerStub(request.get())); 468 new ResourceHandlerStub(request.get()));
417 raw_ptr_resource_handler_ = resource_handler.get(); 469 raw_ptr_resource_handler_ = resource_handler.get();
418 loader_.reset(new ResourceLoader( 470 loader_.reset(new ResourceLoader(
419 request.Pass(), 471 request.Pass(),
420 WrapResourceHandler(resource_handler.Pass(), raw_ptr_to_request_), 472 WrapResourceHandler(resource_handler.Pass(), raw_ptr_to_request_),
421 this)); 473 this));
422 } 474 }
423 475
476 void SetUp() override {
477 job_factory_.SetProtocolHandler("test", CreateProtocolHandler());
478
479 browser_context_.reset(new TestBrowserContext());
480 scoped_refptr<SiteInstance> site_instance =
481 SiteInstance::Create(browser_context_.get());
482 web_contents_.reset(
483 TestWebContents::Create(browser_context_.get(), site_instance.get()));
484
485 scoped_ptr<net::URLRequest> request(
486 resource_context_.GetRequestContext()->CreateRequest(
487 test_url(),
488 net::DEFAULT_PRIORITY,
489 nullptr /* delegate */));
490 SetUpResourceLoader(request.Pass());
491 }
492
424 void TearDown() override { 493 void TearDown() override {
425 // Destroy the WebContents and pump the event loop before destroying 494 // Destroy the WebContents and pump the event loop before destroying
426 // |rvh_test_enabler_| and |thread_bundle_|. This lets asynchronous cleanup 495 // |rvh_test_enabler_| and |thread_bundle_|. This lets asynchronous cleanup
427 // tasks complete. 496 // tasks complete.
428 web_contents_.reset(); 497 web_contents_.reset();
429 base::RunLoop().RunUntilIdle(); 498 base::RunLoop().RunUntilIdle();
430 } 499 }
431 500
432 // ResourceLoaderDelegate: 501 // ResourceLoaderDelegate:
433 ResourceDispatcherHostLoginDelegate* CreateLoginDelegate( 502 ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 EXPECT_FALSE(raw_ptr_resource_handler_->received_response_completed()); 702 EXPECT_FALSE(raw_ptr_resource_handler_->received_response_completed());
634 703
635 raw_ptr_resource_handler_->Resume(); 704 raw_ptr_resource_handler_->Resume();
636 base::RunLoop().RunUntilIdle(); 705 base::RunLoop().RunUntilIdle();
637 706
638 EXPECT_TRUE(raw_ptr_resource_handler_->received_response_completed()); 707 EXPECT_TRUE(raw_ptr_resource_handler_->received_response_completed());
639 EXPECT_EQ(net::URLRequestStatus::SUCCESS, 708 EXPECT_EQ(net::URLRequestStatus::SUCCESS,
640 raw_ptr_resource_handler_->status().status()); 709 raw_ptr_resource_handler_->status().status());
641 } 710 }
642 711
712 // Tests that progress is reported correctly while uploading.
713 // TODO(andresantoso): Add test for the redirect case.
714 TEST_F(ResourceLoaderTest, UploadProgress) {
715 // Set up a test server.
716 net::test_server::EmbeddedTestServer server;
717 ASSERT_TRUE(server.InitializeAndWaitUntilReady());
718 base::FilePath path;
719 PathService::Get(content::DIR_TEST_DATA, &path);
720 server.ServeFilesFromDirectory(path);
721
722 scoped_ptr<net::URLRequest> request(
723 resource_context_.GetRequestContext()->CreateRequest(
724 server.GetURL("/title1.html"),
725 net::DEFAULT_PRIORITY,
726 nullptr /* delegate */));
727
728 // Start an upload.
729 auto stream = new NonChunkedUploadDataStream(10);
730 request->set_upload(make_scoped_ptr(stream));
731
732 SetUpResourceLoader(request.Pass());
733 loader_->StartRequest();
734
735 stream->AppendData("xx");
736 WaitForUploadProgress(2);
737
738 stream->AppendData("yyy");
739 WaitForUploadProgress(5);
740
741 stream->AppendData("zzzzz");
742 WaitForUploadProgress(10);
743 }
744
643 class ResourceLoaderRedirectToFileTest : public ResourceLoaderTest { 745 class ResourceLoaderRedirectToFileTest : public ResourceLoaderTest {
644 public: 746 public:
645 ResourceLoaderRedirectToFileTest() 747 ResourceLoaderRedirectToFileTest()
646 : file_stream_(NULL), 748 : file_stream_(NULL),
647 redirect_to_file_resource_handler_(NULL) { 749 redirect_to_file_resource_handler_(NULL) {
648 } 750 }
649 751
650 base::FilePath temp_path() const { return temp_path_; } 752 base::FilePath temp_path() const { return temp_path_; }
651 ShareableFileReference* deletable_file() const { 753 ShareableFileReference* deletable_file() const {
652 return deletable_file_.get(); 754 return deletable_file_.get();
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 ASSERT_TRUE(base::ReadFileToString(temp_path(), &contents)); 986 ASSERT_TRUE(base::ReadFileToString(temp_path(), &contents));
885 EXPECT_EQ(test_data(), contents); 987 EXPECT_EQ(test_data(), contents);
886 988
887 // Release the loader. The file should be gone now. 989 // Release the loader. The file should be gone now.
888 ReleaseLoader(); 990 ReleaseLoader();
889 base::RunLoop().RunUntilIdle(); 991 base::RunLoop().RunUntilIdle();
890 EXPECT_FALSE(base::PathExists(temp_path())); 992 EXPECT_FALSE(base::PathExists(temp_path()));
891 } 993 }
892 994
893 } // namespace content 995 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/loader/resource_loader.cc ('k') | content/browser/loader/resource_request_info_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698