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

Unified Diff: content/browser/download/download_browsertest.cc

Issue 1203983004: Stop using SpawnedTestServer in DownloadContentTest.* (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: MSVC doesn't want to make default move constructors either. Created 5 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « build/android/pylib/gtest/filter/content_browsertests_disabled ('k') | content/content_tests.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/download/download_browsertest.cc
diff --git a/content/browser/download/download_browsertest.cc b/content/browser/download/download_browsertest.cc
index 37b9b8584e21ce103e0f8288ab69a8bc9a856ac8..6b5cb0056824df515dcc4ab9faa58cb3f9e89a7b 100644
--- a/content/browser/download/download_browsertest.cc
+++ b/content/browser/download/download_browsertest.cc
@@ -5,10 +5,14 @@
// This file contains download browser tests that are known to be runnable
// in a pure content context. Over time tests should be migrated here.
+#include <vector>
+
+#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/format_macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
@@ -28,6 +32,7 @@
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/download_test_observer.h"
+#include "content/public/test/test_download_request_handler.h"
#include "content/public/test/test_file_error_injector.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
@@ -37,7 +42,6 @@
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
-#include "net/test/spawned_test_server/spawned_test_server.h"
#include "net/test/url_request/url_request_mock_http_job.h"
#include "net/test/url_request/url_request_slow_download_job.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -378,71 +382,11 @@ class TestShellDownloadManagerDelegate : public ShellDownloadManagerDelegate {
std::vector<DownloadOpenDelayedCallback> delayed_callbacks_;
};
-// Record all state transitions and byte counts on the observed download.
-class RecordingDownloadObserver : DownloadItem::Observer {
- public:
- struct RecordStruct {
- DownloadItem::DownloadState state;
- int bytes_received;
- };
-
- typedef std::vector<RecordStruct> RecordVector;
-
- RecordingDownloadObserver(DownloadItem* download)
- : download_(download) {
- last_state_.state = download->GetState();
- last_state_.bytes_received = download->GetReceivedBytes();
- download_->AddObserver(this);
- }
-
- ~RecordingDownloadObserver() override { RemoveObserver(); }
-
- void CompareToExpectedRecord(const RecordStruct expected[], size_t size) {
- EXPECT_EQ(size, record_.size());
- int min = size > record_.size() ? record_.size() : size;
- for (int i = 0; i < min; ++i) {
- EXPECT_EQ(expected[i].state, record_[i].state) << "Iteration " << i;
- EXPECT_EQ(expected[i].bytes_received, record_[i].bytes_received)
- << "Iteration " << i;
- }
- }
-
- private:
- void OnDownloadUpdated(DownloadItem* download) override {
- DCHECK_EQ(download_, download);
- DownloadItem::DownloadState state = download->GetState();
- int bytes = download->GetReceivedBytes();
- if (last_state_.state != state || last_state_.bytes_received > bytes) {
- last_state_.state = state;
- last_state_.bytes_received = bytes;
- record_.push_back(last_state_);
- }
- }
-
- void OnDownloadDestroyed(DownloadItem* download) override {
- DCHECK_EQ(download_, download);
- RemoveObserver();
- }
-
- void RemoveObserver() {
- if (download_) {
- download_->RemoveObserver(this);
- download_ = NULL;
- }
- }
-
- DownloadItem* download_;
- RecordStruct last_state_;
- RecordVector record_;
-};
-
// Get the next created download.
class DownloadCreateObserver : DownloadManager::Observer {
public:
DownloadCreateObserver(DownloadManager* manager)
- : manager_(manager),
- item_(NULL),
- waiting_(false) {
+ : manager_(manager), item_(NULL) {
manager_->AddObserver(this);
}
@@ -463,16 +407,16 @@ class DownloadCreateObserver : DownloadManager::Observer {
if (!item_)
item_ = download;
- if (waiting_)
- base::MessageLoopForUI::current()->QuitWhenIdle();
+ if (!completion_closure_.is_null())
+ base::ResetAndReturn(&completion_closure_).Run();
}
DownloadItem* WaitForFinished() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!item_) {
- waiting_ = true;
- RunMessageLoop();
- waiting_ = false;
+ base::RunLoop run_loop;
+ completion_closure_ = run_loop.QuitClosure();
+ run_loop.Run();
}
return item_;
}
@@ -480,28 +424,11 @@ class DownloadCreateObserver : DownloadManager::Observer {
private:
DownloadManager* manager_;
DownloadItem* item_;
- bool waiting_;
+ base::Closure completion_closure_;
};
-
-// Filter for waiting for a certain number of bytes.
-bool DataReceivedFilter(int number_of_bytes, DownloadItem* download) {
- return download->GetReceivedBytes() >= number_of_bytes;
-}
-
-// Filter for download completion.
-bool DownloadCompleteFilter(DownloadItem* download) {
- return download->GetState() == DownloadItem::COMPLETE;
-}
-
-// Filter for saving the size of the download when the first IN_PROGRESS
-// is hit.
-bool InitialSizeFilter(int* download_size, DownloadItem* download) {
- if (download->GetState() != DownloadItem::IN_PROGRESS)
- return false;
-
- *download_size = download->GetReceivedBytes();
- return true;
+bool IsDownloadInState(DownloadItem::DownloadState state, DownloadItem* item) {
+ return item->GetState() == state;
}
// Request handler to be used with CreateRedirectHandler().
@@ -530,12 +457,15 @@ net::EmbeddedTestServer::HandleRequestCallback CreateRedirectHandler(
// Request handler to be used with CreateBasicResponseHandler().
scoped_ptr<net::test_server::HttpResponse> HandleRequestAndSendBasicResponse(
const std::string& relative_url,
+ const base::StringPairs& headers,
const std::string& content_type,
const std::string& body,
const net::test_server::HttpRequest& request) {
scoped_ptr<net::test_server::BasicHttpResponse> response;
if (request.relative_url == relative_url) {
response.reset(new net::test_server::BasicHttpResponse);
+ for (const auto& pair : headers)
+ response->AddCustomHeader(pair.first, pair.second);
response->set_content_type(content_type);
response->set_content(body);
}
@@ -546,27 +476,64 @@ scoped_ptr<net::test_server::HttpResponse> HandleRequestAndSendBasicResponse(
// HTTP 200 status code, a Content-Type header and a body.
net::EmbeddedTestServer::HandleRequestCallback CreateBasicResponseHandler(
const std::string& relative_url,
+ const base::StringPairs& headers,
const std::string& content_type,
const std::string& body) {
- return base::Bind(
- &HandleRequestAndSendBasicResponse, relative_url, content_type, body);
+ return base::Bind(&HandleRequestAndSendBasicResponse, relative_url, headers,
+ content_type, body);
}
-} // namespace
+// Helper class to "flatten" handling of
+// TestDownloadRequestHandler::OnStartHandler.
+class TestRequestStartHandler {
+ public:
+ // Construct an OnStartHandler that can be set as the on_start_handler for
+ // TestDownloadRequestHandler::Parameters.
+ TestDownloadRequestHandler::OnStartHandler GetOnStartHandler() {
+ EXPECT_FALSE(used_) << "GetOnStartHandler() should only be called once for "
+ "an instance of TestRequestStartHandler.";
+ used_ = true;
+ return base::Bind(&TestRequestStartHandler::OnStartHandler,
+ base::Unretained(this));
+ }
-class DownloadContentTest : public ContentBrowserTest {
- protected:
- // An initial send from a website of at least this size will not be
- // help up by buffering in the underlying downloads ByteStream data
- // transfer. This is important because on resumption tests we wait
- // until we've gotten the data we expect before allowing the test server
- // to send its reset, to get around hard close semantics on the Windows
- // socket layer implementation.
- int GetSafeBufferChunk() const {
- return (DownloadResourceHandler::kDownloadByteStreamSize /
- ByteStreamWriter::kFractionBufferBeforeSending) + 1;
+ // Wait until the OnStartHandlers returned in a prior call to
+ // GetOnStartHandler() is invoked.
+ void WaitForCallback() {
+ if (response_callback_.is_null())
+ run_loop_.Run();
+ }
+
+ // Respond to the OnStartHandler() invocation using |headers| and |error|.
+ void RespondWith(const std::string& headers, net::Error error) {
+ ASSERT_FALSE(response_callback_.is_null());
+ response_callback_.Run(headers, error);
+ }
+
+ // Return the headers returned from the invocation of OnStartHandler.
+ const net::HttpRequestHeaders& headers() const {
+ EXPECT_FALSE(response_callback_.is_null());
+ return request_headers_;
}
+ private:
+ void OnStartHandler(const net::HttpRequestHeaders& headers,
+ const TestDownloadRequestHandler::OnStartResponseCallback&
+ response_callback) {
+ request_headers_ = headers;
+ response_callback_ = response_callback;
+ if (run_loop_.running())
+ run_loop_.Quit();
+ }
+
+ bool used_ = false;
+ base::RunLoop run_loop_;
+ net::HttpRequestHeaders request_headers_;
+ TestDownloadRequestHandler::OnStartResponseCallback response_callback_;
+};
+
+class DownloadContentTest : public ContentBrowserTest {
+ protected:
void SetUpOnMainThread() override {
ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
@@ -601,19 +568,22 @@ class DownloadContentTest : public ContentBrowserTest {
DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
}
- // Create a DownloadTestObserverInProgress that will wait for the
- // specified number of downloads to start.
- DownloadCreateObserver* CreateInProgressWaiter(
- Shell* shell, int num_downloads) {
- DownloadManager* download_manager = DownloadManagerForShell(shell);
- return new DownloadCreateObserver(download_manager);
+ void WaitForInterrupt(DownloadItem* download) {
+ DownloadUpdatedObserver(
+ download, base::Bind(&IsDownloadInState, DownloadItem::INTERRUPTED))
+ .WaitForEvent();
}
- DownloadTestObserver* CreateInterruptedWaiter(
- Shell* shell, int num_downloads) {
- DownloadManager* download_manager = DownloadManagerForShell(shell);
- return new DownloadTestObserverInterrupted(download_manager, num_downloads,
- DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
+ void WaitForInProgress(DownloadItem* download) {
+ DownloadUpdatedObserver(
+ download, base::Bind(&IsDownloadInState, DownloadItem::IN_PROGRESS))
+ .WaitForEvent();
+ }
+
+ void WaitForCompletion(DownloadItem* download) {
+ DownloadUpdatedObserver(
+ download, base::Bind(&IsDownloadInState, DownloadItem::COMPLETE))
+ .WaitForEvent();
}
// Note: Cannot be used with other alternative DownloadFileFactorys
@@ -675,67 +645,35 @@ class DownloadContentTest : public ContentBrowserTest {
// Start a download and return the item.
DownloadItem* StartDownloadAndReturnItem(GURL url) {
scoped_ptr<DownloadCreateObserver> observer(
- CreateInProgressWaiter(shell(), 1));
- NavigateToURL(shell(), url);
- observer->WaitForFinished();
- std::vector<DownloadItem*> downloads;
- DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
- EXPECT_EQ(1u, downloads.size());
- if (1u != downloads.size())
- return NULL;
- return downloads[0];
+ new DownloadCreateObserver(DownloadManagerForShell(shell())));
+ shell()->LoadURL(url);
+ return observer->WaitForFinished();
}
- // Wait for data
- void WaitForData(DownloadItem* download, int size) {
- DownloadUpdatedObserver data_observer(
- download, base::Bind(&DataReceivedFilter, size));
- data_observer.WaitForEvent();
- ASSERT_EQ(size, download->GetReceivedBytes());
- ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState());
- }
-
- // Tell the test server to release a pending RST and confirm
- // that the interrupt is received properly (for download resumption
- // testing).
- void ReleaseRSTAndConfirmInterruptForResume(DownloadItem* download) {
- scoped_ptr<DownloadTestObserver> rst_observer(
- CreateInterruptedWaiter(shell(), 1));
- NavigateToURL(shell(), spawned_test_server()->GetURL("download-finish"));
- rst_observer->WaitForFinished();
- EXPECT_EQ(DownloadItem::INTERRUPTED, download->GetState());
- }
-
- // Confirm file status expected for the given location in a stream
- // provided by the resume test server.
- void ConfirmFileStatusForResume(
- DownloadItem* download, bool file_exists,
- int received_bytes, int total_bytes,
- const base::FilePath& expected_filename) {
- // expected_filename is only known if the file exists.
- ASSERT_EQ(file_exists, !expected_filename.empty());
- EXPECT_EQ(received_bytes, download->GetReceivedBytes());
- EXPECT_EQ(total_bytes, download->GetTotalBytes());
- EXPECT_EQ(expected_filename.value(),
- download->GetFullPath().BaseName().value());
- EXPECT_EQ(file_exists,
- (!download->GetFullPath().empty() &&
- base::PathExists(download->GetFullPath())));
-
- if (file_exists) {
- std::string file_contents;
- EXPECT_TRUE(base::ReadFileToString(
- download->GetFullPath(), &file_contents));
-
- ASSERT_EQ(static_cast<size_t>(received_bytes), file_contents.size());
- for (int i = 0; i < received_bytes; ++i) {
- EXPECT_EQ(static_cast<char>((i * 2 + 15) % 256), file_contents[i])
- << "File contents diverged at position " << i
- << " for " << expected_filename.value();
-
- if (static_cast<char>((i * 2 + 15) % 256) != file_contents[i])
- return;
- }
+ static void ReadAndVerifyFileContents(int seed,
+ int64_t expected_size,
+ const base::FilePath& path) {
+ base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
+ ASSERT_TRUE(file.IsValid());
+ int64_t file_length = file.GetLength();
+ ASSERT_EQ(expected_size, file_length);
+
+ const int64_t kBufferSize = 64 * 1024;
+ std::vector<char> pattern;
+ std::vector<char> data;
+ pattern.resize(kBufferSize);
+ data.resize(kBufferSize);
+ for (int64_t offset = 0; offset < file_length;) {
+ int bytes_read = file.Read(offset, &data.front(), kBufferSize);
+ ASSERT_LT(0, bytes_read);
+ ASSERT_GE(kBufferSize, bytes_read);
+
+ TestDownloadRequestHandler::GetPatternBytes(seed, offset, bytes_read,
+ &pattern.front());
+ ASSERT_EQ(0, memcmp(&pattern.front(), &data.front(), bytes_read))
+ << "Comparing block at offset " << offset << " and length "
+ << bytes_read;
+ offset += bytes_read;
}
}
@@ -752,23 +690,19 @@ class DownloadContentTest : public ContentBrowserTest {
scoped_ptr<TestShellDownloadManagerDelegate> test_delegate_;
};
+} // namespace
+
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadCancelled) {
SetupEnsureNoPendingDownloads();
// Create a download, wait until it's started, and confirm
// we're in the expected state.
- scoped_ptr<DownloadCreateObserver> observer(
- CreateInProgressWaiter(shell(), 1));
- NavigateToURL(shell(), GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl));
- observer->WaitForFinished();
-
- std::vector<DownloadItem*> downloads;
- DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
- ASSERT_EQ(1u, downloads.size());
- ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->GetState());
+ DownloadItem* download = StartDownloadAndReturnItem(
+ GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl));
+ ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState());
// Cancel the download and wait for download system quiesce.
- downloads[0]->Cancel(true);
+ download->Cancel(true);
scoped_refptr<DownloadTestFlushObserver> flush_observer(
new DownloadTestFlushObserver(DownloadManagerForShell(shell())));
flush_observer->WaitForFlush();
@@ -784,28 +718,14 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, MultiDownload) {
// Create a download, wait until it's started, and confirm
// we're in the expected state.
- scoped_ptr<DownloadCreateObserver> observer1(
- CreateInProgressWaiter(shell(), 1));
- NavigateToURL(shell(), GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl));
- observer1->WaitForFinished();
-
- std::vector<DownloadItem*> downloads;
- DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
- ASSERT_EQ(1u, downloads.size());
- ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->GetState());
- DownloadItem* download1 = downloads[0]; // The only download.
+ DownloadItem* download1 = StartDownloadAndReturnItem(
+ GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl));
+ ASSERT_EQ(DownloadItem::IN_PROGRESS, download1->GetState());
// Start the second download and wait until it's done.
GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib"));
- // Download the file and wait.
- NavigateToURLAndWaitForDownload(shell(), url, DownloadItem::COMPLETE);
-
- // Should now have 2 items on the manager.
- downloads.clear();
- DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
- ASSERT_EQ(2u, downloads.size());
- // We don't know the order of the downloads.
- DownloadItem* download2 = downloads[(download1 == downloads[0]) ? 1 : 0];
+ DownloadItem* download2 = StartDownloadAndReturnItem(url);
+ WaitForCompletion(download2);
ASSERT_EQ(DownloadItem::IN_PROGRESS, download1->GetState());
ASSERT_EQ(DownloadItem::COMPLETE, download2->GetState());
@@ -962,21 +882,15 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelAtRelease) {
// works properly.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownInProgress) {
// Create a download that won't complete.
- scoped_ptr<DownloadCreateObserver> observer(
- CreateInProgressWaiter(shell(), 1));
- NavigateToURL(shell(), GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl));
- observer->WaitForFinished();
+ DownloadItem* download = StartDownloadAndReturnItem(
+ GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl));
- // Get the item.
- std::vector<DownloadItem*> items;
- DownloadManagerForShell(shell())->GetAllDownloads(&items);
- ASSERT_EQ(1u, items.size());
- EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());
+ EXPECT_EQ(DownloadItem::IN_PROGRESS, download->GetState());
// Shutdown the download manager and make sure we get the right
// notifications in the right order.
StrictMock<MockDownloadItemObserver> item_observer;
- items[0]->AddObserver(&item_observer);
+ download->AddObserver(&item_observer);
MockDownloadManagerObserver manager_observer(
DownloadManagerForShell(shell()));
// Don't care about ModelChanged() events.
@@ -988,11 +902,12 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownInProgress) {
EXPECT_CALL(manager_observer, MockManagerGoingDown(
DownloadManagerForShell(shell())))
.WillOnce(Return());
- EXPECT_CALL(item_observer, OnDownloadUpdated(
- AllOf(items[0],
- Property(&DownloadItem::GetState, DownloadItem::CANCELLED))))
+ EXPECT_CALL(
+ item_observer,
+ OnDownloadUpdated(AllOf(download, Property(&DownloadItem::GetState,
+ DownloadItem::CANCELLED))))
.WillOnce(Return());
- EXPECT_CALL(item_observer, OnDownloadDestroyed(items[0]))
+ EXPECT_CALL(item_observer, OnDownloadDestroyed(download))
.WillOnce(Return());
}
@@ -1009,7 +924,6 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownInProgress) {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&base::PlatformThread::Sleep,
base::TimeDelta::FromMilliseconds(25)));
- items.clear();
}
// Try to shutdown just after we release the download file, by delaying
@@ -1068,237 +982,222 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownAtRelease) {
DownloadManagerForShell(shell())->Shutdown();
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeInterruptedDownload) {
+// Test resumption with a response that contains strong validators.
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, Resume_WithStrongValidators) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
- ASSERT_TRUE(spawned_test_server()->Start());
- GURL url = spawned_test_server()->GetURL(
- base::StringPrintf("rangereset?size=%d&rst_boundary=%d",
- GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
+ TestDownloadRequestHandler request_handler;
+ TestDownloadRequestHandler::Parameters parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ const TestDownloadRequestHandler::InjectedError interruption =
+ parameters.injected_errors.front();
+ request_handler.StartServing(parameters);
- MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell()));
- EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
+ DownloadItem* download = StartDownloadAndReturnItem(request_handler.url());
+ WaitForInterrupt(download);
- DownloadItem* download(StartDownloadAndReturnItem(url));
- WaitForData(download, GetSafeBufferChunk());
- ::testing::Mock::VerifyAndClearExpectations(&dm_observer);
+ ASSERT_EQ(interruption.offset, download->GetReceivedBytes());
+ ASSERT_EQ(parameters.size, download->GetTotalBytes());
- // Confirm resumption while in progress doesn't do anything.
download->Resume();
- ASSERT_EQ(GetSafeBufferChunk(), download->GetReceivedBytes());
- ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState());
-
- // Tell the server to send the RST and confirm the interrupt happens.
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
-
- // Resume, confirming received bytes on resumption is correct.
- // Make sure no creation calls are included.
- EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(0);
- int initial_size = 0;
- DownloadUpdatedObserver initial_size_observer(
- download, base::Bind(&InitialSizeFilter, &initial_size));
- download->Resume();
- initial_size_observer.WaitForEvent();
- EXPECT_EQ(GetSafeBufferChunk(), initial_size);
- ::testing::Mock::VerifyAndClearExpectations(&dm_observer);
-
- // and wait for expected data.
- WaitForData(download, GetSafeBufferChunk() * 2);
-
- // Tell the server to send the RST and confirm the interrupt happens.
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk() * 2, GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
-
- // Resume and wait for completion.
- DownloadUpdatedObserver completion_observer(
- download, base::Bind(DownloadCompleteFilter));
- download->Resume();
- completion_observer.WaitForEvent();
-
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset")));
-
- // Confirm resumption while complete doesn't do anything.
- download->Resume();
- ASSERT_EQ(GetSafeBufferChunk() * 3, download->GetReceivedBytes());
- ASSERT_EQ(DownloadItem::COMPLETE, download->GetState());
- RunAllPendingInMessageLoop();
- ASSERT_EQ(GetSafeBufferChunk() * 3, download->GetReceivedBytes());
- ASSERT_EQ(DownloadItem::COMPLETE, download->GetState());
+ WaitForCompletion(download);
+
+ ASSERT_EQ(parameters.size, download->GetReceivedBytes());
+ ASSERT_EQ(parameters.size, download->GetTotalBytes());
+ ASSERT_NO_FATAL_FAILURE(ReadAndVerifyFileContents(
+ parameters.pattern_generator_seed, parameters.size,
+ download->GetTargetFilePath()));
+
+ // Characterization risk: The next portion of the test examines the requests
+ // that were sent out while downloading our resource. These requests
+ // correspond to the requests that were generated by the browser and the
+ // downloads system and may change as implementation details change.
+ TestDownloadRequestHandler::CompletedRequests requests;
+ request_handler.GetCompletedRequestInfo(&requests);
+
+ ASSERT_EQ(2u, requests.size());
+
+ // The first request only transferrs bytes up until the interruption point.
+ EXPECT_EQ(interruption.offset, requests[0].transferred_byte_count);
+
+ // The next request should only have transferred the remainder of the
+ // resource.
+ EXPECT_EQ(parameters.size - interruption.offset,
+ requests[1].transferred_byte_count);
+
+ std::string value;
+ ASSERT_TRUE(requests[1].request_headers.GetHeader(
+ net::HttpRequestHeaders::kIfRange, &value));
+ EXPECT_EQ(parameters.etag, value);
+
+ ASSERT_TRUE(requests[1].request_headers.GetHeader(
+ net::HttpRequestHeaders::kRange, &value));
+ EXPECT_EQ(base::StringPrintf("bytes=%" PRId64 "-", interruption.offset),
+ value);
}
-// Confirm restart fallback happens if a range request is bounced.
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeInterruptedDownloadNoRange) {
+// A partial resumption results in an HTTP 200 response. I.e. the server ignored
+// the range request and sent the entire resource instead. For If-Range requests
+// (as opposed to If-Match), the behavior for a precondition failure is also to
+// respond with a 200. So this test case covers both validation failure and
+// ignoring the range request.
+IN_PROC_BROWSER_TEST_F(DownloadContentTest,
+ Resume_RestartIfNotPartialResponse) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
- ASSERT_TRUE(spawned_test_server()->Start());
+ const int kOriginalPatternGeneratorSeed = 1;
+ const int kNewPatternGeneratorSeed = 2;
+
+ TestDownloadRequestHandler::Parameters parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ parameters.pattern_generator_seed = kOriginalPatternGeneratorSeed;
+ const TestDownloadRequestHandler::InjectedError interruption =
+ parameters.injected_errors.front();
- // Auto-restart if server doesn't handle ranges.
- GURL url = spawned_test_server()->GetURL(base::StringPrintf(
- // First download hits an RST, rest don't, no ranges.
- "rangereset?size=%d&rst_boundary=%d&"
- "token=NoRange&rst_limit=1&bounce_range",
- GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(parameters);
- // Start the download and wait for first data chunk.
- DownloadItem* download(StartDownloadAndReturnItem(url));
- WaitForData(download, GetSafeBufferChunk());
+ DownloadItem* download = StartDownloadAndReturnItem(request_handler.url());
+ WaitForInterrupt(download);
- RecordingDownloadObserver recorder(download);
+ ASSERT_EQ(interruption.offset, download->GetReceivedBytes());
+ ASSERT_EQ(parameters.size, download->GetTotalBytes());
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
+ parameters = TestDownloadRequestHandler::Parameters();
+ parameters.support_byte_ranges = false;
+ parameters.pattern_generator_seed = kNewPatternGeneratorSeed;
+ request_handler.StartServing(parameters);
- DownloadUpdatedObserver completion_observer(
- download, base::Bind(DownloadCompleteFilter));
download->Resume();
- completion_observer.WaitForEvent();
-
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset")));
-
- static const RecordingDownloadObserver::RecordStruct expected_record[] = {
- // Result of RST
- {DownloadItem::INTERRUPTED, GetSafeBufferChunk()},
- // Starting continuation
- {DownloadItem::IN_PROGRESS, GetSafeBufferChunk()},
- // Notification of receiving whole file.
- {DownloadItem::IN_PROGRESS, 0},
- // Completion.
- {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3},
- };
-
- recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record));
+ WaitForCompletion(download);
+
+ ASSERT_EQ(parameters.size, download->GetReceivedBytes());
+ ASSERT_EQ(parameters.size, download->GetTotalBytes());
+ ASSERT_NO_FATAL_FAILURE(
+ ReadAndVerifyFileContents(kNewPatternGeneratorSeed, parameters.size,
+ download->GetTargetFilePath()));
+
+ // When the downloads system sees the full response, it should accept the
+ // response without restarting. On the network, we should deterministically
+ // see two requests:
+ // * The original request which transfers upto our interruption point.
+ // * The resumption attempt, which receives the entire entity.
+ TestDownloadRequestHandler::CompletedRequests requests;
+ request_handler.GetCompletedRequestInfo(&requests);
+
+ ASSERT_EQ(2u, requests.size());
+
+ // The first request only transfers data up to the interruption point.
+ EXPECT_EQ(interruption.offset, requests[0].transferred_byte_count);
+
+ // The second request transfers the entire response.
+ EXPECT_EQ(parameters.size, requests[1].transferred_byte_count);
+
+ std::string value;
+ ASSERT_TRUE(requests[1].request_headers.GetHeader(
+ net::HttpRequestHeaders::kIfRange, &value));
+ EXPECT_EQ(parameters.etag, value);
+
+ ASSERT_TRUE(requests[1].request_headers.GetHeader(
+ net::HttpRequestHeaders::kRange, &value));
+ EXPECT_EQ(base::StringPrintf("bytes=%" PRId64 "-", interruption.offset),
+ value);
}
-// Confirm we don't try to resume if we don't have a verifier.
-IN_PROC_BROWSER_TEST_F(DownloadContentTest,
- ResumeInterruptedDownloadNoVerifiers) {
+// Confirm we restart if we don't have a verifier.
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, Resume_RestartIfNoETag) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
- ASSERT_TRUE(spawned_test_server()->Start());
-
- GURL url = spawned_test_server()->GetURL(base::StringPrintf(
- // First download hits an RST, rest don't, no verifiers.
- "rangereset?size=%d&rst_boundary=%d&"
- "token=NoRange&rst_limit=1&no_verifiers",
- GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
+ const int kOriginalPatternGeneratorSeed = 1;
+ const int kNewPatternGeneratorSeed = 2;
- // Start the download and wait for first data chunk.
- DownloadItem* download(StartDownloadAndReturnItem(url));
- WaitForData(download, GetSafeBufferChunk());
+ TestDownloadRequestHandler::Parameters parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ ASSERT_EQ(1u, parameters.injected_errors.size());
+ parameters.etag.clear();
+ parameters.pattern_generator_seed = kOriginalPatternGeneratorSeed;
- RecordingDownloadObserver recorder(download);
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(parameters);
+ DownloadItem* download = StartDownloadAndReturnItem(request_handler.url());
+ WaitForInterrupt(download);
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, false, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath());
+ parameters.pattern_generator_seed = kNewPatternGeneratorSeed;
+ parameters.ClearInjectedErrors();
+ request_handler.StartServing(parameters);
- DownloadUpdatedObserver completion_observer(
- download, base::Bind(DownloadCompleteFilter));
download->Resume();
- completion_observer.WaitForEvent();
-
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset")));
-
- static const RecordingDownloadObserver::RecordStruct expected_record[] = {
- // Result of RST
- {DownloadItem::INTERRUPTED, GetSafeBufferChunk()},
- // Restart for lack of verifiers
- {DownloadItem::IN_PROGRESS, 0},
- // Completion.
- {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3},
- };
-
- recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record));
+ WaitForCompletion(download);
+
+ ASSERT_EQ(parameters.size, download->GetReceivedBytes());
+ ASSERT_EQ(parameters.size, download->GetTotalBytes());
+ ASSERT_NO_FATAL_FAILURE(
+ ReadAndVerifyFileContents(kNewPatternGeneratorSeed, parameters.size,
+ download->GetTargetFilePath()));
+
+ TestDownloadRequestHandler::CompletedRequests requests;
+ request_handler.GetCompletedRequestInfo(&requests);
+
+ // Neither If-Range nor Range headers should be present in the second request.
+ ASSERT_EQ(2u, requests.size());
+ std::string value;
+ EXPECT_FALSE(requests[1].request_headers.GetHeader(
+ net::HttpRequestHeaders::kIfRange, &value));
+ EXPECT_FALSE(requests[1].request_headers.GetHeader(
+ net::HttpRequestHeaders::kRange, &value));
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithDeletedFile) {
+// Partial file goes missing before the download is resumed. The download should
+// restart.
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, Resume_RestartIfNoPartialFile) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
- ASSERT_TRUE(spawned_test_server()->Start());
+ TestDownloadRequestHandler::Parameters parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
- GURL url = spawned_test_server()->GetURL(base::StringPrintf(
- // First download hits an RST, rest don't
- "rangereset?size=%d&rst_boundary=%d&"
- "token=NoRange&rst_limit=1",
- GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
-
- // Start the download and wait for first data chunk.
- DownloadItem* download(StartDownloadAndReturnItem(url));
- WaitForData(download, GetSafeBufferChunk());
-
- RecordingDownloadObserver recorder(download);
-
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(parameters);
+ DownloadItem* download = StartDownloadAndReturnItem(request_handler.url());
+ WaitForInterrupt(download);
// Delete the intermediate file.
- base::DeleteFile(download->GetFullPath(), false);
+ ASSERT_TRUE(base::PathExists(download->GetFullPath()));
+ ASSERT_TRUE(base::DeleteFile(download->GetFullPath(), false));
+
+ parameters.ClearInjectedErrors();
+ request_handler.StartServing(parameters);
- DownloadUpdatedObserver completion_observer(
- download, base::Bind(DownloadCompleteFilter));
download->Resume();
- completion_observer.WaitForEvent();
-
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset")));
-
- static const RecordingDownloadObserver::RecordStruct expected_record[] = {
- // Result of RST
- {DownloadItem::INTERRUPTED, GetSafeBufferChunk()},
- // Starting continuation
- {DownloadItem::IN_PROGRESS, GetSafeBufferChunk()},
- // Error because file isn't there.
- {DownloadItem::INTERRUPTED, 0},
- // Restart.
- {DownloadItem::IN_PROGRESS, 0},
- // Completion.
- {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3},
- };
-
- recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record));
+ WaitForCompletion(download);
+
+ ASSERT_EQ(parameters.size, download->GetReceivedBytes());
+ ASSERT_EQ(parameters.size, download->GetTotalBytes());
+ ASSERT_NO_FATAL_FAILURE(ReadAndVerifyFileContents(
+ parameters.pattern_generator_seed, parameters.size,
+ download->GetTargetFilePath()));
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileInitError) {
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, Resume_RecoverFromInitFileError) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
- GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib"));
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(TestDownloadRequestHandler::Parameters());
// Setup the error injector.
scoped_refptr<TestFileErrorInjector> injector(
TestFileErrorInjector::Create(DownloadManagerForShell(shell())));
- TestFileErrorInjector::FileErrorInfo err = {
- url.spec(),
- TestFileErrorInjector::FILE_OPERATION_INITIALIZE,
- 0,
- DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE
- };
+ const TestFileErrorInjector::FileErrorInfo err = {
+ request_handler.url().spec(),
+ TestFileErrorInjector::FILE_OPERATION_INITIALIZE, 0,
+ DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE};
injector->AddError(err);
injector->InjectErrors();
// Start and watch for interrupt.
- scoped_ptr<DownloadTestObserver> int_observer(
- CreateInterruptedWaiter(shell(), 1));
- DownloadItem* download(StartDownloadAndReturnItem(url));
- int_observer->WaitForFinished();
+ DownloadItem* download(StartDownloadAndReturnItem(request_handler.url()));
+ WaitForInterrupt(download);
ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
download->GetLastReason());
@@ -1318,37 +1217,32 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileInitError) {
injector->InjectErrors();
// Resume and watch completion.
- DownloadUpdatedObserver completion_observer(
- download, base::Bind(DownloadCompleteFilter));
download->Resume();
- completion_observer.WaitForEvent();
+ WaitForCompletion(download);
EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE);
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest,
- ResumeWithFileIntermediateRenameError) {
+ Resume_RecoverFromIntermediateFileRenameError) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
- GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib"));
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(TestDownloadRequestHandler::Parameters());
// Setup the error injector.
scoped_refptr<TestFileErrorInjector> injector(
TestFileErrorInjector::Create(DownloadManagerForShell(shell())));
- TestFileErrorInjector::FileErrorInfo err = {
- url.spec(),
- TestFileErrorInjector::FILE_OPERATION_RENAME_UNIQUIFY,
- 0,
- DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE
- };
+ const TestFileErrorInjector::FileErrorInfo err = {
+ request_handler.url().spec(),
+ TestFileErrorInjector::FILE_OPERATION_RENAME_UNIQUIFY, 0,
+ DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE};
injector->AddError(err);
injector->InjectErrors();
// Start and watch for interrupt.
- scoped_ptr<DownloadTestObserver> int_observer(
- CreateInterruptedWaiter(shell(), 1));
- DownloadItem* download(StartDownloadAndReturnItem(url));
- int_observer->WaitForFinished();
+ DownloadItem* download(StartDownloadAndReturnItem(request_handler.url()));
+ WaitForInterrupt(download);
ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
download->GetLastReason());
@@ -1369,18 +1263,17 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
injector->ClearErrors();
injector->InjectErrors();
- // Resume and watch completion.
- DownloadUpdatedObserver completion_observer(
- download, base::Bind(DownloadCompleteFilter));
download->Resume();
- completion_observer.WaitForEvent();
+ WaitForCompletion(download);
EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE);
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileFinalRenameError) {
+IN_PROC_BROWSER_TEST_F(DownloadContentTest,
+ Resume_RecoverFromFinalRenameError) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
- GURL url(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib"));
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(TestDownloadRequestHandler::Parameters());
// Setup the error injector.
scoped_refptr<TestFileErrorInjector> injector(
@@ -1388,19 +1281,15 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileFinalRenameError) {
DownloadManagerForShell(shell())->RemoveAllDownloads();
TestFileErrorInjector::FileErrorInfo err = {
- url.spec(),
- TestFileErrorInjector::FILE_OPERATION_RENAME_ANNOTATE,
- 0,
- DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE
- };
+ request_handler.url().spec(),
+ TestFileErrorInjector::FILE_OPERATION_RENAME_ANNOTATE, 0,
+ DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE};
injector->AddError(err);
injector->InjectErrors();
// Start and watch for interrupt.
- scoped_ptr<DownloadTestObserver> int_observer(
- CreateInterruptedWaiter(shell(), 1));
- DownloadItem* download(StartDownloadAndReturnItem(url));
- int_observer->WaitForFinished();
+ DownloadItem* download(StartDownloadAndReturnItem(request_handler.url()));
+ WaitForInterrupt(download);
ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
download->GetLastReason());
@@ -1419,11 +1308,8 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileFinalRenameError) {
injector->ClearErrors();
injector->InjectErrors();
- // Resume and watch completion.
- DownloadUpdatedObserver completion_observer(
- download, base::Bind(DownloadCompleteFilter));
download->Resume();
- completion_observer.WaitForEvent();
+ WaitForCompletion(download);
EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE);
}
@@ -1432,23 +1318,16 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileFinalRenameError) {
IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelInterruptedDownload) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
- ASSERT_TRUE(spawned_test_server()->Start());
-
- GURL url1 = spawned_test_server()->GetURL(
- base::StringPrintf("rangereset?size=%d&rst_boundary=%d",
- GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
-
- DownloadItem* download(StartDownloadAndReturnItem(url1));
- WaitForData(download, GetSafeBufferChunk());
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption());
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
+ DownloadItem* download = StartDownloadAndReturnItem(request_handler.url());
+ WaitForInterrupt(download);
- base::FilePath intermediate_path(download->GetFullPath());
+ base::FilePath intermediate_path = download->GetFullPath();
ASSERT_FALSE(intermediate_path.empty());
- EXPECT_TRUE(base::PathExists(intermediate_path));
+ ASSERT_TRUE(base::PathExists(intermediate_path));
download->Cancel(true /* user_cancel */);
RunAllPendingInMessageLoop(BrowserThread::FILE);
@@ -1459,81 +1338,59 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelInterruptedDownload) {
EXPECT_TRUE(download->GetFullPath().empty());
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveDownload) {
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveInterruptedDownload) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
- ASSERT_TRUE(spawned_test_server()->Start());
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption());
- // An interrupted download should remove the intermediate file when it is
- // removed.
- {
- GURL url1 = spawned_test_server()->GetURL(
- base::StringPrintf("rangereset?size=%d&rst_boundary=%d",
- GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
-
- DownloadItem* download(StartDownloadAndReturnItem(url1));
- WaitForData(download, GetSafeBufferChunk());
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
-
- base::FilePath intermediate_path(download->GetFullPath());
- ASSERT_FALSE(intermediate_path.empty());
- EXPECT_TRUE(base::PathExists(intermediate_path));
-
- download->Remove();
- RunAllPendingInMessageLoop(BrowserThread::FILE);
- RunAllPendingInMessageLoop();
-
- // The intermediate file should now be gone.
- EXPECT_FALSE(base::PathExists(intermediate_path));
- }
+ DownloadItem* download = StartDownloadAndReturnItem(request_handler.url());
+ WaitForInterrupt(download);
+
+ base::FilePath intermediate_path = download->GetFullPath();
+ ASSERT_FALSE(intermediate_path.empty());
+ ASSERT_TRUE(base::PathExists(intermediate_path));
+
+ download->Remove();
+ RunAllPendingInMessageLoop(BrowserThread::FILE);
+ RunAllPendingInMessageLoop();
+
+ // The intermediate file should now be gone.
+ EXPECT_FALSE(base::PathExists(intermediate_path));
+}
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveCompletedDownload) {
// A completed download shouldn't delete the downloaded file when it is
// removed.
- {
- // Start the second download and wait until it's done.
- GURL url2(net::URLRequestMockHTTPJob::GetMockUrl("download-test.lib"));
- scoped_ptr<DownloadTestObserver> completion_observer(
- CreateWaiter(shell(), 1));
- DownloadItem* download(StartDownloadAndReturnItem(url2));
- completion_observer->WaitForFinished();
-
- // The target path should exist.
- base::FilePath target_path(download->GetTargetFilePath());
- EXPECT_TRUE(base::PathExists(target_path));
- download->Remove();
- RunAllPendingInMessageLoop(BrowserThread::FILE);
- RunAllPendingInMessageLoop();
-
- // The file should still exist.
- EXPECT_TRUE(base::PathExists(target_path));
- }
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(TestDownloadRequestHandler::Parameters());
+ scoped_ptr<DownloadTestObserver> completion_observer(
+ CreateWaiter(shell(), 1));
+ DownloadItem* download(StartDownloadAndReturnItem(request_handler.url()));
+ completion_observer->WaitForFinished();
+
+ // The target path should exist.
+ base::FilePath target_path(download->GetTargetFilePath());
+ EXPECT_TRUE(base::PathExists(target_path));
+ download->Remove();
+ RunAllPendingInMessageLoop(BrowserThread::FILE);
+ RunAllPendingInMessageLoop();
+
+ // The file should still exist.
+ EXPECT_TRUE(base::PathExists(target_path));
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveResumingDownload) {
- SetupEnsureNoPendingDownloads();
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
- ASSERT_TRUE(spawned_test_server()->Start());
-
- GURL url = spawned_test_server()->GetURL(
- base::StringPrintf("rangereset?size=%d&rst_boundary=%d",
- GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
-
- MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell()));
- EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
-
- DownloadItem* download(StartDownloadAndReturnItem(url));
- WaitForData(download, GetSafeBufferChunk());
- ::testing::Mock::VerifyAndClearExpectations(&dm_observer);
+ TestDownloadRequestHandler::Parameters parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(parameters);
- // Tell the server to send the RST and confirm the interrupt happens.
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
+ DownloadItem* download = StartDownloadAndReturnItem(request_handler.url());
+ WaitForInterrupt(download);
base::FilePath intermediate_path(download->GetFullPath());
ASSERT_FALSE(intermediate_path.empty());
@@ -1541,96 +1398,120 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveResumingDownload) {
// Resume and remove download. We expect only a single OnDownloadCreated()
// call, and that's for the second download created below.
+ MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell()));
EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
+
+ TestRequestStartHandler request_start_handler;
+ parameters.on_start_handler = request_start_handler.GetOnStartHandler();
+ request_handler.StartServing(parameters);
+
download->Resume();
+ request_start_handler.WaitForCallback();
+
+ // At this point, the download resumption request has been sent out, but the
+ // reponse hasn't been received yet.
download->Remove();
+ request_start_handler.RespondWith(std::string(), net::OK);
+
// The intermediate file should now be gone.
RunAllPendingInMessageLoop(BrowserThread::FILE);
RunAllPendingInMessageLoop();
EXPECT_FALSE(base::PathExists(intermediate_path));
- // Start the second download and wait until it's done. The test server is
- // single threaded. The response to this download request should follow the
- // response to the previous resumption request.
- GURL url2(
- spawned_test_server()->GetURL("rangereset?size=100&rst_limit=0&token=x"));
- NavigateToURLAndWaitForDownload(shell(), url2, DownloadItem::COMPLETE);
+ parameters.ClearInjectedErrors();
+ parameters.on_start_handler.Reset();
+ request_handler.StartServing(parameters);
+ // Start the second download and wait until it's done. This exercises the
+ // entire downloads stack and effectively flushes all of our worker threads.
+ // We are testing whether the URL request created in the previous
+ // DownloadItem::Resume() call reulted in a new download or not.
+ NavigateToURLAndWaitForDownload(shell(), request_handler.url(),
+ DownloadItem::COMPLETE);
EXPECT_TRUE(EnsureNoPendingDownloads());
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelResumingDownload) {
- SetupEnsureNoPendingDownloads();
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
- ASSERT_TRUE(spawned_test_server()->Start());
-
- GURL url = spawned_test_server()->GetURL(
- base::StringPrintf("rangereset?size=%d&rst_boundary=%d",
- GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
-
- MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell()));
- EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
-
- DownloadItem* download(StartDownloadAndReturnItem(url));
- WaitForData(download, GetSafeBufferChunk());
- ::testing::Mock::VerifyAndClearExpectations(&dm_observer);
+ TestDownloadRequestHandler::Parameters parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(parameters);
- // Tell the server to send the RST and confirm the interrupt happens.
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
+ DownloadItem* download = StartDownloadAndReturnItem(request_handler.url());
+ WaitForInterrupt(download);
base::FilePath intermediate_path(download->GetFullPath());
ASSERT_FALSE(intermediate_path.empty());
EXPECT_TRUE(base::PathExists(intermediate_path));
- // Resume and cancel download. We expect only a single OnDownloadCreated()
+ // Resume and remove download. We expect only a single OnDownloadCreated()
// call, and that's for the second download created below.
+ MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell()));
EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
+
+ TestRequestStartHandler request_start_handler;
+ parameters.on_start_handler = request_start_handler.GetOnStartHandler();
+ request_handler.StartServing(parameters);
+
download->Resume();
- download->Cancel(true);
+ request_start_handler.WaitForCallback();
+
+ // At this point, the download item has initiated a network request for the
+ // resumption attempt, but hasn't received a response yet.
+ download->Cancel(true /* user_cancel */);
+
+ request_start_handler.RespondWith(std::string(), net::OK);
// The intermediate file should now be gone.
+ RunAllPendingInMessageLoop(BrowserThread::IO);
RunAllPendingInMessageLoop(BrowserThread::FILE);
RunAllPendingInMessageLoop();
EXPECT_FALSE(base::PathExists(intermediate_path));
- EXPECT_TRUE(download->GetFullPath().empty());
- // Start the second download and wait until it's done. The test server is
- // single threaded. The response to this download request should follow the
- // response to the previous resumption request.
- GURL url2(
- spawned_test_server()->GetURL("rangereset?size=100&rst_limit=0&token=x"));
- NavigateToURLAndWaitForDownload(shell(), url2, DownloadItem::COMPLETE);
+ parameters.ClearInjectedErrors();
+ parameters.on_start_handler.Reset();
+ request_handler.StartServing(parameters);
+ // Start the second download and wait until it's done. This exercises the
+ // entire downloads stack and effectively flushes all of our worker threads.
+ // We are testing whether the URL request created in the previous
+ // DownloadItem::Resume() call reulted in a new download or not.
+ NavigateToURLAndWaitForDownload(shell(), request_handler.url(),
+ DownloadItem::COMPLETE);
EXPECT_TRUE(EnsureNoPendingDownloads());
}
// Check that the cookie policy is correctly updated when downloading a file
// that redirects cross origin.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, CookiePolicy) {
- ASSERT_TRUE(spawned_test_server()->Start());
- net::HostPortPair host_port = spawned_test_server()->host_port_pair();
- DCHECK_EQ(host_port.host(), std::string("127.0.0.1"));
+ net::EmbeddedTestServer origin_one;
+ net::EmbeddedTestServer origin_two;
+ ASSERT_TRUE(origin_one.Start());
+ ASSERT_TRUE(origin_two.Start());
// Block third-party cookies.
ShellNetworkDelegate::SetAcceptAllCookies(false);
// |url| redirects to a different origin |download| which tries to set a
// cookie.
- std::string download(base::StringPrintf(
- "http://localhost:%d/set-cookie?A=B", host_port.port()));
- GURL url(spawned_test_server()->GetURL("server-redirect?" + download));
+ base::StringPairs cookie_header;
+ cookie_header.push_back(
+ std::make_pair(std::string("Set-Cookie"), std::string("A=B")));
+ origin_one.RegisterRequestHandler(CreateBasicResponseHandler(
+ "/foo", cookie_header, "application/octet-stream", "abcd"));
+ origin_two.RegisterRequestHandler(
+ CreateRedirectHandler("/bar", origin_one.GetURL("/foo")));
// Download the file.
SetupEnsureNoPendingDownloads();
- scoped_ptr<DownloadUrlParameters> dl_params(
- DownloadUrlParameters::FromWebContents(shell()->web_contents(), url));
+ scoped_ptr<DownloadUrlParameters> download_parameters(
+ DownloadUrlParameters::FromWebContents(shell()->web_contents(),
+ origin_two.GetURL("/bar")));
scoped_ptr<DownloadTestObserver> observer(CreateWaiter(shell(), 1));
- DownloadManagerForShell(shell())->DownloadUrl(dl_params.Pass());
+ DownloadManagerForShell(shell())->DownloadUrl(download_parameters.Pass());
observer->WaitForFinished();
// Get the important info from other threads and check it.
@@ -1644,7 +1525,7 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, CookiePolicy) {
// Check that the cookies were correctly set.
EXPECT_EQ("A=B",
content::GetCookies(shell()->web_contents()->GetBrowserContext(),
- GURL(download)));
+ origin_one.GetURL("/")));
}
// A filename suggestion specified via a @download attribute should not be
@@ -1676,7 +1557,7 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
origin_one.RegisterRequestHandler(
CreateRedirectHandler("/ping", origin_two.GetURL("/download")));
origin_two.RegisterRequestHandler(CreateBasicResponseHandler(
- "/download", "application/octet-stream", "Hello"));
+ "/download", base::StringPairs(), "application/octet-stream", "Hello"));
NavigateToURLAndWaitForDownload(
shell(), referrer_url, DownloadItem::COMPLETE);
@@ -1724,7 +1605,7 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
origin_two.RegisterRequestHandler(
CreateRedirectHandler("/pong", origin_one.GetURL("/download")));
origin_one.RegisterRequestHandler(CreateBasicResponseHandler(
- "/download", "application/octet-stream", "Hello"));
+ "/download", base::StringPairs(), "application/octet-stream", "Hello"));
NavigateToURLAndWaitForDownload(
shell(), referrer_url, DownloadItem::COMPLETE);
@@ -1743,12 +1624,7 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
// The content body is empty. Make sure this case is handled properly and we
// don't regress on http://crbug.com/320394.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadGZipWithNoContent) {
- net::EmbeddedTestServer test_server;
- ASSERT_TRUE(test_server.Start());
-
- GURL url = test_server.GetURL("/empty.bin");
- test_server.ServeFilesFromDirectory(GetTestFilePath("download", ""));
-
+ GURL url = net::URLRequestMockHTTPJob::GetMockUrl("empty.bin");
NavigateToURLAndWaitForDownload(shell(), url, DownloadItem::COMPLETE);
// That's it. This should work without crashing.
}
« no previous file with comments | « build/android/pylib/gtest/filter/content_browsertests_disabled ('k') | content/content_tests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698