OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include <stdint.h> | |
6 | |
7 #include <memory> | |
8 #include <set> | |
9 | |
10 #include "base/files/file.h" | |
11 #include "base/files/file_path.h" | |
12 #include "base/files/file_util.h" | |
13 #include "base/files/scoped_temp_dir.h" | |
14 #include "base/macros.h" | |
15 #include "storage/browser/fileapi/native_file_util.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 | |
18 using storage::FileSystemFileUtil; | |
19 using storage::FileSystemOperation; | |
20 using storage::NativeFileUtil; | |
21 | |
22 namespace content { | |
23 | |
24 class NativeFileUtilTest : public testing::Test { | |
25 public: | |
26 NativeFileUtilTest() {} | |
27 | |
28 void SetUp() override { ASSERT_TRUE(data_dir_.CreateUniqueTempDir()); } | |
29 | |
30 protected: | |
31 base::FilePath Path() { return data_dir_.GetPath(); } | |
32 | |
33 base::FilePath Path(const char* file_name) { | |
34 return data_dir_.GetPath().AppendASCII(file_name); | |
35 } | |
36 | |
37 bool FileExists(const base::FilePath& path) { | |
38 return base::PathExists(path) && | |
39 !base::DirectoryExists(path); | |
40 } | |
41 | |
42 int64_t GetSize(const base::FilePath& path) { | |
43 base::File::Info info; | |
44 base::GetFileInfo(path, &info); | |
45 return info.size; | |
46 } | |
47 | |
48 private: | |
49 base::ScopedTempDir data_dir_; | |
50 | |
51 DISALLOW_COPY_AND_ASSIGN(NativeFileUtilTest); | |
52 }; | |
53 | |
54 TEST_F(NativeFileUtilTest, CreateCloseAndDeleteFile) { | |
55 base::FilePath file_name = Path("test_file"); | |
56 int flags = base::File::FLAG_WRITE | base::File::FLAG_ASYNC; | |
57 base::File file = | |
58 NativeFileUtil::CreateOrOpen(file_name, base::File::FLAG_CREATE | flags); | |
59 ASSERT_TRUE(file.IsValid()); | |
60 ASSERT_TRUE(file.created()); | |
61 | |
62 EXPECT_TRUE(base::PathExists(file_name)); | |
63 EXPECT_TRUE(NativeFileUtil::PathExists(file_name)); | |
64 EXPECT_EQ(0, GetSize(file_name)); | |
65 file.Close(); | |
66 | |
67 file = NativeFileUtil::CreateOrOpen(file_name, base::File::FLAG_OPEN | flags); | |
68 ASSERT_TRUE(file.IsValid()); | |
69 ASSERT_FALSE(file.created()); | |
70 file.Close(); | |
71 | |
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)); | |
76 } | |
77 | |
78 TEST_F(NativeFileUtilTest, EnsureFileExists) { | |
79 base::FilePath file_name = Path("foobar"); | |
80 bool created = false; | |
81 ASSERT_EQ(base::File::FILE_OK, | |
82 NativeFileUtil::EnsureFileExists(file_name, &created)); | |
83 ASSERT_TRUE(created); | |
84 | |
85 EXPECT_TRUE(FileExists(file_name)); | |
86 EXPECT_EQ(0, GetSize(file_name)); | |
87 | |
88 ASSERT_EQ(base::File::FILE_OK, | |
89 NativeFileUtil::EnsureFileExists(file_name, &created)); | |
90 EXPECT_FALSE(created); | |
91 } | |
92 | |
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 */)); | |
99 | |
100 EXPECT_TRUE(NativeFileUtil::DirectoryExists(dir_name)); | |
101 EXPECT_TRUE(base::DirectoryExists(dir_name)); | |
102 | |
103 ASSERT_EQ(base::File::FILE_ERROR_EXISTS, | |
104 NativeFileUtil::CreateDirectory(dir_name, | |
105 true /* exclusive */, | |
106 false /* recursive */)); | |
107 | |
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)); | |
112 } | |
113 | |
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)); | |
119 | |
120 bool created = false; | |
121 ASSERT_EQ(base::File::FILE_OK, | |
122 NativeFileUtil::EnsureFileExists(file_name, &created)); | |
123 ASSERT_TRUE(created); | |
124 | |
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); | |
135 | |
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); | |
140 | |
141 EXPECT_EQ(base::File::FILE_OK, | |
142 NativeFileUtil::Touch(file_name, | |
143 new_accessed, new_modified)); | |
144 | |
145 ASSERT_TRUE(base::GetFileInfo(file_name, &info)); | |
146 EXPECT_EQ(new_accessed, info.last_accessed); | |
147 EXPECT_EQ(new_modified, info.last_modified); | |
148 } | |
149 | |
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)); | |
168 | |
169 { | |
170 std::unique_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator = | |
171 NativeFileUtil::CreateFileEnumerator(Path(), false); | |
172 std::set<base::FilePath> set; | |
173 set.insert(path_1); | |
174 set.insert(path_2); | |
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()); | |
179 } | |
180 | |
181 { | |
182 std::unique_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator = | |
183 NativeFileUtil::CreateFileEnumerator(Path(), true); | |
184 std::set<base::FilePath> set; | |
185 set.insert(path_1); | |
186 set.insert(path_2); | |
187 set.insert(path_11); | |
188 set.insert(path_12); | |
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()); | |
194 } | |
195 } | |
196 | |
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); | |
203 | |
204 ASSERT_EQ(base::File::FILE_OK, | |
205 NativeFileUtil::Truncate(file_name, 1020)); | |
206 | |
207 EXPECT_TRUE(FileExists(file_name)); | |
208 EXPECT_EQ(1020, GetSize(file_name)); | |
209 } | |
210 | |
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); | |
221 | |
222 ASSERT_EQ(base::File::FILE_OK, | |
223 NativeFileUtil::Truncate(from_file, 1020)); | |
224 | |
225 EXPECT_TRUE(FileExists(from_file)); | |
226 EXPECT_EQ(1020, GetSize(from_file)); | |
227 | |
228 ASSERT_EQ(base::File::FILE_OK, | |
229 NativeFileUtil::CopyOrMoveFile( | |
230 from_file, to_file1, FileSystemOperation::OPTION_NONE, nosync)); | |
231 | |
232 ASSERT_EQ(base::File::FILE_OK, | |
233 NativeFileUtil::CopyOrMoveFile( | |
234 from_file, to_file2, FileSystemOperation::OPTION_NONE, sync)); | |
235 | |
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)); | |
242 | |
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)); | |
254 | |
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)); | |
261 | |
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)); | |
280 } | |
281 | |
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); | |
290 | |
291 ASSERT_EQ(base::File::FILE_OK, NativeFileUtil::Truncate(from_file, 1020)); | |
292 | |
293 EXPECT_TRUE(FileExists(from_file)); | |
294 EXPECT_EQ(1020, GetSize(from_file)); | |
295 | |
296 ASSERT_EQ(base::File::FILE_OK, | |
297 NativeFileUtil::CopyOrMoveFile( | |
298 from_file, to_file, FileSystemOperation::OPTION_NONE, move)); | |
299 | |
300 EXPECT_FALSE(FileExists(from_file)); | |
301 EXPECT_TRUE(FileExists(to_file)); | |
302 EXPECT_EQ(1020, GetSize(to_file)); | |
303 | |
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)); | |
308 | |
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)); | |
321 | |
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)); | |
328 | |
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)); | |
340 | |
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)); | |
354 } | |
355 | |
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)); | |
366 | |
367 base::File::Info file_info1; | |
368 ASSERT_EQ(base::File::FILE_OK, | |
369 NativeFileUtil::GetFileInfo(from_file, &file_info1)); | |
370 | |
371 // Test for copy (nosync). | |
372 ASSERT_EQ(base::File::FILE_OK, | |
373 NativeFileUtil::CopyOrMoveFile( | |
374 from_file, to_file1, | |
375 FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED, | |
376 NativeFileUtil::COPY_NOSYNC)); | |
377 | |
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); | |
383 | |
384 // Test for copy (sync). | |
385 ASSERT_EQ(base::File::FILE_OK, | |
386 NativeFileUtil::CopyOrMoveFile( | |
387 from_file, to_file2, | |
388 FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED, | |
389 NativeFileUtil::COPY_SYNC)); | |
390 | |
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); | |
395 | |
396 // Test for move. | |
397 ASSERT_EQ(base::File::FILE_OK, | |
398 NativeFileUtil::CopyOrMoveFile( | |
399 from_file, to_file3, | |
400 FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED, | |
401 NativeFileUtil::MOVE)); | |
402 | |
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); | |
407 } | |
408 | |
409 } // namespace content | |
OLD | NEW |