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