summaryrefslogtreecommitdiffstats
path: root/mojo/common/test/multiprocess_test_base_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'mojo/common/test/multiprocess_test_base_unittest.cc')
-rw-r--r--mojo/common/test/multiprocess_test_base_unittest.cc132
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