OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // This file contains download browser tests that are known to be runnable | 5 // This file contains download browser tests that are known to be runnable |
6 // in a pure content context. Over time tests should be migrated here. | 6 // in a pure content context. Over time tests should be migrated here. |
7 | 7 |
| 8 #include <vector> |
| 9 |
| 10 #include "base/callback_helpers.h" |
8 #include "base/command_line.h" | 11 #include "base/command_line.h" |
9 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
10 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
11 #include "base/files/scoped_temp_dir.h" | 14 #include "base/files/scoped_temp_dir.h" |
| 15 #include "base/format_macros.h" |
12 #include "base/memory/ref_counted.h" | 16 #include "base/memory/ref_counted.h" |
13 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
14 #include "base/strings/utf_string_conversions.h" | 18 #include "base/strings/utf_string_conversions.h" |
15 #include "base/threading/platform_thread.h" | 19 #include "base/threading/platform_thread.h" |
16 #include "base/time/time.h" | 20 #include "base/time/time.h" |
17 #include "content/browser/byte_stream.h" | 21 #include "content/browser/byte_stream.h" |
18 #include "content/browser/download/download_file_factory.h" | 22 #include "content/browser/download/download_file_factory.h" |
19 #include "content/browser/download/download_file_impl.h" | 23 #include "content/browser/download/download_file_impl.h" |
20 #include "content/browser/download/download_item_impl.h" | 24 #include "content/browser/download/download_item_impl.h" |
21 #include "content/browser/download/download_manager_impl.h" | 25 #include "content/browser/download/download_manager_impl.h" |
22 #include "content/browser/download/download_resource_handler.h" | 26 #include "content/browser/download/download_resource_handler.h" |
23 #include "content/browser/web_contents/web_contents_impl.h" | 27 #include "content/browser/web_contents/web_contents_impl.h" |
24 #include "content/public/browser/power_save_blocker.h" | 28 #include "content/public/browser/power_save_blocker.h" |
25 #include "content/public/common/content_switches.h" | 29 #include "content/public/common/content_switches.h" |
26 #include "content/public/common/webplugininfo.h" | 30 #include "content/public/common/webplugininfo.h" |
27 #include "content/public/test/browser_test_utils.h" | 31 #include "content/public/test/browser_test_utils.h" |
28 #include "content/public/test/content_browser_test.h" | 32 #include "content/public/test/content_browser_test.h" |
29 #include "content/public/test/content_browser_test_utils.h" | 33 #include "content/public/test/content_browser_test_utils.h" |
30 #include "content/public/test/download_test_observer.h" | 34 #include "content/public/test/download_test_observer.h" |
| 35 #include "content/public/test/test_download_request_handler.h" |
31 #include "content/public/test/test_file_error_injector.h" | 36 #include "content/public/test/test_file_error_injector.h" |
32 #include "content/public/test/test_utils.h" | 37 #include "content/public/test/test_utils.h" |
33 #include "content/shell/browser/shell.h" | 38 #include "content/shell/browser/shell.h" |
34 #include "content/shell/browser/shell_browser_context.h" | 39 #include "content/shell/browser/shell_browser_context.h" |
35 #include "content/shell/browser/shell_download_manager_delegate.h" | 40 #include "content/shell/browser/shell_download_manager_delegate.h" |
36 #include "content/shell/browser/shell_network_delegate.h" | 41 #include "content/shell/browser/shell_network_delegate.h" |
37 #include "net/test/embedded_test_server/embedded_test_server.h" | 42 #include "net/test/embedded_test_server/embedded_test_server.h" |
38 #include "net/test/embedded_test_server/http_request.h" | 43 #include "net/test/embedded_test_server/http_request.h" |
39 #include "net/test/embedded_test_server/http_response.h" | 44 #include "net/test/embedded_test_server/http_response.h" |
40 #include "net/test/spawned_test_server/spawned_test_server.h" | |
41 #include "net/test/url_request/url_request_mock_http_job.h" | 45 #include "net/test/url_request/url_request_mock_http_job.h" |
42 #include "net/test/url_request/url_request_slow_download_job.h" | 46 #include "net/test/url_request/url_request_slow_download_job.h" |
43 #include "testing/gmock/include/gmock/gmock.h" | 47 #include "testing/gmock/include/gmock/gmock.h" |
44 #include "testing/gtest/include/gtest/gtest.h" | 48 #include "testing/gtest/include/gtest/gtest.h" |
45 #include "url/gurl.h" | 49 #include "url/gurl.h" |
46 | 50 |
47 #if defined(ENABLE_PLUGINS) | 51 #if defined(ENABLE_PLUGINS) |
48 #include "content/browser/plugin_service_impl.h" | 52 #include "content/browser/plugin_service_impl.h" |
49 #endif | 53 #endif |
50 | 54 |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 | 375 |
372 void GetDelayedCallbacks( | 376 void GetDelayedCallbacks( |
373 std::vector<DownloadOpenDelayedCallback>* callbacks) { | 377 std::vector<DownloadOpenDelayedCallback>* callbacks) { |
374 callbacks->swap(delayed_callbacks_); | 378 callbacks->swap(delayed_callbacks_); |
375 } | 379 } |
376 private: | 380 private: |
377 bool delay_download_open_; | 381 bool delay_download_open_; |
378 std::vector<DownloadOpenDelayedCallback> delayed_callbacks_; | 382 std::vector<DownloadOpenDelayedCallback> delayed_callbacks_; |
379 }; | 383 }; |
380 | 384 |
381 // Record all state transitions and byte counts on the observed download. | |
382 class RecordingDownloadObserver : DownloadItem::Observer { | |
383 public: | |
384 struct RecordStruct { | |
385 DownloadItem::DownloadState state; | |
386 int bytes_received; | |
387 }; | |
388 | |
389 typedef std::vector<RecordStruct> RecordVector; | |
390 | |
391 RecordingDownloadObserver(DownloadItem* download) | |
392 : download_(download) { | |
393 last_state_.state = download->GetState(); | |
394 last_state_.bytes_received = download->GetReceivedBytes(); | |
395 download_->AddObserver(this); | |
396 } | |
397 | |
398 ~RecordingDownloadObserver() override { RemoveObserver(); } | |
399 | |
400 void CompareToExpectedRecord(const RecordStruct expected[], size_t size) { | |
401 EXPECT_EQ(size, record_.size()); | |
402 int min = size > record_.size() ? record_.size() : size; | |
403 for (int i = 0; i < min; ++i) { | |
404 EXPECT_EQ(expected[i].state, record_[i].state) << "Iteration " << i; | |
405 EXPECT_EQ(expected[i].bytes_received, record_[i].bytes_received) | |
406 << "Iteration " << i; | |
407 } | |
408 } | |
409 | |
410 private: | |
411 void OnDownloadUpdated(DownloadItem* download) override { | |
412 DCHECK_EQ(download_, download); | |
413 DownloadItem::DownloadState state = download->GetState(); | |
414 int bytes = download->GetReceivedBytes(); | |
415 if (last_state_.state != state || last_state_.bytes_received > bytes) { | |
416 last_state_.state = state; | |
417 last_state_.bytes_received = bytes; | |
418 record_.push_back(last_state_); | |
419 } | |
420 } | |
421 | |
422 void OnDownloadDestroyed(DownloadItem* download) override { | |
423 DCHECK_EQ(download_, download); | |
424 RemoveObserver(); | |
425 } | |
426 | |
427 void RemoveObserver() { | |
428 if (download_) { | |
429 download_->RemoveObserver(this); | |
430 download_ = NULL; | |
431 } | |
432 } | |
433 | |
434 DownloadItem* download_; | |
435 RecordStruct last_state_; | |
436 RecordVector record_; | |
437 }; | |
438 | |
439 // Get the next created download. | 385 // Get the next created download. |
440 class DownloadCreateObserver : DownloadManager::Observer { | 386 class DownloadCreateObserver : DownloadManager::Observer { |
441 public: | 387 public: |
442 DownloadCreateObserver(DownloadManager* manager) | 388 DownloadCreateObserver(DownloadManager* manager) |
443 : manager_(manager), | 389 : manager_(manager), item_(NULL) { |
444 item_(NULL), | |
445 waiting_(false) { | |
446 manager_->AddObserver(this); | 390 manager_->AddObserver(this); |
447 } | 391 } |
448 | 392 |
449 ~DownloadCreateObserver() override { | 393 ~DownloadCreateObserver() override { |
450 if (manager_) | 394 if (manager_) |
451 manager_->RemoveObserver(this); | 395 manager_->RemoveObserver(this); |
452 manager_ = NULL; | 396 manager_ = NULL; |
453 } | 397 } |
454 | 398 |
455 void ManagerGoingDown(DownloadManager* manager) override { | 399 void ManagerGoingDown(DownloadManager* manager) override { |
456 DCHECK_EQ(manager_, manager); | 400 DCHECK_EQ(manager_, manager); |
457 manager_->RemoveObserver(this); | 401 manager_->RemoveObserver(this); |
458 manager_ = NULL; | 402 manager_ = NULL; |
459 } | 403 } |
460 | 404 |
461 void OnDownloadCreated(DownloadManager* manager, | 405 void OnDownloadCreated(DownloadManager* manager, |
462 DownloadItem* download) override { | 406 DownloadItem* download) override { |
463 if (!item_) | 407 if (!item_) |
464 item_ = download; | 408 item_ = download; |
465 | 409 |
466 if (waiting_) | 410 if (!completion_closure_.is_null()) |
467 base::MessageLoopForUI::current()->QuitWhenIdle(); | 411 base::ResetAndReturn(&completion_closure_).Run(); |
468 } | 412 } |
469 | 413 |
470 DownloadItem* WaitForFinished() { | 414 DownloadItem* WaitForFinished() { |
471 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 415 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
472 if (!item_) { | 416 if (!item_) { |
473 waiting_ = true; | 417 base::RunLoop run_loop; |
474 RunMessageLoop(); | 418 completion_closure_ = run_loop.QuitClosure(); |
475 waiting_ = false; | 419 run_loop.Run(); |
476 } | 420 } |
477 return item_; | 421 return item_; |
478 } | 422 } |
479 | 423 |
480 private: | 424 private: |
481 DownloadManager* manager_; | 425 DownloadManager* manager_; |
482 DownloadItem* item_; | 426 DownloadItem* item_; |
483 bool waiting_; | 427 base::Closure completion_closure_; |
484 }; | 428 }; |
485 | 429 |
486 | 430 bool IsDownloadInState(DownloadItem::DownloadState state, DownloadItem* item) { |
487 // Filter for waiting for a certain number of bytes. | 431 return item->GetState() == state; |
488 bool DataReceivedFilter(int number_of_bytes, DownloadItem* download) { | |
489 return download->GetReceivedBytes() >= number_of_bytes; | |
490 } | |
491 | |
492 // Filter for download completion. | |
493 bool DownloadCompleteFilter(DownloadItem* download) { | |
494 return download->GetState() == DownloadItem::COMPLETE; | |
495 } | |
496 | |
497 // Filter for saving the size of the download when the first IN_PROGRESS | |
498 // is hit. | |
499 bool InitialSizeFilter(int* download_size, DownloadItem* download) { | |
500 if (download->GetState() != DownloadItem::IN_PROGRESS) | |
501 return false; | |
502 | |
503 *download_size = download->GetReceivedBytes(); | |
504 return true; | |
505 } | 432 } |
506 | 433 |
507 // Request handler to be used with CreateRedirectHandler(). | 434 // Request handler to be used with CreateRedirectHandler(). |
508 scoped_ptr<net::test_server::HttpResponse> HandleRequestAndSendRedirectResponse( | 435 scoped_ptr<net::test_server::HttpResponse> HandleRequestAndSendRedirectResponse( |
509 const std::string& relative_url, | 436 const std::string& relative_url, |
510 const GURL& target_url, | 437 const GURL& target_url, |
511 const net::test_server::HttpRequest& request) { | 438 const net::test_server::HttpRequest& request) { |
512 scoped_ptr<net::test_server::BasicHttpResponse> response; | 439 scoped_ptr<net::test_server::BasicHttpResponse> response; |
513 if (request.relative_url == relative_url) { | 440 if (request.relative_url == relative_url) { |
514 response.reset(new net::test_server::BasicHttpResponse); | 441 response.reset(new net::test_server::BasicHttpResponse); |
515 response->set_code(net::HTTP_FOUND); | 442 response->set_code(net::HTTP_FOUND); |
516 response->AddCustomHeader("Location", target_url.spec()); | 443 response->AddCustomHeader("Location", target_url.spec()); |
517 } | 444 } |
518 return response.Pass(); | 445 return response.Pass(); |
519 } | 446 } |
520 | 447 |
521 // Creates a request handler for EmbeddedTestServer that responds with a HTTP | 448 // Creates a request handler for EmbeddedTestServer that responds with a HTTP |
522 // 302 redirect if the request URL matches |relative_url|. | 449 // 302 redirect if the request URL matches |relative_url|. |
523 net::EmbeddedTestServer::HandleRequestCallback CreateRedirectHandler( | 450 net::EmbeddedTestServer::HandleRequestCallback CreateRedirectHandler( |
524 const std::string& relative_url, | 451 const std::string& relative_url, |
525 const GURL& target_url) { | 452 const GURL& target_url) { |
526 return base::Bind( | 453 return base::Bind( |
527 &HandleRequestAndSendRedirectResponse, relative_url, target_url); | 454 &HandleRequestAndSendRedirectResponse, relative_url, target_url); |
528 } | 455 } |
529 | 456 |
530 // Request handler to be used with CreateBasicResponseHandler(). | 457 // Request handler to be used with CreateBasicResponseHandler(). |
531 scoped_ptr<net::test_server::HttpResponse> HandleRequestAndSendBasicResponse( | 458 scoped_ptr<net::test_server::HttpResponse> HandleRequestAndSendBasicResponse( |
532 const std::string& relative_url, | 459 const std::string& relative_url, |
| 460 const base::StringPairs& headers, |
533 const std::string& content_type, | 461 const std::string& content_type, |
534 const std::string& body, | 462 const std::string& body, |
535 const net::test_server::HttpRequest& request) { | 463 const net::test_server::HttpRequest& request) { |
536 scoped_ptr<net::test_server::BasicHttpResponse> response; | 464 scoped_ptr<net::test_server::BasicHttpResponse> response; |
537 if (request.relative_url == relative_url) { | 465 if (request.relative_url == relative_url) { |
538 response.reset(new net::test_server::BasicHttpResponse); | 466 response.reset(new net::test_server::BasicHttpResponse); |
| 467 for (const auto& pair : headers) |
| 468 response->AddCustomHeader(pair.first, pair.second); |
539 response->set_content_type(content_type); | 469 response->set_content_type(content_type); |
540 response->set_content(body); | 470 response->set_content(body); |
541 } | 471 } |
542 return response.Pass(); | 472 return response.Pass(); |
543 } | 473 } |
544 | 474 |
545 // Creates a request handler for an EmbeddedTestServer that response with an | 475 // Creates a request handler for an EmbeddedTestServer that response with an |
546 // HTTP 200 status code, a Content-Type header and a body. | 476 // HTTP 200 status code, a Content-Type header and a body. |
547 net::EmbeddedTestServer::HandleRequestCallback CreateBasicResponseHandler( | 477 net::EmbeddedTestServer::HandleRequestCallback CreateBasicResponseHandler( |
548 const std::string& relative_url, | 478 const std::string& relative_url, |
| 479 const base::StringPairs& headers, |
549 const std::string& content_type, | 480 const std::string& content_type, |
550 const std::string& body) { | 481 const std::string& body) { |
551 return base::Bind( | 482 return base::Bind(&HandleRequestAndSendBasicResponse, relative_url, headers, |
552 &HandleRequestAndSendBasicResponse, relative_url, content_type, body); | 483 content_type, body); |
553 } | 484 } |
554 | 485 |
555 } // namespace | 486 // Helper class to "flatten" handling of |
| 487 // TestDownloadRequestHandler::OnStartHandler. |
| 488 class TestRequestStartHandler { |
| 489 public: |
| 490 // Construct an OnStartHandler that can be set as the on_start_handler for |
| 491 // TestDownloadRequestHandler::Parameters. |
| 492 TestDownloadRequestHandler::OnStartHandler GetOnStartHandler() { |
| 493 EXPECT_FALSE(used_) << "GetOnStartHandler() should only be called once for " |
| 494 "an instance of TestRequestStartHandler."; |
| 495 used_ = true; |
| 496 return base::Bind(&TestRequestStartHandler::OnStartHandler, |
| 497 base::Unretained(this)); |
| 498 } |
| 499 |
| 500 // Wait until the OnStartHandlers returned in a prior call to |
| 501 // GetOnStartHandler() is invoked. |
| 502 void WaitForCallback() { |
| 503 if (response_callback_.is_null()) |
| 504 run_loop_.Run(); |
| 505 } |
| 506 |
| 507 // Respond to the OnStartHandler() invocation using |headers| and |error|. |
| 508 void RespondWith(const std::string& headers, net::Error error) { |
| 509 ASSERT_FALSE(response_callback_.is_null()); |
| 510 response_callback_.Run(headers, error); |
| 511 } |
| 512 |
| 513 // Return the headers returned from the invocation of OnStartHandler. |
| 514 const net::HttpRequestHeaders& headers() const { |
| 515 EXPECT_FALSE(response_callback_.is_null()); |
| 516 return request_headers_; |
| 517 } |
| 518 |
| 519 private: |
| 520 void OnStartHandler(const net::HttpRequestHeaders& headers, |
| 521 const TestDownloadRequestHandler::OnStartResponseCallback& |
| 522 response_callback) { |
| 523 request_headers_ = headers; |
| 524 response_callback_ = response_callback; |
| 525 if (run_loop_.running()) |
| 526 run_loop_.Quit(); |
| 527 } |
| 528 |
| 529 bool used_ = false; |
| 530 base::RunLoop run_loop_; |
| 531 net::HttpRequestHeaders request_headers_; |
| 532 TestDownloadRequestHandler::OnStartResponseCallback response_callback_; |
| 533 }; |
556 | 534 |
557 class DownloadContentTest : public ContentBrowserTest { | 535 class DownloadContentTest : public ContentBrowserTest { |
558 protected: | 536 protected: |
559 // An initial send from a website of at least this size will not be | |
560 // help up by buffering in the underlying downloads ByteStream data | |
561 // transfer. This is important because on resumption tests we wait | |
562 // until we've gotten the data we expect before allowing the test server | |
563 // to send its reset, to get around hard close semantics on the Windows | |
564 // socket layer implementation. | |
565 int GetSafeBufferChunk() const { | |
566 return (DownloadResourceHandler::kDownloadByteStreamSize / | |
567 ByteStreamWriter::kFractionBufferBeforeSending) + 1; | |
568 } | |
569 | |
570 void SetUpOnMainThread() override { | 537 void SetUpOnMainThread() override { |
571 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); | 538 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); |
572 | 539 |
573 test_delegate_.reset(new TestShellDownloadManagerDelegate()); | 540 test_delegate_.reset(new TestShellDownloadManagerDelegate()); |
574 test_delegate_->SetDownloadBehaviorForTesting(downloads_directory_.path()); | 541 test_delegate_->SetDownloadBehaviorForTesting(downloads_directory_.path()); |
575 DownloadManager* manager = DownloadManagerForShell(shell()); | 542 DownloadManager* manager = DownloadManagerForShell(shell()); |
576 manager->GetDelegate()->Shutdown(); | 543 manager->GetDelegate()->Shutdown(); |
577 manager->SetDelegate(test_delegate_.get()); | 544 manager->SetDelegate(test_delegate_.get()); |
578 test_delegate_->SetDownloadManager(manager); | 545 test_delegate_->SetDownloadManager(manager); |
579 | 546 |
(...skipping 14 matching lines...) Expand all Loading... |
594 | 561 |
595 // Create a DownloadTestObserverTerminal that will wait for the | 562 // Create a DownloadTestObserverTerminal that will wait for the |
596 // specified number of downloads to finish. | 563 // specified number of downloads to finish. |
597 DownloadTestObserver* CreateWaiter( | 564 DownloadTestObserver* CreateWaiter( |
598 Shell* shell, int num_downloads) { | 565 Shell* shell, int num_downloads) { |
599 DownloadManager* download_manager = DownloadManagerForShell(shell); | 566 DownloadManager* download_manager = DownloadManagerForShell(shell); |
600 return new DownloadTestObserverTerminal(download_manager, num_downloads, | 567 return new DownloadTestObserverTerminal(download_manager, num_downloads, |
601 DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); | 568 DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); |
602 } | 569 } |
603 | 570 |
604 // Create a DownloadTestObserverInProgress that will wait for the | 571 void WaitForInterrupt(DownloadItem* download) { |
605 // specified number of downloads to start. | 572 DownloadUpdatedObserver( |
606 DownloadCreateObserver* CreateInProgressWaiter( | 573 download, base::Bind(&IsDownloadInState, DownloadItem::INTERRUPTED)) |
607 Shell* shell, int num_downloads) { | 574 .WaitForEvent(); |
608 DownloadManager* download_manager = DownloadManagerForShell(shell); | |
609 return new DownloadCreateObserver(download_manager); | |
610 } | 575 } |
611 | 576 |
612 DownloadTestObserver* CreateInterruptedWaiter( | 577 void WaitForInProgress(DownloadItem* download) { |
613 Shell* shell, int num_downloads) { | 578 DownloadUpdatedObserver( |
614 DownloadManager* download_manager = DownloadManagerForShell(shell); | 579 download, base::Bind(&IsDownloadInState, DownloadItem::IN_PROGRESS)) |
615 return new DownloadTestObserverInterrupted(download_manager, num_downloads, | 580 .WaitForEvent(); |
616 DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); | 581 } |
| 582 |
| 583 void WaitForCompletion(DownloadItem* download) { |
| 584 DownloadUpdatedObserver( |
| 585 download, base::Bind(&IsDownloadInState, DownloadItem::COMPLETE)) |
| 586 .WaitForEvent(); |
617 } | 587 } |
618 | 588 |
619 // Note: Cannot be used with other alternative DownloadFileFactorys | 589 // Note: Cannot be used with other alternative DownloadFileFactorys |
620 void SetupEnsureNoPendingDownloads() { | 590 void SetupEnsureNoPendingDownloads() { |
621 DownloadManagerForShell(shell())->SetDownloadFileFactoryForTesting( | 591 DownloadManagerForShell(shell())->SetDownloadFileFactoryForTesting( |
622 scoped_ptr<DownloadFileFactory>( | 592 scoped_ptr<DownloadFileFactory>( |
623 new CountingDownloadFileFactory()).Pass()); | 593 new CountingDownloadFileFactory()).Pass()); |
624 } | 594 } |
625 | 595 |
626 bool EnsureNoPendingDownloads() { | 596 bool EnsureNoPendingDownloads() { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 EXPECT_EQ(value, file_contents); | 638 EXPECT_EQ(value, file_contents); |
669 if (memcmp(file_contents.c_str(), value.c_str(), expected_size) != 0) | 639 if (memcmp(file_contents.c_str(), value.c_str(), expected_size) != 0) |
670 return false; | 640 return false; |
671 | 641 |
672 return true; | 642 return true; |
673 } | 643 } |
674 | 644 |
675 // Start a download and return the item. | 645 // Start a download and return the item. |
676 DownloadItem* StartDownloadAndReturnItem(GURL url) { | 646 DownloadItem* StartDownloadAndReturnItem(GURL url) { |
677 scoped_ptr<DownloadCreateObserver> observer( | 647 scoped_ptr<DownloadCreateObserver> observer( |
678 CreateInProgressWaiter(shell(), 1)); | 648 new DownloadCreateObserver(DownloadManagerForShell(shell()))); |
679 NavigateToURL(shell(), url); | 649 shell()->LoadURL(url); |
680 observer->WaitForFinished(); | 650 return observer->WaitForFinished(); |
681 std::vector<DownloadItem*> downloads; | |
682 DownloadManagerForShell(shell())->GetAllDownloads(&downloads); | |
683 EXPECT_EQ(1u, downloads.size()); | |
684 if (1u != downloads.size()) | |
685 return NULL; | |
686 return downloads[0]; | |
687 } | 651 } |
688 | 652 |
689 // Wait for data | 653 static void ReadAndVerifyFileContents(int seed, |
690 void WaitForData(DownloadItem* download, int size) { | 654 int64_t expected_size, |
691 DownloadUpdatedObserver data_observer( | 655 const base::FilePath& path) { |
692 download, base::Bind(&DataReceivedFilter, size)); | 656 base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ); |
693 data_observer.WaitForEvent(); | 657 ASSERT_TRUE(file.IsValid()); |
694 ASSERT_EQ(size, download->GetReceivedBytes()); | 658 int64_t file_length = file.GetLength(); |
695 ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState()); | 659 ASSERT_EQ(expected_size, file_length); |
696 } | |
697 | 660 |
698 // Tell the test server to release a pending RST and confirm | 661 const int64_t kBufferSize = 64 * 1024; |
699 // that the interrupt is received properly (for download resumption | 662 std::vector<char> pattern; |
700 // testing). | 663 std::vector<char> data; |
701 void ReleaseRSTAndConfirmInterruptForResume(DownloadItem* download) { | 664 pattern.resize(kBufferSize); |
702 scoped_ptr<DownloadTestObserver> rst_observer( | 665 data.resize(kBufferSize); |
703 CreateInterruptedWaiter(shell(), 1)); | 666 for (int64_t offset = 0; offset < file_length;) { |
704 NavigateToURL(shell(), spawned_test_server()->GetURL("download-finish")); | 667 int bytes_read = file.Read(offset, &data.front(), kBufferSize); |
705 rst_observer->WaitForFinished(); | 668 ASSERT_LT(0, bytes_read); |
706 EXPECT_EQ(DownloadItem::INTERRUPTED, download->GetState()); | 669 ASSERT_GE(kBufferSize, bytes_read); |
707 } | |
708 | 670 |
709 // Confirm file status expected for the given location in a stream | 671 TestDownloadRequestHandler::GetPatternBytes(seed, offset, bytes_read, |
710 // provided by the resume test server. | 672 &pattern.front()); |
711 void ConfirmFileStatusForResume( | 673 ASSERT_EQ(0, memcmp(&pattern.front(), &data.front(), bytes_read)) |
712 DownloadItem* download, bool file_exists, | 674 << "Comparing block at offset " << offset << " and length " |
713 int received_bytes, int total_bytes, | 675 << bytes_read; |
714 const base::FilePath& expected_filename) { | 676 offset += bytes_read; |
715 // expected_filename is only known if the file exists. | |
716 ASSERT_EQ(file_exists, !expected_filename.empty()); | |
717 EXPECT_EQ(received_bytes, download->GetReceivedBytes()); | |
718 EXPECT_EQ(total_bytes, download->GetTotalBytes()); | |
719 EXPECT_EQ(expected_filename.value(), | |
720 download->GetFullPath().BaseName().value()); | |
721 EXPECT_EQ(file_exists, | |
722 (!download->GetFullPath().empty() && | |
723 base::PathExists(download->GetFullPath()))); | |
724 | |
725 if (file_exists) { | |
726 std::string file_contents; | |
727 EXPECT_TRUE(base::ReadFileToString( | |
728 download->GetFullPath(), &file_contents)); | |
729 | |
730 ASSERT_EQ(static_cast<size_t>(received_bytes), file_contents.size()); | |
731 for (int i = 0; i < received_bytes; ++i) { | |
732 EXPECT_EQ(static_cast<char>((i * 2 + 15) % 256), file_contents[i]) | |
733 << "File contents diverged at position " << i | |
734 << " for " << expected_filename.value(); | |
735 | |
736 if (static_cast<char>((i * 2 + 15) % 256) != file_contents[i]) | |
737 return; | |
738 } | |
739 } | 677 } |
740 } | 678 } |
741 | 679 |
742 private: | 680 private: |
743 static void EnsureNoPendingDownloadJobsOnIO(bool* result) { | 681 static void EnsureNoPendingDownloadJobsOnIO(bool* result) { |
744 if (net::URLRequestSlowDownloadJob::NumberOutstandingRequests()) | 682 if (net::URLRequestSlowDownloadJob::NumberOutstandingRequests()) |
745 *result = false; | 683 *result = false; |
746 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 684 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
747 base::MessageLoop::QuitWhenIdleClosure()); | 685 base::MessageLoop::QuitWhenIdleClosure()); |
748 } | 686 } |
749 | 687 |
750 // Location of the downloads directory for these tests | 688 // Location of the downloads directory for these tests |
751 base::ScopedTempDir downloads_directory_; | 689 base::ScopedTempDir downloads_directory_; |
752 scoped_ptr<TestShellDownloadManagerDelegate> test_delegate_; | 690 scoped_ptr<TestShellDownloadManagerDelegate> test_delegate_; |
753 }; | 691 }; |
754 | 692 |
| 693 } // namespace |
| 694 |
755 IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadCancelled) { | 695 IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadCancelled) { |
756 SetupEnsureNoPendingDownloads(); | 696 SetupEnsureNoPendingDownloads(); |
757 | 697 |
758 // Create a download, wait until it's started, and confirm | 698 // Create a download, wait until it's started, and confirm |
759 // we're in the expected state. | 699 // we're in the expected state. |
760 scoped_ptr<DownloadCreateObserver> observer( | 700 DownloadItem* download = StartDownloadAndReturnItem( |
761 CreateInProgressWaiter(shell(), 1)); | 701 GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl)); |
762 NavigateToURL(shell(), GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl)); | 702 ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState()); |
763 observer->WaitForFinished(); | |
764 | |
765 std::vector<DownloadItem*> downloads; | |
766 DownloadManagerForShell(shell())->GetAllDownloads(&downloads); | |
767 ASSERT_EQ(1u, downloads.size()); | |
768 ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->GetState()); | |
769 | 703 |
770 // Cancel the download and wait for download system quiesce. | 704 // Cancel the download and wait for download system quiesce. |
771 downloads[0]->Cancel(true); | 705 download->Cancel(true); |
772 scoped_refptr<DownloadTestFlushObserver> flush_observer( | 706 scoped_refptr<DownloadTestFlushObserver> flush_observer( |
773 new DownloadTestFlushObserver(DownloadManagerForShell(shell()))); | 707 new DownloadTestFlushObserver(DownloadManagerForShell(shell()))); |
774 flush_observer->WaitForFlush(); | 708 flush_observer->WaitForFlush(); |
775 | 709 |
776 // Get the important info from other threads and check it. | 710 // Get the important info from other threads and check it. |
777 EXPECT_TRUE(EnsureNoPendingDownloads()); | 711 EXPECT_TRUE(EnsureNoPendingDownloads()); |
778 } | 712 } |
779 | 713 |
780 // Check that downloading multiple (in this case, 2) files does not result in | 714 // Check that downloading multiple (in this case, 2) files does not result in |
781 // corrupted files. | 715 // corrupted files. |
782 IN_PROC_BROWSER_TEST_F(DownloadContentTest, MultiDownload) { | 716 IN_PROC_BROWSER_TEST_F(DownloadContentTest, MultiDownload) { |
783 SetupEnsureNoPendingDownloads(); | 717 SetupEnsureNoPendingDownloads(); |
784 | 718 |
785 // Create a download, wait until it's started, and confirm | 719 // Create a download, wait until it's started, and confirm |
786 // we're in the expected state. | 720 // we're in the expected state. |
787 scoped_ptr<DownloadCreateObserver> observer1( | 721 DownloadItem* download1 = StartDownloadAndReturnItem( |
788 CreateInProgressWaiter(shell(), 1)); | 722 GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl)); |
789 NavigateToURL(shell(), GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl)); | 723 ASSERT_EQ(DownloadItem::IN_PROGRESS, download1->GetState()); |
790 observer1->WaitForFinished(); | |
791 | |
792 std::vector<DownloadItem*> downloads; | |
793 DownloadManagerForShell(shell())->GetAllDownloads(&downloads); | |
794 ASSERT_EQ(1u, downloads.size()); | |
795 ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->GetState()); | |
796 DownloadItem* download1 = downloads[0]; // The only download. | |
797 | 724 |
798 // Start the second download and wait until it's done. | 725 // Start the second download and wait until it's done. |
799 GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib")); | 726 GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib")); |
800 // Download the file and wait. | 727 DownloadItem* download2 = StartDownloadAndReturnItem(url); |
801 NavigateToURLAndWaitForDownload(shell(), url, DownloadItem::COMPLETE); | 728 WaitForCompletion(download2); |
802 | |
803 // Should now have 2 items on the manager. | |
804 downloads.clear(); | |
805 DownloadManagerForShell(shell())->GetAllDownloads(&downloads); | |
806 ASSERT_EQ(2u, downloads.size()); | |
807 // We don't know the order of the downloads. | |
808 DownloadItem* download2 = downloads[(download1 == downloads[0]) ? 1 : 0]; | |
809 | 729 |
810 ASSERT_EQ(DownloadItem::IN_PROGRESS, download1->GetState()); | 730 ASSERT_EQ(DownloadItem::IN_PROGRESS, download1->GetState()); |
811 ASSERT_EQ(DownloadItem::COMPLETE, download2->GetState()); | 731 ASSERT_EQ(DownloadItem::COMPLETE, download2->GetState()); |
812 | 732 |
813 // Allow the first request to finish. | 733 // Allow the first request to finish. |
814 scoped_ptr<DownloadTestObserver> observer2(CreateWaiter(shell(), 1)); | 734 scoped_ptr<DownloadTestObserver> observer2(CreateWaiter(shell(), 1)); |
815 NavigateToURL(shell(), | 735 NavigateToURL(shell(), |
816 GURL(net::URLRequestSlowDownloadJob::kFinishDownloadUrl)); | 736 GURL(net::URLRequestSlowDownloadJob::kFinishDownloadUrl)); |
817 observer2->WaitForFinished(); // Wait for the third request. | 737 observer2->WaitForFinished(); // Wait for the third request. |
818 EXPECT_EQ(1u, observer2->NumDownloadsSeenInState(DownloadItem::COMPLETE)); | 738 EXPECT_EQ(1u, observer2->NumDownloadsSeenInState(DownloadItem::COMPLETE)); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
955 delayed_callbacks[0].Run(true); | 875 delayed_callbacks[0].Run(true); |
956 | 876 |
957 // *Now* the download should be complete. | 877 // *Now* the download should be complete. |
958 EXPECT_EQ(DownloadItem::COMPLETE, items[0]->GetState()); | 878 EXPECT_EQ(DownloadItem::COMPLETE, items[0]->GetState()); |
959 } | 879 } |
960 | 880 |
961 // Try to shutdown with a download in progress to make sure shutdown path | 881 // Try to shutdown with a download in progress to make sure shutdown path |
962 // works properly. | 882 // works properly. |
963 IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownInProgress) { | 883 IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownInProgress) { |
964 // Create a download that won't complete. | 884 // Create a download that won't complete. |
965 scoped_ptr<DownloadCreateObserver> observer( | 885 DownloadItem* download = StartDownloadAndReturnItem( |
966 CreateInProgressWaiter(shell(), 1)); | 886 GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl)); |
967 NavigateToURL(shell(), GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl)); | |
968 observer->WaitForFinished(); | |
969 | 887 |
970 // Get the item. | 888 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->GetState()); |
971 std::vector<DownloadItem*> items; | |
972 DownloadManagerForShell(shell())->GetAllDownloads(&items); | |
973 ASSERT_EQ(1u, items.size()); | |
974 EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState()); | |
975 | 889 |
976 // Shutdown the download manager and make sure we get the right | 890 // Shutdown the download manager and make sure we get the right |
977 // notifications in the right order. | 891 // notifications in the right order. |
978 StrictMock<MockDownloadItemObserver> item_observer; | 892 StrictMock<MockDownloadItemObserver> item_observer; |
979 items[0]->AddObserver(&item_observer); | 893 download->AddObserver(&item_observer); |
980 MockDownloadManagerObserver manager_observer( | 894 MockDownloadManagerObserver manager_observer( |
981 DownloadManagerForShell(shell())); | 895 DownloadManagerForShell(shell())); |
982 // Don't care about ModelChanged() events. | 896 // Don't care about ModelChanged() events. |
983 EXPECT_CALL(manager_observer, ModelChanged(_)) | 897 EXPECT_CALL(manager_observer, ModelChanged(_)) |
984 .WillRepeatedly(Return()); | 898 .WillRepeatedly(Return()); |
985 { | 899 { |
986 InSequence notifications; | 900 InSequence notifications; |
987 | 901 |
988 EXPECT_CALL(manager_observer, MockManagerGoingDown( | 902 EXPECT_CALL(manager_observer, MockManagerGoingDown( |
989 DownloadManagerForShell(shell()))) | 903 DownloadManagerForShell(shell()))) |
990 .WillOnce(Return()); | 904 .WillOnce(Return()); |
991 EXPECT_CALL(item_observer, OnDownloadUpdated( | 905 EXPECT_CALL( |
992 AllOf(items[0], | 906 item_observer, |
993 Property(&DownloadItem::GetState, DownloadItem::CANCELLED)))) | 907 OnDownloadUpdated(AllOf(download, Property(&DownloadItem::GetState, |
| 908 DownloadItem::CANCELLED)))) |
994 .WillOnce(Return()); | 909 .WillOnce(Return()); |
995 EXPECT_CALL(item_observer, OnDownloadDestroyed(items[0])) | 910 EXPECT_CALL(item_observer, OnDownloadDestroyed(download)) |
996 .WillOnce(Return()); | 911 .WillOnce(Return()); |
997 } | 912 } |
998 | 913 |
999 // See http://crbug.com/324525. If we have a refcount release/post task | 914 // See http://crbug.com/324525. If we have a refcount release/post task |
1000 // race, the second post will stall the IO thread long enough so that we'll | 915 // race, the second post will stall the IO thread long enough so that we'll |
1001 // lose the race and crash. The first stall is just to give the UI thread | 916 // lose the race and crash. The first stall is just to give the UI thread |
1002 // a chance to get the second stall onto the IO thread queue after the cancel | 917 // a chance to get the second stall onto the IO thread queue after the cancel |
1003 // message created by Shutdown and before the notification callback | 918 // message created by Shutdown and before the notification callback |
1004 // created by the IO thread in canceling the request. | 919 // created by the IO thread in canceling the request. |
1005 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 920 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
1006 base::Bind(&base::PlatformThread::Sleep, | 921 base::Bind(&base::PlatformThread::Sleep, |
1007 base::TimeDelta::FromMilliseconds(25))); | 922 base::TimeDelta::FromMilliseconds(25))); |
1008 DownloadManagerForShell(shell())->Shutdown(); | 923 DownloadManagerForShell(shell())->Shutdown(); |
1009 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 924 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
1010 base::Bind(&base::PlatformThread::Sleep, | 925 base::Bind(&base::PlatformThread::Sleep, |
1011 base::TimeDelta::FromMilliseconds(25))); | 926 base::TimeDelta::FromMilliseconds(25))); |
1012 items.clear(); | |
1013 } | 927 } |
1014 | 928 |
1015 // Try to shutdown just after we release the download file, by delaying | 929 // Try to shutdown just after we release the download file, by delaying |
1016 // release. | 930 // release. |
1017 IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownAtRelease) { | 931 IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownAtRelease) { |
1018 DownloadManagerImpl* download_manager(DownloadManagerForShell(shell())); | 932 DownloadManagerImpl* download_manager(DownloadManagerForShell(shell())); |
1019 | 933 |
1020 // Mark delegate for delayed open. | 934 // Mark delegate for delayed open. |
1021 GetDownloadManagerDelegate()->SetDelayedOpen(true); | 935 GetDownloadManagerDelegate()->SetDelayedOpen(true); |
1022 | 936 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1061 | 975 |
1062 MockDownloadItemObserver observer; | 976 MockDownloadItemObserver observer; |
1063 items[0]->AddObserver(&observer); | 977 items[0]->AddObserver(&observer); |
1064 EXPECT_CALL(observer, OnDownloadDestroyed(items[0])); | 978 EXPECT_CALL(observer, OnDownloadDestroyed(items[0])); |
1065 | 979 |
1066 // Shutdown the download manager. Mostly this is confirming a lack of | 980 // Shutdown the download manager. Mostly this is confirming a lack of |
1067 // crashes. | 981 // crashes. |
1068 DownloadManagerForShell(shell())->Shutdown(); | 982 DownloadManagerForShell(shell())->Shutdown(); |
1069 } | 983 } |
1070 | 984 |
1071 IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeInterruptedDownload) { | 985 // Test resumption with a response that contains strong validators. |
1072 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 986 IN_PROC_BROWSER_TEST_F(DownloadContentTest, Resume_WithStrongValidators) { |
1073 switches::kEnableDownloadResumption); | 987 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
1074 ASSERT_TRUE(spawned_test_server()->Start()); | 988 switches::kEnableDownloadResumption); |
1075 | 989 |
1076 GURL url = spawned_test_server()->GetURL( | 990 TestDownloadRequestHandler request_handler; |
1077 base::StringPrintf("rangereset?size=%d&rst_boundary=%d", | 991 TestDownloadRequestHandler::Parameters parameters = |
1078 GetSafeBufferChunk() * 3, GetSafeBufferChunk())); | 992 TestDownloadRequestHandler::Parameters::WithSingleInterruption(); |
1079 | 993 const TestDownloadRequestHandler::InjectedError interruption = |
1080 MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell())); | 994 parameters.injected_errors.front(); |
1081 EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); | 995 request_handler.StartServing(parameters); |
1082 | 996 |
1083 DownloadItem* download(StartDownloadAndReturnItem(url)); | 997 DownloadItem* download = StartDownloadAndReturnItem(request_handler.url()); |
1084 WaitForData(download, GetSafeBufferChunk()); | 998 WaitForInterrupt(download); |
1085 ::testing::Mock::VerifyAndClearExpectations(&dm_observer); | 999 |
1086 | 1000 ASSERT_EQ(interruption.offset, download->GetReceivedBytes()); |
1087 // Confirm resumption while in progress doesn't do anything. | 1001 ASSERT_EQ(parameters.size, download->GetTotalBytes()); |
1088 download->Resume(); | 1002 |
1089 ASSERT_EQ(GetSafeBufferChunk(), download->GetReceivedBytes()); | 1003 download->Resume(); |
1090 ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState()); | 1004 WaitForCompletion(download); |
1091 | 1005 |
1092 // Tell the server to send the RST and confirm the interrupt happens. | 1006 ASSERT_EQ(parameters.size, download->GetReceivedBytes()); |
1093 ReleaseRSTAndConfirmInterruptForResume(download); | 1007 ASSERT_EQ(parameters.size, download->GetTotalBytes()); |
1094 ConfirmFileStatusForResume( | 1008 ASSERT_NO_FATAL_FAILURE(ReadAndVerifyFileContents( |
1095 download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, | 1009 parameters.pattern_generator_seed, parameters.size, |
1096 base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); | 1010 download->GetTargetFilePath())); |
1097 | 1011 |
1098 // Resume, confirming received bytes on resumption is correct. | 1012 // Characterization risk: The next portion of the test examines the requests |
1099 // Make sure no creation calls are included. | 1013 // that were sent out while downloading our resource. These requests |
1100 EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(0); | 1014 // correspond to the requests that were generated by the browser and the |
1101 int initial_size = 0; | 1015 // downloads system and may change as implementation details change. |
1102 DownloadUpdatedObserver initial_size_observer( | 1016 TestDownloadRequestHandler::CompletedRequests requests; |
1103 download, base::Bind(&InitialSizeFilter, &initial_size)); | 1017 request_handler.GetCompletedRequestInfo(&requests); |
1104 download->Resume(); | 1018 |
1105 initial_size_observer.WaitForEvent(); | 1019 ASSERT_EQ(2u, requests.size()); |
1106 EXPECT_EQ(GetSafeBufferChunk(), initial_size); | 1020 |
1107 ::testing::Mock::VerifyAndClearExpectations(&dm_observer); | 1021 // The first request only transferrs bytes up until the interruption point. |
1108 | 1022 EXPECT_EQ(interruption.offset, requests[0].transferred_byte_count); |
1109 // and wait for expected data. | 1023 |
1110 WaitForData(download, GetSafeBufferChunk() * 2); | 1024 // The next request should only have transferred the remainder of the |
1111 | 1025 // resource. |
1112 // Tell the server to send the RST and confirm the interrupt happens. | 1026 EXPECT_EQ(parameters.size - interruption.offset, |
1113 ReleaseRSTAndConfirmInterruptForResume(download); | 1027 requests[1].transferred_byte_count); |
1114 ConfirmFileStatusForResume( | 1028 |
1115 download, true, GetSafeBufferChunk() * 2, GetSafeBufferChunk() * 3, | 1029 std::string value; |
1116 base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); | 1030 ASSERT_TRUE(requests[1].request_headers.GetHeader( |
1117 | 1031 net::HttpRequestHeaders::kIfRange, &value)); |
1118 // Resume and wait for completion. | 1032 EXPECT_EQ(parameters.etag, value); |
1119 DownloadUpdatedObserver completion_observer( | 1033 |
1120 download, base::Bind(DownloadCompleteFilter)); | 1034 ASSERT_TRUE(requests[1].request_headers.GetHeader( |
1121 download->Resume(); | 1035 net::HttpRequestHeaders::kRange, &value)); |
1122 completion_observer.WaitForEvent(); | 1036 EXPECT_EQ(base::StringPrintf("bytes=%" PRId64 "-", interruption.offset), |
1123 | 1037 value); |
1124 ConfirmFileStatusForResume( | 1038 } |
1125 download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3, | 1039 |
1126 base::FilePath(FILE_PATH_LITERAL("rangereset"))); | 1040 // A partial resumption results in an HTTP 200 response. I.e. the server ignored |
1127 | 1041 // the range request and sent the entire resource instead. For If-Range requests |
1128 // Confirm resumption while complete doesn't do anything. | 1042 // (as opposed to If-Match), the behavior for a precondition failure is also to |
1129 download->Resume(); | 1043 // respond with a 200. So this test case covers both validation failure and |
1130 ASSERT_EQ(GetSafeBufferChunk() * 3, download->GetReceivedBytes()); | 1044 // ignoring the range request. |
1131 ASSERT_EQ(DownloadItem::COMPLETE, download->GetState()); | |
1132 RunAllPendingInMessageLoop(); | |
1133 ASSERT_EQ(GetSafeBufferChunk() * 3, download->GetReceivedBytes()); | |
1134 ASSERT_EQ(DownloadItem::COMPLETE, download->GetState()); | |
1135 } | |
1136 | |
1137 // Confirm restart fallback happens if a range request is bounced. | |
1138 IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeInterruptedDownloadNoRange) { | |
1139 base::CommandLine::ForCurrentProcess()->AppendSwitch( | |
1140 switches::kEnableDownloadResumption); | |
1141 ASSERT_TRUE(spawned_test_server()->Start()); | |
1142 | |
1143 // Auto-restart if server doesn't handle ranges. | |
1144 GURL url = spawned_test_server()->GetURL(base::StringPrintf( | |
1145 // First download hits an RST, rest don't, no ranges. | |
1146 "rangereset?size=%d&rst_boundary=%d&" | |
1147 "token=NoRange&rst_limit=1&bounce_range", | |
1148 GetSafeBufferChunk() * 3, GetSafeBufferChunk())); | |
1149 | |
1150 // Start the download and wait for first data chunk. | |
1151 DownloadItem* download(StartDownloadAndReturnItem(url)); | |
1152 WaitForData(download, GetSafeBufferChunk()); | |
1153 | |
1154 RecordingDownloadObserver recorder(download); | |
1155 | |
1156 ReleaseRSTAndConfirmInterruptForResume(download); | |
1157 ConfirmFileStatusForResume( | |
1158 download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, | |
1159 base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); | |
1160 | |
1161 DownloadUpdatedObserver completion_observer( | |
1162 download, base::Bind(DownloadCompleteFilter)); | |
1163 download->Resume(); | |
1164 completion_observer.WaitForEvent(); | |
1165 | |
1166 ConfirmFileStatusForResume( | |
1167 download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3, | |
1168 base::FilePath(FILE_PATH_LITERAL("rangereset"))); | |
1169 | |
1170 static const RecordingDownloadObserver::RecordStruct expected_record[] = { | |
1171 // Result of RST | |
1172 {DownloadItem::INTERRUPTED, GetSafeBufferChunk()}, | |
1173 // Starting continuation | |
1174 {DownloadItem::IN_PROGRESS, GetSafeBufferChunk()}, | |
1175 // Notification of receiving whole file. | |
1176 {DownloadItem::IN_PROGRESS, 0}, | |
1177 // Completion. | |
1178 {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3}, | |
1179 }; | |
1180 | |
1181 recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record)); | |
1182 } | |
1183 | |
1184 // Confirm we don't try to resume if we don't have a verifier. | |
1185 IN_PROC_BROWSER_TEST_F(DownloadContentTest, | 1045 IN_PROC_BROWSER_TEST_F(DownloadContentTest, |
1186 ResumeInterruptedDownloadNoVerifiers) { | 1046 Resume_RestartIfNotPartialResponse) { |
1187 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 1047 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
1188 switches::kEnableDownloadResumption); | 1048 switches::kEnableDownloadResumption); |
1189 ASSERT_TRUE(spawned_test_server()->Start()); | 1049 const int kOriginalPatternGeneratorSeed = 1; |
1190 | 1050 const int kNewPatternGeneratorSeed = 2; |
1191 GURL url = spawned_test_server()->GetURL(base::StringPrintf( | 1051 |
1192 // First download hits an RST, rest don't, no verifiers. | 1052 TestDownloadRequestHandler::Parameters parameters = |
1193 "rangereset?size=%d&rst_boundary=%d&" | 1053 TestDownloadRequestHandler::Parameters::WithSingleInterruption(); |
1194 "token=NoRange&rst_limit=1&no_verifiers", | 1054 parameters.pattern_generator_seed = kOriginalPatternGeneratorSeed; |
1195 GetSafeBufferChunk() * 3, GetSafeBufferChunk())); | 1055 const TestDownloadRequestHandler::InjectedError interruption = |
1196 | 1056 parameters.injected_errors.front(); |
1197 // Start the download and wait for first data chunk. | 1057 |
1198 DownloadItem* download(StartDownloadAndReturnItem(url)); | 1058 TestDownloadRequestHandler request_handler; |
1199 WaitForData(download, GetSafeBufferChunk()); | 1059 request_handler.StartServing(parameters); |
1200 | 1060 |
1201 RecordingDownloadObserver recorder(download); | 1061 DownloadItem* download = StartDownloadAndReturnItem(request_handler.url()); |
1202 | 1062 WaitForInterrupt(download); |
1203 ReleaseRSTAndConfirmInterruptForResume(download); | 1063 |
1204 ConfirmFileStatusForResume( | 1064 ASSERT_EQ(interruption.offset, download->GetReceivedBytes()); |
1205 download, false, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, | 1065 ASSERT_EQ(parameters.size, download->GetTotalBytes()); |
1206 base::FilePath()); | 1066 |
1207 | 1067 parameters = TestDownloadRequestHandler::Parameters(); |
1208 DownloadUpdatedObserver completion_observer( | 1068 parameters.support_byte_ranges = false; |
1209 download, base::Bind(DownloadCompleteFilter)); | 1069 parameters.pattern_generator_seed = kNewPatternGeneratorSeed; |
1210 download->Resume(); | 1070 request_handler.StartServing(parameters); |
1211 completion_observer.WaitForEvent(); | 1071 |
1212 | 1072 download->Resume(); |
1213 ConfirmFileStatusForResume( | 1073 WaitForCompletion(download); |
1214 download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3, | 1074 |
1215 base::FilePath(FILE_PATH_LITERAL("rangereset"))); | 1075 ASSERT_EQ(parameters.size, download->GetReceivedBytes()); |
1216 | 1076 ASSERT_EQ(parameters.size, download->GetTotalBytes()); |
1217 static const RecordingDownloadObserver::RecordStruct expected_record[] = { | 1077 ASSERT_NO_FATAL_FAILURE( |
1218 // Result of RST | 1078 ReadAndVerifyFileContents(kNewPatternGeneratorSeed, parameters.size, |
1219 {DownloadItem::INTERRUPTED, GetSafeBufferChunk()}, | 1079 download->GetTargetFilePath())); |
1220 // Restart for lack of verifiers | 1080 |
1221 {DownloadItem::IN_PROGRESS, 0}, | 1081 // When the downloads system sees the full response, it should accept the |
1222 // Completion. | 1082 // response without restarting. On the network, we should deterministically |
1223 {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3}, | 1083 // see two requests: |
1224 }; | 1084 // * The original request which transfers upto our interruption point. |
1225 | 1085 // * The resumption attempt, which receives the entire entity. |
1226 recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record)); | 1086 TestDownloadRequestHandler::CompletedRequests requests; |
1227 } | 1087 request_handler.GetCompletedRequestInfo(&requests); |
1228 | 1088 |
1229 IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithDeletedFile) { | 1089 ASSERT_EQ(2u, requests.size()); |
1230 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 1090 |
1231 switches::kEnableDownloadResumption); | 1091 // The first request only transfers data up to the interruption point. |
1232 ASSERT_TRUE(spawned_test_server()->Start()); | 1092 EXPECT_EQ(interruption.offset, requests[0].transferred_byte_count); |
1233 | 1093 |
1234 GURL url = spawned_test_server()->GetURL(base::StringPrintf( | 1094 // The second request transfers the entire response. |
1235 // First download hits an RST, rest don't | 1095 EXPECT_EQ(parameters.size, requests[1].transferred_byte_count); |
1236 "rangereset?size=%d&rst_boundary=%d&" | 1096 |
1237 "token=NoRange&rst_limit=1", | 1097 std::string value; |
1238 GetSafeBufferChunk() * 3, GetSafeBufferChunk())); | 1098 ASSERT_TRUE(requests[1].request_headers.GetHeader( |
1239 | 1099 net::HttpRequestHeaders::kIfRange, &value)); |
1240 // Start the download and wait for first data chunk. | 1100 EXPECT_EQ(parameters.etag, value); |
1241 DownloadItem* download(StartDownloadAndReturnItem(url)); | 1101 |
1242 WaitForData(download, GetSafeBufferChunk()); | 1102 ASSERT_TRUE(requests[1].request_headers.GetHeader( |
1243 | 1103 net::HttpRequestHeaders::kRange, &value)); |
1244 RecordingDownloadObserver recorder(download); | 1104 EXPECT_EQ(base::StringPrintf("bytes=%" PRId64 "-", interruption.offset), |
1245 | 1105 value); |
1246 ReleaseRSTAndConfirmInterruptForResume(download); | 1106 } |
1247 ConfirmFileStatusForResume( | 1107 |
1248 download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, | 1108 // Confirm we restart if we don't have a verifier. |
1249 base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); | 1109 IN_PROC_BROWSER_TEST_F(DownloadContentTest, Resume_RestartIfNoETag) { |
| 1110 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 1111 switches::kEnableDownloadResumption); |
| 1112 const int kOriginalPatternGeneratorSeed = 1; |
| 1113 const int kNewPatternGeneratorSeed = 2; |
| 1114 |
| 1115 TestDownloadRequestHandler::Parameters parameters = |
| 1116 TestDownloadRequestHandler::Parameters::WithSingleInterruption(); |
| 1117 ASSERT_EQ(1u, parameters.injected_errors.size()); |
| 1118 parameters.etag.clear(); |
| 1119 parameters.pattern_generator_seed = kOriginalPatternGeneratorSeed; |
| 1120 |
| 1121 TestDownloadRequestHandler request_handler; |
| 1122 request_handler.StartServing(parameters); |
| 1123 DownloadItem* download = StartDownloadAndReturnItem(request_handler.url()); |
| 1124 WaitForInterrupt(download); |
| 1125 |
| 1126 parameters.pattern_generator_seed = kNewPatternGeneratorSeed; |
| 1127 parameters.ClearInjectedErrors(); |
| 1128 request_handler.StartServing(parameters); |
| 1129 |
| 1130 download->Resume(); |
| 1131 WaitForCompletion(download); |
| 1132 |
| 1133 ASSERT_EQ(parameters.size, download->GetReceivedBytes()); |
| 1134 ASSERT_EQ(parameters.size, download->GetTotalBytes()); |
| 1135 ASSERT_NO_FATAL_FAILURE( |
| 1136 ReadAndVerifyFileContents(kNewPatternGeneratorSeed, parameters.size, |
| 1137 download->GetTargetFilePath())); |
| 1138 |
| 1139 TestDownloadRequestHandler::CompletedRequests requests; |
| 1140 request_handler.GetCompletedRequestInfo(&requests); |
| 1141 |
| 1142 // Neither If-Range nor Range headers should be present in the second request. |
| 1143 ASSERT_EQ(2u, requests.size()); |
| 1144 std::string value; |
| 1145 EXPECT_FALSE(requests[1].request_headers.GetHeader( |
| 1146 net::HttpRequestHeaders::kIfRange, &value)); |
| 1147 EXPECT_FALSE(requests[1].request_headers.GetHeader( |
| 1148 net::HttpRequestHeaders::kRange, &value)); |
| 1149 } |
| 1150 |
| 1151 // Partial file goes missing before the download is resumed. The download should |
| 1152 // restart. |
| 1153 IN_PROC_BROWSER_TEST_F(DownloadContentTest, Resume_RestartIfNoPartialFile) { |
| 1154 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 1155 switches::kEnableDownloadResumption); |
| 1156 TestDownloadRequestHandler::Parameters parameters = |
| 1157 TestDownloadRequestHandler::Parameters::WithSingleInterruption(); |
| 1158 |
| 1159 TestDownloadRequestHandler request_handler; |
| 1160 request_handler.StartServing(parameters); |
| 1161 DownloadItem* download = StartDownloadAndReturnItem(request_handler.url()); |
| 1162 WaitForInterrupt(download); |
1250 | 1163 |
1251 // Delete the intermediate file. | 1164 // Delete the intermediate file. |
1252 base::DeleteFile(download->GetFullPath(), false); | 1165 ASSERT_TRUE(base::PathExists(download->GetFullPath())); |
1253 | 1166 ASSERT_TRUE(base::DeleteFile(download->GetFullPath(), false)); |
1254 DownloadUpdatedObserver completion_observer( | 1167 |
1255 download, base::Bind(DownloadCompleteFilter)); | 1168 parameters.ClearInjectedErrors(); |
1256 download->Resume(); | 1169 request_handler.StartServing(parameters); |
1257 completion_observer.WaitForEvent(); | 1170 |
1258 | 1171 download->Resume(); |
1259 ConfirmFileStatusForResume( | 1172 WaitForCompletion(download); |
1260 download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3, | 1173 |
1261 base::FilePath(FILE_PATH_LITERAL("rangereset"))); | 1174 ASSERT_EQ(parameters.size, download->GetReceivedBytes()); |
1262 | 1175 ASSERT_EQ(parameters.size, download->GetTotalBytes()); |
1263 static const RecordingDownloadObserver::RecordStruct expected_record[] = { | 1176 ASSERT_NO_FATAL_FAILURE(ReadAndVerifyFileContents( |
1264 // Result of RST | 1177 parameters.pattern_generator_seed, parameters.size, |
1265 {DownloadItem::INTERRUPTED, GetSafeBufferChunk()}, | 1178 download->GetTargetFilePath())); |
1266 // Starting continuation | 1179 } |
1267 {DownloadItem::IN_PROGRESS, GetSafeBufferChunk()}, | 1180 |
1268 // Error because file isn't there. | 1181 IN_PROC_BROWSER_TEST_F(DownloadContentTest, Resume_RecoverFromInitFileError) { |
1269 {DownloadItem::INTERRUPTED, 0}, | 1182 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
1270 // Restart. | 1183 switches::kEnableDownloadResumption); |
1271 {DownloadItem::IN_PROGRESS, 0}, | 1184 TestDownloadRequestHandler request_handler; |
1272 // Completion. | 1185 request_handler.StartServing(TestDownloadRequestHandler::Parameters()); |
1273 {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3}, | |
1274 }; | |
1275 | |
1276 recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record)); | |
1277 } | |
1278 | |
1279 IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileInitError) { | |
1280 base::CommandLine::ForCurrentProcess()->AppendSwitch( | |
1281 switches::kEnableDownloadResumption); | |
1282 GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib")); | |
1283 | 1186 |
1284 // Setup the error injector. | 1187 // Setup the error injector. |
1285 scoped_refptr<TestFileErrorInjector> injector( | 1188 scoped_refptr<TestFileErrorInjector> injector( |
1286 TestFileErrorInjector::Create(DownloadManagerForShell(shell()))); | 1189 TestFileErrorInjector::Create(DownloadManagerForShell(shell()))); |
1287 | 1190 |
1288 TestFileErrorInjector::FileErrorInfo err = { | 1191 const TestFileErrorInjector::FileErrorInfo err = { |
1289 url.spec(), | 1192 request_handler.url().spec(), |
1290 TestFileErrorInjector::FILE_OPERATION_INITIALIZE, | 1193 TestFileErrorInjector::FILE_OPERATION_INITIALIZE, 0, |
1291 0, | 1194 DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE}; |
1292 DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE | |
1293 }; | |
1294 injector->AddError(err); | 1195 injector->AddError(err); |
1295 injector->InjectErrors(); | 1196 injector->InjectErrors(); |
1296 | 1197 |
1297 // Start and watch for interrupt. | 1198 // Start and watch for interrupt. |
1298 scoped_ptr<DownloadTestObserver> int_observer( | 1199 DownloadItem* download(StartDownloadAndReturnItem(request_handler.url())); |
1299 CreateInterruptedWaiter(shell(), 1)); | 1200 WaitForInterrupt(download); |
1300 DownloadItem* download(StartDownloadAndReturnItem(url)); | |
1301 int_observer->WaitForFinished(); | |
1302 ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState()); | 1201 ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState()); |
1303 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE, | 1202 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE, |
1304 download->GetLastReason()); | 1203 download->GetLastReason()); |
1305 EXPECT_EQ(0, download->GetReceivedBytes()); | 1204 EXPECT_EQ(0, download->GetReceivedBytes()); |
1306 EXPECT_TRUE(download->GetFullPath().empty()); | 1205 EXPECT_TRUE(download->GetFullPath().empty()); |
1307 EXPECT_TRUE(download->GetTargetFilePath().empty()); | 1206 EXPECT_TRUE(download->GetTargetFilePath().empty()); |
1308 | 1207 |
1309 // We need to make sure that any cross-thread downloads communication has | 1208 // We need to make sure that any cross-thread downloads communication has |
1310 // quiesced before clearing and injecting the new errors, as the | 1209 // quiesced before clearing and injecting the new errors, as the |
1311 // InjectErrors() routine alters the currently in use download file | 1210 // InjectErrors() routine alters the currently in use download file |
1312 // factory, which is a file thread object. | 1211 // factory, which is a file thread object. |
1313 RunAllPendingInMessageLoop(BrowserThread::FILE); | 1212 RunAllPendingInMessageLoop(BrowserThread::FILE); |
1314 RunAllPendingInMessageLoop(); | 1213 RunAllPendingInMessageLoop(); |
1315 | 1214 |
1316 // Clear the old errors list. | 1215 // Clear the old errors list. |
1317 injector->ClearErrors(); | 1216 injector->ClearErrors(); |
1318 injector->InjectErrors(); | 1217 injector->InjectErrors(); |
1319 | 1218 |
1320 // Resume and watch completion. | 1219 // Resume and watch completion. |
1321 DownloadUpdatedObserver completion_observer( | |
1322 download, base::Bind(DownloadCompleteFilter)); | |
1323 download->Resume(); | 1220 download->Resume(); |
1324 completion_observer.WaitForEvent(); | 1221 WaitForCompletion(download); |
1325 EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE); | 1222 EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE); |
1326 } | 1223 } |
1327 | 1224 |
1328 IN_PROC_BROWSER_TEST_F(DownloadContentTest, | 1225 IN_PROC_BROWSER_TEST_F(DownloadContentTest, |
1329 ResumeWithFileIntermediateRenameError) { | 1226 Resume_RecoverFromIntermediateFileRenameError) { |
1330 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 1227 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
1331 switches::kEnableDownloadResumption); | 1228 switches::kEnableDownloadResumption); |
1332 GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib")); | 1229 TestDownloadRequestHandler request_handler; |
| 1230 request_handler.StartServing(TestDownloadRequestHandler::Parameters()); |
1333 | 1231 |
1334 // Setup the error injector. | 1232 // Setup the error injector. |
1335 scoped_refptr<TestFileErrorInjector> injector( | 1233 scoped_refptr<TestFileErrorInjector> injector( |
1336 TestFileErrorInjector::Create(DownloadManagerForShell(shell()))); | 1234 TestFileErrorInjector::Create(DownloadManagerForShell(shell()))); |
1337 | 1235 |
1338 TestFileErrorInjector::FileErrorInfo err = { | 1236 const TestFileErrorInjector::FileErrorInfo err = { |
1339 url.spec(), | 1237 request_handler.url().spec(), |
1340 TestFileErrorInjector::FILE_OPERATION_RENAME_UNIQUIFY, | 1238 TestFileErrorInjector::FILE_OPERATION_RENAME_UNIQUIFY, 0, |
1341 0, | 1239 DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE}; |
1342 DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE | |
1343 }; | |
1344 injector->AddError(err); | 1240 injector->AddError(err); |
1345 injector->InjectErrors(); | 1241 injector->InjectErrors(); |
1346 | 1242 |
1347 // Start and watch for interrupt. | 1243 // Start and watch for interrupt. |
1348 scoped_ptr<DownloadTestObserver> int_observer( | 1244 DownloadItem* download(StartDownloadAndReturnItem(request_handler.url())); |
1349 CreateInterruptedWaiter(shell(), 1)); | 1245 WaitForInterrupt(download); |
1350 DownloadItem* download(StartDownloadAndReturnItem(url)); | |
1351 int_observer->WaitForFinished(); | |
1352 ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState()); | 1246 ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState()); |
1353 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE, | 1247 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE, |
1354 download->GetLastReason()); | 1248 download->GetLastReason()); |
1355 EXPECT_TRUE(download->GetFullPath().empty()); | 1249 EXPECT_TRUE(download->GetFullPath().empty()); |
1356 // Target path will have been set after file name determination. GetFullPath() | 1250 // Target path will have been set after file name determination. GetFullPath() |
1357 // being empty is sufficient to signal that filename determination needs to be | 1251 // being empty is sufficient to signal that filename determination needs to be |
1358 // redone. | 1252 // redone. |
1359 EXPECT_FALSE(download->GetTargetFilePath().empty()); | 1253 EXPECT_FALSE(download->GetTargetFilePath().empty()); |
1360 | 1254 |
1361 // We need to make sure that any cross-thread downloads communication has | 1255 // We need to make sure that any cross-thread downloads communication has |
1362 // quiesced before clearing and injecting the new errors, as the | 1256 // quiesced before clearing and injecting the new errors, as the |
1363 // InjectErrors() routine alters the currently in use download file | 1257 // InjectErrors() routine alters the currently in use download file |
1364 // factory, which is a file thread object. | 1258 // factory, which is a file thread object. |
1365 RunAllPendingInMessageLoop(BrowserThread::FILE); | 1259 RunAllPendingInMessageLoop(BrowserThread::FILE); |
1366 RunAllPendingInMessageLoop(); | 1260 RunAllPendingInMessageLoop(); |
1367 | 1261 |
1368 // Clear the old errors list. | 1262 // Clear the old errors list. |
1369 injector->ClearErrors(); | 1263 injector->ClearErrors(); |
1370 injector->InjectErrors(); | 1264 injector->InjectErrors(); |
1371 | 1265 |
1372 // Resume and watch completion. | |
1373 DownloadUpdatedObserver completion_observer( | |
1374 download, base::Bind(DownloadCompleteFilter)); | |
1375 download->Resume(); | 1266 download->Resume(); |
1376 completion_observer.WaitForEvent(); | 1267 WaitForCompletion(download); |
1377 EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE); | 1268 EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE); |
1378 } | 1269 } |
1379 | 1270 |
1380 IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileFinalRenameError) { | 1271 IN_PROC_BROWSER_TEST_F(DownloadContentTest, |
| 1272 Resume_RecoverFromFinalRenameError) { |
1381 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 1273 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
1382 switches::kEnableDownloadResumption); | 1274 switches::kEnableDownloadResumption); |
1383 GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib")); | 1275 TestDownloadRequestHandler request_handler; |
| 1276 request_handler.StartServing(TestDownloadRequestHandler::Parameters()); |
1384 | 1277 |
1385 // Setup the error injector. | 1278 // Setup the error injector. |
1386 scoped_refptr<TestFileErrorInjector> injector( | 1279 scoped_refptr<TestFileErrorInjector> injector( |
1387 TestFileErrorInjector::Create(DownloadManagerForShell(shell()))); | 1280 TestFileErrorInjector::Create(DownloadManagerForShell(shell()))); |
1388 | 1281 |
1389 DownloadManagerForShell(shell())->RemoveAllDownloads(); | 1282 DownloadManagerForShell(shell())->RemoveAllDownloads(); |
1390 TestFileErrorInjector::FileErrorInfo err = { | 1283 TestFileErrorInjector::FileErrorInfo err = { |
1391 url.spec(), | 1284 request_handler.url().spec(), |
1392 TestFileErrorInjector::FILE_OPERATION_RENAME_ANNOTATE, | 1285 TestFileErrorInjector::FILE_OPERATION_RENAME_ANNOTATE, 0, |
1393 0, | 1286 DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE}; |
1394 DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE | |
1395 }; | |
1396 injector->AddError(err); | 1287 injector->AddError(err); |
1397 injector->InjectErrors(); | 1288 injector->InjectErrors(); |
1398 | 1289 |
1399 // Start and watch for interrupt. | 1290 // Start and watch for interrupt. |
1400 scoped_ptr<DownloadTestObserver> int_observer( | 1291 DownloadItem* download(StartDownloadAndReturnItem(request_handler.url())); |
1401 CreateInterruptedWaiter(shell(), 1)); | 1292 WaitForInterrupt(download); |
1402 DownloadItem* download(StartDownloadAndReturnItem(url)); | |
1403 int_observer->WaitForFinished(); | |
1404 ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState()); | 1293 ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState()); |
1405 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE, | 1294 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE, |
1406 download->GetLastReason()); | 1295 download->GetLastReason()); |
1407 EXPECT_TRUE(download->GetFullPath().empty()); | 1296 EXPECT_TRUE(download->GetFullPath().empty()); |
1408 // Target path should still be intact. | 1297 // Target path should still be intact. |
1409 EXPECT_FALSE(download->GetTargetFilePath().empty()); | 1298 EXPECT_FALSE(download->GetTargetFilePath().empty()); |
1410 | 1299 |
1411 // We need to make sure that any cross-thread downloads communication has | 1300 // We need to make sure that any cross-thread downloads communication has |
1412 // quiesced before clearing and injecting the new errors, as the | 1301 // quiesced before clearing and injecting the new errors, as the |
1413 // InjectErrors() routine alters the currently in use download file | 1302 // InjectErrors() routine alters the currently in use download file |
1414 // factory, which is a file thread object. | 1303 // factory, which is a file thread object. |
1415 RunAllPendingInMessageLoop(BrowserThread::FILE); | 1304 RunAllPendingInMessageLoop(BrowserThread::FILE); |
1416 RunAllPendingInMessageLoop(); | 1305 RunAllPendingInMessageLoop(); |
1417 | 1306 |
1418 // Clear the old errors list. | 1307 // Clear the old errors list. |
1419 injector->ClearErrors(); | 1308 injector->ClearErrors(); |
1420 injector->InjectErrors(); | 1309 injector->InjectErrors(); |
1421 | 1310 |
1422 // Resume and watch completion. | |
1423 DownloadUpdatedObserver completion_observer( | |
1424 download, base::Bind(DownloadCompleteFilter)); | |
1425 download->Resume(); | 1311 download->Resume(); |
1426 completion_observer.WaitForEvent(); | 1312 WaitForCompletion(download); |
1427 EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE); | 1313 EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE); |
1428 } | 1314 } |
1429 | 1315 |
1430 // An interrupted download should remove the intermediate file when it is | 1316 // An interrupted download should remove the intermediate file when it is |
1431 // cancelled. | 1317 // cancelled. |
1432 IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelInterruptedDownload) { | 1318 IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelInterruptedDownload) { |
1433 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 1319 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
1434 switches::kEnableDownloadResumption); | 1320 switches::kEnableDownloadResumption); |
1435 ASSERT_TRUE(spawned_test_server()->Start()); | 1321 TestDownloadRequestHandler request_handler; |
| 1322 request_handler.StartServing( |
| 1323 TestDownloadRequestHandler::Parameters::WithSingleInterruption()); |
1436 | 1324 |
1437 GURL url1 = spawned_test_server()->GetURL( | 1325 DownloadItem* download = StartDownloadAndReturnItem(request_handler.url()); |
1438 base::StringPrintf("rangereset?size=%d&rst_boundary=%d", | 1326 WaitForInterrupt(download); |
1439 GetSafeBufferChunk() * 3, GetSafeBufferChunk())); | |
1440 | 1327 |
1441 DownloadItem* download(StartDownloadAndReturnItem(url1)); | 1328 base::FilePath intermediate_path = download->GetFullPath(); |
1442 WaitForData(download, GetSafeBufferChunk()); | |
1443 | |
1444 ReleaseRSTAndConfirmInterruptForResume(download); | |
1445 ConfirmFileStatusForResume( | |
1446 download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, | |
1447 base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); | |
1448 | |
1449 base::FilePath intermediate_path(download->GetFullPath()); | |
1450 ASSERT_FALSE(intermediate_path.empty()); | 1329 ASSERT_FALSE(intermediate_path.empty()); |
1451 EXPECT_TRUE(base::PathExists(intermediate_path)); | 1330 ASSERT_TRUE(base::PathExists(intermediate_path)); |
1452 | 1331 |
1453 download->Cancel(true /* user_cancel */); | 1332 download->Cancel(true /* user_cancel */); |
1454 RunAllPendingInMessageLoop(BrowserThread::FILE); | 1333 RunAllPendingInMessageLoop(BrowserThread::FILE); |
1455 RunAllPendingInMessageLoop(); | 1334 RunAllPendingInMessageLoop(); |
1456 | 1335 |
1457 // The intermediate file should now be gone. | 1336 // The intermediate file should now be gone. |
1458 EXPECT_FALSE(base::PathExists(intermediate_path)); | 1337 EXPECT_FALSE(base::PathExists(intermediate_path)); |
1459 EXPECT_TRUE(download->GetFullPath().empty()); | 1338 EXPECT_TRUE(download->GetFullPath().empty()); |
1460 } | 1339 } |
1461 | 1340 |
1462 IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveDownload) { | 1341 IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveInterruptedDownload) { |
1463 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 1342 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
1464 switches::kEnableDownloadResumption); | 1343 switches::kEnableDownloadResumption); |
1465 ASSERT_TRUE(spawned_test_server()->Start()); | 1344 TestDownloadRequestHandler request_handler; |
| 1345 request_handler.StartServing( |
| 1346 TestDownloadRequestHandler::Parameters::WithSingleInterruption()); |
1466 | 1347 |
1467 // An interrupted download should remove the intermediate file when it is | 1348 DownloadItem* download = StartDownloadAndReturnItem(request_handler.url()); |
1468 // removed. | 1349 WaitForInterrupt(download); |
1469 { | |
1470 GURL url1 = spawned_test_server()->GetURL( | |
1471 base::StringPrintf("rangereset?size=%d&rst_boundary=%d", | |
1472 GetSafeBufferChunk() * 3, GetSafeBufferChunk())); | |
1473 | 1350 |
1474 DownloadItem* download(StartDownloadAndReturnItem(url1)); | 1351 base::FilePath intermediate_path = download->GetFullPath(); |
1475 WaitForData(download, GetSafeBufferChunk()); | 1352 ASSERT_FALSE(intermediate_path.empty()); |
1476 ReleaseRSTAndConfirmInterruptForResume(download); | 1353 ASSERT_TRUE(base::PathExists(intermediate_path)); |
1477 ConfirmFileStatusForResume( | |
1478 download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, | |
1479 base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); | |
1480 | 1354 |
1481 base::FilePath intermediate_path(download->GetFullPath()); | 1355 download->Remove(); |
1482 ASSERT_FALSE(intermediate_path.empty()); | 1356 RunAllPendingInMessageLoop(BrowserThread::FILE); |
1483 EXPECT_TRUE(base::PathExists(intermediate_path)); | 1357 RunAllPendingInMessageLoop(); |
1484 | 1358 |
1485 download->Remove(); | 1359 // The intermediate file should now be gone. |
1486 RunAllPendingInMessageLoop(BrowserThread::FILE); | 1360 EXPECT_FALSE(base::PathExists(intermediate_path)); |
1487 RunAllPendingInMessageLoop(); | 1361 } |
1488 | 1362 |
1489 // The intermediate file should now be gone. | 1363 IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveCompletedDownload) { |
1490 EXPECT_FALSE(base::PathExists(intermediate_path)); | |
1491 } | |
1492 | |
1493 // A completed download shouldn't delete the downloaded file when it is | 1364 // A completed download shouldn't delete the downloaded file when it is |
1494 // removed. | 1365 // removed. |
1495 { | 1366 TestDownloadRequestHandler request_handler; |
1496 // Start the second download and wait until it's done. | 1367 request_handler.StartServing(TestDownloadRequestHandler::Parameters()); |
1497 GURL url2(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib")); | 1368 scoped_ptr<DownloadTestObserver> completion_observer( |
1498 scoped_ptr<DownloadTestObserver> completion_observer( | 1369 CreateWaiter(shell(), 1)); |
1499 CreateWaiter(shell(), 1)); | 1370 DownloadItem* download(StartDownloadAndReturnItem(request_handler.url())); |
1500 DownloadItem* download(StartDownloadAndReturnItem(url2)); | 1371 completion_observer->WaitForFinished(); |
1501 completion_observer->WaitForFinished(); | |
1502 | 1372 |
1503 // The target path should exist. | 1373 // The target path should exist. |
1504 base::FilePath target_path(download->GetTargetFilePath()); | 1374 base::FilePath target_path(download->GetTargetFilePath()); |
1505 EXPECT_TRUE(base::PathExists(target_path)); | 1375 EXPECT_TRUE(base::PathExists(target_path)); |
1506 download->Remove(); | 1376 download->Remove(); |
1507 RunAllPendingInMessageLoop(BrowserThread::FILE); | 1377 RunAllPendingInMessageLoop(BrowserThread::FILE); |
1508 RunAllPendingInMessageLoop(); | 1378 RunAllPendingInMessageLoop(); |
1509 | 1379 |
1510 // The file should still exist. | 1380 // The file should still exist. |
1511 EXPECT_TRUE(base::PathExists(target_path)); | 1381 EXPECT_TRUE(base::PathExists(target_path)); |
1512 } | |
1513 } | 1382 } |
1514 | 1383 |
1515 IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveResumingDownload) { | 1384 IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveResumingDownload) { |
1516 SetupEnsureNoPendingDownloads(); | |
1517 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 1385 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
1518 switches::kEnableDownloadResumption); | 1386 switches::kEnableDownloadResumption); |
1519 ASSERT_TRUE(spawned_test_server()->Start()); | 1387 TestDownloadRequestHandler::Parameters parameters = |
| 1388 TestDownloadRequestHandler::Parameters::WithSingleInterruption(); |
| 1389 TestDownloadRequestHandler request_handler; |
| 1390 request_handler.StartServing(parameters); |
1520 | 1391 |
1521 GURL url = spawned_test_server()->GetURL( | 1392 DownloadItem* download = StartDownloadAndReturnItem(request_handler.url()); |
1522 base::StringPrintf("rangereset?size=%d&rst_boundary=%d", | 1393 WaitForInterrupt(download); |
1523 GetSafeBufferChunk() * 3, GetSafeBufferChunk())); | |
1524 | |
1525 MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell())); | |
1526 EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); | |
1527 | |
1528 DownloadItem* download(StartDownloadAndReturnItem(url)); | |
1529 WaitForData(download, GetSafeBufferChunk()); | |
1530 ::testing::Mock::VerifyAndClearExpectations(&dm_observer); | |
1531 | |
1532 // Tell the server to send the RST and confirm the interrupt happens. | |
1533 ReleaseRSTAndConfirmInterruptForResume(download); | |
1534 ConfirmFileStatusForResume( | |
1535 download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, | |
1536 base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); | |
1537 | 1394 |
1538 base::FilePath intermediate_path(download->GetFullPath()); | 1395 base::FilePath intermediate_path(download->GetFullPath()); |
1539 ASSERT_FALSE(intermediate_path.empty()); | 1396 ASSERT_FALSE(intermediate_path.empty()); |
1540 EXPECT_TRUE(base::PathExists(intermediate_path)); | 1397 EXPECT_TRUE(base::PathExists(intermediate_path)); |
1541 | 1398 |
1542 // Resume and remove download. We expect only a single OnDownloadCreated() | 1399 // Resume and remove download. We expect only a single OnDownloadCreated() |
1543 // call, and that's for the second download created below. | 1400 // call, and that's for the second download created below. |
| 1401 MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell())); |
1544 EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); | 1402 EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); |
| 1403 |
| 1404 TestRequestStartHandler request_start_handler; |
| 1405 parameters.on_start_handler = request_start_handler.GetOnStartHandler(); |
| 1406 request_handler.StartServing(parameters); |
| 1407 |
1545 download->Resume(); | 1408 download->Resume(); |
| 1409 request_start_handler.WaitForCallback(); |
| 1410 |
| 1411 // At this point, the download resumption request has been sent out, but the |
| 1412 // reponse hasn't been received yet. |
1546 download->Remove(); | 1413 download->Remove(); |
1547 | 1414 |
| 1415 request_start_handler.RespondWith(std::string(), net::OK); |
| 1416 |
1548 // The intermediate file should now be gone. | 1417 // The intermediate file should now be gone. |
1549 RunAllPendingInMessageLoop(BrowserThread::FILE); | 1418 RunAllPendingInMessageLoop(BrowserThread::FILE); |
1550 RunAllPendingInMessageLoop(); | 1419 RunAllPendingInMessageLoop(); |
1551 EXPECT_FALSE(base::PathExists(intermediate_path)); | 1420 EXPECT_FALSE(base::PathExists(intermediate_path)); |
1552 | 1421 |
1553 // Start the second download and wait until it's done. The test server is | 1422 parameters.ClearInjectedErrors(); |
1554 // single threaded. The response to this download request should follow the | 1423 parameters.on_start_handler.Reset(); |
1555 // response to the previous resumption request. | 1424 request_handler.StartServing(parameters); |
1556 GURL url2( | |
1557 spawned_test_server()->GetURL("rangereset?size=100&rst_limit=0&token=x")); | |
1558 NavigateToURLAndWaitForDownload(shell(), url2, DownloadItem::COMPLETE); | |
1559 | 1425 |
| 1426 // Start the second download and wait until it's done. This exercises the |
| 1427 // entire downloads stack and effectively flushes all of our worker threads. |
| 1428 // We are testing whether the URL request created in the previous |
| 1429 // DownloadItem::Resume() call reulted in a new download or not. |
| 1430 NavigateToURLAndWaitForDownload(shell(), request_handler.url(), |
| 1431 DownloadItem::COMPLETE); |
1560 EXPECT_TRUE(EnsureNoPendingDownloads()); | 1432 EXPECT_TRUE(EnsureNoPendingDownloads()); |
1561 } | 1433 } |
1562 | 1434 |
1563 IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelResumingDownload) { | 1435 IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelResumingDownload) { |
1564 SetupEnsureNoPendingDownloads(); | |
1565 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 1436 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
1566 switches::kEnableDownloadResumption); | 1437 switches::kEnableDownloadResumption); |
1567 ASSERT_TRUE(spawned_test_server()->Start()); | 1438 TestDownloadRequestHandler::Parameters parameters = |
| 1439 TestDownloadRequestHandler::Parameters::WithSingleInterruption(); |
| 1440 TestDownloadRequestHandler request_handler; |
| 1441 request_handler.StartServing(parameters); |
1568 | 1442 |
1569 GURL url = spawned_test_server()->GetURL( | 1443 DownloadItem* download = StartDownloadAndReturnItem(request_handler.url()); |
1570 base::StringPrintf("rangereset?size=%d&rst_boundary=%d", | 1444 WaitForInterrupt(download); |
1571 GetSafeBufferChunk() * 3, GetSafeBufferChunk())); | |
1572 | |
1573 MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell())); | |
1574 EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); | |
1575 | |
1576 DownloadItem* download(StartDownloadAndReturnItem(url)); | |
1577 WaitForData(download, GetSafeBufferChunk()); | |
1578 ::testing::Mock::VerifyAndClearExpectations(&dm_observer); | |
1579 | |
1580 // Tell the server to send the RST and confirm the interrupt happens. | |
1581 ReleaseRSTAndConfirmInterruptForResume(download); | |
1582 ConfirmFileStatusForResume( | |
1583 download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, | |
1584 base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); | |
1585 | 1445 |
1586 base::FilePath intermediate_path(download->GetFullPath()); | 1446 base::FilePath intermediate_path(download->GetFullPath()); |
1587 ASSERT_FALSE(intermediate_path.empty()); | 1447 ASSERT_FALSE(intermediate_path.empty()); |
1588 EXPECT_TRUE(base::PathExists(intermediate_path)); | 1448 EXPECT_TRUE(base::PathExists(intermediate_path)); |
1589 | 1449 |
1590 // Resume and cancel download. We expect only a single OnDownloadCreated() | 1450 // Resume and remove download. We expect only a single OnDownloadCreated() |
1591 // call, and that's for the second download created below. | 1451 // call, and that's for the second download created below. |
| 1452 MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell())); |
1592 EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); | 1453 EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); |
| 1454 |
| 1455 TestRequestStartHandler request_start_handler; |
| 1456 parameters.on_start_handler = request_start_handler.GetOnStartHandler(); |
| 1457 request_handler.StartServing(parameters); |
| 1458 |
1593 download->Resume(); | 1459 download->Resume(); |
1594 download->Cancel(true); | 1460 request_start_handler.WaitForCallback(); |
| 1461 |
| 1462 // At this point, the download item has initiated a network request for the |
| 1463 // resumption attempt, but hasn't received a response yet. |
| 1464 download->Cancel(true /* user_cancel */); |
| 1465 |
| 1466 request_start_handler.RespondWith(std::string(), net::OK); |
1595 | 1467 |
1596 // The intermediate file should now be gone. | 1468 // The intermediate file should now be gone. |
| 1469 RunAllPendingInMessageLoop(BrowserThread::IO); |
1597 RunAllPendingInMessageLoop(BrowserThread::FILE); | 1470 RunAllPendingInMessageLoop(BrowserThread::FILE); |
1598 RunAllPendingInMessageLoop(); | 1471 RunAllPendingInMessageLoop(); |
1599 EXPECT_FALSE(base::PathExists(intermediate_path)); | 1472 EXPECT_FALSE(base::PathExists(intermediate_path)); |
1600 EXPECT_TRUE(download->GetFullPath().empty()); | |
1601 | 1473 |
1602 // Start the second download and wait until it's done. The test server is | 1474 parameters.ClearInjectedErrors(); |
1603 // single threaded. The response to this download request should follow the | 1475 parameters.on_start_handler.Reset(); |
1604 // response to the previous resumption request. | 1476 request_handler.StartServing(parameters); |
1605 GURL url2( | |
1606 spawned_test_server()->GetURL("rangereset?size=100&rst_limit=0&token=x")); | |
1607 NavigateToURLAndWaitForDownload(shell(), url2, DownloadItem::COMPLETE); | |
1608 | 1477 |
| 1478 // Start the second download and wait until it's done. This exercises the |
| 1479 // entire downloads stack and effectively flushes all of our worker threads. |
| 1480 // We are testing whether the URL request created in the previous |
| 1481 // DownloadItem::Resume() call reulted in a new download or not. |
| 1482 NavigateToURLAndWaitForDownload(shell(), request_handler.url(), |
| 1483 DownloadItem::COMPLETE); |
1609 EXPECT_TRUE(EnsureNoPendingDownloads()); | 1484 EXPECT_TRUE(EnsureNoPendingDownloads()); |
1610 } | 1485 } |
1611 | 1486 |
1612 // Check that the cookie policy is correctly updated when downloading a file | 1487 // Check that the cookie policy is correctly updated when downloading a file |
1613 // that redirects cross origin. | 1488 // that redirects cross origin. |
1614 IN_PROC_BROWSER_TEST_F(DownloadContentTest, CookiePolicy) { | 1489 IN_PROC_BROWSER_TEST_F(DownloadContentTest, CookiePolicy) { |
1615 ASSERT_TRUE(spawned_test_server()->Start()); | 1490 net::EmbeddedTestServer origin_one; |
1616 net::HostPortPair host_port = spawned_test_server()->host_port_pair(); | 1491 net::EmbeddedTestServer origin_two; |
1617 DCHECK_EQ(host_port.host(), std::string("127.0.0.1")); | 1492 ASSERT_TRUE(origin_one.Start()); |
| 1493 ASSERT_TRUE(origin_two.Start()); |
1618 | 1494 |
1619 // Block third-party cookies. | 1495 // Block third-party cookies. |
1620 ShellNetworkDelegate::SetAcceptAllCookies(false); | 1496 ShellNetworkDelegate::SetAcceptAllCookies(false); |
1621 | 1497 |
1622 // |url| redirects to a different origin |download| which tries to set a | 1498 // |url| redirects to a different origin |download| which tries to set a |
1623 // cookie. | 1499 // cookie. |
1624 std::string download(base::StringPrintf( | 1500 base::StringPairs cookie_header; |
1625 "http://localhost:%d/set-cookie?A=B", host_port.port())); | 1501 cookie_header.push_back( |
1626 GURL url(spawned_test_server()->GetURL("server-redirect?" + download)); | 1502 std::make_pair(std::string("Set-Cookie"), std::string("A=B"))); |
| 1503 origin_one.RegisterRequestHandler(CreateBasicResponseHandler( |
| 1504 "/foo", cookie_header, "application/octet-stream", "abcd")); |
| 1505 origin_two.RegisterRequestHandler( |
| 1506 CreateRedirectHandler("/bar", origin_one.GetURL("/foo"))); |
1627 | 1507 |
1628 // Download the file. | 1508 // Download the file. |
1629 SetupEnsureNoPendingDownloads(); | 1509 SetupEnsureNoPendingDownloads(); |
1630 scoped_ptr<DownloadUrlParameters> dl_params( | 1510 scoped_ptr<DownloadUrlParameters> download_parameters( |
1631 DownloadUrlParameters::FromWebContents(shell()->web_contents(), url)); | 1511 DownloadUrlParameters::FromWebContents(shell()->web_contents(), |
| 1512 origin_two.GetURL("/bar"))); |
1632 scoped_ptr<DownloadTestObserver> observer(CreateWaiter(shell(), 1)); | 1513 scoped_ptr<DownloadTestObserver> observer(CreateWaiter(shell(), 1)); |
1633 DownloadManagerForShell(shell())->DownloadUrl(dl_params.Pass()); | 1514 DownloadManagerForShell(shell())->DownloadUrl(download_parameters.Pass()); |
1634 observer->WaitForFinished(); | 1515 observer->WaitForFinished(); |
1635 | 1516 |
1636 // Get the important info from other threads and check it. | 1517 // Get the important info from other threads and check it. |
1637 EXPECT_TRUE(EnsureNoPendingDownloads()); | 1518 EXPECT_TRUE(EnsureNoPendingDownloads()); |
1638 | 1519 |
1639 std::vector<DownloadItem*> downloads; | 1520 std::vector<DownloadItem*> downloads; |
1640 DownloadManagerForShell(shell())->GetAllDownloads(&downloads); | 1521 DownloadManagerForShell(shell())->GetAllDownloads(&downloads); |
1641 ASSERT_EQ(1u, downloads.size()); | 1522 ASSERT_EQ(1u, downloads.size()); |
1642 ASSERT_EQ(DownloadItem::COMPLETE, downloads[0]->GetState()); | 1523 ASSERT_EQ(DownloadItem::COMPLETE, downloads[0]->GetState()); |
1643 | 1524 |
1644 // Check that the cookies were correctly set. | 1525 // Check that the cookies were correctly set. |
1645 EXPECT_EQ("A=B", | 1526 EXPECT_EQ("A=B", |
1646 content::GetCookies(shell()->web_contents()->GetBrowserContext(), | 1527 content::GetCookies(shell()->web_contents()->GetBrowserContext(), |
1647 GURL(download))); | 1528 origin_one.GetURL("/"))); |
1648 } | 1529 } |
1649 | 1530 |
1650 // A filename suggestion specified via a @download attribute should not be | 1531 // A filename suggestion specified via a @download attribute should not be |
1651 // effective if the final download URL is in another origin from the original | 1532 // effective if the final download URL is in another origin from the original |
1652 // download URL. | 1533 // download URL. |
1653 IN_PROC_BROWSER_TEST_F(DownloadContentTest, | 1534 IN_PROC_BROWSER_TEST_F(DownloadContentTest, |
1654 DownloadAttributeCrossOriginRedirect) { | 1535 DownloadAttributeCrossOriginRedirect) { |
1655 net::EmbeddedTestServer origin_one; | 1536 net::EmbeddedTestServer origin_one; |
1656 net::EmbeddedTestServer origin_two; | 1537 net::EmbeddedTestServer origin_two; |
1657 ASSERT_TRUE(origin_one.Start()); | 1538 ASSERT_TRUE(origin_one.Start()); |
(...skipping 11 matching lines...) Expand all Loading... |
1669 GURL download_url = origin_one.GetURL("/ping"); | 1550 GURL download_url = origin_one.GetURL("/ping"); |
1670 GURL referrer_url = origin_one.GetURL( | 1551 GURL referrer_url = origin_one.GetURL( |
1671 std::string("/download-attribute.html?target=") + download_url.spec()); | 1552 std::string("/download-attribute.html?target=") + download_url.spec()); |
1672 | 1553 |
1673 // <origin_one>/download-attribute.html initiates a download of | 1554 // <origin_one>/download-attribute.html initiates a download of |
1674 // <origin_one>/ping, which redirects to <origin_two>/download. | 1555 // <origin_one>/ping, which redirects to <origin_two>/download. |
1675 origin_one.ServeFilesFromDirectory(GetTestFilePath("download", "")); | 1556 origin_one.ServeFilesFromDirectory(GetTestFilePath("download", "")); |
1676 origin_one.RegisterRequestHandler( | 1557 origin_one.RegisterRequestHandler( |
1677 CreateRedirectHandler("/ping", origin_two.GetURL("/download"))); | 1558 CreateRedirectHandler("/ping", origin_two.GetURL("/download"))); |
1678 origin_two.RegisterRequestHandler(CreateBasicResponseHandler( | 1559 origin_two.RegisterRequestHandler(CreateBasicResponseHandler( |
1679 "/download", "application/octet-stream", "Hello")); | 1560 "/download", base::StringPairs(), "application/octet-stream", "Hello")); |
1680 | 1561 |
1681 NavigateToURLAndWaitForDownload( | 1562 NavigateToURLAndWaitForDownload( |
1682 shell(), referrer_url, DownloadItem::COMPLETE); | 1563 shell(), referrer_url, DownloadItem::COMPLETE); |
1683 | 1564 |
1684 std::vector<DownloadItem*> downloads; | 1565 std::vector<DownloadItem*> downloads; |
1685 DownloadManagerForShell(shell())->GetAllDownloads(&downloads); | 1566 DownloadManagerForShell(shell())->GetAllDownloads(&downloads); |
1686 ASSERT_EQ(1u, downloads.size()); | 1567 ASSERT_EQ(1u, downloads.size()); |
1687 | 1568 |
1688 EXPECT_EQ(FILE_PATH_LITERAL("download"), | 1569 EXPECT_EQ(FILE_PATH_LITERAL("download"), |
1689 downloads[0]->GetTargetFilePath().BaseName().value()); | 1570 downloads[0]->GetTargetFilePath().BaseName().value()); |
(...skipping 27 matching lines...) Expand all Loading... |
1717 origin_one.ServeFilesFromDirectory(GetTestFilePath("download", "")); | 1598 origin_one.ServeFilesFromDirectory(GetTestFilePath("download", "")); |
1718 | 1599 |
1719 // <origin_one>/download-attribute.html initiates a download of | 1600 // <origin_one>/download-attribute.html initiates a download of |
1720 // <origin_one>/ping, which redirects to <origin_two>/pong, and then finally | 1601 // <origin_one>/ping, which redirects to <origin_two>/pong, and then finally |
1721 // to <origin_one>/download. | 1602 // to <origin_one>/download. |
1722 origin_one.RegisterRequestHandler( | 1603 origin_one.RegisterRequestHandler( |
1723 CreateRedirectHandler("/ping", origin_two.GetURL("/pong"))); | 1604 CreateRedirectHandler("/ping", origin_two.GetURL("/pong"))); |
1724 origin_two.RegisterRequestHandler( | 1605 origin_two.RegisterRequestHandler( |
1725 CreateRedirectHandler("/pong", origin_one.GetURL("/download"))); | 1606 CreateRedirectHandler("/pong", origin_one.GetURL("/download"))); |
1726 origin_one.RegisterRequestHandler(CreateBasicResponseHandler( | 1607 origin_one.RegisterRequestHandler(CreateBasicResponseHandler( |
1727 "/download", "application/octet-stream", "Hello")); | 1608 "/download", base::StringPairs(), "application/octet-stream", "Hello")); |
1728 | 1609 |
1729 NavigateToURLAndWaitForDownload( | 1610 NavigateToURLAndWaitForDownload( |
1730 shell(), referrer_url, DownloadItem::COMPLETE); | 1611 shell(), referrer_url, DownloadItem::COMPLETE); |
1731 | 1612 |
1732 std::vector<DownloadItem*> downloads; | 1613 std::vector<DownloadItem*> downloads; |
1733 DownloadManagerForShell(shell())->GetAllDownloads(&downloads); | 1614 DownloadManagerForShell(shell())->GetAllDownloads(&downloads); |
1734 ASSERT_EQ(1u, downloads.size()); | 1615 ASSERT_EQ(1u, downloads.size()); |
1735 | 1616 |
1736 EXPECT_EQ(FILE_PATH_LITERAL("suggested-filename"), | 1617 EXPECT_EQ(FILE_PATH_LITERAL("suggested-filename"), |
1737 downloads[0]->GetTargetFilePath().BaseName().value()); | 1618 downloads[0]->GetTargetFilePath().BaseName().value()); |
1738 ASSERT_TRUE(origin_one.ShutdownAndWaitUntilComplete()); | 1619 ASSERT_TRUE(origin_one.ShutdownAndWaitUntilComplete()); |
1739 ASSERT_TRUE(origin_two.ShutdownAndWaitUntilComplete()); | 1620 ASSERT_TRUE(origin_two.ShutdownAndWaitUntilComplete()); |
1740 } | 1621 } |
1741 | 1622 |
1742 // The file empty.bin is served with a MIME type of application/octet-stream. | 1623 // The file empty.bin is served with a MIME type of application/octet-stream. |
1743 // The content body is empty. Make sure this case is handled properly and we | 1624 // The content body is empty. Make sure this case is handled properly and we |
1744 // don't regress on http://crbug.com/320394. | 1625 // don't regress on http://crbug.com/320394. |
1745 IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadGZipWithNoContent) { | 1626 IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadGZipWithNoContent) { |
1746 net::EmbeddedTestServer test_server; | 1627 GURL url = net::URLRequestMockHTTPJob::GetMockUrl("empty.bin"); |
1747 ASSERT_TRUE(test_server.Start()); | |
1748 | |
1749 GURL url = test_server.GetURL("/empty.bin"); | |
1750 test_server.ServeFilesFromDirectory(GetTestFilePath("download", "")); | |
1751 | |
1752 NavigateToURLAndWaitForDownload(shell(), url, DownloadItem::COMPLETE); | 1628 NavigateToURLAndWaitForDownload(shell(), url, DownloadItem::COMPLETE); |
1753 // That's it. This should work without crashing. | 1629 // That's it. This should work without crashing. |
1754 } | 1630 } |
1755 | 1631 |
1756 IN_PROC_BROWSER_TEST_F(DownloadContentTest, Spam) { | 1632 IN_PROC_BROWSER_TEST_F(DownloadContentTest, Spam) { |
1757 ASSERT_TRUE(embedded_test_server()->Start()); | 1633 ASSERT_TRUE(embedded_test_server()->Start()); |
1758 | 1634 |
1759 NavigateToURLAndWaitForDownload( | 1635 NavigateToURLAndWaitForDownload( |
1760 shell(), | 1636 shell(), |
1761 embedded_test_server()->GetURL( | 1637 embedded_test_server()->GetURL( |
1762 "/download/double-content-disposition.txt"), | 1638 "/download/double-content-disposition.txt"), |
1763 DownloadItem::COMPLETE); | 1639 DownloadItem::COMPLETE); |
1764 | 1640 |
1765 std::vector<DownloadItem*> downloads; | 1641 std::vector<DownloadItem*> downloads; |
1766 DownloadManagerForShell(shell())->GetAllDownloads(&downloads); | 1642 DownloadManagerForShell(shell())->GetAllDownloads(&downloads); |
1767 ASSERT_EQ(1u, downloads.size()); | 1643 ASSERT_EQ(1u, downloads.size()); |
1768 | 1644 |
1769 EXPECT_EQ(FILE_PATH_LITERAL("Jumboshrimp.txt"), | 1645 EXPECT_EQ(FILE_PATH_LITERAL("Jumboshrimp.txt"), |
1770 downloads[0]->GetTargetFilePath().BaseName().value()); | 1646 downloads[0]->GetTargetFilePath().BaseName().value()); |
1771 } | 1647 } |
1772 | 1648 |
1773 } // namespace content | 1649 } // namespace content |
OLD | NEW |