1*635a8641SAndroid Build Coastguard Worker // Copyright 2014 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_proxy.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
8*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
9*635a8641SAndroid Build Coastguard Worker
10*635a8641SAndroid Build Coastguard Worker #include <utility>
11*635a8641SAndroid Build Coastguard Worker
12*635a8641SAndroid Build Coastguard Worker #include "base/bind.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/files/file.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/files/file_util.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/files/scoped_temp_dir.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/memory/weak_ptr.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/message_loop/message_loop.h"
19*635a8641SAndroid Build Coastguard Worker #include "base/run_loop.h"
20*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread.h"
21*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread_restrictions.h"
22*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
23*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
24*635a8641SAndroid Build Coastguard Worker
25*635a8641SAndroid Build Coastguard Worker namespace base {
26*635a8641SAndroid Build Coastguard Worker
27*635a8641SAndroid Build Coastguard Worker class FileProxyTest : public testing::Test {
28*635a8641SAndroid Build Coastguard Worker public:
FileProxyTest()29*635a8641SAndroid Build Coastguard Worker FileProxyTest()
30*635a8641SAndroid Build Coastguard Worker : file_thread_("FileProxyTestFileThread"),
31*635a8641SAndroid Build Coastguard Worker error_(File::FILE_OK),
32*635a8641SAndroid Build Coastguard Worker bytes_written_(-1),
33*635a8641SAndroid Build Coastguard Worker weak_factory_(this) {}
34*635a8641SAndroid Build Coastguard Worker
SetUp()35*635a8641SAndroid Build Coastguard Worker void SetUp() override {
36*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(dir_.CreateUniqueTempDir());
37*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(file_thread_.Start());
38*635a8641SAndroid Build Coastguard Worker }
39*635a8641SAndroid Build Coastguard Worker
DidFinish(File::Error error)40*635a8641SAndroid Build Coastguard Worker void DidFinish(File::Error error) {
41*635a8641SAndroid Build Coastguard Worker error_ = error;
42*635a8641SAndroid Build Coastguard Worker RunLoop::QuitCurrentWhenIdleDeprecated();
43*635a8641SAndroid Build Coastguard Worker }
44*635a8641SAndroid Build Coastguard Worker
DidCreateOrOpen(File::Error error)45*635a8641SAndroid Build Coastguard Worker void DidCreateOrOpen(File::Error error) {
46*635a8641SAndroid Build Coastguard Worker error_ = error;
47*635a8641SAndroid Build Coastguard Worker RunLoop::QuitCurrentWhenIdleDeprecated();
48*635a8641SAndroid Build Coastguard Worker }
49*635a8641SAndroid Build Coastguard Worker
DidCreateTemporary(File::Error error,const FilePath & path)50*635a8641SAndroid Build Coastguard Worker void DidCreateTemporary(File::Error error,
51*635a8641SAndroid Build Coastguard Worker const FilePath& path) {
52*635a8641SAndroid Build Coastguard Worker error_ = error;
53*635a8641SAndroid Build Coastguard Worker path_ = path;
54*635a8641SAndroid Build Coastguard Worker RunLoop::QuitCurrentWhenIdleDeprecated();
55*635a8641SAndroid Build Coastguard Worker }
56*635a8641SAndroid Build Coastguard Worker
DidGetFileInfo(File::Error error,const File::Info & file_info)57*635a8641SAndroid Build Coastguard Worker void DidGetFileInfo(File::Error error,
58*635a8641SAndroid Build Coastguard Worker const File::Info& file_info) {
59*635a8641SAndroid Build Coastguard Worker error_ = error;
60*635a8641SAndroid Build Coastguard Worker file_info_ = file_info;
61*635a8641SAndroid Build Coastguard Worker RunLoop::QuitCurrentWhenIdleDeprecated();
62*635a8641SAndroid Build Coastguard Worker }
63*635a8641SAndroid Build Coastguard Worker
DidRead(File::Error error,const char * data,int bytes_read)64*635a8641SAndroid Build Coastguard Worker void DidRead(File::Error error,
65*635a8641SAndroid Build Coastguard Worker const char* data,
66*635a8641SAndroid Build Coastguard Worker int bytes_read) {
67*635a8641SAndroid Build Coastguard Worker error_ = error;
68*635a8641SAndroid Build Coastguard Worker buffer_.resize(bytes_read);
69*635a8641SAndroid Build Coastguard Worker memcpy(&buffer_[0], data, bytes_read);
70*635a8641SAndroid Build Coastguard Worker RunLoop::QuitCurrentWhenIdleDeprecated();
71*635a8641SAndroid Build Coastguard Worker }
72*635a8641SAndroid Build Coastguard Worker
DidWrite(File::Error error,int bytes_written)73*635a8641SAndroid Build Coastguard Worker void DidWrite(File::Error error,
74*635a8641SAndroid Build Coastguard Worker int bytes_written) {
75*635a8641SAndroid Build Coastguard Worker error_ = error;
76*635a8641SAndroid Build Coastguard Worker bytes_written_ = bytes_written;
77*635a8641SAndroid Build Coastguard Worker RunLoop::QuitCurrentWhenIdleDeprecated();
78*635a8641SAndroid Build Coastguard Worker }
79*635a8641SAndroid Build Coastguard Worker
80*635a8641SAndroid Build Coastguard Worker protected:
CreateProxy(uint32_t flags,FileProxy * proxy)81*635a8641SAndroid Build Coastguard Worker void CreateProxy(uint32_t flags, FileProxy* proxy) {
82*635a8641SAndroid Build Coastguard Worker proxy->CreateOrOpen(
83*635a8641SAndroid Build Coastguard Worker TestPath(), flags,
84*635a8641SAndroid Build Coastguard Worker BindOnce(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
85*635a8641SAndroid Build Coastguard Worker RunLoop().Run();
86*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(proxy->IsValid());
87*635a8641SAndroid Build Coastguard Worker }
88*635a8641SAndroid Build Coastguard Worker
file_task_runner() const89*635a8641SAndroid Build Coastguard Worker TaskRunner* file_task_runner() const {
90*635a8641SAndroid Build Coastguard Worker return file_thread_.task_runner().get();
91*635a8641SAndroid Build Coastguard Worker }
TestDirPath() const92*635a8641SAndroid Build Coastguard Worker const FilePath& TestDirPath() const { return dir_.GetPath(); }
TestPath() const93*635a8641SAndroid Build Coastguard Worker const FilePath TestPath() const { return dir_.GetPath().AppendASCII("test"); }
94*635a8641SAndroid Build Coastguard Worker
95*635a8641SAndroid Build Coastguard Worker ScopedTempDir dir_;
96*635a8641SAndroid Build Coastguard Worker MessageLoopForIO message_loop_;
97*635a8641SAndroid Build Coastguard Worker Thread file_thread_;
98*635a8641SAndroid Build Coastguard Worker
99*635a8641SAndroid Build Coastguard Worker File::Error error_;
100*635a8641SAndroid Build Coastguard Worker FilePath path_;
101*635a8641SAndroid Build Coastguard Worker File::Info file_info_;
102*635a8641SAndroid Build Coastguard Worker std::vector<char> buffer_;
103*635a8641SAndroid Build Coastguard Worker int bytes_written_;
104*635a8641SAndroid Build Coastguard Worker WeakPtrFactory<FileProxyTest> weak_factory_;
105*635a8641SAndroid Build Coastguard Worker };
106*635a8641SAndroid Build Coastguard Worker
TEST_F(FileProxyTest,CreateOrOpen_Create)107*635a8641SAndroid Build Coastguard Worker TEST_F(FileProxyTest, CreateOrOpen_Create) {
108*635a8641SAndroid Build Coastguard Worker FileProxy proxy(file_task_runner());
109*635a8641SAndroid Build Coastguard Worker proxy.CreateOrOpen(
110*635a8641SAndroid Build Coastguard Worker TestPath(), File::FLAG_CREATE | File::FLAG_READ,
111*635a8641SAndroid Build Coastguard Worker BindOnce(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
112*635a8641SAndroid Build Coastguard Worker RunLoop().Run();
113*635a8641SAndroid Build Coastguard Worker
114*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(File::FILE_OK, error_);
115*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(proxy.IsValid());
116*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(proxy.created());
117*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(PathExists(TestPath()));
118*635a8641SAndroid Build Coastguard Worker }
119*635a8641SAndroid Build Coastguard Worker
TEST_F(FileProxyTest,CreateOrOpen_Open)120*635a8641SAndroid Build Coastguard Worker TEST_F(FileProxyTest, CreateOrOpen_Open) {
121*635a8641SAndroid Build Coastguard Worker // Creates a file.
122*635a8641SAndroid Build Coastguard Worker base::WriteFile(TestPath(), nullptr, 0);
123*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(PathExists(TestPath()));
124*635a8641SAndroid Build Coastguard Worker
125*635a8641SAndroid Build Coastguard Worker // Opens the created file.
126*635a8641SAndroid Build Coastguard Worker FileProxy proxy(file_task_runner());
127*635a8641SAndroid Build Coastguard Worker proxy.CreateOrOpen(
128*635a8641SAndroid Build Coastguard Worker TestPath(), File::FLAG_OPEN | File::FLAG_READ,
129*635a8641SAndroid Build Coastguard Worker BindOnce(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
130*635a8641SAndroid Build Coastguard Worker RunLoop().Run();
131*635a8641SAndroid Build Coastguard Worker
132*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(File::FILE_OK, error_);
133*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(proxy.IsValid());
134*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(proxy.created());
135*635a8641SAndroid Build Coastguard Worker }
136*635a8641SAndroid Build Coastguard Worker
TEST_F(FileProxyTest,CreateOrOpen_OpenNonExistent)137*635a8641SAndroid Build Coastguard Worker TEST_F(FileProxyTest, CreateOrOpen_OpenNonExistent) {
138*635a8641SAndroid Build Coastguard Worker FileProxy proxy(file_task_runner());
139*635a8641SAndroid Build Coastguard Worker proxy.CreateOrOpen(
140*635a8641SAndroid Build Coastguard Worker TestPath(), File::FLAG_OPEN | File::FLAG_READ,
141*635a8641SAndroid Build Coastguard Worker BindOnce(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
142*635a8641SAndroid Build Coastguard Worker RunLoop().Run();
143*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(File::FILE_ERROR_NOT_FOUND, error_);
144*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(proxy.IsValid());
145*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(proxy.created());
146*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(PathExists(TestPath()));
147*635a8641SAndroid Build Coastguard Worker }
148*635a8641SAndroid Build Coastguard Worker
TEST_F(FileProxyTest,CreateOrOpen_AbandonedCreate)149*635a8641SAndroid Build Coastguard Worker TEST_F(FileProxyTest, CreateOrOpen_AbandonedCreate) {
150*635a8641SAndroid Build Coastguard Worker bool prev = ThreadRestrictions::SetIOAllowed(false);
151*635a8641SAndroid Build Coastguard Worker {
152*635a8641SAndroid Build Coastguard Worker FileProxy proxy(file_task_runner());
153*635a8641SAndroid Build Coastguard Worker proxy.CreateOrOpen(
154*635a8641SAndroid Build Coastguard Worker TestPath(), File::FLAG_CREATE | File::FLAG_READ,
155*635a8641SAndroid Build Coastguard Worker BindOnce(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
156*635a8641SAndroid Build Coastguard Worker }
157*635a8641SAndroid Build Coastguard Worker RunLoop().Run();
158*635a8641SAndroid Build Coastguard Worker ThreadRestrictions::SetIOAllowed(prev);
159*635a8641SAndroid Build Coastguard Worker
160*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(PathExists(TestPath()));
161*635a8641SAndroid Build Coastguard Worker }
162*635a8641SAndroid Build Coastguard Worker
TEST_F(FileProxyTest,Close)163*635a8641SAndroid Build Coastguard Worker TEST_F(FileProxyTest, Close) {
164*635a8641SAndroid Build Coastguard Worker // Creates a file.
165*635a8641SAndroid Build Coastguard Worker FileProxy proxy(file_task_runner());
166*635a8641SAndroid Build Coastguard Worker CreateProxy(File::FLAG_CREATE | File::FLAG_WRITE, &proxy);
167*635a8641SAndroid Build Coastguard Worker
168*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
169*635a8641SAndroid Build Coastguard Worker // This fails on Windows if the file is not closed.
170*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(base::Move(TestPath(), TestDirPath().AppendASCII("new")));
171*635a8641SAndroid Build Coastguard Worker #endif
172*635a8641SAndroid Build Coastguard Worker
173*635a8641SAndroid Build Coastguard Worker proxy.Close(BindOnce(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
174*635a8641SAndroid Build Coastguard Worker RunLoop().Run();
175*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(File::FILE_OK, error_);
176*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(proxy.IsValid());
177*635a8641SAndroid Build Coastguard Worker
178*635a8641SAndroid Build Coastguard Worker // Now it should pass on all platforms.
179*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(base::Move(TestPath(), TestDirPath().AppendASCII("new")));
180*635a8641SAndroid Build Coastguard Worker }
181*635a8641SAndroid Build Coastguard Worker
TEST_F(FileProxyTest,CreateTemporary)182*635a8641SAndroid Build Coastguard Worker TEST_F(FileProxyTest, CreateTemporary) {
183*635a8641SAndroid Build Coastguard Worker {
184*635a8641SAndroid Build Coastguard Worker FileProxy proxy(file_task_runner());
185*635a8641SAndroid Build Coastguard Worker proxy.CreateTemporary(0 /* additional_file_flags */,
186*635a8641SAndroid Build Coastguard Worker BindOnce(&FileProxyTest::DidCreateTemporary,
187*635a8641SAndroid Build Coastguard Worker weak_factory_.GetWeakPtr()));
188*635a8641SAndroid Build Coastguard Worker RunLoop().Run();
189*635a8641SAndroid Build Coastguard Worker
190*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(proxy.IsValid());
191*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(File::FILE_OK, error_);
192*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(PathExists(path_));
193*635a8641SAndroid Build Coastguard Worker
194*635a8641SAndroid Build Coastguard Worker // The file should be writable.
195*635a8641SAndroid Build Coastguard Worker proxy.Write(0, "test", 4,
196*635a8641SAndroid Build Coastguard Worker BindOnce(&FileProxyTest::DidWrite, weak_factory_.GetWeakPtr()));
197*635a8641SAndroid Build Coastguard Worker RunLoop().Run();
198*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(File::FILE_OK, error_);
199*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(4, bytes_written_);
200*635a8641SAndroid Build Coastguard Worker }
201*635a8641SAndroid Build Coastguard Worker
202*635a8641SAndroid Build Coastguard Worker // Make sure the written data can be read from the returned path.
203*635a8641SAndroid Build Coastguard Worker std::string data;
204*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(ReadFileToString(path_, &data));
205*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("test", data);
206*635a8641SAndroid Build Coastguard Worker
207*635a8641SAndroid Build Coastguard Worker // Make sure we can & do delete the created file to prevent leaks on the bots.
208*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(base::DeleteFile(path_, false));
209*635a8641SAndroid Build Coastguard Worker }
210*635a8641SAndroid Build Coastguard Worker
TEST_F(FileProxyTest,SetAndTake)211*635a8641SAndroid Build Coastguard Worker TEST_F(FileProxyTest, SetAndTake) {
212*635a8641SAndroid Build Coastguard Worker File file(TestPath(), File::FLAG_CREATE | File::FLAG_READ);
213*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(file.IsValid());
214*635a8641SAndroid Build Coastguard Worker FileProxy proxy(file_task_runner());
215*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(proxy.IsValid());
216*635a8641SAndroid Build Coastguard Worker proxy.SetFile(std::move(file));
217*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(proxy.IsValid());
218*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(file.IsValid());
219*635a8641SAndroid Build Coastguard Worker
220*635a8641SAndroid Build Coastguard Worker file = proxy.TakeFile();
221*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(proxy.IsValid());
222*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(file.IsValid());
223*635a8641SAndroid Build Coastguard Worker }
224*635a8641SAndroid Build Coastguard Worker
TEST_F(FileProxyTest,DuplicateFile)225*635a8641SAndroid Build Coastguard Worker TEST_F(FileProxyTest, DuplicateFile) {
226*635a8641SAndroid Build Coastguard Worker FileProxy proxy(file_task_runner());
227*635a8641SAndroid Build Coastguard Worker CreateProxy(File::FLAG_CREATE | File::FLAG_WRITE, &proxy);
228*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(proxy.IsValid());
229*635a8641SAndroid Build Coastguard Worker
230*635a8641SAndroid Build Coastguard Worker base::File duplicate = proxy.DuplicateFile();
231*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(proxy.IsValid());
232*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(duplicate.IsValid());
233*635a8641SAndroid Build Coastguard Worker
234*635a8641SAndroid Build Coastguard Worker FileProxy invalid_proxy(file_task_runner());
235*635a8641SAndroid Build Coastguard Worker ASSERT_FALSE(invalid_proxy.IsValid());
236*635a8641SAndroid Build Coastguard Worker
237*635a8641SAndroid Build Coastguard Worker base::File invalid_duplicate = invalid_proxy.DuplicateFile();
238*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(invalid_proxy.IsValid());
239*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(invalid_duplicate.IsValid());
240*635a8641SAndroid Build Coastguard Worker }
241*635a8641SAndroid Build Coastguard Worker
TEST_F(FileProxyTest,GetInfo)242*635a8641SAndroid Build Coastguard Worker TEST_F(FileProxyTest, GetInfo) {
243*635a8641SAndroid Build Coastguard Worker // Setup.
244*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(4, base::WriteFile(TestPath(), "test", 4));
245*635a8641SAndroid Build Coastguard Worker File::Info expected_info;
246*635a8641SAndroid Build Coastguard Worker GetFileInfo(TestPath(), &expected_info);
247*635a8641SAndroid Build Coastguard Worker
248*635a8641SAndroid Build Coastguard Worker // Run.
249*635a8641SAndroid Build Coastguard Worker FileProxy proxy(file_task_runner());
250*635a8641SAndroid Build Coastguard Worker CreateProxy(File::FLAG_OPEN | File::FLAG_READ, &proxy);
251*635a8641SAndroid Build Coastguard Worker proxy.GetInfo(
252*635a8641SAndroid Build Coastguard Worker BindOnce(&FileProxyTest::DidGetFileInfo, weak_factory_.GetWeakPtr()));
253*635a8641SAndroid Build Coastguard Worker RunLoop().Run();
254*635a8641SAndroid Build Coastguard Worker
255*635a8641SAndroid Build Coastguard Worker // Verify.
256*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(File::FILE_OK, error_);
257*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected_info.size, file_info_.size);
258*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected_info.is_directory, file_info_.is_directory);
259*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected_info.is_symbolic_link, file_info_.is_symbolic_link);
260*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected_info.last_modified, file_info_.last_modified);
261*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected_info.creation_time, file_info_.creation_time);
262*635a8641SAndroid Build Coastguard Worker }
263*635a8641SAndroid Build Coastguard Worker
TEST_F(FileProxyTest,Read)264*635a8641SAndroid Build Coastguard Worker TEST_F(FileProxyTest, Read) {
265*635a8641SAndroid Build Coastguard Worker // Setup.
266*635a8641SAndroid Build Coastguard Worker const char expected_data[] = "bleh";
267*635a8641SAndroid Build Coastguard Worker int expected_bytes = arraysize(expected_data);
268*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(expected_bytes,
269*635a8641SAndroid Build Coastguard Worker base::WriteFile(TestPath(), expected_data, expected_bytes));
270*635a8641SAndroid Build Coastguard Worker
271*635a8641SAndroid Build Coastguard Worker // Run.
272*635a8641SAndroid Build Coastguard Worker FileProxy proxy(file_task_runner());
273*635a8641SAndroid Build Coastguard Worker CreateProxy(File::FLAG_OPEN | File::FLAG_READ, &proxy);
274*635a8641SAndroid Build Coastguard Worker
275*635a8641SAndroid Build Coastguard Worker proxy.Read(0, 128,
276*635a8641SAndroid Build Coastguard Worker BindOnce(&FileProxyTest::DidRead, weak_factory_.GetWeakPtr()));
277*635a8641SAndroid Build Coastguard Worker RunLoop().Run();
278*635a8641SAndroid Build Coastguard Worker
279*635a8641SAndroid Build Coastguard Worker // Verify.
280*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(File::FILE_OK, error_);
281*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected_bytes, static_cast<int>(buffer_.size()));
282*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < buffer_.size(); ++i) {
283*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(expected_data[i], buffer_[i]);
284*635a8641SAndroid Build Coastguard Worker }
285*635a8641SAndroid Build Coastguard Worker }
286*635a8641SAndroid Build Coastguard Worker
TEST_F(FileProxyTest,WriteAndFlush)287*635a8641SAndroid Build Coastguard Worker TEST_F(FileProxyTest, WriteAndFlush) {
288*635a8641SAndroid Build Coastguard Worker FileProxy proxy(file_task_runner());
289*635a8641SAndroid Build Coastguard Worker CreateProxy(File::FLAG_CREATE | File::FLAG_WRITE, &proxy);
290*635a8641SAndroid Build Coastguard Worker
291*635a8641SAndroid Build Coastguard Worker const char data[] = "foo!";
292*635a8641SAndroid Build Coastguard Worker int data_bytes = arraysize(data);
293*635a8641SAndroid Build Coastguard Worker proxy.Write(0, data, data_bytes,
294*635a8641SAndroid Build Coastguard Worker BindOnce(&FileProxyTest::DidWrite, weak_factory_.GetWeakPtr()));
295*635a8641SAndroid Build Coastguard Worker RunLoop().Run();
296*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(File::FILE_OK, error_);
297*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(data_bytes, bytes_written_);
298*635a8641SAndroid Build Coastguard Worker
299*635a8641SAndroid Build Coastguard Worker // Flush the written data. (So that the following read should always
300*635a8641SAndroid Build Coastguard Worker // succeed. On some platforms it may work with or without this flush.)
301*635a8641SAndroid Build Coastguard Worker proxy.Flush(BindOnce(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
302*635a8641SAndroid Build Coastguard Worker RunLoop().Run();
303*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(File::FILE_OK, error_);
304*635a8641SAndroid Build Coastguard Worker
305*635a8641SAndroid Build Coastguard Worker // Verify the written data.
306*635a8641SAndroid Build Coastguard Worker char buffer[10];
307*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(data_bytes, base::ReadFile(TestPath(), buffer, data_bytes));
308*635a8641SAndroid Build Coastguard Worker for (int i = 0; i < data_bytes; ++i) {
309*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(data[i], buffer[i]);
310*635a8641SAndroid Build Coastguard Worker }
311*635a8641SAndroid Build Coastguard Worker }
312*635a8641SAndroid Build Coastguard Worker
313*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID) || defined(OS_FUCHSIA)
314*635a8641SAndroid Build Coastguard Worker // Flaky on Android, see http://crbug.com/489602
315*635a8641SAndroid Build Coastguard Worker // TODO(crbug.com/851734): Implementation depends on stat, which is not
316*635a8641SAndroid Build Coastguard Worker // implemented on Fuchsia
317*635a8641SAndroid Build Coastguard Worker #define MAYBE_SetTimes DISABLED_SetTimes
318*635a8641SAndroid Build Coastguard Worker #else
319*635a8641SAndroid Build Coastguard Worker #define MAYBE_SetTimes SetTimes
320*635a8641SAndroid Build Coastguard Worker #endif
TEST_F(FileProxyTest,MAYBE_SetTimes)321*635a8641SAndroid Build Coastguard Worker TEST_F(FileProxyTest, MAYBE_SetTimes) {
322*635a8641SAndroid Build Coastguard Worker FileProxy proxy(file_task_runner());
323*635a8641SAndroid Build Coastguard Worker CreateProxy(
324*635a8641SAndroid Build Coastguard Worker File::FLAG_CREATE | File::FLAG_WRITE | File::FLAG_WRITE_ATTRIBUTES,
325*635a8641SAndroid Build Coastguard Worker &proxy);
326*635a8641SAndroid Build Coastguard Worker
327*635a8641SAndroid Build Coastguard Worker Time last_accessed_time = Time::Now() - TimeDelta::FromDays(12345);
328*635a8641SAndroid Build Coastguard Worker Time last_modified_time = Time::Now() - TimeDelta::FromHours(98765);
329*635a8641SAndroid Build Coastguard Worker
330*635a8641SAndroid Build Coastguard Worker proxy.SetTimes(
331*635a8641SAndroid Build Coastguard Worker last_accessed_time, last_modified_time,
332*635a8641SAndroid Build Coastguard Worker BindOnce(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
333*635a8641SAndroid Build Coastguard Worker RunLoop().Run();
334*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(File::FILE_OK, error_);
335*635a8641SAndroid Build Coastguard Worker
336*635a8641SAndroid Build Coastguard Worker File::Info info;
337*635a8641SAndroid Build Coastguard Worker GetFileInfo(TestPath(), &info);
338*635a8641SAndroid Build Coastguard Worker
339*635a8641SAndroid Build Coastguard Worker // The returned values may only have the seconds precision, so we cast
340*635a8641SAndroid Build Coastguard Worker // the double values to int here.
341*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<int>(last_modified_time.ToDoubleT()),
342*635a8641SAndroid Build Coastguard Worker static_cast<int>(info.last_modified.ToDoubleT()));
343*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<int>(last_accessed_time.ToDoubleT()),
344*635a8641SAndroid Build Coastguard Worker static_cast<int>(info.last_accessed.ToDoubleT()));
345*635a8641SAndroid Build Coastguard Worker }
346*635a8641SAndroid Build Coastguard Worker
TEST_F(FileProxyTest,SetLength_Shrink)347*635a8641SAndroid Build Coastguard Worker TEST_F(FileProxyTest, SetLength_Shrink) {
348*635a8641SAndroid Build Coastguard Worker // Setup.
349*635a8641SAndroid Build Coastguard Worker const char kTestData[] = "0123456789";
350*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(10, base::WriteFile(TestPath(), kTestData, 10));
351*635a8641SAndroid Build Coastguard Worker File::Info info;
352*635a8641SAndroid Build Coastguard Worker GetFileInfo(TestPath(), &info);
353*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(10, info.size);
354*635a8641SAndroid Build Coastguard Worker
355*635a8641SAndroid Build Coastguard Worker // Run.
356*635a8641SAndroid Build Coastguard Worker FileProxy proxy(file_task_runner());
357*635a8641SAndroid Build Coastguard Worker CreateProxy(File::FLAG_OPEN | File::FLAG_WRITE, &proxy);
358*635a8641SAndroid Build Coastguard Worker proxy.SetLength(
359*635a8641SAndroid Build Coastguard Worker 7, BindOnce(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
360*635a8641SAndroid Build Coastguard Worker RunLoop().Run();
361*635a8641SAndroid Build Coastguard Worker
362*635a8641SAndroid Build Coastguard Worker // Verify.
363*635a8641SAndroid Build Coastguard Worker GetFileInfo(TestPath(), &info);
364*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(7, info.size);
365*635a8641SAndroid Build Coastguard Worker
366*635a8641SAndroid Build Coastguard Worker char buffer[7];
367*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(7, base::ReadFile(TestPath(), buffer, 7));
368*635a8641SAndroid Build Coastguard Worker int i = 0;
369*635a8641SAndroid Build Coastguard Worker for (; i < 7; ++i)
370*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(kTestData[i], buffer[i]);
371*635a8641SAndroid Build Coastguard Worker }
372*635a8641SAndroid Build Coastguard Worker
TEST_F(FileProxyTest,SetLength_Expand)373*635a8641SAndroid Build Coastguard Worker TEST_F(FileProxyTest, SetLength_Expand) {
374*635a8641SAndroid Build Coastguard Worker // Setup.
375*635a8641SAndroid Build Coastguard Worker const char kTestData[] = "9876543210";
376*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(10, base::WriteFile(TestPath(), kTestData, 10));
377*635a8641SAndroid Build Coastguard Worker File::Info info;
378*635a8641SAndroid Build Coastguard Worker GetFileInfo(TestPath(), &info);
379*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(10, info.size);
380*635a8641SAndroid Build Coastguard Worker
381*635a8641SAndroid Build Coastguard Worker // Run.
382*635a8641SAndroid Build Coastguard Worker FileProxy proxy(file_task_runner());
383*635a8641SAndroid Build Coastguard Worker CreateProxy(File::FLAG_OPEN | File::FLAG_WRITE, &proxy);
384*635a8641SAndroid Build Coastguard Worker proxy.SetLength(
385*635a8641SAndroid Build Coastguard Worker 53, BindOnce(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
386*635a8641SAndroid Build Coastguard Worker RunLoop().Run();
387*635a8641SAndroid Build Coastguard Worker
388*635a8641SAndroid Build Coastguard Worker // Verify.
389*635a8641SAndroid Build Coastguard Worker GetFileInfo(TestPath(), &info);
390*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(53, info.size);
391*635a8641SAndroid Build Coastguard Worker
392*635a8641SAndroid Build Coastguard Worker char buffer[53];
393*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(53, base::ReadFile(TestPath(), buffer, 53));
394*635a8641SAndroid Build Coastguard Worker int i = 0;
395*635a8641SAndroid Build Coastguard Worker for (; i < 10; ++i)
396*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(kTestData[i], buffer[i]);
397*635a8641SAndroid Build Coastguard Worker for (; i < 53; ++i)
398*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, buffer[i]);
399*635a8641SAndroid Build Coastguard Worker }
400*635a8641SAndroid Build Coastguard Worker
401*635a8641SAndroid Build Coastguard Worker } // namespace base
402