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