Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: chrome/browser/download/download_browsertest.cc

Issue 17315009: [Downloads] Add more browsertests for resumption. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | content/browser/download/download_browsertest.cc » ('j') | content/browser/download/download_item_impl.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698