15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file contains download browser tests that are known to be runnable 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in a pure content context. Over time tests should be migrated here. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/memory/ref_counted.h" 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/strings/stringprintf.h" 14a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/strings/utf_string_conversions.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/threading/platform_thread.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/time/time.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/byte_stream.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/download/download_file_factory.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/download/download_file_impl.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/download/download_item_impl.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/download/download_manager_impl.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/download/download_resource_handler.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/web_contents/web_contents_impl.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/power_save_blocker.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_switches.h" 26a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "content/public/common/webplugininfo.h" 273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/public/test/browser_test_utils.h" 28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/public/test/content_browser_test.h" 29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/public/test/content_browser_test_utils.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/download_test_observer.h" 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/test/test_file_error_injector.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_utils.h" 333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/shell/browser/shell.h" 343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/shell/browser/shell_browser_context.h" 353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/shell/browser/shell_download_manager_delegate.h" 363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/shell/browser/shell_network_delegate.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/test/net/url_request_slow_download_job.h" 385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "net/test/embedded_test_server/embedded_test_server.h" 395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "net/test/embedded_test_server/http_request.h" 405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "net/test/embedded_test_server/http_response.h" 41b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/test/spawned_test_server/spawned_test_server.h" 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/test/url_request/url_request_mock_http_job.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(ENABLE_PLUGINS) 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/browser/plugin_service_impl.h" 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuusing ::net::test_server::EmbeddedTestServer; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::AllOf; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Field; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::InSequence; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Property; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Return; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::StrictMock; 585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuusing ::testing::_; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockDownloadItemObserver : public DownloadItem::Observer { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockDownloadItemObserver() {} 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~MockDownloadItemObserver() {} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD1(OnDownloadUpdated, void(DownloadItem*)); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD1(OnDownloadOpened, void(DownloadItem*)); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD1(OnDownloadRemoved, void(DownloadItem*)); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD1(OnDownloadDestroyed, void(DownloadItem*)); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockDownloadManagerObserver : public DownloadManager::Observer { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockDownloadManagerObserver(DownloadManager* manager) { 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager_ = manager; 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager->AddObserver(this); 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~MockDownloadManagerObserver() { 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (manager_) 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager_->RemoveObserver(this); 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD2(OnDownloadCreated, void(DownloadManager*, DownloadItem*)); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD1(ModelChanged, void(DownloadManager*)); 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void ManagerGoingDown(DownloadManager* manager) { 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(manager_, manager); 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockManagerGoingDown(manager); 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager_->RemoveObserver(this); 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manager_ = NULL; 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MOCK_METHOD1(MockManagerGoingDown, void(DownloadManager*)); 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DownloadManager* manager_; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DownloadFileWithDelayFactory; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static DownloadManagerImpl* DownloadManagerForShell(Shell* shell) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're in a content_browsertest; we know that the DownloadManager 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is a DownloadManagerImpl. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<DownloadManagerImpl*>( 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserContext::GetDownloadManager( 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shell->web_contents()->GetBrowserContext())); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DownloadFileWithDelay : public DownloadFileImpl { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadFileWithDelay( 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DownloadSaveInfo> save_info, 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& default_download_directory, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& referrer_url, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool calculate_hash, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ByteStreamReader> stream, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::BoundNetLog& bound_net_log, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<PowerSaveBlocker> power_save_blocker, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<DownloadDestinationObserver> observer, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<DownloadFileWithDelayFactory> owner); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~DownloadFileWithDelay(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wraps DownloadFileImpl::Rename* and intercepts the return callback, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // storing it in the factory that produced this object for later 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // retrieval. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RenameAndUniquify( 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& full_path, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RenameCompletionCallback& callback) OVERRIDE; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RenameAndAnnotate( 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& full_path, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RenameCompletionCallback& callback) OVERRIDE; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void RenameCallbackWrapper( 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::WeakPtr<DownloadFileWithDelayFactory>& factory, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RenameCompletionCallback& original_callback, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadInterruptReason reason, 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& path); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This variable may only be read on the FILE thread, and may only be 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // indirected through (e.g. methods on DownloadFileWithDelayFactory called) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on the UI thread. This is because after construction, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DownloadFileWithDelay lives on the file thread, but 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DownloadFileWithDelayFactory is purely a UI thread object. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<DownloadFileWithDelayFactory> owner_; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DownloadFileWithDelay); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All routines on this class must be called on the UI thread. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DownloadFileWithDelayFactory : public DownloadFileFactory { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadFileWithDelayFactory(); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~DownloadFileWithDelayFactory(); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DownloadFileFactory interface. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual DownloadFile* CreateFile( 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DownloadSaveInfo> save_info, 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& default_download_directory, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& referrer_url, 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool calculate_hash, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ByteStreamReader> stream, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::BoundNetLog& bound_net_log, 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<DownloadDestinationObserver> observer) OVERRIDE; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddRenameCallback(base::Closure callback); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void GetAllRenameCallbacks(std::vector<base::Closure>* results); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do not return until GetAllRenameCallbacks() will return a non-empty list. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WaitForSomeCallback(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<DownloadFileWithDelayFactory> weak_ptr_factory_; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<base::Closure> rename_callbacks_; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool waiting_; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DownloadFileWithDelayFactory); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DownloadFileWithDelay::DownloadFileWithDelay( 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DownloadSaveInfo> save_info, 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& default_download_directory, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& referrer_url, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool calculate_hash, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ByteStreamReader> stream, 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::BoundNetLog& bound_net_log, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<PowerSaveBlocker> power_save_blocker, 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<DownloadDestinationObserver> observer, 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<DownloadFileWithDelayFactory> owner) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : DownloadFileImpl( 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save_info.Pass(), default_download_directory, url, referrer_url, 198a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch calculate_hash, stream.Pass(), bound_net_log, observer), 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owner_(owner) {} 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DownloadFileWithDelay::~DownloadFileWithDelay() {} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadFileWithDelay::RenameAndUniquify( 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& full_path, 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const RenameCompletionCallback& callback) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadFileImpl::RenameAndUniquify( 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_path, base::Bind(DownloadFileWithDelay::RenameCallbackWrapper, 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owner_, callback)); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadFileWithDelay::RenameAndAnnotate( 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& full_path, const RenameCompletionCallback& callback) { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadFileImpl::RenameAndAnnotate( 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_path, base::Bind(DownloadFileWithDelay::RenameCallbackWrapper, 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owner_, callback)); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadFileWithDelay::RenameCallbackWrapper( 222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::WeakPtr<DownloadFileWithDelayFactory>& factory, 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RenameCompletionCallback& original_callback, 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadInterruptReason reason, 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& path) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!factory) 228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) factory->AddRenameCallback(base::Bind(original_callback, reason, path)); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DownloadFileWithDelayFactory::DownloadFileWithDelayFactory() 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : weak_ptr_factory_(this), 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_(false) {} 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DownloadFileWithDelayFactory::~DownloadFileWithDelayFactory() {} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DownloadFile* DownloadFileWithDelayFactory::CreateFile( 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DownloadSaveInfo> save_info, 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& default_download_directory, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& referrer_url, 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool calculate_hash, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ByteStreamReader> stream, 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::BoundNetLog& bound_net_log, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<DownloadDestinationObserver> observer) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<PowerSaveBlocker> psb( 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PowerSaveBlocker::Create( 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Download in progress")); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new DownloadFileWithDelay( 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save_info.Pass(), default_download_directory, url, referrer_url, 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) calculate_hash, stream.Pass(), bound_net_log, 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psb.Pass(), observer, weak_ptr_factory_.GetWeakPtr()); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadFileWithDelayFactory::AddRenameCallback(base::Closure callback) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rename_callbacks_.push_back(callback); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (waiting_) 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopForUI::current()->Quit(); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadFileWithDelayFactory::GetAllRenameCallbacks( 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<base::Closure>* results) { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results->swap(rename_callbacks_); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadFileWithDelayFactory::WaitForSomeCallback() { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rename_callbacks_.empty()) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_ = true; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMessageLoop(); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_ = false; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CountingDownloadFile : public DownloadFileImpl { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CountingDownloadFile( 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DownloadSaveInfo> save_info, 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& default_downloads_directory, 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& referrer_url, 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool calculate_hash, 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ByteStreamReader> stream, 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::BoundNetLog& bound_net_log, 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<PowerSaveBlocker> power_save_blocker, 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<DownloadDestinationObserver> observer) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : DownloadFileImpl(save_info.Pass(), default_downloads_directory, 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url, referrer_url, calculate_hash, 293a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch stream.Pass(), bound_net_log, observer) {} 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~CountingDownloadFile() { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_files_--; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Initialize(const InitializeCallback& callback) OVERRIDE { 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_files_++; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DownloadFileImpl::Initialize(callback); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void GetNumberActiveFiles(int* result) { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = active_files_; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Can be called on any thread, and will block (running message loop) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // until data is returned. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int GetNumberActiveFilesFromFileThread() { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = -1; 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BrowserThread::PostTaskAndReply( 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BrowserThread::FILE, 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CountingDownloadFile::GetNumberActiveFiles, &result), 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->QuitClosure()); 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->Run(); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(-1, result); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int active_files_; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CountingDownloadFile::active_files_ = 0; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CountingDownloadFileFactory : public DownloadFileFactory { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CountingDownloadFileFactory() {} 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~CountingDownloadFileFactory() {} 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DownloadFileFactory interface. 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual DownloadFile* CreateFile( 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DownloadSaveInfo> save_info, 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& default_downloads_directory, 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& referrer_url, 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool calculate_hash, 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ByteStreamReader> stream, 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::BoundNetLog& bound_net_log, 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<DownloadDestinationObserver> observer) OVERRIDE { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<PowerSaveBlocker> psb( 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PowerSaveBlocker::Create( 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension, 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Download in progress")); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new CountingDownloadFile( 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) save_info.Pass(), default_downloads_directory, url, referrer_url, 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) calculate_hash, stream.Pass(), bound_net_log, 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) psb.Pass(), observer); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestShellDownloadManagerDelegate : public ShellDownloadManagerDelegate { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestShellDownloadManagerDelegate() 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : delay_download_open_(false) {} 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~TestShellDownloadManagerDelegate() {} 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool ShouldOpenDownload( 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadItem* item, 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DownloadOpenDelayedCallback& callback) OVERRIDE { 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delay_download_open_) { 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delayed_callbacks_.push_back(callback); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetDelayedOpen(bool delay) { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay_download_open_ = delay; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void GetDelayedCallbacks( 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<DownloadOpenDelayedCallback>* callbacks) { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks->swap(delayed_callbacks_); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool delay_download_open_; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<DownloadOpenDelayedCallback> delayed_callbacks_; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Record all state transitions and byte counts on the observed download. 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RecordingDownloadObserver : DownloadItem::Observer { 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct RecordStruct { 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadItem::DownloadState state; 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int bytes_received; 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef std::vector<RecordStruct> RecordVector; 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordingDownloadObserver(DownloadItem* download) 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : download_(download) { 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_state_.state = download->GetState(); 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_state_.bytes_received = download->GetReceivedBytes(); 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download_->AddObserver(this); 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~RecordingDownloadObserver() { 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RemoveObserver(); 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void CompareToExpectedRecord(const RecordStruct expected[], size_t size) { 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(size, record_.size()); 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int min = size > record_.size() ? record_.size() : size; 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < min; ++i) { 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expected[i].state, record_[i].state) << "Iteration " << i; 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expected[i].bytes_received, record_[i].bytes_received) 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "Iteration " << i; 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnDownloadUpdated(DownloadItem* download) OVERRIDE { 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(download_, download); 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadItem::DownloadState state = download->GetState(); 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int bytes = download->GetReceivedBytes(); 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (last_state_.state != state || last_state_.bytes_received > bytes) { 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_state_.state = state; 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_state_.bytes_received = bytes; 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) record_.push_back(last_state_); 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnDownloadDestroyed(DownloadItem* download) OVERRIDE { 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(download_, download); 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RemoveObserver(); 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void RemoveObserver() { 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (download_) { 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download_->RemoveObserver(this); 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download_ = NULL; 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadItem* download_; 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordStruct last_state_; 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordVector record_; 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Get the next created download. 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DownloadCreateObserver : DownloadManager::Observer { 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadCreateObserver(DownloadManager* manager) 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : manager_(manager), 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) item_(NULL), 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_(false) { 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manager_->AddObserver(this); 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~DownloadCreateObserver() { 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (manager_) 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manager_->RemoveObserver(this); 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manager_ = NULL; 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void ManagerGoingDown(DownloadManager* manager) OVERRIDE { 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(manager_, manager); 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manager_->RemoveObserver(this); 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manager_ = NULL; 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnDownloadCreated(DownloadManager* manager, 469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DownloadItem* download) OVERRIDE { 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!item_) 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) item_ = download; 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (waiting_) 474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopForUI::current()->Quit(); 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadItem* WaitForFinished() { 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!item_) { 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_ = true; 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunMessageLoop(); 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_ = false; 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return item_; 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadManager* manager_; 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadItem* item_; 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool waiting_; 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Filter for waiting for a certain number of bytes. 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DataReceivedFilter(int number_of_bytes, DownloadItem* download) { 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return download->GetReceivedBytes() >= number_of_bytes; 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Filter for download completion. 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DownloadCompleteFilter(DownloadItem* download) { 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return download->GetState() == DownloadItem::COMPLETE; 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Filter for saving the size of the download when the first IN_PROGRESS 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// is hit. 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool InitialSizeFilter(int* download_size, DownloadItem* download) { 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (download->GetState() != DownloadItem::IN_PROGRESS) 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *download_size = download->GetReceivedBytes(); 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Request handler to be used with CreateRedirectHandler(). 5155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuscoped_ptr<net::test_server::HttpResponse> HandleRequestAndSendRedirectResponse( 5165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& relative_url, 5175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const GURL& target_url, 5185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const net::test_server::HttpRequest& request) { 5195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<net::test_server::BasicHttpResponse> response; 5205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (request.relative_url == relative_url) { 5215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu response.reset(new net::test_server::BasicHttpResponse); 5225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu response->set_code(net::HTTP_FOUND); 5235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu response->AddCustomHeader("Location", target_url.spec()); 5245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 5255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return response.PassAs<net::test_server::HttpResponse>(); 5265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 5275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Creates a request handler for EmbeddedTestServer that responds with a HTTP 5295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// 302 redirect if the request URL matches |relative_url|. 5305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuEmbeddedTestServer::HandleRequestCallback CreateRedirectHandler( 5315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& relative_url, 5325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const GURL& target_url) { 5335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return base::Bind( 5345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &HandleRequestAndSendRedirectResponse, relative_url, target_url); 5355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 5365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Request handler to be used with CreateBasicResponseHandler(). 5385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuscoped_ptr<net::test_server::HttpResponse> HandleRequestAndSendBasicResponse( 5395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& relative_url, 5405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& content_type, 5415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& body, 5425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const net::test_server::HttpRequest& request) { 5435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<net::test_server::BasicHttpResponse> response; 5445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (request.relative_url == relative_url) { 5455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu response.reset(new net::test_server::BasicHttpResponse); 5465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu response->set_content_type(content_type); 5475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu response->set_content(body); 5485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 5495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return response.PassAs<net::test_server::HttpResponse>(); 5505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 5515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Creates a request handler for an EmbeddedTestServer that response with an 5535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// HTTP 200 status code, a Content-Type header and a body. 5545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuEmbeddedTestServer::HandleRequestCallback CreateBasicResponseHandler( 5555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& relative_url, 5565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& content_type, 5575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& body) { 5585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return base::Bind( 5595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &HandleRequestAndSendBasicResponse, relative_url, content_type, body); 5605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 5615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DownloadContentTest : public ContentBrowserTest { 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // An initial send from a website of at least this size will not be 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // help up by buffering in the underlying downloads ByteStream data 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // transfer. This is important because on resumption tests we wait 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // until we've gotten the data we expect before allowing the test server 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to send its reset, to get around hard close semantics on the Windows 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // socket layer implementation. 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int GetSafeBufferChunk() const { 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (DownloadResourceHandler::kDownloadByteStreamSize / 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ByteStreamWriter::kFractionBufferBeforeSending) + 1; 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUpOnMainThread() OVERRIDE { 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) test_delegate_.reset(new TestShellDownloadManagerDelegate()); 5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) test_delegate_->SetDownloadBehaviorForTesting(downloads_directory_.path()); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadManager* manager = DownloadManagerForShell(shell()); 5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) manager->GetDelegate()->Shutdown(); 5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) manager->SetDelegate(test_delegate_.get()); 5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) test_delegate_->SetDownloadManager(manager); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, FROM_HERE, 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&URLRequestSlowDownloadJob::AddUrlHandler)); 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath mock_base(GetTestFilePath("download", "")); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 5921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci BrowserThread::IO, 5931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FROM_HERE, 5941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind( 5951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &net::URLRequestMockHTTPJob::AddUrlHandler, 5961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci mock_base, 5971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci make_scoped_refptr(content::BrowserThread::GetBlockingPool()))); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TestShellDownloadManagerDelegate* GetDownloadManagerDelegate() { 6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return test_delegate_.get(); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a DownloadTestObserverTerminal that will wait for the 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // specified number of downloads to finish. 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadTestObserver* CreateWaiter( 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shell* shell, int num_downloads) { 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadManager* download_manager = DownloadManagerForShell(shell); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new DownloadTestObserverTerminal(download_manager, num_downloads, 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a DownloadTestObserverInProgress that will wait for the 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // specified number of downloads to start. 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadCreateObserver* CreateInProgressWaiter( 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shell* shell, int num_downloads) { 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadManager* download_manager = DownloadManagerForShell(shell); 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new DownloadCreateObserver(download_manager); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 621eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DownloadTestObserver* CreateInterruptedWaiter( 622eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Shell* shell, int num_downloads) { 623eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DownloadManager* download_manager = DownloadManagerForShell(shell); 624eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return new DownloadTestObserverInterrupted(download_manager, num_downloads, 625eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); 626eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 627eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: Cannot be used with other alternative DownloadFileFactorys 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetupEnsureNoPendingDownloads() { 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadManagerForShell(shell())->SetDownloadFileFactoryForTesting( 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DownloadFileFactory>( 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new CountingDownloadFileFactory()).Pass()); 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool EnsureNoPendingDownloads() { 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = true; 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, FROM_HERE, 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&EnsureNoPendingDownloadJobsOnIO, &result)); 640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->Run(); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result && 642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (CountingDownloadFile::GetNumberActiveFilesFromFileThread() == 0); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void NavigateToURLAndWaitForDownload( 6465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu Shell* shell, 6475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const GURL& url, 6485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DownloadItem::DownloadState expected_terminal_state) { 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DownloadTestObserver> observer(CreateWaiter(shell, 1)); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NavigateToURL(shell, url); 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer->WaitForFinished(); 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1u, observer->NumDownloadsSeenInState(expected_terminal_state)); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Checks that |path| is has |file_size| bytes, and matches the |value| 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // string. 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool VerifyFile(const base::FilePath& path, 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& value, 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int64 file_size) { 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string file_contents; 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 66258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool read = base::ReadFileToString(path, &file_contents); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(read) << "Failed reading file: " << path.value() << std::endl; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // Couldn't read the file. 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: we don't handle really large files (more than size_t can hold) 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so we will fail in that case. 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t expected_size = static_cast<size_t>(file_size); 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check the size. 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(expected_size, file_contents.size()); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (expected_size != file_contents.size()) 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check the contents. 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(value, file_contents); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (memcmp(file_contents.c_str(), value.c_str(), expected_size) != 0) 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Start a download and return the item. 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadItem* StartDownloadAndReturnItem(GURL url) { 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<DownloadCreateObserver> observer( 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateInProgressWaiter(shell(), 1)); 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NavigateToURL(shell(), url); 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observer->WaitForFinished(); 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<DownloadItem*> downloads; 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadManagerForShell(shell())->GetAllDownloads(&downloads); 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1u, downloads.size()); 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (1u != downloads.size()) 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return downloads[0]; 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Wait for data 6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void WaitForData(DownloadItem* download, int size) { 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadUpdatedObserver data_observer( 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, base::Bind(&DataReceivedFilter, size)); 7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data_observer.WaitForEvent(); 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(size, download->GetReceivedBytes()); 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState()); 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Tell the test server to release a pending RST and confirm 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that the interrupt is received properly (for download resumption 7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // testing). 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ReleaseRSTAndConfirmInterruptForResume(DownloadItem* download) { 711eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<DownloadTestObserver> rst_observer( 712eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateInterruptedWaiter(shell(), 1)); 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NavigateToURL(shell(), test_server()->GetURL("download-finish")); 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rst_observer->WaitForFinished(); 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DownloadItem::INTERRUPTED, download->GetState()); 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Confirm file status expected for the given location in a stream 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // provided by the resume test server. 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ConfirmFileStatusForResume( 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadItem* download, bool file_exists, 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int received_bytes, int total_bytes, 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& expected_filename) { 724a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // expected_filename is only known if the file exists. 725a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) ASSERT_EQ(file_exists, !expected_filename.empty()); 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(received_bytes, download->GetReceivedBytes()); 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(total_bytes, download->GetTotalBytes()); 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expected_filename.value(), 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download->GetFullPath().BaseName().value()); 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(file_exists, 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (!download->GetFullPath().empty() && 7327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::PathExists(download->GetFullPath()))); 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (file_exists) { 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string file_contents; 73658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_TRUE(base::ReadFileToString( 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download->GetFullPath(), &file_contents)); 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(static_cast<size_t>(received_bytes), file_contents.size()); 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < received_bytes; ++i) { 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(static_cast<char>((i * 2 + 15) % 256), file_contents[i]) 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "File contents diverged at position " << i 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " for " << expected_filename.value(); 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (static_cast<char>((i * 2 + 15) % 256) != file_contents[i]) 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void EnsureNoPendingDownloadJobsOnIO(bool* result) { 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (URLRequestSlowDownloadJob::NumberOutstandingRequests()) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = false; 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BrowserThread::UI, FROM_HERE, base::MessageLoop::QuitClosure()); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Location of the downloads directory for these tests 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ScopedTempDir downloads_directory_; 7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<TestShellDownloadManagerDelegate> test_delegate_; 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadCancelled) { 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetupEnsureNoPendingDownloads(); 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a download, wait until it's started, and confirm 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we're in the expected state. 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<DownloadCreateObserver> observer( 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateInProgressWaiter(shell(), 1)); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NavigateToURL(shell(), GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl)); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer->WaitForFinished(); 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<DownloadItem*> downloads; 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadManagerForShell(shell())->GetAllDownloads(&downloads); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, downloads.size()); 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->GetState()); 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel the download and wait for download system quiesce. 780868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) downloads[0]->Cancel(true); 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<DownloadTestFlushObserver> flush_observer( 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new DownloadTestFlushObserver(DownloadManagerForShell(shell()))); 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flush_observer->WaitForFlush(); 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the important info from other threads and check it. 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(EnsureNoPendingDownloads()); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that downloading multiple (in this case, 2) files does not result in 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// corrupted files. 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, MultiDownload) { 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetupEnsureNoPendingDownloads(); 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a download, wait until it's started, and confirm 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we're in the expected state. 7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<DownloadCreateObserver> observer1( 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateInProgressWaiter(shell(), 1)); 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NavigateToURL(shell(), GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl)); 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer1->WaitForFinished(); 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<DownloadItem*> downloads; 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadManagerForShell(shell())->GetAllDownloads(&downloads); 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, downloads.size()); 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->GetState()); 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadItem* download1 = downloads[0]; // The only download. 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start the second download and wait until it's done. 8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file(FILE_PATH_LITERAL("download-test.lib")); 8091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GURL url(net::URLRequestMockHTTPJob::GetMockUrl(file)); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Download the file and wait. 8115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NavigateToURLAndWaitForDownload(shell(), url, DownloadItem::COMPLETE); 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Should now have 2 items on the manager. 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) downloads.clear(); 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadManagerForShell(shell())->GetAllDownloads(&downloads); 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(2u, downloads.size()); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't know the order of the downloads. 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadItem* download2 = downloads[(download1 == downloads[0]) ? 1 : 0]; 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(DownloadItem::IN_PROGRESS, download1->GetState()); 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(DownloadItem::COMPLETE, download2->GetState()); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allow the first request to finish. 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DownloadTestObserver> observer2(CreateWaiter(shell(), 1)); 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NavigateToURL(shell(), GURL(URLRequestSlowDownloadJob::kFinishDownloadUrl)); 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer2->WaitForFinished(); // Wait for the third request. 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1u, observer2->NumDownloadsSeenInState(DownloadItem::COMPLETE)); 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the important info from other threads and check it. 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(EnsureNoPendingDownloads()); 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The |DownloadItem|s should now be done and have the final file names. 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that the files have the expected data and size. 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |file1| should be full of '*'s, and |file2| should be the same as the 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // source file. 836b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::FilePath file1(download1->GetTargetFilePath()); 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t file_size1 = URLRequestSlowDownloadJob::kFirstDownloadSize + 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestSlowDownloadJob::kSecondDownloadSize; 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string expected_contents(file_size1, '*'); 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(VerifyFile(file1, expected_contents, file_size1)); 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 842b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::FilePath file2(download2->GetTargetFilePath()); 8437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ASSERT_TRUE(base::ContentsEqual( 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file2, GetTestFilePath("download", "download-test.lib"))); 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 847a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#if defined(ENABLE_PLUGINS) 848a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// Content served with a MIME type of application/octet-stream should be 849a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// downloaded even when a plugin can be found that handles the file type. 850a3f7b4e666c476898878fa745f637129375cd889Ben MurdochIN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadOctetStream) { 851a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const base::FilePath::CharType kTestFilePath[] = 852a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch FILE_PATH_LITERAL("octet-stream.abc"); 853a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const char kTestPluginName[] = "TestPlugin"; 854a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const char kTestMimeType[] = "application/x-test-mime-type"; 855a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const char kTestFileType[] = "abc"; 856a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 857a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch WebPluginInfo plugin_info; 858a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch plugin_info.name = base::ASCIIToUTF16(kTestPluginName); 859a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch plugin_info.mime_types.push_back( 860a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch WebPluginMimeType(kTestMimeType, kTestFileType, "")); 861a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch PluginServiceImpl::GetInstance()->RegisterInternalPlugin(plugin_info, false); 862a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 863a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch // The following is served with a Content-Type of application/octet-stream. 8641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GURL url( 8651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::URLRequestMockHTTPJob::GetMockUrl(base::FilePath(kTestFilePath))); 8665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NavigateToURLAndWaitForDownload(shell(), url, DownloadItem::COMPLETE); 867a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 868a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#endif 869a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Try to cancel just before we release the download file, by delaying final 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// rename callback. 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelAtFinalRename) { 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Setup new factory. 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadFileWithDelayFactory* file_factory = 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new DownloadFileWithDelayFactory(); 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadManagerImpl* download_manager(DownloadManagerForShell(shell())); 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) download_manager->SetDownloadFileFactoryForTesting( 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DownloadFileFactory>(file_factory).Pass()); 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a download 8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file(FILE_PATH_LITERAL("download-test.lib")); 8821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NavigateToURL(shell(), net::URLRequestMockHTTPJob::GetMockUrl(file)); 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait until the first (intermediate file) rename and execute the callback. 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_factory->WaitForSomeCallback(); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<base::Closure> callbacks; 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_factory->GetAllRenameCallbacks(&callbacks); 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, callbacks.size()); 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks[0].Run(); 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks.clear(); 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait until the second (final) rename callback is posted. 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_factory->WaitForSomeCallback(); 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_factory->GetAllRenameCallbacks(&callbacks); 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, callbacks.size()); 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel it. 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<DownloadItem*> items; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) download_manager->GetAllDownloads(&items); 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, items.size()); 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items[0]->Cancel(true); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunAllPendingInMessageLoop(); 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check state. 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(DownloadItem::CANCELLED, items[0]->GetState()); 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Run final rename callback. 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks[0].Run(); 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks.clear(); 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check state. 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(DownloadItem::CANCELLED, items[0]->GetState()); 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Try to cancel just after we release the download file, by delaying 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in ShouldOpenDownload. 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelAtRelease) { 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadManagerImpl* download_manager(DownloadManagerForShell(shell())); 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mark delegate for delayed open. 9215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetDownloadManagerDelegate()->SetDelayedOpen(true); 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Setup new factory. 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadFileWithDelayFactory* file_factory = 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new DownloadFileWithDelayFactory(); 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) download_manager->SetDownloadFileFactoryForTesting( 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DownloadFileFactory>(file_factory).Pass()); 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a download 9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file(FILE_PATH_LITERAL("download-test.lib")); 9311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NavigateToURL(shell(), net::URLRequestMockHTTPJob::GetMockUrl(file)); 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait until the first (intermediate file) rename and execute the callback. 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_factory->WaitForSomeCallback(); 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<base::Closure> callbacks; 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_factory->GetAllRenameCallbacks(&callbacks); 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, callbacks.size()); 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks[0].Run(); 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks.clear(); 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait until the second (final) rename callback is posted. 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_factory->WaitForSomeCallback(); 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_factory->GetAllRenameCallbacks(&callbacks); 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, callbacks.size()); 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Call it. 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks[0].Run(); 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks.clear(); 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Confirm download still IN_PROGRESS (internal state COMPLETING). 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<DownloadItem*> items; 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) download_manager->GetAllDownloads(&items); 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState()); 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel the download; confirm cancel fails. 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, items.size()); 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items[0]->Cancel(true); 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState()); 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Need to complete open test. 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<DownloadOpenDelayedCallback> delayed_callbacks; 9625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetDownloadManagerDelegate()->GetDelayedCallbacks( 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &delayed_callbacks); 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, delayed_callbacks.size()); 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delayed_callbacks[0].Run(true); 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // *Now* the download should be complete. 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(DownloadItem::COMPLETE, items[0]->GetState()); 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Try to shutdown with a download in progress to make sure shutdown path 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// works properly. 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownInProgress) { 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a download that won't complete. 9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<DownloadCreateObserver> observer( 9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateInProgressWaiter(shell(), 1)); 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NavigateToURL(shell(), GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl)); 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer->WaitForFinished(); 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the item. 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<DownloadItem*> items; 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadManagerForShell(shell())->GetAllDownloads(&items); 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, items.size()); 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState()); 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Shutdown the download manager and make sure we get the right 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notifications in the right order. 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StrictMock<MockDownloadItemObserver> item_observer; 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items[0]->AddObserver(&item_observer); 990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockDownloadManagerObserver manager_observer( 991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DownloadManagerForShell(shell())); 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't care about ModelChanged() events. 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(manager_observer, ModelChanged(_)) 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillRepeatedly(Return()); 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InSequence notifications; 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(manager_observer, MockManagerGoingDown( 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadManagerForShell(shell()))) 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(Return()); 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(item_observer, OnDownloadUpdated( 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AllOf(items[0], 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Property(&DownloadItem::GetState, DownloadItem::CANCELLED)))) 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(Return()); 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(item_observer, OnDownloadDestroyed(items[0])) 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(Return()); 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // See http://crbug.com/324525. If we have a refcount release/post task 10105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // race, the second post will stall the IO thread long enough so that we'll 10115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // lose the race and crash. The first stall is just to give the UI thread 10125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // a chance to get the second stall onto the IO thread queue after the cancel 10135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // message created by Shutdown and before the notification callback 10145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // created by the IO thread in canceling the request. 10155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 10165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&base::PlatformThread::Sleep, 10175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta::FromMilliseconds(25))); 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadManagerForShell(shell())->Shutdown(); 10195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 10205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&base::PlatformThread::Sleep, 10215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta::FromMilliseconds(25))); 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items.clear(); 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Try to shutdown just after we release the download file, by delaying 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// release. 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownAtRelease) { 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadManagerImpl* download_manager(DownloadManagerForShell(shell())); 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mark delegate for delayed open. 10315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetDownloadManagerDelegate()->SetDelayedOpen(true); 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Setup new factory. 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadFileWithDelayFactory* file_factory = 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new DownloadFileWithDelayFactory(); 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) download_manager->SetDownloadFileFactoryForTesting( 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DownloadFileFactory>(file_factory).Pass()); 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a download 10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file(FILE_PATH_LITERAL("download-test.lib")); 10411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NavigateToURL(shell(), net::URLRequestMockHTTPJob::GetMockUrl(file)); 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait until the first (intermediate file) rename and execute the callback. 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_factory->WaitForSomeCallback(); 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<base::Closure> callbacks; 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_factory->GetAllRenameCallbacks(&callbacks); 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, callbacks.size()); 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks[0].Run(); 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks.clear(); 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait until the second (final) rename callback is posted. 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_factory->WaitForSomeCallback(); 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_factory->GetAllRenameCallbacks(&callbacks); 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, callbacks.size()); 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Call it. 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks[0].Run(); 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callbacks.clear(); 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Confirm download isn't complete yet. 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<DownloadItem*> items; 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadManagerForShell(shell())->GetAllDownloads(&items); 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState()); 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel the download; confirm cancel fails anyway. 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, items.size()); 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items[0]->Cancel(true); 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState()); 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunAllPendingInMessageLoop(); 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(DownloadItem::IN_PROGRESS, items[0]->GetState()); 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockDownloadItemObserver observer; 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items[0]->AddObserver(&observer); 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(observer, OnDownloadDestroyed(items[0])); 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Shutdown the download manager. Mostly this is confirming a lack of 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // crashes. 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadManagerForShell(shell())->Shutdown(); 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeInterruptedDownload) { 10826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine::ForCurrentProcess()->AppendSwitch( 10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switches::kEnableDownloadResumption); 10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(test_server()->Start()); 10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url = test_server()->GetURL( 10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringPrintf("rangereset?size=%d&rst_boundary=%d", 10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetSafeBufferChunk() * 3, GetSafeBufferChunk())); 10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1090c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell())); 1091c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); 1092c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadItem* download(StartDownloadAndReturnItem(url)); 10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WaitForData(download, GetSafeBufferChunk()); 1095c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ::testing::Mock::VerifyAndClearExpectations(&dm_observer); 10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Confirm resumption while in progress doesn't do anything. 1098a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) download->Resume(); 10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(GetSafeBufferChunk(), download->GetReceivedBytes()); 11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(DownloadItem::IN_PROGRESS, download->GetState()); 11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Tell the server to send the RST and confirm the interrupt happens. 11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReleaseRSTAndConfirmInterruptForResume(download); 11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConfirmFileStatusForResume( 11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, 11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); 11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Resume, confirming received bytes on resumption is correct. 1109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make sure no creation calls are included. 1110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(0); 11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int initial_size = 0; 11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadUpdatedObserver initial_size_observer( 11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, base::Bind(&InitialSizeFilter, &initial_size)); 1114a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) download->Resume(); 11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) initial_size_observer.WaitForEvent(); 11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(GetSafeBufferChunk(), initial_size); 1117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ::testing::Mock::VerifyAndClearExpectations(&dm_observer); 11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // and wait for expected data. 11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WaitForData(download, GetSafeBufferChunk() * 2); 11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Tell the server to send the RST and confirm the interrupt happens. 11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReleaseRSTAndConfirmInterruptForResume(download); 11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConfirmFileStatusForResume( 11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, true, GetSafeBufferChunk() * 2, GetSafeBufferChunk() * 3, 11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); 11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Resume and wait for completion. 11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadUpdatedObserver completion_observer( 11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, base::Bind(DownloadCompleteFilter)); 1131a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) download->Resume(); 11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) completion_observer.WaitForEvent(); 11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConfirmFileStatusForResume( 11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3, 11362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("rangereset"))); 11372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Confirm resumption while complete doesn't do anything. 1139a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) download->Resume(); 11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(GetSafeBufferChunk() * 3, download->GetReceivedBytes()); 11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(DownloadItem::COMPLETE, download->GetState()); 11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunAllPendingInMessageLoop(); 11432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(GetSafeBufferChunk() * 3, download->GetReceivedBytes()); 11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(DownloadItem::COMPLETE, download->GetState()); 11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Confirm restart fallback happens if a range request is bounced. 11482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeInterruptedDownloadNoRange) { 11496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine::ForCurrentProcess()->AppendSwitch( 11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switches::kEnableDownloadResumption); 11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(test_server()->Start()); 11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Auto-restart if server doesn't handle ranges. 11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url = test_server()->GetURL( 11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringPrintf( 11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // First download hits an RST, rest don't, no ranges. 11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "rangereset?size=%d&rst_boundary=%d&" 11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "token=NoRange&rst_limit=1&bounce_range", 11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetSafeBufferChunk() * 3, GetSafeBufferChunk())); 11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Start the download and wait for first data chunk. 11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadItem* download(StartDownloadAndReturnItem(url)); 11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WaitForData(download, GetSafeBufferChunk()); 11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordingDownloadObserver recorder(download); 11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReleaseRSTAndConfirmInterruptForResume(download); 11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConfirmFileStatusForResume( 11692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, 11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); 11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadUpdatedObserver completion_observer( 11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, base::Bind(DownloadCompleteFilter)); 1174a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) download->Resume(); 11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) completion_observer.WaitForEvent(); 11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConfirmFileStatusForResume( 11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3, 11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("rangereset"))); 11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const RecordingDownloadObserver::RecordStruct expected_record[] = { 11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Result of RST 11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {DownloadItem::INTERRUPTED, GetSafeBufferChunk()}, 11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Starting continuation 11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {DownloadItem::IN_PROGRESS, GetSafeBufferChunk()}, 11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Notification of receiving whole file. 11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {DownloadItem::IN_PROGRESS, 0}, 11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Completion. 11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3}, 11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record)); 11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Confirm restart fallback happens if a precondition is failed. 11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, 11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResumeInterruptedDownloadBadPrecondition) { 11986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine::ForCurrentProcess()->AppendSwitch( 11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switches::kEnableDownloadResumption); 12002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(test_server()->Start()); 12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL url = test_server()->GetURL(base::StringPrintf( 12035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // First download hits an RST, rest don't, precondition fail. 12045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "rangereset?size=%d&rst_boundary=%d&" 12055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "token=BadPrecondition&rst_limit=1&fail_precondition=2", 12065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetSafeBufferChunk() * 3, 12075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetSafeBufferChunk())); 12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Start the download and wait for first data chunk. 12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadItem* download(StartDownloadAndReturnItem(url)); 12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WaitForData(download, GetSafeBufferChunk()); 12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordingDownloadObserver recorder(download); 12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReleaseRSTAndConfirmInterruptForResume(download); 12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConfirmFileStatusForResume( 12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, 12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); 12195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ("BadPrecondition2", download->GetETag()); 12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadUpdatedObserver completion_observer( 12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, base::Bind(DownloadCompleteFilter)); 1223a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) download->Resume(); 12242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) completion_observer.WaitForEvent(); 12252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConfirmFileStatusForResume( 12272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3, 12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("rangereset"))); 12295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ("BadPrecondition0", download->GetETag()); 12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const RecordingDownloadObserver::RecordStruct expected_record[] = { 12322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Result of RST 12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {DownloadItem::INTERRUPTED, GetSafeBufferChunk()}, 12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Starting continuation 12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {DownloadItem::IN_PROGRESS, GetSafeBufferChunk()}, 12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Server precondition fail. 1237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch {DownloadItem::INTERRUPTED, 0}, 12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Notification of successful restart. 12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {DownloadItem::IN_PROGRESS, 0}, 12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Completion. 12412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3}, 12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 12432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record)); 12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Confirm we don't try to resume if we don't have a verifier. 12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, 12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResumeInterruptedDownloadNoVerifiers) { 12506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine::ForCurrentProcess()->AppendSwitch( 12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switches::kEnableDownloadResumption); 12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(test_server()->Start()); 12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url = test_server()->GetURL( 12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringPrintf( 12562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // First download hits an RST, rest don't, no verifiers. 12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "rangereset?size=%d&rst_boundary=%d&" 12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "token=NoRange&rst_limit=1&no_verifiers", 12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetSafeBufferChunk() * 3, GetSafeBufferChunk())); 12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Start the download and wait for first data chunk. 12622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadItem* download(StartDownloadAndReturnItem(url)); 12632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WaitForData(download, GetSafeBufferChunk()); 12642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordingDownloadObserver recorder(download); 12662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReleaseRSTAndConfirmInterruptForResume(download); 12682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConfirmFileStatusForResume( 12692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, false, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, 1270a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::FilePath()); 12712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadUpdatedObserver completion_observer( 12732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, base::Bind(DownloadCompleteFilter)); 1274a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) download->Resume(); 12752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) completion_observer.WaitForEvent(); 12762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConfirmFileStatusForResume( 12782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3, 12792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("rangereset"))); 12802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const RecordingDownloadObserver::RecordStruct expected_record[] = { 12822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Result of RST 12832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {DownloadItem::INTERRUPTED, GetSafeBufferChunk()}, 12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Restart for lack of verifiers 12852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {DownloadItem::IN_PROGRESS, 0}, 12862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Completion. 12872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3}, 12882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 12892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record)); 12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithDeletedFile) { 12946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine::ForCurrentProcess()->AppendSwitch( 12952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switches::kEnableDownloadResumption); 12962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(test_server()->Start()); 12972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url = test_server()->GetURL( 12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringPrintf( 13002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // First download hits an RST, rest don't 13012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "rangereset?size=%d&rst_boundary=%d&" 13022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "token=NoRange&rst_limit=1", 13032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetSafeBufferChunk() * 3, GetSafeBufferChunk())); 13042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Start the download and wait for first data chunk. 13062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadItem* download(StartDownloadAndReturnItem(url)); 13072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WaitForData(download, GetSafeBufferChunk()); 13082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordingDownloadObserver recorder(download); 13102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReleaseRSTAndConfirmInterruptForResume(download); 13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConfirmFileStatusForResume( 13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, 13142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); 13152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Delete the intermediate file. 13177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::DeleteFile(download->GetFullPath(), false); 13182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadUpdatedObserver completion_observer( 13202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, base::Bind(DownloadCompleteFilter)); 1321a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) download->Resume(); 13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) completion_observer.WaitForEvent(); 13232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConfirmFileStatusForResume( 13252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, true, GetSafeBufferChunk() * 3, GetSafeBufferChunk() * 3, 13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("rangereset"))); 13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const RecordingDownloadObserver::RecordStruct expected_record[] = { 13292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Result of RST 13302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {DownloadItem::INTERRUPTED, GetSafeBufferChunk()}, 13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Starting continuation 13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {DownloadItem::IN_PROGRESS, GetSafeBufferChunk()}, 13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Error because file isn't there. 1334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch {DownloadItem::INTERRUPTED, 0}, 1335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Restart. 13362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {DownloadItem::IN_PROGRESS, 0}, 13372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Completion. 13382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) {DownloadItem::COMPLETE, GetSafeBufferChunk() * 3}, 13392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 13402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recorder.CompareToExpectedRecord(expected_record, arraysize(expected_record)); 13422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 13432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileInitError) { 13456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine::ForCurrentProcess()->AppendSwitch( 13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switches::kEnableDownloadResumption); 13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file(FILE_PATH_LITERAL("download-test.lib")); 13481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GURL url(net::URLRequestMockHTTPJob::GetMockUrl(file)); 13492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Setup the error injector. 13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TestFileErrorInjector> injector( 13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestFileErrorInjector::Create(DownloadManagerForShell(shell()))); 13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestFileErrorInjector::FileErrorInfo err = { 13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url.spec(), 13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestFileErrorInjector::FILE_OPERATION_INITIALIZE, 13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 0, 13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE 13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 13602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) injector->AddError(err); 13612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) injector->InjectErrors(); 13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Start and watch for interrupt. 1364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<DownloadTestObserver> int_observer( 1365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateInterruptedWaiter(shell(), 1)); 13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadItem* download(StartDownloadAndReturnItem(url)); 13672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int_observer->WaitForFinished(); 13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState()); 13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE, 13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download->GetLastReason()); 13712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, download->GetReceivedBytes()); 13722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(download->GetFullPath().empty()); 13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(download->GetTargetFilePath().empty()); 13742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We need to make sure that any cross-thread downloads communication has 13762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // quiesced before clearing and injecting the new errors, as the 13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // InjectErrors() routine alters the currently in use download file 13782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // factory, which is a file thread object. 13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunAllPendingInMessageLoop(BrowserThread::FILE); 13802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunAllPendingInMessageLoop(); 13812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Clear the old errors list. 13832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) injector->ClearErrors(); 13842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) injector->InjectErrors(); 13852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Resume and watch completion. 13872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadUpdatedObserver completion_observer( 13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, base::Bind(DownloadCompleteFilter)); 1389a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) download->Resume(); 13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) completion_observer.WaitForEvent(); 13912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE); 13922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 13932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, 13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResumeWithFileIntermediateRenameError) { 13966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine::ForCurrentProcess()->AppendSwitch( 13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switches::kEnableDownloadResumption); 13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file(FILE_PATH_LITERAL("download-test.lib")); 13991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GURL url(net::URLRequestMockHTTPJob::GetMockUrl(file)); 14002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Setup the error injector. 14022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TestFileErrorInjector> injector( 14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestFileErrorInjector::Create(DownloadManagerForShell(shell()))); 14042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestFileErrorInjector::FileErrorInfo err = { 14062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url.spec(), 14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestFileErrorInjector::FILE_OPERATION_RENAME_UNIQUIFY, 14082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 0, 14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE 14102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 14112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) injector->AddError(err); 14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) injector->InjectErrors(); 14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Start and watch for interrupt. 1415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<DownloadTestObserver> int_observer( 1416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateInterruptedWaiter(shell(), 1)); 14172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadItem* download(StartDownloadAndReturnItem(url)); 14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int_observer->WaitForFinished(); 14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState()); 14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE, 14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download->GetLastReason()); 14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(download->GetFullPath().empty()); 1423a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Target path will have been set after file name determination. GetFullPath() 1424a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // being empty is sufficient to signal that filename determination needs to be 1425a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // redone. 1426a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_FALSE(download->GetTargetFilePath().empty()); 14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We need to make sure that any cross-thread downloads communication has 14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // quiesced before clearing and injecting the new errors, as the 14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // InjectErrors() routine alters the currently in use download file 14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // factory, which is a file thread object. 14322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunAllPendingInMessageLoop(BrowserThread::FILE); 14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunAllPendingInMessageLoop(); 14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Clear the old errors list. 14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) injector->ClearErrors(); 14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) injector->InjectErrors(); 14382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Resume and watch completion. 14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadUpdatedObserver completion_observer( 14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, base::Bind(DownloadCompleteFilter)); 1442a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) download->Resume(); 14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) completion_observer.WaitForEvent(); 14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE); 14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, ResumeWithFileFinalRenameError) { 14486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine::ForCurrentProcess()->AppendSwitch( 14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switches::kEnableDownloadResumption); 14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file(FILE_PATH_LITERAL("download-test.lib")); 14511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GURL url(net::URLRequestMockHTTPJob::GetMockUrl(file)); 14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Setup the error injector. 14542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<TestFileErrorInjector> injector( 14552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestFileErrorInjector::Create(DownloadManagerForShell(shell()))); 14562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadManagerForShell(shell())->RemoveAllDownloads(); 14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestFileErrorInjector::FileErrorInfo err = { 14592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url.spec(), 14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestFileErrorInjector::FILE_OPERATION_RENAME_ANNOTATE, 14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 0, 14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE 14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) injector->AddError(err); 14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) injector->InjectErrors(); 14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Start and watch for interrupt. 1468eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<DownloadTestObserver> int_observer( 1469eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateInterruptedWaiter(shell(), 1)); 14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadItem* download(StartDownloadAndReturnItem(url)); 14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int_observer->WaitForFinished(); 14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState()); 14732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE, 14742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download->GetLastReason()); 14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(download->GetFullPath().empty()); 1476a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Target path should still be intact. 1477a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_FALSE(download->GetTargetFilePath().empty()); 14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We need to make sure that any cross-thread downloads communication has 14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // quiesced before clearing and injecting the new errors, as the 14812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // InjectErrors() routine alters the currently in use download file 14822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // factory, which is a file thread object. 14832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunAllPendingInMessageLoop(BrowserThread::FILE); 14842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunAllPendingInMessageLoop(); 14852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Clear the old errors list. 14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) injector->ClearErrors(); 14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) injector->InjectErrors(); 14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Resume and watch completion. 14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadUpdatedObserver completion_observer( 14922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download, base::Bind(DownloadCompleteFilter)); 1493a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) download->Resume(); 14942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) completion_observer.WaitForEvent(); 14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(download->GetState(), DownloadItem::COMPLETE); 14962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 149890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// An interrupted download should remove the intermediate file when it is 149990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// cancelled. 150090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelInterruptedDownload) { 15016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine::ForCurrentProcess()->AppendSwitch( 150290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) switches::kEnableDownloadResumption); 150390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(test_server()->Start()); 150490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 150590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GURL url1 = test_server()->GetURL( 150690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::StringPrintf("rangereset?size=%d&rst_boundary=%d", 150790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetSafeBufferChunk() * 3, GetSafeBufferChunk())); 150890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 150990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DownloadItem* download(StartDownloadAndReturnItem(url1)); 151090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WaitForData(download, GetSafeBufferChunk()); 151190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 151290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ReleaseRSTAndConfirmInterruptForResume(download); 151390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ConfirmFileStatusForResume( 151490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, 151590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); 151690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 151790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::FilePath intermediate_path(download->GetFullPath()); 151890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_FALSE(intermediate_path.empty()); 15197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(base::PathExists(intermediate_path)); 152090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 152190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) download->Cancel(true /* user_cancel */); 152290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RunAllPendingInMessageLoop(BrowserThread::FILE); 152390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RunAllPendingInMessageLoop(); 152490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 152590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The intermediate file should now be gone. 15267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(base::PathExists(intermediate_path)); 152790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(download->GetFullPath().empty()); 152890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 152990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 153090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveDownload) { 15316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine::ForCurrentProcess()->AppendSwitch( 153290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) switches::kEnableDownloadResumption); 153390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(test_server()->Start()); 153490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 153590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // An interrupted download should remove the intermediate file when it is 153690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // removed. 153790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) { 153890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GURL url1 = test_server()->GetURL( 153990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::StringPrintf("rangereset?size=%d&rst_boundary=%d", 154090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetSafeBufferChunk() * 3, GetSafeBufferChunk())); 154190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 154290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DownloadItem* download(StartDownloadAndReturnItem(url1)); 154390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WaitForData(download, GetSafeBufferChunk()); 154490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ReleaseRSTAndConfirmInterruptForResume(download); 154590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ConfirmFileStatusForResume( 154690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, 154790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); 154890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 154990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::FilePath intermediate_path(download->GetFullPath()); 155090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_FALSE(intermediate_path.empty()); 15517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(base::PathExists(intermediate_path)); 155290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 155390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) download->Remove(); 155490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RunAllPendingInMessageLoop(BrowserThread::FILE); 155590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RunAllPendingInMessageLoop(); 155690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 155790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The intermediate file should now be gone. 15587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(base::PathExists(intermediate_path)); 155990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 156090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 156190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // A completed download shouldn't delete the downloaded file when it is 156290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // removed. 156390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) { 156490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Start the second download and wait until it's done. 156590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::FilePath file2(FILE_PATH_LITERAL("download-test.lib")); 15661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GURL url2(net::URLRequestMockHTTPJob::GetMockUrl(file2)); 156790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<DownloadTestObserver> completion_observer( 156890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CreateWaiter(shell(), 1)); 156990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DownloadItem* download(StartDownloadAndReturnItem(url2)); 157090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) completion_observer->WaitForFinished(); 157190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 157290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The target path should exist. 157390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::FilePath target_path(download->GetTargetFilePath()); 15747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(base::PathExists(target_path)); 157590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) download->Remove(); 157690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RunAllPendingInMessageLoop(BrowserThread::FILE); 157790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RunAllPendingInMessageLoop(); 157890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 157990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The file should still exist. 15807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(base::PathExists(target_path)); 158190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 158290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 158390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 158490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, RemoveResumingDownload) { 158590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetupEnsureNoPendingDownloads(); 15866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine::ForCurrentProcess()->AppendSwitch( 158790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) switches::kEnableDownloadResumption); 158890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(test_server()->Start()); 158990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 159090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GURL url = test_server()->GetURL( 159190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::StringPrintf("rangereset?size=%d&rst_boundary=%d", 159290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetSafeBufferChunk() * 3, GetSafeBufferChunk())); 159390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 159490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell())); 159590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); 159690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 159790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DownloadItem* download(StartDownloadAndReturnItem(url)); 159890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WaitForData(download, GetSafeBufferChunk()); 159990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ::testing::Mock::VerifyAndClearExpectations(&dm_observer); 160090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 160190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Tell the server to send the RST and confirm the interrupt happens. 160290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ReleaseRSTAndConfirmInterruptForResume(download); 160390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ConfirmFileStatusForResume( 160490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, 160590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); 160690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 160790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::FilePath intermediate_path(download->GetFullPath()); 160890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_FALSE(intermediate_path.empty()); 16097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(base::PathExists(intermediate_path)); 161090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 161190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Resume and remove download. We expect only a single OnDownloadCreated() 161290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // call, and that's for the second download created below. 161390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); 161490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) download->Resume(); 161590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) download->Remove(); 161690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 161790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The intermediate file should now be gone. 161890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RunAllPendingInMessageLoop(BrowserThread::FILE); 161990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RunAllPendingInMessageLoop(); 16207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(base::PathExists(intermediate_path)); 162190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 162290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Start the second download and wait until it's done. The test server is 162390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // single threaded. The response to this download request should follow the 162490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // response to the previous resumption request. 162590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GURL url2(test_server()->GetURL("rangereset?size=100&rst_limit=0&token=x")); 16265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NavigateToURLAndWaitForDownload(shell(), url2, DownloadItem::COMPLETE); 162790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 162890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(EnsureNoPendingDownloads()); 162990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 163090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 163190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, CancelResumingDownload) { 163290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetupEnsureNoPendingDownloads(); 16336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine::ForCurrentProcess()->AppendSwitch( 163490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) switches::kEnableDownloadResumption); 163590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(test_server()->Start()); 163690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 163790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GURL url = test_server()->GetURL( 163890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::StringPrintf("rangereset?size=%d&rst_boundary=%d", 163990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetSafeBufferChunk() * 3, GetSafeBufferChunk())); 164090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 164190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) MockDownloadManagerObserver dm_observer(DownloadManagerForShell(shell())); 164290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); 164390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 164490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DownloadItem* download(StartDownloadAndReturnItem(url)); 164590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WaitForData(download, GetSafeBufferChunk()); 164690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ::testing::Mock::VerifyAndClearExpectations(&dm_observer); 164790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 164890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Tell the server to send the RST and confirm the interrupt happens. 164990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ReleaseRSTAndConfirmInterruptForResume(download); 165090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ConfirmFileStatusForResume( 165190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) download, true, GetSafeBufferChunk(), GetSafeBufferChunk() * 3, 165290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("rangereset.crdownload"))); 165390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 165490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::FilePath intermediate_path(download->GetFullPath()); 165590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_FALSE(intermediate_path.empty()); 16567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_TRUE(base::PathExists(intermediate_path)); 165790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 165890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Resume and cancel download. We expect only a single OnDownloadCreated() 165990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // call, and that's for the second download created below. 166090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_CALL(dm_observer, OnDownloadCreated(_,_)).Times(1); 166190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) download->Resume(); 1662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) download->Cancel(true); 166390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 166490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The intermediate file should now be gone. 166590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RunAllPendingInMessageLoop(BrowserThread::FILE); 166690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RunAllPendingInMessageLoop(); 16677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_FALSE(base::PathExists(intermediate_path)); 166890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(download->GetFullPath().empty()); 166990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 167090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Start the second download and wait until it's done. The test server is 167190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // single threaded. The response to this download request should follow the 167290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // response to the previous resumption request. 167390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GURL url2(test_server()->GetURL("rangereset?size=100&rst_limit=0&token=x")); 16745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NavigateToURLAndWaitForDownload(shell(), url2, DownloadItem::COMPLETE); 167590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 167690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(EnsureNoPendingDownloads()); 167790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 167890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Check that the cookie policy is correctly updated when downloading a file 16803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// that redirects cross origin. 16813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, CookiePolicy) { 16823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ASSERT_TRUE(test_server()->Start()); 16833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) net::HostPortPair host_port = test_server()->host_port_pair(); 16843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_EQ(host_port.host(), std::string("127.0.0.1")); 16853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 16863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Block third-party cookies. 16873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ShellNetworkDelegate::SetAcceptAllCookies(false); 16883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 16893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // |url| redirects to a different origin |download| which tries to set a 16903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // cookie. 16913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string download(base::StringPrintf( 16923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "http://localhost:%d/set-cookie?A=B", host_port.port())); 16933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) GURL url(test_server()->GetURL("server-redirect?" + download)); 16943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 16953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Download the file. 16963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetupEnsureNoPendingDownloads(); 16973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<DownloadUrlParameters> dl_params( 16983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DownloadUrlParameters::FromWebContents(shell()->web_contents(), url)); 16993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<DownloadTestObserver> observer(CreateWaiter(shell(), 1)); 17003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DownloadManagerForShell(shell())->DownloadUrl(dl_params.Pass()); 17013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) observer->WaitForFinished(); 17023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 17033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Get the important info from other threads and check it. 17043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE(EnsureNoPendingDownloads()); 17053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 17063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::vector<DownloadItem*> downloads; 17073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DownloadManagerForShell(shell())->GetAllDownloads(&downloads); 17083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ASSERT_EQ(1u, downloads.size()); 17093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ASSERT_EQ(DownloadItem::COMPLETE, downloads[0]->GetState()); 17103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 17113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Check that the cookies were correctly set. 17123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_EQ("A=B", 17133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content::GetCookies(shell()->web_contents()->GetBrowserContext(), 17143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) GURL(download))); 17153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 17163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 17175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// A filename suggestion specified via a @download attribute should not be 17185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// effective if the final download URL is in another origin from the original 17195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// download URL. 17205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuIN_PROC_BROWSER_TEST_F(DownloadContentTest, 17215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DownloadAttributeCrossOriginRedirect) { 17225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EmbeddedTestServer origin_one; 17235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EmbeddedTestServer origin_two; 17245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(origin_one.InitializeAndWaitUntilReady()); 17255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(origin_two.InitializeAndWaitUntilReady()); 17265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 17275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // The download-attribute.html page contains an anchor element whose href is 17285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // set to the value of the query parameter (specified as |target| in the URL 17295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // below). The suggested filename for the anchor is 'suggested-filename'. When 17305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // the page is loaded, a script simulates a click on the anchor, triggering a 17315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // download of the target URL. 17325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // 17335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // We construct two test servers; origin_one and origin_two. Once started, the 17345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // server URLs will differ by the port number. Therefore they will be in 17355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // different origins. 17365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu GURL download_url = origin_one.GetURL("/ping"); 17375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu GURL referrer_url = origin_one.GetURL( 17385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::string("/download-attribute.html?target=") + download_url.spec()); 17395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 17405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // <origin_one>/download-attribute.html initiates a download of 17415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // <origin_one>/ping, which redirects to <origin_two>/download. 17425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu origin_one.ServeFilesFromDirectory(GetTestFilePath("download", "")); 17435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu origin_one.RegisterRequestHandler( 17445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CreateRedirectHandler("/ping", origin_two.GetURL("/download"))); 17455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu origin_two.RegisterRequestHandler(CreateBasicResponseHandler( 17465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu "/download", "application/octet-stream", "Hello")); 17475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 17485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NavigateToURLAndWaitForDownload( 17495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu shell(), referrer_url, DownloadItem::COMPLETE); 17505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 17515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::vector<DownloadItem*> downloads; 17525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DownloadManagerForShell(shell())->GetAllDownloads(&downloads); 17535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_EQ(1u, downloads.size()); 17545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 17555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(FILE_PATH_LITERAL("download"), 17565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu downloads[0]->GetTargetFilePath().BaseName().value()); 17575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(origin_one.ShutdownAndWaitUntilComplete()); 17585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(origin_two.ShutdownAndWaitUntilComplete()); 17595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 17605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 17615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// A filename suggestion specified via a @download attribute should be effective 17625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// if the final download URL is in the same origin as the initial download URL. 17635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Test that this holds even if there are cross origin redirects in the middle 17645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// of the redirect chain. 17655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuIN_PROC_BROWSER_TEST_F(DownloadContentTest, 17665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DownloadAttributeSameOriginRedirect) { 17675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EmbeddedTestServer origin_one; 17685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EmbeddedTestServer origin_two; 17695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(origin_one.InitializeAndWaitUntilReady()); 17705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(origin_two.InitializeAndWaitUntilReady()); 17715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 17725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // The download-attribute.html page contains an anchor element whose href is 17735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // set to the value of the query parameter (specified as |target| in the URL 17745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // below). The suggested filename for the anchor is 'suggested-filename'. When 17755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // the page is loaded, a script simulates a click on the anchor, triggering a 17765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // download of the target URL. 17775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // 17785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // We construct two test servers; origin_one and origin_two. Once started, the 17795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // server URLs will differ by the port number. Therefore they will be in 17805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // different origins. 17815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu GURL download_url = origin_one.GetURL("/ping"); 17825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu GURL referrer_url = origin_one.GetURL( 17835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::string("/download-attribute.html?target=") + download_url.spec()); 17845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu origin_one.ServeFilesFromDirectory(GetTestFilePath("download", "")); 17855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 17865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // <origin_one>/download-attribute.html initiates a download of 17875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // <origin_one>/ping, which redirects to <origin_two>/pong, and then finally 17885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // to <origin_one>/download. 17895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu origin_one.RegisterRequestHandler( 17905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CreateRedirectHandler("/ping", origin_two.GetURL("/pong"))); 17915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu origin_two.RegisterRequestHandler( 17925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CreateRedirectHandler("/pong", origin_one.GetURL("/download"))); 17935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu origin_one.RegisterRequestHandler(CreateBasicResponseHandler( 17945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu "/download", "application/octet-stream", "Hello")); 17955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 17965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NavigateToURLAndWaitForDownload( 17975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu shell(), referrer_url, DownloadItem::COMPLETE); 17985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 17995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::vector<DownloadItem*> downloads; 18005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DownloadManagerForShell(shell())->GetAllDownloads(&downloads); 18015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_EQ(1u, downloads.size()); 18025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 18035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(FILE_PATH_LITERAL("suggested-filename"), 18045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu downloads[0]->GetTargetFilePath().BaseName().value()); 18055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(origin_one.ShutdownAndWaitUntilComplete()); 18065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(origin_two.ShutdownAndWaitUntilComplete()); 18075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 18085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1809cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// The file empty.bin is served with a MIME type of application/octet-stream. 1810cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// The content body is empty. Make sure this case is handled properly and we 1811cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// don't regress on http://crbug.com/320394. 1812cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadGZipWithNoContent) { 1813cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EmbeddedTestServer test_server; 1814cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ASSERT_TRUE(test_server.InitializeAndWaitUntilReady()); 1815cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1816cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GURL url = test_server.GetURL("/empty.bin"); 1817cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) test_server.ServeFilesFromDirectory(GetTestFilePath("download", "")); 1818cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1819cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NavigateToURLAndWaitForDownload(shell(), url, DownloadItem::COMPLETE); 1820cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // That's it. This should work without crashing. 1821cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 1822cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 1824