1 // Copyright (c) 2012 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_io.h"
11 #include <sys/types.h>
15 #include "ppapi/c/dev/ppb_testing_dev.h"
16 #include "ppapi/c/pp_errors.h"
17 #include "ppapi/c/ppb_file_io.h"
18 #include "ppapi/c/private/pp_file_handle.h"
19 #include "ppapi/c/trusted/ppb_file_io_trusted.h"
20 #include "ppapi/cpp/file_io.h"
21 #include "ppapi/cpp/file_ref.h"
22 #include "ppapi/cpp/file_system.h"
23 #include "ppapi/cpp/instance.h"
24 #include "ppapi/cpp/module.h"
25 #include "ppapi/cpp/private/file_io_private.h"
26 #include "ppapi/tests/test_utils.h"
27 #include "ppapi/tests/testing_instance.h"
29 #if defined(PPAPI_OS_WIN)
32 // TODO(hamaji): Use standard windows APIs instead of compatibility layer?
38 # include <sys/mman.h>
42 REGISTER_TEST_CASE(FileIO
);
46 std::string
ReportMismatch(const std::string
& method_name
,
47 const std::string
& returned_result
,
48 const std::string
& expected_result
) {
49 return method_name
+ " returned '" + returned_result
+ "'; '" +
50 expected_result
+ "' expected.";
53 std::string
ReportOpenError(int32_t open_flags
) {
54 static const char* kFlagNames
[] = {
55 "PP_FILEOPENFLAG_READ",
56 "PP_FILEOPENFLAG_WRITE",
57 "PP_FILEOPENFLAG_CREATE",
58 "PP_FILEOPENFLAG_TRUNCATE",
59 "PP_FILEOPENFLAG_EXCLUSIVE"
62 std::string result
= "FileIO:Open had unexpected behavior with flags: ";
63 bool first_flag
= true;
64 for (int32_t mask
= 1, index
= 0; mask
<= PP_FILEOPENFLAG_EXCLUSIVE
;
65 mask
<<= 1, ++index
) {
66 if (mask
& open_flags
) {
72 result
+= kFlagNames
[index
];
81 int32_t ReadEntireFile(PP_Instance instance
,
85 CallbackType callback_type
) {
86 TestCompletionCallback
callback(instance
, callback_type
);
88 int32_t read_offset
= offset
;
91 callback
.WaitForResult(
92 file_io
->Read(read_offset
, buf
, sizeof(buf
), callback
.GetCallback()));
93 if (callback
.result() < 0)
94 return callback
.result();
95 if (callback
.result() == 0)
97 read_offset
+= callback
.result();
98 data
->append(buf
, callback
.result());
104 int32_t ReadToArrayEntireFile(PP_Instance instance
,
108 CallbackType callback_type
) {
109 TestCompletionCallbackWithOutput
< std::vector
<char> > callback(
110 instance
, callback_type
);
113 callback
.WaitForResult(file_io
->Read(offset
, 256, callback
.GetCallback()));
114 int32_t rv
= callback
.result();
119 const std::vector
<char>& output
= callback
.output();
120 assert(rv
== static_cast<int32_t>(output
.size()));
122 data
->append(output
.begin(), output
.end());
128 int32_t WriteEntireBuffer(PP_Instance instance
,
131 const std::string
& data
,
132 CallbackType callback_type
) {
133 TestCompletionCallback
callback(instance
, callback_type
);
134 int32_t write_offset
= offset
;
135 const char* buf
= data
.c_str();
136 int32_t size
= data
.size();
138 while (write_offset
< offset
+ size
) {
139 callback
.WaitForResult(file_io
->Write(write_offset
,
140 &buf
[write_offset
- offset
],
141 size
- write_offset
+ offset
,
142 callback
.GetCallback()));
143 if (callback
.result() < 0)
144 return callback
.result();
145 if (callback
.result() == 0)
146 return PP_ERROR_FAILED
;
147 write_offset
+= callback
.result();
155 bool TestFileIO::Init() {
156 return CheckTestingInterface() && EnsureRunningOverHTTP();
159 void TestFileIO::RunTests(const std::string
& filter
) {
160 RUN_CALLBACK_TEST(TestFileIO
, Open
, filter
);
161 RUN_CALLBACK_TEST(TestFileIO
, OpenDirectory
, filter
);
162 RUN_CALLBACK_TEST(TestFileIO
, ReadWriteSetLength
, filter
);
163 RUN_CALLBACK_TEST(TestFileIO
, ReadToArrayWriteSetLength
, filter
);
164 RUN_CALLBACK_TEST(TestFileIO
, TouchQuery
, filter
);
165 RUN_CALLBACK_TEST(TestFileIO
, AbortCalls
, filter
);
166 RUN_CALLBACK_TEST(TestFileIO
, ParallelReads
, filter
);
167 RUN_CALLBACK_TEST(TestFileIO
, ParallelWrites
, filter
);
168 RUN_CALLBACK_TEST(TestFileIO
, NotAllowMixedReadWrite
, filter
);
169 RUN_CALLBACK_TEST(TestFileIO
, WillWriteWillSetLength
, filter
);
170 RUN_CALLBACK_TEST(TestFileIO
, RequestOSFileHandle
, filter
);
172 // TODO(viettrungluu): add tests:
173 // - that PP_ERROR_PENDING is correctly returned
174 // - that operations respect the file open modes (flags)
177 std::string
TestFileIO::TestOpen() {
178 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
180 pp::FileSystem
file_system(instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
181 pp::FileRef
file_ref(file_system
, "/file_open");
183 callback
.WaitForResult(file_system
.Open(1024, callback
.GetCallback()));
184 CHECK_CALLBACK_BEHAVIOR(callback
);
185 ASSERT_EQ(PP_OK
, callback
.result());
188 result
= MatchOpenExpectations(
190 PP_FILEOPENFLAG_READ
,
191 DONT_CREATE_IF_DOESNT_EXIST
| OPEN_IF_EXISTS
| DONT_TRUNCATE_IF_EXISTS
);
195 // Test the behavior of the power set of
196 // { PP_FILEOPENFLAG_CREATE,
197 // PP_FILEOPENFLAG_TRUNCATE,
198 // PP_FILEOPENFLAG_EXCLUSIVE }.
200 // First of all, none of them are specified.
201 result
= MatchOpenExpectations(
203 PP_FILEOPENFLAG_WRITE
,
204 DONT_CREATE_IF_DOESNT_EXIST
| OPEN_IF_EXISTS
| DONT_TRUNCATE_IF_EXISTS
);
208 result
= MatchOpenExpectations(
210 PP_FILEOPENFLAG_WRITE
| PP_FILEOPENFLAG_CREATE
,
211 CREATE_IF_DOESNT_EXIST
| OPEN_IF_EXISTS
| DONT_TRUNCATE_IF_EXISTS
);
215 result
= MatchOpenExpectations(
217 PP_FILEOPENFLAG_WRITE
| PP_FILEOPENFLAG_EXCLUSIVE
,
218 DONT_CREATE_IF_DOESNT_EXIST
| OPEN_IF_EXISTS
| DONT_TRUNCATE_IF_EXISTS
);
222 result
= MatchOpenExpectations(
224 PP_FILEOPENFLAG_WRITE
| PP_FILEOPENFLAG_TRUNCATE
,
225 DONT_CREATE_IF_DOESNT_EXIST
| OPEN_IF_EXISTS
| TRUNCATE_IF_EXISTS
);
229 result
= MatchOpenExpectations(
231 PP_FILEOPENFLAG_WRITE
| PP_FILEOPENFLAG_CREATE
|
232 PP_FILEOPENFLAG_EXCLUSIVE
,
233 CREATE_IF_DOESNT_EXIST
| DONT_OPEN_IF_EXISTS
| DONT_TRUNCATE_IF_EXISTS
);
237 result
= MatchOpenExpectations(
239 PP_FILEOPENFLAG_WRITE
| PP_FILEOPENFLAG_CREATE
| PP_FILEOPENFLAG_TRUNCATE
,
240 CREATE_IF_DOESNT_EXIST
| OPEN_IF_EXISTS
| TRUNCATE_IF_EXISTS
);
244 result
= MatchOpenExpectations(
246 PP_FILEOPENFLAG_WRITE
| PP_FILEOPENFLAG_EXCLUSIVE
|
247 PP_FILEOPENFLAG_TRUNCATE
,
248 DONT_CREATE_IF_DOESNT_EXIST
| OPEN_IF_EXISTS
| TRUNCATE_IF_EXISTS
);
252 result
= MatchOpenExpectations(
254 PP_FILEOPENFLAG_WRITE
| PP_FILEOPENFLAG_CREATE
|
255 PP_FILEOPENFLAG_EXCLUSIVE
| PP_FILEOPENFLAG_TRUNCATE
,
256 CREATE_IF_DOESNT_EXIST
| DONT_OPEN_IF_EXISTS
| DONT_TRUNCATE_IF_EXISTS
);
260 // Invalid combination: PP_FILEOPENFLAG_TRUNCATE without
261 // PP_FILEOPENFLAG_WRITE.
262 result
= MatchOpenExpectations(
264 PP_FILEOPENFLAG_READ
| PP_FILEOPENFLAG_TRUNCATE
,
265 INVALID_FLAG_COMBINATION
);
272 std::string
TestFileIO::TestOpenDirectory() {
273 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
275 pp::FileSystem
file_system(instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
276 callback
.WaitForResult(file_system
.Open(1024, callback
.GetCallback()));
277 CHECK_CALLBACK_BEHAVIOR(callback
);
278 ASSERT_EQ(PP_OK
, callback
.result());
281 pp::FileRef
dir_ref(file_system
, "/test_dir_open_directory");
282 callback
.WaitForResult(dir_ref
.MakeDirectory(callback
.GetCallback()));
283 CHECK_CALLBACK_BEHAVIOR(callback
);
284 ASSERT_EQ(PP_OK
, callback
.result());
286 // Open the directory. This is expected to fail since directories cannot be
288 pp::FileIO
file_io(instance_
);
289 callback
.WaitForResult(file_io
.Open(dir_ref
, PP_FILEOPENFLAG_READ
,
290 callback
.GetCallback()));
291 CHECK_CALLBACK_BEHAVIOR(callback
);
292 ASSERT_EQ(PP_ERROR_NOTAFILE
, callback
.result());
297 std::string
TestFileIO::TestReadWriteSetLength() {
298 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
300 pp::FileSystem
file_system(instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
301 pp::FileRef
file_ref(file_system
, "/file_read_write_setlength");
302 callback
.WaitForResult(file_system
.Open(1024, callback
.GetCallback()));
303 CHECK_CALLBACK_BEHAVIOR(callback
);
304 ASSERT_EQ(PP_OK
, callback
.result());
306 pp::FileIO
file_io(instance_
);
307 callback
.WaitForResult(file_io
.Open(file_ref
,
308 PP_FILEOPENFLAG_CREATE
|
309 PP_FILEOPENFLAG_TRUNCATE
|
310 PP_FILEOPENFLAG_READ
|
311 PP_FILEOPENFLAG_WRITE
,
312 callback
.GetCallback()));
313 CHECK_CALLBACK_BEHAVIOR(callback
);
314 ASSERT_EQ(PP_OK
, callback
.result());
316 // Write something to the file.
317 int32_t rv
= WriteEntireBuffer(instance_
->pp_instance(), &file_io
, 0,
318 "test_test", callback_type());
319 ASSERT_EQ(PP_OK
, rv
);
321 // Attempt to read a negative number of bytes; it should fail.
323 callback
.WaitForResult(file_io
.Read(0,
326 callback
.GetCallback()));
327 CHECK_CALLBACK_BEHAVIOR(callback
);
328 ASSERT_EQ(PP_ERROR_FAILED
, callback
.result());
330 // Read the entire file.
331 std::string read_buffer
;
332 rv
= ReadEntireFile(instance_
->pp_instance(), &file_io
, 0, &read_buffer
,
334 ASSERT_EQ(PP_OK
, rv
);
335 ASSERT_EQ(std::string("test_test"), read_buffer
);
337 // Truncate the file.
338 callback
.WaitForResult(file_io
.SetLength(4, callback
.GetCallback()));
339 CHECK_CALLBACK_BEHAVIOR(callback
);
340 ASSERT_EQ(PP_OK
, callback
.result());
342 // Check the file contents.
344 rv
= ReadEntireFile(instance_
->pp_instance(), &file_io
, 0, &read_buffer
,
346 ASSERT_EQ(PP_OK
, rv
);
347 ASSERT_EQ(std::string("test"), read_buffer
);
349 // Try to read past the end of the file.
351 rv
= ReadEntireFile(instance_
->pp_instance(), &file_io
, 100, &read_buffer
,
353 ASSERT_EQ(PP_OK
, rv
);
354 ASSERT_TRUE(read_buffer
.empty());
356 // Write past the end of the file. The file should be zero-padded.
357 rv
= WriteEntireBuffer(instance_
->pp_instance(), &file_io
, 8, "test",
359 ASSERT_EQ(PP_OK
, rv
);
361 // Check the contents of the file.
363 rv
= ReadEntireFile(instance_
->pp_instance(), &file_io
, 0, &read_buffer
,
365 ASSERT_EQ(PP_OK
, rv
);
366 ASSERT_EQ(std::string("test\0\0\0\0test", 12), read_buffer
);
369 callback
.WaitForResult(file_io
.SetLength(16, callback
.GetCallback()));
370 CHECK_CALLBACK_BEHAVIOR(callback
);
371 ASSERT_EQ(PP_OK
, callback
.result());
373 // Check the contents of the file.
375 rv
= ReadEntireFile(instance_
->pp_instance(), &file_io
, 0, &read_buffer
,
377 ASSERT_EQ(PP_OK
, rv
);
378 ASSERT_EQ(std::string("test\0\0\0\0test\0\0\0\0", 16), read_buffer
);
380 // Write in the middle of the file.
381 rv
= WriteEntireBuffer(instance_
->pp_instance(), &file_io
, 4, "test",
383 ASSERT_EQ(PP_OK
, rv
);
385 // Check the contents of the file.
387 rv
= ReadEntireFile(instance_
->pp_instance(), &file_io
, 0, &read_buffer
,
389 ASSERT_EQ(PP_OK
, rv
);
390 ASSERT_EQ(std::string("testtesttest\0\0\0\0", 16), read_buffer
);
392 // Read from the middle of the file.
394 rv
= ReadEntireFile(instance_
->pp_instance(), &file_io
, 4, &read_buffer
,
396 ASSERT_EQ(PP_OK
, rv
);
397 ASSERT_EQ(std::string("testtest\0\0\0\0", 12), read_buffer
);
402 // This is basically a copy of TestReadWriteSetLength, but with the new Read
403 // API. With this test case, we can make sure the two Read's have the same
405 std::string
TestFileIO::TestReadToArrayWriteSetLength() {
406 if (callback_type() == PP_BLOCKING
) {
407 // This test does not make sense for blocking callbacks.
410 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
412 pp::FileSystem
file_system(instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
413 pp::FileRef
file_ref(file_system
, "/file_read_write_setlength");
414 callback
.WaitForResult(file_system
.Open(1024, callback
.GetCallback()));
415 CHECK_CALLBACK_BEHAVIOR(callback
);
416 ASSERT_EQ(PP_OK
, callback
.result());
418 pp::FileIO
file_io(instance_
);
419 callback
.WaitForResult(file_io
.Open(file_ref
,
420 PP_FILEOPENFLAG_CREATE
|
421 PP_FILEOPENFLAG_TRUNCATE
|
422 PP_FILEOPENFLAG_READ
|
423 PP_FILEOPENFLAG_WRITE
,
424 callback
.GetCallback()));
425 CHECK_CALLBACK_BEHAVIOR(callback
);
426 ASSERT_EQ(PP_OK
, callback
.result());
428 // Write something to the file.
429 int32_t rv
= WriteEntireBuffer(instance_
->pp_instance(), &file_io
, 0,
430 "test_test", callback_type());
431 ASSERT_EQ(PP_OK
, rv
);
433 TestCompletionCallbackWithOutput
< std::vector
<char> > callback2(
434 instance_
->pp_instance(), callback_type());
435 // Attempt to read a negative number of bytes; it should fail.
436 callback2
.WaitForResult(file_io
.Read(0, -1, callback2
.GetCallback()));
437 CHECK_CALLBACK_BEHAVIOR(callback2
);
438 ASSERT_EQ(PP_ERROR_FAILED
, callback2
.result());
440 // Read the entire file.
441 std::string read_buffer
;
442 read_buffer
.reserve(10);
443 rv
= ReadToArrayEntireFile(instance_
->pp_instance(), &file_io
, 0,
444 &read_buffer
, callback_type());
445 ASSERT_EQ(PP_OK
, rv
);
446 ASSERT_EQ(std::string("test_test"), read_buffer
);
448 // Truncate the file.
449 callback
.WaitForResult(file_io
.SetLength(4, callback
.GetCallback()));
450 CHECK_CALLBACK_BEHAVIOR(callback
);
451 ASSERT_EQ(PP_OK
, rv
);
453 // Check the file contents.
455 rv
= ReadToArrayEntireFile(instance_
->pp_instance(), &file_io
, 0,
456 &read_buffer
, callback_type());
457 ASSERT_EQ(PP_OK
, rv
);
458 ASSERT_EQ(std::string("test"), read_buffer
);
460 // Try to read past the end of the file.
462 rv
= ReadToArrayEntireFile(instance_
->pp_instance(), &file_io
, 100,
463 &read_buffer
, callback_type());
464 ASSERT_EQ(PP_OK
, rv
);
465 ASSERT_TRUE(read_buffer
.empty());
467 // Write past the end of the file. The file should be zero-padded.
468 rv
= WriteEntireBuffer(instance_
->pp_instance(), &file_io
, 8, "test",
470 ASSERT_EQ(PP_OK
, rv
);
472 // Check the contents of the file.
474 rv
= ReadToArrayEntireFile(instance_
->pp_instance(), &file_io
, 0,
475 &read_buffer
, callback_type());
476 ASSERT_EQ(PP_OK
, rv
);
477 ASSERT_EQ(std::string("test\0\0\0\0test", 12), read_buffer
);
480 callback
.WaitForResult(file_io
.SetLength(16, callback
.GetCallback()));
481 CHECK_CALLBACK_BEHAVIOR(callback
);
482 ASSERT_EQ(PP_OK
, callback
.result());
484 // Check the contents of the file.
486 rv
= ReadToArrayEntireFile(instance_
->pp_instance(), &file_io
, 0,
487 &read_buffer
, callback_type());
488 ASSERT_EQ(PP_OK
, rv
);
489 ASSERT_EQ(std::string("test\0\0\0\0test\0\0\0\0", 16), read_buffer
);
491 // Write in the middle of the file.
492 rv
= WriteEntireBuffer(instance_
->pp_instance(), &file_io
, 4, "test",
494 ASSERT_EQ(PP_OK
, rv
);
496 // Check the contents of the file.
498 rv
= ReadToArrayEntireFile(instance_
->pp_instance(), &file_io
, 0,
499 &read_buffer
, callback_type());
500 ASSERT_EQ(PP_OK
, rv
);
501 ASSERT_EQ(std::string("testtesttest\0\0\0\0", 16), read_buffer
);
503 // Read from the middle of the file.
505 rv
= ReadToArrayEntireFile(instance_
->pp_instance(), &file_io
, 4,
506 &read_buffer
, callback_type());
507 ASSERT_EQ(PP_OK
, rv
);
508 ASSERT_EQ(std::string("testtest\0\0\0\0", 12), read_buffer
);
513 std::string
TestFileIO::TestTouchQuery() {
514 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
516 pp::FileSystem
file_system(instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
517 callback
.WaitForResult(file_system
.Open(1024, callback
.GetCallback()));
518 CHECK_CALLBACK_BEHAVIOR(callback
);
519 ASSERT_EQ(PP_OK
, callback
.result());
521 pp::FileRef
file_ref(file_system
, "/file_touch");
522 pp::FileIO
file_io(instance_
);
523 callback
.WaitForResult(file_io
.Open(file_ref
,
524 PP_FILEOPENFLAG_CREATE
|
525 PP_FILEOPENFLAG_TRUNCATE
|
526 PP_FILEOPENFLAG_WRITE
,
527 callback
.GetCallback()));
528 CHECK_CALLBACK_BEHAVIOR(callback
);
529 ASSERT_EQ(PP_OK
, callback
.result());
531 // Write some data to have a non-zero file size.
532 callback
.WaitForResult(file_io
.Write(0, "test", 4, callback
.GetCallback()));
533 CHECK_CALLBACK_BEHAVIOR(callback
);
534 ASSERT_EQ(4, callback
.result());
536 // last_access_time's granularity is 1 day
537 // last_modified_time's granularity is 2 seconds
538 const PP_Time last_access_time
= 123 * 24 * 3600.0;
539 const PP_Time last_modified_time
= 246.0;
540 callback
.WaitForResult(file_io
.Touch(last_access_time
, last_modified_time
,
541 callback
.GetCallback()));
542 CHECK_CALLBACK_BEHAVIOR(callback
);
543 ASSERT_EQ(PP_OK
, callback
.result());
546 callback
.WaitForResult(file_io
.Query(&info
, callback
.GetCallback()));
547 CHECK_CALLBACK_BEHAVIOR(callback
);
548 ASSERT_EQ(PP_OK
, callback
.result());
550 if ((info
.size
!= 4) ||
551 (info
.type
!= PP_FILETYPE_REGULAR
) ||
552 (info
.system_type
!= PP_FILESYSTEMTYPE_LOCALTEMPORARY
) ||
553 (info
.last_access_time
!= last_access_time
) ||
554 (info
.last_modified_time
!= last_modified_time
))
555 return "FileIO::Query() has returned bad data.";
557 // Call |Query()| again, to make sure it works a second time.
558 callback
.WaitForResult(file_io
.Query(&info
, callback
.GetCallback()));
559 CHECK_CALLBACK_BEHAVIOR(callback
);
560 ASSERT_EQ(PP_OK
, callback
.result());
565 std::string
TestFileIO::TestAbortCalls() {
566 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
568 pp::FileSystem
file_system(instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
569 pp::FileRef
file_ref(file_system
, "/file_abort_calls");
570 callback
.WaitForResult(file_system
.Open(1024, callback
.GetCallback()));
571 CHECK_CALLBACK_BEHAVIOR(callback
);
572 ASSERT_EQ(PP_OK
, callback
.result());
574 int32_t rv
= PP_ERROR_FAILED
;
575 // First, create a file on which to do ops.
577 pp::FileIO
file_io(instance_
);
578 callback
.WaitForResult(
579 file_io
.Open(file_ref
,
580 PP_FILEOPENFLAG_CREATE
| PP_FILEOPENFLAG_WRITE
,
581 callback
.GetCallback()));
582 CHECK_CALLBACK_BEHAVIOR(callback
);
583 ASSERT_EQ(PP_OK
, callback
.result());
585 // N.B.: Should write at least 3 bytes.
586 rv
= WriteEntireBuffer(instance_
->pp_instance(), &file_io
, 0,
587 "foobarbazquux", callback_type());
588 ASSERT_EQ(PP_OK
, rv
);
593 rv
= pp::FileIO(instance_
)
594 .Open(file_ref
, PP_FILEOPENFLAG_READ
, callback
.GetCallback());
596 callback
.WaitForAbortResult(rv
);
597 CHECK_CALLBACK_BEHAVIOR(callback
);
601 PP_FileInfo info
= { 0 };
602 // Save a copy and make sure |info| doesn't get written to if it is aborted.
603 PP_FileInfo info_copy
;
604 memcpy(&info_copy
, &info
, sizeof(info
));
606 pp::FileIO
file_io(instance_
);
607 callback
.WaitForResult(file_io
.Open(file_ref
, PP_FILEOPENFLAG_READ
,
608 callback
.GetCallback()));
609 CHECK_CALLBACK_BEHAVIOR(callback
);
610 ASSERT_EQ(PP_OK
, callback
.result());
612 rv
= file_io
.Query(&info
, callback
.GetCallback());
613 } // Destroy |file_io|.
614 callback
.WaitForResult(rv
);
615 CHECK_CALLBACK_BEHAVIOR(callback
);
616 if (callback_type() == PP_BLOCKING
) {
617 ASSERT_EQ(callback
.result(), PP_OK
);
618 // The operation completed synchronously, so |info| should have changed.
619 ASSERT_NE(0, memcmp(&info_copy
, &info
, sizeof(info
)));
621 ASSERT_EQ(callback
.result(), PP_ERROR_ABORTED
);
622 ASSERT_EQ(0, memcmp(&info_copy
, &info
, sizeof(info
)));
629 pp::FileIO
file_io(instance_
);
630 callback
.WaitForResult(file_io
.Open(file_ref
, PP_FILEOPENFLAG_WRITE
,
631 callback
.GetCallback()));
632 CHECK_CALLBACK_BEHAVIOR(callback
);
633 ASSERT_EQ(PP_OK
, callback
.result());
635 rv
= file_io
.Touch(0, 0, callback
.GetCallback());
636 } // Destroy |file_io|.
637 callback
.WaitForAbortResult(rv
);
638 CHECK_CALLBACK_BEHAVIOR(callback
);
645 pp::FileIO
file_io(instance_
);
646 callback
.WaitForResult(file_io
.Open(file_ref
, PP_FILEOPENFLAG_READ
,
647 callback
.GetCallback()));
648 CHECK_CALLBACK_BEHAVIOR(callback
);
649 ASSERT_EQ(PP_OK
, callback
.result());
651 rv
= file_io
.Read(0, buf
, sizeof(buf
), callback
.GetCallback());
652 } // Destroy |file_io|.
653 // Save a copy to make sure buf isn't written to in the async case.
655 memcpy(&buf_copy
, &buf
, sizeof(buf
));
656 callback
.WaitForResult(rv
);
657 CHECK_CALLBACK_BEHAVIOR(callback
);
658 if (callback_type() == PP_BLOCKING
) {
659 ASSERT_EQ(callback
.result(), sizeof(buf
));
661 ASSERT_EQ(callback
.result(), PP_ERROR_ABORTED
);
662 ASSERT_EQ(0, memcmp(&buf_copy
, &buf
, sizeof(buf
)));
670 pp::FileIO
file_io(instance_
);
671 callback
.WaitForResult(file_io
.Open(file_ref
, PP_FILEOPENFLAG_WRITE
,
672 callback
.GetCallback()));
673 CHECK_CALLBACK_BEHAVIOR(callback
);
674 ASSERT_EQ(PP_OK
, callback
.result());
676 rv
= file_io
.Write(0, buf
, sizeof(buf
), callback
.GetCallback());
677 } // Destroy |file_io|.
678 callback
.WaitForResult(rv
);
679 CHECK_CALLBACK_BEHAVIOR(callback
);
680 if (callback_type() == PP_BLOCKING
)
681 ASSERT_EQ(callback
.result(), sizeof(buf
));
683 ASSERT_EQ(callback
.result(), PP_ERROR_ABORTED
);
686 // Abort |SetLength()|.
689 pp::FileIO
file_io(instance_
);
690 callback
.WaitForResult(file_io
.Open(file_ref
, PP_FILEOPENFLAG_READ
,
691 callback
.GetCallback()));
692 CHECK_CALLBACK_BEHAVIOR(callback
);
693 ASSERT_EQ(PP_OK
, callback
.result());
695 rv
= file_io
.SetLength(3, callback
.GetCallback());
696 } // Destroy |file_io|.
697 callback
.WaitForAbortResult(rv
);
698 CHECK_CALLBACK_BEHAVIOR(callback
);
704 pp::FileIO
file_io(instance_
);
705 callback
.WaitForResult(file_io
.Open(file_ref
, PP_FILEOPENFLAG_WRITE
,
706 callback
.GetCallback()));
707 CHECK_CALLBACK_BEHAVIOR(callback
);
708 ASSERT_EQ(PP_OK
, callback
.result());
710 rv
= file_io
.Flush(callback
.GetCallback());
711 } // Destroy |file_io|.
712 callback
.WaitForAbortResult(rv
);
713 CHECK_CALLBACK_BEHAVIOR(callback
);
719 std::string
TestFileIO::TestParallelReads() {
720 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
721 pp::FileSystem
file_system(instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
722 pp::FileRef
file_ref(file_system
, "/file_parallel_reads");
723 callback
.WaitForResult(file_system
.Open(1024, callback
.GetCallback()));
724 CHECK_CALLBACK_BEHAVIOR(callback
);
725 ASSERT_EQ(PP_OK
, callback
.result());
727 pp::FileIO
file_io(instance_
);
728 callback
.WaitForResult(file_io
.Open(file_ref
,
729 PP_FILEOPENFLAG_CREATE
|
730 PP_FILEOPENFLAG_TRUNCATE
|
731 PP_FILEOPENFLAG_READ
|
732 PP_FILEOPENFLAG_WRITE
,
733 callback
.GetCallback()));
734 CHECK_CALLBACK_BEHAVIOR(callback
);
735 ASSERT_EQ(PP_OK
, callback
.result());
737 // Set up testing contents.
738 int32_t rv
= WriteEntireBuffer(instance_
->pp_instance(), &file_io
, 0,
739 "abcdefghijkl", callback_type());
740 ASSERT_EQ(PP_OK
, rv
);
742 // Parallel read operations.
743 const char* border
= "__border__";
744 const int32_t border_size
= strlen(border
);
746 TestCompletionCallback
callback_1(instance_
->pp_instance(), callback_type());
747 int32_t read_offset_1
= 0;
749 std::vector
<char> extended_buf_1(border_size
* 2 + size_1
);
750 char* buf_1
= &extended_buf_1
[border_size
];
751 memcpy(&extended_buf_1
[0], border
, border_size
);
752 memcpy(buf_1
+ size_1
, border
, border_size
);
754 TestCompletionCallback
callback_2(instance_
->pp_instance(), callback_type());
755 int32_t read_offset_2
= size_1
;
757 std::vector
<char> extended_buf_2(border_size
* 2 + size_2
);
758 char* buf_2
= &extended_buf_2
[border_size
];
759 memcpy(&extended_buf_2
[0], border
, border_size
);
760 memcpy(buf_2
+ size_2
, border
, border_size
);
762 int32_t rv_1
= PP_OK
;
763 int32_t rv_2
= PP_OK
;
764 while (size_1
>= 0 && size_2
>= 0 && size_1
+ size_2
> 0) {
766 rv_1
= file_io
.Read(read_offset_1
, buf_1
, size_1
,
767 callback_1
.GetCallback());
770 rv_2
= file_io
.Read(read_offset_2
, buf_2
, size_2
,
771 callback_2
.GetCallback());
774 callback_1
.WaitForResult(rv_1
);
775 CHECK_CALLBACK_BEHAVIOR(callback_1
);
776 ASSERT_TRUE(callback_1
.result() > 0);
777 read_offset_1
+= callback_1
.result();
778 buf_1
+= callback_1
.result();
779 size_1
-= callback_1
.result();
783 callback_2
.WaitForResult(rv_2
);
784 CHECK_CALLBACK_BEHAVIOR(callback_2
);
785 ASSERT_TRUE(callback_2
.result() > 0);
786 read_offset_2
+= callback_2
.result();
787 buf_2
+= callback_2
.result();
788 size_2
-= callback_2
.result();
792 // If |size_1| or |size_2| is not 0, we have invoked wrong callback(s).
793 ASSERT_EQ(0, size_1
);
794 ASSERT_EQ(0, size_2
);
796 // Make sure every read operation writes into the correct buffer.
797 const char expected_result_1
[] = "__border__abc__border__";
798 const char expected_result_2
[] = "__border__defghijkl__border__";
799 ASSERT_TRUE(strncmp(&extended_buf_1
[0], expected_result_1
,
800 strlen(expected_result_1
)) == 0);
801 ASSERT_TRUE(strncmp(&extended_buf_2
[0], expected_result_2
,
802 strlen(expected_result_2
)) == 0);
806 std::string
TestFileIO::TestParallelWrites() {
807 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
808 pp::FileSystem
file_system(instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
809 pp::FileRef
file_ref(file_system
, "/file_parallel_writes");
810 callback
.WaitForResult(file_system
.Open(1024, callback
.GetCallback()));
811 CHECK_CALLBACK_BEHAVIOR(callback
);
812 ASSERT_EQ(PP_OK
, callback
.result());
814 pp::FileIO
file_io(instance_
);
815 callback
.WaitForResult(file_io
.Open(file_ref
,
816 PP_FILEOPENFLAG_CREATE
|
817 PP_FILEOPENFLAG_TRUNCATE
|
818 PP_FILEOPENFLAG_READ
|
819 PP_FILEOPENFLAG_WRITE
,
820 callback
.GetCallback()));
821 CHECK_CALLBACK_BEHAVIOR(callback
);
822 ASSERT_EQ(PP_OK
, callback
.result());
824 // Parallel write operations.
825 TestCompletionCallback
callback_1(instance_
->pp_instance(), callback_type());
826 int32_t write_offset_1
= 0;
827 const char* buf_1
= "abc";
828 int32_t size_1
= strlen(buf_1
);
830 TestCompletionCallback
callback_2(instance_
->pp_instance(), callback_type());
831 int32_t write_offset_2
= size_1
;
832 const char* buf_2
= "defghijkl";
833 int32_t size_2
= strlen(buf_2
);
835 int32_t rv_1
= PP_OK
;
836 int32_t rv_2
= PP_OK
;
837 while (size_1
>= 0 && size_2
>= 0 && size_1
+ size_2
> 0) {
839 rv_1
= file_io
.Write(write_offset_1
, buf_1
, size_1
,
840 callback_1
.GetCallback());
843 rv_2
= file_io
.Write(write_offset_2
, buf_2
, size_2
,
844 callback_2
.GetCallback());
848 callback_1
.WaitForResult(rv_1
);
849 CHECK_CALLBACK_BEHAVIOR(callback_1
);
850 ASSERT_TRUE(callback_1
.result() > 0);
851 write_offset_1
+= callback_1
.result();
852 buf_1
+= callback_1
.result();
853 size_1
-= callback_1
.result();
857 callback_2
.WaitForResult(rv_2
);
858 CHECK_CALLBACK_BEHAVIOR(callback_2
);
859 ASSERT_TRUE(callback_2
.result() > 0);
860 write_offset_2
+= callback_2
.result();
861 buf_2
+= callback_2
.result();
862 size_2
-= callback_2
.result();
866 // If |size_1| or |size_2| is not 0, we have invoked wrong callback(s).
867 ASSERT_EQ(0, size_1
);
868 ASSERT_EQ(0, size_2
);
870 // Check the file contents.
871 std::string read_buffer
;
872 int32_t rv
= ReadEntireFile(instance_
->pp_instance(), &file_io
, 0,
873 &read_buffer
, callback_type());
874 ASSERT_EQ(PP_OK
, rv
);
875 ASSERT_EQ(std::string("abcdefghijkl"), read_buffer
);
880 std::string
TestFileIO::TestNotAllowMixedReadWrite() {
881 if (callback_type() == PP_BLOCKING
) {
882 // This test does not make sense for blocking callbacks.
885 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
887 pp::FileSystem
file_system(instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
888 pp::FileRef
file_ref(file_system
, "/file_not_allow_mixed_read_write");
889 callback
.WaitForResult(file_system
.Open(1024, callback
.GetCallback()));
890 CHECK_CALLBACK_BEHAVIOR(callback
);
891 ASSERT_EQ(PP_OK
, callback
.result());
893 pp::FileIO
file_io(instance_
);
894 callback
.WaitForResult(file_io
.Open(file_ref
,
895 PP_FILEOPENFLAG_CREATE
|
896 PP_FILEOPENFLAG_TRUNCATE
|
897 PP_FILEOPENFLAG_READ
|
898 PP_FILEOPENFLAG_WRITE
,
899 callback
.GetCallback()));
900 CHECK_CALLBACK_BEHAVIOR(callback
);
901 ASSERT_EQ(PP_OK
, callback
.result());
903 TestCompletionCallback
callback_1(instance_
->pp_instance(), PP_REQUIRED
);
904 int32_t write_offset_1
= 0;
905 const char* buf_1
= "mnopqrstuvw";
906 int32_t rv_1
= file_io
.Write(write_offset_1
, buf_1
, strlen(buf_1
),
907 callback_1
.GetCallback());
908 ASSERT_EQ(PP_OK_COMPLETIONPENDING
, rv_1
);
910 TestCompletionCallback
callback_2(instance_
->pp_instance(), callback_type());
911 int32_t read_offset_2
= 4;
913 callback_2
.WaitForResult(file_io
.Read(read_offset_2
, buf_2
, sizeof(buf_2
),
914 callback_2
.GetCallback()));
915 CHECK_CALLBACK_BEHAVIOR(callback_2
);
916 ASSERT_EQ(PP_ERROR_INPROGRESS
, callback_2
.result());
917 callback_1
.WaitForResult(rv_1
);
918 CHECK_CALLBACK_BEHAVIOR(callback_1
);
920 // Cannot query while a write is pending.
921 rv_1
= file_io
.Write(write_offset_1
, buf_1
, strlen(buf_1
),
922 callback_1
.GetCallback());
923 ASSERT_EQ(PP_OK_COMPLETIONPENDING
, rv_1
);
925 callback_2
.WaitForResult(file_io
.Query(&info
, callback_2
.GetCallback()));
926 CHECK_CALLBACK_BEHAVIOR(callback_2
);
927 ASSERT_EQ(PP_ERROR_INPROGRESS
, callback_2
.result());
928 callback_1
.WaitForResult(rv_1
);
929 CHECK_CALLBACK_BEHAVIOR(callback_1
);
931 // Cannot touch while a write is pending.
932 rv_1
= file_io
.Write(write_offset_1
, buf_1
, strlen(buf_1
),
933 callback_1
.GetCallback());
934 ASSERT_EQ(PP_OK_COMPLETIONPENDING
, rv_1
);
935 callback_2
.WaitForResult(file_io
.Touch(1234.0, 5678.0,
936 callback_2
.GetCallback()));
937 CHECK_CALLBACK_BEHAVIOR(callback_2
);
938 ASSERT_EQ(PP_ERROR_INPROGRESS
, callback_2
.result());
939 callback_1
.WaitForResult(rv_1
);
940 CHECK_CALLBACK_BEHAVIOR(callback_1
);
942 // Cannot set length while a write is pending.
943 rv_1
= file_io
.Write(write_offset_1
, buf_1
, strlen(buf_1
),
944 callback_1
.GetCallback());
945 ASSERT_EQ(PP_OK_COMPLETIONPENDING
, rv_1
);
946 callback_2
.WaitForResult(file_io
.SetLength(123, callback_2
.GetCallback()));
947 CHECK_CALLBACK_BEHAVIOR(callback_2
);
948 ASSERT_EQ(PP_ERROR_INPROGRESS
, callback_2
.result());
949 callback_1
.WaitForResult(rv_1
);
950 CHECK_CALLBACK_BEHAVIOR(callback_1
);
955 std::string
TestFileIO::TestWillWriteWillSetLength() {
956 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
958 pp::FileSystem
file_system(instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
959 pp::FileRef
file_ref(file_system
, "/file_will_write");
960 callback
.WaitForResult(file_system
.Open(1024, callback
.GetCallback()));
961 CHECK_CALLBACK_BEHAVIOR(callback
);
962 ASSERT_EQ(PP_OK
, callback
.result());
964 pp::FileIO
file_io(instance_
);
965 callback
.WaitForResult(file_io
.Open(file_ref
,
966 PP_FILEOPENFLAG_CREATE
|
967 PP_FILEOPENFLAG_TRUNCATE
|
968 PP_FILEOPENFLAG_READ
|
969 PP_FILEOPENFLAG_WRITE
,
970 callback
.GetCallback()));
971 CHECK_CALLBACK_BEHAVIOR(callback
);
972 ASSERT_EQ(PP_OK
, callback
.result());
974 const PPB_FileIOTrusted
* trusted
= static_cast<const PPB_FileIOTrusted
*>(
975 pp::Module::Get()->GetBrowserInterface(PPB_FILEIOTRUSTED_INTERFACE
));
976 ASSERT_TRUE(trusted
);
978 // Get file descriptor. This is only supported in-process for now, so don't
979 // test out of process.
980 const PPB_Testing_Dev
* testing_interface
= GetTestingInterface();
981 if (testing_interface
&& !testing_interface
->IsOutOfProcess()) {
982 int32_t fd
= trusted
->GetOSFileDescriptor(file_io
.pp_resource());
983 ASSERT_TRUE(fd
>= 0);
986 // Calling WillWrite.
987 callback
.WaitForResult(trusted
->WillWrite(
988 file_io
.pp_resource(), 0, 9,
989 callback
.GetCallback().pp_completion_callback()));
990 CHECK_CALLBACK_BEHAVIOR(callback
);
991 ASSERT_EQ(9, callback
.result());
993 // Writing the actual data.
994 int32_t rv
= WriteEntireBuffer(instance_
->pp_instance(), &file_io
, 0,
995 "test_test", callback_type());
996 ASSERT_EQ(PP_OK
, rv
);
998 std::string read_buffer
;
999 rv
= ReadEntireFile(instance_
->pp_instance(), &file_io
, 0, &read_buffer
,
1001 ASSERT_EQ(PP_OK
, rv
);
1002 ASSERT_EQ(std::string("test_test"), read_buffer
);
1004 // Calling WillSetLength.
1005 callback
.WaitForResult(trusted
->WillSetLength(
1006 file_io
.pp_resource(), 4,
1007 callback
.GetCallback().pp_completion_callback()));
1008 CHECK_CALLBACK_BEHAVIOR(callback
);
1009 ASSERT_EQ(PP_OK
, rv
);
1011 // Calling actual SetLength.
1012 callback
.WaitForResult(file_io
.SetLength(4, callback
.GetCallback()));
1013 CHECK_CALLBACK_BEHAVIOR(callback
);
1014 ASSERT_EQ(PP_OK
, rv
);
1016 read_buffer
.clear();
1017 rv
= ReadEntireFile(instance_
->pp_instance(), &file_io
, 0, &read_buffer
,
1019 ASSERT_EQ(PP_OK
, rv
);
1020 ASSERT_EQ(std::string("test"), read_buffer
);
1025 std::string
TestFileIO::TestRequestOSFileHandle() {
1026 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
1028 pp::FileSystem
file_system(instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
1029 pp::FileRef
file_ref(file_system
, "/file_os_fd");
1031 callback
.WaitForResult(file_system
.Open(1024, callback
.GetCallback()));
1032 if (callback
.result() != PP_OK
)
1033 return ReportError("FileSystem::Open", callback
.result());
1035 pp::FileIO_Private
file_io(instance_
);
1036 callback
.WaitForResult(file_io
.Open(file_ref
,
1037 PP_FILEOPENFLAG_CREATE
|
1038 PP_FILEOPENFLAG_TRUNCATE
|
1039 PP_FILEOPENFLAG_READ
|
1040 PP_FILEOPENFLAG_WRITE
,
1041 callback
.GetCallback()));
1042 if (callback
.result() != PP_OK
)
1043 return ReportError("FileIO::Open", callback
.result());
1045 PP_FileHandle handle
= PP_kInvalidFileHandle
;
1046 callback
.WaitForResult(
1047 file_io
.RequestOSFileHandle(&handle
, callback
.GetCallback()));
1048 if (callback
.result() != PP_OK
)
1049 return ReportError("FileIO::RequestOSFileHandle", callback
.result());
1051 if (handle
== PP_kInvalidFileHandle
)
1052 return "FileIO::RequestOSFileHandle() returned a bad file handle.";
1053 #if defined(PPAPI_OS_WIN)
1054 int fd
= _open_osfhandle(reinterpret_cast<intptr_t>(handle
),
1055 _O_RDWR
| _O_BINARY
);
1060 return "FileIO::RequestOSFileHandle() returned a bad file descriptor.";
1062 // Check write(2) for the native FD.
1063 const std::string msg
= "foobar";
1064 ssize_t cnt
= write(fd
, msg
.data(), msg
.size());
1066 return ReportError("write for native FD returned error", errno
);
1067 if (cnt
!= static_cast<ssize_t
>(msg
.size()))
1068 return ReportError("write for native FD count mismatch", cnt
);
1070 // Check lseek(2) for the native FD.
1071 off_t off
= lseek(fd
, 0, SEEK_CUR
);
1072 if (off
== static_cast<off_t
>(-1))
1073 return ReportError("lseek for native FD returned error", errno
);
1074 if (off
!= static_cast<off_t
>(msg
.size()))
1075 return ReportError("lseek for native FD offset mismatch", off
);
1077 off
= lseek(fd
, 0, SEEK_SET
);
1078 if (off
== static_cast<off_t
>(-1))
1079 return ReportError("lseek for native FD returned error", errno
);
1081 return ReportError("lseek for native FD offset mismatch", off
);
1083 // Check read(2) for the native FD.
1084 std::string
buf(msg
.size(), '\0');
1085 cnt
= read(fd
, &buf
[0], msg
.size());
1087 return ReportError("read for native FD returned error", errno
);
1088 if (cnt
!= static_cast<ssize_t
>(msg
.size()))
1089 return ReportError("read for native FD count mismatch", cnt
);
1091 return ReportMismatch("read for native FD", buf
, msg
);
1093 // TODO(hamaji): Test CreateFileMapping for windows.
1094 #if !defined(PPAPI_OS_WIN)
1095 // Check mmap(2) for read.
1096 char* mapped
= reinterpret_cast<char*>(
1097 mmap(NULL
, msg
.size(), PROT_READ
, MAP_PRIVATE
, fd
, 0));
1098 if (mapped
== MAP_FAILED
)
1099 return ReportError("mmap(r) for native FD returned errno", errno
);
1100 // Make sure the buffer is cleared.
1101 buf
= std::string(msg
.size(), '\0');
1102 memcpy(&buf
[0], mapped
, msg
.size());
1104 return ReportMismatch("mmap(r) for native FD", buf
, msg
);
1105 int r
= munmap(mapped
, msg
.size());
1107 return ReportError("munmap for native FD returned error", errno
);
1109 // Check mmap(2) for write.
1110 mapped
= reinterpret_cast<char*>(
1111 mmap(NULL
, msg
.size(), PROT_READ
| PROT_WRITE
, MAP_SHARED
, fd
, 0));
1112 if (mapped
== MAP_FAILED
)
1113 return ReportError("mmap(w) for native FD returned errno", errno
);
1115 strcpy(mapped
, "baz");
1117 r
= munmap(mapped
, msg
.size());
1119 return ReportError("munmap for native FD returned error", errno
);
1122 #if defined(PPAPI_OS_WIN)
1128 return ReportError("close for native FD returned error", errno
);
1130 // TODO(hamaji): Check if the file is actually updated?
1135 std::string
TestFileIO::MatchOpenExpectations(pp::FileSystem
* file_system
,
1137 size_t expectations
) {
1138 std::string bad_argument
=
1139 "TestFileIO::MatchOpenExpectations has invalid input arguments.";
1140 bool invalid_combination
= !!(expectations
& INVALID_FLAG_COMBINATION
);
1141 if (invalid_combination
) {
1142 if (expectations
!= INVALID_FLAG_COMBINATION
)
1143 return bad_argument
;
1145 // Validate that one and only one of <some_expectation> and
1146 // DONT_<some_expectation> is specified.
1147 for (size_t remains
= expectations
, end
= END_OF_OPEN_EXPECATION_PAIRS
;
1148 end
!= 0; remains
>>= 2, end
>>= 2) {
1149 if (!!(remains
& 1) == !!(remains
& 2))
1150 return bad_argument
;
1153 bool create_if_doesnt_exist
= !!(expectations
& CREATE_IF_DOESNT_EXIST
);
1154 bool open_if_exists
= !!(expectations
& OPEN_IF_EXISTS
);
1155 bool truncate_if_exists
= !!(expectations
& TRUNCATE_IF_EXISTS
);
1157 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
1158 pp::FileRef
existent_file_ref(
1159 *file_system
, "/match_open_expectation_existent_non_empty_file");
1160 pp::FileRef
nonexistent_file_ref(
1161 *file_system
, "/match_open_expectation_nonexistent_file");
1163 // Setup files for test.
1165 callback
.WaitForResult(existent_file_ref
.Delete(callback
.GetCallback()));
1166 CHECK_CALLBACK_BEHAVIOR(callback
);
1167 ASSERT_TRUE(callback
.result() == PP_OK
||
1168 callback
.result() == PP_ERROR_FILENOTFOUND
);
1169 callback
.WaitForResult(nonexistent_file_ref
.Delete(callback
.GetCallback()));
1170 CHECK_CALLBACK_BEHAVIOR(callback
);
1171 ASSERT_TRUE(callback
.result() == PP_OK
||
1172 callback
.result() == PP_ERROR_FILENOTFOUND
);
1174 pp::FileIO
existent_file_io(instance_
);
1175 callback
.WaitForResult(existent_file_io
.Open(
1177 PP_FILEOPENFLAG_CREATE
| PP_FILEOPENFLAG_WRITE
,
1178 callback
.GetCallback()));
1179 CHECK_CALLBACK_BEHAVIOR(callback
);
1180 ASSERT_EQ(PP_OK
, callback
.result());
1181 int32_t rv
= WriteEntireBuffer(instance_
->pp_instance(), &existent_file_io
,
1182 0, "foobar", callback_type());
1183 ASSERT_EQ(PP_OK
, rv
);
1186 pp::FileIO
existent_file_io(instance_
);
1187 callback
.WaitForResult(existent_file_io
.Open(existent_file_ref
, open_flags
,
1188 callback
.GetCallback()));
1189 CHECK_CALLBACK_BEHAVIOR(callback
);
1190 if ((invalid_combination
&& callback
.result() == PP_OK
) ||
1191 (!invalid_combination
&&
1192 ((callback
.result() == PP_OK
) != open_if_exists
))) {
1193 return ReportOpenError(open_flags
);
1196 if (!invalid_combination
&& open_if_exists
) {
1198 callback
.WaitForResult(existent_file_io
.Query(&info
,
1199 callback
.GetCallback()));
1200 CHECK_CALLBACK_BEHAVIOR(callback
);
1201 ASSERT_EQ(PP_OK
, callback
.result());
1202 if (truncate_if_exists
!= (info
.size
== 0))
1203 return ReportOpenError(open_flags
);
1206 pp::FileIO
nonexistent_file_io(instance_
);
1207 callback
.WaitForResult(nonexistent_file_io
.Open(nonexistent_file_ref
,
1209 callback
.GetCallback()));
1210 CHECK_CALLBACK_BEHAVIOR(callback
);
1211 if ((invalid_combination
&& callback
.result() == PP_OK
) ||
1212 (!invalid_combination
&&
1213 ((callback
.result() == PP_OK
) != create_if_doesnt_exist
))) {
1214 return ReportOpenError(open_flags
);
1217 return std::string();
1220 // TODO(viettrungluu): Test Close(). crbug.com/69457