Home | History | Annotate | Download | only in download
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // This file contains download browser tests that are known to be runnable
      6 // in a pure content context.  Over time tests should be migrated here.
      7 
      8 #include "base/command_line.h"
      9 #include "base/file_util.h"
     10 #include "base/files/file_path.h"
     11 #include "base/files/scoped_temp_dir.h"
     12 #include "base/strings/stringprintf.h"
     13 #include "base/strings/utf_string_conversions.h"
     14 #include "content/browser/byte_stream.h"
     15 #include "content/browser/download/download_file_factory.h"
     16 #include "content/browser/download/download_file_impl.h"
     17 #include "content/browser/download/download_item_impl.h"
     18 #include "content/browser/download/download_manager_impl.h"
     19 #include "content/browser/download/download_resource_handler.h"
     20 #include "content/browser/plugin_service_impl.h"
     21 #include "content/browser/web_contents/web_contents_impl.h"
     22 #include "content/public/browser/power_save_blocker.h"
     23 #include "content/public/common/content_switches.h"
     24 #include "content/public/common/webplugininfo.h"
     25 #include "content/public/test/browser_test_utils.h"
     26 #include "content/public/test/download_test_observer.h"
     27 #include "content/public/test/test_file_error_injector.h"
     28 #include "content/public/test/test_utils.h"
     29 #include "content/shell/browser/shell.h"
     30 #include "content/shell/browser/shell_browser_context.h"
     31 #include "content/shell/browser/shell_download_manager_delegate.h"
     32 #include "content/shell/browser/shell_network_delegate.h"
     33 #include "content/test/content_browser_test.h"
     34 #include "content/test/content_browser_test_utils.h"
     35 #include "content/test/net/url_request_mock_http_job.h"
     36 #include "content/test/net/url_request_slow_download_job.h"
     37 #include "net/test/spawned_test_server/spawned_test_server.h"
     38 #include "testing/gmock/include/gmock/gmock.h"
     39 #include "testing/gtest/include/gtest/gtest.h"
     40 #include "url/gurl.h"
     41 
     42 using ::testing::_;
     43 using ::testing::AllOf;
     44 using ::testing::Field;
     45 using ::testing::InSequence;
     46 using ::testing::Property;
     47 using ::testing::Return;
     48 using ::testing::StrictMock;
     49 
     50 namespace content {
     51 
     52 namespace {
     53 
     54 class MockDownloadItemObserver : public DownloadItem::Observer {
     55  public:
     56   MockDownloadItemObserver() {}
     57   virtual ~MockDownloadItemObserver() {}
     58 
     59   MOCK_METHOD1(OnDownloadUpdated, void(DownloadItem*));
     60   MOCK_METHOD1(OnDownloadOpened, void(DownloadItem*));
     61   MOCK_METHOD1(OnDownloadRemoved, void(DownloadItem*));
     62   MOCK_METHOD1(OnDownloadDestroyed, void(DownloadItem*));
     63 };
     64 
     65 class MockDownloadManagerObserver : public DownloadManager::Observer {
     66  public:
     67   MockDownloadManagerObserver(DownloadManager* manager) {
     68     manager_ = manager;
     69     manager->AddObserver(this);
     70   }
     71   virtual ~MockDownloadManagerObserver() {
     72     if (manager_)
     73       manager_->RemoveObserver(this);
     74   }
     75 
     76   MOCK_METHOD2(OnDownloadCreated, void(DownloadManager*, DownloadItem*));
     77   MOCK_METHOD1(ModelChanged, void(DownloadManager*));
     78   void ManagerGoingDown(DownloadManager* manager) {
     79     DCHECK_EQ(manager_, manager);
     80     MockManagerGoingDown(manager);
     81 
     82     manager_->RemoveObserver(this);
     83     manager_ = NULL;
     84   }
     85 
     86   MOCK_METHOD1(MockManagerGoingDown, void(DownloadManager*));
     87  private:
     88   DownloadManager* manager_;
     89 };
     90 
     91 class DownloadFileWithDelayFactory;
     92 
     93 static DownloadManagerImpl* DownloadManagerForShell(Shell* shell) {
     94   // We're in a content_browsertest; we know that the DownloadManager
     95   // is a DownloadManagerImpl.
     96   return static_cast<DownloadManagerImpl*>(
     97       BrowserContext::GetDownloadManager(
     98           shell->web_contents()->GetBrowserContext()));
     99 }
    100 
    101 class DownloadFileWithDelay : public DownloadFileImpl {
    102  public:
    103   DownloadFileWithDelay(
    104       scoped_ptr<DownloadSaveInfo> save_info,
    105       const base::FilePath& default_download_directory,
    106       const GURL& url,
    107       const GURL& referrer_url,
    108       bool calculate_hash,
    109       scoped_ptr<ByteStreamReader> stream,
    110       const net::BoundNetLog& bound_net_log,
    111       scoped_ptr<PowerSaveBlocker> power_save_blocker,
    112       base::WeakPtr<DownloadDestinationObserver> observer,
    113       base::WeakPtr<DownloadFileWithDelayFactory> owner);
    114 
    115   virtual ~DownloadFileWithDelay();
    116 
    117   // Wraps DownloadFileImpl::Rename* and intercepts the return callback,
    118   // storing it in the factory that produced this object for later
    119   // retrieval.
    120   virtual void RenameAndUniquify(
    121       const base::FilePath& full_path,
    122       const RenameCompletionCallback& callback) OVERRIDE;
    123   virtual void RenameAndAnnotate(
    124       const base::FilePath& full_path,
    125       const RenameCompletionCallback& callback) OVERRIDE;
    126 
    127  private:
    128   static void RenameCallbackWrapper(
    129       const base::WeakPtr<DownloadFileWithDelayFactory>& factory,
    130       const RenameCompletionCallback& original_callback,
    131       DownloadInterruptReason reason,
    132       const base::FilePath& path);
    133 
    134   // This variable may only be read on the FILE thread, and may only be
    135   // indirected through (e.g. methods on DownloadFileWithDelayFactory called)
    136   // on the UI thread.  This is because after construction,
    137   // DownloadFileWithDelay lives on the file thread, but
    138   // DownloadFileWithDelayFactory is purely a UI thread object.
    139   base::WeakPtr<DownloadFileWithDelayFactory> owner_;
    140 
    141   DISALLOW_COPY_AND_ASSIGN(DownloadFileWithDelay);
    142 };
    143 
    144 // All routines on this class must be called on the UI thread.
    145 class DownloadFileWithDelayFactory : public DownloadFileFactory {
    146  public:
    147   DownloadFileWithDelayFactory();
    148   virtual ~DownloadFileWithDelayFactory();
    149 
    150   // DownloadFileFactory interface.
    151   virtual DownloadFile* CreateFile(
    152       scoped_ptr<DownloadSaveInfo> save_info,
    153       const base::FilePath& default_download_directory,
    154       const GURL& url,
    155       const GURL& referrer_url,
    156       bool calculate_hash,
    157       scoped_ptr<ByteStreamReader> stream,
    158       const net::BoundNetLog& bound_net_log,
    159       base::WeakPtr<DownloadDestinationObserver> observer) OVERRIDE;
    160 
    161   void AddRenameCallback(base::Closure callback);
    162   void GetAllRenameCallbacks(std::vector<base::Closure>* results);
    163 
    164   // Do not return until GetAllRenameCallbacks() will return a non-empty list.
    165   void WaitForSomeCallback();
    166 
    167  private:
    168   base::WeakPtrFactory<DownloadFileWithDelayFactory> weak_ptr_factory_;
    169   std::vector<base::Closure> rename_callbacks_;
    170   bool waiting_;
    171 
    172   DISALLOW_COPY_AND_ASSIGN(DownloadFileWithDelayFactory);
    173 };
    174 
    175 DownloadFileWithDelay::DownloadFileWithDelay(
    176     scoped_ptr<DownloadSaveInfo> save_info,
    177     const base::FilePath& default_download_directory,
    178     const GURL& url,
    179     const GURL& referrer_url,
    180     bool calculate_hash,
    181     scoped_ptr<ByteStreamReader> stream,
    182     const net::BoundNetLog& bound_net_log,
    183     scoped_ptr<PowerSaveBlocker> power_save_blocker,
    184     base::WeakPtr<DownloadDestinationObserver> observer,
    185     base::WeakPtr<DownloadFileWithDelayFactory> owner)
    186     : DownloadFileImpl(
    187         save_info.Pass(), default_download_directory, url, referrer_url,
    188         calculate_hash, stream.Pass(), bound_net_log,
    189         power_save_blocker.Pass(), observer),
    190       owner_(owner) {}
    191 
    192 DownloadFileWithDelay::~DownloadFileWithDelay() {}
    193 
    194 void DownloadFileWithDelay::RenameAndUniquify(
    195     const base::FilePath& full_path,
    196     const RenameCompletionCallback& callback) {
    197   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
    198   DownloadFileImpl::RenameAndUniquify(
    199       full_path, base::Bind(DownloadFileWithDelay::RenameCallbackWrapper,
    200                             owner_, callback));
    201 }
    202 
    203 void DownloadFileWithDelay::RenameAndAnnotate(
    204     const base::FilePath& full_path, const RenameCompletionCallback& callback) {
    205   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
    206   DownloadFileImpl::RenameAndAnnotate(
    207       full_path, base::Bind(DownloadFileWithDelay::RenameCallbackWrapper,
    208                             owner_, callback));
    209 }
    210 
    211 // static
    212 void DownloadFileWithDelay::RenameCallbackWrapper(
    213     const base::WeakPtr<DownloadFileWithDelayFactory>& factory,
    214     const RenameCompletionCallback& original_callback,
    215     DownloadInterruptReason reason,
    216     const base::FilePath& path) {
    217   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    218   if (!factory)
    219     return;
    220   factory->AddRenameCallback(base::Bind(original_callback, reason, path));
    221 }
    222 
    223 DownloadFileWithDelayFactory::DownloadFileWithDelayFactory()
    224     : weak_ptr_factory_(this),
    225       waiting_(false) {}
    226 DownloadFileWithDelayFactory::~DownloadFileWithDelayFactory() {}
    227 
    228 DownloadFile* DownloadFileWithDelayFactory::CreateFile(
    229     scoped_ptr<DownloadSaveInfo> save_info,
    230     const base::FilePath& default_download_directory,
    231     const GURL& url,
    232     const GURL& referrer_url,
    233     bool calculate_hash,
    234     scoped_ptr<ByteStreamReader> stream,
    235     const net::BoundNetLog& bound_net_log,
    236     base::WeakPtr<DownloadDestinationObserver> observer) {
    237   scoped_ptr<PowerSaveBlocker> psb(
    238       PowerSaveBlocker::Create(
    239           PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
    240           "Download in progress"));
    241   return new DownloadFileWithDelay(
    242       save_info.Pass(), default_download_directory, url, referrer_url,
    243       calculate_hash, stream.Pass(), bound_net_log,
    244       psb.Pass(), observer, weak_ptr_factory_.GetWeakPtr());
    245 }
    246 
    247 void DownloadFileWithDelayFactory::AddRenameCallback(base::Closure callback) {
    248   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    249   rename_callbacks_.push_back(callback);
    250   if (waiting_)
    251     base::MessageLoopForUI::current()->Quit();
    252 }
    253 
    254 void DownloadFileWithDelayFactory::GetAllRenameCallbacks(
    255     std::vector<base::Closure>* results) {
    256   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    257   results->swap(rename_callbacks_);
    258 }
    259 
    260 void DownloadFileWithDelayFactory::WaitForSomeCallback() {
    261   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    262 
    263   if (rename_callbacks_.empty()) {
    264     waiting_ = true;
    265     RunMessageLoop();
    266     waiting_ = false;
    267   }
    268 }
    269 
    270 class CountingDownloadFile : public DownloadFileImpl {
    271  public:
    272   CountingDownloadFile(
    273     scoped_ptr<DownloadSaveInfo> save_info,
    274     const base::FilePath& default_downloads_directory,
    275     const GURL& url,
    276     const GURL& referrer_url,
    277     bool calculate_hash,
    278     scoped_ptr<ByteStreamReader> stream,
    279     const net::BoundNetLog& bound_net_log,
    280     scoped_ptr<PowerSaveBlocker> power_save_blocker,
    281     base::WeakPtr<DownloadDestinationObserver> observer)
    282       : DownloadFileImpl(save_info.Pass(), default_downloads_directory,
    283                          url, referrer_url, calculate_hash,
    284                          stream.Pass(), bound_net_log,
    285                          power_save_blocker.Pass(), observer) {}
    286 
    287   virtual ~CountingDownloadFile() {
    288     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
    289     active_files_--;
    290   }
    291 
    292   virtual void Initialize(const InitializeCallback& callback) OVERRIDE {
    293     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
    294     active_files_++;
    295     return DownloadFileImpl::Initialize(callback);
    296   }
    297 
    298   static void GetNumberActiveFiles(int* result) {
    299     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
    300     *result = active_files_;
    301   }
    302 
    303   // Can be called on any thread, and will block (running message loop)
    304   // until data is returned.
    305   static int GetNumberActiveFilesFromFileThread() {
    306     int result = -1;
    307     BrowserThread::PostTaskAndReply(
    308         BrowserThread::FILE,
    309         FROM_HERE,
    310         base::Bind(&CountingDownloadFile::GetNumberActiveFiles, &result),
    311         base::MessageLoop::current()->QuitClosure());
    312     base::MessageLoop::current()->Run();
    313     DCHECK_NE(-1, result);
    314     return result;
    315   }
    316 
    317  private:
    318   static int active_files_;
    319 };
    320 
    321 int CountingDownloadFile::active_files_ = 0;
    322 
    323 class CountingDownloadFileFactory : public DownloadFileFactory {
    324  public:
    325   CountingDownloadFileFactory() {}
    326   virtual ~CountingDownloadFileFactory() {}
    327 
    328   // DownloadFileFactory interface.
    329   virtual DownloadFile* CreateFile(
    330     scoped_ptr<DownloadSaveInfo> save_info,
    331     const base::FilePath& default_downloads_directory,
    332     const GURL& url,
    333     const GURL& referrer_url,
    334     bool calculate_hash,
    335     scoped_ptr<ByteStreamReader> stream,
    336     const net::BoundNetLog& bound_net_log,
    337     base::WeakPtr<DownloadDestinationObserver> observer) OVERRIDE {
    338     scoped_ptr<PowerSaveBlocker> psb(
    339         PowerSaveBlocker::Create(
    340             PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
    341             "Download in progress"));
    342     return new CountingDownloadFile(
    343         save_info.Pass(), default_downloads_directory, url, referrer_url,
    344         calculate_hash, stream.Pass(), bound_net_log,
    345         psb.Pass(), observer);
    346   }
    347 };
    348 
    349 class TestShellDownloadManagerDelegate : public ShellDownloadManagerDelegate {
    350  public:
    351   TestShellDownloadManagerDelegate()
    352       : delay_download_open_(false) {}
    353 
    354   virtual bool ShouldOpenDownload(
    355       DownloadItem* item,
    356       const DownloadOpenDelayedCallback& callback) OVERRIDE {
    357     if (delay_download_open_) {
    358       delayed_callbacks_.push_back(callback);
    359       return false;
    360     }
    361     return true;
    362   }
    363 
    364   void SetDelayedOpen(bool delay) {
    365     delay_download_open_ = delay;
    366   }
    367 
    368   void GetDelayedCallbacks(
    369       std::vector<DownloadOpenDelayedCallback>* callbacks) {
    370     callbacks->swap(delayed_callbacks_);
    371   }
    372  private:
    373   virtual ~TestShellDownloadManagerDelegate() {}
    374 
    375   bool delay_download_open_;
    376   std::vector<DownloadOpenDelayedCallback> delayed_callbacks_;
    377 };
    378 
    379 // Record all state transitions and byte counts on the observed download.
    380 class RecordingDownloadObserver : DownloadItem::Observer {
    381  public:
    382   struct RecordStruct {
    383     DownloadItem::DownloadState state;
    384     int bytes_received;
    385   };
    386 
    387   typedef std::vector<RecordStruct> RecordVector;
    388 
    389   RecordingDownloadObserver(DownloadItem* download)
    390       : download_(download) {
    391     last_state_.state = download->GetState();
    392     last_state_.bytes_received = download->GetReceivedBytes();
    393     download_->AddObserver(this);
    394   }
    395 
    396   virtual ~RecordingDownloadObserver() {
    397     RemoveObserver();
    398   }
    399 
    400   void CompareToExpectedRecord(const RecordStruct expected[], size_t size) {
    401     EXPECT_EQ(size, record_.size());
    402     int min = size > record_.size() ? record_.size() : size;
    403     for (int i = 0; i < min; ++i) {
    404       EXPECT_EQ(expected[i].state, record_[i].state) << "Iteration " << i;
    405       EXPECT_EQ(expected[i].bytes_received, record_[i].bytes_received)
    406           << "Iteration " << i;
    407     }
    408   }
    409 
    410  private:
    411   virtual void OnDownloadUpdated(DownloadItem* download) OVERRIDE {
    412     DCHECK_EQ(download_, download);
    413     DownloadItem::DownloadState state = download->GetState();
    414     int bytes = download->GetReceivedBytes();
    415     if (last_state_.state != state || last_state_.bytes_received > bytes) {
    416       last_state_.state = state;
    417       last_state_.bytes_received = bytes;
    418       record_.push_back(last_state_);
    419     }
    420   }
    421 
    422   virtual void OnDownloadDestroyed(DownloadItem* download) OVERRIDE {
    423     DCHECK_EQ(download_, download);
    424     RemoveObserver();
    425   }
    426 
    427   void RemoveObserver() {
    428     if (download_) {
    429       download_->RemoveObserver(this);
    430       download_ = NULL;
    431     }
    432   }
    433 
    434   DownloadItem* download_;
    435   RecordStruct last_state_;
    436   RecordVector record_;
    437 };
    438 
    439 // Get the next created download.
    440 class DownloadCreateObserver : DownloadManager::Observer {
    441  public:
    442   DownloadCreateObserver(DownloadManager* manager)
    443       : manager_(manager),
    444         item_(NULL),
    445         waiting_(false) {
    446     manager_->AddObserver(this);
    447   }
    448 
    449   virtual ~DownloadCreateObserver() {
    450     if (manager_)
    451       manager_->RemoveObserver(this);
    452     manager_ = NULL;
    453   }
    454 
    455   virtual void ManagerGoingDown(DownloadManager* manager) OVERRIDE {
    456     DCHECK_EQ(manager_, manager);
    457     manager_->RemoveObserver(this);
    458     manager_ = NULL;
    459   }
    460 
    461   virtual void OnDownloadCreated(DownloadManager* manager,
    462                                  DownloadItem* download) OVERRIDE {
    463     if (!item_)
    464       item_ = download;
    465 
    466     if (waiting_)
    467       base::MessageLoopForUI::current()->Quit();
    468   }
    469 
    470   DownloadItem* WaitForFinished() {
    471     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    472     if (!item_) {
    473       waiting_ = true;
    474       RunMessageLoop();
    475       waiting_ = false;
    476     }
    477     return item_;
    478   }
    479 
    480  private:
    481   DownloadManager* manager_;
    482   DownloadItem* item_;
    483   bool waiting_;
    484 };
    485 
    486 
    487 // Filter for waiting for a certain number of bytes.
    488 bool DataReceivedFilter(int number_of_bytes, DownloadItem* download) {
    489   return download->GetReceivedBytes() >= number_of_bytes;
    490 }
    491 
    492 // Filter for download completion.
    493 bool DownloadCompleteFilter(DownloadItem* download) {
    494   return download->GetState() == DownloadItem::COMPLETE;
    495 }
    496 
    497 // Filter for saving the size of the download when the first IN_PROGRESS
    498 // is hit.
    499 bool InitialSizeFilter(int* download_size, DownloadItem* download) {
    500   if (download->GetState() != DownloadItem::IN_PROGRESS)
    501     return false;
    502 
    503   *download_size = download->GetReceivedBytes();
    504   return true;
    505 }
    506 
    507 }  // namespace
    508 
    509 class DownloadContentTest : public ContentBrowserTest {
    510  protected:
    511   // An initial send from a website of at least this size will not be
    512   // help up by buffering in the underlying downloads ByteStream data
    513   // transfer.  This is important because on resumption tests we wait
    514   // until we've gotten the data we expect before allowing the test server
    515   // to send its reset, to get around hard close semantics on the Windows
    516   // socket layer implementation.
    517   int GetSafeBufferChunk() const {
    518     return (DownloadResourceHandler::kDownloadByteStreamSize /
    519        ByteStreamWriter::kFractionBufferBeforeSending) + 1;
    520   }
    521 
    522   virtual void SetUpOnMainThread() OVERRIDE {
    523     ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
    524 
    525     TestShellDownloadManagerDelegate* delegate =
    526         new TestShellDownloadManagerDelegate();
    527     delegate->SetDownloadBehaviorForTesting(downloads_directory_.path());
    528     DownloadManager* manager = DownloadManagerForShell(shell());
    529     manager->SetDelegate(delegate);
    530     delegate->SetDownloadManager(manager);
    531 
    532     BrowserThread::PostTask(
    533         BrowserThread::IO, FROM_HERE,
    534         base::Bind(&URLRequestSlowDownloadJob::AddUrlHandler));
    535     base::FilePath mock_base(GetTestFilePath("download", ""));
    536     BrowserThread::PostTask(
    537         BrowserThread::IO, FROM_HERE,
    538         base::Bind(&URLRequestMockHTTPJob::AddUrlHandler, mock_base));
    539   }
    540 
    541   TestShellDownloadManagerDelegate* GetDownloadManagerDelegate(
    542       DownloadManager* manager) {
    543     return static_cast<TestShellDownloadManagerDelegate*>(
    544         manager->GetDelegate());
    545   }
    546 
    547   // Create a DownloadTestObserverTerminal that will wait for the
    548   // specified number of downloads to finish.
    549   DownloadTestObserver* CreateWaiter(
    550       Shell* shell, int num_downloads) {
    551     DownloadManager* download_manager = DownloadManagerForShell(shell);
    552     return new DownloadTestObserverTerminal(download_manager, num_downloads,
    553         DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
    554   }
    555 
    556   // Create a DownloadTestObserverInProgress that will wait for the
    557   // specified number of downloads to start.
    558   DownloadCreateObserver* CreateInProgressWaiter(
    559       Shell* shell, int num_downloads) {
    560     DownloadManager* download_manager = DownloadManagerForShell(shell);
    561     return new DownloadCreateObserver(download_manager);
    562   }
    563 
    564   DownloadTestObserver* CreateInterruptedWaiter(
    565       Shell* shell, int num_downloads) {
    566     DownloadManager* download_manager = DownloadManagerForShell(shell);
    567     return new DownloadTestObserverInterrupted(download_manager, num_downloads,
    568         DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
    569   }
    570 
    571   // Note: Cannot be used with other alternative DownloadFileFactorys
    572   void SetupEnsureNoPendingDownloads() {
    573     DownloadManagerForShell(shell())->SetDownloadFileFactoryForTesting(
    574         scoped_ptr<DownloadFileFactory>(
    575             new CountingDownloadFileFactory()).Pass());
    576   }
    577 
    578   bool EnsureNoPendingDownloads() {
    579     bool result = true;
    580     BrowserThread::PostTask(
    581         BrowserThread::IO, FROM_HERE,
    582         base::Bind(&EnsureNoPendingDownloadJobsOnIO, &result));
    583     base::MessageLoop::current()->Run();
    584     return result &&
    585            (CountingDownloadFile::GetNumberActiveFilesFromFileThread() == 0);
    586   }
    587 
    588   void DownloadAndWait(Shell* shell, const GURL& url,
    589                        DownloadItem::DownloadState expected_terminal_state) {
    590     scoped_ptr<DownloadTestObserver> observer(CreateWaiter(shell, 1));
    591     NavigateToURL(shell, url);
    592     observer->WaitForFinished();
    593     EXPECT_EQ(1u, observer->NumDownloadsSeenInState(expected_terminal_state));
    594   }
    595 
    596   // Checks that |path| is has |file_size| bytes, and matches the |value|
    597   // string.
    598   bool VerifyFile(const base::FilePath& path,
    599                   const std::string& value,
    600                   const int64 file_size) {
    601     std::string file_contents;
    602 
    603     bool read = base::ReadFileToString(path, &file_contents);
    604     EXPECT_TRUE(read) << "Failed reading file: " << path.value() << std::endl;
    605     if (!read)
    606       return false;  // Couldn't read the file.
    607 
    608     // Note: we don't handle really large files (more than size_t can hold)
    609     // so we will fail in that case.
    610     size_t expected_size = static_cast<size_t>(file_size);
    611 
    612     // Check the size.
    613     EXPECT_EQ(expected_size, file_contents.size());
    614     if (expected_size != file_contents.size())
    615       return false;
    616 
    617     // Check the contents.
    618     EXPECT_EQ(value, file_contents);
    619     if (memcmp(file_contents.c_str(), value.c_str(), expected_size) != 0)
    620       return false;
    621 
    622     return true;
    623   }
    624 
    625   // Start a download and return the item.
    626   DownloadItem* StartDownloadAndReturnItem(GURL url) {
    627     scoped_ptr<DownloadCreateObserver> observer(
    628         CreateInProgressWaiter(shell(), 1));
    629     NavigateToURL(shell(), url);
    630     observer->WaitForFinished();
    631     std::vector<DownloadItem*> downloads;
    632     DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
    633     EXPECT_EQ(1u, downloads.size());
    634     if (1u != downloads.size())
    635       return NULL;
    636     return downloads[0];
    637   }
    638 
    639   // Wait for data
    640   void WaitForData(DownloadItem* download, int size) {
    641     DownloadUpdatedObserver data_observer(
    642         download, base::Bind(&DataReceivedFilter, size));
    643     data_observer.WaitForEvent();
    644     ASSERT_EQ(size, download->GetReceivedBytes());
    645     ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState());
    646   }
    647 
    648   // Tell the test server to release a pending RST and confirm
    649   // that the interrupt is received properly (for download resumption
    650   // testing).
    651   void ReleaseRSTAndConfirmInterruptForResume(DownloadItem* download) {
    652     scoped_ptr<DownloadTestObserver> rst_observer(
    653         CreateInterruptedWaiter(shell(), 1));
    654     NavigateToURL(shell(), test_server()->GetURL("download-finish"));
    655     rst_observer->WaitForFinished();
    656     EXPECT_EQ(DownloadItem::INTERRUPTED, download->GetState());
    657   }
    658 
    659   // Confirm file status expected for the given location in a stream
    660   // provided by the resume test server.
    661   void ConfirmFileStatusForResume(
    662       DownloadItem* download, bool file_exists,
    663       int received_bytes, int total_bytes,
    664       const base::FilePath& expected_filename) {
    665     // expected_filename is only known if the file exists.
    666     ASSERT_EQ(file_exists, !expected_filename.empty());
    667     EXPECT_EQ(received_bytes, download->GetReceivedBytes());
    668     EXPECT_EQ(total_bytes, download->GetTotalBytes());
    669     EXPECT_EQ(expected_filename.value(),
    670               download->GetFullPath().BaseName().value());
    671     EXPECT_EQ(file_exists,
    672               (!download->GetFullPath().empty() &&
    673                base::PathExists(download->GetFullPath())));
    674 
    675     if (file_exists) {
    676       std::string file_contents;
    677       EXPECT_TRUE(base::ReadFileToString(
    678           download->GetFullPath(), &file_contents));
    679 
    680       ASSERT_EQ(static_cast<size_t>(received_bytes), file_contents.size());
    681       for (int i = 0; i < received_bytes; ++i) {
    682         EXPECT_EQ(static_cast<char>((i * 2 + 15) % 256), file_contents[i])
    683             << "File contents diverged at position " << i
    684             << " for " << expected_filename.value();
    685 
    686         if (static_cast<char>((i * 2 + 15) % 256) != file_contents[i])
    687           return;
    688       }
    689     }
    690   }
    691 
    692  private:
    693   static void EnsureNoPendingDownloadJobsOnIO(bool* result) {
    694     if (URLRequestSlowDownloadJob::NumberOutstandingRequests())
    695       *result = false;
    696     BrowserThread::PostTask(
    697         BrowserThread::UI, FROM_HERE, base::MessageLoop::QuitClosure());
    698   }
    699 
    700   // Location of the downloads directory for these tests
    701   base::ScopedTempDir downloads_directory_;
    702 };
    703 
    704 IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadCancelled) {
    705   SetupEnsureNoPendingDownloads();
    706 
    707   // Create a download, wait until it's started, and confirm
    708   // we're in the expected state.
    709   scoped_ptr<DownloadCreateObserver> observer(
    710       CreateInProgressWaiter(shell(), 1));
    711   NavigateToURL(shell(), GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl));
    712   observer->WaitForFinished();
    713 
    714   std::vector<DownloadItem*> downloads;
    715   DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
    716   ASSERT_EQ(1u, downloads.size());
    717   ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->GetState());
    718 
    719   // Cancel the download and wait for download system quiesce.
    720   downloads[0]->Cancel(true);
    721   scoped_refptr<DownloadTestFlushObserver> flush_observer(
    722       new DownloadTestFlushObserver(DownloadManagerForShell(shell())));
    723   flush_observer->WaitForFlush();
    724 
    725   // Get the important info from other threads and check it.
    726   EXPECT_TRUE(EnsureNoPendingDownloads());
    727 }
    728 
    729 // Check that downloading multiple (in this case, 2) files does not result in
    730 // corrupted files.
    731 IN_PROC_BROWSER_TEST_F(DownloadContentTest, MultiDownload) {
    732   SetupEnsureNoPendingDownloads();
    733 
    734   // Create a download, wait until it's started, and confirm
    735   // we're in the expected state.
    736   scoped_ptr<DownloadCreateObserver> observer1(
    737       CreateInProgressWaiter(shell(), 1));
    738   NavigateToURL(shell(), GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl));
    739   observer1->WaitForFinished();
    740 
    741   std::vector<DownloadItem*> downloads;
    742   DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
    743   ASSERT_EQ(1u, downloads.size());
    744   ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->GetState());
    745   DownloadItem* download1 = downloads[0];  // The only download.
    746 
    747   // Start the second download and wait until it's done.
    748   base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
    749   GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
    750   // Download the file and wait.
    751   DownloadAndWait(shell(), url, DownloadItem::COMPLETE);
    752 
    753   // Should now have 2 items on the manager.
    754   downloads.clear();
    755   DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
    756   ASSERT_EQ(2u, downloads.size());
    757   // We don't know the order of the downloads.
    758   DownloadItem* download2 = downloads[(download1 == downloads[0]) ? 1 : 0];
    759 
    760   ASSERT_EQ(DownloadItem::IN_PROGRESS, download1->GetState());
    761   ASSERT_EQ(DownloadItem::COMPLETE, download2->GetState());
    762 
    763   // Allow the first request to finish.
    764   scoped_ptr<DownloadTestObserver> observer2(CreateWaiter(shell(), 1));
    765   NavigateToURL(shell(), GURL(URLRequestSlowDownloadJob::kFinishDownloadUrl));
    766   observer2->WaitForFinished();  // Wait for the third request.
    767   EXPECT_EQ(1u, observer2->NumDownloadsSeenInState(DownloadItem::COMPLETE));
    768 
    769   // Get the important info from other threads and check it.
    770   EXPECT_TRUE(EnsureNoPendingDownloads());
    771 
    772   // The |DownloadItem|s should now be done and have the final file names.
    773   // Verify that the files have the expected data and size.
    774   // |file1| should be full of '*'s, and |file2| should be the same as the
    775   // source file.
    776   base::FilePath file1(download1->GetTargetFilePath());
    777   size_t file_size1 = URLRequestSlowDownloadJob::kFirstDownloadSize +
    778                       URLRequestSlowDownloadJob::kSecondDownloadSize;
    779   std::string expected_contents(file_size1, '*');
    780   ASSERT_TRUE(VerifyFile(file1, expected_contents, file_size1));
    781 
    782   base::FilePath file2(download2->GetTargetFilePath());
    783   ASSERT_TRUE(base::ContentsEqual(
    784       file2, GetTestFilePath("download", "download-test.lib")));
    785 }
    786 
    787 #if defined(ENABLE_PLUGINS)
    788 // Content served with a MIME type of application/octet-stream should be
    789 // downloaded even when a plugin can be found that handles the file type.
    790 IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadOctetStream) {
    791   const base::FilePath::CharType kTestFilePath[] =
    792       FILE_PATH_LITERAL("octet-stream.abc");
    793   const char kTestPluginName[] = "TestPlugin";
    794   const char kTestMimeType[] = "application/x-test-mime-type";
    795   const char kTestFileType[] = "abc";
    796 
    797   WebPluginInfo plugin_info;
    798   plugin_info.name = base::ASCIIToUTF16(kTestPluginName);
    799   plugin_info.mime_types.push_back(
    800       WebPluginMimeType(kTestMimeType, kTestFileType, ""));
    801   PluginServiceImpl::GetInstance()->RegisterInternalPlugin(plugin_info, false);
    802 
    803   // The following is served with a Content-Type of application/octet-stream.
    804   GURL url(URLRequestMockHTTPJob::GetMockUrl(base::FilePath(kTestFilePath)));
    805   DownloadAndWait(shell(), url, DownloadItem::COMPLETE);
    806 }
    807 #endif
    808 
    809 // Try to cancel just before we release the download file, by delaying final
    810 // rename callback.
    811 IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelAtFinalRename) {
    812   // Setup new factory.
    813   DownloadFileWithDelayFactory* file_factory =
    814       new DownloadFileWithDelayFactory();
    815   DownloadManagerImpl* download_manager(DownloadManagerForShell(shell()));
    816   download_manager->SetDownloadFileFactoryForTesting(
    817       scoped_ptr<DownloadFileFactory>(file_factory).Pass());
    818 
    819   // Create a download
    820   base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
    821   NavigateToURL(shell(), URLRequestMockHTTPJob::GetMockUrl(file));
    822 
    823   // Wait until the first (intermediate file) rename and execute the callback.
    824   file_factory->WaitForSomeCallback();
    825   std::vector<base::Closure> callbacks;
    826   file_factory->GetAllRenameCallbacks(&callbacks);
    827   ASSERT_EQ(1u, callbacks.size());
    828   callbacks[0].Run();
    829   callbacks.clear();
    830 
    831   // Wait until the second (final) rename callback is posted.
    832   file_factory->WaitForSomeCallback();
    833   file_factory->GetAllRenameCallbacks(&callbacks);
    834   ASSERT_EQ(1u, callbacks.size());
    835 
    836   // Cancel it.
    837   std::vector<DownloadItem*> items;
    838   download_manager->GetAllDownloads(&items);
    839   ASSERT_EQ(1u, items.size());
    840   items[0]->Cancel(true);
    841   RunAllPendingInMessageLoop();
    842 
    843   // Check state.
    844   EXPECT_EQ(DownloadItem::CANCELLED, items[0]->GetState());
    845 
    846   // Run final rename callback.
    847   callbacks[0].Run();
    848   callbacks.clear();
    849 
    850   // Check state.
    851   EXPECT_EQ(DownloadItem::CANCELLED, items[0]->GetState());
    852 }
    853 
    854 // Try to cancel just after we release the download file, by delaying
    855 // in ShouldOpenDownload.
    856 IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelAtRelease) {
    857   DownloadManagerImpl* download_manager(DownloadManagerForShell(shell()));
    858 
    859   // Mark delegate for delayed open.
    860   GetDownloadManagerDelegate(download_manager)->SetDelayedOpen(true);
    861 
    862   // Setup new factory.
    863   DownloadFileWithDelayFactory* file_factory =
    864       new DownloadFileWithDelayFactory();
    865   download_manager->SetDownloadFileFactoryForTesting(
    866       scoped_ptr<DownloadFileFactory>(file_factory).Pass());
    867 
    868   // Create a download
    869   base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
    870   NavigateToURL(shell(), URLRequestMockHTTPJob::GetMockUrl(file));
    871 
    872   // Wait until the first (intermediate file) rename and execute the callback.
    873   file_factory->WaitForSomeCallback();
    874   std::vector<base::Closure> callbacks;
    875   file_factory->GetAllRenameCallbacks(&callbacks);
    876   ASSERT_EQ(1u, callbacks.size());
    877   callbacks[0].Run();
    878   callbacks.clear();
    879 
    880   // Wait until the second (final) rename callback is posted.
    881   file_factory->WaitForSomeCallback();
    882   file_factory->GetAllRenameCallbacks(&callbacks);
    883   ASSERT_EQ(1u, callbacks.size());
    884 
    885   // Call it.
    886   callbacks[0].Run();
    887   callbacks.clear();
    888 
    889   // Confirm download still IN_PROGRESS (internal state COMPLETING).
    890   std::vector<DownloadItem*> items;
    891   download_manager->GetAllDownloads(&items);
    892   EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());
    893 
    894   // Cancel the download; confirm cancel fails.
    895   ASSERT_EQ(1u, items.size());
    896   items[0]->Cancel(true);
    897   EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());
    898 
    899   // Need to complete open test.
    900   std::vector<DownloadOpenDelayedCallback> delayed_callbacks;
    901   GetDownloadManagerDelegate(download_manager)->GetDelayedCallbacks(
    902       &delayed_callbacks);
    903   ASSERT_EQ(1u, delayed_callbacks.size());
    904   delayed_callbacks[0].Run(true);
    905 
    906   // *Now* the download should be complete.
    907   EXPECT_EQ(DownloadItem::COMPLETE, items[0]->GetState());
    908 }
    909 
    910 // Try to shutdown with a download in progress to make sure shutdown path
    911 // works properly.
    912 IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownInProgress) {
    913   // Create a download that won't complete.
    914   scoped_ptr<DownloadCreateObserver> observer(
    915       CreateInProgressWaiter(shell(), 1));
    916   NavigateToURL(shell(), GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl));
    917   observer->WaitForFinished();
    918 
    919   // Get the item.
    920   std::vector<DownloadItem*> items;
    921   DownloadManagerForShell(shell())->GetAllDownloads(&items);
    922   ASSERT_EQ(1u, items.size());
    923   EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());
    924 
    925   // Shutdown the download manager and make sure we get the right
    926   // notifications in the right order.
    927   StrictMock<MockDownloadItemObserver> item_observer;
    928   items[0]->AddObserver(&item_observer);
    929   MockDownloadManagerObserver manager_observer(
    930       DownloadManagerForShell(shell()));
    931   // Don't care about ModelChanged() events.
    932   EXPECT_CALL(manager_observer, ModelChanged(_))
    933       .WillRepeatedly(Return());
    934   {
    935     InSequence notifications;
    936 
    937     EXPECT_CALL(manager_observer, MockManagerGoingDown(
    938         DownloadManagerForShell(shell())))
    939         .WillOnce(Return());
    940     EXPECT_CALL(item_observer, OnDownloadUpdated(
    941         AllOf(items[0],
    942               Property(&DownloadItem::GetState, DownloadItem::CANCELLED))))
    943         .WillOnce(Return());
    944     EXPECT_CALL(item_observer, OnDownloadDestroyed(items[0]))
    945         .WillOnce(Return());
    946   }
    947   DownloadManagerForShell(shell())->Shutdown();
    948   items.clear();
    949 }
    950 
    951 // Try to shutdown just after we release the download file, by delaying
    952 // release.
    953 IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownAtRelease) {
    954   DownloadManagerImpl* download_manager(DownloadManagerForShell(shell()));
    955 
    956   // Mark delegate for delayed open.
    957   GetDownloadManagerDelegate(download_manager)->SetDelayedOpen(true);
    958 
    959   // Setup new factory.
    960   DownloadFileWithDelayFactory* file_factory =
    961       new DownloadFileWithDelayFactory();
    962   download_manager->SetDownloadFileFactoryForTesting(
    963       scoped_ptr<DownloadFileFactory>(file_factory).Pass());
    964 
    965   // Create a download
    966   base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
    967   NavigateToURL(shell(), URLRequestMockHTTPJob::GetMockUrl(file));
    968 
    969   // Wait until the first (intermediate file) rename and execute the callback.
    970   file_factory->WaitForSomeCallback();
    971   std::vector<base::Closure> callbacks;
    972   file_factory->GetAllRenameCallbacks(&callbacks);
    973   ASSERT_EQ(1u, callbacks.size());
    974   callbacks[0].Run();
    975   callbacks.clear();
    976 
    977   // Wait until the second (final) rename callback is posted.
    978   file_factory->WaitForSomeCallback();
    979   file_factory->GetAllRenameCallbacks(&callbacks);
    980   ASSERT_EQ(1u, callbacks.size());
    981 
    982   // Call it.
    983   callbacks[0].Run();
    984   callbacks.clear();
    985 
    986   // Confirm download isn't complete yet.
    987   std::vector<DownloadItem*> items;
    988   DownloadManagerForShell(shell())->GetAllDownloads(&items);
    989   EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());
    990 
    991   // Cancel the download; confirm cancel fails anyway.
    992   ASSERT_EQ(1u, items.size());
    993   items[0]->Cancel(true);
    994   EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());
    995   RunAllPendingInMessageLoop();
    996   EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState());
    997 
    998   MockDownloadItemObserver observer;
    999   items[0]->AddObserver(&observer);
   1000   EXPECT_CALL(observer, OnDownloadDestroyed(items[0]));
   1001 
   1002   // Shutdown the download manager.  Mostly this is confirming a lack of
   1003   // crashes.
   1004   DownloadManagerForShell(shell())->Shutdown();
   1005 }
   1006 
   1007 IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeInterruptedDownload) {
   1008   CommandLine::ForCurrentProcess()->AppendSwitch(
   1009       switches::kEnableDownloadResumption);
   1010   ASSERT_TRUE(test_server()->Start());
   1011 
   1012   GURL url = test_server()->GetURL(
   1013       base::StringPrintf("rangereset?size=%d&rst_boundary=%d",
   1014                    GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
   1015 
   1016   MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell()));
   1017   EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
   1018 
   1019   DownloadItem* download(StartDownloadAndReturnItem(url));
   1020   WaitForData(download, GetSafeBufferChunk());
   1021   ::testing::Mock::VerifyAndClearExpectations(&dm_observer);
   1022 
   1023   // Confirm resumption while in progress doesn't do anything.
   1024   download->Resume();
   1025   ASSERT_EQ(GetSafeBufferChunk(), download->GetReceivedBytes());
   1026   ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState());
   1027 
   1028   // Tell the server to send the RST and confirm the interrupt happens.
   1029   ReleaseRSTAndConfirmInterruptForResume(download);
   1030   ConfirmFileStatusForResume(
   1031       download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
   1032       base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
   1033 
   1034   // Resume, confirming received bytes on resumption is correct.
   1035   // Make sure no creation calls are included.
   1036   EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(0);
   1037   int initial_size = 0;
   1038   DownloadUpdatedObserver initial_size_observer(
   1039       download, base::Bind(&InitialSizeFilter, &initial_size));
   1040   download->Resume();
   1041   initial_size_observer.WaitForEvent();
   1042   EXPECT_EQ(GetSafeBufferChunk(), initial_size);
   1043   ::testing::Mock::VerifyAndClearExpectations(&dm_observer);
   1044 
   1045   // and wait for expected data.
   1046   WaitForData(download, GetSafeBufferChunk() * 2);
   1047 
   1048   // Tell the server to send the RST and confirm the interrupt happens.
   1049   ReleaseRSTAndConfirmInterruptForResume(download);
   1050   ConfirmFileStatusForResume(
   1051       download, true, GetSafeBufferChunk() * 2, GetSafeBufferChunk() * 3,
   1052       base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
   1053 
   1054   // Resume and wait for completion.
   1055   DownloadUpdatedObserver completion_observer(
   1056       download, base::Bind(DownloadCompleteFilter));
   1057   download->Resume();
   1058   completion_observer.WaitForEvent();
   1059 
   1060   ConfirmFileStatusForResume(
   1061       download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3,
   1062       base::FilePath(FILE_PATH_LITERAL("rangereset")));
   1063 
   1064   // Confirm resumption while complete doesn't do anything.
   1065   download->Resume();
   1066   ASSERT_EQ(GetSafeBufferChunk() * 3, download->GetReceivedBytes());
   1067   ASSERT_EQ(DownloadItem::COMPLETE, download->GetState());
   1068   RunAllPendingInMessageLoop();
   1069   ASSERT_EQ(GetSafeBufferChunk() * 3, download->GetReceivedBytes());
   1070   ASSERT_EQ(DownloadItem::COMPLETE, download->GetState());
   1071 }
   1072 
   1073 // Confirm restart fallback happens if a range request is bounced.
   1074 IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeInterruptedDownloadNoRange) {
   1075   CommandLine::ForCurrentProcess()->AppendSwitch(
   1076       switches::kEnableDownloadResumption);
   1077   ASSERT_TRUE(test_server()->Start());
   1078 
   1079   // Auto-restart if server doesn't handle ranges.
   1080   GURL url = test_server()->GetURL(
   1081       base::StringPrintf(
   1082           // First download hits an RST, rest don't, no ranges.
   1083           "rangereset?size=%d&rst_boundary=%d&"
   1084           "token=NoRange&rst_limit=1&bounce_range",
   1085           GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
   1086 
   1087   // Start the download and wait for first data chunk.
   1088   DownloadItem* download(StartDownloadAndReturnItem(url));
   1089   WaitForData(download, GetSafeBufferChunk());
   1090 
   1091   RecordingDownloadObserver recorder(download);
   1092 
   1093   ReleaseRSTAndConfirmInterruptForResume(download);
   1094   ConfirmFileStatusForResume(
   1095       download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
   1096       base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
   1097 
   1098   DownloadUpdatedObserver completion_observer(
   1099       download, base::Bind(DownloadCompleteFilter));
   1100   download->Resume();
   1101   completion_observer.WaitForEvent();
   1102 
   1103   ConfirmFileStatusForResume(
   1104       download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3,
   1105       base::FilePath(FILE_PATH_LITERAL("rangereset")));
   1106 
   1107   static const RecordingDownloadObserver::RecordStruct expected_record[] = {
   1108     // Result of RST
   1109     {DownloadItem::INTERRUPTED, GetSafeBufferChunk()},
   1110     // Starting continuation
   1111     {DownloadItem::IN_PROGRESS, GetSafeBufferChunk()},
   1112     // Notification of receiving whole file.
   1113     {DownloadItem::IN_PROGRESS, 0},
   1114     // Completion.
   1115     {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3},
   1116   };
   1117 
   1118   recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record));
   1119 }
   1120 
   1121 // Confirm restart fallback happens if a precondition is failed.
   1122 IN_PROC_BROWSER_TEST_F(DownloadContentTest,
   1123                        ResumeInterruptedDownloadBadPrecondition) {
   1124   CommandLine::ForCurrentProcess()->AppendSwitch(
   1125       switches::kEnableDownloadResumption);
   1126   ASSERT_TRUE(test_server()->Start());
   1127 
   1128   GURL url = test_server()->GetURL(base::StringPrintf(
   1129       // First download hits an RST, rest don't, precondition fail.
   1130       "rangereset?size=%d&rst_boundary=%d&"
   1131       "token=BadPrecondition&rst_limit=1&fail_precondition=2",
   1132       GetSafeBufferChunk() * 3,
   1133       GetSafeBufferChunk()));
   1134 
   1135   // Start the download and wait for first data chunk.
   1136   DownloadItem* download(StartDownloadAndReturnItem(url));
   1137   WaitForData(download, GetSafeBufferChunk());
   1138 
   1139   RecordingDownloadObserver recorder(download);
   1140 
   1141   ReleaseRSTAndConfirmInterruptForResume(download);
   1142   ConfirmFileStatusForResume(
   1143       download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
   1144       base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
   1145   EXPECT_EQ("BadPrecondition2", download->GetETag());
   1146 
   1147   DownloadUpdatedObserver completion_observer(
   1148       download, base::Bind(DownloadCompleteFilter));
   1149   download->Resume();
   1150   completion_observer.WaitForEvent();
   1151 
   1152   ConfirmFileStatusForResume(
   1153       download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3,
   1154       base::FilePath(FILE_PATH_LITERAL("rangereset")));
   1155   EXPECT_EQ("BadPrecondition0", download->GetETag());
   1156 
   1157   static const RecordingDownloadObserver::RecordStruct expected_record[] = {
   1158     // Result of RST
   1159     {DownloadItem::INTERRUPTED, GetSafeBufferChunk()},
   1160     // Starting continuation
   1161     {DownloadItem::IN_PROGRESS, GetSafeBufferChunk()},
   1162     // Server precondition fail.
   1163     {DownloadItem::INTERRUPTED, 0},
   1164     // Notification of successful restart.
   1165     {DownloadItem::IN_PROGRESS, 0},
   1166     // Completion.
   1167     {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3},
   1168   };
   1169 
   1170   recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record));
   1171 }
   1172 
   1173 // Confirm we don't try to resume if we don't have a verifier.
   1174 IN_PROC_BROWSER_TEST_F(DownloadContentTest,
   1175                        ResumeInterruptedDownloadNoVerifiers) {
   1176   CommandLine::ForCurrentProcess()->AppendSwitch(
   1177       switches::kEnableDownloadResumption);
   1178   ASSERT_TRUE(test_server()->Start());
   1179 
   1180   GURL url = test_server()->GetURL(
   1181       base::StringPrintf(
   1182           // First download hits an RST, rest don't, no verifiers.
   1183           "rangereset?size=%d&rst_boundary=%d&"
   1184           "token=NoRange&rst_limit=1&no_verifiers",
   1185           GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
   1186 
   1187   // Start the download and wait for first data chunk.
   1188   DownloadItem* download(StartDownloadAndReturnItem(url));
   1189   WaitForData(download, GetSafeBufferChunk());
   1190 
   1191   RecordingDownloadObserver recorder(download);
   1192 
   1193   ReleaseRSTAndConfirmInterruptForResume(download);
   1194   ConfirmFileStatusForResume(
   1195       download, false, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
   1196       base::FilePath());
   1197 
   1198   DownloadUpdatedObserver completion_observer(
   1199       download, base::Bind(DownloadCompleteFilter));
   1200   download->Resume();
   1201   completion_observer.WaitForEvent();
   1202 
   1203   ConfirmFileStatusForResume(
   1204       download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3,
   1205       base::FilePath(FILE_PATH_LITERAL("rangereset")));
   1206 
   1207   static const RecordingDownloadObserver::RecordStruct expected_record[] = {
   1208     // Result of RST
   1209     {DownloadItem::INTERRUPTED, GetSafeBufferChunk()},
   1210     // Restart for lack of verifiers
   1211     {DownloadItem::IN_PROGRESS, 0},
   1212     // Completion.
   1213     {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3},
   1214   };
   1215 
   1216   recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record));
   1217 }
   1218 
   1219 IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithDeletedFile) {
   1220   CommandLine::ForCurrentProcess()->AppendSwitch(
   1221       switches::kEnableDownloadResumption);
   1222   ASSERT_TRUE(test_server()->Start());
   1223 
   1224   GURL url = test_server()->GetURL(
   1225       base::StringPrintf(
   1226           // First download hits an RST, rest don't
   1227           "rangereset?size=%d&rst_boundary=%d&"
   1228           "token=NoRange&rst_limit=1",
   1229           GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
   1230 
   1231   // Start the download and wait for first data chunk.
   1232   DownloadItem* download(StartDownloadAndReturnItem(url));
   1233   WaitForData(download, GetSafeBufferChunk());
   1234 
   1235   RecordingDownloadObserver recorder(download);
   1236 
   1237   ReleaseRSTAndConfirmInterruptForResume(download);
   1238   ConfirmFileStatusForResume(
   1239       download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
   1240       base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
   1241 
   1242   // Delete the intermediate file.
   1243   base::DeleteFile(download->GetFullPath(), false);
   1244 
   1245   DownloadUpdatedObserver completion_observer(
   1246       download, base::Bind(DownloadCompleteFilter));
   1247   download->Resume();
   1248   completion_observer.WaitForEvent();
   1249 
   1250   ConfirmFileStatusForResume(
   1251       download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3,
   1252       base::FilePath(FILE_PATH_LITERAL("rangereset")));
   1253 
   1254   static const RecordingDownloadObserver::RecordStruct expected_record[] = {
   1255     // Result of RST
   1256     {DownloadItem::INTERRUPTED, GetSafeBufferChunk()},
   1257     // Starting continuation
   1258     {DownloadItem::IN_PROGRESS, GetSafeBufferChunk()},
   1259     // Error because file isn't there.
   1260     {DownloadItem::INTERRUPTED, 0},
   1261     // Restart.
   1262     {DownloadItem::IN_PROGRESS, 0},
   1263     // Completion.
   1264     {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3},
   1265   };
   1266 
   1267   recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record));
   1268 }
   1269 
   1270 IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileInitError) {
   1271   CommandLine::ForCurrentProcess()->AppendSwitch(
   1272       switches::kEnableDownloadResumption);
   1273   base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
   1274   GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
   1275 
   1276   // Setup the error injector.
   1277   scoped_refptr<TestFileErrorInjector> injector(
   1278       TestFileErrorInjector::Create(DownloadManagerForShell(shell())));
   1279 
   1280   TestFileErrorInjector::FileErrorInfo err = {
   1281     url.spec(),
   1282     TestFileErrorInjector::FILE_OPERATION_INITIALIZE,
   1283     0,
   1284     DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE
   1285   };
   1286   injector->AddError(err);
   1287   injector->InjectErrors();
   1288 
   1289   // Start and watch for interrupt.
   1290   scoped_ptr<DownloadTestObserver> int_observer(
   1291       CreateInterruptedWaiter(shell(), 1));
   1292   DownloadItem* download(StartDownloadAndReturnItem(url));
   1293   int_observer->WaitForFinished();
   1294   ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
   1295   EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
   1296             download->GetLastReason());
   1297   EXPECT_EQ(0, download->GetReceivedBytes());
   1298   EXPECT_TRUE(download->GetFullPath().empty());
   1299   EXPECT_TRUE(download->GetTargetFilePath().empty());
   1300 
   1301   // We need to make sure that any cross-thread downloads communication has
   1302   // quiesced before clearing and injecting the new errors, as the
   1303   // InjectErrors() routine alters the currently in use download file
   1304   // factory, which is a file thread object.
   1305   RunAllPendingInMessageLoop(BrowserThread::FILE);
   1306   RunAllPendingInMessageLoop();
   1307 
   1308   // Clear the old errors list.
   1309   injector->ClearErrors();
   1310   injector->InjectErrors();
   1311 
   1312   // Resume and watch completion.
   1313   DownloadUpdatedObserver completion_observer(
   1314       download, base::Bind(DownloadCompleteFilter));
   1315   download->Resume();
   1316   completion_observer.WaitForEvent();
   1317   EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE);
   1318 }
   1319 
   1320 IN_PROC_BROWSER_TEST_F(DownloadContentTest,
   1321                        ResumeWithFileIntermediateRenameError) {
   1322   CommandLine::ForCurrentProcess()->AppendSwitch(
   1323       switches::kEnableDownloadResumption);
   1324   base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
   1325   GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
   1326 
   1327   // Setup the error injector.
   1328   scoped_refptr<TestFileErrorInjector> injector(
   1329       TestFileErrorInjector::Create(DownloadManagerForShell(shell())));
   1330 
   1331   TestFileErrorInjector::FileErrorInfo err = {
   1332     url.spec(),
   1333     TestFileErrorInjector::FILE_OPERATION_RENAME_UNIQUIFY,
   1334     0,
   1335     DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE
   1336   };
   1337   injector->AddError(err);
   1338   injector->InjectErrors();
   1339 
   1340   // Start and watch for interrupt.
   1341   scoped_ptr<DownloadTestObserver> int_observer(
   1342       CreateInterruptedWaiter(shell(), 1));
   1343   DownloadItem* download(StartDownloadAndReturnItem(url));
   1344   int_observer->WaitForFinished();
   1345   ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
   1346   EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
   1347             download->GetLastReason());
   1348   EXPECT_TRUE(download->GetFullPath().empty());
   1349   // Target path will have been set after file name determination. GetFullPath()
   1350   // being empty is sufficient to signal that filename determination needs to be
   1351   // redone.
   1352   EXPECT_FALSE(download->GetTargetFilePath().empty());
   1353 
   1354   // We need to make sure that any cross-thread downloads communication has
   1355   // quiesced before clearing and injecting the new errors, as the
   1356   // InjectErrors() routine alters the currently in use download file
   1357   // factory, which is a file thread object.
   1358   RunAllPendingInMessageLoop(BrowserThread::FILE);
   1359   RunAllPendingInMessageLoop();
   1360 
   1361   // Clear the old errors list.
   1362   injector->ClearErrors();
   1363   injector->InjectErrors();
   1364 
   1365   // Resume and watch completion.
   1366   DownloadUpdatedObserver completion_observer(
   1367       download, base::Bind(DownloadCompleteFilter));
   1368   download->Resume();
   1369   completion_observer.WaitForEvent();
   1370   EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE);
   1371 }
   1372 
   1373 IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileFinalRenameError) {
   1374   CommandLine::ForCurrentProcess()->AppendSwitch(
   1375       switches::kEnableDownloadResumption);
   1376   base::FilePath file(FILE_PATH_LITERAL("download-test.lib"));
   1377   GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
   1378 
   1379   // Setup the error injector.
   1380   scoped_refptr<TestFileErrorInjector> injector(
   1381       TestFileErrorInjector::Create(DownloadManagerForShell(shell())));
   1382 
   1383   DownloadManagerForShell(shell())->RemoveAllDownloads();
   1384   TestFileErrorInjector::FileErrorInfo err = {
   1385     url.spec(),
   1386     TestFileErrorInjector::FILE_OPERATION_RENAME_ANNOTATE,
   1387     0,
   1388     DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE
   1389   };
   1390   injector->AddError(err);
   1391   injector->InjectErrors();
   1392 
   1393   // Start and watch for interrupt.
   1394   scoped_ptr<DownloadTestObserver> int_observer(
   1395       CreateInterruptedWaiter(shell(), 1));
   1396   DownloadItem* download(StartDownloadAndReturnItem(url));
   1397   int_observer->WaitForFinished();
   1398   ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
   1399   EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
   1400             download->GetLastReason());
   1401   EXPECT_TRUE(download->GetFullPath().empty());
   1402   // Target path should still be intact.
   1403   EXPECT_FALSE(download->GetTargetFilePath().empty());
   1404 
   1405   // We need to make sure that any cross-thread downloads communication has
   1406   // quiesced before clearing and injecting the new errors, as the
   1407   // InjectErrors() routine alters the currently in use download file
   1408   // factory, which is a file thread object.
   1409   RunAllPendingInMessageLoop(BrowserThread::FILE);
   1410   RunAllPendingInMessageLoop();
   1411 
   1412   // Clear the old errors list.
   1413   injector->ClearErrors();
   1414   injector->InjectErrors();
   1415 
   1416   // Resume and watch completion.
   1417   DownloadUpdatedObserver completion_observer(
   1418       download, base::Bind(DownloadCompleteFilter));
   1419   download->Resume();
   1420   completion_observer.WaitForEvent();
   1421   EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE);
   1422 }
   1423 
   1424 // An interrupted download should remove the intermediate file when it is
   1425 // cancelled.
   1426 IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelInterruptedDownload) {
   1427   CommandLine::ForCurrentProcess()->AppendSwitch(
   1428       switches::kEnableDownloadResumption);
   1429   ASSERT_TRUE(test_server()->Start());
   1430 
   1431   GURL url1 = test_server()->GetURL(
   1432       base::StringPrintf("rangereset?size=%d&rst_boundary=%d",
   1433                          GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
   1434 
   1435   DownloadItem* download(StartDownloadAndReturnItem(url1));
   1436   WaitForData(download, GetSafeBufferChunk());
   1437 
   1438   ReleaseRSTAndConfirmInterruptForResume(download);
   1439   ConfirmFileStatusForResume(
   1440       download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
   1441       base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
   1442 
   1443   base::FilePath intermediate_path(download->GetFullPath());
   1444   ASSERT_FALSE(intermediate_path.empty());
   1445   EXPECT_TRUE(base::PathExists(intermediate_path));
   1446 
   1447   download->Cancel(true /* user_cancel */);
   1448   RunAllPendingInMessageLoop(BrowserThread::FILE);
   1449   RunAllPendingInMessageLoop();
   1450 
   1451   // The intermediate file should now be gone.
   1452   EXPECT_FALSE(base::PathExists(intermediate_path));
   1453   EXPECT_TRUE(download->GetFullPath().empty());
   1454 }
   1455 
   1456 IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveDownload) {
   1457   CommandLine::ForCurrentProcess()->AppendSwitch(
   1458       switches::kEnableDownloadResumption);
   1459   ASSERT_TRUE(test_server()->Start());
   1460 
   1461   // An interrupted download should remove the intermediate file when it is
   1462   // removed.
   1463   {
   1464     GURL url1 = test_server()->GetURL(
   1465         base::StringPrintf("rangereset?size=%d&rst_boundary=%d",
   1466                            GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
   1467 
   1468     DownloadItem* download(StartDownloadAndReturnItem(url1));
   1469     WaitForData(download, GetSafeBufferChunk());
   1470     ReleaseRSTAndConfirmInterruptForResume(download);
   1471     ConfirmFileStatusForResume(
   1472         download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
   1473         base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
   1474 
   1475     base::FilePath intermediate_path(download->GetFullPath());
   1476     ASSERT_FALSE(intermediate_path.empty());
   1477     EXPECT_TRUE(base::PathExists(intermediate_path));
   1478 
   1479     download->Remove();
   1480     RunAllPendingInMessageLoop(BrowserThread::FILE);
   1481     RunAllPendingInMessageLoop();
   1482 
   1483     // The intermediate file should now be gone.
   1484     EXPECT_FALSE(base::PathExists(intermediate_path));
   1485   }
   1486 
   1487   // A completed download shouldn't delete the downloaded file when it is
   1488   // removed.
   1489   {
   1490     // Start the second download and wait until it's done.
   1491     base::FilePath file2(FILE_PATH_LITERAL("download-test.lib"));
   1492     GURL url2(URLRequestMockHTTPJob::GetMockUrl(file2));
   1493     scoped_ptr<DownloadTestObserver> completion_observer(
   1494         CreateWaiter(shell(), 1));
   1495     DownloadItem* download(StartDownloadAndReturnItem(url2));
   1496     completion_observer->WaitForFinished();
   1497 
   1498     // The target path should exist.
   1499     base::FilePath target_path(download->GetTargetFilePath());
   1500     EXPECT_TRUE(base::PathExists(target_path));
   1501     download->Remove();
   1502     RunAllPendingInMessageLoop(BrowserThread::FILE);
   1503     RunAllPendingInMessageLoop();
   1504 
   1505     // The file should still exist.
   1506     EXPECT_TRUE(base::PathExists(target_path));
   1507   }
   1508 }
   1509 
   1510 IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveResumingDownload) {
   1511   SetupEnsureNoPendingDownloads();
   1512   CommandLine::ForCurrentProcess()->AppendSwitch(
   1513       switches::kEnableDownloadResumption);
   1514   ASSERT_TRUE(test_server()->Start());
   1515 
   1516   GURL url = test_server()->GetURL(
   1517       base::StringPrintf("rangereset?size=%d&rst_boundary=%d",
   1518                          GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
   1519 
   1520   MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell()));
   1521   EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
   1522 
   1523   DownloadItem* download(StartDownloadAndReturnItem(url));
   1524   WaitForData(download, GetSafeBufferChunk());
   1525   ::testing::Mock::VerifyAndClearExpectations(&dm_observer);
   1526 
   1527   // Tell the server to send the RST and confirm the interrupt happens.
   1528   ReleaseRSTAndConfirmInterruptForResume(download);
   1529   ConfirmFileStatusForResume(
   1530       download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
   1531       base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
   1532 
   1533   base::FilePath intermediate_path(download->GetFullPath());
   1534   ASSERT_FALSE(intermediate_path.empty());
   1535   EXPECT_TRUE(base::PathExists(intermediate_path));
   1536 
   1537   // Resume and remove download. We expect only a single OnDownloadCreated()
   1538   // call, and that's for the second download created below.
   1539   EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
   1540   download->Resume();
   1541   download->Remove();
   1542 
   1543   // The intermediate file should now be gone.
   1544   RunAllPendingInMessageLoop(BrowserThread::FILE);
   1545   RunAllPendingInMessageLoop();
   1546   EXPECT_FALSE(base::PathExists(intermediate_path));
   1547 
   1548   // Start the second download and wait until it's done. The test server is
   1549   // single threaded. The response to this download request should follow the
   1550   // response to the previous resumption request.
   1551   GURL url2(test_server()->GetURL("rangereset?size=100&rst_limit=0&token=x"));
   1552   DownloadAndWait(shell(), url2, DownloadItem::COMPLETE);
   1553 
   1554   EXPECT_TRUE(EnsureNoPendingDownloads());
   1555 }
   1556 
   1557 IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelResumingDownload) {
   1558   SetupEnsureNoPendingDownloads();
   1559   CommandLine::ForCurrentProcess()->AppendSwitch(
   1560       switches::kEnableDownloadResumption);
   1561   ASSERT_TRUE(test_server()->Start());
   1562 
   1563   GURL url = test_server()->GetURL(
   1564       base::StringPrintf("rangereset?size=%d&rst_boundary=%d",
   1565                          GetSafeBufferChunk() * 3, GetSafeBufferChunk()));
   1566 
   1567   MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell()));
   1568   EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
   1569 
   1570   DownloadItem* download(StartDownloadAndReturnItem(url));
   1571   WaitForData(download, GetSafeBufferChunk());
   1572   ::testing::Mock::VerifyAndClearExpectations(&dm_observer);
   1573 
   1574   // Tell the server to send the RST and confirm the interrupt happens.
   1575   ReleaseRSTAndConfirmInterruptForResume(download);
   1576   ConfirmFileStatusForResume(
   1577       download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3,
   1578       base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload")));
   1579 
   1580   base::FilePath intermediate_path(download->GetFullPath());
   1581   ASSERT_FALSE(intermediate_path.empty());
   1582   EXPECT_TRUE(base::PathExists(intermediate_path));
   1583 
   1584   // Resume and cancel download. We expect only a single OnDownloadCreated()
   1585   // call, and that's for the second download created below.
   1586   EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1);
   1587   download->Resume();
   1588   download->Cancel(true);
   1589 
   1590   // The intermediate file should now be gone.
   1591   RunAllPendingInMessageLoop(BrowserThread::FILE);
   1592   RunAllPendingInMessageLoop();
   1593   EXPECT_FALSE(base::PathExists(intermediate_path));
   1594   EXPECT_TRUE(download->GetFullPath().empty());
   1595 
   1596   // Start the second download and wait until it's done. The test server is
   1597   // single threaded. The response to this download request should follow the
   1598   // response to the previous resumption request.
   1599   GURL url2(test_server()->GetURL("rangereset?size=100&rst_limit=0&token=x"));
   1600   DownloadAndWait(shell(), url2, DownloadItem::COMPLETE);
   1601 
   1602   EXPECT_TRUE(EnsureNoPendingDownloads());
   1603 }
   1604 
   1605 // Check that the cookie policy is correctly updated when downloading a file
   1606 // that redirects cross origin.
   1607 IN_PROC_BROWSER_TEST_F(DownloadContentTest, CookiePolicy) {
   1608   ASSERT_TRUE(test_server()->Start());
   1609   net::HostPortPair host_port = test_server()->host_port_pair();
   1610   DCHECK_EQ(host_port.host(), std::string("127.0.0.1"));
   1611 
   1612   // Block third-party cookies.
   1613   ShellNetworkDelegate::SetAcceptAllCookies(false);
   1614 
   1615   // |url| redirects to a different origin |download| which tries to set a
   1616   // cookie.
   1617   std::string download(base::StringPrintf(
   1618       "http://localhost:%d/set-cookie?A=B", host_port.port()));
   1619   GURL url(test_server()->GetURL("server-redirect?" + download));
   1620 
   1621   // Download the file.
   1622   SetupEnsureNoPendingDownloads();
   1623   scoped_ptr<DownloadUrlParameters> dl_params(
   1624       DownloadUrlParameters::FromWebContents(shell()->web_contents(), url));
   1625   scoped_ptr<DownloadTestObserver> observer(CreateWaiter(shell(), 1));
   1626   DownloadManagerForShell(shell())->DownloadUrl(dl_params.Pass());
   1627   observer->WaitForFinished();
   1628 
   1629   // Get the important info from other threads and check it.
   1630   EXPECT_TRUE(EnsureNoPendingDownloads());
   1631 
   1632   std::vector<DownloadItem*> downloads;
   1633   DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
   1634   ASSERT_EQ(1u, downloads.size());
   1635   ASSERT_EQ(DownloadItem::COMPLETE, downloads[0]->GetState());
   1636 
   1637   // Check that the cookies were correctly set.
   1638   EXPECT_EQ("A=B",
   1639             content::GetCookies(shell()->web_contents()->GetBrowserContext(),
   1640                                 GURL(download)));
   1641 }
   1642 
   1643 }  // namespace content
   1644