Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / base / files / file_unittest.cc
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 "base/files/file.h"
6 #include "base/files/file_util.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/time/time.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 using base::File;
13 using base::FilePath;
14
15 TEST(FileTest, Create) {
16   base::ScopedTempDir temp_dir;
17   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
18   FilePath file_path = temp_dir.path().AppendASCII("create_file_1");
19
20   {
21     // Don't create a File at all.
22     File file;
23     EXPECT_FALSE(file.IsValid());
24     EXPECT_EQ(base::File::FILE_ERROR_FAILED, file.error_details());
25
26     File file2(base::File::FILE_ERROR_TOO_MANY_OPENED);
27     EXPECT_FALSE(file2.IsValid());
28     EXPECT_EQ(base::File::FILE_ERROR_TOO_MANY_OPENED, file2.error_details());
29   }
30
31   {
32     // Open a file that doesn't exist.
33     File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
34     EXPECT_FALSE(file.IsValid());
35     EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, file.error_details());
36   }
37
38   {
39     // Open or create a file.
40     File file(file_path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ);
41     EXPECT_TRUE(file.IsValid());
42     EXPECT_TRUE(file.created());
43     EXPECT_EQ(base::File::FILE_OK, file.error_details());
44   }
45
46   {
47     // Open an existing file.
48     File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
49     EXPECT_TRUE(file.IsValid());
50     EXPECT_FALSE(file.created());
51     EXPECT_EQ(base::File::FILE_OK, file.error_details());
52
53     // This time verify closing the file.
54     file.Close();
55     EXPECT_FALSE(file.IsValid());
56   }
57
58   {
59     // Open an existing file through Initialize
60     File file;
61     file.Initialize(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
62     EXPECT_TRUE(file.IsValid());
63     EXPECT_FALSE(file.created());
64     EXPECT_EQ(base::File::FILE_OK, file.error_details());
65
66     // This time verify closing the file.
67     file.Close();
68     EXPECT_FALSE(file.IsValid());
69   }
70
71   {
72     // Create a file that exists.
73     File file(file_path, base::File::FLAG_CREATE | base::File::FLAG_READ);
74     EXPECT_FALSE(file.IsValid());
75     EXPECT_FALSE(file.created());
76     EXPECT_EQ(base::File::FILE_ERROR_EXISTS, file.error_details());
77   }
78
79   {
80     // Create or overwrite a file.
81     File file(file_path,
82               base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
83     EXPECT_TRUE(file.IsValid());
84     EXPECT_TRUE(file.created());
85     EXPECT_EQ(base::File::FILE_OK, file.error_details());
86   }
87
88   {
89     // Create a delete-on-close file.
90     file_path = temp_dir.path().AppendASCII("create_file_2");
91     File file(file_path,
92               base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ |
93                   base::File::FLAG_DELETE_ON_CLOSE);
94     EXPECT_TRUE(file.IsValid());
95     EXPECT_TRUE(file.created());
96     EXPECT_EQ(base::File::FILE_OK, file.error_details());
97   }
98
99   EXPECT_FALSE(base::PathExists(file_path));
100 }
101
102 TEST(FileTest, Async) {
103   base::ScopedTempDir temp_dir;
104   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
105   FilePath file_path = temp_dir.path().AppendASCII("create_file");
106
107   {
108     File file(file_path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_ASYNC);
109     EXPECT_TRUE(file.IsValid());
110     EXPECT_TRUE(file.async());
111   }
112
113   {
114     File file(file_path, base::File::FLAG_OPEN_ALWAYS);
115     EXPECT_TRUE(file.IsValid());
116     EXPECT_FALSE(file.async());
117   }
118 }
119
120 TEST(FileTest, DeleteOpenFile) {
121   base::ScopedTempDir temp_dir;
122   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
123   FilePath file_path = temp_dir.path().AppendASCII("create_file_1");
124
125   // Create a file.
126   File file(file_path,
127             base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ |
128                 base::File::FLAG_SHARE_DELETE);
129   EXPECT_TRUE(file.IsValid());
130   EXPECT_TRUE(file.created());
131   EXPECT_EQ(base::File::FILE_OK, file.error_details());
132
133   // Open an existing file and mark it as delete on close.
134   File same_file(file_path,
135                  base::File::FLAG_OPEN | base::File::FLAG_DELETE_ON_CLOSE |
136                      base::File::FLAG_READ);
137   EXPECT_TRUE(file.IsValid());
138   EXPECT_FALSE(same_file.created());
139   EXPECT_EQ(base::File::FILE_OK, same_file.error_details());
140
141   // Close both handles and check that the file is gone.
142   file.Close();
143   same_file.Close();
144   EXPECT_FALSE(base::PathExists(file_path));
145 }
146
147 TEST(FileTest, ReadWrite) {
148   base::ScopedTempDir temp_dir;
149   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
150   FilePath file_path = temp_dir.path().AppendASCII("read_write_file");
151   File file(file_path,
152             base::File::FLAG_CREATE | base::File::FLAG_READ |
153                 base::File::FLAG_WRITE);
154   ASSERT_TRUE(file.IsValid());
155
156   char data_to_write[] = "test";
157   const int kTestDataSize = 4;
158
159   // Write 0 bytes to the file.
160   int bytes_written = file.Write(0, data_to_write, 0);
161   EXPECT_EQ(0, bytes_written);
162
163   // Write "test" to the file.
164   bytes_written = file.Write(0, data_to_write, kTestDataSize);
165   EXPECT_EQ(kTestDataSize, bytes_written);
166
167   // Read from EOF.
168   char data_read_1[32];
169   int bytes_read = file.Read(kTestDataSize, data_read_1, kTestDataSize);
170   EXPECT_EQ(0, bytes_read);
171
172   // Read from somewhere in the middle of the file.
173   const int kPartialReadOffset = 1;
174   bytes_read = file.Read(kPartialReadOffset, data_read_1, kTestDataSize);
175   EXPECT_EQ(kTestDataSize - kPartialReadOffset, bytes_read);
176   for (int i = 0; i < bytes_read; i++)
177     EXPECT_EQ(data_to_write[i + kPartialReadOffset], data_read_1[i]);
178
179   // Read 0 bytes.
180   bytes_read = file.Read(0, data_read_1, 0);
181   EXPECT_EQ(0, bytes_read);
182
183   // Read the entire file.
184   bytes_read = file.Read(0, data_read_1, kTestDataSize);
185   EXPECT_EQ(kTestDataSize, bytes_read);
186   for (int i = 0; i < bytes_read; i++)
187     EXPECT_EQ(data_to_write[i], data_read_1[i]);
188
189   // Read again, but using the trivial native wrapper.
190   bytes_read = file.ReadNoBestEffort(0, data_read_1, kTestDataSize);
191   EXPECT_LE(bytes_read, kTestDataSize);
192   for (int i = 0; i < bytes_read; i++)
193     EXPECT_EQ(data_to_write[i], data_read_1[i]);
194
195   // Write past the end of the file.
196   const int kOffsetBeyondEndOfFile = 10;
197   const int kPartialWriteLength = 2;
198   bytes_written = file.Write(kOffsetBeyondEndOfFile,
199                              data_to_write, kPartialWriteLength);
200   EXPECT_EQ(kPartialWriteLength, bytes_written);
201
202   // Make sure the file was extended.
203   int64 file_size = 0;
204   EXPECT_TRUE(GetFileSize(file_path, &file_size));
205   EXPECT_EQ(kOffsetBeyondEndOfFile + kPartialWriteLength, file_size);
206
207   // Make sure the file was zero-padded.
208   char data_read_2[32];
209   bytes_read = file.Read(0, data_read_2, static_cast<int>(file_size));
210   EXPECT_EQ(file_size, bytes_read);
211   for (int i = 0; i < kTestDataSize; i++)
212     EXPECT_EQ(data_to_write[i], data_read_2[i]);
213   for (int i = kTestDataSize; i < kOffsetBeyondEndOfFile; i++)
214     EXPECT_EQ(0, data_read_2[i]);
215   for (int i = kOffsetBeyondEndOfFile; i < file_size; i++)
216     EXPECT_EQ(data_to_write[i - kOffsetBeyondEndOfFile], data_read_2[i]);
217 }
218
219 TEST(FileTest, Append) {
220   base::ScopedTempDir temp_dir;
221   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
222   FilePath file_path = temp_dir.path().AppendASCII("append_file");
223   File file(file_path, base::File::FLAG_CREATE | base::File::FLAG_APPEND);
224   ASSERT_TRUE(file.IsValid());
225
226   char data_to_write[] = "test";
227   const int kTestDataSize = 4;
228
229   // Write 0 bytes to the file.
230   int bytes_written = file.Write(0, data_to_write, 0);
231   EXPECT_EQ(0, bytes_written);
232
233   // Write "test" to the file.
234   bytes_written = file.Write(0, data_to_write, kTestDataSize);
235   EXPECT_EQ(kTestDataSize, bytes_written);
236
237   file.Close();
238   File file2(file_path,
239              base::File::FLAG_OPEN | base::File::FLAG_READ |
240                  base::File::FLAG_APPEND);
241   ASSERT_TRUE(file2.IsValid());
242
243   // Test passing the file around.
244   file = file2.Pass();
245   EXPECT_FALSE(file2.IsValid());
246   ASSERT_TRUE(file.IsValid());
247
248   char append_data_to_write[] = "78";
249   const int kAppendDataSize = 2;
250
251   // Append "78" to the file.
252   bytes_written = file.Write(0, append_data_to_write, kAppendDataSize);
253   EXPECT_EQ(kAppendDataSize, bytes_written);
254
255   // Read the entire file.
256   char data_read_1[32];
257   int bytes_read = file.Read(0, data_read_1,
258                              kTestDataSize + kAppendDataSize);
259   EXPECT_EQ(kTestDataSize + kAppendDataSize, bytes_read);
260   for (int i = 0; i < kTestDataSize; i++)
261     EXPECT_EQ(data_to_write[i], data_read_1[i]);
262   for (int i = 0; i < kAppendDataSize; i++)
263     EXPECT_EQ(append_data_to_write[i], data_read_1[kTestDataSize + i]);
264 }
265
266
267 TEST(FileTest, Length) {
268   base::ScopedTempDir temp_dir;
269   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
270   FilePath file_path = temp_dir.path().AppendASCII("truncate_file");
271   File file(file_path,
272             base::File::FLAG_CREATE | base::File::FLAG_READ |
273                 base::File::FLAG_WRITE);
274   ASSERT_TRUE(file.IsValid());
275   EXPECT_EQ(0, file.GetLength());
276
277   // Write "test" to the file.
278   char data_to_write[] = "test";
279   int kTestDataSize = 4;
280   int bytes_written = file.Write(0, data_to_write, kTestDataSize);
281   EXPECT_EQ(kTestDataSize, bytes_written);
282
283   // Extend the file.
284   const int kExtendedFileLength = 10;
285   int64 file_size = 0;
286   EXPECT_TRUE(file.SetLength(kExtendedFileLength));
287   EXPECT_EQ(kExtendedFileLength, file.GetLength());
288   EXPECT_TRUE(GetFileSize(file_path, &file_size));
289   EXPECT_EQ(kExtendedFileLength, file_size);
290
291   // Make sure the file was zero-padded.
292   char data_read[32];
293   int bytes_read = file.Read(0, data_read, static_cast<int>(file_size));
294   EXPECT_EQ(file_size, bytes_read);
295   for (int i = 0; i < kTestDataSize; i++)
296     EXPECT_EQ(data_to_write[i], data_read[i]);
297   for (int i = kTestDataSize; i < file_size; i++)
298     EXPECT_EQ(0, data_read[i]);
299
300   // Truncate the file.
301   const int kTruncatedFileLength = 2;
302   EXPECT_TRUE(file.SetLength(kTruncatedFileLength));
303   EXPECT_EQ(kTruncatedFileLength, file.GetLength());
304   EXPECT_TRUE(GetFileSize(file_path, &file_size));
305   EXPECT_EQ(kTruncatedFileLength, file_size);
306
307   // Make sure the file was truncated.
308   bytes_read = file.Read(0, data_read, kTestDataSize);
309   EXPECT_EQ(file_size, bytes_read);
310   for (int i = 0; i < file_size; i++)
311     EXPECT_EQ(data_to_write[i], data_read[i]);
312 }
313
314 // Flakily fails: http://crbug.com/86494
315 #if defined(OS_ANDROID)
316 TEST(FileTest, TouchGetInfo) {
317 #else
318 TEST(FileTest, DISABLED_TouchGetInfo) {
319 #endif
320   base::ScopedTempDir temp_dir;
321   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
322   File file(temp_dir.path().AppendASCII("touch_get_info_file"),
323             base::File::FLAG_CREATE | base::File::FLAG_WRITE |
324                 base::File::FLAG_WRITE_ATTRIBUTES);
325   ASSERT_TRUE(file.IsValid());
326
327   // Get info for a newly created file.
328   base::File::Info info;
329   EXPECT_TRUE(file.GetInfo(&info));
330
331   // Add 2 seconds to account for possible rounding errors on
332   // filesystems that use a 1s or 2s timestamp granularity.
333   base::Time now = base::Time::Now() + base::TimeDelta::FromSeconds(2);
334   EXPECT_EQ(0, info.size);
335   EXPECT_FALSE(info.is_directory);
336   EXPECT_FALSE(info.is_symbolic_link);
337   EXPECT_LE(info.last_accessed.ToInternalValue(), now.ToInternalValue());
338   EXPECT_LE(info.last_modified.ToInternalValue(), now.ToInternalValue());
339   EXPECT_LE(info.creation_time.ToInternalValue(), now.ToInternalValue());
340   base::Time creation_time = info.creation_time;
341
342   // Write "test" to the file.
343   char data[] = "test";
344   const int kTestDataSize = 4;
345   int bytes_written = file.Write(0, data, kTestDataSize);
346   EXPECT_EQ(kTestDataSize, bytes_written);
347
348   // Change the last_accessed and last_modified dates.
349   // It's best to add values that are multiples of 2 (in seconds)
350   // to the current last_accessed and last_modified times, because
351   // FATxx uses a 2s timestamp granularity.
352   base::Time new_last_accessed =
353       info.last_accessed + base::TimeDelta::FromSeconds(234);
354   base::Time new_last_modified =
355       info.last_modified + base::TimeDelta::FromMinutes(567);
356
357   EXPECT_TRUE(file.SetTimes(new_last_accessed, new_last_modified));
358
359   // Make sure the file info was updated accordingly.
360   EXPECT_TRUE(file.GetInfo(&info));
361   EXPECT_EQ(info.size, kTestDataSize);
362   EXPECT_FALSE(info.is_directory);
363   EXPECT_FALSE(info.is_symbolic_link);
364
365   // ext2/ext3 and HPS/HPS+ seem to have a timestamp granularity of 1s.
366 #if defined(OS_POSIX)
367   EXPECT_EQ(info.last_accessed.ToTimeVal().tv_sec,
368             new_last_accessed.ToTimeVal().tv_sec);
369   EXPECT_EQ(info.last_modified.ToTimeVal().tv_sec,
370             new_last_modified.ToTimeVal().tv_sec);
371 #else
372   EXPECT_EQ(info.last_accessed.ToInternalValue(),
373             new_last_accessed.ToInternalValue());
374   EXPECT_EQ(info.last_modified.ToInternalValue(),
375             new_last_modified.ToInternalValue());
376 #endif
377
378   EXPECT_EQ(info.creation_time.ToInternalValue(),
379             creation_time.ToInternalValue());
380 }
381
382 TEST(FileTest, ReadAtCurrentPosition) {
383   base::ScopedTempDir temp_dir;
384   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
385   FilePath file_path = temp_dir.path().AppendASCII("read_at_current_position");
386   File file(file_path,
387             base::File::FLAG_CREATE | base::File::FLAG_READ |
388                 base::File::FLAG_WRITE);
389   EXPECT_TRUE(file.IsValid());
390
391   const char kData[] = "test";
392   const int kDataSize = sizeof(kData) - 1;
393   EXPECT_EQ(kDataSize, file.Write(0, kData, kDataSize));
394
395   EXPECT_EQ(0, file.Seek(base::File::FROM_BEGIN, 0));
396
397   char buffer[kDataSize];
398   int first_chunk_size = kDataSize / 2;
399   EXPECT_EQ(first_chunk_size, file.ReadAtCurrentPos(buffer, first_chunk_size));
400   EXPECT_EQ(kDataSize - first_chunk_size,
401             file.ReadAtCurrentPos(buffer + first_chunk_size,
402                                   kDataSize - first_chunk_size));
403   EXPECT_EQ(std::string(buffer, buffer + kDataSize), std::string(kData));
404 }
405
406 TEST(FileTest, WriteAtCurrentPosition) {
407   base::ScopedTempDir temp_dir;
408   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
409   FilePath file_path = temp_dir.path().AppendASCII("write_at_current_position");
410   File file(file_path,
411             base::File::FLAG_CREATE | base::File::FLAG_READ |
412                 base::File::FLAG_WRITE);
413   EXPECT_TRUE(file.IsValid());
414
415   const char kData[] = "test";
416   const int kDataSize = sizeof(kData) - 1;
417
418   int first_chunk_size = kDataSize / 2;
419   EXPECT_EQ(first_chunk_size, file.WriteAtCurrentPos(kData, first_chunk_size));
420   EXPECT_EQ(kDataSize - first_chunk_size,
421             file.WriteAtCurrentPos(kData + first_chunk_size,
422                                    kDataSize - first_chunk_size));
423
424   char buffer[kDataSize];
425   EXPECT_EQ(kDataSize, file.Read(0, buffer, kDataSize));
426   EXPECT_EQ(std::string(buffer, buffer + kDataSize), std::string(kData));
427 }
428
429 TEST(FileTest, Seek) {
430   base::ScopedTempDir temp_dir;
431   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
432   FilePath file_path = temp_dir.path().AppendASCII("seek_file");
433   File file(file_path,
434             base::File::FLAG_CREATE | base::File::FLAG_READ |
435                 base::File::FLAG_WRITE);
436   ASSERT_TRUE(file.IsValid());
437
438   const int64 kOffset = 10;
439   EXPECT_EQ(kOffset, file.Seek(base::File::FROM_BEGIN, kOffset));
440   EXPECT_EQ(2 * kOffset, file.Seek(base::File::FROM_CURRENT, kOffset));
441   EXPECT_EQ(kOffset, file.Seek(base::File::FROM_CURRENT, -kOffset));
442   EXPECT_TRUE(file.SetLength(kOffset * 2));
443   EXPECT_EQ(kOffset, file.Seek(base::File::FROM_END, -kOffset));
444 }
445
446 #if defined(OS_WIN)
447 TEST(FileTest, GetInfoForDirectory) {
448   base::ScopedTempDir temp_dir;
449   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
450   FilePath empty_dir = temp_dir.path().Append(FILE_PATH_LITERAL("gpfi_test"));
451   ASSERT_TRUE(CreateDirectory(empty_dir));
452
453   base::File dir(
454       ::CreateFile(empty_dir.value().c_str(),
455                    FILE_ALL_ACCESS,
456                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
457                    NULL,
458                    OPEN_EXISTING,
459                    FILE_FLAG_BACKUP_SEMANTICS,  // Needed to open a directory.
460                    NULL));
461   ASSERT_TRUE(dir.IsValid());
462
463   base::File::Info info;
464   EXPECT_TRUE(dir.GetInfo(&info));
465   EXPECT_TRUE(info.is_directory);
466   EXPECT_FALSE(info.is_symbolic_link);
467   EXPECT_EQ(0, info.size);
468 }
469 #endif  // defined(OS_WIN)
470
471 #if defined(OS_POSIX) && defined(GTEST_HAS_DEATH_TEST)
472 TEST(FileTest, MemoryCorruption) {
473   {
474     // Test that changing the checksum value is detected.
475     base::File file;
476     EXPECT_NE(file.file_.file_memory_checksum_,
477               implicit_cast<unsigned int>(file.GetPlatformFile()));
478     file.file_.file_memory_checksum_ = file.GetPlatformFile();
479     EXPECT_DEATH(file.IsValid(), "");
480
481     file.file_.UpdateChecksum();  // Do not crash on File::~File().
482   }
483
484   {
485     // Test that changing the file descriptor value is detected.
486     base::File file;
487     file.file_.file_.reset(17);
488     EXPECT_DEATH(file.IsValid(), "");
489
490     // Do not crash on File::~File().
491     ignore_result(file.file_.file_.release());
492     file.file_.UpdateChecksum();
493   }
494
495   {
496     // Test that GetPlatformFile() checks for corruption.
497     base::File file;
498     file.file_.file_memory_checksum_ = file.GetPlatformFile();
499     EXPECT_DEATH(file.GetPlatformFile(), "");
500
501     file.file_.UpdateChecksum();  // Do not crash on File::~File().
502   }
503
504   {
505     // Test that the base::File destructor checks for corruption.
506     scoped_ptr<base::File> file(new File());
507     file->file_.file_memory_checksum_ = file->GetPlatformFile();
508     EXPECT_DEATH(file.reset(), "");
509
510     // Do not crash on this thread's destructor call.
511     file->file_.UpdateChecksum();
512   }
513
514   {
515     // Test that the base::File constructor checks for corruption.
516     base::File file;
517     file.file_.file_memory_checksum_ = file.GetPlatformFile();
518     EXPECT_DEATH(File f(file.Pass()), "");
519
520     file.file_.UpdateChecksum();  // Do not crash on File::~File().
521   }
522
523   {
524     // Test that doing IO checks for corruption.
525     base::File file;
526     file.file_.file_.reset(17);  // A fake open FD value.
527
528     EXPECT_DEATH(file.Seek(File::FROM_BEGIN, 0), "");
529     EXPECT_DEATH(file.Read(0, NULL, 0), "");
530     EXPECT_DEATH(file.ReadAtCurrentPos(NULL, 0), "");
531     EXPECT_DEATH(file.Write(0, NULL, 0), "");
532
533     ignore_result(file.file_.file_.release());
534     file.file_.UpdateChecksum();
535   }
536 }
537 #endif  // defined(OS_POSIX)