blob: b252940485a68fa1ed81f4e4f38521924ca7e9ed [file] [log] [blame]
[email protected]481a4b72012-06-15 22:56:531// 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
[email protected]0c92b0d2012-12-08 00:46:237#include <algorithm>
8#include <vector>
9
10#include "ppapi/c/pp_file_info.h"
11#include "ppapi/c/ppb_file_io.h"
[email protected]481a4b72012-06-15 22:56:5312#include "ppapi/cpp/module.h"
[email protected]ee0abbf2012-06-25 22:19:2813#include "ppapi/cpp/private/flash_file.h"
[email protected]481a4b72012-06-15 22:56:5314#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
[email protected]ee0abbf2012-06-25 22:19:2824using pp::flash::FileModuleLocal;
25
[email protected]481a4b72012-06-15 22:56:5326namespace {
27
28void 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
36bool WriteFile(PP_FileHandle file_handle, const std::string& contents) {
37#if defined(PPAPI_OS_WIN)
38 DWORD bytes_written = 0;
brettw669d47b12015-02-13 21:17:3839 BOOL result = ::WriteFile(file_handle, contents.c_str(),
40 static_cast<DWORD>(contents.size()),
[email protected]481a4b72012-06-15 22:56:5341 &bytes_written, NULL);
42 return result && bytes_written == static_cast<DWORD>(contents.size());
43#else
44 ssize_t bytes_written = 0;
45 do {
46 bytes_written = write(file_handle, contents.c_str(), contents.size());
47 } while (bytes_written == -1 && errno == EINTR);
48 return bytes_written == static_cast<ssize_t>(contents.size());
49#endif
50}
51
52bool ReadFile(PP_FileHandle file_handle, std::string* contents) {
53 static const size_t kBufferSize = 1024;
54 char* buffer = new char[kBufferSize];
55 bool result = false;
56 contents->clear();
57
58#if defined(PPAPI_OS_WIN)
59 SetFilePointer(file_handle, 0, NULL, FILE_BEGIN);
60 DWORD bytes_read = 0;
61 do {
62 result = !!::ReadFile(file_handle, buffer, kBufferSize, &bytes_read, NULL);
63 if (result && bytes_read > 0)
64 contents->append(buffer, bytes_read);
65 } while (result && bytes_read > 0);
66#else
67 lseek(file_handle, 0, SEEK_SET);
68 ssize_t bytes_read = 0;
69 do {
70 do {
71 bytes_read = read(file_handle, buffer, kBufferSize);
72 } while (bytes_read == -1 && errno == EINTR);
73 result = bytes_read != -1;
74 if (bytes_read > 0)
75 contents->append(buffer, bytes_read);
76 } while (bytes_read > 0);
77#endif
78
79 delete[] buffer;
80 return result;
81}
82
[email protected]0c92b0d2012-12-08 00:46:2383bool DirEntryEqual(FileModuleLocal::DirEntry i,
84 FileModuleLocal::DirEntry j) {
85 return i.name == j.name && i.is_dir == j.is_dir;
86}
87
88bool DirEntryLessThan(FileModuleLocal::DirEntry i,
89 FileModuleLocal::DirEntry j) {
90 if (i.name == j.name)
91 return i.is_dir < j.is_dir;
92 return i.name < j.name;
93}
94
[email protected]481a4b72012-06-15 22:56:5395} // namespace
96
97REGISTER_TEST_CASE(FlashFile);
98
99TestFlashFile::TestFlashFile(TestingInstance* instance)
[email protected]ee0abbf2012-06-25 22:19:28100 : TestCase(instance) {
[email protected]481a4b72012-06-15 22:56:53101}
102
103TestFlashFile::~TestFlashFile() {
104}
105
106bool TestFlashFile::Init() {
[email protected]ee0abbf2012-06-25 22:19:28107 return FileModuleLocal::IsAvailable();
[email protected]481a4b72012-06-15 22:56:53108}
109
110void TestFlashFile::RunTests(const std::string& filter) {
[email protected]0c92b0d2012-12-08 00:46:23111 RUN_TEST(OpenFile, filter);
112 RUN_TEST(RenameFile, filter);
113 RUN_TEST(DeleteFileOrDir, filter);
114 RUN_TEST(CreateDir, filter);
115 RUN_TEST(QueryFile, filter);
116 RUN_TEST(GetDirContents, filter);
[email protected]481a4b72012-06-15 22:56:53117 RUN_TEST(CreateTemporaryFile, filter);
118}
119
[email protected]0c92b0d2012-12-08 00:46:23120void TestFlashFile::SetUp() {
121 // Clear out existing test data.
122 FileModuleLocal::DeleteFileOrDir(instance_, std::string(), true);
[email protected]ee0abbf2012-06-25 22:19:28123 // Make sure that the root directory exists.
124 FileModuleLocal::CreateDir(instance_, std::string());
[email protected]0c92b0d2012-12-08 00:46:23125}
[email protected]ee0abbf2012-06-25 22:19:28126
[email protected]0c92b0d2012-12-08 00:46:23127std::string TestFlashFile::TestOpenFile() {
128 SetUp();
129 std::string filename = "abc.txt";
130 PP_FileHandle file_handle = FileModuleLocal::OpenFile(instance_,
131 filename,
132 PP_FILEOPENFLAG_WRITE |
133 PP_FILEOPENFLAG_CREATE);
134 ASSERT_NE(PP_kInvalidFileHandle, file_handle);
135
136 std::string contents = "This is file.";
137 std::string read_contents;
138 ASSERT_TRUE(WriteFile(file_handle, contents));
139 ASSERT_FALSE(ReadFile(file_handle, &read_contents));
140 CloseFileHandle(file_handle);
141
142 file_handle = FileModuleLocal::OpenFile(instance_,
143 filename,
144 PP_FILEOPENFLAG_READ);
145 ASSERT_NE(PP_kInvalidFileHandle, file_handle);
146
147 ASSERT_FALSE(WriteFile(file_handle, contents));
148 ASSERT_TRUE(ReadFile(file_handle, &read_contents));
149 ASSERT_EQ(contents, read_contents);
150 CloseFileHandle(file_handle);
151
152 PASS();
153}
154
155std::string TestFlashFile::TestRenameFile() {
156 SetUp();
157 std::string filename = "abc.txt";
158 std::string new_filename = "abc_new.txt";
159 std::string contents = "This is file.";
160 std::string read_contents;
161
162 PP_FileHandle file_handle = FileModuleLocal::OpenFile(instance_,
163 filename,
164 PP_FILEOPENFLAG_WRITE |
165 PP_FILEOPENFLAG_CREATE);
166 ASSERT_NE(PP_kInvalidFileHandle, file_handle);
167 ASSERT_TRUE(WriteFile(file_handle, contents));
168 CloseFileHandle(file_handle);
169
170 ASSERT_TRUE(FileModuleLocal::RenameFile(instance_, filename, new_filename));
171
172 file_handle = FileModuleLocal::OpenFile(instance_,
173 new_filename,
174 PP_FILEOPENFLAG_READ);
175 ASSERT_NE(PP_kInvalidFileHandle, file_handle);
176 ASSERT_TRUE(ReadFile(file_handle, &read_contents));
177 ASSERT_EQ(contents, read_contents);
178 CloseFileHandle(file_handle);
179
180 // Check that the old file no longer exists.
181 PP_FileInfo unused;
182 ASSERT_FALSE(FileModuleLocal::QueryFile(instance_, filename, &unused));
183
184 PASS();
185}
186
187std::string TestFlashFile::TestDeleteFileOrDir() {
188 SetUp();
189 std::string filename = "abc.txt";
190 std::string dirname = "def";
191 std::string contents = "This is file.";
192
193 // Test file deletion.
194 PP_FileHandle file_handle = FileModuleLocal::OpenFile(instance_,
195 filename,
196 PP_FILEOPENFLAG_WRITE |
197 PP_FILEOPENFLAG_CREATE);
198 ASSERT_NE(PP_kInvalidFileHandle, file_handle);
199 ASSERT_TRUE(WriteFile(file_handle, contents));
200 CloseFileHandle(file_handle);
201 ASSERT_TRUE(FileModuleLocal::DeleteFileOrDir(instance_, filename, false));
202 PP_FileInfo unused;
203 ASSERT_FALSE(FileModuleLocal::QueryFile(instance_, filename, &unused));
204
205 // Test directory deletion.
206 ASSERT_TRUE(FileModuleLocal::CreateDir(instance_, dirname));
207 ASSERT_TRUE(FileModuleLocal::DeleteFileOrDir(instance_, dirname, false));
208 ASSERT_FALSE(FileModuleLocal::QueryFile(instance_, dirname, &unused));
209
210 // Test recursive directory deletion.
211 ASSERT_TRUE(FileModuleLocal::CreateDir(instance_, dirname));
212 file_handle = FileModuleLocal::OpenFile(
213 instance_, dirname + "/" + filename,
214 PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE);
215 ASSERT_NE(PP_kInvalidFileHandle, file_handle);
216 ASSERT_TRUE(WriteFile(file_handle, contents));
217 CloseFileHandle(file_handle);
218 ASSERT_FALSE(FileModuleLocal::DeleteFileOrDir(instance_, dirname, false));
219 ASSERT_TRUE(FileModuleLocal::DeleteFileOrDir(instance_, dirname, true));
220 ASSERT_FALSE(FileModuleLocal::QueryFile(instance_, filename, &unused));
221
222 PASS();
223}
224
225std::string TestFlashFile::TestCreateDir() {
226 SetUp();
227 std::string dirname = "abc";
228 PP_FileInfo info;
229 ASSERT_FALSE(FileModuleLocal::QueryFile(instance_, dirname, &info));
230 ASSERT_TRUE(FileModuleLocal::CreateDir(instance_, dirname));
231 ASSERT_TRUE(FileModuleLocal::QueryFile(instance_, dirname, &info));
[email protected]6d852862014-01-24 01:10:23232 ASSERT_EQ(PP_FILETYPE_DIRECTORY, info.type);
[email protected]0c92b0d2012-12-08 00:46:23233
234 PASS();
235}
236
237std::string TestFlashFile::TestQueryFile() {
238 std::string filename = "abc.txt";
239 std::string dirname = "def";
240 std::string contents = "This is file.";
241 PP_FileInfo info;
242
243 // Test querying a file.
244 PP_FileHandle file_handle = FileModuleLocal::OpenFile(instance_,
245 filename,
246 PP_FILEOPENFLAG_WRITE |
247 PP_FILEOPENFLAG_CREATE);
248 ASSERT_NE(PP_kInvalidFileHandle, file_handle);
249 ASSERT_TRUE(WriteFile(file_handle, contents));
250 CloseFileHandle(file_handle);
251 ASSERT_TRUE(FileModuleLocal::QueryFile(instance_, filename, &info));
252 ASSERT_EQ(static_cast<size_t>(info.size), contents.size());
[email protected]6d852862014-01-24 01:10:23253 ASSERT_EQ(PP_FILETYPE_REGULAR, info.type);
[email protected]0c92b0d2012-12-08 00:46:23254 // TODO(raymes): Test the other fields.
255
256 // Test querying a directory.
257 ASSERT_TRUE(FileModuleLocal::CreateDir(instance_, dirname));
258 ASSERT_TRUE(FileModuleLocal::QueryFile(instance_, dirname, &info));
[email protected]6d852862014-01-24 01:10:23259 ASSERT_EQ(PP_FILETYPE_DIRECTORY, info.type);
[email protected]0c92b0d2012-12-08 00:46:23260 // TODO(raymes): Test the other fields.
261
262 // Test querying a non-existent file.
263 ASSERT_FALSE(FileModuleLocal::QueryFile(instance_, "xx", &info));
264
265 PASS();
266}
267
268std::string TestFlashFile::TestGetDirContents() {
269 SetUp();
270 std::vector<FileModuleLocal::DirEntry> result;
271 ASSERT_TRUE(FileModuleLocal::GetDirContents(instance_, std::string(),
272 &result));
[email protected]6d852862014-01-24 01:10:23273 ASSERT_EQ(1, result.size());
[email protected]0c92b0d2012-12-08 00:46:23274 ASSERT_EQ(result[0].name, "..");
275 ASSERT_EQ(result[0].is_dir, true);
276
277 std::string filename = "abc.txt";
278 std::string dirname = "def";
279 std::string contents = "This is file.";
280 PP_FileHandle file_handle = FileModuleLocal::OpenFile(instance_,
281 filename,
282 PP_FILEOPENFLAG_WRITE |
283 PP_FILEOPENFLAG_CREATE);
284 ASSERT_NE(PP_kInvalidFileHandle, file_handle);
285 ASSERT_TRUE(WriteFile(file_handle, contents));
286 CloseFileHandle(file_handle);
287 ASSERT_TRUE(FileModuleLocal::CreateDir(instance_, dirname));
288
[email protected]007b3f82013-04-09 08:46:45289 ASSERT_TRUE(
290 FileModuleLocal::GetDirContents(instance_, std::string(), &result));
291 FileModuleLocal::DirEntry expected[] = { { "..", true }, { filename, false },
292 { dirname, true } };
[email protected]0c92b0d2012-12-08 00:46:23293 size_t expected_size = sizeof(expected) / sizeof(expected[0]);
294
295 std::sort(expected, expected + expected_size, DirEntryLessThan);
296 std::sort(result.begin(), result.end(), DirEntryLessThan);
297
298 ASSERT_EQ(expected_size, result.size());
299 ASSERT_TRUE(std::equal(expected, expected + expected_size, result.begin(),
300 DirEntryEqual));
301
302 PASS();
303}
304
305std::string TestFlashFile::TestCreateTemporaryFile() {
306 SetUp();
[email protected]ee0abbf2012-06-25 22:19:28307 size_t before_create = 0;
[email protected]481a4b72012-06-15 22:56:53308 ASSERT_SUBTEST_SUCCESS(GetItemCountUnderModuleLocalRoot(&before_create));
309
[email protected]ee0abbf2012-06-25 22:19:28310 PP_FileHandle file_handle = FileModuleLocal::CreateTemporaryFile(instance_);
311 ASSERT_NE(PP_kInvalidFileHandle, file_handle);
[email protected]481a4b72012-06-15 22:56:53312
313 std::string contents = "This is a temp file.";
314 ASSERT_TRUE(WriteFile(file_handle, contents));
315 std::string read_contents;
316 ASSERT_TRUE(ReadFile(file_handle, &read_contents));
317 ASSERT_EQ(contents, read_contents);
318
319 CloseFileHandle(file_handle);
320
[email protected]ee0abbf2012-06-25 22:19:28321 size_t after_close = 0;
[email protected]481a4b72012-06-15 22:56:53322 ASSERT_SUBTEST_SUCCESS(GetItemCountUnderModuleLocalRoot(&after_close));
323 ASSERT_EQ(before_create, after_close);
324
325 PASS();
326}
327
328std::string TestFlashFile::GetItemCountUnderModuleLocalRoot(
[email protected]ee0abbf2012-06-25 22:19:28329 size_t* item_count) {
[email protected]d301c4a2012-07-12 21:27:01330 std::vector<FileModuleLocal::DirEntry> contents;
[email protected]007b3f82013-04-09 08:46:45331 ASSERT_TRUE(
332 FileModuleLocal::GetDirContents(instance_, std::string(), &contents));
[email protected]ee0abbf2012-06-25 22:19:28333 *item_count = contents.size();
[email protected]481a4b72012-06-15 22:56:53334 PASS();
335}