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

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

Issue 10912173: Replace the DownloadFileManager with direct ownership of DownloadFileImpl (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync to LKGR (r156083) 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"
11 #include "content/browser/download/download_create_info.h"
12 #include "content/browser/download/download_file_impl.h" 11 #include "content/browser/download/download_file_impl.h"
13 #include "content/browser/download/download_file_manager.h" 12 #include "content/browser/download/download_file_factory.h"
14 #include "content/browser/download/download_interrupt_reasons_impl.h" 13 #include "content/browser/download/download_interrupt_reasons_impl.h"
14 #include "content/browser/download/download_manager_impl.h"
15 #include "content/browser/power_save_blocker.h" 15 #include "content/browser/power_save_blocker.h"
16 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" 16 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
17 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/download_id.h"
19 #include "googleurl/src/gurl.h" 18 #include "googleurl/src/gurl.h"
20 19
21 namespace content { 20 namespace content {
22 class ByteStreamReader; 21 class ByteStreamReader;
23 } 22 }
24 23
25 namespace { 24 namespace {
26 25
27 DownloadFileManager* GetDownloadFileManager() {
28 content::ResourceDispatcherHostImpl* rdh =
29 content::ResourceDispatcherHostImpl::Get();
30 DCHECK(rdh != NULL);
31 return rdh->download_file_manager();
32 }
33
34 // A class that performs file operations and injects errors. 26 // A class that performs file operations and injects errors.
35 class DownloadFileWithErrors: public DownloadFileImpl { 27 class DownloadFileWithErrors: public DownloadFileImpl {
36 public: 28 public:
37 typedef base::Callback<void(const GURL& url, content::DownloadId id)> 29 typedef base::Callback<void(const GURL& url)> ConstructionCallback;
38 ConstructionCallback;
39 typedef base::Callback<void(const GURL& url)> DestructionCallback; 30 typedef base::Callback<void(const GURL& url)> DestructionCallback;
40 31
41 DownloadFileWithErrors( 32 DownloadFileWithErrors(
42 const DownloadCreateInfo* info, 33 const content::DownloadSaveInfo& save_info,
34 const GURL& url,
35 const GURL& referrer_url,
36 int64 received_bytes,
37 bool calculate_hash,
43 scoped_ptr<content::ByteStreamReader> stream, 38 scoped_ptr<content::ByteStreamReader> stream,
44 DownloadRequestHandleInterface* request_handle,
45 content::DownloadManager* download_manager,
46 bool calculate_hash,
47 const net::BoundNetLog& bound_net_log, 39 const net::BoundNetLog& bound_net_log,
40 scoped_ptr<content::PowerSaveBlocker> power_save_blocker,
41 base::WeakPtr<content::DownloadDestinationObserver> observer,
48 const content::TestFileErrorInjector::FileErrorInfo& error_info, 42 const content::TestFileErrorInjector::FileErrorInfo& error_info,
49 const ConstructionCallback& ctor_callback, 43 const ConstructionCallback& ctor_callback,
50 const DestructionCallback& dtor_callback); 44 const DestructionCallback& dtor_callback);
51 45
52 ~DownloadFileWithErrors(); 46 ~DownloadFileWithErrors();
53 47
48 virtual void Initialize(const InitializeCallback& callback) OVERRIDE;
49
54 // DownloadFile interface. 50 // DownloadFile interface.
55 virtual content::DownloadInterruptReason Initialize() OVERRIDE;
56 virtual content::DownloadInterruptReason AppendDataToFile( 51 virtual content::DownloadInterruptReason AppendDataToFile(
57 const char* data, size_t data_len) OVERRIDE; 52 const char* data, size_t data_len) OVERRIDE;
58 virtual void Rename(const FilePath& full_path, 53 virtual void Rename(const FilePath& full_path,
59 bool overwrite_existing_file, 54 bool overwrite_existing_file,
60 const RenameCompletionCallback& callback) OVERRIDE; 55 const RenameCompletionCallback& callback) OVERRIDE;
61 56
62 private: 57 private:
63 // Error generating helper. 58 // Error generating helper.
64 content::DownloadInterruptReason ShouldReturnError( 59 content::DownloadInterruptReason ShouldReturnError(
65 content::TestFileErrorInjector::FileOperationCode code, 60 content::TestFileErrorInjector::FileOperationCode code,
66 content::DownloadInterruptReason original_error); 61 content::DownloadInterruptReason original_error);
67 62
68 // Used in place of original rename callback to intercept with 63 // Determine whether to overwrite an operation with the given code
69 // ShouldReturnError. 64 // with a substitute error; if returns true, |*original_error| is
70 void RenameErrorCallback( 65 // written with the error to use for overwriting.
71 const RenameCompletionCallback& original_callback, 66 // NOTE: This routine changes state; specifically, it increases the
72 content::DownloadInterruptReason original_error, 67 // operations counts for the specified code. It should only be called
73 const FilePath& path_result); 68 // once per operation.
69 bool OverwriteError(
70 content::TestFileErrorInjector::FileOperationCode code,
71 content::DownloadInterruptReason* output_error);
74 72
75 // Source URL for the file being downloaded. 73 // Source URL for the file being downloaded.
76 GURL source_url_; 74 GURL source_url_;
77 75
78 // Our injected error. Only one per file. 76 // Our injected error. Only one per file.
79 content::TestFileErrorInjector::FileErrorInfo error_info_; 77 content::TestFileErrorInjector::FileErrorInfo error_info_;
80 78
81 // Count per operation. 0-based. 79 // Count per operation. 0-based.
82 std::map<content::TestFileErrorInjector::FileOperationCode, int> 80 std::map<content::TestFileErrorInjector::FileOperationCode, int>
83 operation_counter_; 81 operation_counter_;
84 82
85 // Callback for destruction. 83 // Callback for destruction.
86 DestructionCallback destruction_callback_; 84 DestructionCallback destruction_callback_;
87 }; 85 };
88 86
87 static void InitializeErrorCallback(
88 const content::DownloadFile::InitializeCallback original_callback,
89 content::DownloadInterruptReason overwrite_error,
90 content::DownloadInterruptReason original_error) {
91 original_callback.Run(overwrite_error);
92 }
93
94 static void RenameErrorCallback(
95 const content::DownloadFile::RenameCompletionCallback original_callback,
96 content::DownloadInterruptReason overwrite_error,
97 content::DownloadInterruptReason original_error,
98 const FilePath& path_result) {
99 original_callback.Run(
100 overwrite_error,
101 overwrite_error == content::DOWNLOAD_INTERRUPT_REASON_NONE ?
102 path_result : FilePath());
103 }
104
89 DownloadFileWithErrors::DownloadFileWithErrors( 105 DownloadFileWithErrors::DownloadFileWithErrors(
90 const DownloadCreateInfo* info, 106 const content::DownloadSaveInfo& save_info,
107 const GURL& url,
108 const GURL& referrer_url,
109 int64 received_bytes,
110 bool calculate_hash,
91 scoped_ptr<content::ByteStreamReader> stream, 111 scoped_ptr<content::ByteStreamReader> stream,
92 DownloadRequestHandleInterface* request_handle,
93 content::DownloadManager* download_manager,
94 bool calculate_hash,
95 const net::BoundNetLog& bound_net_log, 112 const net::BoundNetLog& bound_net_log,
113 scoped_ptr<content::PowerSaveBlocker> power_save_blocker,
114 base::WeakPtr<content::DownloadDestinationObserver> observer,
96 const content::TestFileErrorInjector::FileErrorInfo& error_info, 115 const content::TestFileErrorInjector::FileErrorInfo& error_info,
97 const ConstructionCallback& ctor_callback, 116 const ConstructionCallback& ctor_callback,
98 const DestructionCallback& dtor_callback) 117 const DestructionCallback& dtor_callback)
99 : DownloadFileImpl(info, 118 : DownloadFileImpl(
100 stream.Pass(), 119 save_info, url, referrer_url, received_bytes, calculate_hash,
101 request_handle, 120 stream.Pass(), bound_net_log, power_save_blocker.Pass(),
102 download_manager, 121 observer),
103 calculate_hash, 122 source_url_(url),
104 scoped_ptr<content::PowerSaveBlocker>(NULL).Pass(),
105 bound_net_log),
106 source_url_(info->url()),
107 error_info_(error_info), 123 error_info_(error_info),
108 destruction_callback_(dtor_callback) { 124 destruction_callback_(dtor_callback) {
109 ctor_callback.Run(source_url_, info->download_id); 125 ctor_callback.Run(source_url_);
110 } 126 }
111 127
112 DownloadFileWithErrors::~DownloadFileWithErrors() { 128 DownloadFileWithErrors::~DownloadFileWithErrors() {
113 destruction_callback_.Run(source_url_); 129 destruction_callback_.Run(source_url_);
114 } 130 }
115 131
116 content::DownloadInterruptReason DownloadFileWithErrors::Initialize() { 132 void DownloadFileWithErrors::Initialize(
117 return ShouldReturnError( 133 const InitializeCallback& callback) {
134 content::DownloadInterruptReason error_to_return =
135 content::DOWNLOAD_INTERRUPT_REASON_NONE;
136 InitializeCallback callback_to_use = callback;
137
138 // Replace callback if the error needs to be overwritten.
139 if (OverwriteError(
118 content::TestFileErrorInjector::FILE_OPERATION_INITIALIZE, 140 content::TestFileErrorInjector::FILE_OPERATION_INITIALIZE,
119 DownloadFileImpl::Initialize()); 141 &error_to_return)) {
142 callback_to_use = base::Bind(&InitializeErrorCallback, callback,
143 error_to_return);
144 }
145
146 DownloadFileImpl::Initialize(callback_to_use);
120 } 147 }
121 148
122 content::DownloadInterruptReason DownloadFileWithErrors::AppendDataToFile( 149 content::DownloadInterruptReason DownloadFileWithErrors::AppendDataToFile(
123 const char* data, size_t data_len) { 150 const char* data, size_t data_len) {
124 return ShouldReturnError( 151 return ShouldReturnError(
125 content::TestFileErrorInjector::FILE_OPERATION_WRITE, 152 content::TestFileErrorInjector::FILE_OPERATION_WRITE,
126 DownloadFileImpl::AppendDataToFile(data, data_len)); 153 DownloadFileImpl::AppendDataToFile(data, data_len));
127 } 154 }
128 155
129 void DownloadFileWithErrors::Rename( 156 void DownloadFileWithErrors::Rename(
130 const FilePath& full_path, 157 const FilePath& full_path,
131 bool overwrite_existing_file, 158 bool overwrite_existing_file,
132 const RenameCompletionCallback& callback) { 159 const RenameCompletionCallback& callback) {
133 DownloadFileImpl::Rename( 160 content::DownloadInterruptReason error_to_return =
134 full_path, overwrite_existing_file, 161 content::DOWNLOAD_INTERRUPT_REASON_NONE;
135 base::Bind(&DownloadFileWithErrors::RenameErrorCallback, 162 RenameCompletionCallback callback_to_use = callback;
136 // Unretained since this'll only be called from 163
137 // the DownloadFileImpl slice of the same object. 164 // Replace callback if the error needs to be overwritten.
138 base::Unretained(this), callback)); 165 if (OverwriteError(
166 content::TestFileErrorInjector::FILE_OPERATION_RENAME,
167 &error_to_return)) {
168 callback_to_use = base::Bind(&RenameErrorCallback, callback,
169 error_to_return);
170 }
171
172 DownloadFileImpl::Rename(full_path, overwrite_existing_file, callback_to_use);
173 }
174
175 bool DownloadFileWithErrors::OverwriteError(
176 content::TestFileErrorInjector::FileOperationCode code,
177 content::DownloadInterruptReason* output_error) {
178 int counter = operation_counter_[code]++;
179
180 if (code != error_info_.code)
181 return false;
182
183 if (counter != error_info_.operation_instance)
184 return false;
185
186 *output_error = error_info_.error;
187 return true;
139 } 188 }
140 189
141 content::DownloadInterruptReason DownloadFileWithErrors::ShouldReturnError( 190 content::DownloadInterruptReason DownloadFileWithErrors::ShouldReturnError(
142 content::TestFileErrorInjector::FileOperationCode code, 191 content::TestFileErrorInjector::FileOperationCode code,
143 content::DownloadInterruptReason original_error) { 192 content::DownloadInterruptReason original_error) {
144 int counter = operation_counter_[code]; 193 content::DownloadInterruptReason output_error = original_error;
145 ++operation_counter_[code]; 194 OverwriteError(code, &output_error);
146 195 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 } 196 }
176 197
177 } // namespace 198 } // namespace
178 199
179 namespace content { 200 namespace content {
180 201
181 // A factory for constructing DownloadFiles that inject errors. 202 // A factory for constructing DownloadFiles that inject errors.
182 class DownloadFileWithErrorsFactory 203 class DownloadFileWithErrorsFactory : public DownloadFileFactory {
183 : public DownloadFileManager::DownloadFileFactory {
184 public: 204 public:
185
186 DownloadFileWithErrorsFactory( 205 DownloadFileWithErrorsFactory(
187 const DownloadFileWithErrors::ConstructionCallback& ctor_callback, 206 const DownloadFileWithErrors::ConstructionCallback& ctor_callback,
188 const DownloadFileWithErrors::DestructionCallback& dtor_callback); 207 const DownloadFileWithErrors::DestructionCallback& dtor_callback);
189 virtual ~DownloadFileWithErrorsFactory(); 208 virtual ~DownloadFileWithErrorsFactory();
190 209
191 // DownloadFileFactory interface. 210 // DownloadFileFactory interface.
192 virtual DownloadFile* CreateFile( 211 virtual DownloadFile* CreateFile(
193 DownloadCreateInfo* info, 212 const content::DownloadSaveInfo& save_info,
194 scoped_ptr<content::ByteStreamReader> stream, 213 GURL url,
195 content::DownloadManager* download_manager, 214 GURL referrer_url,
196 bool calculate_hash, 215 int64 received_bytes,
197 const net::BoundNetLog& bound_net_log); 216 bool calculate_hash,
217 scoped_ptr<content::ByteStreamReader> stream,
218 const net::BoundNetLog& bound_net_log,
219 base::WeakPtr<content::DownloadDestinationObserver> observer) OVERRIDE;
198 220
199 bool AddError( 221 bool AddError(
200 const TestFileErrorInjector::FileErrorInfo& error_info); 222 const TestFileErrorInjector::FileErrorInfo& error_info);
201 223
202 void ClearErrors(); 224 void ClearErrors();
203 225
204 private: 226 private:
205 // Our injected error list, mapped by URL. One per file. 227 // Our injected error list, mapped by URL. One per file.
206 TestFileErrorInjector::ErrorMap injected_errors_; 228 TestFileErrorInjector::ErrorMap injected_errors_;
207 229
208 // Callback for creation and destruction. 230 // Callback for creation and destruction.
209 DownloadFileWithErrors::ConstructionCallback construction_callback_; 231 DownloadFileWithErrors::ConstructionCallback construction_callback_;
210 DownloadFileWithErrors::DestructionCallback destruction_callback_; 232 DownloadFileWithErrors::DestructionCallback destruction_callback_;
211 }; 233 };
212 234
213 DownloadFileWithErrorsFactory::DownloadFileWithErrorsFactory( 235 DownloadFileWithErrorsFactory::DownloadFileWithErrorsFactory(
214 const DownloadFileWithErrors::ConstructionCallback& ctor_callback, 236 const DownloadFileWithErrors::ConstructionCallback& ctor_callback,
215 const DownloadFileWithErrors::DestructionCallback& dtor_callback) 237 const DownloadFileWithErrors::DestructionCallback& dtor_callback)
216 : construction_callback_(ctor_callback), 238 : construction_callback_(ctor_callback),
217 destruction_callback_(dtor_callback) { 239 destruction_callback_(dtor_callback) {
218 } 240 }
219 241
220 DownloadFileWithErrorsFactory::~DownloadFileWithErrorsFactory() { 242 DownloadFileWithErrorsFactory::~DownloadFileWithErrorsFactory() {
221 } 243 }
222 244
223 content::DownloadFile* DownloadFileWithErrorsFactory::CreateFile( 245 content::DownloadFile* DownloadFileWithErrorsFactory::CreateFile(
224 DownloadCreateInfo* info, 246 const content::DownloadSaveInfo& save_info,
247 GURL url,
248 GURL referrer_url,
249 int64 received_bytes,
250 bool calculate_hash,
225 scoped_ptr<content::ByteStreamReader> stream, 251 scoped_ptr<content::ByteStreamReader> stream,
226 content::DownloadManager* download_manager, 252 const net::BoundNetLog& bound_net_log,
227 bool calculate_hash, 253 base::WeakPtr<content::DownloadDestinationObserver> observer) {
228 const net::BoundNetLog& bound_net_log) { 254 if (injected_errors_.find(url.spec()) == injected_errors_.end()) {
229 std::string url = info->url().spec();
230
231 if (injected_errors_.find(url) == injected_errors_.end()) {
232 // Have to create entry, because FileErrorInfo is not a POD type. 255 // Have to create entry, because FileErrorInfo is not a POD type.
233 TestFileErrorInjector::FileErrorInfo err_info = { 256 TestFileErrorInjector::FileErrorInfo err_info = {
234 url, 257 url.spec(),
235 TestFileErrorInjector::FILE_OPERATION_INITIALIZE, 258 TestFileErrorInjector::FILE_OPERATION_INITIALIZE,
236 -1, 259 -1,
237 content::DOWNLOAD_INTERRUPT_REASON_NONE 260 content::DOWNLOAD_INTERRUPT_REASON_NONE
238 }; 261 };
239 injected_errors_[url] = err_info; 262 injected_errors_[url.spec()] = err_info;
240 } 263 }
241 264
265 scoped_ptr<content::PowerSaveBlocker> psb(
266 new content::PowerSaveBlocker(
267 content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
268 "Download in progress"));
242 return new DownloadFileWithErrors( 269 return new DownloadFileWithErrors(
243 info, 270 save_info,
271 url,
272 referrer_url,
273 received_bytes,
274 calculate_hash,
244 stream.Pass(), 275 stream.Pass(),
245 new DownloadRequestHandle(info->request_handle),
246 download_manager,
247 calculate_hash,
248 bound_net_log, 276 bound_net_log,
249 injected_errors_[url], 277 psb.Pass(),
278 observer,
279 injected_errors_[url.spec()],
250 construction_callback_, 280 construction_callback_,
251 destruction_callback_); 281 destruction_callback_);
252 } 282 }
253 283
254 bool DownloadFileWithErrorsFactory::AddError( 284 bool DownloadFileWithErrorsFactory::AddError(
255 const TestFileErrorInjector::FileErrorInfo& error_info) { 285 const TestFileErrorInjector::FileErrorInfo& error_info) {
256 // Creates an empty entry if necessary. Duplicate entries overwrite. 286 // Creates an empty entry if necessary. Duplicate entries overwrite.
257 injected_errors_[error_info.url] = error_info; 287 injected_errors_[error_info.url] = error_info;
258 288
259 return true; 289 return true;
260 } 290 }
261 291
262 void DownloadFileWithErrorsFactory::ClearErrors() { 292 void DownloadFileWithErrorsFactory::ClearErrors() {
263 injected_errors_.clear(); 293 injected_errors_.clear();
264 } 294 }
265 295
266 TestFileErrorInjector::TestFileErrorInjector() 296 TestFileErrorInjector::TestFileErrorInjector(
267 : created_factory_(NULL) { 297 scoped_refptr<content::DownloadManager> download_manager)
298 : created_factory_(NULL),
299 // This code is only used for browser_tests, so a
300 // DownloadManager is always a DownloadManagerImpl.
301 download_manager_(
302 static_cast<DownloadManagerImpl*>(download_manager.release())) {
268 // Record the value of the pointer, for later validation. 303 // Record the value of the pointer, for later validation.
269 created_factory_ = 304 created_factory_ =
270 new DownloadFileWithErrorsFactory( 305 new DownloadFileWithErrorsFactory(
271 base::Bind(&TestFileErrorInjector:: 306 base::Bind(&TestFileErrorInjector::RecordDownloadFileConstruction,
272 RecordDownloadFileConstruction,
273 this), 307 this),
274 base::Bind(&TestFileErrorInjector:: 308 base::Bind(&TestFileErrorInjector::RecordDownloadFileDestruction,
275 RecordDownloadFileDestruction,
276 this)); 309 this));
277 310
278 // We will transfer ownership of the factory to the download file manager. 311 // We will transfer ownership of the factory to the download manager.
279 scoped_ptr<DownloadFileWithErrorsFactory> download_file_factory( 312 scoped_ptr<DownloadFileFactory> download_file_factory(
280 created_factory_); 313 created_factory_);
281 314
282 content::BrowserThread::PostTask( 315 download_manager_->SetDownloadFileFactoryForTesting(
283 content::BrowserThread::FILE, 316 download_file_factory.Pass());
284 FROM_HERE,
285 base::Bind(&TestFileErrorInjector::AddFactory,
286 this,
287 base::Passed(&download_file_factory)));
288 } 317 }
289 318
290 TestFileErrorInjector::~TestFileErrorInjector() { 319 TestFileErrorInjector::~TestFileErrorInjector() {
291 } 320 }
292 321
293 void TestFileErrorInjector::AddFactory(
294 scoped_ptr<DownloadFileWithErrorsFactory> factory) {
295 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
296
297 DownloadFileManager* download_file_manager = GetDownloadFileManager();
298 DCHECK(download_file_manager);
299
300 // Convert to base class pointer, for GCC.
301 scoped_ptr<DownloadFileManager::DownloadFileFactory> plain_factory(
302 factory.release());
303
304 download_file_manager->SetFileFactoryForTesting(plain_factory.Pass());
305 }
306
307 bool TestFileErrorInjector::AddError(const FileErrorInfo& error_info) { 322 bool TestFileErrorInjector::AddError(const FileErrorInfo& error_info) {
308 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 323 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
309 DCHECK_LE(0, error_info.operation_instance); 324 DCHECK_LE(0, error_info.operation_instance);
310 DCHECK(injected_errors_.find(error_info.url) == injected_errors_.end()); 325 DCHECK(injected_errors_.find(error_info.url) == injected_errors_.end());
311 326
312 // Creates an empty entry if necessary. 327 // Creates an empty entry if necessary.
313 injected_errors_[error_info.url] = error_info; 328 injected_errors_[error_info.url] = error_info;
314 329
315 return true; 330 return true;
316 } 331 }
317 332
318 void TestFileErrorInjector::ClearErrors() { 333 void TestFileErrorInjector::ClearErrors() {
319 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 334 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
320 injected_errors_.clear(); 335 injected_errors_.clear();
321 } 336 }
322 337
323 bool TestFileErrorInjector::InjectErrors() { 338 bool TestFileErrorInjector::InjectErrors() {
324 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 339 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
325 340
326 ClearFoundFiles(); 341 ClearFoundFiles();
327 342
328 content::BrowserThread::PostTask( 343 DCHECK_EQ(static_cast<content::DownloadFileFactory*>(created_factory_),
329 content::BrowserThread::FILE, 344 download_manager_->GetDownloadFileFactoryForTesting());
330 FROM_HERE, 345
331 base::Bind(&TestFileErrorInjector::InjectErrorsOnFileThread, 346 created_factory_->ClearErrors();
332 this, 347
333 injected_errors_, 348 for (ErrorMap::const_iterator it = injected_errors_.begin();
334 created_factory_)); 349 it != injected_errors_.end(); ++it)
350 created_factory_->AddError(it->second);
335 351
336 return true; 352 return true;
337 } 353 }
338 354
339 void TestFileErrorInjector::InjectErrorsOnFileThread(
340 ErrorMap map, DownloadFileWithErrorsFactory* factory) {
341 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
342
343 // Validate that our factory is in use.
344 DownloadFileManager* download_file_manager = GetDownloadFileManager();
345 DCHECK(download_file_manager);
346
347 DownloadFileManager::DownloadFileFactory* file_factory =
348 download_file_manager->GetFileFactoryForTesting();
349
350 // Validate that we still have the same factory.
351 DCHECK_EQ(static_cast<DownloadFileManager::DownloadFileFactory*>(factory),
352 file_factory);
353
354 // We want to replace all existing injection errors.
355 factory->ClearErrors();
356
357 for (ErrorMap::const_iterator it = map.begin(); it != map.end(); ++it)
358 factory->AddError(it->second);
359 }
360
361 size_t TestFileErrorInjector::CurrentFileCount() const { 355 size_t TestFileErrorInjector::CurrentFileCount() const {
362 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 356 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
363 return files_.size(); 357 return files_.size();
364 } 358 }
365 359
366 size_t TestFileErrorInjector::TotalFileCount() const { 360 size_t TestFileErrorInjector::TotalFileCount() const {
367 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 361 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
368 return found_files_.size(); 362 return found_files_.size();
369 } 363 }
370 364
371 365
372 bool TestFileErrorInjector::HadFile(const GURL& url) const { 366 bool TestFileErrorInjector::HadFile(const GURL& url) const {
373 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 367 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
374 368
375 return (found_files_.find(url) != found_files_.end()); 369 return (found_files_.find(url) != found_files_.end());
376 } 370 }
377 371
378 const content::DownloadId TestFileErrorInjector::GetId(
379 const GURL& url) const {
380 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
381
382 FileMap::const_iterator it = found_files_.find(url);
383 if (it == found_files_.end())
384 return content::DownloadId::Invalid();
385
386 return it->second;
387 }
388
389 void TestFileErrorInjector::ClearFoundFiles() { 372 void TestFileErrorInjector::ClearFoundFiles() {
390 found_files_.clear(); 373 found_files_.clear();
391 } 374 }
392 375
393 void TestFileErrorInjector::DownloadFileCreated(GURL url, 376 void TestFileErrorInjector::DownloadFileCreated(GURL url) {
394 content::DownloadId id) {
395 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 377 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
396 DCHECK(files_.find(url) == files_.end()); 378 DCHECK(files_.find(url) == files_.end());
397 379
398 files_[url] = id; 380 files_.insert(url);
399 found_files_[url] = id; 381 found_files_.insert(url);
400 } 382 }
401 383
402 void TestFileErrorInjector::DestroyingDownloadFile(GURL url) { 384 void TestFileErrorInjector::DestroyingDownloadFile(GURL url) {
403 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 385 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
404 DCHECK(files_.find(url) != files_.end()); 386 DCHECK(files_.find(url) != files_.end());
405 387
406 files_.erase(url); 388 files_.erase(url);
407 } 389 }
408 390
409 void TestFileErrorInjector::RecordDownloadFileConstruction( 391 void TestFileErrorInjector::RecordDownloadFileConstruction(const GURL& url) {
410 const GURL& url, content::DownloadId id) {
411 content::BrowserThread::PostTask( 392 content::BrowserThread::PostTask(
412 content::BrowserThread::UI, 393 content::BrowserThread::UI,
413 FROM_HERE, 394 FROM_HERE,
414 base::Bind(&TestFileErrorInjector::DownloadFileCreated, 395 base::Bind(&TestFileErrorInjector::DownloadFileCreated,
415 this, 396 this,
416 url, 397 url));
417 id));
418 } 398 }
419 399
420 void TestFileErrorInjector::RecordDownloadFileDestruction(const GURL& url) { 400 void TestFileErrorInjector::RecordDownloadFileDestruction(const GURL& url) {
421 content::BrowserThread::PostTask( 401 content::BrowserThread::PostTask(
422 content::BrowserThread::UI, 402 content::BrowserThread::UI,
423 FROM_HERE, 403 FROM_HERE,
424 base::Bind(&TestFileErrorInjector::DestroyingDownloadFile, 404 base::Bind(&TestFileErrorInjector::DestroyingDownloadFile,
425 this, 405 this,
426 url)); 406 url));
427 } 407 }
428 408
429 // static 409 // static
430 scoped_refptr<TestFileErrorInjector> TestFileErrorInjector::Create() { 410 scoped_refptr<TestFileErrorInjector> TestFileErrorInjector::Create(
411 scoped_refptr<content::DownloadManager> download_manager) {
431 static bool visited = false; 412 static bool visited = false;
432 DCHECK(!visited); // Only allowed to be called once. 413 DCHECK(!visited); // Only allowed to be called once.
433 visited = true; 414 visited = true;
434 415
435 scoped_refptr<TestFileErrorInjector> single_injector( 416 scoped_refptr<TestFileErrorInjector> single_injector(
436 new TestFileErrorInjector); 417 new TestFileErrorInjector(download_manager));
437 418
438 return single_injector; 419 return single_injector;
439 } 420 }
440 421
441 // static 422 // static
442 std::string TestFileErrorInjector::DebugString(FileOperationCode code) { 423 std::string TestFileErrorInjector::DebugString(FileOperationCode code) {
443 switch (code) { 424 switch (code) {
444 case FILE_OPERATION_INITIALIZE: 425 case FILE_OPERATION_INITIALIZE:
445 return "INITIALIZE"; 426 return "INITIALIZE";
446 case FILE_OPERATION_WRITE: 427 case FILE_OPERATION_WRITE:
447 return "WRITE"; 428 return "WRITE";
448 case FILE_OPERATION_RENAME: 429 case FILE_OPERATION_RENAME:
449 return "RENAME"; 430 return "RENAME";
450 default: 431 default:
451 break; 432 break;
452 } 433 }
453 434
454 return "Unknown"; 435 return "Unknown";
455 } 436 }
456 437
457 } // namespace content 438 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698