Add missing pnacl libraries and headers and tools.
[chromium-blink-merge.git] / base / files / file_util_proxy_unittest.cc
blobef23fd8438d324b874ee4335e912bf58071a8f5a
1 // Copyright (c) 2012 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.
5 #include "base/files/file_util_proxy.h"
7 #include <map>
9 #include "base/bind.h"
10 #include "base/file_util.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/logging.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/message_loop.h"
15 #include "base/platform_file.h"
16 #include "base/threading/thread.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 namespace base {
21 class FileUtilProxyTest : public testing::Test {
22 public:
23 FileUtilProxyTest()
24 : message_loop_(MessageLoop::TYPE_IO),
25 file_thread_("FileUtilProxyTestFileThread"),
26 error_(PLATFORM_FILE_OK),
27 created_(false),
28 file_(kInvalidPlatformFileValue),
29 bytes_written_(-1),
30 weak_factory_(this) {}
32 virtual void SetUp() OVERRIDE {
33 ASSERT_TRUE(dir_.CreateUniqueTempDir());
34 ASSERT_TRUE(file_thread_.Start());
37 virtual void TearDown() OVERRIDE {
38 if (file_ != kInvalidPlatformFileValue)
39 ClosePlatformFile(file_);
42 void DidFinish(PlatformFileError error) {
43 error_ = error;
44 MessageLoop::current()->QuitWhenIdle();
47 void DidCreateOrOpen(PlatformFileError error,
48 PassPlatformFile file,
49 bool created) {
50 error_ = error;
51 file_ = file.ReleaseValue();
52 created_ = created;
53 MessageLoop::current()->QuitWhenIdle();
56 void DidCreateTemporary(PlatformFileError error,
57 PassPlatformFile file,
58 const FilePath& path) {
59 error_ = error;
60 file_ = file.ReleaseValue();
61 path_ = path;
62 MessageLoop::current()->QuitWhenIdle();
65 void DidGetFileInfo(PlatformFileError error,
66 const PlatformFileInfo& file_info) {
67 error_ = error;
68 file_info_ = file_info;
69 MessageLoop::current()->QuitWhenIdle();
72 void DidRead(PlatformFileError error,
73 const char* data,
74 int bytes_read) {
75 error_ = error;
76 buffer_.resize(bytes_read);
77 memcpy(&buffer_[0], data, bytes_read);
78 MessageLoop::current()->QuitWhenIdle();
81 void DidWrite(PlatformFileError error,
82 int bytes_written) {
83 error_ = error;
84 bytes_written_ = bytes_written;
85 MessageLoop::current()->QuitWhenIdle();
88 protected:
89 PlatformFile GetTestPlatformFile(int flags) {
90 if (file_ != kInvalidPlatformFileValue)
91 return file_;
92 bool created;
93 PlatformFileError error;
94 file_ = CreatePlatformFile(test_path(), flags, &created, &error);
95 EXPECT_EQ(PLATFORM_FILE_OK, error);
96 EXPECT_NE(kInvalidPlatformFileValue, file_);
97 return file_;
100 TaskRunner* file_task_runner() const {
101 return file_thread_.message_loop_proxy().get();
103 const FilePath& test_dir_path() const { return dir_.path(); }
104 const FilePath test_path() const { return dir_.path().AppendASCII("test"); }
106 MessageLoop message_loop_;
107 Thread file_thread_;
109 ScopedTempDir dir_;
110 PlatformFileError error_;
111 bool created_;
112 PlatformFile file_;
113 FilePath path_;
114 PlatformFileInfo file_info_;
115 std::vector<char> buffer_;
116 int bytes_written_;
117 WeakPtrFactory<FileUtilProxyTest> weak_factory_;
120 TEST_F(FileUtilProxyTest, CreateOrOpen_Create) {
121 FileUtilProxy::CreateOrOpen(
122 file_task_runner(),
123 test_path(),
124 PLATFORM_FILE_CREATE | PLATFORM_FILE_READ,
125 Bind(&FileUtilProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
126 MessageLoop::current()->Run();
128 EXPECT_EQ(PLATFORM_FILE_OK, error_);
129 EXPECT_TRUE(created_);
130 EXPECT_NE(kInvalidPlatformFileValue, file_);
131 EXPECT_TRUE(file_util::PathExists(test_path()));
134 TEST_F(FileUtilProxyTest, CreateOrOpen_Open) {
135 // Creates a file.
136 file_util::WriteFile(test_path(), NULL, 0);
137 ASSERT_TRUE(file_util::PathExists(test_path()));
139 // Opens the created file.
140 FileUtilProxy::CreateOrOpen(
141 file_task_runner(),
142 test_path(),
143 PLATFORM_FILE_OPEN | PLATFORM_FILE_READ,
144 Bind(&FileUtilProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
145 MessageLoop::current()->Run();
147 EXPECT_EQ(PLATFORM_FILE_OK, error_);
148 EXPECT_FALSE(created_);
149 EXPECT_NE(kInvalidPlatformFileValue, file_);
152 TEST_F(FileUtilProxyTest, CreateOrOpen_OpenNonExistent) {
153 FileUtilProxy::CreateOrOpen(
154 file_task_runner(),
155 test_path(),
156 PLATFORM_FILE_OPEN | PLATFORM_FILE_READ,
157 Bind(&FileUtilProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
158 MessageLoop::current()->Run();
159 EXPECT_EQ(PLATFORM_FILE_ERROR_NOT_FOUND, error_);
160 EXPECT_FALSE(created_);
161 EXPECT_EQ(kInvalidPlatformFileValue, file_);
162 EXPECT_FALSE(file_util::PathExists(test_path()));
165 TEST_F(FileUtilProxyTest, Close) {
166 // Creates a file.
167 PlatformFile file = GetTestPlatformFile(
168 PLATFORM_FILE_CREATE | PLATFORM_FILE_WRITE);
170 #if defined(OS_WIN)
171 // This fails on Windows if the file is not closed.
172 EXPECT_FALSE(file_util::Move(test_path(),
173 test_dir_path().AppendASCII("new")));
174 #endif
176 FileUtilProxy::Close(
177 file_task_runner(),
178 file,
179 Bind(&FileUtilProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
180 MessageLoop::current()->Run();
181 EXPECT_EQ(PLATFORM_FILE_OK, error_);
183 // Now it should pass on all platforms.
184 EXPECT_TRUE(file_util::Move(test_path(), test_dir_path().AppendASCII("new")));
187 TEST_F(FileUtilProxyTest, CreateTemporary) {
188 FileUtilProxy::CreateTemporary(
189 file_task_runner(), 0 /* additional_file_flags */,
190 Bind(&FileUtilProxyTest::DidCreateTemporary, weak_factory_.GetWeakPtr()));
191 MessageLoop::current()->Run();
192 EXPECT_EQ(PLATFORM_FILE_OK, error_);
193 EXPECT_TRUE(file_util::PathExists(path_));
194 EXPECT_NE(kInvalidPlatformFileValue, file_);
196 // The file should be writable.
197 #if defined(OS_WIN)
198 HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
199 OVERLAPPED overlapped = {0};
200 overlapped.hEvent = hEvent;
201 DWORD bytes_written;
202 if (!::WriteFile(file_, "test", 4, &bytes_written, &overlapped)) {
203 // Temporary file is created with ASYNC flag, so WriteFile may return 0
204 // with ERROR_IO_PENDING.
205 EXPECT_EQ(ERROR_IO_PENDING, GetLastError());
206 GetOverlappedResult(file_, &overlapped, &bytes_written, TRUE);
208 EXPECT_EQ(4, bytes_written);
209 #else
210 // On POSIX ASYNC flag does not affect synchronous read/write behavior.
211 EXPECT_EQ(4, WritePlatformFile(file_, 0, "test", 4));
212 #endif
213 EXPECT_TRUE(ClosePlatformFile(file_));
214 file_ = kInvalidPlatformFileValue;
216 // Make sure the written data can be read from the returned path.
217 std::string data;
218 EXPECT_TRUE(file_util::ReadFileToString(path_, &data));
219 EXPECT_EQ("test", data);
221 // Make sure we can & do delete the created file to prevent leaks on the bots.
222 EXPECT_TRUE(file_util::Delete(path_, false));
225 TEST_F(FileUtilProxyTest, GetFileInfo_File) {
226 // Setup.
227 ASSERT_EQ(4, file_util::WriteFile(test_path(), "test", 4));
228 PlatformFileInfo expected_info;
229 file_util::GetFileInfo(test_path(), &expected_info);
231 // Run.
232 FileUtilProxy::GetFileInfo(
233 file_task_runner(),
234 test_path(),
235 Bind(&FileUtilProxyTest::DidGetFileInfo, weak_factory_.GetWeakPtr()));
236 MessageLoop::current()->Run();
238 // Verify.
239 EXPECT_EQ(PLATFORM_FILE_OK, error_);
240 EXPECT_EQ(expected_info.size, file_info_.size);
241 EXPECT_EQ(expected_info.is_directory, file_info_.is_directory);
242 EXPECT_EQ(expected_info.is_symbolic_link, file_info_.is_symbolic_link);
243 EXPECT_EQ(expected_info.last_modified, file_info_.last_modified);
244 EXPECT_EQ(expected_info.last_accessed, file_info_.last_accessed);
245 EXPECT_EQ(expected_info.creation_time, file_info_.creation_time);
248 TEST_F(FileUtilProxyTest, GetFileInfo_Directory) {
249 // Setup.
250 ASSERT_TRUE(file_util::CreateDirectory(test_path()));
251 PlatformFileInfo expected_info;
252 file_util::GetFileInfo(test_path(), &expected_info);
254 // Run.
255 FileUtilProxy::GetFileInfo(
256 file_task_runner(),
257 test_path(),
258 Bind(&FileUtilProxyTest::DidGetFileInfo, weak_factory_.GetWeakPtr()));
259 MessageLoop::current()->Run();
261 // Verify.
262 EXPECT_EQ(PLATFORM_FILE_OK, error_);
263 EXPECT_EQ(expected_info.size, file_info_.size);
264 EXPECT_EQ(expected_info.is_directory, file_info_.is_directory);
265 EXPECT_EQ(expected_info.is_symbolic_link, file_info_.is_symbolic_link);
266 EXPECT_EQ(expected_info.last_modified, file_info_.last_modified);
267 EXPECT_EQ(expected_info.last_accessed, file_info_.last_accessed);
268 EXPECT_EQ(expected_info.creation_time, file_info_.creation_time);
271 TEST_F(FileUtilProxyTest, Read) {
272 // Setup.
273 const char expected_data[] = "bleh";
274 int expected_bytes = arraysize(expected_data);
275 ASSERT_EQ(expected_bytes,
276 file_util::WriteFile(test_path(), expected_data, expected_bytes));
278 // Run.
279 FileUtilProxy::Read(
280 file_task_runner(),
281 GetTestPlatformFile(PLATFORM_FILE_OPEN | PLATFORM_FILE_READ),
282 0, // offset
283 128,
284 Bind(&FileUtilProxyTest::DidRead, weak_factory_.GetWeakPtr()));
285 MessageLoop::current()->Run();
287 // Verify.
288 EXPECT_EQ(PLATFORM_FILE_OK, error_);
289 EXPECT_EQ(expected_bytes, static_cast<int>(buffer_.size()));
290 for (size_t i = 0; i < buffer_.size(); ++i) {
291 EXPECT_EQ(expected_data[i], buffer_[i]);
295 TEST_F(FileUtilProxyTest, WriteAndFlush) {
296 const char data[] = "foo!";
297 int data_bytes = ARRAYSIZE_UNSAFE(data);
298 PlatformFile file = GetTestPlatformFile(
299 PLATFORM_FILE_CREATE | PLATFORM_FILE_WRITE);
301 FileUtilProxy::Write(
302 file_task_runner(),
303 file,
304 0, // offset
305 data,
306 data_bytes,
307 Bind(&FileUtilProxyTest::DidWrite, weak_factory_.GetWeakPtr()));
308 MessageLoop::current()->Run();
309 EXPECT_EQ(PLATFORM_FILE_OK, error_);
310 EXPECT_EQ(data_bytes, bytes_written_);
312 // Flush the written data. (So that the following read should always
313 // succeed. On some platforms it may work with or without this flush.)
314 FileUtilProxy::Flush(
315 file_task_runner(),
316 file,
317 Bind(&FileUtilProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
318 MessageLoop::current()->Run();
319 EXPECT_EQ(PLATFORM_FILE_OK, error_);
321 // Verify the written data.
322 char buffer[10];
323 EXPECT_EQ(data_bytes, file_util::ReadFile(test_path(), buffer, data_bytes));
324 for (int i = 0; i < data_bytes; ++i) {
325 EXPECT_EQ(data[i], buffer[i]);
329 TEST_F(FileUtilProxyTest, Touch) {
330 Time last_accessed_time = Time::Now() - TimeDelta::FromDays(12345);
331 Time last_modified_time = Time::Now() - TimeDelta::FromHours(98765);
333 FileUtilProxy::Touch(
334 file_task_runner(),
335 GetTestPlatformFile(PLATFORM_FILE_CREATE |
336 PLATFORM_FILE_WRITE |
337 PLATFORM_FILE_WRITE_ATTRIBUTES),
338 last_accessed_time,
339 last_modified_time,
340 Bind(&FileUtilProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
341 MessageLoop::current()->Run();
342 EXPECT_EQ(PLATFORM_FILE_OK, error_);
344 PlatformFileInfo info;
345 file_util::GetFileInfo(test_path(), &info);
347 // The returned values may only have the seconds precision, so we cast
348 // the double values to int here.
349 EXPECT_EQ(static_cast<int>(last_modified_time.ToDoubleT()),
350 static_cast<int>(info.last_modified.ToDoubleT()));
351 EXPECT_EQ(static_cast<int>(last_accessed_time.ToDoubleT()),
352 static_cast<int>(info.last_accessed.ToDoubleT()));
355 TEST_F(FileUtilProxyTest, Truncate_Shrink) {
356 // Setup.
357 const char kTestData[] = "0123456789";
358 ASSERT_EQ(10, file_util::WriteFile(test_path(), kTestData, 10));
359 PlatformFileInfo info;
360 file_util::GetFileInfo(test_path(), &info);
361 ASSERT_EQ(10, info.size);
363 // Run.
364 FileUtilProxy::Truncate(
365 file_task_runner(),
366 GetTestPlatformFile(PLATFORM_FILE_OPEN | PLATFORM_FILE_WRITE),
368 Bind(&FileUtilProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
369 MessageLoop::current()->Run();
371 // Verify.
372 file_util::GetFileInfo(test_path(), &info);
373 ASSERT_EQ(7, info.size);
375 char buffer[7];
376 EXPECT_EQ(7, file_util::ReadFile(test_path(), buffer, 7));
377 int i = 0;
378 for (; i < 7; ++i)
379 EXPECT_EQ(kTestData[i], buffer[i]);
382 TEST_F(FileUtilProxyTest, Truncate_Expand) {
383 // Setup.
384 const char kTestData[] = "9876543210";
385 ASSERT_EQ(10, file_util::WriteFile(test_path(), kTestData, 10));
386 PlatformFileInfo info;
387 file_util::GetFileInfo(test_path(), &info);
388 ASSERT_EQ(10, info.size);
390 // Run.
391 FileUtilProxy::Truncate(
392 file_task_runner(),
393 GetTestPlatformFile(PLATFORM_FILE_OPEN | PLATFORM_FILE_WRITE),
395 Bind(&FileUtilProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
396 MessageLoop::current()->Run();
398 // Verify.
399 file_util::GetFileInfo(test_path(), &info);
400 ASSERT_EQ(53, info.size);
402 char buffer[53];
403 EXPECT_EQ(53, file_util::ReadFile(test_path(), buffer, 53));
404 int i = 0;
405 for (; i < 10; ++i)
406 EXPECT_EQ(kTestData[i], buffer[i]);
407 for (; i < 53; ++i)
408 EXPECT_EQ(0, buffer[i]);
411 } // namespace base