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