OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ppapi/tests/test_file_ref.h" | 5 #include "ppapi/tests/test_file_ref.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 |
| 9 #include <sstream> |
8 #include <vector> | 10 #include <vector> |
9 | 11 |
10 #include "ppapi/c/pp_errors.h" | 12 #include "ppapi/c/pp_errors.h" |
11 #include "ppapi/c/ppb_file_io.h" | 13 #include "ppapi/c/ppb_file_io.h" |
12 #include "ppapi/c/dev/ppb_testing_dev.h" | 14 #include "ppapi/c/dev/ppb_testing_dev.h" |
13 #include "ppapi/cpp/dev/directory_entry_dev.h" | 15 #include "ppapi/cpp/directory_entry.h" |
14 #include "ppapi/cpp/dev/directory_reader_dev.h" | |
15 #include "ppapi/cpp/file_io.h" | 16 #include "ppapi/cpp/file_io.h" |
16 #include "ppapi/cpp/file_ref.h" | 17 #include "ppapi/cpp/file_ref.h" |
17 #include "ppapi/cpp/file_system.h" | 18 #include "ppapi/cpp/file_system.h" |
18 #include "ppapi/cpp/instance.h" | 19 #include "ppapi/cpp/instance.h" |
19 #include "ppapi/cpp/module.h" | 20 #include "ppapi/cpp/module.h" |
20 #include "ppapi/cpp/url_loader.h" | 21 #include "ppapi/cpp/url_loader.h" |
21 #include "ppapi/cpp/url_request_info.h" | 22 #include "ppapi/cpp/url_request_info.h" |
22 #include "ppapi/cpp/url_response_info.h" | 23 #include "ppapi/cpp/url_response_info.h" |
23 #include "ppapi/tests/test_utils.h" | 24 #include "ppapi/tests/test_utils.h" |
24 #include "ppapi/tests/testing_instance.h" | 25 #include "ppapi/tests/testing_instance.h" |
25 | 26 |
26 REGISTER_TEST_CASE(FileRef); | 27 REGISTER_TEST_CASE(FileRef); |
27 | 28 |
28 namespace { | 29 namespace { |
29 | 30 |
30 const char* kPersFileName = "persistent"; | 31 const char* kPersFileName = "persistent"; |
31 const char* kTempFileName = "temporary"; | 32 const char* kTempFileName = "temporary"; |
32 const char* kParentPath = "/foo/bar"; | 33 const char* kParentPath = "/foo/bar"; |
33 const char* kPersFilePath = "/foo/bar/persistent"; | 34 const char* kPersFilePath = "/foo/bar/persistent"; |
34 const char* kTempFilePath = "/foo/bar/temporary"; | 35 const char* kTempFilePath = "/foo/bar/temporary"; |
35 const char* kTerribleName = "!@#$%^&*()-_=+{}[] ;:'\"|`~\t\n\r\b?"; | 36 const char* kTerribleName = "!@#$%^&*()-_=+{}[] ;:'\"|`~\t\n\r\b?"; |
36 | 37 |
| 38 typedef std::vector<pp::DirectoryEntry> DirEntries; |
| 39 |
37 std::string ReportMismatch(const std::string& method_name, | 40 std::string ReportMismatch(const std::string& method_name, |
38 const std::string& returned_result, | 41 const std::string& returned_result, |
39 const std::string& expected_result) { | 42 const std::string& expected_result) { |
40 return method_name + " returned '" + returned_result + "'; '" + | 43 return method_name + " returned '" + returned_result + "'; '" + |
41 expected_result + "' expected."; | 44 expected_result + "' expected."; |
42 } | 45 } |
43 | 46 |
44 } // namespace | 47 } // namespace |
45 | 48 |
46 bool TestFileRef::Init() { | 49 bool TestFileRef::Init() { |
(...skipping 14 matching lines...) Expand all Loading... |
61 | 64 |
62 pp::URLResponseInfo response_info(loader.GetResponseInfo()); | 65 pp::URLResponseInfo response_info(loader.GetResponseInfo()); |
63 ASSERT_FALSE(response_info.is_null()); | 66 ASSERT_FALSE(response_info.is_null()); |
64 ASSERT_EQ(200, response_info.GetStatusCode()); | 67 ASSERT_EQ(200, response_info.GetStatusCode()); |
65 | 68 |
66 *file_ref_ext = pp::FileRef(response_info.GetBodyAsFileRef()); | 69 *file_ref_ext = pp::FileRef(response_info.GetBodyAsFileRef()); |
67 ASSERT_EQ(PP_FILESYSTEMTYPE_EXTERNAL, file_ref_ext->GetFileSystemType()); | 70 ASSERT_EQ(PP_FILESYSTEMTYPE_EXTERNAL, file_ref_ext->GetFileSystemType()); |
68 PASS(); | 71 PASS(); |
69 } | 72 } |
70 | 73 |
| 74 int32_t TestFileRef::DeleteDirectoryRecursively(pp::FileRef* dir) { |
| 75 if (!dir) |
| 76 return PP_ERROR_BADARGUMENT; |
| 77 |
| 78 TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
| 79 TestCompletionCallbackWithOutput<DirEntries> output_callback( |
| 80 instance_->pp_instance(), callback_type()); |
| 81 |
| 82 output_callback.WaitForResult( |
| 83 dir->ReadDirectoryEntries(output_callback.GetCallback())); |
| 84 int32_t rv = output_callback.result(); |
| 85 if (rv != PP_OK && rv != PP_ERROR_FILENOTFOUND) |
| 86 return rv; |
| 87 |
| 88 DirEntries entries = output_callback.output(); |
| 89 for (DirEntries::const_iterator it = entries.begin(); |
| 90 it != entries.end(); |
| 91 ++it) { |
| 92 pp::FileRef file_ref = it->file_ref(); |
| 93 if (it->file_type() == PP_FILETYPE_DIRECTORY) { |
| 94 rv = DeleteDirectoryRecursively(&file_ref); |
| 95 if (rv != PP_OK && rv != PP_ERROR_FILENOTFOUND) |
| 96 return rv; |
| 97 } else { |
| 98 callback.WaitForResult(file_ref.Delete(callback.GetCallback())); |
| 99 rv = callback.result(); |
| 100 if (rv != PP_OK && rv != PP_ERROR_FILENOTFOUND) |
| 101 return rv; |
| 102 } |
| 103 } |
| 104 callback.WaitForResult(dir->Delete(callback.GetCallback())); |
| 105 return callback.result(); |
| 106 } |
| 107 |
71 void TestFileRef::RunTests(const std::string& filter) { | 108 void TestFileRef::RunTests(const std::string& filter) { |
72 RUN_CALLBACK_TEST(TestFileRef, Create, filter); | 109 RUN_CALLBACK_TEST(TestFileRef, Create, filter); |
73 RUN_CALLBACK_TEST(TestFileRef, GetFileSystemType, filter); | 110 RUN_CALLBACK_TEST(TestFileRef, GetFileSystemType, filter); |
74 RUN_CALLBACK_TEST(TestFileRef, GetName, filter); | 111 RUN_CALLBACK_TEST(TestFileRef, GetName, filter); |
75 RUN_CALLBACK_TEST(TestFileRef, GetPath, filter); | 112 RUN_CALLBACK_TEST(TestFileRef, GetPath, filter); |
76 RUN_CALLBACK_TEST(TestFileRef, GetParent, filter); | 113 RUN_CALLBACK_TEST(TestFileRef, GetParent, filter); |
77 RUN_CALLBACK_TEST(TestFileRef, MakeDirectory, filter); | 114 RUN_CALLBACK_TEST(TestFileRef, MakeDirectory, filter); |
78 RUN_CALLBACK_TEST(TestFileRef, QueryAndTouchFile, filter); | 115 RUN_CALLBACK_TEST(TestFileRef, QueryAndTouchFile, filter); |
79 RUN_CALLBACK_TEST(TestFileRef, DeleteFileAndDirectory, filter); | 116 RUN_CALLBACK_TEST(TestFileRef, DeleteFileAndDirectory, filter); |
80 RUN_CALLBACK_TEST(TestFileRef, RenameFileAndDirectory, filter); | 117 RUN_CALLBACK_TEST(TestFileRef, RenameFileAndDirectory, filter); |
81 RUN_CALLBACK_TEST(TestFileRef, Query, filter); | 118 // FileRef::Query is out-of-process only. |
| 119 if (testing_interface_->IsOutOfProcess()) |
| 120 RUN_CALLBACK_TEST(TestFileRef, Query, filter); |
82 RUN_CALLBACK_TEST(TestFileRef, FileNameEscaping, filter); | 121 RUN_CALLBACK_TEST(TestFileRef, FileNameEscaping, filter); |
| 122 // FileRef::ReadDirectoryEntries is out-of-process only. |
| 123 if (testing_interface_->IsOutOfProcess()) |
| 124 RUN_CALLBACK_TEST(TestFileRef, ReadDirectoryEntries, filter); |
83 } | 125 } |
84 | 126 |
85 std::string TestFileRef::TestCreate() { | 127 std::string TestFileRef::TestCreate() { |
86 std::vector<std::string> invalid_paths; | 128 std::vector<std::string> invalid_paths; |
87 invalid_paths.push_back("invalid_path"); // no '/' at the first character | 129 invalid_paths.push_back("invalid_path"); // no '/' at the first character |
88 invalid_paths.push_back(std::string()); // empty path | 130 invalid_paths.push_back(std::string()); // empty path |
89 // The following are directory traversal checks | 131 // The following are directory traversal checks |
90 invalid_paths.push_back(".."); | 132 invalid_paths.push_back(".."); |
91 invalid_paths.push_back("/../invalid_path"); | 133 invalid_paths.push_back("/../invalid_path"); |
92 invalid_paths.push_back("/../../invalid_path"); | 134 invalid_paths.push_back("/../../invalid_path"); |
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 | 623 |
582 // Create the file with the terrible name. | 624 // Create the file with the terrible name. |
583 std::string full_file_path = test_dir_path + "/" + kTerribleName; | 625 std::string full_file_path = test_dir_path + "/" + kTerribleName; |
584 pp::FileRef file_ref(file_system, full_file_path.c_str()); | 626 pp::FileRef file_ref(file_system, full_file_path.c_str()); |
585 pp::FileIO file_io(instance_); | 627 pp::FileIO file_io(instance_); |
586 callback.WaitForResult( | 628 callback.WaitForResult( |
587 file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback.GetCallback())); | 629 file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback.GetCallback())); |
588 CHECK_CALLBACK_BEHAVIOR(callback); | 630 CHECK_CALLBACK_BEHAVIOR(callback); |
589 ASSERT_EQ(PP_OK, callback.result()); | 631 ASSERT_EQ(PP_OK, callback.result()); |
590 | 632 |
591 // DirectoryReader only works out-of-process. | 633 // FileRef::ReadDirectoryEntries only works out-of-process. |
592 if (testing_interface_->IsOutOfProcess()) { | 634 if (testing_interface_->IsOutOfProcess()) { |
593 TestCompletionCallbackWithOutput< std::vector<pp::DirectoryEntry_Dev> > | 635 TestCompletionCallbackWithOutput<DirEntries> |
594 output_callback(instance_->pp_instance(), callback_type()); | 636 output_callback(instance_->pp_instance(), callback_type()); |
595 pp::DirectoryReader_Dev directory_reader(test_dir_ref); | |
596 | 637 |
597 output_callback.WaitForResult( | 638 output_callback.WaitForResult( |
598 directory_reader.ReadEntries(output_callback.GetCallback())); | 639 test_dir_ref.ReadDirectoryEntries(output_callback.GetCallback())); |
599 CHECK_CALLBACK_BEHAVIOR(output_callback); | 640 CHECK_CALLBACK_BEHAVIOR(output_callback); |
600 ASSERT_EQ(PP_OK, output_callback.result()); | 641 ASSERT_EQ(PP_OK, output_callback.result()); |
601 | 642 |
602 std::vector<pp::DirectoryEntry_Dev> entries = output_callback.output(); | 643 DirEntries entries = output_callback.output(); |
603 ASSERT_EQ(1, entries.size()); | 644 ASSERT_EQ(1, entries.size()); |
604 ASSERT_EQ(kTerribleName, entries.front().file_ref().GetName().AsString()); | 645 ASSERT_EQ(kTerribleName, entries.front().file_ref().GetName().AsString()); |
605 } | 646 } |
606 | 647 |
607 PASS(); | 648 PASS(); |
608 } | 649 } |
| 650 |
| 651 std::string TestFileRef::TestReadDirectoryEntries() { |
| 652 TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
| 653 pp::FileSystem file_system( |
| 654 instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY); |
| 655 callback.WaitForResult(file_system.Open(1024, callback.GetCallback())); |
| 656 CHECK_CALLBACK_BEHAVIOR(callback); |
| 657 ASSERT_EQ(PP_OK, callback.result()); |
| 658 |
| 659 // Setup testing directories and files. |
| 660 const char* test_dir_name = "/test_get_next_file"; |
| 661 const char* file_prefix = "file_"; |
| 662 const char* dir_prefix = "dir_"; |
| 663 |
| 664 pp::FileRef test_dir(file_system, test_dir_name); |
| 665 int32_t rv = DeleteDirectoryRecursively(&test_dir); |
| 666 ASSERT_TRUE(rv == PP_OK || rv == PP_ERROR_FILENOTFOUND); |
| 667 |
| 668 callback.WaitForResult(test_dir.MakeDirectory(callback.GetCallback())); |
| 669 CHECK_CALLBACK_BEHAVIOR(callback); |
| 670 ASSERT_EQ(PP_OK, callback.result()); |
| 671 |
| 672 static const int kNumFiles = 3; |
| 673 std::set<std::string> expected_file_names; |
| 674 for (int i = 1; i <= kNumFiles; ++i) { |
| 675 std::ostringstream buffer; |
| 676 buffer << test_dir_name << '/' << file_prefix << i; |
| 677 pp::FileRef file_ref(file_system, buffer.str().c_str()); |
| 678 |
| 679 pp::FileIO file_io(instance_); |
| 680 callback.WaitForResult( |
| 681 file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback.GetCallback())); |
| 682 CHECK_CALLBACK_BEHAVIOR(callback); |
| 683 ASSERT_EQ(PP_OK, callback.result()); |
| 684 |
| 685 expected_file_names.insert(buffer.str()); |
| 686 } |
| 687 |
| 688 static const int kNumDirectories = 3; |
| 689 std::set<std::string> expected_dir_names; |
| 690 for (int i = 1; i <= kNumDirectories; ++i) { |
| 691 std::ostringstream buffer; |
| 692 buffer << test_dir_name << '/' << dir_prefix << i; |
| 693 pp::FileRef file_ref(file_system, buffer.str().c_str()); |
| 694 |
| 695 callback.WaitForResult(file_ref.MakeDirectory(callback.GetCallback())); |
| 696 CHECK_CALLBACK_BEHAVIOR(callback); |
| 697 ASSERT_EQ(PP_OK, callback.result()); |
| 698 |
| 699 expected_dir_names.insert(buffer.str()); |
| 700 } |
| 701 |
| 702 // Test that |ReadDirectoryEntries()| is able to fetch all |
| 703 // directories and files that we created. |
| 704 { |
| 705 TestCompletionCallbackWithOutput<DirEntries> output_callback( |
| 706 instance_->pp_instance(), callback_type()); |
| 707 |
| 708 output_callback.WaitForResult( |
| 709 test_dir.ReadDirectoryEntries(output_callback.GetCallback())); |
| 710 CHECK_CALLBACK_BEHAVIOR(output_callback); |
| 711 ASSERT_EQ(PP_OK, output_callback.result()); |
| 712 |
| 713 DirEntries entries = output_callback.output(); |
| 714 size_t sum = expected_file_names.size() + expected_dir_names.size(); |
| 715 ASSERT_EQ(sum, entries.size()); |
| 716 |
| 717 for (DirEntries::const_iterator it = entries.begin(); |
| 718 it != entries.end(); ++it) { |
| 719 pp::FileRef file_ref = it->file_ref(); |
| 720 std::string file_path = file_ref.GetPath().AsString(); |
| 721 std::set<std::string>::iterator found = |
| 722 expected_file_names.find(file_path); |
| 723 if (found != expected_file_names.end()) { |
| 724 if (it->file_type() != PP_FILETYPE_REGULAR) |
| 725 return file_path + " should have been a regular file."; |
| 726 expected_file_names.erase(found); |
| 727 } else { |
| 728 found = expected_dir_names.find(file_path); |
| 729 if (found == expected_dir_names.end()) |
| 730 return "Unexpected file path: " + file_path; |
| 731 if (it->file_type() != PP_FILETYPE_DIRECTORY) |
| 732 return file_path + " should have been a directory."; |
| 733 expected_dir_names.erase(found); |
| 734 } |
| 735 } |
| 736 ASSERT_TRUE(expected_file_names.empty()); |
| 737 ASSERT_TRUE(expected_dir_names.empty()); |
| 738 } |
| 739 |
| 740 // Test cancellation of asynchronous |ReadDirectoryEntries()|. |
| 741 TestCompletionCallbackWithOutput<DirEntries> output_callback( |
| 742 instance_->pp_instance(), callback_type()); |
| 743 { |
| 744 rv = pp::FileRef(file_system, test_dir_name) |
| 745 .ReadDirectoryEntries(output_callback.GetCallback()); |
| 746 } |
| 747 output_callback.WaitForAbortResult(rv); |
| 748 CHECK_CALLBACK_BEHAVIOR(output_callback); |
| 749 |
| 750 |
| 751 PASS(); |
| 752 } |
OLD | NEW |