b5e100297d9af0d3c6e218b4d2f53d79808b67c1
[platform/framework/web/crosswalk.git] / src / base / files / file_proxy_unittest.cc
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/files/file_proxy.h"
6
7 #include <map>
8
9 #include "base/bind.h"
10 #include "base/file_util.h"
11 #include "base/files/file.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/logging.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/threading/thread.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace base {
20
21 class FileProxyTest : public testing::Test {
22  public:
23   FileProxyTest()
24       : file_thread_("FileProxyTestFileThread"),
25         error_(File::FILE_OK),
26         bytes_written_(-1),
27         weak_factory_(this) {}
28
29   virtual void SetUp() OVERRIDE {
30     ASSERT_TRUE(dir_.CreateUniqueTempDir());
31     ASSERT_TRUE(file_thread_.Start());
32   }
33
34   void DidFinish(File::Error error) {
35     error_ = error;
36     MessageLoop::current()->QuitWhenIdle();
37   }
38
39   void DidCreateOrOpen(File::Error error) {
40     error_ = error;
41     MessageLoop::current()->QuitWhenIdle();
42   }
43
44   void DidCreateTemporary(File::Error error,
45                           const FilePath& path) {
46     error_ = error;
47     path_ = path;
48     MessageLoop::current()->QuitWhenIdle();
49   }
50
51   void DidGetFileInfo(File::Error error,
52                       const File::Info& file_info) {
53     error_ = error;
54     file_info_ = file_info;
55     MessageLoop::current()->QuitWhenIdle();
56   }
57
58   void DidRead(File::Error error,
59                const char* data,
60                int bytes_read) {
61     error_ = error;
62     buffer_.resize(bytes_read);
63     memcpy(&buffer_[0], data, bytes_read);
64     MessageLoop::current()->QuitWhenIdle();
65   }
66
67   void DidWrite(File::Error error,
68                 int bytes_written) {
69     error_ = error;
70     bytes_written_ = bytes_written;
71     MessageLoop::current()->QuitWhenIdle();
72   }
73
74  protected:
75   void CreateProxy(uint32 flags, FileProxy* proxy) {
76     proxy->CreateOrOpen(
77         test_path(), flags,
78         Bind(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
79     MessageLoop::current()->Run();
80     EXPECT_TRUE(proxy->IsValid());
81   }
82
83   TaskRunner* file_task_runner() const {
84     return file_thread_.message_loop_proxy().get();
85   }
86   const FilePath& test_dir_path() const { return dir_.path(); }
87   const FilePath test_path() const { return dir_.path().AppendASCII("test"); }
88
89   MessageLoopForIO message_loop_;
90   Thread file_thread_;
91
92   ScopedTempDir dir_;
93   File::Error error_;
94   FilePath path_;
95   File::Info file_info_;
96   std::vector<char> buffer_;
97   int bytes_written_;
98   WeakPtrFactory<FileProxyTest> weak_factory_;
99 };
100
101 TEST_F(FileProxyTest, CreateOrOpen_Create) {
102   FileProxy proxy(file_task_runner());
103   proxy.CreateOrOpen(
104       test_path(),
105       File::FLAG_CREATE | File::FLAG_READ,
106       Bind(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
107   MessageLoop::current()->Run();
108
109   EXPECT_EQ(File::FILE_OK, error_);
110   EXPECT_TRUE(proxy.IsValid());
111   EXPECT_TRUE(proxy.created());
112   EXPECT_TRUE(PathExists(test_path()));
113 }
114
115 TEST_F(FileProxyTest, CreateOrOpen_Open) {
116   // Creates a file.
117   base::WriteFile(test_path(), NULL, 0);
118   ASSERT_TRUE(PathExists(test_path()));
119
120   // Opens the created file.
121   FileProxy proxy(file_task_runner());
122   proxy.CreateOrOpen(
123       test_path(),
124       File::FLAG_OPEN | File::FLAG_READ,
125       Bind(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
126   MessageLoop::current()->Run();
127
128   EXPECT_EQ(File::FILE_OK, error_);
129   EXPECT_TRUE(proxy.IsValid());
130   EXPECT_FALSE(proxy.created());
131 }
132
133 TEST_F(FileProxyTest, CreateOrOpen_OpenNonExistent) {
134   FileProxy proxy(file_task_runner());
135   proxy.CreateOrOpen(
136       test_path(),
137       File::FLAG_OPEN | File::FLAG_READ,
138       Bind(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
139   MessageLoop::current()->Run();
140   EXPECT_EQ(File::FILE_ERROR_NOT_FOUND, error_);
141   EXPECT_FALSE(proxy.IsValid());
142   EXPECT_FALSE(proxy.created());
143   EXPECT_FALSE(PathExists(test_path()));
144 }
145
146 TEST_F(FileProxyTest, Close) {
147   // Creates a file.
148   FileProxy proxy(file_task_runner());
149   CreateProxy(File::FLAG_CREATE | File::FLAG_WRITE, &proxy);
150
151 #if defined(OS_WIN)
152   // This fails on Windows if the file is not closed.
153   EXPECT_FALSE(base::Move(test_path(), test_dir_path().AppendASCII("new")));
154 #endif
155
156   proxy.Close(Bind(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
157   MessageLoop::current()->Run();
158   EXPECT_EQ(File::FILE_OK, error_);
159   EXPECT_FALSE(proxy.IsValid());
160
161   // Now it should pass on all platforms.
162   EXPECT_TRUE(base::Move(test_path(), test_dir_path().AppendASCII("new")));
163 }
164
165 TEST_F(FileProxyTest, CreateTemporary) {
166   {
167     FileProxy proxy(file_task_runner());
168     proxy.CreateTemporary(
169         0 /* additional_file_flags */,
170         Bind(&FileProxyTest::DidCreateTemporary, weak_factory_.GetWeakPtr()));
171     MessageLoop::current()->Run();
172
173     EXPECT_TRUE(proxy.IsValid());
174     EXPECT_EQ(File::FILE_OK, error_);
175     EXPECT_TRUE(PathExists(path_));
176
177     // The file should be writable.
178     proxy.Write(0, "test", 4,
179                 Bind(&FileProxyTest::DidWrite, weak_factory_.GetWeakPtr()));
180     MessageLoop::current()->Run();
181     EXPECT_EQ(File::FILE_OK, error_);
182     EXPECT_EQ(4, bytes_written_);
183   }
184
185   // Make sure the written data can be read from the returned path.
186   std::string data;
187   EXPECT_TRUE(ReadFileToString(path_, &data));
188   EXPECT_EQ("test", data);
189
190   // Make sure we can & do delete the created file to prevent leaks on the bots.
191   EXPECT_TRUE(base::DeleteFile(path_, false));
192 }
193
194 TEST_F(FileProxyTest, GetInfo) {
195   // Setup.
196   ASSERT_EQ(4, base::WriteFile(test_path(), "test", 4));
197   File::Info expected_info;
198   GetFileInfo(test_path(), &expected_info);
199
200   // Run.
201   FileProxy proxy(file_task_runner());
202   CreateProxy(File::FLAG_OPEN | File::FLAG_READ, &proxy);
203   proxy.GetInfo(
204       Bind(&FileProxyTest::DidGetFileInfo, weak_factory_.GetWeakPtr()));
205   MessageLoop::current()->Run();
206
207   // Verify.
208   EXPECT_EQ(File::FILE_OK, error_);
209   EXPECT_EQ(expected_info.size, file_info_.size);
210   EXPECT_EQ(expected_info.is_directory, file_info_.is_directory);
211   EXPECT_EQ(expected_info.is_symbolic_link, file_info_.is_symbolic_link);
212
213   File file = proxy.TakeFile();
214   EXPECT_TRUE(file.GetInfo(&expected_info));
215   EXPECT_EQ(expected_info.last_modified, file_info_.last_modified);
216   EXPECT_EQ(expected_info.creation_time, file_info_.creation_time);
217 }
218
219 TEST_F(FileProxyTest, Read) {
220   // Setup.
221   const char expected_data[] = "bleh";
222   int expected_bytes = arraysize(expected_data);
223   ASSERT_EQ(expected_bytes,
224             base::WriteFile(test_path(), expected_data, expected_bytes));
225
226   // Run.
227   FileProxy proxy(file_task_runner());
228   CreateProxy(File::FLAG_OPEN | File::FLAG_READ, &proxy);
229
230   proxy.Read(0, 128, Bind(&FileProxyTest::DidRead, weak_factory_.GetWeakPtr()));
231   MessageLoop::current()->Run();
232
233   // Verify.
234   EXPECT_EQ(File::FILE_OK, error_);
235   EXPECT_EQ(expected_bytes, static_cast<int>(buffer_.size()));
236   for (size_t i = 0; i < buffer_.size(); ++i) {
237     EXPECT_EQ(expected_data[i], buffer_[i]);
238   }
239 }
240
241 TEST_F(FileProxyTest, WriteAndFlush) {
242   FileProxy proxy(file_task_runner());
243   CreateProxy(File::FLAG_CREATE | File::FLAG_WRITE, &proxy);
244
245   const char data[] = "foo!";
246   int data_bytes = ARRAYSIZE_UNSAFE(data);
247   proxy.Write(0, data, data_bytes,
248               Bind(&FileProxyTest::DidWrite, weak_factory_.GetWeakPtr()));
249   MessageLoop::current()->Run();
250   EXPECT_EQ(File::FILE_OK, error_);
251   EXPECT_EQ(data_bytes, bytes_written_);
252
253   // Flush the written data.  (So that the following read should always
254   // succeed.  On some platforms it may work with or without this flush.)
255   proxy.Flush(Bind(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
256   MessageLoop::current()->Run();
257   EXPECT_EQ(File::FILE_OK, error_);
258
259   // Verify the written data.
260   char buffer[10];
261   EXPECT_EQ(data_bytes, base::ReadFile(test_path(), buffer, data_bytes));
262   for (int i = 0; i < data_bytes; ++i) {
263     EXPECT_EQ(data[i], buffer[i]);
264   }
265 }
266
267 TEST_F(FileProxyTest, SetTimes) {
268   FileProxy proxy(file_task_runner());
269   CreateProxy(
270       File::FLAG_CREATE | File::FLAG_WRITE | File::FLAG_WRITE_ATTRIBUTES,
271       &proxy);
272
273   Time last_accessed_time = Time::Now() - TimeDelta::FromDays(12345);
274   Time last_modified_time = Time::Now() - TimeDelta::FromHours(98765);
275
276   proxy.SetTimes(last_accessed_time, last_modified_time,
277                  Bind(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
278   MessageLoop::current()->Run();
279   EXPECT_EQ(File::FILE_OK, error_);
280
281   File::Info info;
282   GetFileInfo(test_path(), &info);
283
284   // The returned values may only have the seconds precision, so we cast
285   // the double values to int here.
286   EXPECT_EQ(static_cast<int>(last_modified_time.ToDoubleT()),
287             static_cast<int>(info.last_modified.ToDoubleT()));
288   EXPECT_EQ(static_cast<int>(last_accessed_time.ToDoubleT()),
289             static_cast<int>(info.last_accessed.ToDoubleT()));
290 }
291
292 TEST_F(FileProxyTest, SetLength_Shrink) {
293   // Setup.
294   const char kTestData[] = "0123456789";
295   ASSERT_EQ(10, base::WriteFile(test_path(), kTestData, 10));
296   File::Info info;
297   GetFileInfo(test_path(), &info);
298   ASSERT_EQ(10, info.size);
299
300   // Run.
301   FileProxy proxy(file_task_runner());
302   CreateProxy(File::FLAG_OPEN | File::FLAG_WRITE, &proxy);
303   proxy.SetLength(7,
304                   Bind(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
305   MessageLoop::current()->Run();
306
307   // Verify.
308   GetFileInfo(test_path(), &info);
309   ASSERT_EQ(7, info.size);
310
311   char buffer[7];
312   EXPECT_EQ(7, base::ReadFile(test_path(), buffer, 7));
313   int i = 0;
314   for (; i < 7; ++i)
315     EXPECT_EQ(kTestData[i], buffer[i]);
316 }
317
318 TEST_F(FileProxyTest, SetLength_Expand) {
319   // Setup.
320   const char kTestData[] = "9876543210";
321   ASSERT_EQ(10, base::WriteFile(test_path(), kTestData, 10));
322   File::Info info;
323   GetFileInfo(test_path(), &info);
324   ASSERT_EQ(10, info.size);
325
326   // Run.
327   FileProxy proxy(file_task_runner());
328   CreateProxy(File::FLAG_OPEN | File::FLAG_WRITE, &proxy);
329   proxy.SetLength(53,
330                   Bind(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
331   MessageLoop::current()->Run();
332
333   // Verify.
334   GetFileInfo(test_path(), &info);
335   ASSERT_EQ(53, info.size);
336
337   char buffer[53];
338   EXPECT_EQ(53, base::ReadFile(test_path(), buffer, 53));
339   int i = 0;
340   for (; i < 10; ++i)
341     EXPECT_EQ(kTestData[i], buffer[i]);
342   for (; i < 53; ++i)
343     EXPECT_EQ(0, buffer[i]);
344 }
345
346 }  // namespace base