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.
7 #include "base/file_util.h"
8 #include "base/files/file.h"
9 #include "base/files/file_path.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "webkit/browser/fileapi/native_file_util.h"
14 using storage::FileSystemFileUtil
;
15 using storage::FileSystemOperation
;
16 using storage::NativeFileUtil
;
20 class NativeFileUtilTest
: public testing::Test
{
22 NativeFileUtilTest() {}
24 virtual void SetUp() {
25 ASSERT_TRUE(data_dir_
.CreateUniqueTempDir());
29 base::FilePath
Path() {
30 return data_dir_
.path();
33 base::FilePath
Path(const char* file_name
) {
34 return data_dir_
.path().AppendASCII(file_name
);
37 bool FileExists(const base::FilePath
& path
) {
38 return base::PathExists(path
) &&
39 !base::DirectoryExists(path
);
42 int64
GetSize(const base::FilePath
& path
) {
43 base::File::Info info
;
44 base::GetFileInfo(path
, &info
);
49 base::ScopedTempDir data_dir_
;
51 DISALLOW_COPY_AND_ASSIGN(NativeFileUtilTest
);
54 TEST_F(NativeFileUtilTest
, CreateCloseAndDeleteFile
) {
55 base::FilePath file_name
= Path("test_file");
56 int flags
= base::File::FLAG_WRITE
| base::File::FLAG_ASYNC
;
58 NativeFileUtil::CreateOrOpen(file_name
, base::File::FLAG_CREATE
| flags
);
59 ASSERT_TRUE(file
.IsValid());
60 ASSERT_TRUE(file
.created());
62 EXPECT_TRUE(base::PathExists(file_name
));
63 EXPECT_TRUE(NativeFileUtil::PathExists(file_name
));
64 EXPECT_EQ(0, GetSize(file_name
));
67 file
= NativeFileUtil::CreateOrOpen(file_name
, base::File::FLAG_OPEN
| flags
);
68 ASSERT_TRUE(file
.IsValid());
69 ASSERT_FALSE(file
.created());
72 ASSERT_EQ(base::File::FILE_OK
,
73 NativeFileUtil::DeleteFile(file_name
));
74 EXPECT_FALSE(base::PathExists(file_name
));
75 EXPECT_FALSE(NativeFileUtil::PathExists(file_name
));
78 TEST_F(NativeFileUtilTest
, EnsureFileExists
) {
79 base::FilePath file_name
= Path("foobar");
81 ASSERT_EQ(base::File::FILE_OK
,
82 NativeFileUtil::EnsureFileExists(file_name
, &created
));
85 EXPECT_TRUE(FileExists(file_name
));
86 EXPECT_EQ(0, GetSize(file_name
));
88 ASSERT_EQ(base::File::FILE_OK
,
89 NativeFileUtil::EnsureFileExists(file_name
, &created
));
90 EXPECT_FALSE(created
);
93 TEST_F(NativeFileUtilTest
, CreateAndDeleteDirectory
) {
94 base::FilePath dir_name
= Path("test_dir");
95 ASSERT_EQ(base::File::FILE_OK
,
96 NativeFileUtil::CreateDirectory(dir_name
,
97 false /* exclusive */,
98 false /* recursive */));
100 EXPECT_TRUE(NativeFileUtil::DirectoryExists(dir_name
));
101 EXPECT_TRUE(base::DirectoryExists(dir_name
));
103 ASSERT_EQ(base::File::FILE_ERROR_EXISTS
,
104 NativeFileUtil::CreateDirectory(dir_name
,
105 true /* exclusive */,
106 false /* recursive */));
108 ASSERT_EQ(base::File::FILE_OK
,
109 NativeFileUtil::DeleteDirectory(dir_name
));
110 EXPECT_FALSE(base::DirectoryExists(dir_name
));
111 EXPECT_FALSE(NativeFileUtil::DirectoryExists(dir_name
));
114 TEST_F(NativeFileUtilTest
, TouchFileAndGetFileInfo
) {
115 base::FilePath file_name
= Path("test_file");
116 base::File::Info native_info
;
117 ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
118 NativeFileUtil::GetFileInfo(file_name
, &native_info
));
120 bool created
= false;
121 ASSERT_EQ(base::File::FILE_OK
,
122 NativeFileUtil::EnsureFileExists(file_name
, &created
));
123 ASSERT_TRUE(created
);
125 base::File::Info info
;
126 ASSERT_TRUE(base::GetFileInfo(file_name
, &info
));
127 ASSERT_EQ(base::File::FILE_OK
,
128 NativeFileUtil::GetFileInfo(file_name
, &native_info
));
129 ASSERT_EQ(info
.size
, native_info
.size
);
130 ASSERT_EQ(info
.is_directory
, native_info
.is_directory
);
131 ASSERT_EQ(info
.is_symbolic_link
, native_info
.is_symbolic_link
);
132 ASSERT_EQ(info
.last_modified
, native_info
.last_modified
);
133 ASSERT_EQ(info
.last_accessed
, native_info
.last_accessed
);
134 ASSERT_EQ(info
.creation_time
, native_info
.creation_time
);
136 const base::Time new_accessed
=
137 info
.last_accessed
+ base::TimeDelta::FromHours(10);
138 const base::Time new_modified
=
139 info
.last_modified
+ base::TimeDelta::FromHours(5);
141 EXPECT_EQ(base::File::FILE_OK
,
142 NativeFileUtil::Touch(file_name
,
143 new_accessed
, new_modified
));
145 ASSERT_TRUE(base::GetFileInfo(file_name
, &info
));
146 EXPECT_EQ(new_accessed
, info
.last_accessed
);
147 EXPECT_EQ(new_modified
, info
.last_modified
);
150 TEST_F(NativeFileUtilTest
, CreateFileEnumerator
) {
151 base::FilePath path_1
= Path("dir1");
152 base::FilePath path_2
= Path("file1");
153 base::FilePath path_11
= Path("dir1").AppendASCII("file11");
154 base::FilePath path_12
= Path("dir1").AppendASCII("dir12");
155 base::FilePath path_121
=
156 Path("dir1").AppendASCII("dir12").AppendASCII("file121");
157 ASSERT_EQ(base::File::FILE_OK
,
158 NativeFileUtil::CreateDirectory(path_1
, false, false));
159 bool created
= false;
160 ASSERT_EQ(base::File::FILE_OK
,
161 NativeFileUtil::EnsureFileExists(path_2
, &created
));
162 ASSERT_EQ(base::File::FILE_OK
,
163 NativeFileUtil::EnsureFileExists(path_11
, &created
));
164 ASSERT_EQ(base::File::FILE_OK
,
165 NativeFileUtil::CreateDirectory(path_12
, false, false));
166 ASSERT_EQ(base::File::FILE_OK
,
167 NativeFileUtil::EnsureFileExists(path_121
, &created
));
170 scoped_ptr
<FileSystemFileUtil::AbstractFileEnumerator
> enumerator
=
171 NativeFileUtil::CreateFileEnumerator(Path(), false);
172 std::set
<base::FilePath
> set
;
175 for (base::FilePath path
= enumerator
->Next(); !path
.empty();
176 path
= enumerator
->Next())
177 EXPECT_EQ(1U, set
.erase(path
));
178 EXPECT_TRUE(set
.empty());
182 scoped_ptr
<FileSystemFileUtil::AbstractFileEnumerator
> enumerator
=
183 NativeFileUtil::CreateFileEnumerator(Path(), true);
184 std::set
<base::FilePath
> set
;
189 set
.insert(path_121
);
190 for (base::FilePath path
= enumerator
->Next(); !path
.empty();
191 path
= enumerator
->Next())
192 EXPECT_EQ(1U, set
.erase(path
));
193 EXPECT_TRUE(set
.empty());
197 TEST_F(NativeFileUtilTest
, Truncate
) {
198 base::FilePath file_name
= Path("truncated");
199 bool created
= false;
200 ASSERT_EQ(base::File::FILE_OK
,
201 NativeFileUtil::EnsureFileExists(file_name
, &created
));
202 ASSERT_TRUE(created
);
204 ASSERT_EQ(base::File::FILE_OK
,
205 NativeFileUtil::Truncate(file_name
, 1020));
207 EXPECT_TRUE(FileExists(file_name
));
208 EXPECT_EQ(1020, GetSize(file_name
));
211 TEST_F(NativeFileUtilTest
, CopyFile
) {
212 base::FilePath from_file
= Path("fromfile");
213 base::FilePath to_file1
= Path("tofile1");
214 base::FilePath to_file2
= Path("tofile2");
215 const NativeFileUtil::CopyOrMoveMode nosync
= NativeFileUtil::COPY_NOSYNC
;
216 const NativeFileUtil::CopyOrMoveMode sync
= NativeFileUtil::COPY_SYNC
;
217 bool created
= false;
218 ASSERT_EQ(base::File::FILE_OK
,
219 NativeFileUtil::EnsureFileExists(from_file
, &created
));
220 ASSERT_TRUE(created
);
222 ASSERT_EQ(base::File::FILE_OK
,
223 NativeFileUtil::Truncate(from_file
, 1020));
225 EXPECT_TRUE(FileExists(from_file
));
226 EXPECT_EQ(1020, GetSize(from_file
));
228 ASSERT_EQ(base::File::FILE_OK
,
229 NativeFileUtil::CopyOrMoveFile(
230 from_file
, to_file1
, FileSystemOperation::OPTION_NONE
, nosync
));
232 ASSERT_EQ(base::File::FILE_OK
,
233 NativeFileUtil::CopyOrMoveFile(
234 from_file
, to_file2
, FileSystemOperation::OPTION_NONE
, sync
));
236 EXPECT_TRUE(FileExists(from_file
));
237 EXPECT_EQ(1020, GetSize(from_file
));
238 EXPECT_TRUE(FileExists(to_file1
));
239 EXPECT_EQ(1020, GetSize(to_file1
));
240 EXPECT_TRUE(FileExists(to_file2
));
241 EXPECT_EQ(1020, GetSize(to_file2
));
243 base::FilePath dir
= Path("dir");
244 ASSERT_EQ(base::File::FILE_OK
,
245 NativeFileUtil::CreateDirectory(dir
, false, false));
246 ASSERT_TRUE(base::DirectoryExists(dir
));
247 base::FilePath to_dir_file
= dir
.AppendASCII("file");
248 ASSERT_EQ(base::File::FILE_OK
,
249 NativeFileUtil::CopyOrMoveFile(
250 from_file
, to_dir_file
,
251 FileSystemOperation::OPTION_NONE
, nosync
));
252 EXPECT_TRUE(FileExists(to_dir_file
));
253 EXPECT_EQ(1020, GetSize(to_dir_file
));
255 // Following tests are error checking.
256 // Source doesn't exist.
257 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
258 NativeFileUtil::CopyOrMoveFile(
259 Path("nonexists"), Path("file"),
260 FileSystemOperation::OPTION_NONE
, nosync
));
262 // Source is not a file.
263 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_FILE
,
264 NativeFileUtil::CopyOrMoveFile(
265 dir
, Path("file"), FileSystemOperation::OPTION_NONE
, nosync
));
266 // Destination is not a file.
267 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION
,
268 NativeFileUtil::CopyOrMoveFile(
269 from_file
, dir
, FileSystemOperation::OPTION_NONE
, nosync
));
270 // Destination's parent doesn't exist.
271 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
272 NativeFileUtil::CopyOrMoveFile(
273 from_file
, Path("nodir").AppendASCII("file"),
274 FileSystemOperation::OPTION_NONE
, nosync
));
275 // Destination's parent is a file.
276 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
277 NativeFileUtil::CopyOrMoveFile(
278 from_file
, Path("tofile1").AppendASCII("file"),
279 FileSystemOperation::OPTION_NONE
, nosync
));
282 TEST_F(NativeFileUtilTest
, MoveFile
) {
283 base::FilePath from_file
= Path("fromfile");
284 base::FilePath to_file
= Path("tofile");
285 const NativeFileUtil::CopyOrMoveMode move
= NativeFileUtil::MOVE
;
286 bool created
= false;
287 ASSERT_EQ(base::File::FILE_OK
,
288 NativeFileUtil::EnsureFileExists(from_file
, &created
));
289 ASSERT_TRUE(created
);
291 ASSERT_EQ(base::File::FILE_OK
, NativeFileUtil::Truncate(from_file
, 1020));
293 EXPECT_TRUE(FileExists(from_file
));
294 EXPECT_EQ(1020, GetSize(from_file
));
296 ASSERT_EQ(base::File::FILE_OK
,
297 NativeFileUtil::CopyOrMoveFile(
298 from_file
, to_file
, FileSystemOperation::OPTION_NONE
, move
));
300 EXPECT_FALSE(FileExists(from_file
));
301 EXPECT_TRUE(FileExists(to_file
));
302 EXPECT_EQ(1020, GetSize(to_file
));
304 ASSERT_EQ(base::File::FILE_OK
,
305 NativeFileUtil::EnsureFileExists(from_file
, &created
));
306 ASSERT_TRUE(FileExists(from_file
));
307 ASSERT_EQ(base::File::FILE_OK
, NativeFileUtil::Truncate(from_file
, 1020));
309 base::FilePath dir
= Path("dir");
310 ASSERT_EQ(base::File::FILE_OK
,
311 NativeFileUtil::CreateDirectory(dir
, false, false));
312 ASSERT_TRUE(base::DirectoryExists(dir
));
313 base::FilePath to_dir_file
= dir
.AppendASCII("file");
314 ASSERT_EQ(base::File::FILE_OK
,
315 NativeFileUtil::CopyOrMoveFile(
316 from_file
, to_dir_file
,
317 FileSystemOperation::OPTION_NONE
, move
));
318 EXPECT_FALSE(FileExists(from_file
));
319 EXPECT_TRUE(FileExists(to_dir_file
));
320 EXPECT_EQ(1020, GetSize(to_dir_file
));
322 // Following is error checking.
323 // Source doesn't exist.
324 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
325 NativeFileUtil::CopyOrMoveFile(
326 Path("nonexists"), Path("file"),
327 FileSystemOperation::OPTION_NONE
, move
));
329 // Source is not a file.
330 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_FILE
,
331 NativeFileUtil::CopyOrMoveFile(
332 dir
, Path("file"), FileSystemOperation::OPTION_NONE
, move
));
333 ASSERT_EQ(base::File::FILE_OK
,
334 NativeFileUtil::EnsureFileExists(from_file
, &created
));
335 ASSERT_TRUE(FileExists(from_file
));
336 // Destination is not a file.
337 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION
,
338 NativeFileUtil::CopyOrMoveFile(
339 from_file
, dir
, FileSystemOperation::OPTION_NONE
, move
));
341 ASSERT_EQ(base::File::FILE_OK
,
342 NativeFileUtil::EnsureFileExists(from_file
, &created
));
343 ASSERT_TRUE(FileExists(from_file
));
344 // Destination's parent doesn't exist.
345 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
346 NativeFileUtil::CopyOrMoveFile(
347 from_file
, Path("nodir").AppendASCII("file"),
348 FileSystemOperation::OPTION_NONE
, move
));
349 // Destination's parent is a file.
350 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
,
351 NativeFileUtil::CopyOrMoveFile(
352 from_file
, Path("tofile1").AppendASCII("file"),
353 FileSystemOperation::OPTION_NONE
, move
));
356 TEST_F(NativeFileUtilTest
, PreserveLastModified
) {
357 base::FilePath from_file
= Path("fromfile");
358 base::FilePath to_file1
= Path("tofile1");
359 base::FilePath to_file2
= Path("tofile2");
360 base::FilePath to_file3
= Path("tofile3");
361 bool created
= false;
362 ASSERT_EQ(base::File::FILE_OK
,
363 NativeFileUtil::EnsureFileExists(from_file
, &created
));
364 ASSERT_TRUE(created
);
365 EXPECT_TRUE(FileExists(from_file
));
367 base::File::Info file_info1
;
368 ASSERT_EQ(base::File::FILE_OK
,
369 NativeFileUtil::GetFileInfo(from_file
, &file_info1
));
371 // Test for copy (nosync).
372 ASSERT_EQ(base::File::FILE_OK
,
373 NativeFileUtil::CopyOrMoveFile(
375 FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED
,
376 NativeFileUtil::COPY_NOSYNC
));
378 base::File::Info file_info2
;
379 ASSERT_TRUE(FileExists(to_file1
));
380 ASSERT_EQ(base::File::FILE_OK
,
381 NativeFileUtil::GetFileInfo(to_file1
, &file_info2
));
382 EXPECT_EQ(file_info1
.last_modified
, file_info2
.last_modified
);
384 // Test for copy (sync).
385 ASSERT_EQ(base::File::FILE_OK
,
386 NativeFileUtil::CopyOrMoveFile(
388 FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED
,
389 NativeFileUtil::COPY_SYNC
));
391 ASSERT_TRUE(FileExists(to_file2
));
392 ASSERT_EQ(base::File::FILE_OK
,
393 NativeFileUtil::GetFileInfo(to_file1
, &file_info2
));
394 EXPECT_EQ(file_info1
.last_modified
, file_info2
.last_modified
);
397 ASSERT_EQ(base::File::FILE_OK
,
398 NativeFileUtil::CopyOrMoveFile(
400 FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED
,
401 NativeFileUtil::MOVE
));
403 ASSERT_TRUE(FileExists(to_file3
));
404 ASSERT_EQ(base::File::FILE_OK
,
405 NativeFileUtil::GetFileInfo(to_file2
, &file_info2
));
406 EXPECT_EQ(file_info1
.last_modified
, file_info2
.last_modified
);
409 } // namespace content