OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 The Native Client 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 <string.h> |
| 6 |
| 7 #include "native_client/src/shared/platform/nacl_check.h" |
| 8 #include "native_client/src/third_party/ppapi/c/pp_errors.h" |
| 9 #include "native_client/src/third_party/ppapi/c/ppb_file_io.h" |
| 10 #include "native_client/tests/ppapi_test_lib/get_browser_interface.h" |
| 11 #include "native_client/tests/ppapi_test_lib/test_interface.h" |
| 12 #include "native_client/tests/ppapi_browser/ppb_file_io/common.h" |
| 13 |
| 14 namespace { |
| 15 |
| 16 using common::FileIOTester; |
| 17 using common::InitFileInfo; |
| 18 using common::kTestData; |
| 19 using common::OpenFileForTest; |
| 20 using common::TestCallbackData; |
| 21 using common::TestSequenceElement; |
| 22 |
| 23 struct TestReadData { |
| 24 TestReadData(PP_Resource file_io, int64_t offset_bytes, int32_t bytes_to_read) |
| 25 : file_io(file_io), buffer(new char[bytes_to_read]), |
| 26 offset(offset_bytes), bytes_to_read(bytes_to_read), bytes_read(0) { } |
| 27 ~TestReadData() { |
| 28 delete[] buffer; |
| 29 } |
| 30 |
| 31 const PP_Resource file_io; |
| 32 char* const buffer; |
| 33 const int64_t offset; |
| 34 const int32_t bytes_to_read; |
| 35 int32_t bytes_read; |
| 36 }; |
| 37 |
| 38 // Completion callback function called from the read operation. If the read |
| 39 // operation is not completed, a successive read operation will be invoked. |
| 40 void ReadCallback(void* data, int32_t bytes_read) { |
| 41 EXPECT(bytes_read >= 0); |
| 42 |
| 43 TestReadData* read_data = reinterpret_cast<TestReadData*>(data); |
| 44 read_data->bytes_read += bytes_read; |
| 45 |
| 46 if (read_data->bytes_read == read_data->bytes_to_read || |
| 47 bytes_read == 0) { // no more bytes to available to read |
| 48 // Verify the data |
| 49 EXPECT(strncmp(kTestData + read_data->offset, read_data->buffer, |
| 50 read_data->bytes_read) == 0); |
| 51 PostTestMessage(__FUNCTION__, "VERIFIED"); // Test for this in browser. |
| 52 delete read_data; |
| 53 } else { |
| 54 int64_t offset = read_data->offset + read_data->bytes_read; |
| 55 char* buffer = read_data->buffer + read_data->bytes_read; |
| 56 int32_t bytes_to_read = |
| 57 read_data->bytes_to_read - read_data->bytes_read; |
| 58 PPBFileIO()->Read(read_data->file_io, offset, buffer, bytes_to_read, |
| 59 PP_MakeCompletionCallback(ReadCallback, read_data)); |
| 60 } |
| 61 } |
| 62 |
| 63 // TestParallelRead performs two read operations, one from the beginning of the |
| 64 // file, and one from the offset. Both operations are of the same size. |
| 65 class TestParallelRead : public TestSequenceElement { |
| 66 public: |
| 67 TestParallelRead(int64_t offset, int32_t bytes_to_read) |
| 68 : TestSequenceElement("TestParallelRead", PP_OK_COMPLETIONPENDING, PP_OK), |
| 69 offset_(offset), bytes_to_read_(bytes_to_read) {} |
| 70 |
| 71 private: |
| 72 virtual void Setup(TestCallbackData* callback_data) { |
| 73 TestReadData* read_data = new TestReadData(callback_data->existing_file_io, |
| 74 0, // read from beginning |
| 75 bytes_to_read_); |
| 76 int32_t pp_error = PPBFileIO()->Read(read_data->file_io, read_data->offset, |
| 77 read_data->buffer, |
| 78 read_data->bytes_to_read, |
| 79 PP_MakeCompletionCallback(ReadCallback, |
| 80 read_data)); |
| 81 EXPECT(pp_error == PP_OK_COMPLETIONPENDING); |
| 82 |
| 83 read_data = new TestReadData(callback_data->existing_file_io, offset_, |
| 84 bytes_to_read_); |
| 85 pp_error = PPBFileIO()->Read(read_data->file_io, read_data->offset, |
| 86 read_data->buffer, |
| 87 read_data->bytes_to_read, |
| 88 PP_MakeCompletionCallback(ReadCallback, |
| 89 read_data)); |
| 90 EXPECT(pp_error == PP_OK_COMPLETIONPENDING); |
| 91 } |
| 92 |
| 93 const int32_t offset_; |
| 94 const int32_t bytes_to_read_; |
| 95 }; |
| 96 |
| 97 class TestFileRead : public TestSequenceElement { |
| 98 public: |
| 99 TestFileRead(int64_t offset, int32_t bytes_to_read) |
| 100 : TestSequenceElement("TestFileRead", PP_OK_COMPLETIONPENDING, PP_OK), |
| 101 offset_(offset), bytes_to_read_(bytes_to_read) {} |
| 102 |
| 103 private: |
| 104 void Setup(TestCallbackData* callback_data) { |
| 105 TestReadData* read_data = new TestReadData(callback_data->existing_file_io, |
| 106 offset_, bytes_to_read_); |
| 107 int32_t pp_error = PPBFileIO()->Read(read_data->file_io, read_data->offset, |
| 108 read_data->buffer, |
| 109 read_data->bytes_to_read, |
| 110 PP_MakeCompletionCallback(ReadCallback, |
| 111 read_data)); |
| 112 EXPECT(pp_error == PP_OK_COMPLETIONPENDING); |
| 113 } |
| 114 |
| 115 const int64_t offset_; |
| 116 const int32_t bytes_to_read_; |
| 117 }; |
| 118 |
| 119 // Test the partial read of a file |
| 120 void TestPartialFileRead(PP_FileSystemType system_type) { |
| 121 PP_FileInfo file_info = { 0 }; |
| 122 InitFileInfo(system_type, &file_info); |
| 123 |
| 124 const int64_t offset = 1; // some non-zero offset |
| 125 const int32_t bytes_to_read = strlen(kTestData) / 2; |
| 126 |
| 127 FileIOTester tester(file_info); |
| 128 tester.AddSequenceElement(new OpenFileForTest); |
| 129 tester.AddSequenceElement(new TestFileRead(offset, bytes_to_read)); |
| 130 tester.Run(); |
| 131 } |
| 132 |
| 133 // Test complete read of a file in one operation. |
| 134 void TestCompleteReadFile(PP_FileSystemType system_type) { |
| 135 PP_FileInfo file_info = { 0 }; |
| 136 InitFileInfo(system_type, &file_info); |
| 137 |
| 138 FileIOTester tester(file_info); |
| 139 tester.AddSequenceElement(new OpenFileForTest); |
| 140 tester.AddSequenceElement(new TestFileRead(0, // start at beginning |
| 141 strlen(kTestData))); |
| 142 tester.Run(); |
| 143 } |
| 144 |
| 145 void TestParallelReadFile(PP_FileSystemType system_type) { |
| 146 PP_FileInfo file_info = { 0 }; |
| 147 InitFileInfo(system_type, &file_info); |
| 148 |
| 149 const int64_t offset = strlen(kTestData) / 2; |
| 150 const int32_t bytes_to_read = strlen(kTestData) / 3; |
| 151 |
| 152 FileIOTester tester(file_info); |
| 153 tester.AddSequenceElement(new OpenFileForTest); |
| 154 tester.AddSequenceElement(new TestParallelRead(offset, bytes_to_read)); |
| 155 tester.Run(); |
| 156 } |
| 157 |
| 158 } // namespace |
| 159 |
| 160 void TestPartialFileReadLocalPersistent() { |
| 161 TestPartialFileRead(PP_FILESYSTEMTYPE_LOCALPERSISTENT); |
| 162 TEST_PASSED; |
| 163 } |
| 164 |
| 165 void TestPartialFileReadLocalTemporary() { |
| 166 TestPartialFileRead(PP_FILESYSTEMTYPE_LOCALTEMPORARY); |
| 167 TEST_PASSED; |
| 168 } |
| 169 |
| 170 void TestCompleteReadLocalPersistent() { |
| 171 TestCompleteReadFile(PP_FILESYSTEMTYPE_LOCALPERSISTENT); |
| 172 TEST_PASSED; |
| 173 } |
| 174 |
| 175 void TestCompleteReadLocalTemporary() { |
| 176 TestCompleteReadFile(PP_FILESYSTEMTYPE_LOCALTEMPORARY); |
| 177 TEST_PASSED; |
| 178 } |
| 179 |
| 180 // Test multiple reads of a file using multiple callbacks and different offsets. |
| 181 void TestParallelReadLocalPersistent() { |
| 182 TestParallelReadFile(PP_FILESYSTEMTYPE_LOCALPERSISTENT); |
| 183 TEST_PASSED; |
| 184 } |
| 185 |
| 186 void TestParallelReadLocalTemporary() { |
| 187 TestParallelReadFile(PP_FILESYSTEMTYPE_LOCALTEMPORARY); |
| 188 TEST_PASSED; |
| 189 } |
OLD | NEW |