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

Side by Side Diff: content/browser/fileapi/recursive_operation_delegate_unittest.cc

Issue 1184343002: Recursive operation delegate continues operations with ignoring errors. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | storage/browser/fileapi/file_system_operation.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "storage/browser/fileapi/recursive_operation_delegate.h" 5 #include "storage/browser/fileapi/recursive_operation_delegate.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 weak_factory_(this) {} 48 weak_factory_(this) {}
49 ~LoggingRecursiveOperation() override {} 49 ~LoggingRecursiveOperation() override {}
50 50
51 const std::vector<LogEntry>& log_entries() const { return log_entries_; } 51 const std::vector<LogEntry>& log_entries() const { return log_entries_; }
52 52
53 // RecursiveOperationDelegate overrides. 53 // RecursiveOperationDelegate overrides.
54 void Run() override { NOTREACHED(); } 54 void Run() override { NOTREACHED(); }
55 55
56 void RunRecursively() override { StartRecursiveOperation(root_, callback_); } 56 void RunRecursively() override { StartRecursiveOperation(root_, callback_); }
57 57
58 void RunRecursivelyWithIgnoringError(const ErrorCallback& error_callback) {
59 StartRecursiveOperationWithIgnoringError(root_, error_callback, callback_);
60 }
61
58 void ProcessFile(const FileSystemURL& url, 62 void ProcessFile(const FileSystemURL& url,
59 const StatusCallback& callback) override { 63 const StatusCallback& callback) override {
60 RecordLogEntry(LogEntry::PROCESS_FILE, url); 64 RecordLogEntry(LogEntry::PROCESS_FILE, url);
65
66 if (error_url_.is_valid() && error_url_ == url) {
67 callback.Run(base::File::FILE_ERROR_FAILED);
68 return;
69 }
70
61 operation_runner()->GetMetadata( 71 operation_runner()->GetMetadata(
62 url, 72 url,
63 base::Bind(&LoggingRecursiveOperation::DidGetMetadata, 73 base::Bind(&LoggingRecursiveOperation::DidGetMetadata,
64 weak_factory_.GetWeakPtr(), callback)); 74 weak_factory_.GetWeakPtr(), callback));
65 } 75 }
66 76
67 void ProcessDirectory(const FileSystemURL& url, 77 void ProcessDirectory(const FileSystemURL& url,
68 const StatusCallback& callback) override { 78 const StatusCallback& callback) override {
69 RecordLogEntry(LogEntry::PROCESS_DIRECTORY, url); 79 RecordLogEntry(LogEntry::PROCESS_DIRECTORY, url);
70 callback.Run(base::File::FILE_OK); 80 callback.Run(base::File::FILE_OK);
71 } 81 }
72 82
73 void PostProcessDirectory(const FileSystemURL& url, 83 void PostProcessDirectory(const FileSystemURL& url,
74 const StatusCallback& callback) override { 84 const StatusCallback& callback) override {
75 RecordLogEntry(LogEntry::POST_PROCESS_DIRECTORY, url); 85 RecordLogEntry(LogEntry::POST_PROCESS_DIRECTORY, url);
76 callback.Run(base::File::FILE_OK); 86 callback.Run(base::File::FILE_OK);
77 } 87 }
78 88
89 void SetEntryToFail(const FileSystemURL& url) { error_url_ = url; }
90
79 private: 91 private:
80 void RecordLogEntry(LogEntry::Type type, const FileSystemURL& url) { 92 void RecordLogEntry(LogEntry::Type type, const FileSystemURL& url) {
81 LogEntry entry; 93 LogEntry entry;
82 entry.type = type; 94 entry.type = type;
83 entry.url = url; 95 entry.url = url;
84 log_entries_.push_back(entry); 96 log_entries_.push_back(entry);
85 } 97 }
86 98
87 void DidGetMetadata(const StatusCallback& callback, 99 void DidGetMetadata(const StatusCallback& callback,
88 base::File::Error result, 100 base::File::Error result,
89 const base::File::Info& file_info) { 101 const base::File::Info& file_info) {
90 if (result != base::File::FILE_OK) { 102 if (result != base::File::FILE_OK) {
91 callback.Run(result); 103 callback.Run(result);
92 return; 104 return;
93 } 105 }
94 106
95 callback.Run(file_info.is_directory ? 107 callback.Run(file_info.is_directory ?
96 base::File::FILE_ERROR_NOT_A_FILE : 108 base::File::FILE_ERROR_NOT_A_FILE :
97 base::File::FILE_OK); 109 base::File::FILE_OK);
98 } 110 }
99 111
100 FileSystemURL root_; 112 FileSystemURL root_;
101 StatusCallback callback_; 113 StatusCallback callback_;
102 std::vector<LogEntry> log_entries_; 114 std::vector<LogEntry> log_entries_;
115 FileSystemURL error_url_;
103 116
104 base::WeakPtrFactory<LoggingRecursiveOperation> weak_factory_; 117 base::WeakPtrFactory<LoggingRecursiveOperation> weak_factory_;
105 DISALLOW_COPY_AND_ASSIGN(LoggingRecursiveOperation); 118 DISALLOW_COPY_AND_ASSIGN(LoggingRecursiveOperation);
106 }; 119 };
107 120
108 void ReportStatus(base::File::Error* out_error, 121 void ReportStatus(base::File::Error* out_error,
109 base::File::Error error) { 122 base::File::Error error) {
110 DCHECK(out_error); 123 DCHECK(out_error);
111 *out_error = error; 124 *out_error = error;
112 } 125 }
113 126
127 typedef std::pair<FileSystemURL, base::File::Error> ErrorEntry;
128
129 void ReportError(std::vector<ErrorEntry>* out_errors,
130 const FileSystemURL& url,
131 base::File::Error error) {
132 DCHECK(out_errors);
133 out_errors->push_back(std::make_pair(url, error));
134 }
135
114 // To test the Cancel() during operation, calls Cancel() of |operation| 136 // To test the Cancel() during operation, calls Cancel() of |operation|
115 // after |counter| times message posting. 137 // after |counter| times message posting.
116 void CallCancelLater(storage::RecursiveOperationDelegate* operation, 138 void CallCancelLater(storage::RecursiveOperationDelegate* operation,
117 int counter) { 139 int counter) {
118 if (counter > 0) { 140 if (counter > 0) {
119 base::ThreadTaskRunnerHandle::Get()->PostTask( 141 base::ThreadTaskRunnerHandle::Get()->PostTask(
120 FROM_HERE, 142 FROM_HERE,
121 base::Bind(&CallCancelLater, base::Unretained(operation), counter - 1)); 143 base::Bind(&CallCancelLater, base::Unretained(operation), counter - 1));
122 return; 144 return;
123 } 145 }
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 context->file_system_context(), src_root, 291 context->file_system_context(), src_root,
270 base::Bind(&ReportStatus, &error))); 292 base::Bind(&ReportStatus, &error)));
271 operation->RunRecursively(); 293 operation->RunRecursively();
272 294
273 // Invoke Cancel(), after 5 times message posting. 295 // Invoke Cancel(), after 5 times message posting.
274 CallCancelLater(operation.get(), 5); 296 CallCancelLater(operation.get(), 5);
275 base::RunLoop().RunUntilIdle(); 297 base::RunLoop().RunUntilIdle();
276 ASSERT_EQ(base::File::FILE_ERROR_ABORT, error); 298 ASSERT_EQ(base::File::FILE_ERROR_ABORT, error);
277 } 299 }
278 300
301 TEST_F(RecursiveOperationDelegateTest, AbortWithError) {
302 FileSystemURL src_root(CreateDirectory("src"));
303 FileSystemURL src_dir1(CreateDirectory("src/dir1"));
304 FileSystemURL src_file1(CreateFile("src/file1"));
305 FileSystemURL src_file2(CreateFile("src/dir1/file2"));
306 FileSystemURL src_file3(CreateFile("src/dir1/file3"));
307
308 base::File::Error error = base::File::FILE_ERROR_FAILED;
309 scoped_ptr<FileSystemOperationContext> context = NewContext();
310 scoped_ptr<LoggingRecursiveOperation> operation(
311 new LoggingRecursiveOperation(context->file_system_context(), src_root,
312 base::Bind(&ReportStatus, &error)));
313 operation->SetEntryToFail(src_file1);
314 operation->RunRecursively();
315 base::RunLoop().RunUntilIdle();
316
317 ASSERT_EQ(base::File::FILE_ERROR_FAILED, error);
318
319 // Confirm that operation has been aborted in the middle.
320 const std::vector<LoggingRecursiveOperation::LogEntry>& log_entries =
321 operation->log_entries();
322 ASSERT_EQ(3U, log_entries.size());
323
324 EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE,
325 log_entries[0].type);
326 EXPECT_EQ(src_root, log_entries[0].url);
327
328 EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_DIRECTORY,
329 log_entries[1].type);
330 EXPECT_EQ(src_root, log_entries[1].url);
331
332 EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE,
333 log_entries[2].type);
334 EXPECT_EQ(src_file1, log_entries[2].url);
335 }
336
337 TEST_F(RecursiveOperationDelegateTest, ContinueWithError) {
338 FileSystemURL src_root(CreateDirectory("src"));
339 FileSystemURL src_dir1(CreateDirectory("src/dir1"));
340 FileSystemURL src_file1(CreateFile("src/file1"));
341 FileSystemURL src_file2(CreateFile("src/dir1/file2"));
342 FileSystemURL src_file3(CreateFile("src/dir1/file3"));
343
344 base::File::Error error = base::File::FILE_ERROR_FAILED;
345 std::vector<ErrorEntry> errors;
346 scoped_ptr<FileSystemOperationContext> context = NewContext();
347 scoped_ptr<LoggingRecursiveOperation> operation(
348 new LoggingRecursiveOperation(context->file_system_context(), src_root,
349 base::Bind(&ReportStatus, &error)));
350 operation->SetEntryToFail(src_file1);
351 operation->RunRecursivelyWithIgnoringError(base::Bind(&ReportError, &errors));
352 base::RunLoop().RunUntilIdle();
353
354 // Error code should be base::File::FILE_ERROR_FAILED.
355 ASSERT_EQ(base::File::FILE_ERROR_FAILED, error);
356
357 // Error callback should be called.
358 ASSERT_EQ(1U, errors.size());
359 ASSERT_EQ(src_file1, errors[0].first);
360 ASSERT_EQ(base::File::FILE_ERROR_FAILED, errors[0].second);
361
362 // Confirm that operation continues after the error.
363 const std::vector<LoggingRecursiveOperation::LogEntry>& log_entries =
364 operation->log_entries();
365 ASSERT_EQ(8U, log_entries.size());
366
367 EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE,
368 log_entries[0].type);
369 EXPECT_EQ(src_root, log_entries[0].url);
370
371 EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_DIRECTORY,
372 log_entries[1].type);
373 EXPECT_EQ(src_root, log_entries[1].url);
374
375 EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE,
376 log_entries[2].type);
377 EXPECT_EQ(src_file1, log_entries[2].url);
378
379 EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_DIRECTORY,
380 log_entries[3].type);
381 EXPECT_EQ(src_dir1, log_entries[3].url);
382
383 EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE,
384 log_entries[4].type);
385 EXPECT_EQ(src_file3, log_entries[4].url);
386
387 EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE,
388 log_entries[5].type);
389 EXPECT_EQ(src_file2, log_entries[5].url);
390
391 EXPECT_EQ(LoggingRecursiveOperation::LogEntry::POST_PROCESS_DIRECTORY,
392 log_entries[6].type);
393 EXPECT_EQ(src_dir1, log_entries[6].url);
394
395 EXPECT_EQ(LoggingRecursiveOperation::LogEntry::POST_PROCESS_DIRECTORY,
396 log_entries[7].type);
397 EXPECT_EQ(src_root, log_entries[7].url);
398 }
399
279 } // namespace content 400 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | storage/browser/fileapi/file_system_operation.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698