xref: /aosp_15_r20/external/libchrome/base/files/file_unittest.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #include "base/files/file.h"
6*635a8641SAndroid Build Coastguard Worker 
7*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
8*635a8641SAndroid Build Coastguard Worker 
9*635a8641SAndroid Build Coastguard Worker #include <utility>
10*635a8641SAndroid Build Coastguard Worker 
11*635a8641SAndroid Build Coastguard Worker #include "base/files/file_util.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/files/memory_mapped_file.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/files/scoped_temp_dir.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/time/time.h"
15*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
16*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
17*635a8641SAndroid Build Coastguard Worker 
18*635a8641SAndroid Build Coastguard Worker using base::File;
19*635a8641SAndroid Build Coastguard Worker using base::FilePath;
20*635a8641SAndroid Build Coastguard Worker 
TEST(FileTest,Create)21*635a8641SAndroid Build Coastguard Worker TEST(FileTest, Create) {
22*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
23*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
24*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("create_file_1");
25*635a8641SAndroid Build Coastguard Worker 
26*635a8641SAndroid Build Coastguard Worker   {
27*635a8641SAndroid Build Coastguard Worker     // Don't create a File at all.
28*635a8641SAndroid Build Coastguard Worker     File file;
29*635a8641SAndroid Build Coastguard Worker     EXPECT_FALSE(file.IsValid());
30*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(base::File::FILE_ERROR_FAILED, file.error_details());
31*635a8641SAndroid Build Coastguard Worker 
32*635a8641SAndroid Build Coastguard Worker     File file2(base::File::FILE_ERROR_TOO_MANY_OPENED);
33*635a8641SAndroid Build Coastguard Worker     EXPECT_FALSE(file2.IsValid());
34*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(base::File::FILE_ERROR_TOO_MANY_OPENED, file2.error_details());
35*635a8641SAndroid Build Coastguard Worker   }
36*635a8641SAndroid Build Coastguard Worker 
37*635a8641SAndroid Build Coastguard Worker   {
38*635a8641SAndroid Build Coastguard Worker     // Open a file that doesn't exist.
39*635a8641SAndroid Build Coastguard Worker     File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
40*635a8641SAndroid Build Coastguard Worker     EXPECT_FALSE(file.IsValid());
41*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, file.error_details());
42*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, base::File::GetLastFileError());
43*635a8641SAndroid Build Coastguard Worker   }
44*635a8641SAndroid Build Coastguard Worker 
45*635a8641SAndroid Build Coastguard Worker   {
46*635a8641SAndroid Build Coastguard Worker     // Open or create a file.
47*635a8641SAndroid Build Coastguard Worker     File file(file_path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ);
48*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(file.IsValid());
49*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(file.created());
50*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(base::File::FILE_OK, file.error_details());
51*635a8641SAndroid Build Coastguard Worker   }
52*635a8641SAndroid Build Coastguard Worker 
53*635a8641SAndroid Build Coastguard Worker   {
54*635a8641SAndroid Build Coastguard Worker     // Open an existing file.
55*635a8641SAndroid Build Coastguard Worker     File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
56*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(file.IsValid());
57*635a8641SAndroid Build Coastguard Worker     EXPECT_FALSE(file.created());
58*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(base::File::FILE_OK, file.error_details());
59*635a8641SAndroid Build Coastguard Worker 
60*635a8641SAndroid Build Coastguard Worker     // This time verify closing the file.
61*635a8641SAndroid Build Coastguard Worker     file.Close();
62*635a8641SAndroid Build Coastguard Worker     EXPECT_FALSE(file.IsValid());
63*635a8641SAndroid Build Coastguard Worker   }
64*635a8641SAndroid Build Coastguard Worker 
65*635a8641SAndroid Build Coastguard Worker   {
66*635a8641SAndroid Build Coastguard Worker     // Open an existing file through Initialize
67*635a8641SAndroid Build Coastguard Worker     File file;
68*635a8641SAndroid Build Coastguard Worker     file.Initialize(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
69*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(file.IsValid());
70*635a8641SAndroid Build Coastguard Worker     EXPECT_FALSE(file.created());
71*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(base::File::FILE_OK, file.error_details());
72*635a8641SAndroid Build Coastguard Worker 
73*635a8641SAndroid Build Coastguard Worker     // This time verify closing the file.
74*635a8641SAndroid Build Coastguard Worker     file.Close();
75*635a8641SAndroid Build Coastguard Worker     EXPECT_FALSE(file.IsValid());
76*635a8641SAndroid Build Coastguard Worker   }
77*635a8641SAndroid Build Coastguard Worker 
78*635a8641SAndroid Build Coastguard Worker   {
79*635a8641SAndroid Build Coastguard Worker     // Create a file that exists.
80*635a8641SAndroid Build Coastguard Worker     File file(file_path, base::File::FLAG_CREATE | base::File::FLAG_READ);
81*635a8641SAndroid Build Coastguard Worker     EXPECT_FALSE(file.IsValid());
82*635a8641SAndroid Build Coastguard Worker     EXPECT_FALSE(file.created());
83*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(base::File::FILE_ERROR_EXISTS, file.error_details());
84*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(base::File::FILE_ERROR_EXISTS, base::File::GetLastFileError());
85*635a8641SAndroid Build Coastguard Worker   }
86*635a8641SAndroid Build Coastguard Worker 
87*635a8641SAndroid Build Coastguard Worker   {
88*635a8641SAndroid Build Coastguard Worker     // Create or overwrite a file.
89*635a8641SAndroid Build Coastguard Worker     File file(file_path,
90*635a8641SAndroid Build Coastguard Worker               base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
91*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(file.IsValid());
92*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(file.created());
93*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(base::File::FILE_OK, file.error_details());
94*635a8641SAndroid Build Coastguard Worker   }
95*635a8641SAndroid Build Coastguard Worker 
96*635a8641SAndroid Build Coastguard Worker   {
97*635a8641SAndroid Build Coastguard Worker     // Create a delete-on-close file.
98*635a8641SAndroid Build Coastguard Worker     file_path = temp_dir.GetPath().AppendASCII("create_file_2");
99*635a8641SAndroid Build Coastguard Worker     File file(file_path,
100*635a8641SAndroid Build Coastguard Worker               base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ |
101*635a8641SAndroid Build Coastguard Worker                   base::File::FLAG_DELETE_ON_CLOSE);
102*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(file.IsValid());
103*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(file.created());
104*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(base::File::FILE_OK, file.error_details());
105*635a8641SAndroid Build Coastguard Worker   }
106*635a8641SAndroid Build Coastguard Worker 
107*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(base::PathExists(file_path));
108*635a8641SAndroid Build Coastguard Worker }
109*635a8641SAndroid Build Coastguard Worker 
TEST(FileTest,SelfSwap)110*635a8641SAndroid Build Coastguard Worker TEST(FileTest, SelfSwap) {
111*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
112*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
113*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("create_file_1");
114*635a8641SAndroid Build Coastguard Worker   File file(file_path,
115*635a8641SAndroid Build Coastguard Worker             base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_DELETE_ON_CLOSE);
116*635a8641SAndroid Build Coastguard Worker   std::swap(file, file);
117*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(file.IsValid());
118*635a8641SAndroid Build Coastguard Worker }
119*635a8641SAndroid Build Coastguard Worker 
TEST(FileTest,Async)120*635a8641SAndroid Build Coastguard Worker TEST(FileTest, Async) {
121*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
122*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
123*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("create_file");
124*635a8641SAndroid Build Coastguard Worker 
125*635a8641SAndroid Build Coastguard Worker   {
126*635a8641SAndroid Build Coastguard Worker     File file(file_path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_ASYNC);
127*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(file.IsValid());
128*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(file.async());
129*635a8641SAndroid Build Coastguard Worker   }
130*635a8641SAndroid Build Coastguard Worker 
131*635a8641SAndroid Build Coastguard Worker   {
132*635a8641SAndroid Build Coastguard Worker     File file(file_path, base::File::FLAG_OPEN_ALWAYS);
133*635a8641SAndroid Build Coastguard Worker     EXPECT_TRUE(file.IsValid());
134*635a8641SAndroid Build Coastguard Worker     EXPECT_FALSE(file.async());
135*635a8641SAndroid Build Coastguard Worker   }
136*635a8641SAndroid Build Coastguard Worker }
137*635a8641SAndroid Build Coastguard Worker 
TEST(FileTest,DeleteOpenFile)138*635a8641SAndroid Build Coastguard Worker TEST(FileTest, DeleteOpenFile) {
139*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
140*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
141*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("create_file_1");
142*635a8641SAndroid Build Coastguard Worker 
143*635a8641SAndroid Build Coastguard Worker   // Create a file.
144*635a8641SAndroid Build Coastguard Worker   File file(file_path,
145*635a8641SAndroid Build Coastguard Worker             base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ |
146*635a8641SAndroid Build Coastguard Worker                 base::File::FLAG_SHARE_DELETE);
147*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(file.IsValid());
148*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(file.created());
149*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(base::File::FILE_OK, file.error_details());
150*635a8641SAndroid Build Coastguard Worker 
151*635a8641SAndroid Build Coastguard Worker   // Open an existing file and mark it as delete on close.
152*635a8641SAndroid Build Coastguard Worker   File same_file(file_path,
153*635a8641SAndroid Build Coastguard Worker                  base::File::FLAG_OPEN | base::File::FLAG_DELETE_ON_CLOSE |
154*635a8641SAndroid Build Coastguard Worker                      base::File::FLAG_READ);
155*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(file.IsValid());
156*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(same_file.created());
157*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(base::File::FILE_OK, same_file.error_details());
158*635a8641SAndroid Build Coastguard Worker 
159*635a8641SAndroid Build Coastguard Worker   // Close both handles and check that the file is gone.
160*635a8641SAndroid Build Coastguard Worker   file.Close();
161*635a8641SAndroid Build Coastguard Worker   same_file.Close();
162*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(base::PathExists(file_path));
163*635a8641SAndroid Build Coastguard Worker }
164*635a8641SAndroid Build Coastguard Worker 
TEST(FileTest,ReadWrite)165*635a8641SAndroid Build Coastguard Worker TEST(FileTest, ReadWrite) {
166*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
167*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
168*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("read_write_file");
169*635a8641SAndroid Build Coastguard Worker   File file(file_path,
170*635a8641SAndroid Build Coastguard Worker             base::File::FLAG_CREATE | base::File::FLAG_READ |
171*635a8641SAndroid Build Coastguard Worker                 base::File::FLAG_WRITE);
172*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
173*635a8641SAndroid Build Coastguard Worker 
174*635a8641SAndroid Build Coastguard Worker   char data_to_write[] = "test";
175*635a8641SAndroid Build Coastguard Worker   const int kTestDataSize = 4;
176*635a8641SAndroid Build Coastguard Worker 
177*635a8641SAndroid Build Coastguard Worker   // Write 0 bytes to the file.
178*635a8641SAndroid Build Coastguard Worker   int bytes_written = file.Write(0, data_to_write, 0);
179*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, bytes_written);
180*635a8641SAndroid Build Coastguard Worker 
181*635a8641SAndroid Build Coastguard Worker   // Write 0 bytes, with buf=nullptr.
182*635a8641SAndroid Build Coastguard Worker   bytes_written = file.Write(0, nullptr, 0);
183*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, bytes_written);
184*635a8641SAndroid Build Coastguard Worker 
185*635a8641SAndroid Build Coastguard Worker   // Write "test" to the file.
186*635a8641SAndroid Build Coastguard Worker   bytes_written = file.Write(0, data_to_write, kTestDataSize);
187*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kTestDataSize, bytes_written);
188*635a8641SAndroid Build Coastguard Worker 
189*635a8641SAndroid Build Coastguard Worker   // Read from EOF.
190*635a8641SAndroid Build Coastguard Worker   char data_read_1[32];
191*635a8641SAndroid Build Coastguard Worker   int bytes_read = file.Read(kTestDataSize, data_read_1, kTestDataSize);
192*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, bytes_read);
193*635a8641SAndroid Build Coastguard Worker 
194*635a8641SAndroid Build Coastguard Worker   // Read from somewhere in the middle of the file.
195*635a8641SAndroid Build Coastguard Worker   const int kPartialReadOffset = 1;
196*635a8641SAndroid Build Coastguard Worker   bytes_read = file.Read(kPartialReadOffset, data_read_1, kTestDataSize);
197*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kTestDataSize - kPartialReadOffset, bytes_read);
198*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < bytes_read; i++)
199*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(data_to_write[i + kPartialReadOffset], data_read_1[i]);
200*635a8641SAndroid Build Coastguard Worker 
201*635a8641SAndroid Build Coastguard Worker   // Read 0 bytes.
202*635a8641SAndroid Build Coastguard Worker   bytes_read = file.Read(0, data_read_1, 0);
203*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, bytes_read);
204*635a8641SAndroid Build Coastguard Worker 
205*635a8641SAndroid Build Coastguard Worker   // Read the entire file.
206*635a8641SAndroid Build Coastguard Worker   bytes_read = file.Read(0, data_read_1, kTestDataSize);
207*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kTestDataSize, bytes_read);
208*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < bytes_read; i++)
209*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(data_to_write[i], data_read_1[i]);
210*635a8641SAndroid Build Coastguard Worker 
211*635a8641SAndroid Build Coastguard Worker   // Read again, but using the trivial native wrapper.
212*635a8641SAndroid Build Coastguard Worker   bytes_read = file.ReadNoBestEffort(0, data_read_1, kTestDataSize);
213*635a8641SAndroid Build Coastguard Worker   EXPECT_LE(bytes_read, kTestDataSize);
214*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < bytes_read; i++)
215*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(data_to_write[i], data_read_1[i]);
216*635a8641SAndroid Build Coastguard Worker 
217*635a8641SAndroid Build Coastguard Worker   // Write past the end of the file.
218*635a8641SAndroid Build Coastguard Worker   const int kOffsetBeyondEndOfFile = 10;
219*635a8641SAndroid Build Coastguard Worker   const int kPartialWriteLength = 2;
220*635a8641SAndroid Build Coastguard Worker   bytes_written = file.Write(kOffsetBeyondEndOfFile,
221*635a8641SAndroid Build Coastguard Worker                              data_to_write, kPartialWriteLength);
222*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kPartialWriteLength, bytes_written);
223*635a8641SAndroid Build Coastguard Worker 
224*635a8641SAndroid Build Coastguard Worker   // Make sure the file was extended.
225*635a8641SAndroid Build Coastguard Worker   int64_t file_size = 0;
226*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(GetFileSize(file_path, &file_size));
227*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kOffsetBeyondEndOfFile + kPartialWriteLength, file_size);
228*635a8641SAndroid Build Coastguard Worker 
229*635a8641SAndroid Build Coastguard Worker   // Make sure the file was zero-padded.
230*635a8641SAndroid Build Coastguard Worker   char data_read_2[32];
231*635a8641SAndroid Build Coastguard Worker   bytes_read = file.Read(0, data_read_2, static_cast<int>(file_size));
232*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(file_size, bytes_read);
233*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kTestDataSize; i++)
234*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(data_to_write[i], data_read_2[i]);
235*635a8641SAndroid Build Coastguard Worker   for (int i = kTestDataSize; i < kOffsetBeyondEndOfFile; i++)
236*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(0, data_read_2[i]);
237*635a8641SAndroid Build Coastguard Worker   for (int i = kOffsetBeyondEndOfFile; i < file_size; i++)
238*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(data_to_write[i - kOffsetBeyondEndOfFile], data_read_2[i]);
239*635a8641SAndroid Build Coastguard Worker }
240*635a8641SAndroid Build Coastguard Worker 
TEST(FileTest,GetLastFileError)241*635a8641SAndroid Build Coastguard Worker TEST(FileTest, GetLastFileError) {
242*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
243*635a8641SAndroid Build Coastguard Worker   ::SetLastError(ERROR_ACCESS_DENIED);
244*635a8641SAndroid Build Coastguard Worker #else
245*635a8641SAndroid Build Coastguard Worker   errno = EACCES;
246*635a8641SAndroid Build Coastguard Worker #endif
247*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(File::FILE_ERROR_ACCESS_DENIED, File::GetLastFileError());
248*635a8641SAndroid Build Coastguard Worker 
249*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
250*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
251*635a8641SAndroid Build Coastguard Worker 
252*635a8641SAndroid Build Coastguard Worker   FilePath nonexistent_path(temp_dir.GetPath().AppendASCII("nonexistent"));
253*635a8641SAndroid Build Coastguard Worker   File file(nonexistent_path, File::FLAG_OPEN | File::FLAG_READ);
254*635a8641SAndroid Build Coastguard Worker   File::Error last_error = File::GetLastFileError();
255*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(file.IsValid());
256*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(File::FILE_ERROR_NOT_FOUND, file.error_details());
257*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(File::FILE_ERROR_NOT_FOUND, last_error);
258*635a8641SAndroid Build Coastguard Worker }
259*635a8641SAndroid Build Coastguard Worker 
TEST(FileTest,Append)260*635a8641SAndroid Build Coastguard Worker TEST(FileTest, Append) {
261*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
262*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
263*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("append_file");
264*635a8641SAndroid Build Coastguard Worker   File file(file_path, base::File::FLAG_CREATE | base::File::FLAG_APPEND);
265*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
266*635a8641SAndroid Build Coastguard Worker 
267*635a8641SAndroid Build Coastguard Worker   char data_to_write[] = "test";
268*635a8641SAndroid Build Coastguard Worker   const int kTestDataSize = 4;
269*635a8641SAndroid Build Coastguard Worker 
270*635a8641SAndroid Build Coastguard Worker   // Write 0 bytes to the file.
271*635a8641SAndroid Build Coastguard Worker   int bytes_written = file.Write(0, data_to_write, 0);
272*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, bytes_written);
273*635a8641SAndroid Build Coastguard Worker 
274*635a8641SAndroid Build Coastguard Worker   // Write 0 bytes, with buf=nullptr.
275*635a8641SAndroid Build Coastguard Worker   bytes_written = file.Write(0, nullptr, 0);
276*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, bytes_written);
277*635a8641SAndroid Build Coastguard Worker 
278*635a8641SAndroid Build Coastguard Worker   // Write "test" to the file.
279*635a8641SAndroid Build Coastguard Worker   bytes_written = file.Write(0, data_to_write, kTestDataSize);
280*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kTestDataSize, bytes_written);
281*635a8641SAndroid Build Coastguard Worker 
282*635a8641SAndroid Build Coastguard Worker   file.Close();
283*635a8641SAndroid Build Coastguard Worker   File file2(file_path,
284*635a8641SAndroid Build Coastguard Worker              base::File::FLAG_OPEN | base::File::FLAG_READ |
285*635a8641SAndroid Build Coastguard Worker                  base::File::FLAG_APPEND);
286*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file2.IsValid());
287*635a8641SAndroid Build Coastguard Worker 
288*635a8641SAndroid Build Coastguard Worker   // Test passing the file around.
289*635a8641SAndroid Build Coastguard Worker   file = std::move(file2);
290*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(file2.IsValid());
291*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
292*635a8641SAndroid Build Coastguard Worker 
293*635a8641SAndroid Build Coastguard Worker   char append_data_to_write[] = "78";
294*635a8641SAndroid Build Coastguard Worker   const int kAppendDataSize = 2;
295*635a8641SAndroid Build Coastguard Worker 
296*635a8641SAndroid Build Coastguard Worker   // Append "78" to the file.
297*635a8641SAndroid Build Coastguard Worker   bytes_written = file.Write(0, append_data_to_write, kAppendDataSize);
298*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kAppendDataSize, bytes_written);
299*635a8641SAndroid Build Coastguard Worker 
300*635a8641SAndroid Build Coastguard Worker   // Read the entire file.
301*635a8641SAndroid Build Coastguard Worker   char data_read_1[32];
302*635a8641SAndroid Build Coastguard Worker   int bytes_read = file.Read(0, data_read_1,
303*635a8641SAndroid Build Coastguard Worker                              kTestDataSize + kAppendDataSize);
304*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kTestDataSize + kAppendDataSize, bytes_read);
305*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kTestDataSize; i++)
306*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(data_to_write[i], data_read_1[i]);
307*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kAppendDataSize; i++)
308*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(append_data_to_write[i], data_read_1[kTestDataSize + i]);
309*635a8641SAndroid Build Coastguard Worker }
310*635a8641SAndroid Build Coastguard Worker 
311*635a8641SAndroid Build Coastguard Worker 
TEST(FileTest,Length)312*635a8641SAndroid Build Coastguard Worker TEST(FileTest, Length) {
313*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
314*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
315*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("truncate_file");
316*635a8641SAndroid Build Coastguard Worker   File file(file_path,
317*635a8641SAndroid Build Coastguard Worker             base::File::FLAG_CREATE | base::File::FLAG_READ |
318*635a8641SAndroid Build Coastguard Worker                 base::File::FLAG_WRITE);
319*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
320*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, file.GetLength());
321*635a8641SAndroid Build Coastguard Worker 
322*635a8641SAndroid Build Coastguard Worker   // Write "test" to the file.
323*635a8641SAndroid Build Coastguard Worker   char data_to_write[] = "test";
324*635a8641SAndroid Build Coastguard Worker   int kTestDataSize = 4;
325*635a8641SAndroid Build Coastguard Worker   int bytes_written = file.Write(0, data_to_write, kTestDataSize);
326*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kTestDataSize, bytes_written);
327*635a8641SAndroid Build Coastguard Worker 
328*635a8641SAndroid Build Coastguard Worker   // Extend the file.
329*635a8641SAndroid Build Coastguard Worker   const int kExtendedFileLength = 10;
330*635a8641SAndroid Build Coastguard Worker   int64_t file_size = 0;
331*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(file.SetLength(kExtendedFileLength));
332*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kExtendedFileLength, file.GetLength());
333*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(GetFileSize(file_path, &file_size));
334*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kExtendedFileLength, file_size);
335*635a8641SAndroid Build Coastguard Worker 
336*635a8641SAndroid Build Coastguard Worker   // Make sure the file was zero-padded.
337*635a8641SAndroid Build Coastguard Worker   char data_read[32];
338*635a8641SAndroid Build Coastguard Worker   int bytes_read = file.Read(0, data_read, static_cast<int>(file_size));
339*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(file_size, bytes_read);
340*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kTestDataSize; i++)
341*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(data_to_write[i], data_read[i]);
342*635a8641SAndroid Build Coastguard Worker   for (int i = kTestDataSize; i < file_size; i++)
343*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(0, data_read[i]);
344*635a8641SAndroid Build Coastguard Worker 
345*635a8641SAndroid Build Coastguard Worker   // Truncate the file.
346*635a8641SAndroid Build Coastguard Worker   const int kTruncatedFileLength = 2;
347*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(file.SetLength(kTruncatedFileLength));
348*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kTruncatedFileLength, file.GetLength());
349*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(GetFileSize(file_path, &file_size));
350*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kTruncatedFileLength, file_size);
351*635a8641SAndroid Build Coastguard Worker 
352*635a8641SAndroid Build Coastguard Worker   // Make sure the file was truncated.
353*635a8641SAndroid Build Coastguard Worker   bytes_read = file.Read(0, data_read, kTestDataSize);
354*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(file_size, bytes_read);
355*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < file_size; i++)
356*635a8641SAndroid Build Coastguard Worker     EXPECT_EQ(data_to_write[i], data_read[i]);
357*635a8641SAndroid Build Coastguard Worker 
358*635a8641SAndroid Build Coastguard Worker   // Close the file and reopen with base::File::FLAG_CREATE_ALWAYS, and make
359*635a8641SAndroid Build Coastguard Worker   // sure the file is empty (old file was overridden).
360*635a8641SAndroid Build Coastguard Worker   file.Close();
361*635a8641SAndroid Build Coastguard Worker   file.Initialize(file_path,
362*635a8641SAndroid Build Coastguard Worker                   base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
363*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, file.GetLength());
364*635a8641SAndroid Build Coastguard Worker }
365*635a8641SAndroid Build Coastguard Worker 
366*635a8641SAndroid Build Coastguard Worker // Flakily fails: http://crbug.com/86494
367*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
TEST(FileTest,TouchGetInfo)368*635a8641SAndroid Build Coastguard Worker TEST(FileTest, TouchGetInfo) {
369*635a8641SAndroid Build Coastguard Worker #else
370*635a8641SAndroid Build Coastguard Worker TEST(FileTest, DISABLED_TouchGetInfo) {
371*635a8641SAndroid Build Coastguard Worker #endif
372*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
373*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
374*635a8641SAndroid Build Coastguard Worker   File file(temp_dir.GetPath().AppendASCII("touch_get_info_file"),
375*635a8641SAndroid Build Coastguard Worker             base::File::FLAG_CREATE | base::File::FLAG_WRITE |
376*635a8641SAndroid Build Coastguard Worker                 base::File::FLAG_WRITE_ATTRIBUTES);
377*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
378*635a8641SAndroid Build Coastguard Worker 
379*635a8641SAndroid Build Coastguard Worker   // Get info for a newly created file.
380*635a8641SAndroid Build Coastguard Worker   base::File::Info info;
381*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(file.GetInfo(&info));
382*635a8641SAndroid Build Coastguard Worker 
383*635a8641SAndroid Build Coastguard Worker   // Add 2 seconds to account for possible rounding errors on
384*635a8641SAndroid Build Coastguard Worker   // filesystems that use a 1s or 2s timestamp granularity.
385*635a8641SAndroid Build Coastguard Worker   base::Time now = base::Time::Now() + base::TimeDelta::FromSeconds(2);
386*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, info.size);
387*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(info.is_directory);
388*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(info.is_symbolic_link);
389*635a8641SAndroid Build Coastguard Worker   EXPECT_LE(info.last_accessed.ToInternalValue(), now.ToInternalValue());
390*635a8641SAndroid Build Coastguard Worker   EXPECT_LE(info.last_modified.ToInternalValue(), now.ToInternalValue());
391*635a8641SAndroid Build Coastguard Worker   EXPECT_LE(info.creation_time.ToInternalValue(), now.ToInternalValue());
392*635a8641SAndroid Build Coastguard Worker   base::Time creation_time = info.creation_time;
393*635a8641SAndroid Build Coastguard Worker 
394*635a8641SAndroid Build Coastguard Worker   // Write "test" to the file.
395*635a8641SAndroid Build Coastguard Worker   char data[] = "test";
396*635a8641SAndroid Build Coastguard Worker   const int kTestDataSize = 4;
397*635a8641SAndroid Build Coastguard Worker   int bytes_written = file.Write(0, data, kTestDataSize);
398*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kTestDataSize, bytes_written);
399*635a8641SAndroid Build Coastguard Worker 
400*635a8641SAndroid Build Coastguard Worker   // Change the last_accessed and last_modified dates.
401*635a8641SAndroid Build Coastguard Worker   // It's best to add values that are multiples of 2 (in seconds)
402*635a8641SAndroid Build Coastguard Worker   // to the current last_accessed and last_modified times, because
403*635a8641SAndroid Build Coastguard Worker   // FATxx uses a 2s timestamp granularity.
404*635a8641SAndroid Build Coastguard Worker   base::Time new_last_accessed =
405*635a8641SAndroid Build Coastguard Worker       info.last_accessed + base::TimeDelta::FromSeconds(234);
406*635a8641SAndroid Build Coastguard Worker   base::Time new_last_modified =
407*635a8641SAndroid Build Coastguard Worker       info.last_modified + base::TimeDelta::FromMinutes(567);
408*635a8641SAndroid Build Coastguard Worker 
409*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(file.SetTimes(new_last_accessed, new_last_modified));
410*635a8641SAndroid Build Coastguard Worker 
411*635a8641SAndroid Build Coastguard Worker   // Make sure the file info was updated accordingly.
412*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(file.GetInfo(&info));
413*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(info.size, kTestDataSize);
414*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(info.is_directory);
415*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(info.is_symbolic_link);
416*635a8641SAndroid Build Coastguard Worker 
417*635a8641SAndroid Build Coastguard Worker   // ext2/ext3 and HPS/HPS+ seem to have a timestamp granularity of 1s.
418*635a8641SAndroid Build Coastguard Worker #if defined(OS_POSIX)
419*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(info.last_accessed.ToTimeVal().tv_sec,
420*635a8641SAndroid Build Coastguard Worker             new_last_accessed.ToTimeVal().tv_sec);
421*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(info.last_modified.ToTimeVal().tv_sec,
422*635a8641SAndroid Build Coastguard Worker             new_last_modified.ToTimeVal().tv_sec);
423*635a8641SAndroid Build Coastguard Worker #else
424*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(info.last_accessed.ToInternalValue(),
425*635a8641SAndroid Build Coastguard Worker             new_last_accessed.ToInternalValue());
426*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(info.last_modified.ToInternalValue(),
427*635a8641SAndroid Build Coastguard Worker             new_last_modified.ToInternalValue());
428*635a8641SAndroid Build Coastguard Worker #endif
429*635a8641SAndroid Build Coastguard Worker 
430*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(info.creation_time.ToInternalValue(),
431*635a8641SAndroid Build Coastguard Worker             creation_time.ToInternalValue());
432*635a8641SAndroid Build Coastguard Worker }
433*635a8641SAndroid Build Coastguard Worker 
434*635a8641SAndroid Build Coastguard Worker TEST(FileTest, ReadAtCurrentPosition) {
435*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
436*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
437*635a8641SAndroid Build Coastguard Worker   FilePath file_path =
438*635a8641SAndroid Build Coastguard Worker       temp_dir.GetPath().AppendASCII("read_at_current_position");
439*635a8641SAndroid Build Coastguard Worker   File file(file_path,
440*635a8641SAndroid Build Coastguard Worker             base::File::FLAG_CREATE | base::File::FLAG_READ |
441*635a8641SAndroid Build Coastguard Worker                 base::File::FLAG_WRITE);
442*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(file.IsValid());
443*635a8641SAndroid Build Coastguard Worker 
444*635a8641SAndroid Build Coastguard Worker   const char kData[] = "test";
445*635a8641SAndroid Build Coastguard Worker   const int kDataSize = sizeof(kData) - 1;
446*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kDataSize, file.Write(0, kData, kDataSize));
447*635a8641SAndroid Build Coastguard Worker 
448*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, file.Seek(base::File::FROM_BEGIN, 0));
449*635a8641SAndroid Build Coastguard Worker 
450*635a8641SAndroid Build Coastguard Worker   char buffer[kDataSize];
451*635a8641SAndroid Build Coastguard Worker   int first_chunk_size = kDataSize / 2;
452*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(first_chunk_size, file.ReadAtCurrentPos(buffer, first_chunk_size));
453*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kDataSize - first_chunk_size,
454*635a8641SAndroid Build Coastguard Worker             file.ReadAtCurrentPos(buffer + first_chunk_size,
455*635a8641SAndroid Build Coastguard Worker                                   kDataSize - first_chunk_size));
456*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(buffer, buffer + kDataSize), std::string(kData));
457*635a8641SAndroid Build Coastguard Worker }
458*635a8641SAndroid Build Coastguard Worker 
459*635a8641SAndroid Build Coastguard Worker TEST(FileTest, WriteAtCurrentPosition) {
460*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
461*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
462*635a8641SAndroid Build Coastguard Worker   FilePath file_path =
463*635a8641SAndroid Build Coastguard Worker       temp_dir.GetPath().AppendASCII("write_at_current_position");
464*635a8641SAndroid Build Coastguard Worker   File file(file_path,
465*635a8641SAndroid Build Coastguard Worker             base::File::FLAG_CREATE | base::File::FLAG_READ |
466*635a8641SAndroid Build Coastguard Worker                 base::File::FLAG_WRITE);
467*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(file.IsValid());
468*635a8641SAndroid Build Coastguard Worker 
469*635a8641SAndroid Build Coastguard Worker   const char kData[] = "test";
470*635a8641SAndroid Build Coastguard Worker   const int kDataSize = sizeof(kData) - 1;
471*635a8641SAndroid Build Coastguard Worker 
472*635a8641SAndroid Build Coastguard Worker   int first_chunk_size = kDataSize / 2;
473*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(first_chunk_size, file.WriteAtCurrentPos(kData, first_chunk_size));
474*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kDataSize - first_chunk_size,
475*635a8641SAndroid Build Coastguard Worker             file.WriteAtCurrentPos(kData + first_chunk_size,
476*635a8641SAndroid Build Coastguard Worker                                    kDataSize - first_chunk_size));
477*635a8641SAndroid Build Coastguard Worker 
478*635a8641SAndroid Build Coastguard Worker   char buffer[kDataSize];
479*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kDataSize, file.Read(0, buffer, kDataSize));
480*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(std::string(buffer, buffer + kDataSize), std::string(kData));
481*635a8641SAndroid Build Coastguard Worker }
482*635a8641SAndroid Build Coastguard Worker 
483*635a8641SAndroid Build Coastguard Worker TEST(FileTest, Seek) {
484*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
485*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
486*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("seek_file");
487*635a8641SAndroid Build Coastguard Worker   File file(file_path,
488*635a8641SAndroid Build Coastguard Worker             base::File::FLAG_CREATE | base::File::FLAG_READ |
489*635a8641SAndroid Build Coastguard Worker                 base::File::FLAG_WRITE);
490*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
491*635a8641SAndroid Build Coastguard Worker 
492*635a8641SAndroid Build Coastguard Worker   const int64_t kOffset = 10;
493*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kOffset, file.Seek(base::File::FROM_BEGIN, kOffset));
494*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(2 * kOffset, file.Seek(base::File::FROM_CURRENT, kOffset));
495*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kOffset, file.Seek(base::File::FROM_CURRENT, -kOffset));
496*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(file.SetLength(kOffset * 2));
497*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(kOffset, file.Seek(base::File::FROM_END, -kOffset));
498*635a8641SAndroid Build Coastguard Worker }
499*635a8641SAndroid Build Coastguard Worker 
500*635a8641SAndroid Build Coastguard Worker TEST(FileTest, Duplicate) {
501*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
502*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
503*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("file");
504*635a8641SAndroid Build Coastguard Worker   File file(file_path,(base::File::FLAG_CREATE |
505*635a8641SAndroid Build Coastguard Worker                        base::File::FLAG_READ |
506*635a8641SAndroid Build Coastguard Worker                        base::File::FLAG_WRITE));
507*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
508*635a8641SAndroid Build Coastguard Worker 
509*635a8641SAndroid Build Coastguard Worker   File file2(file.Duplicate());
510*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file2.IsValid());
511*635a8641SAndroid Build Coastguard Worker 
512*635a8641SAndroid Build Coastguard Worker   // Write through one handle, close it, read through the other.
513*635a8641SAndroid Build Coastguard Worker   static const char kData[] = "now is a good time.";
514*635a8641SAndroid Build Coastguard Worker   static const int kDataLen = sizeof(kData) - 1;
515*635a8641SAndroid Build Coastguard Worker 
516*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(0, file.Seek(base::File::FROM_CURRENT, 0));
517*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(0, file2.Seek(base::File::FROM_CURRENT, 0));
518*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(kDataLen, file.WriteAtCurrentPos(kData, kDataLen));
519*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(kDataLen, file.Seek(base::File::FROM_CURRENT, 0));
520*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(kDataLen, file2.Seek(base::File::FROM_CURRENT, 0));
521*635a8641SAndroid Build Coastguard Worker   file.Close();
522*635a8641SAndroid Build Coastguard Worker   char buf[kDataLen];
523*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(kDataLen, file2.Read(0, &buf[0], kDataLen));
524*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(std::string(kData, kDataLen), std::string(&buf[0], kDataLen));
525*635a8641SAndroid Build Coastguard Worker }
526*635a8641SAndroid Build Coastguard Worker 
527*635a8641SAndroid Build Coastguard Worker TEST(FileTest, DuplicateDeleteOnClose) {
528*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
529*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
530*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("file");
531*635a8641SAndroid Build Coastguard Worker   File file(file_path,(base::File::FLAG_CREATE |
532*635a8641SAndroid Build Coastguard Worker                        base::File::FLAG_READ |
533*635a8641SAndroid Build Coastguard Worker                        base::File::FLAG_WRITE |
534*635a8641SAndroid Build Coastguard Worker                        base::File::FLAG_DELETE_ON_CLOSE));
535*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
536*635a8641SAndroid Build Coastguard Worker   File file2(file.Duplicate());
537*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file2.IsValid());
538*635a8641SAndroid Build Coastguard Worker   file.Close();
539*635a8641SAndroid Build Coastguard Worker   file2.Close();
540*635a8641SAndroid Build Coastguard Worker   ASSERT_FALSE(base::PathExists(file_path));
541*635a8641SAndroid Build Coastguard Worker }
542*635a8641SAndroid Build Coastguard Worker 
543*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
544*635a8641SAndroid Build Coastguard Worker // Flakily times out on Windows, see http://crbug.com/846276.
545*635a8641SAndroid Build Coastguard Worker #define MAYBE_WriteDataToLargeOffset DISABLED_WriteDataToLargeOffset
546*635a8641SAndroid Build Coastguard Worker #else
547*635a8641SAndroid Build Coastguard Worker #define MAYBE_WriteDataToLargeOffset WriteDataToLargeOffset
548*635a8641SAndroid Build Coastguard Worker #endif
549*635a8641SAndroid Build Coastguard Worker TEST(FileTest, MAYBE_WriteDataToLargeOffset) {
550*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
551*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
552*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("file");
553*635a8641SAndroid Build Coastguard Worker   File file(file_path,
554*635a8641SAndroid Build Coastguard Worker             (base::File::FLAG_CREATE | base::File::FLAG_READ |
555*635a8641SAndroid Build Coastguard Worker              base::File::FLAG_WRITE | base::File::FLAG_DELETE_ON_CLOSE));
556*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
557*635a8641SAndroid Build Coastguard Worker 
558*635a8641SAndroid Build Coastguard Worker   const char kData[] = "this file is sparse.";
559*635a8641SAndroid Build Coastguard Worker   const int kDataLen = sizeof(kData) - 1;
560*635a8641SAndroid Build Coastguard Worker   const int64_t kLargeFileOffset = (1LL << 31);
561*635a8641SAndroid Build Coastguard Worker 
562*635a8641SAndroid Build Coastguard Worker   // If the file fails to write, it is probably we are running out of disk space
563*635a8641SAndroid Build Coastguard Worker   // and the file system doesn't support sparse file.
564*635a8641SAndroid Build Coastguard Worker   if (file.Write(kLargeFileOffset - kDataLen - 1, kData, kDataLen) < 0)
565*635a8641SAndroid Build Coastguard Worker     return;
566*635a8641SAndroid Build Coastguard Worker 
567*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(kDataLen, file.Write(kLargeFileOffset + 1, kData, kDataLen));
568*635a8641SAndroid Build Coastguard Worker }
569*635a8641SAndroid Build Coastguard Worker 
570*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
571*635a8641SAndroid Build Coastguard Worker TEST(FileTest, GetInfoForDirectory) {
572*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
573*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
574*635a8641SAndroid Build Coastguard Worker   FilePath empty_dir =
575*635a8641SAndroid Build Coastguard Worker       temp_dir.GetPath().Append(FILE_PATH_LITERAL("gpfi_test"));
576*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(CreateDirectory(empty_dir));
577*635a8641SAndroid Build Coastguard Worker 
578*635a8641SAndroid Build Coastguard Worker   base::File dir(
579*635a8641SAndroid Build Coastguard Worker       ::CreateFile(empty_dir.value().c_str(),
580*635a8641SAndroid Build Coastguard Worker                    GENERIC_READ | GENERIC_WRITE,
581*635a8641SAndroid Build Coastguard Worker                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
582*635a8641SAndroid Build Coastguard Worker                    NULL,
583*635a8641SAndroid Build Coastguard Worker                    OPEN_EXISTING,
584*635a8641SAndroid Build Coastguard Worker                    FILE_FLAG_BACKUP_SEMANTICS,  // Needed to open a directory.
585*635a8641SAndroid Build Coastguard Worker                    NULL));
586*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(dir.IsValid());
587*635a8641SAndroid Build Coastguard Worker 
588*635a8641SAndroid Build Coastguard Worker   base::File::Info info;
589*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(dir.GetInfo(&info));
590*635a8641SAndroid Build Coastguard Worker   EXPECT_TRUE(info.is_directory);
591*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(info.is_symbolic_link);
592*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(0, info.size);
593*635a8641SAndroid Build Coastguard Worker }
594*635a8641SAndroid Build Coastguard Worker 
595*635a8641SAndroid Build Coastguard Worker TEST(FileTest, DeleteNoop) {
596*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
597*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
598*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("file");
599*635a8641SAndroid Build Coastguard Worker 
600*635a8641SAndroid Build Coastguard Worker   // Creating and closing a file with DELETE perms should do nothing special.
601*635a8641SAndroid Build Coastguard Worker   File file(file_path,
602*635a8641SAndroid Build Coastguard Worker             (base::File::FLAG_CREATE | base::File::FLAG_READ |
603*635a8641SAndroid Build Coastguard Worker              base::File::FLAG_WRITE | base::File::FLAG_CAN_DELETE_ON_CLOSE));
604*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
605*635a8641SAndroid Build Coastguard Worker   file.Close();
606*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(base::PathExists(file_path));
607*635a8641SAndroid Build Coastguard Worker }
608*635a8641SAndroid Build Coastguard Worker 
609*635a8641SAndroid Build Coastguard Worker TEST(FileTest, Delete) {
610*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
611*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
612*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("file");
613*635a8641SAndroid Build Coastguard Worker 
614*635a8641SAndroid Build Coastguard Worker   // Creating a file with DELETE and then marking for delete on close should
615*635a8641SAndroid Build Coastguard Worker   // delete it.
616*635a8641SAndroid Build Coastguard Worker   File file(file_path,
617*635a8641SAndroid Build Coastguard Worker             (base::File::FLAG_CREATE | base::File::FLAG_READ |
618*635a8641SAndroid Build Coastguard Worker              base::File::FLAG_WRITE | base::File::FLAG_CAN_DELETE_ON_CLOSE));
619*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
620*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.DeleteOnClose(true));
621*635a8641SAndroid Build Coastguard Worker   file.Close();
622*635a8641SAndroid Build Coastguard Worker   ASSERT_FALSE(base::PathExists(file_path));
623*635a8641SAndroid Build Coastguard Worker }
624*635a8641SAndroid Build Coastguard Worker 
625*635a8641SAndroid Build Coastguard Worker TEST(FileTest, DeleteThenRevoke) {
626*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
627*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
628*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("file");
629*635a8641SAndroid Build Coastguard Worker 
630*635a8641SAndroid Build Coastguard Worker   // Creating a file with DELETE, marking it for delete, then clearing delete on
631*635a8641SAndroid Build Coastguard Worker   // close should not delete it.
632*635a8641SAndroid Build Coastguard Worker   File file(file_path,
633*635a8641SAndroid Build Coastguard Worker             (base::File::FLAG_CREATE | base::File::FLAG_READ |
634*635a8641SAndroid Build Coastguard Worker              base::File::FLAG_WRITE | base::File::FLAG_CAN_DELETE_ON_CLOSE));
635*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
636*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.DeleteOnClose(true));
637*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.DeleteOnClose(false));
638*635a8641SAndroid Build Coastguard Worker   file.Close();
639*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(base::PathExists(file_path));
640*635a8641SAndroid Build Coastguard Worker }
641*635a8641SAndroid Build Coastguard Worker 
642*635a8641SAndroid Build Coastguard Worker TEST(FileTest, IrrevokableDeleteOnClose) {
643*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
644*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
645*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("file");
646*635a8641SAndroid Build Coastguard Worker 
647*635a8641SAndroid Build Coastguard Worker   // DELETE_ON_CLOSE cannot be revoked by this opener.
648*635a8641SAndroid Build Coastguard Worker   File file(
649*635a8641SAndroid Build Coastguard Worker       file_path,
650*635a8641SAndroid Build Coastguard Worker       (base::File::FLAG_CREATE | base::File::FLAG_READ |
651*635a8641SAndroid Build Coastguard Worker        base::File::FLAG_WRITE | base::File::FLAG_DELETE_ON_CLOSE |
652*635a8641SAndroid Build Coastguard Worker        base::File::FLAG_SHARE_DELETE | base::File::FLAG_CAN_DELETE_ON_CLOSE));
653*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
654*635a8641SAndroid Build Coastguard Worker   // https://msdn.microsoft.com/library/windows/desktop/aa364221.aspx says that
655*635a8641SAndroid Build Coastguard Worker   // setting the dispositon has no effect if the handle was opened with
656*635a8641SAndroid Build Coastguard Worker   // FLAG_DELETE_ON_CLOSE. Do not make the test's success dependent on whether
657*635a8641SAndroid Build Coastguard Worker   // or not SetFileInformationByHandle indicates success or failure. (It happens
658*635a8641SAndroid Build Coastguard Worker   // to indicate success on Windows 10.)
659*635a8641SAndroid Build Coastguard Worker   file.DeleteOnClose(false);
660*635a8641SAndroid Build Coastguard Worker   file.Close();
661*635a8641SAndroid Build Coastguard Worker   ASSERT_FALSE(base::PathExists(file_path));
662*635a8641SAndroid Build Coastguard Worker }
663*635a8641SAndroid Build Coastguard Worker 
664*635a8641SAndroid Build Coastguard Worker TEST(FileTest, IrrevokableDeleteOnCloseOther) {
665*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
666*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
667*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("file");
668*635a8641SAndroid Build Coastguard Worker 
669*635a8641SAndroid Build Coastguard Worker   // DELETE_ON_CLOSE cannot be revoked by another opener.
670*635a8641SAndroid Build Coastguard Worker   File file(
671*635a8641SAndroid Build Coastguard Worker       file_path,
672*635a8641SAndroid Build Coastguard Worker       (base::File::FLAG_CREATE | base::File::FLAG_READ |
673*635a8641SAndroid Build Coastguard Worker        base::File::FLAG_WRITE | base::File::FLAG_DELETE_ON_CLOSE |
674*635a8641SAndroid Build Coastguard Worker        base::File::FLAG_SHARE_DELETE | base::File::FLAG_CAN_DELETE_ON_CLOSE));
675*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
676*635a8641SAndroid Build Coastguard Worker 
677*635a8641SAndroid Build Coastguard Worker   File file2(
678*635a8641SAndroid Build Coastguard Worker       file_path,
679*635a8641SAndroid Build Coastguard Worker       (base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE |
680*635a8641SAndroid Build Coastguard Worker        base::File::FLAG_SHARE_DELETE | base::File::FLAG_CAN_DELETE_ON_CLOSE));
681*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file2.IsValid());
682*635a8641SAndroid Build Coastguard Worker 
683*635a8641SAndroid Build Coastguard Worker   file2.DeleteOnClose(false);
684*635a8641SAndroid Build Coastguard Worker   file2.Close();
685*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(base::PathExists(file_path));
686*635a8641SAndroid Build Coastguard Worker   file.Close();
687*635a8641SAndroid Build Coastguard Worker   ASSERT_FALSE(base::PathExists(file_path));
688*635a8641SAndroid Build Coastguard Worker }
689*635a8641SAndroid Build Coastguard Worker 
690*635a8641SAndroid Build Coastguard Worker TEST(FileTest, DeleteWithoutPermission) {
691*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
692*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
693*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("file");
694*635a8641SAndroid Build Coastguard Worker 
695*635a8641SAndroid Build Coastguard Worker   // It should not be possible to mark a file for deletion when it was not
696*635a8641SAndroid Build Coastguard Worker   // created/opened with DELETE.
697*635a8641SAndroid Build Coastguard Worker   File file(file_path, (base::File::FLAG_CREATE | base::File::FLAG_READ |
698*635a8641SAndroid Build Coastguard Worker                         base::File::FLAG_WRITE));
699*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
700*635a8641SAndroid Build Coastguard Worker   ASSERT_FALSE(file.DeleteOnClose(true));
701*635a8641SAndroid Build Coastguard Worker   file.Close();
702*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(base::PathExists(file_path));
703*635a8641SAndroid Build Coastguard Worker }
704*635a8641SAndroid Build Coastguard Worker 
705*635a8641SAndroid Build Coastguard Worker TEST(FileTest, UnsharedDeleteOnClose) {
706*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
707*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
708*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("file");
709*635a8641SAndroid Build Coastguard Worker 
710*635a8641SAndroid Build Coastguard Worker   // Opening with DELETE_ON_CLOSE when a previous opener hasn't enabled sharing
711*635a8641SAndroid Build Coastguard Worker   // will fail.
712*635a8641SAndroid Build Coastguard Worker   File file(file_path, (base::File::FLAG_CREATE | base::File::FLAG_READ |
713*635a8641SAndroid Build Coastguard Worker                         base::File::FLAG_WRITE));
714*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
715*635a8641SAndroid Build Coastguard Worker   File file2(
716*635a8641SAndroid Build Coastguard Worker       file_path,
717*635a8641SAndroid Build Coastguard Worker       (base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE |
718*635a8641SAndroid Build Coastguard Worker        base::File::FLAG_DELETE_ON_CLOSE | base::File::FLAG_SHARE_DELETE));
719*635a8641SAndroid Build Coastguard Worker   ASSERT_FALSE(file2.IsValid());
720*635a8641SAndroid Build Coastguard Worker 
721*635a8641SAndroid Build Coastguard Worker   file.Close();
722*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(base::PathExists(file_path));
723*635a8641SAndroid Build Coastguard Worker }
724*635a8641SAndroid Build Coastguard Worker 
725*635a8641SAndroid Build Coastguard Worker TEST(FileTest, NoDeleteOnCloseWithMappedFile) {
726*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
727*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
728*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("file");
729*635a8641SAndroid Build Coastguard Worker 
730*635a8641SAndroid Build Coastguard Worker   // Mapping a file into memory blocks DeleteOnClose.
731*635a8641SAndroid Build Coastguard Worker   File file(file_path,
732*635a8641SAndroid Build Coastguard Worker             (base::File::FLAG_CREATE | base::File::FLAG_READ |
733*635a8641SAndroid Build Coastguard Worker              base::File::FLAG_WRITE | base::File::FLAG_CAN_DELETE_ON_CLOSE));
734*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
735*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(5, file.WriteAtCurrentPos("12345", 5));
736*635a8641SAndroid Build Coastguard Worker 
737*635a8641SAndroid Build Coastguard Worker   {
738*635a8641SAndroid Build Coastguard Worker     base::MemoryMappedFile mapping;
739*635a8641SAndroid Build Coastguard Worker     ASSERT_TRUE(mapping.Initialize(file.Duplicate()));
740*635a8641SAndroid Build Coastguard Worker     ASSERT_EQ(5U, mapping.length());
741*635a8641SAndroid Build Coastguard Worker 
742*635a8641SAndroid Build Coastguard Worker     EXPECT_FALSE(file.DeleteOnClose(true));
743*635a8641SAndroid Build Coastguard Worker   }
744*635a8641SAndroid Build Coastguard Worker 
745*635a8641SAndroid Build Coastguard Worker   file.Close();
746*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(base::PathExists(file_path));
747*635a8641SAndroid Build Coastguard Worker }
748*635a8641SAndroid Build Coastguard Worker 
749*635a8641SAndroid Build Coastguard Worker // Check that we handle the async bit being set incorrectly in a sane way.
750*635a8641SAndroid Build Coastguard Worker TEST(FileTest, UseSyncApiWithAsyncFile) {
751*635a8641SAndroid Build Coastguard Worker   base::ScopedTempDir temp_dir;
752*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
753*635a8641SAndroid Build Coastguard Worker   FilePath file_path = temp_dir.GetPath().AppendASCII("file");
754*635a8641SAndroid Build Coastguard Worker 
755*635a8641SAndroid Build Coastguard Worker   File file(file_path, base::File::FLAG_CREATE | base::File::FLAG_WRITE |
756*635a8641SAndroid Build Coastguard Worker                            base::File::FLAG_ASYNC);
757*635a8641SAndroid Build Coastguard Worker   File lying_file(file.TakePlatformFile(), false /* async */);
758*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(lying_file.IsValid());
759*635a8641SAndroid Build Coastguard Worker 
760*635a8641SAndroid Build Coastguard Worker   ASSERT_EQ(lying_file.WriteAtCurrentPos("12345", 5), -1);
761*635a8641SAndroid Build Coastguard Worker }
762*635a8641SAndroid Build Coastguard Worker #endif  // defined(OS_WIN)
763