Make certificate viewer a tab-modal dialog.
[chromium-blink-merge.git] / ppapi / tests / test_file_ref.cc
blob4aab3d67b21c054205481725961a481947d5a8cd
1 // Copyright (c) 2011 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 "ppapi/tests/test_file_ref.h"
7 #include <stdio.h>
8 #include <vector>
10 #include "ppapi/c/pp_errors.h"
11 #include "ppapi/c/ppb_file_io.h"
12 #include "ppapi/c/dev/ppb_testing_dev.h"
13 #include "ppapi/cpp/dev/directory_entry_dev.h"
14 #include "ppapi/cpp/dev/directory_reader_dev.h"
15 #include "ppapi/cpp/file_io.h"
16 #include "ppapi/cpp/file_ref.h"
17 #include "ppapi/cpp/file_system.h"
18 #include "ppapi/cpp/instance.h"
19 #include "ppapi/cpp/module.h"
20 #include "ppapi/cpp/url_loader.h"
21 #include "ppapi/cpp/url_request_info.h"
22 #include "ppapi/cpp/url_response_info.h"
23 #include "ppapi/tests/test_utils.h"
24 #include "ppapi/tests/testing_instance.h"
26 REGISTER_TEST_CASE(FileRef);
28 namespace {
30 const char* kPersFileName = "persistent";
31 const char* kTempFileName = "temporary";
32 const char* kParentPath = "/foo/bar";
33 const char* kPersFilePath = "/foo/bar/persistent";
34 const char* kTempFilePath = "/foo/bar/temporary";
35 const char* kTerribleName = "!@#$%^&*()-_=+{}[] ;:'\"|`~\t\n\r\b?";
37 std::string ReportMismatch(const std::string& method_name,
38 const std::string& returned_result,
39 const std::string& expected_result) {
40 return method_name + " returned '" + returned_result + "'; '" +
41 expected_result + "' expected.";
44 } // namespace
46 bool TestFileRef::Init() {
47 return CheckTestingInterface() && EnsureRunningOverHTTP();
50 std::string TestFileRef::MakeExternalFileRef(pp::FileRef* file_ref_ext) {
51 pp::URLRequestInfo request(instance_);
52 request.SetURL("test_url_loader_data/hello.txt");
53 request.SetStreamToFile(true);
55 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
57 pp::URLLoader loader(instance_);
58 callback.WaitForResult(loader.Open(request, callback.GetCallback()));
59 CHECK_CALLBACK_BEHAVIOR(callback);
60 ASSERT_EQ(PP_OK, callback.result());
62 pp::URLResponseInfo response_info(loader.GetResponseInfo());
63 ASSERT_FALSE(response_info.is_null());
64 ASSERT_EQ(200, response_info.GetStatusCode());
66 *file_ref_ext = pp::FileRef(response_info.GetBodyAsFileRef());
67 ASSERT_EQ(PP_FILESYSTEMTYPE_EXTERNAL, file_ref_ext->GetFileSystemType());
68 PASS();
71 void TestFileRef::RunTests(const std::string& filter) {
72 RUN_CALLBACK_TEST(TestFileRef, Create, filter);
73 RUN_CALLBACK_TEST(TestFileRef, GetFileSystemType, filter);
74 RUN_CALLBACK_TEST(TestFileRef, GetName, filter);
75 RUN_CALLBACK_TEST(TestFileRef, GetPath, filter);
76 RUN_CALLBACK_TEST(TestFileRef, GetParent, filter);
77 RUN_CALLBACK_TEST(TestFileRef, MakeDirectory, filter);
78 RUN_CALLBACK_TEST(TestFileRef, QueryAndTouchFile, filter);
79 RUN_CALLBACK_TEST(TestFileRef, DeleteFileAndDirectory, filter);
80 RUN_CALLBACK_TEST(TestFileRef, RenameFileAndDirectory, filter);
81 RUN_CALLBACK_TEST(TestFileRef, Query, filter);
82 RUN_CALLBACK_TEST(TestFileRef, FileNameEscaping, filter);
85 std::string TestFileRef::TestCreate() {
86 std::vector<std::string> invalid_paths;
87 invalid_paths.push_back("invalid_path"); // no '/' at the first character
88 invalid_paths.push_back(std::string()); // empty path
89 // The following are directory traversal checks
90 invalid_paths.push_back("..");
91 invalid_paths.push_back("/../invalid_path");
92 invalid_paths.push_back("/../../invalid_path");
93 invalid_paths.push_back("/invalid/../../path");
94 const size_t num_invalid_paths = invalid_paths.size();
96 pp::FileSystem file_system_pers(
97 instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
98 pp::FileSystem file_system_temp(
99 instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
100 for (size_t j = 0; j < num_invalid_paths; ++j) {
101 pp::FileRef file_ref_pers(file_system_pers, invalid_paths[j].c_str());
102 if (file_ref_pers.pp_resource() != 0) {
103 return "file_ref_pers expected to be invalid for path: " +
104 invalid_paths[j];
106 pp::FileRef file_ref_temp(file_system_temp, invalid_paths[j].c_str());
107 if (file_ref_temp.pp_resource() != 0) {
108 return "file_ref_temp expected to be invalid for path: " +
109 invalid_paths[j];
112 PASS();
115 std::string TestFileRef::TestGetFileSystemType() {
116 pp::FileSystem file_system_pers(
117 instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
118 pp::FileSystem file_system_temp(
119 instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
121 pp::FileRef file_ref_pers(file_system_pers, kPersFilePath);
122 if (file_ref_pers.GetFileSystemType() != PP_FILESYSTEMTYPE_LOCALPERSISTENT)
123 return "file_ref_pers expected to be persistent.";
125 pp::FileRef file_ref_temp(file_system_temp, kTempFilePath);
126 if (file_ref_temp.GetFileSystemType() != PP_FILESYSTEMTYPE_LOCALTEMPORARY)
127 return "file_ref_temp expected to be temporary.";
129 pp::FileRef file_ref_ext;
130 std::string result = MakeExternalFileRef(&file_ref_ext);
131 if (!result.empty())
132 return result;
133 PASS();
136 std::string TestFileRef::TestGetName() {
137 pp::FileSystem file_system_pers(
138 instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
139 pp::FileSystem file_system_temp(
140 instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
142 pp::FileRef file_ref_pers(file_system_pers, kPersFilePath);
143 std::string name = file_ref_pers.GetName().AsString();
144 if (name != kPersFileName)
145 return ReportMismatch("FileRef::GetName", name, kPersFileName);
147 pp::FileRef file_ref_temp(file_system_temp, kTempFilePath);
148 name = file_ref_temp.GetName().AsString();
149 if (name != kTempFileName)
150 return ReportMismatch("FileRef::GetName", name, kTempFileName);
152 // Test the "/" case.
153 pp::FileRef file_ref_slash(file_system_temp, "/");
154 name = file_ref_slash.GetName().AsString();
155 if (name != "/")
156 return ReportMismatch("FileRef::GetName", name, "/");
158 pp::URLRequestInfo request(instance_);
159 request.SetURL("test_url_loader_data/hello.txt");
160 request.SetStreamToFile(true);
162 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
164 pp::URLLoader loader(instance_);
165 callback.WaitForResult(loader.Open(request, callback.GetCallback()));
166 CHECK_CALLBACK_BEHAVIOR(callback);
167 ASSERT_EQ(PP_OK, callback.result());
169 pp::URLResponseInfo response_info(loader.GetResponseInfo());
170 ASSERT_FALSE(response_info.is_null());
171 ASSERT_EQ(200, response_info.GetStatusCode());
173 pp::FileRef file_ref_ext(response_info.GetBodyAsFileRef());
174 name = file_ref_ext.GetName().AsString();
175 ASSERT_FALSE(name.empty());
177 PASS();
180 std::string TestFileRef::TestGetPath() {
181 pp::FileSystem file_system_pers(
182 instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
183 pp::FileSystem file_system_temp(
184 instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
186 pp::FileRef file_ref_pers(file_system_pers, kPersFilePath);
187 ASSERT_EQ(kPersFilePath, file_ref_pers.GetPath().AsString());
189 pp::FileRef file_ref_temp(file_system_temp, kTempFilePath);
190 ASSERT_EQ(kTempFilePath, file_ref_temp.GetPath().AsString());
192 pp::URLRequestInfo request(instance_);
193 request.SetURL("test_url_loader_data/hello.txt");
194 request.SetStreamToFile(true);
196 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
198 pp::URLLoader loader(instance_);
199 callback.WaitForResult(loader.Open(request, callback.GetCallback()));
200 CHECK_CALLBACK_BEHAVIOR(callback);
201 ASSERT_EQ(PP_OK, callback.result());
203 pp::URLResponseInfo response_info(loader.GetResponseInfo());
204 ASSERT_FALSE(response_info.is_null());
205 ASSERT_EQ(200, response_info.GetStatusCode());
207 pp::FileRef file_ref_ext(response_info.GetBodyAsFileRef());
208 ASSERT_TRUE(file_ref_ext.GetPath().is_undefined());
210 PASS();
213 std::string TestFileRef::TestGetParent() {
214 pp::FileSystem file_system_pers(
215 instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
216 pp::FileSystem file_system_temp(
217 instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
219 pp::FileRef file_ref_pers(file_system_pers, kPersFilePath);
220 ASSERT_EQ(kParentPath, file_ref_pers.GetParent().GetPath().AsString());
222 pp::FileRef file_ref_temp(file_system_temp, kTempFilePath);
223 ASSERT_EQ(kParentPath, file_ref_temp.GetParent().GetPath().AsString());
225 // Test the "/" case.
226 pp::FileRef file_ref_slash(file_system_temp, "/");
227 ASSERT_EQ("/", file_ref_slash.GetParent().GetPath().AsString());
229 // Test the "/foo" case (the parent is "/").
230 pp::FileRef file_ref_with_root_parent(file_system_temp, "/foo");
231 ASSERT_EQ("/", file_ref_with_root_parent.GetParent().GetPath().AsString());
233 pp::URLRequestInfo request(instance_);
234 request.SetURL("test_url_loader_data/hello.txt");
235 request.SetStreamToFile(true);
237 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
239 pp::URLLoader loader(instance_);
240 callback.WaitForResult(loader.Open(request, callback.GetCallback()));
241 CHECK_CALLBACK_BEHAVIOR(callback);
242 ASSERT_EQ(PP_OK, callback.result());
244 pp::URLResponseInfo response_info(loader.GetResponseInfo());
245 ASSERT_FALSE(response_info.is_null());
246 ASSERT_EQ(200, response_info.GetStatusCode());
248 pp::FileRef file_ref_ext(response_info.GetBodyAsFileRef());
249 ASSERT_TRUE(file_ref_ext.GetParent().is_null());
251 PASS();
254 std::string TestFileRef::TestMakeDirectory() {
255 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
257 // Open.
258 pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
259 callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
260 CHECK_CALLBACK_BEHAVIOR(callback);
261 ASSERT_EQ(PP_OK, callback.result());
263 // MakeDirectory.
264 pp::FileRef dir_ref(file_system, "/test_dir_make_directory");
265 callback.WaitForResult(dir_ref.MakeDirectory(callback.GetCallback()));
266 CHECK_CALLBACK_BEHAVIOR(callback);
267 ASSERT_EQ(PP_OK, callback.result());
269 // MakeDirectory aborted.
270 int32_t rv = PP_ERROR_FAILED;
272 rv = pp::FileRef(file_system, "/test_dir_make_abort")
273 .MakeDirectory(callback.GetCallback());
275 callback.WaitForAbortResult(rv);
276 CHECK_CALLBACK_BEHAVIOR(callback);
278 // MakeDirectoryIncludingAncestors.
279 dir_ref = pp::FileRef(file_system, "/dir_make_dir_1/dir_make_dir_2");
280 callback.WaitForResult(
281 dir_ref.MakeDirectoryIncludingAncestors(callback.GetCallback()));
282 CHECK_CALLBACK_BEHAVIOR(callback);
283 ASSERT_EQ(PP_OK, callback.result());
285 // MakeDirectoryIncludingAncestors aborted.
287 rv = pp::FileRef(file_system, "/dir_make_abort_1/dir_make_abort_2")
288 .MakeDirectoryIncludingAncestors(callback.GetCallback());
290 callback.WaitForAbortResult(rv);
291 CHECK_CALLBACK_BEHAVIOR(callback);
293 // MakeDirectory with nested path should fail.
294 dir_ref = pp::FileRef(file_system, "/dir_make_dir_3/dir_make_dir_4");
295 callback.WaitForResult(dir_ref.MakeDirectory(callback.GetCallback()));
296 CHECK_CALLBACK_BEHAVIOR(callback);
297 ASSERT_NE(PP_OK, callback.result());
299 PASS();
302 std::string TestFileRef::TestQueryAndTouchFile() {
303 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
304 pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
305 callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
306 CHECK_CALLBACK_BEHAVIOR(callback);
307 ASSERT_EQ(PP_OK, callback.result());
309 pp::FileRef file_ref(file_system, "/file_touch");
310 pp::FileIO file_io(instance_);
311 callback.WaitForResult(
312 file_io.Open(file_ref,
313 PP_FILEOPENFLAG_CREATE |
314 PP_FILEOPENFLAG_TRUNCATE |
315 PP_FILEOPENFLAG_WRITE,
316 callback.GetCallback()));
317 CHECK_CALLBACK_BEHAVIOR(callback);
318 ASSERT_EQ(PP_OK, callback.result());
320 // Write some data to have a non-zero file size.
321 callback.WaitForResult(file_io.Write(0, "test", 4, callback.GetCallback()));
322 CHECK_CALLBACK_BEHAVIOR(callback);
323 ASSERT_EQ(4, callback.result());
325 // Touch.
326 // last_access_time's granularity is 1 day
327 // last_modified_time's granularity is 2 seconds
328 const PP_Time last_access_time = 123 * 24 * 3600.0;
329 const PP_Time last_modified_time = 246.0;
330 callback.WaitForResult(file_ref.Touch(last_access_time, last_modified_time,
331 callback.GetCallback()));
332 CHECK_CALLBACK_BEHAVIOR(callback);
333 ASSERT_EQ(PP_OK, callback.result());
335 // Touch aborted.
336 int32_t rv = PP_ERROR_FAILED;
338 rv = pp::FileRef(file_system, "/file_touch_abort")
339 .Touch(last_access_time, last_modified_time, callback.GetCallback());
341 callback.WaitForResult(rv);
342 CHECK_CALLBACK_BEHAVIOR(callback);
343 if (rv == PP_OK_COMPLETIONPENDING) {
344 // Touch tried to run asynchronously and should have been aborted.
345 ASSERT_EQ(PP_ERROR_ABORTED, callback.result());
346 } else {
347 // Touch ran synchronously and should have failed because the file does not
348 // exist.
349 ASSERT_EQ(PP_ERROR_FILENOTFOUND, callback.result());
352 // Query.
353 PP_FileInfo info;
354 callback.WaitForResult(file_io.Query(&info, callback.GetCallback()));
355 CHECK_CALLBACK_BEHAVIOR(callback);
356 ASSERT_EQ(PP_OK, callback.result());
357 ASSERT_EQ(4, info.size);
358 ASSERT_EQ(PP_FILETYPE_REGULAR, info.type);
359 ASSERT_EQ(PP_FILESYSTEMTYPE_LOCALTEMPORARY, info.system_type);
360 ASSERT_EQ(last_access_time, info.last_access_time);
361 ASSERT_EQ(last_modified_time, info.last_modified_time);
363 // Cancellation test.
364 // TODO(viettrungluu): this test causes a bunch of LOG(WARNING)s; investigate.
365 // TODO(viettrungluu): check |info| for late writes.
367 rv = pp::FileRef(file_system, "/file_touch").Touch(
368 last_access_time, last_modified_time, callback.GetCallback());
370 callback.WaitForAbortResult(rv);
371 CHECK_CALLBACK_BEHAVIOR(callback);
373 PASS();
376 std::string TestFileRef::TestDeleteFileAndDirectory() {
377 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
378 pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
379 callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
380 CHECK_CALLBACK_BEHAVIOR(callback);
381 ASSERT_EQ(PP_OK, callback.result());
383 pp::FileRef file_ref(file_system, "/file_delete");
384 pp::FileIO file_io(instance_);
385 callback.WaitForResult(
386 file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback.GetCallback()));
387 CHECK_CALLBACK_BEHAVIOR(callback);
388 ASSERT_EQ(PP_OK, callback.result());
390 callback.WaitForResult(file_ref.Delete(callback.GetCallback()));
391 CHECK_CALLBACK_BEHAVIOR(callback);
392 ASSERT_EQ(PP_OK, callback.result());
394 pp::FileRef dir_ref(file_system, "/dir_delete");
395 callback.WaitForResult(dir_ref.MakeDirectory(callback.GetCallback()));
396 CHECK_CALLBACK_BEHAVIOR(callback);
397 ASSERT_EQ(PP_OK, callback.result());
399 callback.WaitForResult(dir_ref.Delete(callback.GetCallback()));
400 CHECK_CALLBACK_BEHAVIOR(callback);
401 ASSERT_EQ(PP_OK, callback.result());
403 pp::FileRef nested_dir_ref(file_system, "/dir_delete_1/dir_delete_2");
404 callback.WaitForResult(
405 nested_dir_ref.MakeDirectoryIncludingAncestors(callback.GetCallback()));
406 CHECK_CALLBACK_BEHAVIOR(callback);
407 ASSERT_EQ(PP_OK, callback.result());
409 // Attempt to delete the parent directory (should fail; it's non-empty).
410 pp::FileRef parent_dir_ref = nested_dir_ref.GetParent();
411 callback.WaitForResult(parent_dir_ref.Delete(callback.GetCallback()));
412 CHECK_CALLBACK_BEHAVIOR(callback);
413 ASSERT_EQ(PP_ERROR_FAILED, callback.result());
415 pp::FileRef nonexistent_file_ref(file_system, "/nonexistent_file_delete");
416 callback.WaitForResult(nonexistent_file_ref.Delete(callback.GetCallback()));
417 CHECK_CALLBACK_BEHAVIOR(callback);
418 ASSERT_EQ(PP_ERROR_FILENOTFOUND, callback.result());
420 // Delete aborted.
421 int32_t rv = PP_ERROR_FAILED;
423 pp::FileRef file_ref_abort(file_system, "/file_delete_abort");
424 pp::FileIO file_io_abort(instance_);
425 callback.WaitForResult(
426 file_io_abort.Open(file_ref_abort, PP_FILEOPENFLAG_CREATE,
427 callback.GetCallback()));
428 CHECK_CALLBACK_BEHAVIOR(callback);
429 ASSERT_EQ(PP_OK, callback.result());
430 rv = file_ref_abort.Delete(callback.GetCallback());
432 callback.WaitForAbortResult(rv);
433 CHECK_CALLBACK_BEHAVIOR(callback);
435 PASS();
438 std::string TestFileRef::TestRenameFileAndDirectory() {
439 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
440 pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
441 callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
442 CHECK_CALLBACK_BEHAVIOR(callback);
443 ASSERT_EQ(PP_OK, callback.result());
445 pp::FileRef file_ref(file_system, "/file_rename");
446 pp::FileIO file_io(instance_);
447 callback.WaitForResult(
448 file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback.GetCallback()));
449 CHECK_CALLBACK_BEHAVIOR(callback);
450 ASSERT_EQ(PP_OK, callback.result());
452 pp::FileRef target_file_ref(file_system, "/target_file_rename");
453 callback.WaitForResult(
454 file_ref.Rename(target_file_ref, callback.GetCallback()));
455 CHECK_CALLBACK_BEHAVIOR(callback);
456 ASSERT_EQ(PP_OK, callback.result());
458 pp::FileRef dir_ref(file_system, "/dir_rename");
459 callback.WaitForResult(dir_ref.MakeDirectory(callback.GetCallback()));
460 CHECK_CALLBACK_BEHAVIOR(callback);
461 ASSERT_EQ(PP_OK, callback.result());
463 pp::FileRef target_dir_ref(file_system, "/target_dir_rename");
464 callback.WaitForResult(
465 dir_ref.Rename(target_dir_ref, callback.GetCallback()));
466 CHECK_CALLBACK_BEHAVIOR(callback);
467 ASSERT_EQ(PP_OK, callback.result());
469 pp::FileRef nested_dir_ref(file_system, "/dir_rename_1/dir_rename_2");
470 callback.WaitForResult(
471 nested_dir_ref.MakeDirectoryIncludingAncestors(callback.GetCallback()));
472 CHECK_CALLBACK_BEHAVIOR(callback);
473 ASSERT_EQ(PP_OK, callback.result());
475 // Try to rename nested directory to the parent name. Should fail.
476 pp::FileRef target_nested_dir_ref(file_system, "/dir_rename_1");
477 callback.WaitForResult(
478 nested_dir_ref.Rename(target_nested_dir_ref, callback.GetCallback()));
479 CHECK_CALLBACK_BEHAVIOR(callback);
480 ASSERT_EQ(PP_ERROR_FAILED, callback.result());
482 // Rename aborted.
483 // TODO(viettrungluu): Figure out what we want to do if the target file
484 // resource is destroyed before completion.
485 int32_t rv = PP_ERROR_FAILED;
486 pp::FileRef target_file_ref_abort(file_system,
487 "/target_file_rename_abort");
489 pp::FileRef file_ref_abort(file_system, "/file_rename_abort");
490 pp::FileIO file_io_abort(instance_);
491 callback.WaitForResult(
492 file_io_abort.Open(file_ref_abort, PP_FILEOPENFLAG_CREATE,
493 callback.GetCallback()));
494 CHECK_CALLBACK_BEHAVIOR(callback);
495 ASSERT_EQ(PP_OK, callback.result());
497 rv = file_ref_abort.Rename(target_file_ref_abort, callback.GetCallback());
499 callback.WaitForAbortResult(rv);
500 CHECK_CALLBACK_BEHAVIOR(callback);
502 PASS();
505 std::string TestFileRef::TestQuery() {
506 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
508 pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
509 callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
510 CHECK_CALLBACK_BEHAVIOR(callback);
511 ASSERT_EQ(PP_OK, callback.result());
513 pp::FileRef file_ref(file_system, "/file");
514 pp::FileIO file_io(instance_);
515 callback.WaitForResult(file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE,
516 callback.GetCallback()));
517 CHECK_CALLBACK_BEHAVIOR(callback);
518 ASSERT_EQ(PP_OK, callback.result());
520 // We touch the file so we can easily check access and modified time.
521 callback.WaitForResult(file_io.Touch(0, 0, callback.GetCallback()));
522 CHECK_CALLBACK_BEHAVIOR(callback);
523 ASSERT_EQ(PP_OK, callback.result());
525 TestCompletionCallbackWithOutput<PP_FileInfo> out_callback(
526 instance_->pp_instance(), callback_type());
527 out_callback.WaitForResult(file_ref.Query(out_callback.GetCallback()));
528 CHECK_CALLBACK_BEHAVIOR(out_callback);
529 ASSERT_EQ(PP_OK, out_callback.result());
531 PP_FileInfo info = out_callback.output();
532 ASSERT_EQ(0, info.size);
533 ASSERT_EQ(PP_FILETYPE_REGULAR, info.type);
534 ASSERT_EQ(PP_FILESYSTEMTYPE_LOCALTEMPORARY, info.system_type);
535 ASSERT_DOUBLE_EQ(0.0, info.last_access_time);
536 ASSERT_DOUBLE_EQ(0.0, info.last_modified_time);
538 // Query a file ref on an external filesystem.
539 pp::FileRef file_ref_ext;
540 std::string result = MakeExternalFileRef(&file_ref_ext);
541 if (!result.empty())
542 return result;
543 out_callback.WaitForResult(file_ref_ext.Query(out_callback.GetCallback()));
544 CHECK_CALLBACK_BEHAVIOR(out_callback);
545 if (out_callback.result() != PP_OK)
546 return ReportError("Query() result", out_callback.result());
547 ASSERT_EQ(PP_OK, out_callback.result());
549 info = out_callback.output();
550 ASSERT_EQ(PP_FILETYPE_REGULAR, info.type);
551 ASSERT_EQ(PP_FILESYSTEMTYPE_EXTERNAL, info.system_type);
553 // We can't touch the file, so just sanity check the times.
554 ASSERT_TRUE(info.creation_time >= 0.0);
555 ASSERT_TRUE(info.last_modified_time >= 0.0);
556 ASSERT_TRUE(info.last_access_time >= 0.0);
558 // Query a file ref for a file that doesn't exist.
559 pp::FileRef missing_file_ref(file_system, "/missing_file");
560 out_callback.WaitForResult(missing_file_ref.Query(
561 out_callback.GetCallback()));
562 CHECK_CALLBACK_BEHAVIOR(out_callback);
563 ASSERT_EQ(PP_ERROR_FILENOTFOUND, out_callback.result());
565 PASS();
568 std::string TestFileRef::TestFileNameEscaping() {
569 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
570 pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
571 callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
572 CHECK_CALLBACK_BEHAVIOR(callback);
573 ASSERT_EQ(PP_OK, callback.result());
575 std::string test_dir_path = "/dir_for_escaping_test";
576 // Create a directory in which to test.
577 pp::FileRef test_dir_ref(file_system, test_dir_path.c_str());
578 callback.WaitForResult(test_dir_ref.MakeDirectory(callback.GetCallback()));
579 CHECK_CALLBACK_BEHAVIOR(callback);
580 ASSERT_EQ(PP_OK, callback.result());
582 // Create the file with the terrible name.
583 std::string full_file_path = test_dir_path + "/" + kTerribleName;
584 pp::FileRef file_ref(file_system, full_file_path.c_str());
585 pp::FileIO file_io(instance_);
586 callback.WaitForResult(
587 file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback.GetCallback()));
588 CHECK_CALLBACK_BEHAVIOR(callback);
589 ASSERT_EQ(PP_OK, callback.result());
591 // DirectoryReader only works out-of-process.
592 if (testing_interface_->IsOutOfProcess()) {
593 TestCompletionCallbackWithOutput< std::vector<pp::DirectoryEntry_Dev> >
594 output_callback(instance_->pp_instance(), callback_type());
595 pp::DirectoryReader_Dev directory_reader(test_dir_ref);
597 output_callback.WaitForResult(
598 directory_reader.ReadEntries(output_callback.GetCallback()));
599 CHECK_CALLBACK_BEHAVIOR(output_callback);
600 ASSERT_EQ(PP_OK, output_callback.result());
602 std::vector<pp::DirectoryEntry_Dev> entries = output_callback.output();
603 ASSERT_EQ(1, entries.size());
604 ASSERT_EQ(kTerribleName, entries.front().file_ref().GetName().AsString());
607 PASS();