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

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

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

Powered by Google App Engine
This is Rietveld 408576698