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

Side by Side Diff: content/browser/download/download_browsertest.cc

Issue 11571025: Initial CL for Downloads resumption. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Ready for review. Created 7 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "base/command_line.h"
8 #include "base/file_path.h" 9 #include "base/file_path.h"
9 #include "base/file_util.h" 10 #include "base/file_util.h"
10 #include "base/files/scoped_temp_dir.h" 11 #include "base/files/scoped_temp_dir.h"
11 #include "content/browser/download/download_file_factory.h" 12 #include "content/browser/download/download_file_factory.h"
12 #include "content/browser/download/download_file_impl.h" 13 #include "content/browser/download/download_file_impl.h"
13 #include "content/browser/download/download_item_impl.h" 14 #include "content/browser/download/download_item_impl.h"
14 #include "content/browser/download/download_manager_impl.h" 15 #include "content/browser/download/download_manager_impl.h"
15 #include "content/browser/power_save_blocker.h" 16 #include "content/browser/power_save_blocker.h"
16 #include "content/browser/web_contents/web_contents_impl.h" 17 #include "content/browser/web_contents/web_contents_impl.h"
18 #include "content/public/common/content_switches.h"
17 #include "content/public/test/download_test_observer.h" 19 #include "content/public/test/download_test_observer.h"
18 #include "content/public/test/test_utils.h" 20 #include "content/public/test/test_utils.h"
19 #include "content/shell/shell.h" 21 #include "content/shell/shell.h"
20 #include "content/shell/shell_browser_context.h" 22 #include "content/shell/shell_browser_context.h"
21 #include "content/shell/shell_download_manager_delegate.h" 23 #include "content/shell/shell_download_manager_delegate.h"
22 #include "content/test/content_browser_test.h" 24 #include "content/test/content_browser_test.h"
23 #include "content/test/content_browser_test_utils.h" 25 #include "content/test/content_browser_test_utils.h"
24 #include "content/test/net/url_request_mock_http_job.h" 26 #include "content/test/net/url_request_mock_http_job.h"
25 #include "content/test/net/url_request_slow_download_job.h" 27 #include "content/test/net/url_request_slow_download_job.h"
26 #include "googleurl/src/gurl.h" 28 #include "googleurl/src/gurl.h"
29 #include "net/test/test_server.h"
27 #include "testing/gmock/include/gmock/gmock.h" 30 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h" 31 #include "testing/gtest/include/gtest/gtest.h"
29 32
30 using ::testing::_; 33 using ::testing::_;
31 using ::testing::AllOf; 34 using ::testing::AllOf;
32 using ::testing::Field; 35 using ::testing::Field;
33 using ::testing::InSequence; 36 using ::testing::InSequence;
34 using ::testing::Property; 37 using ::testing::Property;
35 using ::testing::Return; 38 using ::testing::Return;
36 using ::testing::StrictMock; 39 using ::testing::StrictMock;
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 std::vector<DownloadOpenDelayedCallback>* callbacks) { 339 std::vector<DownloadOpenDelayedCallback>* callbacks) {
337 callbacks->swap(delayed_callbacks_); 340 callbacks->swap(delayed_callbacks_);
338 } 341 }
339 private: 342 private:
340 virtual ~TestShellDownloadManagerDelegate() {} 343 virtual ~TestShellDownloadManagerDelegate() {}
341 344
342 bool delay_download_open_; 345 bool delay_download_open_;
343 std::vector<DownloadOpenDelayedCallback> delayed_callbacks_; 346 std::vector<DownloadOpenDelayedCallback> delayed_callbacks_;
344 }; 347 };
345 348
349 // Filter for handling resumption; don't return true until
350 // we see first a transition to IN_PROGRESS then a transition to
351 // some final state. Since this is a stateful filter, we
352 // must provide a flag in which to store the state; that flag
353 // must be false on initialization.
354 bool DownloadResumptionFilter(bool* state_flag, DownloadItem* download) {
ahendrickson 2012/12/27 17:10:27 I may be mis-remembering the coding style, but sho
Randy Smith (Not in Mondays) 2012/12/27 17:51:00 Unfortunately, I don't have the option. The Downl
355 if (*state_flag && DownloadItem::IN_PROGRESS != download->GetState()) {
356 return true;
357 }
358
359 if (DownloadItem::IN_PROGRESS == download->GetState())
360 *state_flag = true;
361
362 return false;
363 }
364
365 // Filter for waiting for intermediate file rename.
366 bool IntermediateFileRenameFilter(DownloadItem* download) {
367 return !download->GetFullPath().empty();
368 }
369
346 } // namespace 370 } // namespace
347 371
348 class DownloadContentTest : public ContentBrowserTest { 372 class DownloadContentTest : public ContentBrowserTest {
349 protected: 373 protected:
350 virtual void SetUpOnMainThread() OVERRIDE { 374 virtual void SetUpOnMainThread() OVERRIDE {
351 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); 375 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
352 376
353 TestShellDownloadManagerDelegate* delegate = 377 TestShellDownloadManagerDelegate* delegate =
354 new TestShellDownloadManagerDelegate(); 378 new TestShellDownloadManagerDelegate();
355 delegate->SetDownloadBehaviorForTesting(downloads_directory_.path()); 379 delegate->SetDownloadBehaviorForTesting(downloads_directory_.path());
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 bool EnsureNoPendingDownloads() { 423 bool EnsureNoPendingDownloads() {
400 bool result = true; 424 bool result = true;
401 BrowserThread::PostTask( 425 BrowserThread::PostTask(
402 BrowserThread::IO, FROM_HERE, 426 BrowserThread::IO, FROM_HERE,
403 base::Bind(&EnsureNoPendingDownloadJobsOnIO, &result)); 427 base::Bind(&EnsureNoPendingDownloadJobsOnIO, &result));
404 MessageLoop::current()->Run(); 428 MessageLoop::current()->Run();
405 return result && 429 return result &&
406 (CountingDownloadFile::GetNumberActiveFilesFromFileThread() == 0); 430 (CountingDownloadFile::GetNumberActiveFilesFromFileThread() == 0);
407 } 431 }
408 432
409 void DownloadAndWait(Shell* shell, const GURL& url) { 433 void DownloadAndWait(Shell* shell, const GURL& url,
434 DownloadItem::DownloadState expected_terminal_state) {
410 scoped_ptr<DownloadTestObserver> observer(CreateWaiter(shell, 1)); 435 scoped_ptr<DownloadTestObserver> observer(CreateWaiter(shell, 1));
411 NavigateToURL(shell, url); 436 NavigateToURL(shell, url);
412 observer->WaitForFinished(); 437 observer->WaitForFinished();
413 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE)); 438 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(expected_terminal_state));
414 } 439 }
415 440
416 // Checks that |path| is has |file_size| bytes, and matches the |value| 441 // Checks that |path| is has |file_size| bytes, and matches the |value|
417 // string. 442 // string.
418 bool VerifyFile(const FilePath& path, 443 bool VerifyFile(const FilePath& path,
419 const std::string& value, 444 const std::string& value,
420 const int64 file_size) { 445 const int64 file_size) {
421 std::string file_contents; 446 std::string file_contents;
422 447
423 bool read = file_util::ReadFileToString(path, &file_contents); 448 bool read = file_util::ReadFileToString(path, &file_contents);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 std::vector<DownloadItem*> downloads; 518 std::vector<DownloadItem*> downloads;
494 DownloadManagerForShell(shell())->GetAllDownloads(&downloads); 519 DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
495 ASSERT_EQ(1u, downloads.size()); 520 ASSERT_EQ(1u, downloads.size());
496 ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->GetState()); 521 ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->GetState());
497 DownloadItem* download1 = downloads[0]; // The only download. 522 DownloadItem* download1 = downloads[0]; // The only download.
498 523
499 // Start the second download and wait until it's done. 524 // Start the second download and wait until it's done.
500 FilePath file(FILE_PATH_LITERAL("download-test.lib")); 525 FilePath file(FILE_PATH_LITERAL("download-test.lib"));
501 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); 526 GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
502 // Download the file and wait. 527 // Download the file and wait.
503 DownloadAndWait(shell(), url); 528 DownloadAndWait(shell(), url, DownloadItem::COMPLETE);
504 529
505 // Should now have 2 items on the manager. 530 // Should now have 2 items on the manager.
506 downloads.clear(); 531 downloads.clear();
507 DownloadManagerForShell(shell())->GetAllDownloads(&downloads); 532 DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
508 ASSERT_EQ(2u, downloads.size()); 533 ASSERT_EQ(2u, downloads.size());
509 // We don't know the order of the downloads. 534 // We don't know the order of the downloads.
510 DownloadItem* download2 = downloads[(download1 == downloads[0]) ? 1 : 0]; 535 DownloadItem* download2 = downloads[(download1 == downloads[0]) ? 1 : 0];
511 536
512 ASSERT_EQ(DownloadItem::IN_PROGRESS, download1->GetState()); 537 ASSERT_EQ(DownloadItem::IN_PROGRESS, download1->GetState());
513 ASSERT_EQ(DownloadItem::COMPLETE, download2->GetState()); 538 ASSERT_EQ(DownloadItem::COMPLETE, download2->GetState());
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 751
727 MockDownloadItemObserver observer; 752 MockDownloadItemObserver observer;
728 items[0]->AddObserver(&observer); 753 items[0]->AddObserver(&observer);
729 EXPECT_CALL(observer, OnDownloadDestroyed(items[0])); 754 EXPECT_CALL(observer, OnDownloadDestroyed(items[0]));
730 755
731 // Shutdown the download manager. Mostly this is confirming a lack of 756 // Shutdown the download manager. Mostly this is confirming a lack of
732 // crashes. 757 // crashes.
733 DownloadManagerForShell(shell())->Shutdown(); 758 DownloadManagerForShell(shell())->Shutdown();
734 } 759 }
735 760
761 IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeInterruptedDownload) {
762 CommandLine::ForCurrentProcess()->AppendSwitch(
763 switches::kEnableDownloadResumption);
764 ASSERT_TRUE(test_server()->Start());
765 // Default behavior is a 15K file with a RST at 10K. We request
766 // a hold on the response so that we can get the target name determined
767 // before handling the RST.
768 // TODO(rdsmith): Figure out how to handle the races needed
769 // so that we don't have to wait for the target name determination.
770 GURL url = test_server()->GetURL("rangereset?hold");
771
772 // Download and wait for file determination.
773 scoped_ptr<DownloadTestObserver> observer(CreateInProgressWaiter(shell(), 1));
774 NavigateToURL(shell(), url);
775 observer->WaitForFinished();
776
777 std::vector<DownloadItem*> downloads;
778 DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
779 ASSERT_EQ(1u, downloads.size());
780 DownloadItem* download(downloads[0]);
781 if (download->GetFullPath().empty()) {
782 DownloadUpdatedObserver intermediate_observer(
783 download, base::Bind(&IntermediateFileRenameFilter));
784 intermediate_observer.WaitForEvent();
785 }
786
787 // Unleash the RST!
788 scoped_ptr<DownloadTestObserver> rst_observer(CreateWaiter(shell(), 1));
789 GURL release_url = test_server()->GetURL("download-finish");
790 NavigateToURL(shell(), release_url);
791 rst_observer->WaitForFinished();
792 EXPECT_EQ(DownloadItem::INTERRUPTED, download->GetState());
793 EXPECT_EQ(10000u, download->GetReceivedBytes());
794 EXPECT_EQ(15000u, download->GetTotalBytes());
795 EXPECT_EQ(FILE_PATH_LITERAL("rangereset.crdownload"),
796 download->GetFullPath().BaseName().value());
797
798 {
799 std::string file_contents;
800 std::string expected_contents(10000, 'X');
801 ASSERT_TRUE(file_util::ReadFileToString(
802 download->GetFullPath(), &file_contents));
803 EXPECT_EQ(10000u, file_contents.size());
804 // In conditional to avoid spamming the console with two 15000 char strings.
805 if (expected_contents != file_contents)
806 EXPECT_TRUE(false) << "File contents do not have expected value.";
807 }
808
809 // Resume; should get entire file (note that a restart will fail
810 // here because it'll produce another RST).
811 bool flag(false);
812 DownloadUpdatedObserver complete_observer(
813 download, base::Bind(&DownloadResumptionFilter, &flag));
814 download->ResumeInterruptedDownload();
815 NavigateToURL(shell(), release_url); // Needed to get past hold.
816 complete_observer.WaitForEvent();
817 EXPECT_EQ(DownloadItem::COMPLETE, download->GetState());
818 EXPECT_EQ(15000u, download->GetReceivedBytes());
819 EXPECT_EQ(15000u, download->GetTotalBytes());
820 EXPECT_EQ(FILE_PATH_LITERAL("rangereset"),
821 download->GetFullPath().BaseName().value())
822 << "Target path name: " << download->GetTargetFilePath().value();
823
824 {
825 std::string file_contents;
826 std::string expected_contents(15000, 'X');
827 ASSERT_TRUE(file_util::ReadFileToString(
828 download->GetFullPath(), &file_contents));
829 EXPECT_EQ(15000u, file_contents.size());
830 // In conditional to avoid spamming the console with two 15000 char strings.
831 if (expected_contents != file_contents)
832 EXPECT_TRUE(false) << "File contents do not have expected value.";
833 }
834 }
835
736 } // namespace content 836 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698