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

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: Created 5 years, 1 month 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
Index: content/browser/download/download_browsertest.cc
diff --git a/content/browser/download/download_browsertest.cc b/content/browser/download/download_browsertest.cc
index 9bad4d3f421135165c7113baa601d8c35b3ba4df..08afa40c5a2ad43de3f23476c21e043d7d759a66 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,20 @@ 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;
svaldez 2015/11/12 20:25:51 Might just want to merge these into DownloadStateF
asanka 2015/11/13 21:40:01 Good call. I changed called it IsDownloadInState()
}
-// 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;
+bool DownloadInterruptFilter(DownloadItem* download) {
+ return download->GetState() == DownloadItem::INTERRUPTED;
+}
- *download_size = download->GetReceivedBytes();
- return true;
+bool DownloadInProgressFilter(DownloadItem* download) {
+ return download->GetState() == DownloadItem::IN_PROGRESS;
}
// Request handler to be used with CreateRedirectHandler().
@@ -530,12 +466,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 +485,15 @@ 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
-
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;
- }
-
void SetUpOnMainThread() override {
ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
@@ -601,19 +528,19 @@ 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(&DownloadInterruptFilter))
svaldez 2015/11/12 20:25:51 See above.
asanka 2015/11/13 21:40:01 Done.
+ .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(&DownloadInProgressFilter))
+ .WaitForEvent();
+ }
+
+ void WaitForCompletion(DownloadItem* download) {
+ DownloadUpdatedObserver(download, base::Bind(&DownloadCompleteFilter))
+ .WaitForEvent();
}
// Note: Cannot be used with other alternative DownloadFileFactorys
@@ -675,67 +602,35 @@ class DownloadContentTest : public ContentBrowserTest {
// Start a download and return the item.
DownloadItem* StartDownloadAndReturnItem(GURL url) {
scoped_ptr<DownloadCreateObserver> observer(
- CreateInProgressWaiter(shell(), 1));
+ new DownloadCreateObserver(DownloadManagerForShell(shell())));
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];
+ 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 +647,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());
svaldez 2015/11/12 20:25:51 Can this race and be in COMPLETE state?
asanka 2015/11/13 21:40:01 Great catch! In practice we get lucky, but only be
asanka 2015/11/14 03:32:47 Actually, no. I misspoke. Here and in the instance
// 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 +675,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 +839,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());
svaldez 2015/11/12 20:25:51 See above.
asanka 2015/11/13 21:40:00 Ditto.
// 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 +859,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 +881,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,288 +939,231 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownAtRelease) {
DownloadManagerForShell(shell())->Shutdown();
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeInterruptedDownload) {
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, Resume_BasicWithStrongValidators) {
Randy Smith (Not in Mondays) 2015/11/12 00:57:57 Does this really involve basic auth? It's not obv
asanka 2015/11/13 21:40:00 Basic meaning it's a basic test with no additional
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;
+ auto parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ auto interruption = parameters.injected_errors.front();
Randy Smith (Not in Mondays) 2015/11/12 00:57:57 nit, suggestion: I'm a little uncomfortable with a
asanka 2015/11/13 21:40:01 Done.
+ request_handler.StartServing(parameters);
- MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell()));
- EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
-
- DownloadItem* download(StartDownloadAndReturnItem(url));
- WaitForData(download, GetSafeBufferChunk());
- ::testing::Mock::VerifyAndClearExpectations(&dm_observer);
+ DownloadItem* download = StartDownloadAndReturnItem(request_handler.url());
+ WaitForInterrupt(download);
- // Confirm resumption while in progress doesn't do anything.
- download->Resume();
- ASSERT_EQ(GetSafeBufferChunk(), download->GetReceivedBytes());
- ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState());
+ ASSERT_EQ(interruption.offset, download->GetReceivedBytes());
+ ASSERT_EQ(parameters.size, download->GetTotalBytes());
- // 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.
Randy Smith (Not in Mondays) 2015/11/12 00:57:56 Suggestion: I'm not sure if it's worth it, but I t
asanka 2015/11/13 21:40:01 Yeah. I was thinking of ways to generalize it. The
Randy Smith (Not in Mondays) 2015/11/17 22:21:42 Hmmm. Maybe have an observer track total bytes tr
+ 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_content_length);
+
+ // The next request should only have transferred the remainder of the
+ // resource.
+ EXPECT_EQ(parameters.size - interruption.offset,
+ requests[1].transferred_content_length);
+
+ 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) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableDownloadResumption);
- ASSERT_TRUE(spawned_test_server()->Start());
-
- // 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()));
-
- // 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")));
-
- 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));
-}
-
-// Confirm restart fallback happens if a precondition is failed.
+// A partial resumption results in an HTTP 200 response. I.e. ther server
svaldez 2015/11/12 20:25:51 *the
asanka 2015/11/13 21:40:01 Done.
+// 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,
- ResumeInterruptedDownloadBadPrecondition) {
+ Resume_RestartIfNotPartialResponse) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
- ASSERT_TRUE(spawned_test_server()->Start());
+ const int kOriginalPatternGeneratorSeed = 1;
+ const int kNewPatternGeneratorSeed = 2;
- GURL url = spawned_test_server()->GetURL(base::StringPrintf(
- // First download hits an RST, rest don't, precondition fail.
- "rangereset?size=%d&rst_boundary=%d&"
- "token=BadPrecondition&rst_limit=1&fail_precondition=2",
- GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
+ TestDownloadRequestHandler::Parameters parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ parameters.pattern_generator_seed = kOriginalPatternGeneratorSeed;
+ const TestDownloadRequestHandler::InjectedError interruption =
Randy Smith (Not in Mondays) 2015/11/12 00:57:57 I would like you to be consistent about use or lac
asanka 2015/11/13 21:40:01 Yup. Did a consistency pass.
+ parameters.injected_errors.front();
- // Start the download and wait for first data chunk.
- DownloadItem* download(StartDownloadAndReturnItem(url));
- WaitForData(download, GetSafeBufferChunk());
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(parameters);
- RecordingDownloadObserver recorder(download);
+ DownloadItem* download = StartDownloadAndReturnItem(request_handler.url());
+ WaitForInterrupt(download);
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
- EXPECT_EQ("BadPrecondition2", download->GetETag());
+ ASSERT_EQ(interruption.offset, download->GetReceivedBytes());
+ ASSERT_EQ(parameters.size, download->GetTotalBytes());
- DownloadUpdatedObserver completion_observer(
- download, base::Bind(DownloadCompleteFilter));
- download->Resume();
- completion_observer.WaitForEvent();
+ parameters = TestDownloadRequestHandler::Parameters();
+ parameters.support_byte_ranges = false;
+ parameters.pattern_generator_seed = kNewPatternGeneratorSeed;
+ request_handler.StartServing(parameters);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset")));
- EXPECT_EQ("BadPrecondition0", download->GetETag());
-
- static const RecordingDownloadObserver::RecordStruct expected_record[] = {
- // Result of RST
- {DownloadItem::INTERRUPTED, GetSafeBufferChunk()},
- // Starting continuation
- {DownloadItem::IN_PROGRESS, GetSafeBufferChunk()},
- // Server precondition fail.
- {DownloadItem::INTERRUPTED, 0},
- // Notification of successful restart.
- {DownloadItem::IN_PROGRESS, 0},
- // Completion.
- {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3},
- };
-
- recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record));
+ download->Resume();
+ WaitForCompletion(download);
+
+ ASSERT_EQ(parameters.size, download->GetReceivedBytes());
+ ASSERT_EQ(parameters.size, download->GetTotalBytes());
+ ASSERT_NO_FATAL_FAILURE(
+ ReadAndVerifyFileContents(kNewPatternGeneratorSeed, 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.
Randy Smith (Not in Mondays) 2015/11/12 00:57:57 This is pretty much the same test as above, right?
asanka 2015/11/13 21:40:00 This one asserts that the resumption resulted in a
+ TestDownloadRequestHandler::CompletedRequests requests;
+ request_handler.GetCompletedRequestInfo(&requests);
+
+ ASSERT_EQ(2u, requests.size());
+
+ // The first request only sends data up to the interruption point.
+ EXPECT_EQ(interruption.offset, requests[0].transferred_content_length);
+
+ // The second request sends the entire response.
+ EXPECT_EQ(parameters.size, requests[1].transferred_content_length);
+
+ 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.
Randy Smith (Not in Mondays) 2015/11/12 00:57:57 nit, suggestion: I *think* the terminology we sett
asanka 2015/11/13 21:40:00 You're correct. Updated.
-IN_PROC_BROWSER_TEST_F(DownloadContentTest,
- ResumeInterruptedDownloadNoVerifiers) {
+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) {
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, Resume_RestartIfNoPartialFile) {
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
- "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());
+ TestDownloadRequestHandler::Parameters parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
- 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));
- DownloadUpdatedObserver completion_observer(
- download, base::Bind(DownloadCompleteFilter));
- download->Resume();
- completion_observer.WaitForEvent();
+ parameters.ClearInjectedErrors();
+ request_handler.StartServing(parameters);
- 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));
+ download->Resume();
+ 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()));
+
+ // The following verification is definitely a characterization test of
+ // implementation details. We are going to see three requests being made. The
+ // one in the middle is a partial request that is abandoned because the
+ // intermediate file is missing.
Randy Smith (Not in Mondays) 2015/11/12 00:57:57 I'm trying to come up with the failure modes we're
asanka 2015/11/13 21:40:01 We are verifying that the download logic abandons
+ TestDownloadRequestHandler::CompletedRequests requests;
+ request_handler.GetCompletedRequestInfo(&requests);
+ ASSERT_EQ(3u, requests.size());
+ EXPECT_EQ(parameters.size, requests[2].transferred_content_length);
+ std::string dummy_value;
+ EXPECT_FALSE(requests[2].request_headers.GetHeader(
+ net::HttpRequestHeaders::kRange, &dummy_value));
+ EXPECT_FALSE(requests[2].request_headers.GetHeader(
+ net::HttpRequestHeaders::kIfRange, &dummy_value));
}
-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
- };
+ 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());
@@ -1377,29 +1191,26 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileInitError) {
}
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
- };
+ 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());
@@ -1428,10 +1239,12 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE);
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileFinalRenameError) {
+IN_PROC_BROWSER_TEST_F(DownloadContentTest,
+ Resume_RecoverFromFinalRenameError) {
Randy Smith (Not in Mondays) 2015/11/12 00:57:57 Why two lines? (I suspect the answer is "git cl f
asanka 2015/11/13 21:40:00 'git cl format' :) but it's also 81 characters wit
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(
@@ -1439,19 +1252,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());
@@ -1483,23 +1292,17 @@ 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()));
+ TestDownloadRequestHandler::Parameters parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(parameters);
- DownloadItem* download(StartDownloadAndReturnItem(url1));
- WaitForData(download, GetSafeBufferChunk());
+ DownloadItem* download = StartDownloadAndReturnItem(request_handler.url());
+ WaitForInterrupt(download);
- ReleaseRSTAndConfirmInterruptForResume(download);
- ConfirmFileStatusForResume(
- download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
- base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
-
- 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);
@@ -1510,81 +1313,60 @@ 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::Parameters parameters =
+ TestDownloadRequestHandler::Parameters::WithSingleInterruption();
+ TestDownloadRequestHandler request_handler;
+ request_handler.StartServing(parameters);
- // 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());
@@ -1592,8 +1374,10 @@ 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);
download->Resume();
+ EXPECT_EQ(DownloadItem::INTERRUPTED, download->GetState());
Randy Smith (Not in Mondays) 2015/11/12 00:57:57 Is this characterization? Isn't it just because R
asanka 2015/11/13 21:40:01 Correct on both counts. I consider this to be an A
download->Remove();
// The intermediate file should now be gone.
@@ -1601,87 +1385,86 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveResumingDownload) {
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();
+ 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);
Randy Smith (Not in Mondays) 2015/11/12 00:57:57 Possibly we should go over the API contract detail
asanka 2015/11/13 21:40:01 Yup. Reworked in the same manner, but the API shou
download->Resume();
- download->Cancel(true);
+ EXPECT_EQ(DownloadItem::INTERRUPTED, download->GetState());
+ download->Cancel(true /* user_cancel */);
// The intermediate file should now be gone.
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();
+ 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.
@@ -1695,7 +1478,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
@@ -1727,7 +1510,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);
@@ -1775,7 +1558,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);
@@ -1794,12 +1577,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.
}

Powered by Google App Engine
This is Rietveld 408576698