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

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

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