Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
|
jam
2012/08/27 17:14:49
nit: files in content don't have "content" in thei
Randy Smith (Not in Mondays)
2012/08/28 21:09:15
Done.
| |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // This file contains download browser tests that are known to be runnable | |
| 6 // in a pure content context. Over time tests should be migrated here. | |
| 7 | |
| 8 #include "base/file_path.h" | |
| 9 #include "base/file_util.h" | |
| 10 #include "base/scoped_temp_dir.h" | |
| 11 #include "content/public/browser/browser_context.h" | |
|
jam
2012/08/27 17:14:49
nit: by convention (i.e. like webkit api), files i
Randy Smith (Not in Mondays)
2012/08/28 21:09:15
Done for everything except for download_test_obser
| |
| 12 #include "content/public/browser/download_item.h" | |
| 13 #include "content/public/browser/download_manager.h" | |
| 14 #include "content/public/browser/web_contents.h" | |
| 15 #include "content/public/test/download_test_observer.h" | |
| 16 #include "content/shell/shell.h" | |
| 17 #include "content/shell/shell_download_manager_delegate.h" | |
| 18 #include "content/test/content_browser_test.h" | |
| 19 #include "content/test/content_browser_test_utils.h" | |
| 20 #include "content/test/net/url_request_mock_http_job.h" | |
| 21 #include "content/test/net/url_request_slow_download_job.h" | |
| 22 #include "googleurl/src/gurl.h" | |
| 23 | |
| 24 namespace content { | |
| 25 | |
| 26 namespace { | |
| 27 | |
| 28 static DownloadManager* DownloadManagerForShell(Shell* shell) { | |
| 29 return BrowserContext::GetDownloadManager( | |
| 30 shell->web_contents()->GetBrowserContext()); | |
| 31 } | |
| 32 | |
| 33 } // namespace | |
| 34 | |
| 35 class DownloadContentTest : public ContentBrowserTest { | |
| 36 protected: | |
| 37 virtual void SetUpOnMainThread() OVERRIDE { | |
| 38 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); | |
| 39 | |
| 40 ShellDownloadManagerDelegate* delegate = | |
| 41 static_cast<ShellDownloadManagerDelegate*>( | |
|
jam
2012/08/27 17:14:49
nit: indent
Randy Smith (Not in Mondays)
2012/08/28 21:09:15
Done.
| |
| 42 shell()->web_contents()->GetBrowserContext() | |
| 43 ->GetDownloadManagerDelegate()); | |
| 44 delegate->SetDownloadBehaviorForTesting(downloads_directory_.path()); | |
| 45 | |
| 46 BrowserThread::PostTask( | |
| 47 BrowserThread::IO, FROM_HERE, | |
| 48 base::Bind(&URLRequestSlowDownloadJob::AddUrlHandler)); | |
| 49 FilePath mock_base(GetTestFilePath("download", "")); | |
| 50 BrowserThread::PostTask( | |
| 51 BrowserThread::IO, FROM_HERE, | |
| 52 base::Bind(&URLRequestMockHTTPJob::AddUrlHandler, mock_base)); | |
| 53 } | |
| 54 | |
| 55 // Create a DownloadTestObserverTerminal that will wait for the | |
| 56 // specified number of downloads to finish. | |
| 57 content::DownloadTestObserver* CreateWaiter( | |
|
jam
2012/08/27 17:14:49
nit: here and below, get rid of "content::"
Randy Smith (Not in Mondays)
2012/08/28 21:09:15
Done.
| |
| 58 Shell* shell, int num_downloads) { | |
| 59 DownloadManager* download_manager = DownloadManagerForShell(shell); | |
| 60 return new content::DownloadTestObserverTerminal( | |
| 61 download_manager, num_downloads, | |
| 62 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); | |
| 63 } | |
| 64 | |
| 65 // Create a DownloadTestObserverInProgress that will wait for the | |
| 66 // specified number of downloads to start. | |
| 67 content::DownloadTestObserver* CreateInProgressWaiter( | |
| 68 Shell* shell, int num_downloads) { | |
| 69 DownloadManager* download_manager = DownloadManagerForShell(shell); | |
| 70 return new content::DownloadTestObserverInProgress( | |
| 71 download_manager, num_downloads); | |
| 72 } | |
| 73 | |
| 74 bool EnsureNoPendingDownloads() { | |
| 75 bool result = true; | |
| 76 BrowserThread::PostTask( | |
| 77 BrowserThread::IO, FROM_HERE, | |
| 78 base::Bind(&EnsureNoPendingDownloadJobsOnIO, &result)); | |
| 79 MessageLoop::current()->Run(); | |
| 80 return result && DownloadManager::EnsureNoPendingDownloadsForTesting(); | |
| 81 } | |
| 82 | |
| 83 void DownloadAndWait(Shell* shell, const GURL& url) { | |
| 84 scoped_ptr<content::DownloadTestObserver> observer(CreateWaiter(shell, 1)); | |
| 85 NavigateToURL(shell, url); | |
| 86 observer->WaitForFinished(); | |
| 87 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE)); | |
| 88 } | |
| 89 | |
| 90 // Checks that |path| is has |file_size| bytes, and matches the |value| | |
| 91 // string. | |
| 92 bool VerifyFile(const FilePath& path, | |
| 93 const std::string& value, | |
| 94 const int64 file_size) { | |
| 95 std::string file_contents; | |
| 96 | |
| 97 bool read = file_util::ReadFileToString(path, &file_contents); | |
| 98 EXPECT_TRUE(read) << "Failed reading file: " << path.value() << std::endl; | |
| 99 if (!read) | |
| 100 return false; // Couldn't read the file. | |
| 101 | |
| 102 // Note: we don't handle really large files (more than size_t can hold) | |
| 103 // so we will fail in that case. | |
| 104 size_t expected_size = static_cast<size_t>(file_size); | |
| 105 | |
| 106 // Check the size. | |
| 107 EXPECT_EQ(expected_size, file_contents.size()); | |
| 108 if (expected_size != file_contents.size()) | |
| 109 return false; | |
| 110 | |
| 111 // Check the contents. | |
| 112 EXPECT_EQ(value, file_contents); | |
| 113 if (memcmp(file_contents.c_str(), value.c_str(), expected_size) != 0) | |
| 114 return false; | |
| 115 | |
| 116 return true; | |
| 117 } | |
| 118 | |
| 119 private: | |
| 120 static void EnsureNoPendingDownloadJobsOnIO(bool* result) { | |
| 121 if (URLRequestSlowDownloadJob::NumberOutstandingRequests()) | |
| 122 *result = false; | |
| 123 BrowserThread::PostTask( | |
| 124 BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure()); | |
| 125 } | |
| 126 | |
| 127 // Location of the downloads directory for these tests | |
| 128 ScopedTempDir downloads_directory_; | |
| 129 }; | |
| 130 | |
| 131 IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadCancelled) { | |
| 132 // TODO(rdsmith): Fragile code warning! The code below relies on the | |
| 133 // DownloadTestObserverInProgress only finishing when the new download | |
| 134 // has reached the state of being entered into the history and being | |
| 135 // user-visible (that's what's required for the Remove to be valid and | |
| 136 // for the download shelf to be visible). By the pure semantics of | |
| 137 // DownloadTestObserverInProgress, that's not guaranteed; DownloadItems | |
| 138 // are created in the IN_PROGRESS state and made known to the DownloadManager | |
| 139 // immediately, so any ModelChanged event on the DownloadManager after | |
| 140 // navigation would allow the observer to return. However, the only | |
| 141 // ModelChanged() event the code will currently fire is in | |
| 142 // OnCreateDownloadEntryComplete, at which point the download item will | |
| 143 // be in the state we need. | |
| 144 // The right way to fix this is to create finer grained states on the | |
| 145 // DownloadItem, and wait for the state that indicates the item has been | |
| 146 // entered in the history and made visible in the UI. | |
| 147 | |
| 148 // Create a download, wait until it's started, and confirm | |
| 149 // we're in the expected state. | |
| 150 scoped_ptr<DownloadTestObserver> observer(CreateInProgressWaiter(shell(), 1)); | |
| 151 NavigateToURL(shell(), GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl)); | |
| 152 observer->WaitForFinished(); | |
| 153 | |
| 154 std::vector<DownloadItem*> downloads; | |
| 155 DownloadManagerForShell(shell())->SearchDownloads(string16(), &downloads); | |
| 156 ASSERT_EQ(1u, downloads.size()); | |
| 157 ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->GetState()); | |
| 158 | |
| 159 // Cancel the download and wait for download system quiesce. | |
| 160 downloads[0]->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); | |
| 161 scoped_refptr<DownloadTestFlushObserver> flush_observer( | |
| 162 new DownloadTestFlushObserver(DownloadManagerForShell(shell()))); | |
| 163 flush_observer->WaitForFlush(); | |
| 164 | |
| 165 // Get the important info from other threads and check it. | |
| 166 EXPECT_TRUE(EnsureNoPendingDownloads()); | |
| 167 } | |
| 168 | |
| 169 // Check that downloading multiple (in this case, 2) files does not result in | |
| 170 // corrupted files. | |
| 171 IN_PROC_BROWSER_TEST_F(DownloadContentTest, MultiDownload) { | |
| 172 // Create a download, wait until it's started, and confirm | |
| 173 // we're in the expected state. | |
| 174 scoped_ptr<DownloadTestObserver> observer1( | |
| 175 CreateInProgressWaiter(shell(), 1)); | |
| 176 NavigateToURL(shell(), GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl)); | |
| 177 observer1->WaitForFinished(); | |
| 178 | |
| 179 std::vector<DownloadItem*> downloads; | |
| 180 DownloadManagerForShell(shell())->SearchDownloads(string16(), &downloads); | |
| 181 ASSERT_EQ(1u, downloads.size()); | |
| 182 ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->GetState()); | |
| 183 DownloadItem* download1 = downloads[0]; // The only download. | |
| 184 | |
| 185 // Start the second download and wait until it's done. | |
| 186 FilePath file(FILE_PATH_LITERAL("download-test.lib")); | |
| 187 GURL url(URLRequestMockHTTPJob::GetMockUrl(file)); | |
| 188 // Download the file and wait. | |
| 189 DownloadAndWait(shell(), url); | |
| 190 | |
| 191 // Should now have 2 items on the manager. | |
| 192 downloads.clear(); | |
| 193 DownloadManagerForShell(shell())->SearchDownloads(string16(), &downloads); | |
| 194 ASSERT_EQ(2u, downloads.size()); | |
| 195 // We don't know the order of the downloads. | |
| 196 DownloadItem* download2 = downloads[(download1 == downloads[0]) ? 1 : 0]; | |
| 197 | |
| 198 ASSERT_EQ(DownloadItem::IN_PROGRESS, download1->GetState()); | |
| 199 ASSERT_EQ(DownloadItem::COMPLETE, download2->GetState()); | |
| 200 | |
| 201 // Allow the first request to finish. | |
| 202 scoped_ptr<DownloadTestObserver> observer2(CreateWaiter(shell(), 1)); | |
| 203 NavigateToURL(shell(), GURL(URLRequestSlowDownloadJob::kFinishDownloadUrl)); | |
| 204 observer2->WaitForFinished(); // Wait for the third request. | |
| 205 EXPECT_EQ(1u, observer2->NumDownloadsSeenInState(DownloadItem::COMPLETE)); | |
| 206 | |
| 207 // Get the important info from other threads and check it. | |
| 208 EXPECT_TRUE(EnsureNoPendingDownloads()); | |
| 209 | |
| 210 // The |DownloadItem|s should now be done and have the final file names. | |
| 211 // Verify that the files have the expected data and size. | |
| 212 // |file1| should be full of '*'s, and |file2| should be the same as the | |
| 213 // source file. | |
| 214 FilePath file1(download1->GetFullPath()); | |
| 215 size_t file_size1 = URLRequestSlowDownloadJob::kFirstDownloadSize + | |
| 216 URLRequestSlowDownloadJob::kSecondDownloadSize; | |
| 217 std::string expected_contents(file_size1, '*'); | |
| 218 ASSERT_TRUE(VerifyFile(file1, expected_contents, file_size1)); | |
| 219 | |
| 220 FilePath file2(download2->GetFullPath()); | |
| 221 ASSERT_TRUE(file_util::ContentsEqual( | |
| 222 file2, GetTestFilePath("download", "download-test.lib"))); | |
| 223 } | |
| 224 | |
| 225 } // namespace content | |
| OLD | NEW |