| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 <stdint.h> | 5 #include <stdint.h> |
| 6 #include <string.h> |
| 7 |
| 8 #include <utility> |
| 6 #include <vector> | 9 #include <vector> |
| 7 | 10 |
| 8 #include "mojo/file_utils/file_util.h" | 11 #include "mojo/file_utils/file_util.h" |
| 9 #include "mojo/public/cpp/application/application_impl.h" | 12 #include "mojo/public/cpp/application/application_impl.h" |
| 10 #include "mojo/public/cpp/application/application_test_base.h" | 13 #include "mojo/public/cpp/application/application_test_base.h" |
| 14 #include "mojo/public/cpp/application/connect.h" |
| 15 #include "mojo/public/cpp/bindings/synchronous_interface_ptr.h" |
| 11 #include "mojo/public/cpp/utility/run_loop.h" | 16 #include "mojo/public/cpp/utility/run_loop.h" |
| 12 #include "mojo/services/files/interfaces/directory.mojom.h" | 17 #include "mojo/services/files/interfaces/directory.mojom-sync.h" |
| 13 #include "mojo/services/files/interfaces/file.mojom.h" | 18 #include "mojo/services/files/interfaces/file.mojom-sync.h" |
| 14 #include "mojo/services/files/interfaces/files.mojom.h" | 19 #include "mojo/services/files/interfaces/files.mojom-sync.h" |
| 15 | 20 |
| 16 namespace file_utils { | 21 namespace file_utils { |
| 17 namespace test { | 22 namespace test { |
| 18 namespace { | 23 namespace { |
| 19 | 24 |
| 20 using FileUtilTest = mojo::test::ApplicationTestBase; | 25 using FileUtilTest = mojo::test::ApplicationTestBase; |
| 21 | 26 |
| 22 // TODO(smklein): Stuff copied from mojo/services/files/c/lib/template_util.h | 27 // Writes |input| to |file| and that the requisite number of bytes was written. |
| 23 typedef char YesType; | 28 void WriteFileHelper(mojo::SynchronousInterfacePtr<mojo::files::File>* file, |
| 24 | 29 const std::string& input) { |
| 25 struct NoType { | 30 auto bytes_to_write = mojo::Array<uint8_t>::New(input.size()); |
| 26 YesType dummy[2]; | 31 memcpy(bytes_to_write.data(), input.data(), input.size()); |
| 27 }; | 32 mojo::files::Error error = mojo::files::Error::INTERNAL; |
| 28 | 33 uint32_t num_bytes_written = 0; |
| 29 template <typename T> | 34 ASSERT_TRUE((*file)->Write(std::move(bytes_to_write), 0, |
| 30 struct IsMoveOnlyType { | 35 mojo::files::Whence::FROM_CURRENT, &error, |
| 31 template <typename U> | 36 &num_bytes_written)); |
| 32 static YesType Test(const typename U::MoveOnlyTypeForCPP03*); | 37 EXPECT_EQ(mojo::files::Error::OK, error); |
| 33 | 38 EXPECT_EQ(input.size(), num_bytes_written); |
| 34 template <typename U> | |
| 35 static NoType Test(...); | |
| 36 | |
| 37 static const bool value = | |
| 38 sizeof(Test<T>(0)) == sizeof(YesType) && !std::is_const<T>::value; | |
| 39 }; | |
| 40 | |
| 41 template <typename T> | |
| 42 typename std::enable_if<!IsMoveOnlyType<T>::value, T>::type& Forward(T& t) { | |
| 43 return t; | |
| 44 } | 39 } |
| 45 | 40 |
| 46 template <typename T> | 41 // Seeks to |offset| in |file| (from the current position), verifying that the |
| 47 typename std::enable_if<IsMoveOnlyType<T>::value, T>::type Forward(T& t) { | 42 // resulting position is |expected_position|. |
| 48 return t.Pass(); | 43 void SeekFileHelper(mojo::SynchronousInterfacePtr<mojo::files::File>* file, |
| 49 } | |
| 50 | |
| 51 template <typename T1> | |
| 52 mojo::Callback<void(T1)> Capture(T1* t1) { | |
| 53 return [t1](T1 got_t1) { *t1 = Forward(got_t1); }; | |
| 54 } | |
| 55 | |
| 56 template <typename T1, typename T2> | |
| 57 mojo::Callback<void(T1, T2)> Capture(T1* t1, T2* t2) { | |
| 58 return [t1, t2](T1 got_t1, T2 got_t2) { | |
| 59 *t1 = Forward(got_t1); | |
| 60 *t2 = Forward(got_t2); | |
| 61 }; | |
| 62 } | |
| 63 // TODO(smklein): (End of stuff copied from template_util.h) | |
| 64 | |
| 65 // Given a FilePtr |file|, write the string |input| and verify | |
| 66 // the output matches the |input|'s size. | |
| 67 void WriteFileHelper(mojo::files::FilePtr* file, const std::string& input) { | |
| 68 std::vector<uint8_t> bytes_to_write; | |
| 69 for (size_t i = 0; i < input.size(); i++) | |
| 70 bytes_to_write.push_back(static_cast<uint8_t>(input[i])); | |
| 71 mojo::files::Error error = mojo::files::Error::INTERNAL; | |
| 72 uint32_t num_bytes_written = 0; | |
| 73 (*file)->Write(mojo::Array<uint8_t>::From(bytes_to_write), 0, | |
| 74 mojo::files::Whence::FROM_CURRENT, | |
| 75 Capture(&error, &num_bytes_written)); | |
| 76 ASSERT_TRUE(file->WaitForIncomingResponse()); | |
| 77 EXPECT_EQ(mojo::files::Error::OK, error); | |
| 78 EXPECT_EQ(bytes_to_write.size(), num_bytes_written); | |
| 79 } | |
| 80 | |
| 81 // Given a FilePtr |file|, seek to offset |offset| using whence | |
| 82 // FROM_CURRENT. Verifies the post-seek position is |expected_position|. | |
| 83 void SeekFileHelper(mojo::files::FilePtr* file, | |
| 84 int64_t offset, | 44 int64_t offset, |
| 85 int64_t expected_position) { | 45 int64_t expected_position) { |
| 86 int64_t position = -1; | 46 int64_t position = -1; |
| 87 mojo::files::Error error = mojo::files::Error::INTERNAL; | 47 mojo::files::Error error = mojo::files::Error::INTERNAL; |
| 88 (*file)->Seek(offset, mojo::files::Whence::FROM_CURRENT, | 48 ASSERT_TRUE((*file)->Seek(offset, mojo::files::Whence::FROM_CURRENT, &error, |
| 89 Capture(&error, &position)); | 49 &position)); |
| 90 ASSERT_TRUE(file->WaitForIncomingResponse()); | |
| 91 EXPECT_EQ(mojo::files::Error::OK, error); | 50 EXPECT_EQ(mojo::files::Error::OK, error); |
| 92 EXPECT_EQ(expected_position, position); | 51 EXPECT_EQ(expected_position, position); |
| 93 } | 52 } |
| 94 | 53 |
| 95 // Given a FilePtr |file|, read from the file at offset |offset| (using | 54 // Reads |expected_output.size()| bytes from |file| at offset |offset| (using |
| 96 // Whence::FROM_CURRENT), and verify the result matches the string | 55 // Whence::FROM_CURRENT), and verify that the result matches |expected_output|. |
| 97 // |expected_output|. | 56 void ReadFileHelper(mojo::SynchronousInterfacePtr<mojo::files::File>* file, |
| 98 void ReadFileHelper(mojo::files::FilePtr* file, | |
| 99 int64_t offset, | 57 int64_t offset, |
| 100 const std::string& expected_output) { | 58 const std::string& expected_output) { |
| 101 mojo::Array<uint8_t> bytes_read; | 59 mojo::Array<uint8_t> bytes_read; |
| 102 mojo::files::Error error = mojo::files::Error::INTERNAL; | 60 mojo::files::Error error = mojo::files::Error::INTERNAL; |
| 103 uint32_t num_bytes_to_read = expected_output.size(); | 61 uint32_t num_bytes_to_read = expected_output.size(); |
| 104 (*file)->Read(num_bytes_to_read, offset, mojo::files::Whence::FROM_CURRENT, | 62 ASSERT_TRUE((*file)->Read(num_bytes_to_read, offset, |
| 105 Capture(&error, &bytes_read)); | 63 mojo::files::Whence::FROM_CURRENT, &error, |
| 106 ASSERT_TRUE(file->WaitForIncomingResponse()); | 64 &bytes_read)); |
| 107 EXPECT_EQ(mojo::files::Error::OK, error); | 65 EXPECT_EQ(mojo::files::Error::OK, error); |
| 108 EXPECT_EQ(num_bytes_to_read, bytes_read.size()); | 66 ASSERT_EQ(num_bytes_to_read, bytes_read.size()); |
| 109 for (size_t i = 0; i < expected_output.size(); i++) | 67 EXPECT_EQ( |
| 110 EXPECT_EQ(static_cast<uint8_t>(expected_output[i]), bytes_read[i]); | 68 0, memcmp(bytes_read.data(), expected_output.data(), num_bytes_to_read)); |
| 111 } | 69 } |
| 112 | 70 |
| 113 // Open the file named |path_name| in |directory| and verify that no error | 71 // Closes |file| and verifies that no error occurs. |
| 114 // occurs. Returns the newly opened file. | 72 void CloseFileHelper(mojo::SynchronousInterfacePtr<mojo::files::File>* file) { |
| 115 mojo::files::FilePtr OpenFileHelper(mojo::files::DirectoryPtr* directory, | |
| 116 const std::string& path_name) { | |
| 117 mojo::files::FilePtr temp_file; | |
| 118 mojo::files::Error error = mojo::files::Error::INTERNAL; | 73 mojo::files::Error error = mojo::files::Error::INTERNAL; |
| 119 (*directory) | 74 ASSERT_TRUE((*file)->Close(&error)); |
| 120 ->OpenFile(path_name, GetProxy(&temp_file), | 75 EXPECT_EQ(mojo::files::Error::OK, error); |
| 121 mojo::files::kOpenFlagWrite | mojo::files::kOpenFlagRead, | 76 } |
| 122 Capture(&error)); | 77 |
| 123 EXPECT_EQ(true, directory->WaitForIncomingResponse()); | 78 // Opens the file named |path_name| in |directory| and verifies that no error |
| 79 // occurs. Returns the newly-opened file. |
| 80 mojo::SynchronousInterfacePtr<mojo::files::File> OpenFileHelper( |
| 81 mojo::SynchronousInterfacePtr<mojo::files::Directory>* directory, |
| 82 const std::string& path_name) { |
| 83 mojo::SynchronousInterfacePtr<mojo::files::File> temp_file; |
| 84 mojo::files::Error error = mojo::files::Error::INTERNAL; |
| 85 EXPECT_TRUE( |
| 86 (*directory) |
| 87 ->OpenFile(path_name, GetSynchronousProxy(&temp_file), |
| 88 mojo::files::kOpenFlagWrite | mojo::files::kOpenFlagRead, |
| 89 &error)); |
| 124 EXPECT_EQ(mojo::files::Error::OK, error); | 90 EXPECT_EQ(mojo::files::Error::OK, error); |
| 125 return temp_file; | 91 return temp_file; |
| 126 } | 92 } |
| 127 | 93 |
| 128 // Close the FilePtr |file| and verify that no error occurs. | |
| 129 void CloseFileHelper(mojo::files::FilePtr* file) { | |
| 130 mojo::files::Error error = mojo::files::Error::INTERNAL; | |
| 131 (*file)->Close(Capture(&error)); | |
| 132 ASSERT_TRUE(file->WaitForIncomingResponse()); | |
| 133 EXPECT_EQ(mojo::files::Error::OK, error); | |
| 134 } | |
| 135 | |
| 136 TEST_F(FileUtilTest, BasicCreateTemporaryFile) { | 94 TEST_F(FileUtilTest, BasicCreateTemporaryFile) { |
| 137 mojo::files::FilesPtr files; | 95 mojo::SynchronousInterfacePtr<mojo::files::Files> files; |
| 138 application_impl()->ConnectToServiceDeprecated("mojo:files", &files); | 96 mojo::ConnectToService(application_impl()->shell(), "mojo:files", |
| 97 GetSynchronousProxy(&files)); |
| 139 | 98 |
| 140 mojo::files::Error error = mojo::files::Error::INTERNAL; | 99 mojo::files::Error error = mojo::files::Error::INTERNAL; |
| 141 mojo::files::DirectoryPtr directory; | 100 mojo::SynchronousInterfacePtr<mojo::files::Directory> directory; |
| 142 files->OpenFileSystem(nullptr, mojo::GetProxy(&directory), Capture(&error)); | 101 ASSERT_TRUE(files->OpenFileSystem( |
| 143 | 102 nullptr, mojo::GetSynchronousProxy(&directory), &error)); |
| 144 ASSERT_TRUE(files.WaitForIncomingResponse()); | |
| 145 EXPECT_EQ(mojo::files::Error::OK, error); | 103 EXPECT_EQ(mojo::files::Error::OK, error); |
| 146 | 104 |
| 147 std::string filename1, filename2, filename3; | 105 std::string filename1; |
| 148 mojo::files::FilePtr file1, file2, file3; | 106 auto file1 = mojo::SynchronousInterfacePtr<mojo::files::File>::Create( |
| 149 file1 = CreateTemporaryFileInDir(&directory, &filename1); | 107 CreateTemporaryFileInDir(&directory, &filename1)); |
| 150 ASSERT_TRUE(file1); | 108 ASSERT_TRUE(file1); |
| 151 file2 = CreateTemporaryFileInDir(&directory, &filename2); | 109 std::string filename2; |
| 110 auto file2 = mojo::SynchronousInterfacePtr<mojo::files::File>::Create( |
| 111 CreateTemporaryFileInDir(&directory, &filename2)); |
| 152 ASSERT_TRUE(file2); | 112 ASSERT_TRUE(file2); |
| 153 file3 = CreateTemporaryFileInDir(&directory, &filename3); | 113 std::string filename3; |
| 114 auto file3 = mojo::SynchronousInterfacePtr<mojo::files::File>::Create( |
| 115 CreateTemporaryFileInDir(&directory, &filename3)); |
| 154 ASSERT_TRUE(file3); | 116 ASSERT_TRUE(file3); |
| 155 | 117 |
| 156 // The temp filenames should not be equal. | 118 // The temp filenames should not be equal. |
| 157 EXPECT_NE(filename1, filename2); | 119 EXPECT_NE(filename1, filename2); |
| 158 EXPECT_NE(filename1, filename3); | 120 EXPECT_NE(filename1, filename3); |
| 159 EXPECT_NE(filename2, filename3); | 121 EXPECT_NE(filename2, filename3); |
| 160 | 122 |
| 161 // Test that 'Write' can be called on the temp files. | 123 // Test that 'Write' can be called on the temp files. |
| 162 WriteFileHelper(&file1, "abcde"); | 124 WriteFileHelper(&file1, "abcde"); |
| 163 WriteFileHelper(&file2, "fghij"); | 125 WriteFileHelper(&file2, "fghij"); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 190 | 152 |
| 191 // Test that the files can be closed once more. | 153 // Test that the files can be closed once more. |
| 192 CloseFileHelper(&file1); | 154 CloseFileHelper(&file1); |
| 193 CloseFileHelper(&file2); | 155 CloseFileHelper(&file2); |
| 194 CloseFileHelper(&file3); | 156 CloseFileHelper(&file3); |
| 195 } | 157 } |
| 196 | 158 |
| 197 } // namespace | 159 } // namespace |
| 198 } // namespace test | 160 } // namespace test |
| 199 } // namespace file_utils | 161 } // namespace file_utils |
| OLD | NEW |