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

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

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

Powered by Google App Engine
This is Rietveld 408576698