Chromium Code Reviews| Index: ppapi/tests/test_file_io.cc |
| diff --git a/ppapi/tests/test_file_io.cc b/ppapi/tests/test_file_io.cc |
| index ea9224fa2d54eeaa9c6fd85c7f237a3da07550a3..5b5853daeeaf0106b7fca4367a128cde69f97ee2 100644 |
| --- a/ppapi/tests/test_file_io.cc |
| +++ b/ppapi/tests/test_file_io.cc |
| @@ -4,22 +4,41 @@ |
| #include "ppapi/tests/test_file_io.h" |
| +#include <errno.h> |
| +#include <fcntl.h> |
| #include <string.h> |
| +#include <sys/stat.h> |
| +#include <sys/types.h> |
| #include <vector> |
| #include "ppapi/c/dev/ppb_testing_dev.h" |
| #include "ppapi/c/pp_errors.h" |
| #include "ppapi/c/ppb_file_io.h" |
| +#include "ppapi/c/private/pp_file_handle.h" |
| #include "ppapi/c/trusted/ppb_file_io_trusted.h" |
| #include "ppapi/cpp/file_io.h" |
| #include "ppapi/cpp/file_ref.h" |
| #include "ppapi/cpp/file_system.h" |
| #include "ppapi/cpp/instance.h" |
| #include "ppapi/cpp/module.h" |
| +#include "ppapi/cpp/private/file_io_private.h" |
| #include "ppapi/tests/test_utils.h" |
| #include "ppapi/tests/testing_instance.h" |
| +#if defined(PPAPI_OS_WIN) |
| +# include <io.h> |
| +# include <windows.h> |
| +// TODO(hamaji): Use standard windows APIs instead of compatibility layer? |
| +# define lseek _lseek |
| +# define read _read |
| +# define write _write |
| +# define ssize_t int |
| +#else |
| +# include <sys/mman.h> |
| +# include <unistd.h> |
| +#endif |
| + |
| REGISTER_TEST_CASE(FileIO); |
| namespace { |
| @@ -148,6 +167,7 @@ void TestFileIO::RunTests(const std::string& filter) { |
| RUN_TEST_FORCEASYNC_AND_NOT(ParallelWrites, filter); |
| RUN_TEST_FORCEASYNC_AND_NOT(NotAllowMixedReadWrite, filter); |
| RUN_TEST_FORCEASYNC_AND_NOT(WillWriteWillSetLength, filter); |
| + RUN_TEST_FORCEASYNC_AND_NOT(GetOSFileHandle, filter); |
| // TODO(viettrungluu): add tests: |
| // - that PP_ERROR_PENDING is correctly returned |
| @@ -1248,6 +1268,130 @@ std::string TestFileIO::TestWillWriteWillSetLength() { |
| PASS(); |
| } |
| +std::string TestFileIO::TestGetOSFileHandle() { |
| + TestCompletionCallback callback(instance_->pp_instance(), force_async_); |
|
dmichael (off chromium)
2013/03/27 19:40:53
I know it would be inconsistent with the rest of t
hamaji
2013/03/28 00:17:29
Done.
|
| + |
| + pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY); |
| + pp::FileRef file_ref(file_system, "/file_os_fd"); |
| + |
| + int32_t rv = file_system.Open(1024, callback.GetCallback()); |
| + if (force_async_ && rv != PP_OK_COMPLETIONPENDING) |
| + return ReportError("FileSystem::Open force_async", rv); |
| + if (rv == PP_OK_COMPLETIONPENDING) |
| + rv = callback.WaitForResult(); |
| + if (rv != PP_OK) |
| + return ReportError("FileSystem::Open", rv); |
| + |
| + pp::FileIO file_io(instance_); |
| + rv = file_io.Open(file_ref, |
| + PP_FILEOPENFLAG_CREATE | |
| + PP_FILEOPENFLAG_TRUNCATE | |
| + PP_FILEOPENFLAG_READ | |
| + PP_FILEOPENFLAG_WRITE, |
| + callback.GetCallback()); |
| + if (force_async_ && rv != PP_OK_COMPLETIONPENDING) |
| + return ReportError("FileIO::Open force_async", rv); |
| + if (rv == PP_OK_COMPLETIONPENDING) |
| + rv = callback.WaitForResult(); |
| + if (rv != PP_OK) |
| + return ReportError("FileIO::Open", rv); |
| + |
| + pp::FileIO_Private file_io_private; |
| + PP_FileHandle handle; |
| + rv = file_io_private.GetOSFileHandle(file_io, |
| + &handle, |
| + callback.GetCallback()); |
| + if (force_async_ && rv != PP_OK_COMPLETIONPENDING) |
| + return ReportError("FileIO::GetOSFileHandle force_async", rv); |
| + if (rv == PP_OK_COMPLETIONPENDING) |
| + rv = callback.WaitForResult(); |
| + if (rv != PP_OK) |
| + return ReportError("FileIO::GetOSFileHandle", rv); |
| + |
| + if (handle == PP_kInvalidFileHandle) |
| + return "FileIO::GetOSFileHandle() returned a bad file handle."; |
| +#if defined(PPAPI_OS_WIN) |
| + int fd = _open_osfhandle(reinterpret_cast<intptr_t>(handle), |
| + _O_RDWR | _O_BINARY); |
| +#else |
| + int fd = handle; |
| +#endif |
| + if (fd < 0) |
| + return "FileIO::GetOSFileHandle() returned a bad file descriptor."; |
| + |
| + // Check write(2) for the native FD. |
| + const std::string msg = "foobar"; |
| + ssize_t cnt = write(fd, msg.data(), msg.size()); |
| + if (cnt < 0) |
| + return ReportError("write for native FD returned error", errno); |
| + if (cnt != static_cast<ssize_t>(msg.size())) |
| + return ReportError("write for native FD count mismatch", cnt); |
| + |
| + // Check lseek(2) for the native FD. |
| + off_t off = lseek(fd, 0, SEEK_CUR); |
| + if (off == static_cast<off_t>(-1)) |
| + return ReportError("lseek for native FD returned error", errno); |
| + if (off != static_cast<off_t>(msg.size())) |
| + return ReportError("lseek for native FD offset mismatch", off); |
| + |
| + off = lseek(fd, 0, SEEK_SET); |
| + if (off == static_cast<off_t>(-1)) |
| + return ReportError("lseek for native FD returned error", errno); |
| + if (off != 0) |
| + return ReportError("lseek for native FD offset mismatch", off); |
| + |
| + // Check read(2) for the native FD. |
| + std::string buf(msg.size(), '\0'); |
| + cnt = read(fd, &buf[0], msg.size()); |
| + if (cnt < 0) |
| + return ReportError("read for native FD returned error", errno); |
| + if (cnt != static_cast<ssize_t>(msg.size())) |
| + return ReportError("read for native FD count mismatch", cnt); |
| + if (msg != buf) |
| + return ReportMismatch("read for native FD", buf, msg); |
| + |
| + // TODO(hamaji): Test CreateFileMapping for windows. |
| +#if !defined(PPAPI_OS_WIN) |
| + // Check mmap(2) for read. |
| + char* mapped = reinterpret_cast<char*>( |
| + mmap(NULL, msg.size(), PROT_READ, MAP_PRIVATE, fd, 0)); |
| + if (mapped == MAP_FAILED) |
| + return ReportError("mmap(r) for native FD returned errno", errno); |
| + // Make sure the buffer is cleared. |
| + buf = std::string(msg.size(), '\0'); |
| + memcpy(&buf[0], mapped, msg.size()); |
| + if (msg != buf) |
| + return ReportMismatch("mmap(r) for native FD", buf, msg); |
| + int r = munmap(mapped, msg.size()); |
| + if (r < 0) |
| + return ReportError("munmap for native FD returned error", errno); |
| + |
| + // Check mmap(2) for write. |
| + mapped = reinterpret_cast<char*>( |
| + mmap(NULL, msg.size(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); |
| + if (mapped == MAP_FAILED) |
| + return ReportError("mmap(w) for native FD returned errno", errno); |
| + // s/foo/baz/ |
| + strcpy(mapped, "baz"); |
| + |
| + r = munmap(mapped, msg.size()); |
| + if (r < 0) |
| + return ReportError("munmap for native FD returned error", errno); |
| +#endif |
| + |
| +#if defined(PPAPI_OS_WIN) |
| + int r = _close(fd); |
| +#else |
| + r = close(handle); |
| +#endif |
| + if (r < 0) |
| + return ReportError("close for native FD returned error", errno); |
| + |
| + // TODO(hamaji): Check if the file is actually updated? |
| + |
| + PASS(); |
| +} |
| + |
| std::string TestFileIO::MatchOpenExpectations(pp::FileSystem* file_system, |
| size_t open_flags, |
| size_t expectations) { |