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

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

Issue 10799005: Replace the DownloadFileManager with direct ownership (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merged to LKGR. Created 8 years, 4 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
« no previous file with comments | « content/public/test/test_file_error_injector.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 205
186 DownloadFileWithErrorsFactory( 206 DownloadFileWithErrorsFactory(
187 const DownloadFileWithErrors::ConstructionCallback& ctor_callback, 207 const DownloadFileWithErrors::ConstructionCallback& ctor_callback,
188 const DownloadFileWithErrors::DestructionCallback& dtor_callback); 208 const DownloadFileWithErrors::DestructionCallback& dtor_callback);
189 virtual ~DownloadFileWithErrorsFactory(); 209 virtual ~DownloadFileWithErrorsFactory();
190 210
191 // DownloadFileFactory interface. 211 // DownloadFileFactory interface.
192 virtual DownloadFile* CreateFile( 212 virtual DownloadFile* CreateFile(
193 DownloadCreateInfo* info, 213 const content::DownloadSaveInfo& save_info,
194 scoped_ptr<content::ByteStreamReader> stream, 214 GURL url,
195 content::DownloadManager* download_manager, 215 GURL referrer_url,
196 bool calculate_hash, 216 int64 received_bytes,
197 const net::BoundNetLog& bound_net_log); 217 bool calculate_hash,
218 scoped_ptr<content::ByteStreamReader> stream,
219 const net::BoundNetLog& bound_net_log,
220 base::WeakPtr<content::DownloadDestinationObserver> observer);
198 221
199 bool AddError( 222 bool AddError(
200 const TestFileErrorInjector::FileErrorInfo& error_info); 223 const TestFileErrorInjector::FileErrorInfo& error_info);
201 224
202 void ClearErrors(); 225 void ClearErrors();
203 226
204 private: 227 private:
205 // Our injected error list, mapped by URL. One per file. 228 // Our injected error list, mapped by URL. One per file.
206 TestFileErrorInjector::ErrorMap injected_errors_; 229 TestFileErrorInjector::ErrorMap injected_errors_;
207 230
208 // Callback for creation and destruction. 231 // Callback for creation and destruction.
209 DownloadFileWithErrors::ConstructionCallback construction_callback_; 232 DownloadFileWithErrors::ConstructionCallback construction_callback_;
210 DownloadFileWithErrors::DestructionCallback destruction_callback_; 233 DownloadFileWithErrors::DestructionCallback destruction_callback_;
211 }; 234 };
212 235
213 DownloadFileWithErrorsFactory::DownloadFileWithErrorsFactory( 236 DownloadFileWithErrorsFactory::DownloadFileWithErrorsFactory(
214 const DownloadFileWithErrors::ConstructionCallback& ctor_callback, 237 const DownloadFileWithErrors::ConstructionCallback& ctor_callback,
215 const DownloadFileWithErrors::DestructionCallback& dtor_callback) 238 const DownloadFileWithErrors::DestructionCallback& dtor_callback)
216 : construction_callback_(ctor_callback), 239 : construction_callback_(ctor_callback),
217 destruction_callback_(dtor_callback) { 240 destruction_callback_(dtor_callback) {
218 } 241 }
219 242
220 DownloadFileWithErrorsFactory::~DownloadFileWithErrorsFactory() { 243 DownloadFileWithErrorsFactory::~DownloadFileWithErrorsFactory() {
221 } 244 }
222 245
223 content::DownloadFile* DownloadFileWithErrorsFactory::CreateFile( 246 content::DownloadFile* DownloadFileWithErrorsFactory::CreateFile(
224 DownloadCreateInfo* info, 247 const content::DownloadSaveInfo& save_info,
248 GURL url,
249 GURL referrer_url,
250 int64 received_bytes,
251 bool calculate_hash,
225 scoped_ptr<content::ByteStreamReader> stream, 252 scoped_ptr<content::ByteStreamReader> stream,
226 content::DownloadManager* download_manager, 253 const net::BoundNetLog& bound_net_log,
227 bool calculate_hash, 254 base::WeakPtr<content::DownloadDestinationObserver> observer) {
228 const net::BoundNetLog& bound_net_log) { 255 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. 256 // Have to create entry, because FileErrorInfo is not a POD type.
233 TestFileErrorInjector::FileErrorInfo err_info = { 257 TestFileErrorInjector::FileErrorInfo err_info = {
234 url, 258 url.spec(),
235 TestFileErrorInjector::FILE_OPERATION_INITIALIZE, 259 TestFileErrorInjector::FILE_OPERATION_INITIALIZE,
236 -1, 260 -1,
237 content::DOWNLOAD_INTERRUPT_REASON_NONE 261 content::DOWNLOAD_INTERRUPT_REASON_NONE
238 }; 262 };
239 injected_errors_[url] = err_info; 263 injected_errors_[url.spec()] = err_info;
240 } 264 }
241 265
266 scoped_ptr<content::PowerSaveBlocker> psb(
267 new content::PowerSaveBlocker(
268 content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
269 "Download in progress"));
242 return new DownloadFileWithErrors( 270 return new DownloadFileWithErrors(
243 info, 271 save_info,
272 url,
273 referrer_url,
274 received_bytes,
275 calculate_hash,
244 stream.Pass(), 276 stream.Pass(),
245 new DownloadRequestHandle(info->request_handle),
246 download_manager,
247 calculate_hash,
248 bound_net_log, 277 bound_net_log,
249 injected_errors_[url], 278 psb.Pass(),
279 observer,
280 injected_errors_[url.spec()],
250 construction_callback_, 281 construction_callback_,
251 destruction_callback_); 282 destruction_callback_);
252 } 283 }
253 284
254 bool DownloadFileWithErrorsFactory::AddError( 285 bool DownloadFileWithErrorsFactory::AddError(
255 const TestFileErrorInjector::FileErrorInfo& error_info) { 286 const TestFileErrorInjector::FileErrorInfo& error_info) {
256 // Creates an empty entry if necessary. Duplicate entries overwrite. 287 // Creates an empty entry if necessary. Duplicate entries overwrite.
257 injected_errors_[error_info.url] = error_info; 288 injected_errors_[error_info.url] = error_info;
258 289
259 return true; 290 return true;
260 } 291 }
261 292
262 void DownloadFileWithErrorsFactory::ClearErrors() { 293 void DownloadFileWithErrorsFactory::ClearErrors() {
263 injected_errors_.clear(); 294 injected_errors_.clear();
264 } 295 }
265 296
266 TestFileErrorInjector::TestFileErrorInjector() 297 TestFileErrorInjector::TestFileErrorInjector(
267 : created_factory_(NULL) { 298 scoped_refptr<content::DownloadManager> download_manager)
299 : created_factory_(NULL),
300 // This code is only used for browser_tests, so a
301 // DownloadManager is always a DownloadManagerImpl.
302 download_manager_(
303 static_cast<DownloadManagerImpl*>(download_manager.release())) {
268 // Record the value of the pointer, for later validation. 304 // Record the value of the pointer, for later validation.
269 created_factory_ = 305 created_factory_ =
270 new DownloadFileWithErrorsFactory( 306 new DownloadFileWithErrorsFactory(
271 base::Bind(&TestFileErrorInjector:: 307 base::Bind(&TestFileErrorInjector::RecordDownloadFileConstruction,
272 RecordDownloadFileConstruction,
273 this), 308 this),
274 base::Bind(&TestFileErrorInjector:: 309 base::Bind(&TestFileErrorInjector::RecordDownloadFileDestruction,
275 RecordDownloadFileDestruction,
276 this)); 310 this));
277 311
278 // We will transfer ownership of the factory to the download file manager. 312 // We will transfer ownership of the factory to the download manager.
279 scoped_ptr<DownloadFileWithErrorsFactory> download_file_factory( 313 scoped_ptr<DownloadFileFactory> download_file_factory(
280 created_factory_); 314 created_factory_);
281 315
282 content::BrowserThread::PostTask( 316 download_manager_->SetDownloadFileFactoryForTesting(
283 content::BrowserThread::FILE, 317 download_file_factory.Pass());
284 FROM_HERE,
285 base::Bind(&TestFileErrorInjector::AddFactory,
286 this,
287 base::Passed(&download_file_factory)));
288 } 318 }
289 319
290 TestFileErrorInjector::~TestFileErrorInjector() { 320 TestFileErrorInjector::~TestFileErrorInjector() {
291 } 321 }
292 322
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) { 323 bool TestFileErrorInjector::AddError(const FileErrorInfo& error_info) {
308 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 324 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
309 DCHECK_LE(0, error_info.operation_instance); 325 DCHECK_LE(0, error_info.operation_instance);
310 DCHECK(injected_errors_.find(error_info.url) == injected_errors_.end()); 326 DCHECK(injected_errors_.find(error_info.url) == injected_errors_.end());
311 327
312 // Creates an empty entry if necessary. 328 // Creates an empty entry if necessary.
313 injected_errors_[error_info.url] = error_info; 329 injected_errors_[error_info.url] = error_info;
314 330
315 return true; 331 return true;
316 } 332 }
317 333
318 void TestFileErrorInjector::ClearErrors() { 334 void TestFileErrorInjector::ClearErrors() {
319 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 335 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
320 injected_errors_.clear(); 336 injected_errors_.clear();
321 } 337 }
322 338
323 bool TestFileErrorInjector::InjectErrors() { 339 bool TestFileErrorInjector::InjectErrors() {
324 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 340 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
325 341
326 ClearFoundFiles(); 342 ClearFoundFiles();
327 343
328 content::BrowserThread::PostTask( 344 DCHECK_EQ(static_cast<content::DownloadFileFactory*>(created_factory_),
329 content::BrowserThread::FILE, 345 download_manager_->GetDownloadFileFactoryForTesting());
330 FROM_HERE, 346
331 base::Bind(&TestFileErrorInjector::InjectErrorsOnFileThread, 347 created_factory_->ClearErrors();
332 this, 348
333 injected_errors_, 349 for (ErrorMap::const_iterator it = injected_errors_.begin();
334 created_factory_)); 350 it != injected_errors_.end(); ++it)
351 created_factory_->AddError(it->second);
335 352
336 return true; 353 return true;
337 } 354 }
338 355
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 { 356 size_t TestFileErrorInjector::CurrentFileCount() const {
362 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 357 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
363 return files_.size(); 358 return files_.size();
364 } 359 }
365 360
366 size_t TestFileErrorInjector::TotalFileCount() const { 361 size_t TestFileErrorInjector::TotalFileCount() const {
367 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 362 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
368 return found_files_.size(); 363 return found_files_.size();
369 } 364 }
370 365
371 366
372 bool TestFileErrorInjector::HadFile(const GURL& url) const { 367 bool TestFileErrorInjector::HadFile(const GURL& url) const {
373 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 368 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
374 369
375 return (found_files_.find(url) != found_files_.end()); 370 return (found_files_.find(url) != found_files_.end());
376 } 371 }
377 372
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() { 373 void TestFileErrorInjector::ClearFoundFiles() {
390 found_files_.clear(); 374 found_files_.clear();
391 } 375 }
392 376
393 void TestFileErrorInjector::DownloadFileCreated(GURL url, 377 void TestFileErrorInjector::DownloadFileCreated(GURL url) {
394 content::DownloadId id) {
395 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 378 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
396 DCHECK(files_.find(url) == files_.end()); 379 DCHECK(files_.find(url) == files_.end());
397 380
398 files_[url] = id; 381 files_.insert(url);
399 found_files_[url] = id; 382 found_files_.insert(url);
400 } 383 }
401 384
402 void TestFileErrorInjector::DestroyingDownloadFile(GURL url) { 385 void TestFileErrorInjector::DestroyingDownloadFile(GURL url) {
403 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 386 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
404 DCHECK(files_.find(url) != files_.end()); 387 DCHECK(files_.find(url) != files_.end());
405 388
406 files_.erase(url); 389 files_.erase(url);
407 } 390 }
408 391
409 void TestFileErrorInjector::RecordDownloadFileConstruction( 392 void TestFileErrorInjector::RecordDownloadFileConstruction(const GURL& url) {
410 const GURL& url, content::DownloadId id) {
411 content::BrowserThread::PostTask( 393 content::BrowserThread::PostTask(
412 content::BrowserThread::UI, 394 content::BrowserThread::UI,
413 FROM_HERE, 395 FROM_HERE,
414 base::Bind(&TestFileErrorInjector::DownloadFileCreated, 396 base::Bind(&TestFileErrorInjector::DownloadFileCreated,
415 this, 397 this,
416 url, 398 url));
417 id));
418 } 399 }
419 400
420 void TestFileErrorInjector::RecordDownloadFileDestruction(const GURL& url) { 401 void TestFileErrorInjector::RecordDownloadFileDestruction(const GURL& url) {
421 content::BrowserThread::PostTask( 402 content::BrowserThread::PostTask(
422 content::BrowserThread::UI, 403 content::BrowserThread::UI,
423 FROM_HERE, 404 FROM_HERE,
424 base::Bind(&TestFileErrorInjector::DestroyingDownloadFile, 405 base::Bind(&TestFileErrorInjector::DestroyingDownloadFile,
425 this, 406 this,
426 url)); 407 url));
427 } 408 }
428 409
429 // static 410 // static
430 scoped_refptr<TestFileErrorInjector> TestFileErrorInjector::Create() { 411 scoped_refptr<TestFileErrorInjector> TestFileErrorInjector::Create(
412 scoped_refptr<content::DownloadManager> download_manager) {
431 static bool visited = false; 413 static bool visited = false;
432 DCHECK(!visited); // Only allowed to be called once. 414 DCHECK(!visited); // Only allowed to be called once.
433 visited = true; 415 visited = true;
434 416
435 scoped_refptr<TestFileErrorInjector> single_injector( 417 scoped_refptr<TestFileErrorInjector> single_injector(
436 new TestFileErrorInjector); 418 new TestFileErrorInjector(download_manager));
437 419
438 return single_injector; 420 return single_injector;
439 } 421 }
440 422
441 // static 423 // static
442 std::string TestFileErrorInjector::DebugString(FileOperationCode code) { 424 std::string TestFileErrorInjector::DebugString(FileOperationCode code) {
443 switch (code) { 425 switch (code) {
444 case FILE_OPERATION_INITIALIZE: 426 case FILE_OPERATION_INITIALIZE:
445 return "INITIALIZE"; 427 return "INITIALIZE";
446 case FILE_OPERATION_WRITE: 428 case FILE_OPERATION_WRITE:
447 return "WRITE"; 429 return "WRITE";
448 case FILE_OPERATION_RENAME: 430 case FILE_OPERATION_RENAME:
449 return "RENAME"; 431 return "RENAME";
450 default: 432 default:
451 break; 433 break;
452 } 434 }
453 435
454 return "Unknown"; 436 return "Unknown";
455 } 437 }
456 438
457 } // namespace content 439 } // namespace content
OLDNEW
« no previous file with comments | « content/public/test/test_file_error_injector.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698