Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / content / browser / fileapi / native_file_util_unittest.cc
blob85aadb672f7aca13e3166049f2f73e3fa55445ba
1 // Copyright 2014 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.
5 #include <set>
7 #include "base/files/file.h"
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "storage/browser/fileapi/native_file_util.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 using storage::FileSystemFileUtil;
15 using storage::FileSystemOperation;
16 using storage::NativeFileUtil;
18 namespace content {
20 class NativeFileUtilTest : public testing::Test {
21 public:
22 NativeFileUtilTest() {}
24 void SetUp() override { ASSERT_TRUE(data_dir_.CreateUniqueTempDir()); }
26 protected:
27 base::FilePath Path() {
28 return data_dir_.path();
31 base::FilePath Path(const char* file_name) {
32 return data_dir_.path().AppendASCII(file_name);
35 bool FileExists(const base::FilePath& path) {
36 return base::PathExists(path) &&
37 !base::DirectoryExists(path);
40 int64 GetSize(const base::FilePath& path) {
41 base::File::Info info;
42 base::GetFileInfo(path, &info);
43 return info.size;
46 private:
47 base::ScopedTempDir data_dir_;
49 DISALLOW_COPY_AND_ASSIGN(NativeFileUtilTest);
52 TEST_F(NativeFileUtilTest, CreateCloseAndDeleteFile) {
53 base::FilePath file_name = Path("test_file");
54 int flags = base::File::FLAG_WRITE | base::File::FLAG_ASYNC;
55 base::File file =
56 NativeFileUtil::CreateOrOpen(file_name, base::File::FLAG_CREATE | flags);
57 ASSERT_TRUE(file.IsValid());
58 ASSERT_TRUE(file.created());
60 EXPECT_TRUE(base::PathExists(file_name));
61 EXPECT_TRUE(NativeFileUtil::PathExists(file_name));
62 EXPECT_EQ(0, GetSize(file_name));
63 file.Close();
65 file = NativeFileUtil::CreateOrOpen(file_name, base::File::FLAG_OPEN | flags);
66 ASSERT_TRUE(file.IsValid());
67 ASSERT_FALSE(file.created());
68 file.Close();
70 ASSERT_EQ(base::File::FILE_OK,
71 NativeFileUtil::DeleteFile(file_name));
72 EXPECT_FALSE(base::PathExists(file_name));
73 EXPECT_FALSE(NativeFileUtil::PathExists(file_name));
76 TEST_F(NativeFileUtilTest, EnsureFileExists) {
77 base::FilePath file_name = Path("foobar");
78 bool created = false;
79 ASSERT_EQ(base::File::FILE_OK,
80 NativeFileUtil::EnsureFileExists(file_name, &created));
81 ASSERT_TRUE(created);
83 EXPECT_TRUE(FileExists(file_name));
84 EXPECT_EQ(0, GetSize(file_name));
86 ASSERT_EQ(base::File::FILE_OK,
87 NativeFileUtil::EnsureFileExists(file_name, &created));
88 EXPECT_FALSE(created);
91 TEST_F(NativeFileUtilTest, CreateAndDeleteDirectory) {
92 base::FilePath dir_name = Path("test_dir");
93 ASSERT_EQ(base::File::FILE_OK,
94 NativeFileUtil::CreateDirectory(dir_name,
95 false /* exclusive */,
96 false /* recursive */));
98 EXPECT_TRUE(NativeFileUtil::DirectoryExists(dir_name));
99 EXPECT_TRUE(base::DirectoryExists(dir_name));
101 ASSERT_EQ(base::File::FILE_ERROR_EXISTS,
102 NativeFileUtil::CreateDirectory(dir_name,
103 true /* exclusive */,
104 false /* recursive */));
106 ASSERT_EQ(base::File::FILE_OK,
107 NativeFileUtil::DeleteDirectory(dir_name));
108 EXPECT_FALSE(base::DirectoryExists(dir_name));
109 EXPECT_FALSE(NativeFileUtil::DirectoryExists(dir_name));
112 TEST_F(NativeFileUtilTest, TouchFileAndGetFileInfo) {
113 base::FilePath file_name = Path("test_file");
114 base::File::Info native_info;
115 ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND,
116 NativeFileUtil::GetFileInfo(file_name, &native_info));
118 bool created = false;
119 ASSERT_EQ(base::File::FILE_OK,
120 NativeFileUtil::EnsureFileExists(file_name, &created));
121 ASSERT_TRUE(created);
123 base::File::Info info;
124 ASSERT_TRUE(base::GetFileInfo(file_name, &info));
125 ASSERT_EQ(base::File::FILE_OK,
126 NativeFileUtil::GetFileInfo(file_name, &native_info));
127 ASSERT_EQ(info.size, native_info.size);
128 ASSERT_EQ(info.is_directory, native_info.is_directory);
129 ASSERT_EQ(info.is_symbolic_link, native_info.is_symbolic_link);
130 ASSERT_EQ(info.last_modified, native_info.last_modified);
131 ASSERT_EQ(info.last_accessed, native_info.last_accessed);
132 ASSERT_EQ(info.creation_time, native_info.creation_time);
134 const base::Time new_accessed =
135 info.last_accessed + base::TimeDelta::FromHours(10);
136 const base::Time new_modified =
137 info.last_modified + base::TimeDelta::FromHours(5);
139 EXPECT_EQ(base::File::FILE_OK,
140 NativeFileUtil::Touch(file_name,
141 new_accessed, new_modified));
143 ASSERT_TRUE(base::GetFileInfo(file_name, &info));
144 EXPECT_EQ(new_accessed, info.last_accessed);
145 EXPECT_EQ(new_modified, info.last_modified);
148 TEST_F(NativeFileUtilTest, CreateFileEnumerator) {
149 base::FilePath path_1 = Path("dir1");
150 base::FilePath path_2 = Path("file1");
151 base::FilePath path_11 = Path("dir1").AppendASCII("file11");
152 base::FilePath path_12 = Path("dir1").AppendASCII("dir12");
153 base::FilePath path_121 =
154 Path("dir1").AppendASCII("dir12").AppendASCII("file121");
155 ASSERT_EQ(base::File::FILE_OK,
156 NativeFileUtil::CreateDirectory(path_1, false, false));
157 bool created = false;
158 ASSERT_EQ(base::File::FILE_OK,
159 NativeFileUtil::EnsureFileExists(path_2, &created));
160 ASSERT_EQ(base::File::FILE_OK,
161 NativeFileUtil::EnsureFileExists(path_11, &created));
162 ASSERT_EQ(base::File::FILE_OK,
163 NativeFileUtil::CreateDirectory(path_12, false, false));
164 ASSERT_EQ(base::File::FILE_OK,
165 NativeFileUtil::EnsureFileExists(path_121, &created));
168 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator =
169 NativeFileUtil::CreateFileEnumerator(Path(), false);
170 std::set<base::FilePath> set;
171 set.insert(path_1);
172 set.insert(path_2);
173 for (base::FilePath path = enumerator->Next(); !path.empty();
174 path = enumerator->Next())
175 EXPECT_EQ(1U, set.erase(path));
176 EXPECT_TRUE(set.empty());
180 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator =
181 NativeFileUtil::CreateFileEnumerator(Path(), true);
182 std::set<base::FilePath> set;
183 set.insert(path_1);
184 set.insert(path_2);
185 set.insert(path_11);
186 set.insert(path_12);
187 set.insert(path_121);
188 for (base::FilePath path = enumerator->Next(); !path.empty();
189 path = enumerator->Next())
190 EXPECT_EQ(1U, set.erase(path));
191 EXPECT_TRUE(set.empty());
195 TEST_F(NativeFileUtilTest, Truncate) {
196 base::FilePath file_name = Path("truncated");
197 bool created = false;
198 ASSERT_EQ(base::File::FILE_OK,
199 NativeFileUtil::EnsureFileExists(file_name, &created));
200 ASSERT_TRUE(created);
202 ASSERT_EQ(base::File::FILE_OK,
203 NativeFileUtil::Truncate(file_name, 1020));
205 EXPECT_TRUE(FileExists(file_name));
206 EXPECT_EQ(1020, GetSize(file_name));
209 TEST_F(NativeFileUtilTest, CopyFile) {
210 base::FilePath from_file = Path("fromfile");
211 base::FilePath to_file1 = Path("tofile1");
212 base::FilePath to_file2 = Path("tofile2");
213 const NativeFileUtil::CopyOrMoveMode nosync = NativeFileUtil::COPY_NOSYNC;
214 const NativeFileUtil::CopyOrMoveMode sync = NativeFileUtil::COPY_SYNC;
215 bool created = false;
216 ASSERT_EQ(base::File::FILE_OK,
217 NativeFileUtil::EnsureFileExists(from_file, &created));
218 ASSERT_TRUE(created);
220 ASSERT_EQ(base::File::FILE_OK,
221 NativeFileUtil::Truncate(from_file, 1020));
223 EXPECT_TRUE(FileExists(from_file));
224 EXPECT_EQ(1020, GetSize(from_file));
226 ASSERT_EQ(base::File::FILE_OK,
227 NativeFileUtil::CopyOrMoveFile(
228 from_file, to_file1, FileSystemOperation::OPTION_NONE, nosync));
230 ASSERT_EQ(base::File::FILE_OK,
231 NativeFileUtil::CopyOrMoveFile(
232 from_file, to_file2, FileSystemOperation::OPTION_NONE, sync));
234 EXPECT_TRUE(FileExists(from_file));
235 EXPECT_EQ(1020, GetSize(from_file));
236 EXPECT_TRUE(FileExists(to_file1));
237 EXPECT_EQ(1020, GetSize(to_file1));
238 EXPECT_TRUE(FileExists(to_file2));
239 EXPECT_EQ(1020, GetSize(to_file2));
241 base::FilePath dir = Path("dir");
242 ASSERT_EQ(base::File::FILE_OK,
243 NativeFileUtil::CreateDirectory(dir, false, false));
244 ASSERT_TRUE(base::DirectoryExists(dir));
245 base::FilePath to_dir_file = dir.AppendASCII("file");
246 ASSERT_EQ(base::File::FILE_OK,
247 NativeFileUtil::CopyOrMoveFile(
248 from_file, to_dir_file,
249 FileSystemOperation::OPTION_NONE, nosync));
250 EXPECT_TRUE(FileExists(to_dir_file));
251 EXPECT_EQ(1020, GetSize(to_dir_file));
253 // Following tests are error checking.
254 // Source doesn't exist.
255 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
256 NativeFileUtil::CopyOrMoveFile(
257 Path("nonexists"), Path("file"),
258 FileSystemOperation::OPTION_NONE, nosync));
260 // Source is not a file.
261 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_FILE,
262 NativeFileUtil::CopyOrMoveFile(
263 dir, Path("file"), FileSystemOperation::OPTION_NONE, nosync));
264 // Destination is not a file.
265 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION,
266 NativeFileUtil::CopyOrMoveFile(
267 from_file, dir, FileSystemOperation::OPTION_NONE, nosync));
268 // Destination's parent doesn't exist.
269 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
270 NativeFileUtil::CopyOrMoveFile(
271 from_file, Path("nodir").AppendASCII("file"),
272 FileSystemOperation::OPTION_NONE, nosync));
273 // Destination's parent is a file.
274 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
275 NativeFileUtil::CopyOrMoveFile(
276 from_file, Path("tofile1").AppendASCII("file"),
277 FileSystemOperation::OPTION_NONE, nosync));
280 TEST_F(NativeFileUtilTest, MoveFile) {
281 base::FilePath from_file = Path("fromfile");
282 base::FilePath to_file = Path("tofile");
283 const NativeFileUtil::CopyOrMoveMode move = NativeFileUtil::MOVE;
284 bool created = false;
285 ASSERT_EQ(base::File::FILE_OK,
286 NativeFileUtil::EnsureFileExists(from_file, &created));
287 ASSERT_TRUE(created);
289 ASSERT_EQ(base::File::FILE_OK, NativeFileUtil::Truncate(from_file, 1020));
291 EXPECT_TRUE(FileExists(from_file));
292 EXPECT_EQ(1020, GetSize(from_file));
294 ASSERT_EQ(base::File::FILE_OK,
295 NativeFileUtil::CopyOrMoveFile(
296 from_file, to_file, FileSystemOperation::OPTION_NONE, move));
298 EXPECT_FALSE(FileExists(from_file));
299 EXPECT_TRUE(FileExists(to_file));
300 EXPECT_EQ(1020, GetSize(to_file));
302 ASSERT_EQ(base::File::FILE_OK,
303 NativeFileUtil::EnsureFileExists(from_file, &created));
304 ASSERT_TRUE(FileExists(from_file));
305 ASSERT_EQ(base::File::FILE_OK, NativeFileUtil::Truncate(from_file, 1020));
307 base::FilePath dir = Path("dir");
308 ASSERT_EQ(base::File::FILE_OK,
309 NativeFileUtil::CreateDirectory(dir, false, false));
310 ASSERT_TRUE(base::DirectoryExists(dir));
311 base::FilePath to_dir_file = dir.AppendASCII("file");
312 ASSERT_EQ(base::File::FILE_OK,
313 NativeFileUtil::CopyOrMoveFile(
314 from_file, to_dir_file,
315 FileSystemOperation::OPTION_NONE, move));
316 EXPECT_FALSE(FileExists(from_file));
317 EXPECT_TRUE(FileExists(to_dir_file));
318 EXPECT_EQ(1020, GetSize(to_dir_file));
320 // Following is error checking.
321 // Source doesn't exist.
322 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
323 NativeFileUtil::CopyOrMoveFile(
324 Path("nonexists"), Path("file"),
325 FileSystemOperation::OPTION_NONE, move));
327 // Source is not a file.
328 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_FILE,
329 NativeFileUtil::CopyOrMoveFile(
330 dir, Path("file"), FileSystemOperation::OPTION_NONE, move));
331 ASSERT_EQ(base::File::FILE_OK,
332 NativeFileUtil::EnsureFileExists(from_file, &created));
333 ASSERT_TRUE(FileExists(from_file));
334 // Destination is not a file.
335 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION,
336 NativeFileUtil::CopyOrMoveFile(
337 from_file, dir, FileSystemOperation::OPTION_NONE, move));
339 ASSERT_EQ(base::File::FILE_OK,
340 NativeFileUtil::EnsureFileExists(from_file, &created));
341 ASSERT_TRUE(FileExists(from_file));
342 // Destination's parent doesn't exist.
343 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
344 NativeFileUtil::CopyOrMoveFile(
345 from_file, Path("nodir").AppendASCII("file"),
346 FileSystemOperation::OPTION_NONE, move));
347 // Destination's parent is a file.
348 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
349 NativeFileUtil::CopyOrMoveFile(
350 from_file, Path("tofile1").AppendASCII("file"),
351 FileSystemOperation::OPTION_NONE, move));
354 TEST_F(NativeFileUtilTest, PreserveLastModified) {
355 base::FilePath from_file = Path("fromfile");
356 base::FilePath to_file1 = Path("tofile1");
357 base::FilePath to_file2 = Path("tofile2");
358 base::FilePath to_file3 = Path("tofile3");
359 bool created = false;
360 ASSERT_EQ(base::File::FILE_OK,
361 NativeFileUtil::EnsureFileExists(from_file, &created));
362 ASSERT_TRUE(created);
363 EXPECT_TRUE(FileExists(from_file));
365 base::File::Info file_info1;
366 ASSERT_EQ(base::File::FILE_OK,
367 NativeFileUtil::GetFileInfo(from_file, &file_info1));
369 // Test for copy (nosync).
370 ASSERT_EQ(base::File::FILE_OK,
371 NativeFileUtil::CopyOrMoveFile(
372 from_file, to_file1,
373 FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED,
374 NativeFileUtil::COPY_NOSYNC));
376 base::File::Info file_info2;
377 ASSERT_TRUE(FileExists(to_file1));
378 ASSERT_EQ(base::File::FILE_OK,
379 NativeFileUtil::GetFileInfo(to_file1, &file_info2));
380 EXPECT_EQ(file_info1.last_modified, file_info2.last_modified);
382 // Test for copy (sync).
383 ASSERT_EQ(base::File::FILE_OK,
384 NativeFileUtil::CopyOrMoveFile(
385 from_file, to_file2,
386 FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED,
387 NativeFileUtil::COPY_SYNC));
389 ASSERT_TRUE(FileExists(to_file2));
390 ASSERT_EQ(base::File::FILE_OK,
391 NativeFileUtil::GetFileInfo(to_file1, &file_info2));
392 EXPECT_EQ(file_info1.last_modified, file_info2.last_modified);
394 // Test for move.
395 ASSERT_EQ(base::File::FILE_OK,
396 NativeFileUtil::CopyOrMoveFile(
397 from_file, to_file3,
398 FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED,
399 NativeFileUtil::MOVE));
401 ASSERT_TRUE(FileExists(to_file3));
402 ASSERT_EQ(base::File::FILE_OK,
403 NativeFileUtil::GetFileInfo(to_file2, &file_info2));
404 EXPECT_EQ(file_info1.last_modified, file_info2.last_modified);
407 } // namespace content