This source file includes following definitions.
- ManagerGoingDown
- DownloadManagerForShell
- owner_
- RenameAndUniquify
- RenameAndAnnotate
- RenameCallbackWrapper
- waiting_
- CreateFile
- AddRenameCallback
- GetAllRenameCallbacks
- WaitForSomeCallback
- Initialize
- GetNumberActiveFiles
- GetNumberActiveFilesFromFileThread
- CreateFile
- ShouldOpenDownload
- SetDelayedOpen
- GetDelayedCallbacks
- CompareToExpectedRecord
- OnDownloadUpdated
- OnDownloadDestroyed
- RemoveObserver
- waiting_
- ManagerGoingDown
- OnDownloadCreated
- WaitForFinished
- DataReceivedFilter
- DownloadCompleteFilter
- InitialSizeFilter
- GetSafeBufferChunk
- SetUpOnMainThread
- GetDownloadManagerDelegate
- CreateWaiter
- CreateInProgressWaiter
- CreateInterruptedWaiter
- SetupEnsureNoPendingDownloads
- EnsureNoPendingDownloads
- DownloadAndWait
- VerifyFile
- StartDownloadAndReturnItem
- WaitForData
- ReleaseRSTAndConfirmInterruptForResume
- ConfirmFileStatusForResume
- EnsureNoPendingDownloadJobsOnIO
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "content/browser/byte_stream.h"
#include "content/browser/download/download_file_factory.h"
#include "content/browser/download/download_file_impl.h"
#include "content/browser/download/download_item_impl.h"
#include "content/browser/download/download_manager_impl.h"
#include "content/browser/download/download_resource_handler.h"
#include "content/browser/plugin_service_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/power_save_blocker.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/webplugininfo.h"
#include "content/public/test/browser_test_utils.h"
#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_file_error_injector.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_browser_context.h"
#include "content/shell/browser/shell_download_manager_delegate.h"
#include "content/shell/browser/shell_network_delegate.h"
#include "content/test/net/url_request_mock_http_job.h"
#include "content/test/net/url_request_slow_download_job.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
using ::testing::_;
using ::testing::AllOf;
using ::testing::Field;
using ::testing::InSequence;
using ::testing::Property;
using ::testing::Return;
using ::testing::StrictMock;
namespace content {
namespace {
class MockDownloadItemObserver : public DownloadItem::Observer {
public:
MockDownloadItemObserver() {}
virtual ~MockDownloadItemObserver() {}
MOCK_METHOD1(OnDownloadUpdated, void(DownloadItem*));
MOCK_METHOD1(OnDownloadOpened, void(DownloadItem*));
MOCK_METHOD1(OnDownloadRemoved, void(DownloadItem*));
MOCK_METHOD1(OnDownloadDestroyed, void(DownloadItem*));
};
class MockDownloadManagerObserver : public DownloadManager::Observer {
public:
MockDownloadManagerObserver(DownloadManager* manager) {
manager_ = manager;
manager->AddObserver(this);
}
virtual ~MockDownloadManagerObserver() {
if (manager_)
manager_->RemoveObserver(this);
}
MOCK_METHOD2(OnDownloadCreated, void(DownloadManager*, DownloadItem*));
MOCK_METHOD1(ModelChanged, void(DownloadManager*));
void ManagerGoingDown(DownloadManager* manager) {
DCHECK_EQ(manager_, manager);
MockManagerGoingDown(manager);
manager_->RemoveObserver(this);
manager_ = NULL;
}
MOCK_METHOD1(MockManagerGoingDown, void(DownloadManager*));
private:
DownloadManager* manager_;
};
class DownloadFileWithDelayFactory;
static DownloadManagerImpl* DownloadManagerForShell(Shell* shell) {
return static_cast<DownloadManagerImpl*>(
BrowserContext::GetDownloadManager(
shell->web_contents()->GetBrowserContext()));
}
class DownloadFileWithDelay : public DownloadFileImpl {
public:
DownloadFileWithDelay(
scoped_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_download_directory,
const GURL& url,
const GURL& referrer_url,
bool calculate_hash,
scoped_ptr<ByteStreamReader> stream,
const net::BoundNetLog& bound_net_log,
scoped_ptr<PowerSaveBlocker> power_save_blocker,
base::WeakPtr<DownloadDestinationObserver> observer,
base::WeakPtr<DownloadFileWithDelayFactory> owner);
virtual ~DownloadFileWithDelay();
virtual void RenameAndUniquify(
const base::FilePath& full_path,
const RenameCompletionCallback& callback) OVERRIDE;
virtual void RenameAndAnnotate(
const base::FilePath& full_path,
const RenameCompletionCallback& callback) OVERRIDE;
private:
static void RenameCallbackWrapper(
const base::WeakPtr<DownloadFileWithDelayFactory>& factory,
const RenameCompletionCallback& original_callback,
DownloadInterruptReason reason,
const base::FilePath& path);
base::WeakPtr<DownloadFileWithDelayFactory> owner_;
DISALLOW_COPY_AND_ASSIGN(DownloadFileWithDelay);
};
class DownloadFileWithDelayFactory : public DownloadFileFactory {
public:
DownloadFileWithDelayFactory();
virtual ~DownloadFileWithDelayFactory();
virtual DownloadFile* CreateFile(
scoped_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_download_directory,
const GURL& url,
const GURL& referrer_url,
bool calculate_hash,
scoped_ptr<ByteStreamReader> stream,
const net::BoundNetLog& bound_net_log,
base::WeakPtr<DownloadDestinationObserver> observer) OVERRIDE;
void AddRenameCallback(base::Closure callback);
void GetAllRenameCallbacks(std::vector<base::Closure>* results);
void WaitForSomeCallback();
private:
base::WeakPtrFactory<DownloadFileWithDelayFactory> weak_ptr_factory_;
std::vector<base::Closure> rename_callbacks_;
bool waiting_;
DISALLOW_COPY_AND_ASSIGN(DownloadFileWithDelayFactory);
};
DownloadFileWithDelay::DownloadFileWithDelay(
scoped_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_download_directory,
const GURL& url,
const GURL& referrer_url,
bool calculate_hash,
scoped_ptr<ByteStreamReader> stream,
const net::BoundNetLog& bound_net_log,
scoped_ptr<PowerSaveBlocker> power_save_blocker,
base::WeakPtr<DownloadDestinationObserver> observer,
base::WeakPtr<DownloadFileWithDelayFactory> owner)
: DownloadFileImpl(
save_info.Pass(), default_download_directory, url, referrer_url,
calculate_hash, stream.Pass(), bound_net_log,
power_save_blocker.Pass(), observer),
owner_(owner) {}
DownloadFileWithDelay::~DownloadFileWithDelay() {}
void DownloadFileWithDelay::RenameAndUniquify(
const base::FilePath& full_path,
const RenameCompletionCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
DownloadFileImpl::RenameAndUniquify(
full_path, base::Bind(DownloadFileWithDelay::RenameCallbackWrapper,
owner_, callback));
}
void DownloadFileWithDelay::RenameAndAnnotate(
const base::FilePath& full_path, const RenameCompletionCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
DownloadFileImpl::RenameAndAnnotate(
full_path, base::Bind(DownloadFileWithDelay::RenameCallbackWrapper,
owner_, callback));
}
void DownloadFileWithDelay::RenameCallbackWrapper(
const base::WeakPtr<DownloadFileWithDelayFactory>& factory,
const RenameCompletionCallback& original_callback,
DownloadInterruptReason reason,
const base::FilePath& path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!factory)
return;
factory->AddRenameCallback(base::Bind(original_callback, reason, path));
}
DownloadFileWithDelayFactory::DownloadFileWithDelayFactory()
: weak_ptr_factory_(this),
waiting_(false) {}
DownloadFileWithDelayFactory::~DownloadFileWithDelayFactory() {}
DownloadFile* DownloadFileWithDelayFactory::CreateFile(
scoped_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_download_directory,
const GURL& url,
const GURL& referrer_url,
bool calculate_hash,
scoped_ptr<ByteStreamReader> stream,
const net::BoundNetLog& bound_net_log,
base::WeakPtr<DownloadDestinationObserver> observer) {
scoped_ptr<PowerSaveBlocker> psb(
PowerSaveBlocker::Create(
PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
"Download in progress"));
return new DownloadFileWithDelay(
save_info.Pass(), default_download_directory, url, referrer_url,
calculate_hash, stream.Pass(), bound_net_log,
psb.Pass(), observer, weak_ptr_factory_.GetWeakPtr());
}
void DownloadFileWithDelayFactory::AddRenameCallback(base::Closure callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
rename_callbacks_.push_back(callback);
if (waiting_)
base::MessageLoopForUI::current()->Quit();
}
void DownloadFileWithDelayFactory::GetAllRenameCallbacks(
std::vector<base::Closure>* results) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
results->swap(rename_callbacks_);
}
void DownloadFileWithDelayFactory::WaitForSomeCallback() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (rename_callbacks_.empty()) {
waiting_ = true;
RunMessageLoop();
waiting_ = false;
}
}
class CountingDownloadFile : public DownloadFileImpl {
public:
CountingDownloadFile(
scoped_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_downloads_directory,
const GURL& url,
const GURL& referrer_url,
bool calculate_hash,
scoped_ptr<ByteStreamReader> stream,
const net::BoundNetLog& bound_net_log,
scoped_ptr<PowerSaveBlocker> power_save_blocker,
base::WeakPtr<DownloadDestinationObserver> observer)
: DownloadFileImpl(save_info.Pass(), default_downloads_directory,
url, referrer_url, calculate_hash,
stream.Pass(), bound_net_log,
power_save_blocker.Pass(), observer) {}
virtual ~CountingDownloadFile() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
active_files_--;
}
virtual void Initialize(const InitializeCallback& callback) OVERRIDE {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
active_files_++;
return DownloadFileImpl::Initialize(callback);
}
static void GetNumberActiveFiles(int* result) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
*result = active_files_;
}
static int GetNumberActiveFilesFromFileThread() {
int result = -1;
BrowserThread::PostTaskAndReply(
BrowserThread::FILE,
FROM_HERE,
base::Bind(&CountingDownloadFile::GetNumberActiveFiles, &result),
base::MessageLoop::current()->QuitClosure());
base::MessageLoop::current()->Run();
DCHECK_NE(-1, result);
return result;
}
private:
static int active_files_;
};
int CountingDownloadFile::active_files_ = 0;
class CountingDownloadFileFactory : public DownloadFileFactory {
public:
CountingDownloadFileFactory() {}
virtual ~CountingDownloadFileFactory() {}
virtual DownloadFile* CreateFile(
scoped_ptr<DownloadSaveInfo> save_info,
const base::FilePath& default_downloads_directory,
const GURL& url,
const GURL& referrer_url,
bool calculate_hash,
scoped_ptr<ByteStreamReader> stream,
const net::BoundNetLog& bound_net_log,
base::WeakPtr<DownloadDestinationObserver> observer) OVERRIDE {
scoped_ptr<PowerSaveBlocker> psb(
PowerSaveBlocker::Create(
PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
"Download in progress"));
return new CountingDownloadFile(
save_info.Pass(), default_downloads_directory, url, referrer_url,
calculate_hash, stream.Pass(), bound_net_log,
psb.Pass(), observer);
}
};
class TestShellDownloadManagerDelegate : public ShellDownloadManagerDelegate {
public:
TestShellDownloadManagerDelegate()
: delay_download_open_(false) {}
virtual ~TestShellDownloadManagerDelegate() {}
virtual bool ShouldOpenDownload(
DownloadItem* item,
const DownloadOpenDelayedCallback& callback) OVERRIDE {
if (delay_download_open_) {
delayed_callbacks_.push_back(callback);
return false;
}
return true;
}
void SetDelayedOpen(bool delay) {
delay_download_open_ = delay;
}
void GetDelayedCallbacks(
std::vector<DownloadOpenDelayedCallback>* callbacks) {
callbacks->swap(delayed_callbacks_);
}
private:
bool delay_download_open_;
std::vector<DownloadOpenDelayedCallback> delayed_callbacks_;
};
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);
}
virtual ~RecordingDownloadObserver() {
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:
virtual 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_);
}
}
virtual 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_;
};
class DownloadCreateObserver : DownloadManager::Observer {
public:
DownloadCreateObserver(DownloadManager* manager)
: manager_(manager),
item_(NULL),
waiting_(false) {
manager_->AddObserver(this);
}
virtual ~DownloadCreateObserver() {
if (manager_)
manager_->RemoveObserver(this);
manager_ = NULL;
}
virtual void ManagerGoingDown(DownloadManager* manager) OVERRIDE {
DCHECK_EQ(manager_, manager);
manager_->RemoveObserver(this);
manager_ = NULL;
}
virtual void OnDownloadCreated(DownloadManager* manager,
DownloadItem* download) OVERRIDE {
if (!item_)
item_ = download;
if (waiting_)
base::MessageLoopForUI::current()->Quit();
}
DownloadItem* WaitForFinished() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!item_) {
waiting_ = true;
RunMessageLoop();
waiting_ = false;
}
return item_;
}
private:
DownloadManager* manager_;
DownloadItem* item_;
bool waiting_;
};
bool DataReceivedFilter(int number_of_bytes, DownloadItem* download) {
return download->GetReceivedBytes() >= number_of_bytes;
}
bool DownloadCompleteFilter(DownloadItem* download) {
return download->GetState() == DownloadItem::COMPLETE;
}
bool InitialSizeFilter(int* download_size, DownloadItem* download) {
if (download->GetState() != DownloadItem::IN_PROGRESS)
return false;
*download_size = download->GetReceivedBytes();
return true;
}
}
class DownloadContentTest : public ContentBrowserTest {
protected:
int GetSafeBufferChunk() const {
return (DownloadResourceHandler::kDownloadByteStreamSize /
ByteStreamWriter::kFractionBufferBeforeSending) + 1;
}
virtual void SetUpOnMainThread() OVERRIDE {
ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
test_delegate_.reset(new TestShellDownloadManagerDelegate());
test_delegate_->SetDownloadBehaviorForTesting(downloads_directory_.path());
DownloadManager* manager = DownloadManagerForShell(shell());
manager->GetDelegate()->Shutdown();
manager->SetDelegate(test_delegate_.get());
test_delegate_->SetDownloadManager(manager);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&URLRequestSlowDownloadJob::AddUrlHandler));
base::FilePath mock_base(GetTestFilePath("download", ""));
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&URLRequestMockHTTPJob::AddUrlHandler, mock_base));
}
TestShellDownloadManagerDelegate* GetDownloadManagerDelegate() {
return test_delegate_.get();
}
DownloadTestObserver* CreateWaiter(
Shell* shell, int num_downloads) {
DownloadManager* download_manager = DownloadManagerForShell(shell);
return new DownloadTestObserverTerminal(download_manager, num_downloads,
DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
}
DownloadCreateObserver* CreateInProgressWaiter(
Shell* shell, int num_downloads) {
DownloadManager* download_manager = DownloadManagerForShell(shell);
return new DownloadCreateObserver(download_manager);
}
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 SetupEnsureNoPendingDownloads() {
DownloadManagerForShell(shell())->SetDownloadFileFactoryForTesting(
scoped_ptr<DownloadFileFactory>(
new CountingDownloadFileFactory()).Pass());
}
bool EnsureNoPendingDownloads() {
bool result = true;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&EnsureNoPendingDownloadJobsOnIO, &result));
base::MessageLoop::current()->Run();
return result &&
(CountingDownloadFile::GetNumberActiveFilesFromFileThread() == 0);
}
void DownloadAndWait(Shell* shell, const GURL& url,
DownloadItem::DownloadState expected_terminal_state) {
scoped_ptr<DownloadTestObserver> observer(CreateWaiter(shell, 1));
NavigateToURL(shell, url);
observer->WaitForFinished();
EXPECT_EQ(1u, observer->NumDownloadsSeenInState(expected_terminal_state));
}
bool VerifyFile(const base::FilePath& path,
const std::string& value,
const int64 file_size) {
std::string file_contents;
bool read = base::ReadFileToString(path, &file_contents);
EXPECT_TRUE(read) << "Failed reading file: " << path.value() << std::endl;
if (!read)
return false;
size_t expected_size = static_cast<size_t>(file_size);
EXPECT_EQ(expected_size, file_contents.size());
if (expected_size != file_contents.size())
return false;
EXPECT_EQ(value, file_contents);
if (memcmp(file_contents.c_str(), value.c_str(), expected_size) != 0)
return false;
return true;
}
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];
}
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());
}
void ReleaseRSTAndConfirmInterruptForResume(DownloadItem* download) {
scoped_ptr<DownloadTestObserver> rst_observer(
CreateInterruptedWaiter(shell(), 1));
NavigateToURL(shell(), test_server()->GetURL("download-finish"));
rst_observer->WaitForFinished();
EXPECT_EQ(DownloadItem::INTERRUPTED, download->GetState());
}
void ConfirmFileStatusForResume(
DownloadItem* download, bool file_exists,
int received_bytes, int total_bytes,
const base::FilePath& expected_filename) {
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;
}
}
}
private:
static void EnsureNoPendingDownloadJobsOnIO(bool* result) {
if (URLRequestSlowDownloadJob::NumberOutstandingRequests())
*result = false;
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE, base::MessageLoop::QuitClosure());
}
base::ScopedTempDir downloads_directory_;
scoped_ptr<TestShellDownloadManagerDelegate> test_delegate_;
};
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadCancelled) {
SetupEnsureNoPendingDownloads();
scoped_ptr<DownloadCreateObserver> observer(
CreateInProgressWaiter(shell(), 1));
NavigateToURL(shell(), GURL(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());
downloads[0]->Cancel(true);
scoped_refptr<DownloadTestFlushObserver> flush_observer(
new DownloadTestFlushObserver(DownloadManagerForShell(shell())));
flush_observer->WaitForFlush();
EXPECT_TRUE(EnsureNoPendingDownloads());
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, MultiDownload) {
SetupEnsureNoPendingDownloads();
scoped_ptr<DownloadCreateObserver> observer1(
CreateInProgressWaiter(shell(), 1));
NavigateToURL(shell(), GURL(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];
base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
DownloadAndWait(shell(), url, DownloadItem::COMPLETE);
downloads.clear();
DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
ASSERT_EQ(2u, downloads.size());
DownloadItem* download2 = downloads[(download1 == downloads[0]) ? 1 : 0];
ASSERT_EQ(DownloadItem::IN_PROGRESS, download1->GetState());
ASSERT_EQ(DownloadItem::COMPLETE, download2->GetState());
scoped_ptr<DownloadTestObserver> observer2(CreateWaiter(shell(), 1));
NavigateToURL(shell(), GURL(URLRequestSlowDownloadJob::kFinishDownloadUrl));
observer2->WaitForFinished();
EXPECT_EQ(1u, observer2->NumDownloadsSeenInState(DownloadItem::COMPLETE));
EXPECT_TRUE(EnsureNoPendingDownloads());
base::FilePath file1(download1->GetTargetFilePath());
size_t file_size1 = URLRequestSlowDownloadJob::kFirstDownloadSize +
URLRequestSlowDownloadJob::kSecondDownloadSize;
std::string expected_contents(file_size1, '*');
ASSERT_TRUE(VerifyFile(file1, expected_contents, file_size1));
base::FilePath file2(download2->GetTargetFilePath());
ASSERT_TRUE(base::ContentsEqual(
file2, GetTestFilePath("download", "download-test.lib")));
}
#if defined(ENABLE_PLUGINS)
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadOctetStream) {
const base::FilePath::CharType kTestFilePath[] =
FILE_PATH_LITERAL("octet-stream.abc");
const char kTestPluginName[] = "TestPlugin";
const char kTestMimeType[] = "application/x-test-mime-type";
const char kTestFileType[] = "abc";
WebPluginInfo plugin_info;
plugin_info.name = base::ASCIIToUTF16(kTestPluginName);
plugin_info.mime_types.push_back(
WebPluginMimeType(kTestMimeType, kTestFileType, ""));
PluginServiceImpl::GetInstance()->RegisterInternalPlugin(plugin_info, false);
GURL url(URLRequestMockHTTPJob::GetMockUrl(base::FilePath(kTestFilePath)));
DownloadAndWait(shell(), url, DownloadItem::COMPLETE);
}
#endif
IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelAtFinalRename) {
DownloadFileWithDelayFactory* file_factory =
new DownloadFileWithDelayFactory();
DownloadManagerImpl* download_manager(DownloadManagerForShell(shell()));
download_manager->SetDownloadFileFactoryForTesting(
scoped_ptr<DownloadFileFactory>(file_factory).Pass());
base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
NavigateToURL(shell(), URLRequestMockHTTPJob::GetMockUrl(file));
file_factory->WaitForSomeCallback();
std::vector<base::Closure> callbacks;
file_factory->GetAllRenameCallbacks(&callbacks);
ASSERT_EQ(1u, callbacks.size());
callbacks[0].Run();
callbacks.clear();
file_factory->WaitForSomeCallback();
file_factory->GetAllRenameCallbacks(&callbacks);
ASSERT_EQ(1u, callbacks.size());
std::vector<DownloadItem*> items;
download_manager->GetAllDownloads(&items);
ASSERT_EQ(1u, items.size());
items[0]->Cancel(true);
RunAllPendingInMessageLoop();
EXPECT_EQ(DownloadItem::CANCELLED, items[0]->GetState());
callbacks[0].Run();
callbacks.clear();
EXPECT_EQ(DownloadItem::CANCELLED, items[0]->GetState());
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelAtRelease) {
DownloadManagerImpl* download_manager(DownloadManagerForShell(shell()));
GetDownloadManagerDelegate()->SetDelayedOpen(true);
DownloadFileWithDelayFactory* file_factory =
new DownloadFileWithDelayFactory();
download_manager->SetDownloadFileFactoryForTesting(
scoped_ptr<DownloadFileFactory>(file_factory).Pass());
base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
NavigateToURL(shell(), URLRequestMockHTTPJob::GetMockUrl(file));
file_factory->WaitForSomeCallback();
std::vector<base::Closure> callbacks;
file_factory->GetAllRenameCallbacks(&callbacks);
ASSERT_EQ(1u, callbacks.size());
callbacks[0].Run();
callbacks.clear();
file_factory->WaitForSomeCallback();
file_factory->GetAllRenameCallbacks(&callbacks);
ASSERT_EQ(1u, callbacks.size());
callbacks[0].Run();
callbacks.clear();
std::vector<DownloadItem*> items;
download_manager->GetAllDownloads(&items);
EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());
ASSERT_EQ(1u, items.size());
items[0]->Cancel(true);
EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());
std::vector<DownloadOpenDelayedCallback> delayed_callbacks;
GetDownloadManagerDelegate()->GetDelayedCallbacks(
&delayed_callbacks);
ASSERT_EQ(1u, delayed_callbacks.size());
delayed_callbacks[0].Run(true);
EXPECT_EQ(DownloadItem::COMPLETE, items[0]->GetState());
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownInProgress) {
scoped_ptr<DownloadCreateObserver> observer(
CreateInProgressWaiter(shell(), 1));
NavigateToURL(shell(), GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl));
observer->WaitForFinished();
std::vector<DownloadItem*> items;
DownloadManagerForShell(shell())->GetAllDownloads(&items);
ASSERT_EQ(1u, items.size());
EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());
StrictMock<MockDownloadItemObserver> item_observer;
items[0]->AddObserver(&item_observer);
MockDownloadManagerObserver manager_observer(
DownloadManagerForShell(shell()));
EXPECT_CALL(manager_observer, ModelChanged(_))
.WillRepeatedly(Return());
{
InSequence notifications;
EXPECT_CALL(manager_observer, MockManagerGoingDown(
DownloadManagerForShell(shell())))
.WillOnce(Return());
EXPECT_CALL(item_observer, OnDownloadUpdated(
AllOf(items[0],
Property(&DownloadItem::GetState, DownloadItem::CANCELLED))))
.WillOnce(Return());
EXPECT_CALL(item_observer, OnDownloadDestroyed(items[0]))
.WillOnce(Return());
}
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&base::PlatformThread::Sleep,
base::TimeDelta::FromMilliseconds(25)));
DownloadManagerForShell(shell())->Shutdown();
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&base::PlatformThread::Sleep,
base::TimeDelta::FromMilliseconds(25)));
items.clear();
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownAtRelease) {
DownloadManagerImpl* download_manager(DownloadManagerForShell(shell()));
GetDownloadManagerDelegate()->SetDelayedOpen(true);
DownloadFileWithDelayFactory* file_factory =
new DownloadFileWithDelayFactory();
download_manager->SetDownloadFileFactoryForTesting(
scoped_ptr<DownloadFileFactory>(file_factory).Pass());
base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
NavigateToURL(shell(), URLRequestMockHTTPJob::GetMockUrl(file));
file_factory->WaitForSomeCallback();
std::vector<base::Closure> callbacks;
file_factory->GetAllRenameCallbacks(&callbacks);
ASSERT_EQ(1u, callbacks.size());
callbacks[0].Run();
callbacks.clear();
file_factory->WaitForSomeCallback();
file_factory->GetAllRenameCallbacks(&callbacks);
ASSERT_EQ(1u, callbacks.size());
callbacks[0].Run();
callbacks.clear();
std::vector<DownloadItem*> items;
DownloadManagerForShell(shell())->GetAllDownloads(&items);
EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());
ASSERT_EQ(1u, items.size());
items[0]->Cancel(true);
EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());
RunAllPendingInMessageLoop();
EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());
MockDownloadItemObserver observer;
items[0]->AddObserver(&observer);
EXPECT_CALL(observer, OnDownloadDestroyed(items[0]));
DownloadManagerForShell(shell())->Shutdown();
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeInterruptedDownload) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
ASSERT_TRUE(test_server()->Start());
GURL url = 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);
download->Resume();
ASSERT_EQ(GetSafeBufferChunk(), download->GetReceivedBytes());
ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState());
ReleaseRSTAndConfirmInterruptForResume(download);
ConfirmFileStatusForResume(
download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
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);
WaitForData(download, GetSafeBufferChunk() * 2);
ReleaseRSTAndConfirmInterruptForResume(download);
ConfirmFileStatusForResume(
download, true, GetSafeBufferChunk() * 2, 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")));
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());
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeInterruptedDownloadNoRange) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
ASSERT_TRUE(test_server()->Start());
GURL url = test_server()->GetURL(
base::StringPrintf(
"rangereset?size=%d&rst_boundary=%d&"
"token=NoRange&rst_limit=1&bounce_range",
GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
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[] = {
{DownloadItem::INTERRUPTED, GetSafeBufferChunk()},
{DownloadItem::IN_PROGRESS, GetSafeBufferChunk()},
{DownloadItem::IN_PROGRESS, 0},
{DownloadItem::COMPLETE, GetSafeBufferChunk() * 3},
};
recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record));
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest,
ResumeInterruptedDownloadBadPrecondition) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
ASSERT_TRUE(test_server()->Start());
GURL url = test_server()->GetURL(base::StringPrintf(
"rangereset?size=%d&rst_boundary=%d&"
"token=BadPrecondition&rst_limit=1&fail_precondition=2",
GetSafeBufferChunk() * 3,
GetSafeBufferChunk()));
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")));
EXPECT_EQ("BadPrecondition2", download->GetETag());
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")));
EXPECT_EQ("BadPrecondition0", download->GetETag());
static const RecordingDownloadObserver::RecordStruct expected_record[] = {
{DownloadItem::INTERRUPTED, GetSafeBufferChunk()},
{DownloadItem::IN_PROGRESS, GetSafeBufferChunk()},
{DownloadItem::INTERRUPTED, 0},
{DownloadItem::IN_PROGRESS, 0},
{DownloadItem::COMPLETE, GetSafeBufferChunk() * 3},
};
recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record));
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest,
ResumeInterruptedDownloadNoVerifiers) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
ASSERT_TRUE(test_server()->Start());
GURL url = test_server()->GetURL(
base::StringPrintf(
"rangereset?size=%d&rst_boundary=%d&"
"token=NoRange&rst_limit=1&no_verifiers",
GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
DownloadItem* download(StartDownloadAndReturnItem(url));
WaitForData(download, GetSafeBufferChunk());
RecordingDownloadObserver recorder(download);
ReleaseRSTAndConfirmInterruptForResume(download);
ConfirmFileStatusForResume(
download, false, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
base::FilePath());
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[] = {
{DownloadItem::INTERRUPTED, GetSafeBufferChunk()},
{DownloadItem::IN_PROGRESS, 0},
{DownloadItem::COMPLETE, GetSafeBufferChunk() * 3},
};
recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record));
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithDeletedFile) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
ASSERT_TRUE(test_server()->Start());
GURL url = test_server()->GetURL(
base::StringPrintf(
"rangereset?size=%d&rst_boundary=%d&"
"token=NoRange&rst_limit=1",
GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
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")));
base::DeleteFile(download->GetFullPath(), false);
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[] = {
{DownloadItem::INTERRUPTED, GetSafeBufferChunk()},
{DownloadItem::IN_PROGRESS, GetSafeBufferChunk()},
{DownloadItem::INTERRUPTED, 0},
{DownloadItem::IN_PROGRESS, 0},
{DownloadItem::COMPLETE, GetSafeBufferChunk() * 3},
};
recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record));
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileInitError) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
scoped_refptr<TestFileErrorInjector> injector(
TestFileErrorInjector::Create(DownloadManagerForShell(shell())));
TestFileErrorInjector::FileErrorInfo err = {
url.spec(),
TestFileErrorInjector::FILE_OPERATION_INITIALIZE,
0,
DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE
};
injector->AddError(err);
injector->InjectErrors();
scoped_ptr<DownloadTestObserver> int_observer(
CreateInterruptedWaiter(shell(), 1));
DownloadItem* download(StartDownloadAndReturnItem(url));
int_observer->WaitForFinished();
ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
download->GetLastReason());
EXPECT_EQ(0, download->GetReceivedBytes());
EXPECT_TRUE(download->GetFullPath().empty());
EXPECT_TRUE(download->GetTargetFilePath().empty());
RunAllPendingInMessageLoop(BrowserThread::FILE);
RunAllPendingInMessageLoop();
injector->ClearErrors();
injector->InjectErrors();
DownloadUpdatedObserver completion_observer(
download, base::Bind(DownloadCompleteFilter));
download->Resume();
completion_observer.WaitForEvent();
EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE);
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest,
ResumeWithFileIntermediateRenameError) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
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
};
injector->AddError(err);
injector->InjectErrors();
scoped_ptr<DownloadTestObserver> int_observer(
CreateInterruptedWaiter(shell(), 1));
DownloadItem* download(StartDownloadAndReturnItem(url));
int_observer->WaitForFinished();
ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
download->GetLastReason());
EXPECT_TRUE(download->GetFullPath().empty());
EXPECT_FALSE(download->GetTargetFilePath().empty());
RunAllPendingInMessageLoop(BrowserThread::FILE);
RunAllPendingInMessageLoop();
injector->ClearErrors();
injector->InjectErrors();
DownloadUpdatedObserver completion_observer(
download, base::Bind(DownloadCompleteFilter));
download->Resume();
completion_observer.WaitForEvent();
EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE);
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileFinalRenameError) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
scoped_refptr<TestFileErrorInjector> injector(
TestFileErrorInjector::Create(DownloadManagerForShell(shell())));
DownloadManagerForShell(shell())->RemoveAllDownloads();
TestFileErrorInjector::FileErrorInfo err = {
url.spec(),
TestFileErrorInjector::FILE_OPERATION_RENAME_ANNOTATE,
0,
DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE
};
injector->AddError(err);
injector->InjectErrors();
scoped_ptr<DownloadTestObserver> int_observer(
CreateInterruptedWaiter(shell(), 1));
DownloadItem* download(StartDownloadAndReturnItem(url));
int_observer->WaitForFinished();
ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
download->GetLastReason());
EXPECT_TRUE(download->GetFullPath().empty());
EXPECT_FALSE(download->GetTargetFilePath().empty());
RunAllPendingInMessageLoop(BrowserThread::FILE);
RunAllPendingInMessageLoop();
injector->ClearErrors();
injector->InjectErrors();
DownloadUpdatedObserver completion_observer(
download, base::Bind(DownloadCompleteFilter));
download->Resume();
completion_observer.WaitForEvent();
EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE);
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelInterruptedDownload) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
ASSERT_TRUE(test_server()->Start());
GURL url1 = 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->Cancel(true );
RunAllPendingInMessageLoop(BrowserThread::FILE);
RunAllPendingInMessageLoop();
EXPECT_FALSE(base::PathExists(intermediate_path));
EXPECT_TRUE(download->GetFullPath().empty());
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveDownload) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
ASSERT_TRUE(test_server()->Start());
{
GURL url1 = 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();
EXPECT_FALSE(base::PathExists(intermediate_path));
}
{
base::FilePath file2(FILE_PATH_LITERAL("download-test.lib"));
GURL url2(URLRequestMockHTTPJob::GetMockUrl(file2));
scoped_ptr<DownloadTestObserver> completion_observer(
CreateWaiter(shell(), 1));
DownloadItem* download(StartDownloadAndReturnItem(url2));
completion_observer->WaitForFinished();
base::FilePath target_path(download->GetTargetFilePath());
EXPECT_TRUE(base::PathExists(target_path));
download->Remove();
RunAllPendingInMessageLoop(BrowserThread::FILE);
RunAllPendingInMessageLoop();
EXPECT_TRUE(base::PathExists(target_path));
}
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveResumingDownload) {
SetupEnsureNoPendingDownloads();
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
ASSERT_TRUE(test_server()->Start());
GURL url = 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);
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));
EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
download->Resume();
download->Remove();
RunAllPendingInMessageLoop(BrowserThread::FILE);
RunAllPendingInMessageLoop();
EXPECT_FALSE(base::PathExists(intermediate_path));
GURL url2(test_server()->GetURL("rangereset?size=100&rst_limit=0&token=x"));
DownloadAndWait(shell(), url2, DownloadItem::COMPLETE);
EXPECT_TRUE(EnsureNoPendingDownloads());
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelResumingDownload) {
SetupEnsureNoPendingDownloads();
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableDownloadResumption);
ASSERT_TRUE(test_server()->Start());
GURL url = 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);
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));
EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
download->Resume();
download->Cancel(true);
RunAllPendingInMessageLoop(BrowserThread::FILE);
RunAllPendingInMessageLoop();
EXPECT_FALSE(base::PathExists(intermediate_path));
EXPECT_TRUE(download->GetFullPath().empty());
GURL url2(test_server()->GetURL("rangereset?size=100&rst_limit=0&token=x"));
DownloadAndWait(shell(), url2, DownloadItem::COMPLETE);
EXPECT_TRUE(EnsureNoPendingDownloads());
}
IN_PROC_BROWSER_TEST_F(DownloadContentTest, CookiePolicy) {
ASSERT_TRUE(test_server()->Start());
net::HostPortPair host_port = test_server()->host_port_pair();
DCHECK_EQ(host_port.host(), std::string("127.0.0.1"));
ShellNetworkDelegate::SetAcceptAllCookies(false);
std::string download(base::StringPrintf(
"http://localhost:%d/set-cookie?A=B", host_port.port()));
GURL url(test_server()->GetURL("server-redirect?" + download));
SetupEnsureNoPendingDownloads();
scoped_ptr<DownloadUrlParameters> dl_params(
DownloadUrlParameters::FromWebContents(shell()->web_contents(), url));
scoped_ptr<DownloadTestObserver> observer(CreateWaiter(shell(), 1));
DownloadManagerForShell(shell())->DownloadUrl(dl_params.Pass());
observer->WaitForFinished();
EXPECT_TRUE(EnsureNoPendingDownloads());
std::vector<DownloadItem*> downloads;
DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
ASSERT_EQ(1u, downloads.size());
ASSERT_EQ(DownloadItem::COMPLETE, downloads[0]->GetState());
EXPECT_EQ("A=B",
content::GetCookies(shell()->web_contents()->GetBrowserContext(),
GURL(download)));
}
}