xref: /aosp_15_r20/external/cronet/base/files/file_proxy_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/files/file_proxy.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
8*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include <string_view>
11*6777b538SAndroid Build Coastguard Worker #include <utility>
12*6777b538SAndroid Build Coastguard Worker 
13*6777b538SAndroid Build Coastguard Worker #include "base/containers/heap_array.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/files/file.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/files/file_util.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/files/scoped_temp_dir.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/memory/weak_ptr.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/test/task_environment.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread_restrictions.h"
24*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
25*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
26*6777b538SAndroid Build Coastguard Worker 
27*6777b538SAndroid Build Coastguard Worker namespace base {
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker class FileProxyTest : public testing::Test {
30*6777b538SAndroid Build Coastguard Worker  public:
FileProxyTest()31*6777b538SAndroid Build Coastguard Worker   FileProxyTest()
32*6777b538SAndroid Build Coastguard Worker       : task_environment_(test::TaskEnvironment::MainThreadType::IO),
33*6777b538SAndroid Build Coastguard Worker         file_thread_("FileProxyTestFileThread"),
34*6777b538SAndroid Build Coastguard Worker         error_(File::FILE_OK),
35*6777b538SAndroid Build Coastguard Worker         bytes_written_(-1) {}
36*6777b538SAndroid Build Coastguard Worker 
SetUp()37*6777b538SAndroid Build Coastguard Worker   void SetUp() override {
38*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(dir_.CreateUniqueTempDir());
39*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(file_thread_.Start());
40*6777b538SAndroid Build Coastguard Worker   }
41*6777b538SAndroid Build Coastguard Worker 
DidFinish(base::RepeatingClosure continuation,File::Error error)42*6777b538SAndroid Build Coastguard Worker   void DidFinish(base::RepeatingClosure continuation, File::Error error) {
43*6777b538SAndroid Build Coastguard Worker     error_ = error;
44*6777b538SAndroid Build Coastguard Worker     continuation.Run();
45*6777b538SAndroid Build Coastguard Worker   }
46*6777b538SAndroid Build Coastguard Worker 
DidCreateOrOpen(base::RepeatingClosure continuation,File::Error error)47*6777b538SAndroid Build Coastguard Worker   void DidCreateOrOpen(base::RepeatingClosure continuation, File::Error error) {
48*6777b538SAndroid Build Coastguard Worker     error_ = error;
49*6777b538SAndroid Build Coastguard Worker     continuation.Run();
50*6777b538SAndroid Build Coastguard Worker   }
51*6777b538SAndroid Build Coastguard Worker 
DidCreateTemporary(base::RepeatingClosure continuation,File::Error error,const FilePath & path)52*6777b538SAndroid Build Coastguard Worker   void DidCreateTemporary(base::RepeatingClosure continuation,
53*6777b538SAndroid Build Coastguard Worker                           File::Error error,
54*6777b538SAndroid Build Coastguard Worker                           const FilePath& path) {
55*6777b538SAndroid Build Coastguard Worker     error_ = error;
56*6777b538SAndroid Build Coastguard Worker     path_ = path;
57*6777b538SAndroid Build Coastguard Worker     continuation.Run();
58*6777b538SAndroid Build Coastguard Worker   }
59*6777b538SAndroid Build Coastguard Worker 
DidGetFileInfo(base::RepeatingClosure continuation,File::Error error,const File::Info & file_info)60*6777b538SAndroid Build Coastguard Worker   void DidGetFileInfo(base::RepeatingClosure continuation,
61*6777b538SAndroid Build Coastguard Worker                       File::Error error,
62*6777b538SAndroid Build Coastguard Worker                       const File::Info& file_info) {
63*6777b538SAndroid Build Coastguard Worker     error_ = error;
64*6777b538SAndroid Build Coastguard Worker     file_info_ = file_info;
65*6777b538SAndroid Build Coastguard Worker     continuation.Run();
66*6777b538SAndroid Build Coastguard Worker   }
67*6777b538SAndroid Build Coastguard Worker 
DidRead(base::RepeatingClosure continuation,File::Error error,base::span<const char> data)68*6777b538SAndroid Build Coastguard Worker   void DidRead(base::RepeatingClosure continuation,
69*6777b538SAndroid Build Coastguard Worker                File::Error error,
70*6777b538SAndroid Build Coastguard Worker                base::span<const char> data) {
71*6777b538SAndroid Build Coastguard Worker     error_ = error;
72*6777b538SAndroid Build Coastguard Worker     buffer_ = base::HeapArray<char>::CopiedFrom(data);
73*6777b538SAndroid Build Coastguard Worker     continuation.Run();
74*6777b538SAndroid Build Coastguard Worker   }
75*6777b538SAndroid Build Coastguard Worker 
DidWrite(base::RepeatingClosure continuation,File::Error error,int bytes_written)76*6777b538SAndroid Build Coastguard Worker   void DidWrite(base::RepeatingClosure continuation,
77*6777b538SAndroid Build Coastguard Worker                 File::Error error,
78*6777b538SAndroid Build Coastguard Worker                 int bytes_written) {
79*6777b538SAndroid Build Coastguard Worker     error_ = error;
80*6777b538SAndroid Build Coastguard Worker     bytes_written_ = bytes_written;
81*6777b538SAndroid Build Coastguard Worker     continuation.Run();
82*6777b538SAndroid Build Coastguard Worker   }
83*6777b538SAndroid Build Coastguard Worker 
84*6777b538SAndroid Build Coastguard Worker  protected:
CreateProxy(uint32_t flags,FileProxy * proxy)85*6777b538SAndroid Build Coastguard Worker   void CreateProxy(uint32_t flags, FileProxy* proxy) {
86*6777b538SAndroid Build Coastguard Worker     RunLoop run_loop;
87*6777b538SAndroid Build Coastguard Worker     proxy->CreateOrOpen(
88*6777b538SAndroid Build Coastguard Worker         TestPath(), flags,
89*6777b538SAndroid Build Coastguard Worker         BindOnce(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr(),
90*6777b538SAndroid Build Coastguard Worker                  run_loop.QuitWhenIdleClosure()));
91*6777b538SAndroid Build Coastguard Worker     run_loop.Run();
92*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(proxy->IsValid());
93*6777b538SAndroid Build Coastguard Worker   }
94*6777b538SAndroid Build Coastguard Worker 
file_task_runner() const95*6777b538SAndroid Build Coastguard Worker   TaskRunner* file_task_runner() const {
96*6777b538SAndroid Build Coastguard Worker     return file_thread_.task_runner().get();
97*6777b538SAndroid Build Coastguard Worker   }
TestDirPath() const98*6777b538SAndroid Build Coastguard Worker   const FilePath& TestDirPath() const { return dir_.GetPath(); }
TestPath() const99*6777b538SAndroid Build Coastguard Worker   const FilePath TestPath() const { return dir_.GetPath().AppendASCII("test"); }
100*6777b538SAndroid Build Coastguard Worker 
101*6777b538SAndroid Build Coastguard Worker   ScopedTempDir dir_;
102*6777b538SAndroid Build Coastguard Worker   test::TaskEnvironment task_environment_;
103*6777b538SAndroid Build Coastguard Worker   Thread file_thread_;
104*6777b538SAndroid Build Coastguard Worker 
105*6777b538SAndroid Build Coastguard Worker   File::Error error_;
106*6777b538SAndroid Build Coastguard Worker   FilePath path_;
107*6777b538SAndroid Build Coastguard Worker   File::Info file_info_;
108*6777b538SAndroid Build Coastguard Worker   base::HeapArray<char> buffer_;
109*6777b538SAndroid Build Coastguard Worker   int bytes_written_;
110*6777b538SAndroid Build Coastguard Worker   WeakPtrFactory<FileProxyTest> weak_factory_{this};
111*6777b538SAndroid Build Coastguard Worker };
112*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileProxyTest,CreateOrOpen_Create)113*6777b538SAndroid Build Coastguard Worker TEST_F(FileProxyTest, CreateOrOpen_Create) {
114*6777b538SAndroid Build Coastguard Worker   FileProxy proxy(file_task_runner());
115*6777b538SAndroid Build Coastguard Worker   RunLoop run_loop;
116*6777b538SAndroid Build Coastguard Worker   proxy.CreateOrOpen(
117*6777b538SAndroid Build Coastguard Worker       TestPath(), File::FLAG_CREATE | File::FLAG_READ,
118*6777b538SAndroid Build Coastguard Worker       BindOnce(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr(),
119*6777b538SAndroid Build Coastguard Worker                run_loop.QuitWhenIdleClosure()));
120*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
121*6777b538SAndroid Build Coastguard Worker 
122*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(File::FILE_OK, error_);
123*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(proxy.IsValid());
124*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(proxy.created());
125*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(PathExists(TestPath()));
126*6777b538SAndroid Build Coastguard Worker }
127*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileProxyTest,CreateOrOpen_Open)128*6777b538SAndroid Build Coastguard Worker TEST_F(FileProxyTest, CreateOrOpen_Open) {
129*6777b538SAndroid Build Coastguard Worker   // Creates a file.
130*6777b538SAndroid Build Coastguard Worker   base::WriteFile(TestPath(), base::StringPiece());
131*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(PathExists(TestPath()));
132*6777b538SAndroid Build Coastguard Worker 
133*6777b538SAndroid Build Coastguard Worker   // Opens the created file.
134*6777b538SAndroid Build Coastguard Worker   FileProxy proxy(file_task_runner());
135*6777b538SAndroid Build Coastguard Worker   RunLoop run_loop;
136*6777b538SAndroid Build Coastguard Worker   proxy.CreateOrOpen(
137*6777b538SAndroid Build Coastguard Worker       TestPath(), File::FLAG_OPEN | File::FLAG_READ,
138*6777b538SAndroid Build Coastguard Worker       BindOnce(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr(),
139*6777b538SAndroid Build Coastguard Worker                run_loop.QuitWhenIdleClosure()));
140*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
141*6777b538SAndroid Build Coastguard Worker 
142*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(File::FILE_OK, error_);
143*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(proxy.IsValid());
144*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(proxy.created());
145*6777b538SAndroid Build Coastguard Worker }
146*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileProxyTest,CreateOrOpen_OpenNonExistent)147*6777b538SAndroid Build Coastguard Worker TEST_F(FileProxyTest, CreateOrOpen_OpenNonExistent) {
148*6777b538SAndroid Build Coastguard Worker   FileProxy proxy(file_task_runner());
149*6777b538SAndroid Build Coastguard Worker   RunLoop run_loop;
150*6777b538SAndroid Build Coastguard Worker   proxy.CreateOrOpen(
151*6777b538SAndroid Build Coastguard Worker       TestPath(), File::FLAG_OPEN | File::FLAG_READ,
152*6777b538SAndroid Build Coastguard Worker       BindOnce(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr(),
153*6777b538SAndroid Build Coastguard Worker                run_loop.QuitWhenIdleClosure()));
154*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
155*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(File::FILE_ERROR_NOT_FOUND, error_);
156*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(proxy.IsValid());
157*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(proxy.created());
158*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(PathExists(TestPath()));
159*6777b538SAndroid Build Coastguard Worker }
160*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileProxyTest,CreateOrOpen_AbandonedCreate)161*6777b538SAndroid Build Coastguard Worker TEST_F(FileProxyTest, CreateOrOpen_AbandonedCreate) {
162*6777b538SAndroid Build Coastguard Worker   {
163*6777b538SAndroid Build Coastguard Worker     base::ScopedDisallowBlocking disallow_blocking;
164*6777b538SAndroid Build Coastguard Worker     RunLoop run_loop;
165*6777b538SAndroid Build Coastguard Worker     {
166*6777b538SAndroid Build Coastguard Worker       FileProxy proxy(file_task_runner());
167*6777b538SAndroid Build Coastguard Worker       proxy.CreateOrOpen(
168*6777b538SAndroid Build Coastguard Worker           TestPath(), File::FLAG_CREATE | File::FLAG_READ,
169*6777b538SAndroid Build Coastguard Worker           BindOnce(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr(),
170*6777b538SAndroid Build Coastguard Worker                    run_loop.QuitWhenIdleClosure()));
171*6777b538SAndroid Build Coastguard Worker     }
172*6777b538SAndroid Build Coastguard Worker     run_loop.Run();
173*6777b538SAndroid Build Coastguard Worker   }
174*6777b538SAndroid Build Coastguard Worker 
175*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(PathExists(TestPath()));
176*6777b538SAndroid Build Coastguard Worker }
177*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileProxyTest,Close)178*6777b538SAndroid Build Coastguard Worker TEST_F(FileProxyTest, Close) {
179*6777b538SAndroid Build Coastguard Worker   // Creates a file.
180*6777b538SAndroid Build Coastguard Worker   FileProxy proxy(file_task_runner());
181*6777b538SAndroid Build Coastguard Worker   CreateProxy(File::FLAG_CREATE | File::FLAG_WRITE, &proxy);
182*6777b538SAndroid Build Coastguard Worker 
183*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
184*6777b538SAndroid Build Coastguard Worker   // This fails on Windows if the file is not closed.
185*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(base::Move(TestPath(), TestDirPath().AppendASCII("new")));
186*6777b538SAndroid Build Coastguard Worker #endif
187*6777b538SAndroid Build Coastguard Worker 
188*6777b538SAndroid Build Coastguard Worker   RunLoop run_loop;
189*6777b538SAndroid Build Coastguard Worker   proxy.Close(BindOnce(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr(),
190*6777b538SAndroid Build Coastguard Worker                        run_loop.QuitWhenIdleClosure()));
191*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
192*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(File::FILE_OK, error_);
193*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(proxy.IsValid());
194*6777b538SAndroid Build Coastguard Worker 
195*6777b538SAndroid Build Coastguard Worker   // Now it should pass on all platforms.
196*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::Move(TestPath(), TestDirPath().AppendASCII("new")));
197*6777b538SAndroid Build Coastguard Worker }
198*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileProxyTest,CreateTemporary)199*6777b538SAndroid Build Coastguard Worker TEST_F(FileProxyTest, CreateTemporary) {
200*6777b538SAndroid Build Coastguard Worker   {
201*6777b538SAndroid Build Coastguard Worker     FileProxy proxy(file_task_runner());
202*6777b538SAndroid Build Coastguard Worker     {
203*6777b538SAndroid Build Coastguard Worker       RunLoop run_loop;
204*6777b538SAndroid Build Coastguard Worker       proxy.CreateTemporary(
205*6777b538SAndroid Build Coastguard Worker           0 /* additional_file_flags */,
206*6777b538SAndroid Build Coastguard Worker           BindOnce(&FileProxyTest::DidCreateTemporary,
207*6777b538SAndroid Build Coastguard Worker                    weak_factory_.GetWeakPtr(), run_loop.QuitWhenIdleClosure()));
208*6777b538SAndroid Build Coastguard Worker       run_loop.Run();
209*6777b538SAndroid Build Coastguard Worker     }
210*6777b538SAndroid Build Coastguard Worker 
211*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(proxy.IsValid());
212*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(File::FILE_OK, error_);
213*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(PathExists(path_));
214*6777b538SAndroid Build Coastguard Worker 
215*6777b538SAndroid Build Coastguard Worker     // The file should be writable.
216*6777b538SAndroid Build Coastguard Worker     {
217*6777b538SAndroid Build Coastguard Worker       RunLoop run_loop;
218*6777b538SAndroid Build Coastguard Worker       proxy.Write(0, base::as_byte_span(std::string_view("test")),
219*6777b538SAndroid Build Coastguard Worker                   BindOnce(&FileProxyTest::DidWrite, weak_factory_.GetWeakPtr(),
220*6777b538SAndroid Build Coastguard Worker                            run_loop.QuitWhenIdleClosure()));
221*6777b538SAndroid Build Coastguard Worker       run_loop.Run();
222*6777b538SAndroid Build Coastguard Worker     }
223*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(File::FILE_OK, error_);
224*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(4, bytes_written_);
225*6777b538SAndroid Build Coastguard Worker   }
226*6777b538SAndroid Build Coastguard Worker 
227*6777b538SAndroid Build Coastguard Worker   // Make sure the written data can be read from the returned path.
228*6777b538SAndroid Build Coastguard Worker   std::string data;
229*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ReadFileToString(path_, &data));
230*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("test", data);
231*6777b538SAndroid Build Coastguard Worker 
232*6777b538SAndroid Build Coastguard Worker   // Make sure we can & do delete the created file to prevent leaks on the bots.
233*6777b538SAndroid Build Coastguard Worker   // Try a few times because files may be locked by anti-virus or other.
234*6777b538SAndroid Build Coastguard Worker   bool deleted_temp_file = false;
235*6777b538SAndroid Build Coastguard Worker   for (int i = 0; !deleted_temp_file && i < 3; ++i) {
236*6777b538SAndroid Build Coastguard Worker     if (base::DeleteFile(path_))
237*6777b538SAndroid Build Coastguard Worker       deleted_temp_file = true;
238*6777b538SAndroid Build Coastguard Worker     else
239*6777b538SAndroid Build Coastguard Worker       // Wait one second and then try again
240*6777b538SAndroid Build Coastguard Worker       PlatformThread::Sleep(Seconds(1));
241*6777b538SAndroid Build Coastguard Worker   }
242*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(deleted_temp_file);
243*6777b538SAndroid Build Coastguard Worker }
244*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileProxyTest,SetAndTake)245*6777b538SAndroid Build Coastguard Worker TEST_F(FileProxyTest, SetAndTake) {
246*6777b538SAndroid Build Coastguard Worker   File file(TestPath(), File::FLAG_CREATE | File::FLAG_READ);
247*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
248*6777b538SAndroid Build Coastguard Worker   FileProxy proxy(file_task_runner());
249*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(proxy.IsValid());
250*6777b538SAndroid Build Coastguard Worker   proxy.SetFile(std::move(file));
251*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(proxy.IsValid());
252*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(file.IsValid());
253*6777b538SAndroid Build Coastguard Worker 
254*6777b538SAndroid Build Coastguard Worker   file = proxy.TakeFile();
255*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(proxy.IsValid());
256*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(file.IsValid());
257*6777b538SAndroid Build Coastguard Worker }
258*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileProxyTest,DuplicateFile)259*6777b538SAndroid Build Coastguard Worker TEST_F(FileProxyTest, DuplicateFile) {
260*6777b538SAndroid Build Coastguard Worker   FileProxy proxy(file_task_runner());
261*6777b538SAndroid Build Coastguard Worker   CreateProxy(File::FLAG_CREATE | File::FLAG_WRITE, &proxy);
262*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(proxy.IsValid());
263*6777b538SAndroid Build Coastguard Worker 
264*6777b538SAndroid Build Coastguard Worker   base::File duplicate = proxy.DuplicateFile();
265*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(proxy.IsValid());
266*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(duplicate.IsValid());
267*6777b538SAndroid Build Coastguard Worker 
268*6777b538SAndroid Build Coastguard Worker   FileProxy invalid_proxy(file_task_runner());
269*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(invalid_proxy.IsValid());
270*6777b538SAndroid Build Coastguard Worker 
271*6777b538SAndroid Build Coastguard Worker   base::File invalid_duplicate = invalid_proxy.DuplicateFile();
272*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(invalid_proxy.IsValid());
273*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(invalid_duplicate.IsValid());
274*6777b538SAndroid Build Coastguard Worker }
275*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileProxyTest,GetInfo)276*6777b538SAndroid Build Coastguard Worker TEST_F(FileProxyTest, GetInfo) {
277*6777b538SAndroid Build Coastguard Worker   // Setup.
278*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(base::WriteFile(TestPath(), "test"));
279*6777b538SAndroid Build Coastguard Worker   File::Info expected_info;
280*6777b538SAndroid Build Coastguard Worker   GetFileInfo(TestPath(), &expected_info);
281*6777b538SAndroid Build Coastguard Worker 
282*6777b538SAndroid Build Coastguard Worker   // Run.
283*6777b538SAndroid Build Coastguard Worker   FileProxy proxy(file_task_runner());
284*6777b538SAndroid Build Coastguard Worker   CreateProxy(File::FLAG_OPEN | File::FLAG_READ, &proxy);
285*6777b538SAndroid Build Coastguard Worker   RunLoop run_loop;
286*6777b538SAndroid Build Coastguard Worker   proxy.GetInfo(BindOnce(&FileProxyTest::DidGetFileInfo,
287*6777b538SAndroid Build Coastguard Worker                          weak_factory_.GetWeakPtr(),
288*6777b538SAndroid Build Coastguard Worker                          run_loop.QuitWhenIdleClosure()));
289*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
290*6777b538SAndroid Build Coastguard Worker 
291*6777b538SAndroid Build Coastguard Worker   // Verify.
292*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(File::FILE_OK, error_);
293*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected_info.size, file_info_.size);
294*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected_info.is_directory, file_info_.is_directory);
295*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected_info.is_symbolic_link, file_info_.is_symbolic_link);
296*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected_info.last_modified, file_info_.last_modified);
297*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected_info.creation_time, file_info_.creation_time);
298*6777b538SAndroid Build Coastguard Worker }
299*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileProxyTest,Read)300*6777b538SAndroid Build Coastguard Worker TEST_F(FileProxyTest, Read) {
301*6777b538SAndroid Build Coastguard Worker   // Setup.
302*6777b538SAndroid Build Coastguard Worker   constexpr base::StringPiece expected_data = "bleh";
303*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(base::WriteFile(TestPath(), expected_data));
304*6777b538SAndroid Build Coastguard Worker 
305*6777b538SAndroid Build Coastguard Worker   // Run.
306*6777b538SAndroid Build Coastguard Worker   FileProxy proxy(file_task_runner());
307*6777b538SAndroid Build Coastguard Worker   CreateProxy(File::FLAG_OPEN | File::FLAG_READ, &proxy);
308*6777b538SAndroid Build Coastguard Worker 
309*6777b538SAndroid Build Coastguard Worker   RunLoop run_loop;
310*6777b538SAndroid Build Coastguard Worker   proxy.Read(0, 128,
311*6777b538SAndroid Build Coastguard Worker              BindOnce(&FileProxyTest::DidRead, weak_factory_.GetWeakPtr(),
312*6777b538SAndroid Build Coastguard Worker                       run_loop.QuitWhenIdleClosure()));
313*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
314*6777b538SAndroid Build Coastguard Worker 
315*6777b538SAndroid Build Coastguard Worker   // Verify.
316*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(File::FILE_OK, error_);
317*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(expected_data, base::StringPiece(buffer_.data(), buffer_.size()));
318*6777b538SAndroid Build Coastguard Worker }
319*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileProxyTest,WriteAndFlush)320*6777b538SAndroid Build Coastguard Worker TEST_F(FileProxyTest, WriteAndFlush) {
321*6777b538SAndroid Build Coastguard Worker   FileProxy proxy(file_task_runner());
322*6777b538SAndroid Build Coastguard Worker   CreateProxy(File::FLAG_CREATE | File::FLAG_WRITE, &proxy);
323*6777b538SAndroid Build Coastguard Worker 
324*6777b538SAndroid Build Coastguard Worker   auto write_span = base::as_byte_span("foo!");
325*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(write_span.size(), 5u);  // Includes the NUL, too.
326*6777b538SAndroid Build Coastguard Worker   {
327*6777b538SAndroid Build Coastguard Worker     RunLoop run_loop;
328*6777b538SAndroid Build Coastguard Worker     proxy.Write(0, write_span,
329*6777b538SAndroid Build Coastguard Worker                 BindOnce(&FileProxyTest::DidWrite, weak_factory_.GetWeakPtr(),
330*6777b538SAndroid Build Coastguard Worker                          run_loop.QuitWhenIdleClosure()));
331*6777b538SAndroid Build Coastguard Worker     run_loop.Run();
332*6777b538SAndroid Build Coastguard Worker   }
333*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(File::FILE_OK, error_);
334*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(write_span.size(), static_cast<size_t>(bytes_written_));
335*6777b538SAndroid Build Coastguard Worker 
336*6777b538SAndroid Build Coastguard Worker   // Flush the written data.  (So that the following read should always
337*6777b538SAndroid Build Coastguard Worker   // succeed.  On some platforms it may work with or without this flush.)
338*6777b538SAndroid Build Coastguard Worker   {
339*6777b538SAndroid Build Coastguard Worker     RunLoop run_loop;
340*6777b538SAndroid Build Coastguard Worker     proxy.Flush(BindOnce(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr(),
341*6777b538SAndroid Build Coastguard Worker                          run_loop.QuitWhenIdleClosure()));
342*6777b538SAndroid Build Coastguard Worker     run_loop.Run();
343*6777b538SAndroid Build Coastguard Worker   }
344*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(File::FILE_OK, error_);
345*6777b538SAndroid Build Coastguard Worker 
346*6777b538SAndroid Build Coastguard Worker   // Verify the written data.
347*6777b538SAndroid Build Coastguard Worker   char read_buffer[10];
348*6777b538SAndroid Build Coastguard Worker   EXPECT_GE(std::size(read_buffer), write_span.size());
349*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(write_span.size(), base::ReadFile(TestPath(), read_buffer));
350*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < write_span.size(); ++i) {
351*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(write_span[i], read_buffer[i]);
352*6777b538SAndroid Build Coastguard Worker   }
353*6777b538SAndroid Build Coastguard Worker }
354*6777b538SAndroid Build Coastguard Worker 
355*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID)
356*6777b538SAndroid Build Coastguard Worker // Flaky on Android, see http://crbug.com/489602
357*6777b538SAndroid Build Coastguard Worker #define MAYBE_SetTimes DISABLED_SetTimes
358*6777b538SAndroid Build Coastguard Worker #else
359*6777b538SAndroid Build Coastguard Worker #define MAYBE_SetTimes SetTimes
360*6777b538SAndroid Build Coastguard Worker #endif
TEST_F(FileProxyTest,MAYBE_SetTimes)361*6777b538SAndroid Build Coastguard Worker TEST_F(FileProxyTest, MAYBE_SetTimes) {
362*6777b538SAndroid Build Coastguard Worker   FileProxy proxy(file_task_runner());
363*6777b538SAndroid Build Coastguard Worker   CreateProxy(
364*6777b538SAndroid Build Coastguard Worker       File::FLAG_CREATE | File::FLAG_WRITE | File::FLAG_WRITE_ATTRIBUTES,
365*6777b538SAndroid Build Coastguard Worker       &proxy);
366*6777b538SAndroid Build Coastguard Worker 
367*6777b538SAndroid Build Coastguard Worker   Time last_accessed_time = Time::Now() - Days(12345);
368*6777b538SAndroid Build Coastguard Worker   Time last_modified_time = Time::Now() - Hours(98765);
369*6777b538SAndroid Build Coastguard Worker 
370*6777b538SAndroid Build Coastguard Worker   RunLoop run_loop;
371*6777b538SAndroid Build Coastguard Worker   proxy.SetTimes(last_accessed_time, last_modified_time,
372*6777b538SAndroid Build Coastguard Worker                  BindOnce(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr(),
373*6777b538SAndroid Build Coastguard Worker                           run_loop.QuitWhenIdleClosure()));
374*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
375*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(File::FILE_OK, error_);
376*6777b538SAndroid Build Coastguard Worker 
377*6777b538SAndroid Build Coastguard Worker   File::Info info;
378*6777b538SAndroid Build Coastguard Worker   GetFileInfo(TestPath(), &info);
379*6777b538SAndroid Build Coastguard Worker 
380*6777b538SAndroid Build Coastguard Worker   // The returned values may only have the seconds precision, so we cast
381*6777b538SAndroid Build Coastguard Worker   // the double values to int here.
382*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<int>(last_modified_time.InSecondsFSinceUnixEpoch()),
383*6777b538SAndroid Build Coastguard Worker             static_cast<int>(info.last_modified.InSecondsFSinceUnixEpoch()));
384*6777b538SAndroid Build Coastguard Worker 
385*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(IS_FUCHSIA)
386*6777b538SAndroid Build Coastguard Worker   // On Fuchsia, /tmp is noatime
387*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<int>(last_accessed_time.InSecondsFSinceUnixEpoch()),
388*6777b538SAndroid Build Coastguard Worker             static_cast<int>(info.last_accessed.InSecondsFSinceUnixEpoch()));
389*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_FUCHSIA)
390*6777b538SAndroid Build Coastguard Worker }
391*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileProxyTest,SetLength_Shrink)392*6777b538SAndroid Build Coastguard Worker TEST_F(FileProxyTest, SetLength_Shrink) {
393*6777b538SAndroid Build Coastguard Worker   // Setup.
394*6777b538SAndroid Build Coastguard Worker   const char kTestData[] = "0123456789";
395*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(base::WriteFile(TestPath(), kTestData));
396*6777b538SAndroid Build Coastguard Worker   File::Info info;
397*6777b538SAndroid Build Coastguard Worker   GetFileInfo(TestPath(), &info);
398*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(10, info.size);
399*6777b538SAndroid Build Coastguard Worker 
400*6777b538SAndroid Build Coastguard Worker   // Run.
401*6777b538SAndroid Build Coastguard Worker   FileProxy proxy(file_task_runner());
402*6777b538SAndroid Build Coastguard Worker   CreateProxy(File::FLAG_OPEN | File::FLAG_WRITE, &proxy);
403*6777b538SAndroid Build Coastguard Worker   RunLoop run_loop;
404*6777b538SAndroid Build Coastguard Worker   proxy.SetLength(
405*6777b538SAndroid Build Coastguard Worker       7, BindOnce(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr(),
406*6777b538SAndroid Build Coastguard Worker                   run_loop.QuitWhenIdleClosure()));
407*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
408*6777b538SAndroid Build Coastguard Worker 
409*6777b538SAndroid Build Coastguard Worker   // Verify.
410*6777b538SAndroid Build Coastguard Worker   GetFileInfo(TestPath(), &info);
411*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(7, info.size);
412*6777b538SAndroid Build Coastguard Worker 
413*6777b538SAndroid Build Coastguard Worker   char buffer[7];
414*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(7, base::ReadFile(TestPath(), buffer));
415*6777b538SAndroid Build Coastguard Worker   int i = 0;
416*6777b538SAndroid Build Coastguard Worker   for (; i < 7; ++i)
417*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kTestData[i], buffer[i]);
418*6777b538SAndroid Build Coastguard Worker }
419*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileProxyTest,SetLength_Expand)420*6777b538SAndroid Build Coastguard Worker TEST_F(FileProxyTest, SetLength_Expand) {
421*6777b538SAndroid Build Coastguard Worker   // Setup.
422*6777b538SAndroid Build Coastguard Worker   const char kTestData[] = "9876543210";
423*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(base::WriteFile(TestPath(), kTestData));
424*6777b538SAndroid Build Coastguard Worker   File::Info info;
425*6777b538SAndroid Build Coastguard Worker   GetFileInfo(TestPath(), &info);
426*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(10, info.size);
427*6777b538SAndroid Build Coastguard Worker 
428*6777b538SAndroid Build Coastguard Worker   // Run.
429*6777b538SAndroid Build Coastguard Worker   FileProxy proxy(file_task_runner());
430*6777b538SAndroid Build Coastguard Worker   CreateProxy(File::FLAG_OPEN | File::FLAG_WRITE, &proxy);
431*6777b538SAndroid Build Coastguard Worker   RunLoop run_loop;
432*6777b538SAndroid Build Coastguard Worker   proxy.SetLength(
433*6777b538SAndroid Build Coastguard Worker       53, BindOnce(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr(),
434*6777b538SAndroid Build Coastguard Worker                    run_loop.QuitWhenIdleClosure()));
435*6777b538SAndroid Build Coastguard Worker   run_loop.Run();
436*6777b538SAndroid Build Coastguard Worker 
437*6777b538SAndroid Build Coastguard Worker   // Verify.
438*6777b538SAndroid Build Coastguard Worker   GetFileInfo(TestPath(), &info);
439*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(53, info.size);
440*6777b538SAndroid Build Coastguard Worker 
441*6777b538SAndroid Build Coastguard Worker   char buffer[53];
442*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(53, base::ReadFile(TestPath(), buffer));
443*6777b538SAndroid Build Coastguard Worker   int i = 0;
444*6777b538SAndroid Build Coastguard Worker   for (; i < 10; ++i)
445*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kTestData[i], buffer[i]);
446*6777b538SAndroid Build Coastguard Worker   for (; i < 53; ++i)
447*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(0, buffer[i]);
448*6777b538SAndroid Build Coastguard Worker }
449*6777b538SAndroid Build Coastguard Worker 
450*6777b538SAndroid Build Coastguard Worker }  // namespace base
451