diff options
Diffstat (limited to 'mojo/common/test/multiprocess_test_base_unittest.cc')
-rw-r--r-- | mojo/common/test/multiprocess_test_base_unittest.cc | 132 |
1 files changed, 100 insertions, 32 deletions
diff --git a/mojo/common/test/multiprocess_test_base_unittest.cc b/mojo/common/test/multiprocess_test_base_unittest.cc index 9681ee3..7b0a7ff 100644 --- a/mojo/common/test/multiprocess_test_base_unittest.cc +++ b/mojo/common/test/multiprocess_test_base_unittest.cc @@ -15,93 +15,161 @@ #include "base/posix/eintr_wrapper.h" #endif +#if defined(OS_WIN) +#include <windows.h> + +#include "base/win/windows_version.h" +#endif + namespace mojo { namespace { +// Returns true and logs a warning on Windows prior to Vista. +bool SkipTest() { +#if defined(OS_WIN) + if (base::win::GetVersion() < base::win::VERSION_VISTA) { + LOG(WARNING) << "Test skipped: Vista or later needed."; + return true; + } +#endif + + return false; +} + +bool IsNonBlocking(const embedder::PlatformHandle& handle) { +#if defined(OS_WIN) + // Haven't figured out a way to query whether a HANDLE was created with + // FILE_FLAG_OVERLAPPED. + return true; +#else + return fcntl(handle.fd, F_GETFL) & O_NONBLOCK; +#endif +} + +// Note: On POSIX, this method sets the handle to block. +bool WriteByte(const embedder::PlatformHandle& handle, char c) { +#if defined(OS_WIN) + DWORD num_bytes_written = 0; + OVERLAPPED overlapped = { 0 }; + + if (!WriteFile(handle.handle, &c, 1, &num_bytes_written, &overlapped)) { + if (GetLastError() != ERROR_IO_PENDING) + return false; + + if (GetOverlappedResult(handle.handle, &overlapped, &num_bytes_written, + TRUE)) { + return num_bytes_written == 1; + } + + return false; + } + return num_bytes_written == 1; +#else + // We're lazy. Set it to block. + PCHECK(fcntl(handle.fd, F_SETFL, 0) == 0); + + return HANDLE_EINTR(write(handle.fd, &c, 1)) == 1; +#endif +} + +// Note: On POSIX, this method sets the handle to block. +bool ReadByte(const embedder::PlatformHandle& handle, char* c) { +#if defined(OS_WIN) + DWORD num_bytes_read = 0; + OVERLAPPED overlapped = { 0 }; + + if (!ReadFile(handle.handle, c, 1, &num_bytes_read, &overlapped)) { + if (GetLastError() != ERROR_IO_PENDING) + return false; + + if (GetOverlappedResult(handle.handle, &overlapped, &num_bytes_read, TRUE)) + return num_bytes_read == 1; + + return false; + } + return num_bytes_read == 1; +#else + // We're lazy. Set it to block. + PCHECK(fcntl(handle.fd, F_SETFL, 0) == 0); + + return HANDLE_EINTR(read(handle.fd, c, 1)) == 1; +#endif +} + typedef test::MultiprocessTestBase MultiprocessTestBaseTest; TEST_F(MultiprocessTestBaseTest, RunChild) { -// TODO(vtl): Not implemented on Windows yet. -#if defined(OS_POSIX) + if (SkipTest()) + return; + EXPECT_TRUE(server_platform_handle.is_valid()); -#endif + StartChild("RunChild"); EXPECT_EQ(123, WaitForChildShutdown()); } MOJO_MULTIPROCESS_TEST_CHILD_MAIN(RunChild) { -// TODO(vtl): Not implemented on Windows yet. -#if defined(OS_POSIX) CHECK(MultiprocessTestBaseTest::client_platform_handle.is_valid()); -#endif return 123; } TEST_F(MultiprocessTestBaseTest, TestChildMainNotFound) { + if (SkipTest()) + return; + StartChild("NoSuchTestChildMain"); int result = WaitForChildShutdown(); EXPECT_FALSE(result >= 0 && result <= 127); } -// POSIX-specific test of passed handle ---------------------------------------- +TEST_F(MultiprocessTestBaseTest, PassedChannel) { + if (SkipTest()) + return; -#if defined(OS_POSIX) -TEST_F(MultiprocessTestBaseTest, PassedChannelPosix) { EXPECT_TRUE(server_platform_handle.is_valid()); - StartChild("PassedChannelPosix"); + StartChild("PassedChannel"); - // Take ownership of the FD. + // Take ownership of the handle. embedder::ScopedPlatformHandle handle = server_platform_handle.Pass(); - int fd = handle.get().fd; - // The FD should be non-blocking. Check this. - CHECK((fcntl(fd, F_GETFL) & O_NONBLOCK)); - // We're lazy. Set it to block. - PCHECK(fcntl(fd, F_SETFL, 0) == 0); + // The handle should be non-blocking. + EXPECT_TRUE(IsNonBlocking(handle.get())); // Write a byte. const char c = 'X'; - ssize_t write_size = HANDLE_EINTR(write(fd, &c, 1)); - EXPECT_EQ(1, write_size); + EXPECT_TRUE(WriteByte(handle.get(), c)); // It'll echo it back to us, incremented. char d = 0; - ssize_t read_size = HANDLE_EINTR(read(fd, &d, 1)); - EXPECT_EQ(1, read_size); + EXPECT_TRUE(ReadByte(handle.get(), &d)); EXPECT_EQ(c + 1, d); // And return it, incremented again. EXPECT_EQ(c + 2, WaitForChildShutdown()); } -MOJO_MULTIPROCESS_TEST_CHILD_MAIN(PassedChannelPosix) { +MOJO_MULTIPROCESS_TEST_CHILD_MAIN(PassedChannel) { CHECK(MultiprocessTestBaseTest::client_platform_handle.is_valid()); - // Take ownership of the FD. + // Take ownership of the handle. embedder::ScopedPlatformHandle handle = MultiprocessTestBaseTest::client_platform_handle.Pass(); - int fd = handle.get().fd; - // The FD should still be non-blocking. Check this. - CHECK((fcntl(fd, F_GETFL) & O_NONBLOCK)); - // We're lazy. Set it to block. - PCHECK(fcntl(fd, F_SETFL, 0) == 0); + // The handle should be non-blocking. + EXPECT_TRUE(IsNonBlocking(handle.get())); // Read a byte. char c = 0; - ssize_t read_size = HANDLE_EINTR(read(fd, &c, 1)); - CHECK_EQ(read_size, 1); + EXPECT_TRUE(ReadByte(handle.get(), &c)); // Write it back, incremented. c++; - ssize_t write_size = HANDLE_EINTR(write(fd, &c, 1)); - CHECK_EQ(write_size, 1); + EXPECT_TRUE(WriteByte(handle.get(), c)); // And return it, incremented again. c++; return static_cast<int>(c); } -#endif // defined(OS_POSIX) } // namespace } // namespace mojo |