- add sources.
[platform/framework/web/crosswalk.git] / src / ppapi / tests / test_flash_file.cc
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.
4
5 #include "ppapi/tests/test_flash_file.h"
6
7 #include <algorithm>
8 #include <vector>
9
10 #include "ppapi/c/pp_file_info.h"
11 #include "ppapi/c/ppb_file_io.h"
12 #include "ppapi/cpp/module.h"
13 #include "ppapi/cpp/private/flash_file.h"
14 #include "ppapi/tests/testing_instance.h"
15 #include "ppapi/tests/test_utils.h"
16
17 #if defined(PPAPI_OS_WIN)
18 #include <windows.h>
19 #else
20 #include <errno.h>
21 #include <unistd.h>
22 #endif
23
24 using pp::flash::FileModuleLocal;
25
26 namespace {
27
28 void CloseFileHandle(PP_FileHandle file_handle) {
29 #if defined(PPAPI_OS_WIN)
30   CloseHandle(file_handle);
31 #else
32   close(file_handle);
33 #endif
34 }
35
36 bool WriteFile(PP_FileHandle file_handle, const std::string& contents) {
37 #if defined(PPAPI_OS_WIN)
38   DWORD bytes_written = 0;
39   BOOL result = ::WriteFile(file_handle, contents.c_str(), contents.size(),
40                             &bytes_written, NULL);
41   return result && bytes_written == static_cast<DWORD>(contents.size());
42 #else
43   ssize_t bytes_written = 0;
44   do {
45     bytes_written = write(file_handle, contents.c_str(), contents.size());
46   } while (bytes_written == -1 && errno == EINTR);
47   return bytes_written == static_cast<ssize_t>(contents.size());
48 #endif
49 }
50
51 bool ReadFile(PP_FileHandle file_handle, std::string* contents) {
52   static const size_t kBufferSize = 1024;
53   char* buffer = new char[kBufferSize];
54   bool result = false;
55   contents->clear();
56
57 #if defined(PPAPI_OS_WIN)
58   SetFilePointer(file_handle, 0, NULL, FILE_BEGIN);
59   DWORD bytes_read = 0;
60   do {
61     result = !!::ReadFile(file_handle, buffer, kBufferSize, &bytes_read, NULL);
62     if (result && bytes_read > 0)
63       contents->append(buffer, bytes_read);
64   } while (result && bytes_read > 0);
65 #else
66   lseek(file_handle, 0, SEEK_SET);
67   ssize_t bytes_read = 0;
68   do {
69     do {
70       bytes_read = read(file_handle, buffer, kBufferSize);
71     } while (bytes_read == -1 && errno == EINTR);
72     result = bytes_read != -1;
73     if (bytes_read > 0)
74       contents->append(buffer, bytes_read);
75   } while (bytes_read > 0);
76 #endif
77
78   delete[] buffer;
79   return result;
80 }
81
82 bool DirEntryEqual(FileModuleLocal::DirEntry i,
83                    FileModuleLocal::DirEntry j) {
84   return i.name == j.name && i.is_dir == j.is_dir;
85 }
86
87 bool DirEntryLessThan(FileModuleLocal::DirEntry i,
88                       FileModuleLocal::DirEntry j) {
89   if (i.name == j.name)
90     return i.is_dir < j.is_dir;
91   return i.name < j.name;
92 }
93
94 }  // namespace
95
96 REGISTER_TEST_CASE(FlashFile);
97
98 TestFlashFile::TestFlashFile(TestingInstance* instance)
99     : TestCase(instance) {
100 }
101
102 TestFlashFile::~TestFlashFile() {
103 }
104
105 bool TestFlashFile::Init() {
106   return FileModuleLocal::IsAvailable();
107 }
108
109 void TestFlashFile::RunTests(const std::string& filter) {
110   RUN_TEST(OpenFile, filter);
111   RUN_TEST(RenameFile, filter);
112   RUN_TEST(DeleteFileOrDir, filter);
113   RUN_TEST(CreateDir, filter);
114   RUN_TEST(QueryFile, filter);
115   RUN_TEST(GetDirContents, filter);
116   RUN_TEST(CreateTemporaryFile, filter);
117 }
118
119 void TestFlashFile::SetUp() {
120   // Clear out existing test data.
121   FileModuleLocal::DeleteFileOrDir(instance_, std::string(), true);
122   // Make sure that the root directory exists.
123   FileModuleLocal::CreateDir(instance_, std::string());
124 }
125
126 std::string TestFlashFile::TestOpenFile() {
127   SetUp();
128   std::string filename = "abc.txt";
129   PP_FileHandle file_handle = FileModuleLocal::OpenFile(instance_,
130                                                         filename,
131                                                         PP_FILEOPENFLAG_WRITE |
132                                                         PP_FILEOPENFLAG_CREATE);
133   ASSERT_NE(PP_kInvalidFileHandle, file_handle);
134
135   std::string contents = "This is file.";
136   std::string read_contents;
137   ASSERT_TRUE(WriteFile(file_handle, contents));
138   ASSERT_FALSE(ReadFile(file_handle, &read_contents));
139   CloseFileHandle(file_handle);
140
141   file_handle = FileModuleLocal::OpenFile(instance_,
142                                           filename,
143                                           PP_FILEOPENFLAG_READ);
144   ASSERT_NE(PP_kInvalidFileHandle, file_handle);
145
146   ASSERT_FALSE(WriteFile(file_handle, contents));
147   ASSERT_TRUE(ReadFile(file_handle, &read_contents));
148   ASSERT_EQ(contents, read_contents);
149   CloseFileHandle(file_handle);
150
151   PASS();
152 }
153
154 std::string TestFlashFile::TestRenameFile() {
155   SetUp();
156   std::string filename = "abc.txt";
157   std::string new_filename = "abc_new.txt";
158   std::string contents = "This is file.";
159   std::string read_contents;
160
161   PP_FileHandle file_handle = FileModuleLocal::OpenFile(instance_,
162                                                         filename,
163                                                         PP_FILEOPENFLAG_WRITE |
164                                                         PP_FILEOPENFLAG_CREATE);
165   ASSERT_NE(PP_kInvalidFileHandle, file_handle);
166   ASSERT_TRUE(WriteFile(file_handle, contents));
167   CloseFileHandle(file_handle);
168
169   ASSERT_TRUE(FileModuleLocal::RenameFile(instance_, filename, new_filename));
170
171   file_handle = FileModuleLocal::OpenFile(instance_,
172                                           new_filename,
173                                           PP_FILEOPENFLAG_READ);
174   ASSERT_NE(PP_kInvalidFileHandle, file_handle);
175   ASSERT_TRUE(ReadFile(file_handle, &read_contents));
176   ASSERT_EQ(contents, read_contents);
177   CloseFileHandle(file_handle);
178
179   // Check that the old file no longer exists.
180   PP_FileInfo unused;
181   ASSERT_FALSE(FileModuleLocal::QueryFile(instance_, filename, &unused));
182
183   PASS();
184 }
185
186 std::string TestFlashFile::TestDeleteFileOrDir() {
187   SetUp();
188   std::string filename = "abc.txt";
189   std::string dirname = "def";
190   std::string contents = "This is file.";
191
192   // Test file deletion.
193   PP_FileHandle file_handle = FileModuleLocal::OpenFile(instance_,
194                                                         filename,
195                                                         PP_FILEOPENFLAG_WRITE |
196                                                         PP_FILEOPENFLAG_CREATE);
197   ASSERT_NE(PP_kInvalidFileHandle, file_handle);
198   ASSERT_TRUE(WriteFile(file_handle, contents));
199   CloseFileHandle(file_handle);
200   ASSERT_TRUE(FileModuleLocal::DeleteFileOrDir(instance_, filename, false));
201   PP_FileInfo unused;
202   ASSERT_FALSE(FileModuleLocal::QueryFile(instance_, filename, &unused));
203
204   // Test directory deletion.
205   ASSERT_TRUE(FileModuleLocal::CreateDir(instance_, dirname));
206   ASSERT_TRUE(FileModuleLocal::DeleteFileOrDir(instance_, dirname, false));
207   ASSERT_FALSE(FileModuleLocal::QueryFile(instance_, dirname, &unused));
208
209   // Test recursive directory deletion.
210   ASSERT_TRUE(FileModuleLocal::CreateDir(instance_, dirname));
211   file_handle = FileModuleLocal::OpenFile(
212       instance_, dirname + "/" + filename,
213       PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE);
214   ASSERT_NE(PP_kInvalidFileHandle, file_handle);
215   ASSERT_TRUE(WriteFile(file_handle, contents));
216   CloseFileHandle(file_handle);
217   ASSERT_FALSE(FileModuleLocal::DeleteFileOrDir(instance_, dirname, false));
218   ASSERT_TRUE(FileModuleLocal::DeleteFileOrDir(instance_, dirname, true));
219   ASSERT_FALSE(FileModuleLocal::QueryFile(instance_, filename, &unused));
220
221   PASS();
222 }
223
224 std::string TestFlashFile::TestCreateDir() {
225   SetUp();
226   std::string dirname = "abc";
227   PP_FileInfo info;
228   ASSERT_FALSE(FileModuleLocal::QueryFile(instance_, dirname, &info));
229   ASSERT_TRUE(FileModuleLocal::CreateDir(instance_, dirname));
230   ASSERT_TRUE(FileModuleLocal::QueryFile(instance_, dirname, &info));
231   ASSERT_EQ(info.type, PP_FILETYPE_DIRECTORY);
232
233   PASS();
234 }
235
236 std::string TestFlashFile::TestQueryFile() {
237   std::string filename = "abc.txt";
238   std::string dirname = "def";
239   std::string contents = "This is file.";
240   PP_FileInfo info;
241
242   // Test querying a file.
243   PP_FileHandle file_handle = FileModuleLocal::OpenFile(instance_,
244                                                         filename,
245                                                         PP_FILEOPENFLAG_WRITE |
246                                                         PP_FILEOPENFLAG_CREATE);
247   ASSERT_NE(PP_kInvalidFileHandle, file_handle);
248   ASSERT_TRUE(WriteFile(file_handle, contents));
249   CloseFileHandle(file_handle);
250   ASSERT_TRUE(FileModuleLocal::QueryFile(instance_, filename, &info));
251   ASSERT_EQ(static_cast<size_t>(info.size), contents.size());
252   ASSERT_EQ(info.type, PP_FILETYPE_REGULAR);
253   // TODO(raymes): Test the other fields.
254
255   // Test querying a directory.
256   ASSERT_TRUE(FileModuleLocal::CreateDir(instance_, dirname));
257   ASSERT_TRUE(FileModuleLocal::QueryFile(instance_, dirname, &info));
258   ASSERT_EQ(info.type, PP_FILETYPE_DIRECTORY);
259   // TODO(raymes): Test the other fields.
260
261   // Test querying a non-existent file.
262   ASSERT_FALSE(FileModuleLocal::QueryFile(instance_, "xx", &info));
263
264   PASS();
265 }
266
267 std::string TestFlashFile::TestGetDirContents() {
268   SetUp();
269   std::vector<FileModuleLocal::DirEntry> result;
270   ASSERT_TRUE(FileModuleLocal::GetDirContents(instance_, std::string(),
271                                               &result));
272   ASSERT_EQ(result.size(), 1);
273   ASSERT_EQ(result[0].name, "..");
274   ASSERT_EQ(result[0].is_dir, true);
275
276   std::string filename = "abc.txt";
277   std::string dirname = "def";
278   std::string contents = "This is file.";
279   PP_FileHandle file_handle = FileModuleLocal::OpenFile(instance_,
280                                                         filename,
281                                                         PP_FILEOPENFLAG_WRITE |
282                                                         PP_FILEOPENFLAG_CREATE);
283   ASSERT_NE(PP_kInvalidFileHandle, file_handle);
284   ASSERT_TRUE(WriteFile(file_handle, contents));
285   CloseFileHandle(file_handle);
286   ASSERT_TRUE(FileModuleLocal::CreateDir(instance_, dirname));
287
288   ASSERT_TRUE(
289       FileModuleLocal::GetDirContents(instance_, std::string(), &result));
290   FileModuleLocal::DirEntry expected[] = { { "..", true }, { filename, false },
291                                            { dirname, true } };
292   size_t expected_size = sizeof(expected) / sizeof(expected[0]);
293
294   std::sort(expected, expected + expected_size, DirEntryLessThan);
295   std::sort(result.begin(), result.end(), DirEntryLessThan);
296
297   ASSERT_EQ(expected_size, result.size());
298   ASSERT_TRUE(std::equal(expected, expected + expected_size, result.begin(),
299                          DirEntryEqual));
300
301   PASS();
302 }
303
304 std::string TestFlashFile::TestCreateTemporaryFile() {
305   SetUp();
306   size_t before_create = 0;
307   ASSERT_SUBTEST_SUCCESS(GetItemCountUnderModuleLocalRoot(&before_create));
308
309   PP_FileHandle file_handle = FileModuleLocal::CreateTemporaryFile(instance_);
310   ASSERT_NE(PP_kInvalidFileHandle, file_handle);
311
312   std::string contents = "This is a temp file.";
313   ASSERT_TRUE(WriteFile(file_handle, contents));
314   std::string read_contents;
315   ASSERT_TRUE(ReadFile(file_handle, &read_contents));
316   ASSERT_EQ(contents, read_contents);
317
318   CloseFileHandle(file_handle);
319
320   size_t after_close = 0;
321   ASSERT_SUBTEST_SUCCESS(GetItemCountUnderModuleLocalRoot(&after_close));
322   ASSERT_EQ(before_create, after_close);
323
324   PASS();
325 }
326
327 std::string TestFlashFile::GetItemCountUnderModuleLocalRoot(
328     size_t* item_count) {
329   std::vector<FileModuleLocal::DirEntry> contents;
330   ASSERT_TRUE(
331       FileModuleLocal::GetDirContents(instance_, std::string(), &contents));
332   *item_count = contents.size();
333   PASS();
334 }