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_io.h" | 5 #include "ppapi/tests/test_file_io.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 #include <string.h> | 8 #include <string.h> |
9 | 9 |
10 #include "ppapi/c/pp_errors.h" | 10 #include "ppapi/c/pp_errors.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 | 22 |
23 namespace { | 23 namespace { |
24 | 24 |
25 std::string ReportMismatch(const std::string& method_name, | 25 std::string ReportMismatch(const std::string& method_name, |
26 const std::string& returned_result, | 26 const std::string& returned_result, |
27 const std::string& expected_result) { | 27 const std::string& expected_result) { |
28 return method_name + " returned '" + returned_result + "'; '" + | 28 return method_name + " returned '" + returned_result + "'; '" + |
29 expected_result + "' expected."; | 29 expected_result + "' expected."; |
30 } | 30 } |
31 | 31 |
| 32 std::string ReportOpenError(int32_t open_flags) { |
| 33 static const char* kFlagNames[] = { |
| 34 "PP_FILEOPENFLAG_READ", |
| 35 "PP_FILEOPENFLAG_WRITE", |
| 36 "PP_FILEOPENFLAG_CREATE", |
| 37 "PP_FILEOPENFLAG_TRUNCATE", |
| 38 "PP_FILEOPENFLAG_EXCLUSIVE" |
| 39 }; |
| 40 |
| 41 std::string result = "FileIO:Open had unexpected behavior with flags: "; |
| 42 bool first_flag = true; |
| 43 for (int32_t mask = 1, index = 0; mask <= PP_FILEOPENFLAG_EXCLUSIVE; |
| 44 mask <<= 1, ++index) { |
| 45 if (mask & open_flags) { |
| 46 if (first_flag) { |
| 47 first_flag = false; |
| 48 } else { |
| 49 result += " | "; |
| 50 } |
| 51 result += kFlagNames[index]; |
| 52 } |
| 53 } |
| 54 if (first_flag) |
| 55 result += "[None]"; |
| 56 |
| 57 return result; |
| 58 } |
| 59 |
32 int32_t ReadEntireFile(PP_Instance instance, | 60 int32_t ReadEntireFile(PP_Instance instance, |
33 pp::FileIO_Dev* file_io, | 61 pp::FileIO_Dev* file_io, |
34 int32_t offset, | 62 int32_t offset, |
35 std::string* data) { | 63 std::string* data) { |
36 TestCompletionCallback callback(instance); | 64 TestCompletionCallback callback(instance); |
37 char buf[256]; | 65 char buf[256]; |
38 int32_t read_offset = offset; | 66 int32_t read_offset = offset; |
39 | 67 |
40 for (;;) { | 68 for (;;) { |
41 int32_t rv = file_io->Read(read_offset, buf, sizeof(buf), callback); | 69 int32_t rv = file_io->Read(read_offset, buf, sizeof(buf), callback); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 TestCompletionCallback callback(instance_->pp_instance()); | 124 TestCompletionCallback callback(instance_->pp_instance()); |
97 | 125 |
98 pp::FileSystem_Dev file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY); | 126 pp::FileSystem_Dev file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY); |
99 pp::FileRef_Dev file_ref(file_system, "/file_open"); | 127 pp::FileRef_Dev file_ref(file_system, "/file_open"); |
100 int32_t rv = file_system.Open(1024, callback); | 128 int32_t rv = file_system.Open(1024, callback); |
101 if (rv == PP_OK_COMPLETIONPENDING) | 129 if (rv == PP_OK_COMPLETIONPENDING) |
102 rv = callback.WaitForResult(); | 130 rv = callback.WaitForResult(); |
103 if (rv != PP_OK) | 131 if (rv != PP_OK) |
104 return ReportError("FileSystem::Open", rv); | 132 return ReportError("FileSystem::Open", rv); |
105 | 133 |
106 pp::FileIO_Dev file_io(instance_); | 134 std::string result; |
107 rv = file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback); | 135 result = MatchOpenExpectations( |
108 if (rv == PP_OK_COMPLETIONPENDING) | 136 &file_system, |
109 rv = callback.WaitForResult(); | 137 PP_FILEOPENFLAG_READ, |
110 if (rv != PP_OK) | 138 DONT_CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | DONT_TRUNCATE_IF_EXISTS); |
111 return ReportError("FileIO::Open", rv); | 139 if (!result.empty()) |
| 140 return result; |
112 | 141 |
113 // Try opening a file that doesn't exist. | 142 // Test the behavior of the power set of |
114 pp::FileRef_Dev nonexistent_file_ref(file_system, "/nonexistent_file"); | 143 // { PP_FILEOPENFLAG_CREATE, |
115 pp::FileIO_Dev nonexistent_file_io(instance_); | 144 // PP_FILEOPENFLAG_TRUNCATE, |
116 rv = nonexistent_file_io.Open( | 145 // PP_FILEOPENFLAG_EXCLUSIVE }. |
117 nonexistent_file_ref, PP_FILEOPENFLAG_READ, callback); | 146 |
118 if (rv == PP_OK_COMPLETIONPENDING) | 147 // First of all, none of them are specificed. |
119 rv = callback.WaitForResult(); | 148 result = MatchOpenExpectations( |
120 if (rv != PP_ERROR_FILENOTFOUND) | 149 &file_system, |
121 return ReportError("FileIO::Open", rv); | 150 PP_FILEOPENFLAG_WRITE, |
| 151 DONT_CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | DONT_TRUNCATE_IF_EXISTS); |
| 152 if (!result.empty()) |
| 153 return result; |
| 154 |
| 155 result = MatchOpenExpectations( |
| 156 &file_system, |
| 157 PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE, |
| 158 CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | DONT_TRUNCATE_IF_EXISTS); |
| 159 if (!result.empty()) |
| 160 return result; |
| 161 |
| 162 result = MatchOpenExpectations( |
| 163 &file_system, |
| 164 PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_EXCLUSIVE, |
| 165 DONT_CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | DONT_TRUNCATE_IF_EXISTS); |
| 166 if (!result.empty()) |
| 167 return result; |
| 168 |
| 169 result = MatchOpenExpectations( |
| 170 &file_system, |
| 171 PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_TRUNCATE, |
| 172 DONT_CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | TRUNCATE_IF_EXISTS); |
| 173 if (!result.empty()) |
| 174 return result; |
| 175 |
| 176 result = MatchOpenExpectations( |
| 177 &file_system, |
| 178 PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE | |
| 179 PP_FILEOPENFLAG_EXCLUSIVE, |
| 180 CREATE_IF_DOESNT_EXIST | DONT_OPEN_IF_EXISTS | DONT_TRUNCATE_IF_EXISTS); |
| 181 if (!result.empty()) |
| 182 return result; |
| 183 |
| 184 result = MatchOpenExpectations( |
| 185 &file_system, |
| 186 PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE | PP_FILEOPENFLAG_TRUNCATE, |
| 187 CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | TRUNCATE_IF_EXISTS); |
| 188 if (!result.empty()) |
| 189 return result; |
| 190 |
| 191 result = MatchOpenExpectations( |
| 192 &file_system, |
| 193 PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_EXCLUSIVE | |
| 194 PP_FILEOPENFLAG_TRUNCATE, |
| 195 DONT_CREATE_IF_DOESNT_EXIST | OPEN_IF_EXISTS | TRUNCATE_IF_EXISTS); |
| 196 if (!result.empty()) |
| 197 return result; |
| 198 |
| 199 result = MatchOpenExpectations( |
| 200 &file_system, |
| 201 PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE | |
| 202 PP_FILEOPENFLAG_EXCLUSIVE | PP_FILEOPENFLAG_TRUNCATE, |
| 203 CREATE_IF_DOESNT_EXIST | DONT_OPEN_IF_EXISTS | DONT_TRUNCATE_IF_EXISTS); |
| 204 if (!result.empty()) |
| 205 return result; |
| 206 |
| 207 // Invalid combination: PP_FILEOPENFLAG_TRUNCATE without |
| 208 // PP_FILEOPENFLAG_WRITE. |
| 209 result = MatchOpenExpectations( |
| 210 &file_system, |
| 211 PP_FILEOPENFLAG_READ | PP_FILEOPENFLAG_TRUNCATE, |
| 212 INVALID_FLAG_COMBINATION); |
| 213 if (!result.empty()) |
| 214 return result; |
122 | 215 |
123 PASS(); | 216 PASS(); |
124 } | 217 } |
125 | 218 |
126 std::string TestFileIO::TestReadWriteSetLength() { | 219 std::string TestFileIO::TestReadWriteSetLength() { |
127 TestCompletionCallback callback(instance_->pp_instance()); | 220 TestCompletionCallback callback(instance_->pp_instance()); |
128 | 221 |
129 pp::FileSystem_Dev file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY); | 222 pp::FileSystem_Dev file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY); |
130 pp::FileRef_Dev file_ref(file_system, "/file_read_write_setlength"); | 223 pp::FileRef_Dev file_ref(file_system, "/file_read_write_setlength"); |
131 int32_t rv = file_system.Open(1024, callback); | 224 int32_t rv = file_system.Open(1024, callback); |
132 if (rv == PP_OK_COMPLETIONPENDING) | 225 if (rv == PP_OK_COMPLETIONPENDING) |
133 rv = callback.WaitForResult(); | 226 rv = callback.WaitForResult(); |
134 if (rv != PP_OK) | 227 if (rv != PP_OK) |
135 return ReportError("FileSystem::Open", rv); | 228 return ReportError("FileSystem::Open", rv); |
136 | 229 |
137 pp::FileIO_Dev file_io(instance_); | 230 pp::FileIO_Dev file_io(instance_); |
138 rv = file_io.Open(file_ref, | 231 rv = file_io.Open(file_ref, |
139 PP_FILEOPENFLAG_CREATE | | 232 PP_FILEOPENFLAG_CREATE | |
| 233 PP_FILEOPENFLAG_TRUNCATE | |
140 PP_FILEOPENFLAG_READ | | 234 PP_FILEOPENFLAG_READ | |
141 PP_FILEOPENFLAG_WRITE, | 235 PP_FILEOPENFLAG_WRITE, |
142 callback); | 236 callback); |
143 if (rv == PP_OK_COMPLETIONPENDING) | 237 if (rv == PP_OK_COMPLETIONPENDING) |
144 rv = callback.WaitForResult(); | 238 rv = callback.WaitForResult(); |
145 if (rv != PP_OK) | 239 if (rv != PP_OK) |
146 return ReportError("FileIO::Open", rv); | 240 return ReportError("FileIO::Open", rv); |
147 | 241 |
148 // Write something to the file. | 242 // Write something to the file. |
149 rv = WriteEntireBuffer(instance_->pp_instance(), &file_io, 0, "test_test"); | 243 rv = WriteEntireBuffer(instance_->pp_instance(), &file_io, 0, "test_test"); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 pp::FileSystem_Dev file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY); | 337 pp::FileSystem_Dev file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY); |
244 int32_t rv = file_system.Open(1024, callback); | 338 int32_t rv = file_system.Open(1024, callback); |
245 if (rv == PP_OK_COMPLETIONPENDING) | 339 if (rv == PP_OK_COMPLETIONPENDING) |
246 rv = callback.WaitForResult(); | 340 rv = callback.WaitForResult(); |
247 if (rv != PP_OK) | 341 if (rv != PP_OK) |
248 return ReportError("FileSystem::Open", rv); | 342 return ReportError("FileSystem::Open", rv); |
249 | 343 |
250 pp::FileRef_Dev file_ref(file_system, "/file_touch"); | 344 pp::FileRef_Dev file_ref(file_system, "/file_touch"); |
251 pp::FileIO_Dev file_io(instance_); | 345 pp::FileIO_Dev file_io(instance_); |
252 rv = file_io.Open(file_ref, | 346 rv = file_io.Open(file_ref, |
253 PP_FILEOPENFLAG_CREATE | PP_FILEOPENFLAG_WRITE, | 347 PP_FILEOPENFLAG_CREATE | |
| 348 PP_FILEOPENFLAG_TRUNCATE | |
| 349 PP_FILEOPENFLAG_WRITE, |
254 callback); | 350 callback); |
255 if (rv == PP_OK_COMPLETIONPENDING) | 351 if (rv == PP_OK_COMPLETIONPENDING) |
256 rv = callback.WaitForResult(); | 352 rv = callback.WaitForResult(); |
257 if (rv != PP_OK) | 353 if (rv != PP_OK) |
258 return ReportError("FileIO::Open", rv); | 354 return ReportError("FileIO::Open", rv); |
259 | 355 |
260 // Write some data to have a non-zero file size. | 356 // Write some data to have a non-zero file size. |
261 rv = file_io.Write(0, "test", 4, callback); | 357 rv = file_io.Write(0, "test", 4, callback); |
262 if (rv == PP_OK_COMPLETIONPENDING) | 358 if (rv == PP_OK_COMPLETIONPENDING) |
263 rv = callback.WaitForResult(); | 359 rv = callback.WaitForResult(); |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 return ReportError("FileIO::Flush", rv); | 585 return ReportError("FileIO::Flush", rv); |
490 } | 586 } |
491 } | 587 } |
492 | 588 |
493 // TODO(viettrungluu): Also test that Close() aborts callbacks. | 589 // TODO(viettrungluu): Also test that Close() aborts callbacks. |
494 // crbug.com/69457 | 590 // crbug.com/69457 |
495 | 591 |
496 PASS(); | 592 PASS(); |
497 } | 593 } |
498 | 594 |
| 595 std::string TestFileIO::MatchOpenExpectations(pp::FileSystem_Dev* file_system, |
| 596 size_t open_flags, |
| 597 size_t expectations) { |
| 598 std::string bad_argument = |
| 599 "TestFileIO::MatchOpenExpectations has invalid input arguments."; |
| 600 bool invalid_combination = !!(expectations & INVALID_FLAG_COMBINATION); |
| 601 if (invalid_combination) { |
| 602 if (expectations != INVALID_FLAG_COMBINATION) |
| 603 return bad_argument; |
| 604 } else { |
| 605 // Validate that one and only one of <some_expectation> and |
| 606 // DONT_<some_expectation> is specified. |
| 607 for (size_t remains = expectations, end = END_OF_OPEN_EXPECATION_PAIRS; |
| 608 end != 0; remains >>= 2, end >>= 2) { |
| 609 if (!!(remains & 1) == !!(remains & 2)) |
| 610 return bad_argument; |
| 611 } |
| 612 } |
| 613 bool create_if_doesnt_exist = !!(expectations & CREATE_IF_DOESNT_EXIST); |
| 614 bool open_if_exists = !!(expectations & OPEN_IF_EXISTS); |
| 615 bool truncate_if_exists = !!(expectations & TRUNCATE_IF_EXISTS); |
| 616 |
| 617 TestCompletionCallback callback(instance_->pp_instance()); |
| 618 pp::FileRef_Dev existent_file_ref( |
| 619 *file_system, "/match_open_expectation_existent_non_empty_file"); |
| 620 pp::FileRef_Dev nonexistent_file_ref( |
| 621 *file_system, "/match_open_expectation_nonexistent_file"); |
| 622 |
| 623 // Setup files for test. |
| 624 { |
| 625 int32_t rv = existent_file_ref.Delete(callback); |
| 626 if (rv == PP_OK_COMPLETIONPENDING) |
| 627 rv = callback.WaitForResult(); |
| 628 if (rv != PP_OK && rv != PP_ERROR_FILENOTFOUND) |
| 629 return ReportError("FileRef::Delete", rv); |
| 630 |
| 631 rv = nonexistent_file_ref.Delete(callback); |
| 632 if (rv == PP_OK_COMPLETIONPENDING) |
| 633 rv = callback.WaitForResult(); |
| 634 if (rv != PP_OK && rv != PP_ERROR_FILENOTFOUND) |
| 635 return ReportError("FileRef::Delete", rv); |
| 636 |
| 637 pp::FileIO_Dev existent_file_io(instance_); |
| 638 rv = existent_file_io.Open(existent_file_ref, |
| 639 PP_FILEOPENFLAG_CREATE | PP_FILEOPENFLAG_WRITE, |
| 640 callback); |
| 641 if (rv == PP_OK_COMPLETIONPENDING) |
| 642 rv = callback.WaitForResult(); |
| 643 if (rv != PP_OK) |
| 644 return ReportError("FileIO::Open", rv); |
| 645 |
| 646 rv = WriteEntireBuffer(instance_->pp_instance(), &existent_file_io, 0, |
| 647 "foobar"); |
| 648 if (rv != PP_OK) |
| 649 return ReportError("FileIO::Write", rv); |
| 650 } |
| 651 |
| 652 pp::FileIO_Dev existent_file_io(instance_); |
| 653 int32_t rv = existent_file_io.Open(existent_file_ref, open_flags, callback); |
| 654 if (rv == PP_OK_COMPLETIONPENDING) |
| 655 rv = callback.WaitForResult(); |
| 656 if ((invalid_combination && rv == PP_OK) || |
| 657 (!invalid_combination && ((rv == PP_OK) != open_if_exists))) { |
| 658 return ReportOpenError(open_flags); |
| 659 } |
| 660 |
| 661 if (!invalid_combination && open_if_exists) { |
| 662 PP_FileInfo_Dev info; |
| 663 rv = existent_file_io.Query(&info, callback); |
| 664 if (rv == PP_OK_COMPLETIONPENDING) |
| 665 rv = callback.WaitForResult(); |
| 666 if (rv != PP_OK) |
| 667 return ReportError("FileIO::Query", rv); |
| 668 |
| 669 if (truncate_if_exists != (info.size == 0)) |
| 670 return ReportOpenError(open_flags); |
| 671 } |
| 672 |
| 673 pp::FileIO_Dev nonexistent_file_io(instance_); |
| 674 rv = nonexistent_file_io.Open(nonexistent_file_ref, open_flags, callback); |
| 675 if (rv == PP_OK_COMPLETIONPENDING) |
| 676 rv = callback.WaitForResult(); |
| 677 if ((invalid_combination && rv == PP_OK) || |
| 678 (!invalid_combination && ((rv == PP_OK) != create_if_doesnt_exist))) { |
| 679 return ReportOpenError(open_flags); |
| 680 } |
| 681 |
| 682 return std::string(); |
| 683 } |
| 684 |
499 // TODO(viettrungluu): Test Close(). crbug.com/69457 | 685 // TODO(viettrungluu): Test Close(). crbug.com/69457 |
OLD | NEW |