OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <sstream> | 5 #include <sstream> |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/command_line.h" | |
9 #include "base/file_util.h" | 10 #include "base/file_util.h" |
10 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
11 #include "base/files/scoped_temp_dir.h" | 12 #include "base/files/scoped_temp_dir.h" |
12 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
13 #include "base/path_service.h" | 14 #include "base/path_service.h" |
14 #include "base/prefs/pref_service.h" | 15 #include "base/prefs/pref_service.h" |
15 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
16 #include "base/strings/string_split.h" | 17 #include "base/strings/string_split.h" |
17 #include "base/strings/stringprintf.h" | 18 #include "base/strings/stringprintf.h" |
18 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
61 #include "chrome/test/base/ui_test_utils.h" | 62 #include "chrome/test/base/ui_test_utils.h" |
62 #include "content/public/browser/download_item.h" | 63 #include "content/public/browser/download_item.h" |
63 #include "content/public/browser/download_manager.h" | 64 #include "content/public/browser/download_manager.h" |
64 #include "content/public/browser/download_save_info.h" | 65 #include "content/public/browser/download_save_info.h" |
65 #include "content/public/browser/download_url_parameters.h" | 66 #include "content/public/browser/download_url_parameters.h" |
66 #include "content/public/browser/notification_source.h" | 67 #include "content/public/browser/notification_source.h" |
67 #include "content/public/browser/plugin_service.h" | 68 #include "content/public/browser/plugin_service.h" |
68 #include "content/public/browser/render_view_host.h" | 69 #include "content/public/browser/render_view_host.h" |
69 #include "content/public/browser/resource_context.h" | 70 #include "content/public/browser/resource_context.h" |
70 #include "content/public/browser/web_contents.h" | 71 #include "content/public/browser/web_contents.h" |
72 #include "content/public/common/content_switches.h" | |
71 #include "content/public/common/context_menu_params.h" | 73 #include "content/public/common/context_menu_params.h" |
72 #include "content/public/common/page_transition_types.h" | 74 #include "content/public/common/page_transition_types.h" |
73 #include "content/public/test/browser_test_utils.h" | 75 #include "content/public/test/browser_test_utils.h" |
74 #include "content/public/test/download_test_observer.h" | 76 #include "content/public/test/download_test_observer.h" |
75 #include "content/public/test/test_file_error_injector.h" | 77 #include "content/public/test/test_file_error_injector.h" |
76 #include "content/public/test/test_navigation_observer.h" | 78 #include "content/public/test/test_navigation_observer.h" |
77 #include "content/test/net/url_request_mock_http_job.h" | 79 #include "content/test/net/url_request_mock_http_job.h" |
78 #include "content/test/net/url_request_slow_download_job.h" | 80 #include "content/test/net/url_request_slow_download_job.h" |
79 #include "grit/generated_resources.h" | 81 #include "grit/generated_resources.h" |
80 #include "net/base/net_util.h" | 82 #include "net/base/net_util.h" |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
178 } | 180 } |
179 | 181 |
180 content::DownloadItem* item_; | 182 content::DownloadItem* item_; |
181 bool waiting_; | 183 bool waiting_; |
182 bool error_; | 184 bool error_; |
183 int prev_percent_; | 185 int prev_percent_; |
184 | 186 |
185 DISALLOW_COPY_AND_ASSIGN(PercentWaiter); | 187 DISALLOW_COPY_AND_ASSIGN(PercentWaiter); |
186 }; | 188 }; |
187 | 189 |
190 // DownloadTestObserver subclass that observes one download until it transitions | |
191 // from a non-resumable state to a resumable state a specified number of | |
192 // times. Note that this observer can only observe a single download. | |
193 class DownloadTestObserverResumable : public content::DownloadTestObserver { | |
194 public: | |
195 // Construct a new observer. |transition_count| is the number of times the | |
196 // download should transition from a non-resumable state to a resumable state. | |
197 DownloadTestObserverResumable(DownloadManager* download_manager, | |
198 size_t transition_count) | |
199 : DownloadTestObserver(download_manager, 1, | |
200 ON_DANGEROUS_DOWNLOAD_FAIL), | |
201 was_previously_resumable_(false), | |
202 transitions_left_(transition_count) { | |
203 Init(); | |
204 } | |
205 virtual ~DownloadTestObserverResumable() {} | |
206 | |
207 private: | |
208 virtual bool IsDownloadInFinalState(DownloadItem* download) OVERRIDE { | |
209 bool is_resumable_now = download->CanResume(); | |
210 if (!was_previously_resumable_ && is_resumable_now) | |
211 --transitions_left_; | |
212 was_previously_resumable_ = is_resumable_now; | |
213 return transitions_left_ == 0; | |
214 } | |
215 | |
216 bool was_previously_resumable_; | |
217 size_t transitions_left_; | |
218 | |
219 DISALLOW_COPY_AND_ASSIGN(DownloadTestObserverResumable); | |
220 }; | |
221 | |
188 // IDs and paths of CRX files used in tests. | 222 // IDs and paths of CRX files used in tests. |
189 const char kGoodCrxId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; | 223 const char kGoodCrxId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; |
190 const base::FilePath kGoodCrxPath(FILE_PATH_LITERAL("extensions/good.crx")); | 224 const base::FilePath kGoodCrxPath(FILE_PATH_LITERAL("extensions/good.crx")); |
191 | 225 |
192 const char kLargeThemeCrxId[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf"; | 226 const char kLargeThemeCrxId[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf"; |
193 const base::FilePath kLargeThemePath( | 227 const base::FilePath kLargeThemePath( |
194 FILE_PATH_LITERAL("extensions/theme2.crx")); | 228 FILE_PATH_LITERAL("extensions/theme2.crx")); |
195 | 229 |
196 // Get History Information. | 230 // Get History Information. |
197 class DownloadsHistoryDataCollector { | 231 class DownloadsHistoryDataCollector { |
(...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
998 } | 1032 } |
999 } | 1033 } |
1000 | 1034 |
1001 // A mock install prompt that simulates the user allowing an install request. | 1035 // A mock install prompt that simulates the user allowing an install request. |
1002 void SetAllowMockInstallPrompt() { | 1036 void SetAllowMockInstallPrompt() { |
1003 download_crx_util::SetMockInstallPromptForTesting( | 1037 download_crx_util::SetMockInstallPromptForTesting( |
1004 new MockAutoConfirmExtensionInstallPrompt( | 1038 new MockAutoConfirmExtensionInstallPrompt( |
1005 browser()->tab_strip_model()->GetActiveWebContents())); | 1039 browser()->tab_strip_model()->GetActiveWebContents())); |
1006 } | 1040 } |
1007 | 1041 |
1042 // This method: | |
1043 // * Starts a mock download by navigating browser() to a URLRequestMockHTTPJob | |
1044 // mock URL. | |
1045 // * Injects |error| on the first write using |error_injector|. | |
1046 // * Waits for the download to be interrupted. | |
1047 // * Clears the errors on |error_injector|. | |
1048 // * Returns the resulting interrupted download. | |
1049 DownloadItem* StartMockDownloadAndInjectError( | |
1050 content::TestFileErrorInjector* error_injector, | |
1051 content::DownloadInterruptReason error) { | |
1052 base::FilePath file_path(FILE_PATH_LITERAL("download-test1.lib")); | |
1053 GURL url = URLRequestMockHTTPJob::GetMockUrl(file_path); | |
1054 | |
1055 content::TestFileErrorInjector::FileErrorInfo error_info; | |
1056 error_info.url = url.spec(); | |
1057 error_info.code = content::TestFileErrorInjector::FILE_OPERATION_WRITE; | |
1058 error_info.operation_instance = 0; | |
1059 error_info.error = error; | |
1060 error_injector->ClearErrors(); | |
1061 error_injector->AddError(error_info); | |
1062 error_injector->InjectErrors(); | |
1063 | |
1064 scoped_ptr<content::DownloadTestObserver> observer( | |
1065 new DownloadTestObserverResumable( | |
1066 DownloadManagerForBrowser(browser()), 1)); | |
1067 ui_test_utils::NavigateToURL(browser(), url); | |
1068 observer->WaitForFinished(); | |
1069 | |
1070 content::DownloadManager::DownloadVector downloads; | |
1071 DownloadManagerForBrowser(browser())->GetAllDownloads(&downloads); | |
1072 EXPECT_EQ(1u, downloads.size()); | |
1073 | |
1074 if (downloads.size() != 1) | |
1075 return NULL; | |
1076 | |
1077 error_injector->ClearErrors(); | |
1078 error_injector->InjectErrors(); | |
1079 DownloadItem* download = downloads[0]; | |
1080 EXPECT_EQ(DownloadItem::INTERRUPTED, download->GetState()); | |
1081 EXPECT_EQ(error, download->GetLastReason()); | |
1082 return download; | |
1083 } | |
1084 | |
1008 private: | 1085 private: |
1009 static void EnsureNoPendingDownloadJobsOnIO(bool* result) { | 1086 static void EnsureNoPendingDownloadJobsOnIO(bool* result) { |
1010 if (URLRequestSlowDownloadJob::NumberOutstandingRequests()) | 1087 if (URLRequestSlowDownloadJob::NumberOutstandingRequests()) |
1011 *result = false; | 1088 *result = false; |
1012 BrowserThread::PostTask( | 1089 BrowserThread::PostTask( |
1013 BrowserThread::UI, FROM_HERE, base::MessageLoop::QuitClosure()); | 1090 BrowserThread::UI, FROM_HERE, base::MessageLoop::QuitClosure()); |
1014 } | 1091 } |
1015 | 1092 |
1016 // Location of the test data. | 1093 // Location of the test data. |
1017 base::FilePath test_dir_; | 1094 base::FilePath test_dir_; |
(...skipping 1946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2964 EXPECT_EQ(dir.value(), off_prefs->SaveFilePath().value()); | 3041 EXPECT_EQ(dir.value(), off_prefs->SaveFilePath().value()); |
2965 | 3042 |
2966 off_prefs->SetSaveFilePath(dir.AppendASCII("off")); | 3043 off_prefs->SetSaveFilePath(dir.AppendASCII("off")); |
2967 EXPECT_EQ(dir.value(), on_prefs->SaveFilePath().value()); | 3044 EXPECT_EQ(dir.value(), on_prefs->SaveFilePath().value()); |
2968 EXPECT_EQ(dir.AppendASCII("off").value(), off_prefs->SaveFilePath().value()); | 3045 EXPECT_EQ(dir.AppendASCII("off").value(), off_prefs->SaveFilePath().value()); |
2969 | 3046 |
2970 on_prefs->SetSaveFilePath(dir.AppendASCII("on")); | 3047 on_prefs->SetSaveFilePath(dir.AppendASCII("on")); |
2971 EXPECT_EQ(dir.AppendASCII("on").value(), on_prefs->SaveFilePath().value()); | 3048 EXPECT_EQ(dir.AppendASCII("on").value(), on_prefs->SaveFilePath().value()); |
2972 EXPECT_EQ(dir.AppendASCII("off").value(), off_prefs->SaveFilePath().value()); | 3049 EXPECT_EQ(dir.AppendASCII("off").value(), off_prefs->SaveFilePath().value()); |
2973 } | 3050 } |
3051 | |
3052 // A download that is interrupted due to a file error should be able to be | |
3053 // resumed. | |
3054 IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_NoPrompt) { | |
3055 CommandLine::ForCurrentProcess()->AppendSwitch( | |
3056 switches::kEnableDownloadResumption); | |
3057 scoped_refptr<content::TestFileErrorInjector> error_injector( | |
3058 content::TestFileErrorInjector::Create( | |
3059 DownloadManagerForBrowser(browser()))); | |
3060 scoped_ptr<content::DownloadTestObserver> completion_observer( | |
3061 CreateWaiter(browser(), 1)); | |
3062 EnableFileChooser(true); | |
3063 | |
3064 DownloadItem* download = StartMockDownloadAndInjectError( | |
3065 error_injector, | |
3066 content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); | |
3067 ASSERT_TRUE(download); | |
3068 | |
3069 download->Resume(); | |
3070 completion_observer->WaitForFinished(); | |
3071 | |
3072 EXPECT_EQ( | |
3073 1u, completion_observer->NumDownloadsSeenInState(DownloadItem::COMPLETE)); | |
3074 EXPECT_FALSE(DidShowFileChooser()); | |
3075 } | |
3076 | |
3077 // A download that's interrupted due to a reason that indicates that the target | |
3078 // path is invalid or unusable should cause a prompt to be displayed on | |
3079 // resumption. | |
3080 IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_WithPrompt) { | |
3081 CommandLine::ForCurrentProcess()->AppendSwitch( | |
3082 switches::kEnableDownloadResumption); | |
3083 scoped_refptr<content::TestFileErrorInjector> error_injector( | |
3084 content::TestFileErrorInjector::Create( | |
3085 DownloadManagerForBrowser(browser()))); | |
3086 scoped_ptr<content::DownloadTestObserver> completion_observer( | |
3087 CreateWaiter(browser(), 1)); | |
3088 EnableFileChooser(true); | |
3089 | |
3090 DownloadItem* download = StartMockDownloadAndInjectError( | |
3091 error_injector, | |
3092 content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE); | |
3093 ASSERT_TRUE(download); | |
3094 | |
3095 download->Resume(); | |
3096 completion_observer->WaitForFinished(); | |
3097 | |
3098 EXPECT_EQ( | |
3099 1u, completion_observer->NumDownloadsSeenInState(DownloadItem::COMPLETE)); | |
3100 EXPECT_TRUE(DidShowFileChooser()); | |
3101 } | |
3102 | |
3103 // A download that's interrupted due to a reason that indicates that the target | |
3104 // path is invalid or unusable should cause a prompt to be displayed on | |
3105 // resumption. | |
Randy Smith (Not in Mondays)
2013/06/19 21:46:21
nit: Description doesn't differentiate from previo
asanka
2013/06/20 20:04:01
Done.
| |
3106 IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_WithPromptAlways) { | |
3107 CommandLine::ForCurrentProcess()->AppendSwitch( | |
3108 switches::kEnableDownloadResumption); | |
3109 browser()->profile()->GetPrefs()->SetBoolean( | |
3110 prefs::kPromptForDownload, true); | |
3111 scoped_refptr<content::TestFileErrorInjector> error_injector( | |
3112 content::TestFileErrorInjector::Create( | |
3113 DownloadManagerForBrowser(browser()))); | |
3114 scoped_ptr<content::DownloadTestObserver> completion_observer( | |
3115 CreateWaiter(browser(), 1)); | |
3116 EnableFileChooser(true); | |
3117 | |
3118 DownloadItem* download = StartMockDownloadAndInjectError( | |
3119 error_injector, | |
3120 content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); | |
3121 ASSERT_TRUE(download); | |
3122 | |
3123 // Prompts the user initially because of the kPromptForDownload preference. | |
3124 EXPECT_TRUE(DidShowFileChooser()); | |
3125 | |
3126 download->Resume(); | |
3127 completion_observer->WaitForFinished(); | |
3128 | |
3129 EXPECT_EQ( | |
3130 1u, completion_observer->NumDownloadsSeenInState(DownloadItem::COMPLETE)); | |
3131 // Shouldn't prompt for resumption. | |
3132 EXPECT_FALSE(DidShowFileChooser()); | |
3133 } | |
3134 | |
3135 // A download that is interrupted due to a transient error should be resumed | |
3136 // automatically. | |
3137 IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_Automatic) { | |
3138 CommandLine::ForCurrentProcess()->AppendSwitch( | |
3139 switches::kEnableDownloadResumption); | |
3140 scoped_refptr<content::TestFileErrorInjector> error_injector( | |
3141 content::TestFileErrorInjector::Create( | |
3142 DownloadManagerForBrowser(browser()))); | |
3143 | |
3144 DownloadItem* download = StartMockDownloadAndInjectError( | |
3145 error_injector, | |
3146 content::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); | |
3147 ASSERT_TRUE(download); | |
3148 | |
3149 // The number of times this the download is resumed automatically is defined | |
3150 // in DownloadItemImpl::kMaxAutoResumeAttempts. The number of DownloadFiles | |
3151 // created should be that number + 1 (for the original download request). We | |
3152 // only care that it is greater than 1. | |
3153 EXPECT_GT(1u, error_injector->TotalFileCount()); | |
3154 } | |
3155 | |
3156 // An interrupting download should be resumable multiple times. | |
3157 IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_MultipleAttempts) { | |
3158 CommandLine::ForCurrentProcess()->AppendSwitch( | |
3159 switches::kEnableDownloadResumption); | |
3160 scoped_refptr<content::TestFileErrorInjector> error_injector( | |
3161 content::TestFileErrorInjector::Create( | |
3162 DownloadManagerForBrowser(browser()))); | |
3163 scoped_ptr<content::DownloadTestObserver> completion_observer( | |
3164 CreateWaiter(browser(), 1)); | |
3165 // Wait for two transitions to a resumable state | |
3166 scoped_ptr<content::DownloadTestObserver> resumable_observer( | |
3167 new DownloadTestObserverResumable( | |
3168 DownloadManagerForBrowser(browser()), 2)); | |
3169 | |
3170 EnableFileChooser(true); | |
3171 DownloadItem* download = StartMockDownloadAndInjectError( | |
3172 error_injector, | |
3173 content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); | |
3174 ASSERT_TRUE(download); | |
3175 | |
3176 content::TestFileErrorInjector::FileErrorInfo error_info; | |
3177 error_info.url = download->GetOriginalUrl().spec(); | |
3178 error_info.code = content::TestFileErrorInjector::FILE_OPERATION_WRITE; | |
3179 error_info.operation_instance = 0; | |
3180 error_info.error = content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED; | |
3181 error_injector->AddError(error_info); | |
3182 error_injector->InjectErrors(); | |
3183 | |
3184 // Resuming should cause the download to be interrupted again due to the | |
3185 // errors we are injecting. | |
3186 download->Resume(); | |
3187 resumable_observer->WaitForFinished(); | |
3188 ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState()); | |
3189 ASSERT_EQ(content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, | |
3190 download->GetLastReason()); | |
3191 | |
3192 error_injector->ClearErrors(); | |
3193 error_injector->InjectErrors(); | |
3194 | |
3195 // No errors this time. The download should complete successfully. | |
3196 download->Resume(); | |
3197 completion_observer->WaitForFinished(); | |
Randy Smith (Not in Mondays)
2013/06/19 21:46:21
nit: I'd rather have this wait for a transition ou
asanka
2013/06/20 20:04:01
Done.
| |
3198 | |
3199 EXPECT_FALSE(DidShowFileChooser()); | |
3200 } | |
OLD | NEW |