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

Side by Side Diff: content/public/test/test_file_error_injector.cc

Issue 10950015: Shift "commit point" for when a download will no longer accept cancels. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Incorporated comments. Created 8 years, 3 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 "content/public/test/test_file_error_injector.h" 5 #include "content/public/test/test_file_error_injector.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 virtual void Rename(const FilePath& full_path, 58 virtual void Rename(const FilePath& full_path,
59 bool overwrite_existing_file, 59 bool overwrite_existing_file,
60 const RenameCompletionCallback& callback) OVERRIDE; 60 const RenameCompletionCallback& callback) OVERRIDE;
61 61
62 private: 62 private:
63 // Error generating helper. 63 // Error generating helper.
64 content::DownloadInterruptReason ShouldReturnError( 64 content::DownloadInterruptReason ShouldReturnError(
65 content::TestFileErrorInjector::FileOperationCode code, 65 content::TestFileErrorInjector::FileOperationCode code,
66 content::DownloadInterruptReason original_error); 66 content::DownloadInterruptReason original_error);
67 67
68 // Used in place of original rename callback to intercept with 68 // Determine whether to overwrite an operation with the given code
69 // ShouldReturnError. 69 // with a substitute error; if returns true, |*original_error| is
70 void RenameErrorCallback( 70 // written with the error to use for overwriting.
71 const RenameCompletionCallback& original_callback, 71 // NOTE: This routine changes state; specifically, it increases the
72 content::DownloadInterruptReason original_error, 72 // operations counts for the specified code. It should only be called
73 const FilePath& path_result); 73 // once per operation.
74 bool OverwriteError(
75 content::TestFileErrorInjector::FileOperationCode code,
76 content::DownloadInterruptReason* output_error);
74 77
75 // Source URL for the file being downloaded. 78 // Source URL for the file being downloaded.
76 GURL source_url_; 79 GURL source_url_;
77 80
78 // Our injected error. Only one per file. 81 // Our injected error. Only one per file.
79 content::TestFileErrorInjector::FileErrorInfo error_info_; 82 content::TestFileErrorInjector::FileErrorInfo error_info_;
80 83
81 // Count per operation. 0-based. 84 // Count per operation. 0-based.
82 std::map<content::TestFileErrorInjector::FileOperationCode, int> 85 std::map<content::TestFileErrorInjector::FileOperationCode, int>
83 operation_counter_; 86 operation_counter_;
84 87
85 // Callback for destruction. 88 // Callback for destruction.
86 DestructionCallback destruction_callback_; 89 DestructionCallback destruction_callback_;
87 }; 90 };
88 91
92 static void RenameErrorCallback(
93 const content::DownloadFile::RenameCompletionCallback original_callback,
94 content::DownloadInterruptReason overwrite_error,
95 content::DownloadInterruptReason original_error,
96 const FilePath& path_result) {
97 original_callback.Run(
98 overwrite_error,
99 overwrite_error == content::DOWNLOAD_INTERRUPT_REASON_NONE ?
100 path_result : FilePath());
101 }
102
103
89 DownloadFileWithErrors::DownloadFileWithErrors( 104 DownloadFileWithErrors::DownloadFileWithErrors(
90 const DownloadCreateInfo* info, 105 const DownloadCreateInfo* info,
91 scoped_ptr<content::ByteStreamReader> stream, 106 scoped_ptr<content::ByteStreamReader> stream,
92 DownloadRequestHandleInterface* request_handle, 107 DownloadRequestHandleInterface* request_handle,
93 content::DownloadManager* download_manager, 108 content::DownloadManager* download_manager,
94 bool calculate_hash, 109 bool calculate_hash,
95 const net::BoundNetLog& bound_net_log, 110 const net::BoundNetLog& bound_net_log,
96 const content::TestFileErrorInjector::FileErrorInfo& error_info, 111 const content::TestFileErrorInjector::FileErrorInfo& error_info,
97 const ConstructionCallback& ctor_callback, 112 const ConstructionCallback& ctor_callback,
98 const DestructionCallback& dtor_callback) 113 const DestructionCallback& dtor_callback)
99 : DownloadFileImpl(info, 114 : DownloadFileImpl(info,
100 stream.Pass(), 115 stream.Pass(),
101 request_handle, 116 request_handle,
102 download_manager, 117 download_manager,
103 calculate_hash, 118 calculate_hash,
104 scoped_ptr<content::PowerSaveBlocker>(NULL).Pass(), 119 scoped_ptr<content::PowerSaveBlocker>(NULL).Pass(),
105 bound_net_log), 120 bound_net_log),
106 source_url_(info->url()), 121 source_url_(info->url()),
107 error_info_(error_info), 122 error_info_(error_info),
108 destruction_callback_(dtor_callback) { 123 destruction_callback_(dtor_callback) {
109 ctor_callback.Run(source_url_, info->download_id); 124 ctor_callback.Run(source_url_, info->download_id);
110 } 125 }
111 126
112 DownloadFileWithErrors::~DownloadFileWithErrors() { 127 DownloadFileWithErrors::~DownloadFileWithErrors() {
113 destruction_callback_.Run(source_url_); 128 destruction_callback_.Run(source_url_);
114 } 129 }
115 130
116 content::DownloadInterruptReason DownloadFileWithErrors::Initialize() { 131 content::DownloadInterruptReason DownloadFileWithErrors::Initialize() {
117 return ShouldReturnError( 132 return ShouldReturnError(
118 content::TestFileErrorInjector::FILE_OPERATION_INITIALIZE, 133 content::TestFileErrorInjector::FILE_OPERATION_INITIALIZE,
119 DownloadFileImpl::Initialize()); 134 DownloadFileImpl::Initialize());
120 } 135 }
121 136
122 content::DownloadInterruptReason DownloadFileWithErrors::AppendDataToFile( 137 content::DownloadInterruptReason DownloadFileWithErrors::AppendDataToFile(
123 const char* data, size_t data_len) { 138 const char* data, size_t data_len) {
124 return ShouldReturnError( 139 return ShouldReturnError(
125 content::TestFileErrorInjector::FILE_OPERATION_WRITE, 140 content::TestFileErrorInjector::FILE_OPERATION_WRITE,
126 DownloadFileImpl::AppendDataToFile(data, data_len)); 141 DownloadFileImpl::AppendDataToFile(data, data_len));
127 } 142 }
128 143
129 void DownloadFileWithErrors::Rename( 144 void DownloadFileWithErrors::Rename(
130 const FilePath& full_path, 145 const FilePath& full_path,
131 bool overwrite_existing_file, 146 bool overwrite_existing_file,
132 const RenameCompletionCallback& callback) { 147 const RenameCompletionCallback& callback) {
133 DownloadFileImpl::Rename( 148 content::DownloadInterruptReason error_to_return =
134 full_path, overwrite_existing_file, 149 content::DOWNLOAD_INTERRUPT_REASON_NONE;
135 base::Bind(&DownloadFileWithErrors::RenameErrorCallback, 150 RenameCompletionCallback callback_to_use = callback;
136 // Unretained since this'll only be called from 151
137 // the DownloadFileImpl slice of the same object. 152 // Replace callback if the error needs to be overwritten.
138 base::Unretained(this), callback)); 153 if (OverwriteError(
154 content::TestFileErrorInjector::FILE_OPERATION_RENAME,
155 &error_to_return)) {
156 callback_to_use = base::Bind(&RenameErrorCallback, callback,
157 error_to_return);
158 }
159
160 DownloadFileImpl::Rename(full_path, overwrite_existing_file, callback_to_use);
161 }
162
163 bool DownloadFileWithErrors::OverwriteError(
164 content::TestFileErrorInjector::FileOperationCode code,
165 content::DownloadInterruptReason* output_error) {
166 int counter = operation_counter_[code]++;
167
168 if (code != error_info_.code)
169 return false;
170
171 if (counter != error_info_.operation_instance)
172 return false;
173
174 *output_error = error_info_.error;
175 return true;
139 } 176 }
140 177
141 content::DownloadInterruptReason DownloadFileWithErrors::ShouldReturnError( 178 content::DownloadInterruptReason DownloadFileWithErrors::ShouldReturnError(
142 content::TestFileErrorInjector::FileOperationCode code, 179 content::TestFileErrorInjector::FileOperationCode code,
143 content::DownloadInterruptReason original_error) { 180 content::DownloadInterruptReason original_error) {
144 int counter = operation_counter_[code]; 181 content::DownloadInterruptReason output_error = original_error;
145 ++operation_counter_[code]; 182 OverwriteError(code, &output_error);
146 183 return output_error;
147 if (code != error_info_.code)
148 return original_error;
149
150 if (counter != error_info_.operation_instance)
151 return original_error;
152
153 VLOG(1) << " " << __FUNCTION__ << "()"
154 << " url = '" << source_url_.spec() << "'"
155 << " code = " << content::TestFileErrorInjector::DebugString(code)
156 << " (" << code << ")"
157 << " counter = " << counter
158 << " original_error = "
159 << content::InterruptReasonDebugString(original_error)
160 << " (" << original_error << ")"
161 << " new error = "
162 << content::InterruptReasonDebugString(error_info_.error)
163 << " (" << error_info_.error << ")";
164
165 return error_info_.error;
166 }
167
168 void DownloadFileWithErrors::RenameErrorCallback(
169 const RenameCompletionCallback& original_callback,
170 content::DownloadInterruptReason original_error,
171 const FilePath& path_result) {
172 original_callback.Run(ShouldReturnError(
173 content::TestFileErrorInjector::FILE_OPERATION_RENAME,
174 original_error), path_result);
175 } 184 }
176 185
177 } // namespace 186 } // namespace
178 187
179 namespace content { 188 namespace content {
180 189
181 // A factory for constructing DownloadFiles that inject errors. 190 // A factory for constructing DownloadFiles that inject errors.
182 class DownloadFileWithErrorsFactory 191 class DownloadFileWithErrorsFactory : public content::DownloadFileFactory {
183 : public DownloadFileManager::DownloadFileFactory {
184 public: 192 public:
185 193
186 DownloadFileWithErrorsFactory( 194 DownloadFileWithErrorsFactory(
187 const DownloadFileWithErrors::ConstructionCallback& ctor_callback, 195 const DownloadFileWithErrors::ConstructionCallback& ctor_callback,
188 const DownloadFileWithErrors::DestructionCallback& dtor_callback); 196 const DownloadFileWithErrors::DestructionCallback& dtor_callback);
189 virtual ~DownloadFileWithErrorsFactory(); 197 virtual ~DownloadFileWithErrorsFactory();
190 198
191 // DownloadFileFactory interface. 199 // DownloadFileFactory interface.
192 virtual DownloadFile* CreateFile( 200 virtual DownloadFile* CreateFile(
193 DownloadCreateInfo* info, 201 DownloadCreateInfo* info,
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 } 299 }
292 300
293 void TestFileErrorInjector::AddFactory( 301 void TestFileErrorInjector::AddFactory(
294 scoped_ptr<DownloadFileWithErrorsFactory> factory) { 302 scoped_ptr<DownloadFileWithErrorsFactory> factory) {
295 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 303 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
296 304
297 DownloadFileManager* download_file_manager = GetDownloadFileManager(); 305 DownloadFileManager* download_file_manager = GetDownloadFileManager();
298 DCHECK(download_file_manager); 306 DCHECK(download_file_manager);
299 307
300 // Convert to base class pointer, for GCC. 308 // Convert to base class pointer, for GCC.
301 scoped_ptr<DownloadFileManager::DownloadFileFactory> plain_factory( 309 scoped_ptr<content::DownloadFileFactory> plain_factory(
302 factory.release()); 310 factory.release());
303 311
304 download_file_manager->SetFileFactoryForTesting(plain_factory.Pass()); 312 download_file_manager->SetFileFactoryForTesting(plain_factory.Pass());
305 } 313 }
306 314
307 bool TestFileErrorInjector::AddError(const FileErrorInfo& error_info) { 315 bool TestFileErrorInjector::AddError(const FileErrorInfo& error_info) {
308 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 316 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
309 DCHECK_LE(0, error_info.operation_instance); 317 DCHECK_LE(0, error_info.operation_instance);
310 DCHECK(injected_errors_.find(error_info.url) == injected_errors_.end()); 318 DCHECK(injected_errors_.find(error_info.url) == injected_errors_.end());
311 319
(...skipping 25 matching lines...) Expand all
337 } 345 }
338 346
339 void TestFileErrorInjector::InjectErrorsOnFileThread( 347 void TestFileErrorInjector::InjectErrorsOnFileThread(
340 ErrorMap map, DownloadFileWithErrorsFactory* factory) { 348 ErrorMap map, DownloadFileWithErrorsFactory* factory) {
341 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 349 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
342 350
343 // Validate that our factory is in use. 351 // Validate that our factory is in use.
344 DownloadFileManager* download_file_manager = GetDownloadFileManager(); 352 DownloadFileManager* download_file_manager = GetDownloadFileManager();
345 DCHECK(download_file_manager); 353 DCHECK(download_file_manager);
346 354
347 DownloadFileManager::DownloadFileFactory* file_factory = 355 content::DownloadFileFactory* file_factory =
348 download_file_manager->GetFileFactoryForTesting(); 356 download_file_manager->GetFileFactoryForTesting();
349 357
350 // Validate that we still have the same factory. 358 // Validate that we still have the same factory.
351 DCHECK_EQ(static_cast<DownloadFileManager::DownloadFileFactory*>(factory), 359 DCHECK_EQ(static_cast<content::DownloadFileFactory*>(factory),
352 file_factory); 360 file_factory);
353 361
354 // We want to replace all existing injection errors. 362 // We want to replace all existing injection errors.
355 factory->ClearErrors(); 363 factory->ClearErrors();
356 364
357 for (ErrorMap::const_iterator it = map.begin(); it != map.end(); ++it) 365 for (ErrorMap::const_iterator it = map.begin(); it != map.end(); ++it)
358 factory->AddError(it->second); 366 factory->AddError(it->second);
359 } 367 }
360 368
361 size_t TestFileErrorInjector::CurrentFileCount() const { 369 size_t TestFileErrorInjector::CurrentFileCount() const {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 case FILE_OPERATION_RENAME: 456 case FILE_OPERATION_RENAME:
449 return "RENAME"; 457 return "RENAME";
450 default: 458 default:
451 break; 459 break;
452 } 460 }
453 461
454 return "Unknown"; 462 return "Unknown";
455 } 463 }
456 464
457 } // namespace content 465 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698