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

Side by Side Diff: webkit/fileapi/local_file_system_operation_write_unittest.cc

Issue 15994002: Move more browser-specific webkit/fileapi code to webkit/browser/fileapi (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 7 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include <vector>
6
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/message_loop.h"
11 #include "base/message_loop_proxy.h"
12 #include "googleurl/src/gurl.h"
13 #include "net/url_request/url_request.h"
14 #include "net/url_request/url_request_context.h"
15 #include "net/url_request/url_request_job.h"
16 #include "net/url_request/url_request_job_factory_impl.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "webkit/blob/blob_data.h"
19 #include "webkit/blob/blob_storage_controller.h"
20 #include "webkit/blob/blob_url_request_job.h"
21 #include "webkit/blob/mock_blob_url_request_context.h"
22 #include "webkit/browser/fileapi/file_system_file_util.h"
23 #include "webkit/browser/fileapi/local_file_util.h"
24 #include "webkit/fileapi/file_system_context.h"
25 #include "webkit/fileapi/file_system_operation.h"
26 #include "webkit/fileapi/file_system_operation_context.h"
27 #include "webkit/fileapi/file_system_util.h"
28 #include "webkit/fileapi/local_file_system_operation.h"
29 #include "webkit/fileapi/mock_file_change_observer.h"
30 #include "webkit/fileapi/mock_file_system_context.h"
31 #include "webkit/quota/mock_quota_manager.h"
32
33 using webkit_blob::MockBlobURLRequestContext;
34 using webkit_blob::ScopedTextBlob;
35
36 namespace fileapi {
37
38 namespace {
39
40 const GURL kOrigin("http://example.com");
41 const FileSystemType kFileSystemType = kFileSystemTypeTest;
42
43 void AssertStatusEq(base::PlatformFileError expected,
44 base::PlatformFileError actual) {
45 ASSERT_EQ(expected, actual);
46 }
47
48 } // namespace
49
50 class LocalFileSystemOperationWriteTest
51 : public testing::Test,
52 public base::SupportsWeakPtr<LocalFileSystemOperationWriteTest> {
53 public:
54 LocalFileSystemOperationWriteTest()
55 : loop_(base::MessageLoop::TYPE_IO),
56 status_(base::PLATFORM_FILE_OK),
57 cancel_status_(base::PLATFORM_FILE_ERROR_FAILED),
58 bytes_written_(0),
59 complete_(false) {
60 change_observers_ = MockFileChangeObserver::CreateList(&change_observer_);
61 }
62
63 virtual void SetUp() {
64 ASSERT_TRUE(dir_.CreateUniqueTempDir());
65
66 quota_manager_ = new quota::MockQuotaManager(
67 false /* is_incognito */, dir_.path(),
68 base::MessageLoopProxy::current(),
69 base::MessageLoopProxy::current(),
70 NULL /* special storage policy */);
71 virtual_path_ = base::FilePath(FILE_PATH_LITERAL("temporary file"));
72
73 file_system_context_ = CreateFileSystemContextForTesting(
74 quota_manager_->proxy(), dir_.path());
75 url_request_context_.reset(
76 new MockBlobURLRequestContext(file_system_context_));
77
78 NewOperation()->CreateFile(
79 URLForPath(virtual_path_), true /* exclusive */,
80 base::Bind(&AssertStatusEq, base::PLATFORM_FILE_OK));
81 }
82
83 virtual void TearDown() {
84 quota_manager_ = NULL;
85 file_system_context_ = NULL;
86 base::MessageLoop::current()->RunUntilIdle();
87 }
88
89 LocalFileSystemOperation* NewOperation() {
90 LocalFileSystemOperation* operation =
91 file_system_context_->CreateFileSystemOperation(
92 URLForPath(base::FilePath()), NULL)->AsLocalFileSystemOperation();
93 operation->operation_context()->set_change_observers(change_observers());
94 return operation;
95 }
96
97 base::PlatformFileError status() const { return status_; }
98 base::PlatformFileError cancel_status() const { return cancel_status_; }
99 void add_bytes_written(int64 bytes, bool complete) {
100 bytes_written_ += bytes;
101 EXPECT_FALSE(complete_);
102 complete_ = complete;
103 }
104 int64 bytes_written() const { return bytes_written_; }
105 bool complete() const { return complete_; }
106
107 protected:
108 const ChangeObserverList& change_observers() const {
109 return change_observers_;
110 }
111
112 MockFileChangeObserver* change_observer() {
113 return &change_observer_;
114 }
115
116 FileSystemURL URLForPath(const base::FilePath& path) const {
117 return file_system_context_->CreateCrackedFileSystemURL(
118 kOrigin, kFileSystemType, path);
119 }
120
121 // Callback function for recording test results.
122 FileSystemOperation::WriteCallback RecordWriteCallback() {
123 return base::Bind(&LocalFileSystemOperationWriteTest::DidWrite,
124 AsWeakPtr());
125 }
126
127 FileSystemOperation::StatusCallback RecordCancelCallback() {
128 return base::Bind(&LocalFileSystemOperationWriteTest::DidCancel,
129 AsWeakPtr());
130 }
131
132 void DidWrite(base::PlatformFileError status, int64 bytes, bool complete) {
133 if (status == base::PLATFORM_FILE_OK) {
134 add_bytes_written(bytes, complete);
135 if (complete)
136 base::MessageLoop::current()->Quit();
137 } else {
138 EXPECT_FALSE(complete_);
139 EXPECT_EQ(status_, base::PLATFORM_FILE_OK);
140 complete_ = true;
141 status_ = status;
142 if (base::MessageLoop::current()->is_running())
143 base::MessageLoop::current()->Quit();
144 }
145 }
146
147 void DidCancel(base::PlatformFileError status) {
148 cancel_status_ = status;
149 }
150
151 const MockBlobURLRequestContext& url_request_context() const {
152 return *url_request_context_;
153 }
154
155 scoped_refptr<FileSystemContext> file_system_context_;
156 scoped_refptr<quota::MockQuotaManager> quota_manager_;
157
158 base::MessageLoop loop_;
159
160 base::ScopedTempDir dir_;
161 base::FilePath virtual_path_;
162
163 // For post-operation status.
164 base::PlatformFileError status_;
165 base::PlatformFileError cancel_status_;
166 int64 bytes_written_;
167 bool complete_;
168
169 scoped_ptr<MockBlobURLRequestContext> url_request_context_;
170
171 MockFileChangeObserver change_observer_;
172 ChangeObserverList change_observers_;
173
174 DISALLOW_COPY_AND_ASSIGN(LocalFileSystemOperationWriteTest);
175 };
176
177 TEST_F(LocalFileSystemOperationWriteTest, TestWriteSuccess) {
178 const GURL blob_url("blob:success");
179 ScopedTextBlob blob(url_request_context(), blob_url, "Hello, world!\n");
180
181 NewOperation()->Write(
182 &url_request_context(), URLForPath(virtual_path_), blob_url,
183 0, RecordWriteCallback());
184 base::MessageLoop::current()->Run();
185
186 EXPECT_EQ(14, bytes_written());
187 EXPECT_EQ(base::PLATFORM_FILE_OK, status());
188 EXPECT_TRUE(complete());
189
190 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
191 }
192
193 TEST_F(LocalFileSystemOperationWriteTest, TestWriteZero) {
194 GURL blob_url("blob:zero");
195 scoped_refptr<webkit_blob::BlobData> blob_data(new webkit_blob::BlobData());
196
197 url_request_context().blob_storage_controller()->AddFinishedBlob(
198 blob_url, blob_data);
199
200 NewOperation()->Write(
201 &url_request_context(), URLForPath(virtual_path_),
202 blob_url, 0, RecordWriteCallback());
203 base::MessageLoop::current()->Run();
204
205 url_request_context().blob_storage_controller()->RemoveBlob(blob_url);
206
207 EXPECT_EQ(0, bytes_written());
208 EXPECT_EQ(base::PLATFORM_FILE_OK, status());
209 EXPECT_TRUE(complete());
210
211 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
212 }
213
214 TEST_F(LocalFileSystemOperationWriteTest, TestWriteInvalidBlobUrl) {
215 NewOperation()->Write(
216 &url_request_context(), URLForPath(virtual_path_),
217 GURL("blob:invalid"), 0, RecordWriteCallback());
218 base::MessageLoop::current()->Run();
219
220 EXPECT_EQ(0, bytes_written());
221 EXPECT_EQ(base::PLATFORM_FILE_ERROR_FAILED, status());
222 EXPECT_TRUE(complete());
223
224 EXPECT_EQ(0, change_observer()->get_and_reset_modify_file_count());
225 }
226
227 TEST_F(LocalFileSystemOperationWriteTest, TestWriteInvalidFile) {
228 GURL blob_url("blob:writeinvalidfile");
229 ScopedTextBlob blob(url_request_context(), blob_url,
230 "It\'ll not be written.");
231
232 NewOperation()->Write(
233 &url_request_context(),
234 URLForPath(base::FilePath(FILE_PATH_LITERAL("nonexist"))),
235 blob_url, 0, RecordWriteCallback());
236 base::MessageLoop::current()->Run();
237
238 EXPECT_EQ(0, bytes_written());
239 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status());
240 EXPECT_TRUE(complete());
241
242 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
243 }
244
245 TEST_F(LocalFileSystemOperationWriteTest, TestWriteDir) {
246 base::FilePath virtual_dir_path(FILE_PATH_LITERAL("d"));
247 NewOperation()->CreateDirectory(
248 URLForPath(virtual_dir_path),
249 true /* exclusive */, false /* recursive */,
250 base::Bind(&AssertStatusEq, base::PLATFORM_FILE_OK));
251
252 GURL blob_url("blob:writedir");
253 ScopedTextBlob blob(url_request_context(), blob_url,
254 "It\'ll not be written, too.");
255
256 NewOperation()->Write(&url_request_context(), URLForPath(virtual_dir_path),
257 blob_url, 0, RecordWriteCallback());
258 base::MessageLoop::current()->Run();
259
260 EXPECT_EQ(0, bytes_written());
261 // TODO(kinuko): This error code is platform- or fileutil- dependent
262 // right now. Make it return PLATFORM_FILE_ERROR_NOT_A_FILE in every case.
263 EXPECT_TRUE(status() == base::PLATFORM_FILE_ERROR_NOT_A_FILE ||
264 status() == base::PLATFORM_FILE_ERROR_ACCESS_DENIED ||
265 status() == base::PLATFORM_FILE_ERROR_FAILED);
266 EXPECT_TRUE(complete());
267
268 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
269 }
270
271 TEST_F(LocalFileSystemOperationWriteTest, TestWriteFailureByQuota) {
272 GURL blob_url("blob:success");
273 ScopedTextBlob blob(url_request_context(), blob_url, "Hello, world!\n");
274
275 quota_manager_->SetQuota(
276 kOrigin, FileSystemTypeToQuotaStorageType(kFileSystemType), 10);
277 NewOperation()->Write(
278 &url_request_context(), URLForPath(virtual_path_), blob_url,
279 0, RecordWriteCallback());
280 base::MessageLoop::current()->Run();
281
282 EXPECT_EQ(10, bytes_written());
283 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status());
284 EXPECT_TRUE(complete());
285
286 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
287 }
288
289 TEST_F(LocalFileSystemOperationWriteTest, TestImmediateCancelSuccessfulWrite) {
290 GURL blob_url("blob:success");
291 ScopedTextBlob blob(url_request_context(), blob_url, "Hello, world!\n");
292
293 FileSystemOperation* write_operation = NewOperation();
294 write_operation->Write(&url_request_context(), URLForPath(virtual_path_),
295 blob_url, 0, RecordWriteCallback());
296 write_operation->Cancel(RecordCancelCallback());
297 // We use RunAllPendings() instead of Run() here, because we won't dispatch
298 // callbacks after Cancel() is issued (so no chance to Quit) nor do we need
299 // to run another write cycle.
300 base::MessageLoop::current()->RunUntilIdle();
301
302 // Issued Cancel() before receiving any response from Write(),
303 // so nothing should have happen.
304 EXPECT_EQ(0, bytes_written());
305 EXPECT_EQ(base::PLATFORM_FILE_ERROR_ABORT, status());
306 EXPECT_EQ(base::PLATFORM_FILE_OK, cancel_status());
307 EXPECT_TRUE(complete());
308
309 EXPECT_EQ(0, change_observer()->get_and_reset_modify_file_count());
310 }
311
312 TEST_F(LocalFileSystemOperationWriteTest, TestImmediateCancelFailingWrite) {
313 GURL blob_url("blob:writeinvalidfile");
314 ScopedTextBlob blob(url_request_context(), blob_url,
315 "It\'ll not be written.");
316
317 FileSystemOperation* write_operation = NewOperation();
318 write_operation->Write(
319 &url_request_context(),
320 URLForPath(base::FilePath(FILE_PATH_LITERAL("nonexist"))),
321 blob_url, 0, RecordWriteCallback());
322 write_operation->Cancel(RecordCancelCallback());
323 // We use RunAllPendings() instead of Run() here, because we won't dispatch
324 // callbacks after Cancel() is issued (so no chance to Quit) nor do we need
325 // to run another write cycle.
326 base::MessageLoop::current()->RunUntilIdle();
327
328 // Issued Cancel() before receiving any response from Write(),
329 // so nothing should have happen.
330 EXPECT_EQ(0, bytes_written());
331 EXPECT_EQ(base::PLATFORM_FILE_ERROR_ABORT, status());
332 EXPECT_EQ(base::PLATFORM_FILE_OK, cancel_status());
333 EXPECT_TRUE(complete());
334
335 EXPECT_EQ(0, change_observer()->get_and_reset_modify_file_count());
336 }
337
338 // TODO(ericu,dmikurube,kinuko): Add more tests for cancel cases.
339
340 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/fileapi/local_file_system_operation_unittest.cc ('k') | webkit/fileapi/mock_file_change_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698